aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/bus.c
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2013-04-08 18:51:38 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-08 19:57:15 -0400
commite46980a10a76ec3282dd6832c1974b880acd23d3 (patch)
tree42d8e5abab5991b4026af385545e23af619f610b /drivers/misc/mei/bus.c
parentd6c36a475fccfca05fd05362c98e49f6dd07721c (diff)
mei: bus: Add device enabling and disabling API
It should be left to the drivers to enable and disable the device on the MEI bus when e.g getting probed. For drivers to be able to safely call the enable and disable hooks, the mei_cl_ops must be set before it's probed and thus this should happen before registering the device on the MEI bus. Hence the mei_cl_add_device() prototype change. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/bus.c')
-rw-r--r--drivers/misc/mei/bus.c99
1 files changed, 98 insertions, 1 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 6badfa1110e9..834ceeb69cbf 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -153,7 +153,8 @@ static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev,
153 return NULL; 153 return NULL;
154} 154}
155struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, 155struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
156 uuid_le uuid, char *name) 156 uuid_le uuid, char *name,
157 struct mei_cl_ops *ops)
157{ 158{
158 struct mei_cl_device *device; 159 struct mei_cl_device *device;
159 struct mei_cl *cl; 160 struct mei_cl *cl;
@@ -168,6 +169,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
168 return NULL; 169 return NULL;
169 170
170 device->cl = cl; 171 device->cl = cl;
172 device->ops = ops;
171 173
172 device->dev.parent = &dev->pdev->dev; 174 device->dev.parent = &dev->pdev->dev;
173 device->dev.bus = &mei_cl_bus_type; 175 device->dev.bus = &mei_cl_bus_type;
@@ -408,6 +410,101 @@ void mei_cl_set_drvdata(struct mei_cl_device *device, void *data)
408} 410}
409EXPORT_SYMBOL_GPL(mei_cl_set_drvdata); 411EXPORT_SYMBOL_GPL(mei_cl_set_drvdata);
410 412
413int mei_cl_enable_device(struct mei_cl_device *device)
414{
415 int err;
416 struct mei_device *dev;
417 struct mei_cl *cl = device->cl;
418
419 if (cl == NULL)
420 return -ENODEV;
421
422 dev = cl->dev;
423
424 mutex_lock(&dev->device_lock);
425
426 cl->state = MEI_FILE_CONNECTING;
427
428 err = mei_cl_connect(cl, NULL);
429 if (err < 0) {
430 mutex_unlock(&dev->device_lock);
431 dev_err(&dev->pdev->dev, "Could not connect to the ME client");
432
433 return err;
434 }
435
436 mutex_unlock(&dev->device_lock);
437
438 if (device->event_cb && !cl->read_cb)
439 mei_cl_read_start(device->cl);
440
441 if (!device->ops || !device->ops->enable)
442 return 0;
443
444 return device->ops->enable(device);
445}
446EXPORT_SYMBOL_GPL(mei_cl_enable_device);
447
448int mei_cl_disable_device(struct mei_cl_device *device)
449{
450 int err;
451 struct mei_device *dev;
452 struct mei_cl *cl = device->cl;
453
454 if (cl == NULL)
455 return -ENODEV;
456
457 dev = cl->dev;
458
459 mutex_lock(&dev->device_lock);
460
461 if (cl->state != MEI_FILE_CONNECTED) {
462 mutex_unlock(&dev->device_lock);
463 dev_err(&dev->pdev->dev, "Already disconnected");
464
465 return 0;
466 }
467
468 cl->state = MEI_FILE_DISCONNECTING;
469
470 err = mei_cl_disconnect(cl);
471 if (err < 0) {
472 mutex_unlock(&dev->device_lock);
473 dev_err(&dev->pdev->dev,
474 "Could not disconnect from the ME client");
475
476 return err;
477 }
478
479 /* Flush queues and remove any pending read */
480 mei_cl_flush_queues(cl);
481
482 if (cl->read_cb) {
483 struct mei_cl_cb *cb = NULL;
484
485 cb = mei_cl_find_read_cb(cl);
486 /* Remove entry from read list */
487 if (cb)
488 list_del(&cb->list);
489
490 cb = cl->read_cb;
491 cl->read_cb = NULL;
492
493 if (cb) {
494 mei_io_cb_free(cb);
495 cb = NULL;
496 }
497 }
498
499 mutex_unlock(&dev->device_lock);
500
501 if (!device->ops || !device->ops->disable)
502 return 0;
503
504 return device->ops->disable(device);
505}
506EXPORT_SYMBOL_GPL(mei_cl_disable_device);
507
411void mei_cl_bus_rx_event(struct mei_cl *cl) 508void mei_cl_bus_rx_event(struct mei_cl *cl)
412{ 509{
413 struct mei_cl_device *device = cl->device; 510 struct mei_cl_device *device = cl->device;