diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2016-02-07 22:35:41 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-07 23:47:20 +0100 |
commit | a816a00ece63d16ade7e9c0ca8b5a7e4c5ea2453 (patch) | |
tree | 4ce36a74010f7f8b65d0ab7520c8ad701eda445a /drivers/misc | |
parent | mei: drop reserved host client ids (diff) | |
download | linux-a816a00ece63d16ade7e9c0ca8b5a7e4c5ea2453.tar.xz linux-a816a00ece63d16ade7e9c0ca8b5a7e4c5ea2453.zip |
mei: bus: run rescan on me_clients list change
Since clients can be now added and removed during runtime
we need to run bus rescan whenever me_clients list is modified.
Signed-off-by: Alexander Usyskin <alexander.usyskin@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')
-rw-r--r-- | drivers/misc/mei/bus.c | 8 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 8 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 3 |
4 files changed, 20 insertions, 1 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index bc18e5519da6..951d32265040 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -977,6 +977,14 @@ void mei_cl_bus_rescan(struct mei_device *bus) dev_dbg(bus->dev, "rescan end"); } +void mei_cl_bus_rescan_work(struct work_struct *work) +{ + struct mei_device *bus = + container_of(work, struct mei_device, bus_rescan_work); + + mei_cl_bus_rescan(bus); +} + int __mei_cldev_driver_register(struct mei_cl_driver *cldrv, struct module *owner) { diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index a2f32b0eb649..0c9310ad6136 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -401,6 +401,9 @@ static int mei_hbm_fw_add_cl_req(struct mei_device *dev, if (ret) status = !MEI_HBMS_SUCCESS; + if (dev->dev_state == MEI_DEV_ENABLED) + schedule_work(&dev->bus_rescan_work); + return mei_hbm_add_cl_resp(dev, req->me_addr, status); } @@ -789,8 +792,11 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, struct mei_cl *cl, cl->state = MEI_FILE_CONNECTED; else { cl->state = MEI_FILE_DISCONNECT_REPLY; - if (rs->status == MEI_CL_CONN_NOT_FOUND) + if (rs->status == MEI_CL_CONN_NOT_FOUND) { mei_me_cl_del(dev, cl->me_cl); + if (dev->dev_state == MEI_DEV_ENABLED) + schedule_work(&dev->bus_rescan_work); + } } cl->status = mei_cl_conn_status_to_errno(rs->status); } diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index cfcb46da13f1..52fde2b498ef 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -93,6 +93,7 @@ void mei_cancel_work(struct mei_device *dev) { cancel_work_sync(&dev->init_work); cancel_work_sync(&dev->reset_work); + cancel_work_sync(&dev->bus_rescan_work); cancel_delayed_work(&dev->timer_work); } @@ -394,6 +395,7 @@ void mei_device_init(struct mei_device *dev, INIT_DELAYED_WORK(&dev->timer_work, mei_timer); INIT_WORK(&dev->init_work, mei_host_client_init); INIT_WORK(&dev->reset_work, mei_reset_work); + INIT_WORK(&dev->bus_rescan_work, mei_cl_bus_rescan_work); INIT_LIST_HEAD(&dev->iamthif_cl.link); mei_io_list_init(&dev->amthif_cmd_list); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 320ddae5ee1e..c31adb8a0cff 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -304,6 +304,7 @@ struct mei_hw_ops { /* MEI bus API*/ void mei_cl_bus_rescan(struct mei_device *bus); +void mei_cl_bus_rescan_work(struct work_struct *work); void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bool blocking); @@ -410,6 +411,7 @@ const char *mei_pg_state_str(enum mei_pg_state state); * * @init_work : work item for the device init * @reset_work : work item for the device reset + * @bus_rescan_work : work item for the bus rescan * * @device_list : mei client bus list * @cl_bus_lock : client bus list lock @@ -501,6 +503,7 @@ struct mei_device { struct work_struct init_work; struct work_struct reset_work; + struct work_struct bus_rescan_work; /* List of bus devices */ struct list_head device_list; |