aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2015-07-23 08:08:47 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-03 20:24:48 -0400
commit6009595a66e460af0b170d736398c49395cb4499 (patch)
treef165c655c8584c34feb695d54415f189972f2e76
parentb39910c2e0ac7c3d0e2f1999b04308c771b1d8fc (diff)
mei: bus: link client devices instead of host clients
MEI bus was designed around nfc and was hard to extend. Instead of the hard coded way of adding the devices on the mei bus we scan the whole me client list and create a device for each eligible me client (mei_cl_bus_rescan); currently we support only clients with single connection and fixed address clients. NFC radio name detection is run as a fixup routine The patch replaces handling the device list based on struct me_cl to device list based on me_cl_devices. The creating a connection is pushed from the device creation time to device enablement. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/mei/bus-fixup.c288
-rw-r--r--drivers/misc/mei/bus.c213
-rw-r--r--drivers/misc/mei/client.c9
-rw-r--r--drivers/misc/mei/init.c2
-rw-r--r--drivers/misc/mei/mei_dev.h11
5 files changed, 213 insertions, 310 deletions
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index a4c6719d36b4..3e536ca85f7d 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -30,6 +30,11 @@
30#define MEI_UUID_NFC_INFO UUID_LE(0xd2de1625, 0x382d, 0x417d, \ 30#define MEI_UUID_NFC_INFO UUID_LE(0xd2de1625, 0x382d, 0x417d, \
31 0x48, 0xa4, 0xef, 0xab, 0xba, 0x8a, 0x12, 0x06) 31 0x48, 0xa4, 0xef, 0xab, 0xba, 0x8a, 0x12, 0x06)
32 32
33static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
34
35#define MEI_UUID_NFC_HCI UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, \
36 0x94, 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c)
37
33#define MEI_UUID_ANY NULL_UUID_LE 38#define MEI_UUID_ANY NULL_UUID_LE
34 39
35/** 40/**
@@ -93,68 +98,10 @@ struct mei_nfc_if_version {
93 u8 radio_type; 98 u8 radio_type;
94} __packed; 99} __packed;
95 100
96struct mei_nfc_connect {
97 u8 fw_ivn;
98 u8 vendor_id;
99} __packed;
100
101struct mei_nfc_connect_resp {
102 u8 fw_ivn;
103 u8 vendor_id;
104 u16 me_major;
105 u16 me_minor;
106 u16 me_hotfix;
107 u16 me_build;
108} __packed;
109
110struct mei_nfc_hci_hdr {
111 u8 cmd;
112 u8 status;
113 u16 req_id;
114 u32 reserved;
115 u16 data_size;
116} __packed;
117 101
118#define MEI_NFC_CMD_MAINTENANCE 0x00 102#define MEI_NFC_CMD_MAINTENANCE 0x00
119#define MEI_NFC_CMD_HCI_SEND 0x01
120#define MEI_NFC_CMD_HCI_RECV 0x02
121
122#define MEI_NFC_SUBCMD_CONNECT 0x00
123#define MEI_NFC_SUBCMD_IF_VERSION 0x01 103#define MEI_NFC_SUBCMD_IF_VERSION 0x01
124 104
125#define MEI_NFC_HEADER_SIZE 10
126
127/**
128 * struct mei_nfc_dev - NFC mei device
129 *
130 * @me_cl: NFC me client
131 * @cl: NFC host client
132 * @cl_info: NFC info host client
133 * @init_work: perform connection to the info client
134 * @fw_ivn: NFC Interface Version Number
135 * @vendor_id: NFC manufacturer ID
136 * @radio_type: NFC radio type
137 * @bus_name: bus name
138 *
139 */
140struct mei_nfc_dev {
141 struct mei_me_client *me_cl;
142 struct mei_cl *cl;
143 struct mei_cl *cl_info;
144 struct work_struct init_work;
145 u8 fw_ivn;
146 u8 vendor_id;
147 u8 radio_type;
148 const char *bus_name;
149};
150
151/* UUIDs for NFC F/W clients */
152const uuid_le mei_nfc_guid = UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50,
153 0x94, 0xd4, 0x50, 0x26,
154 0x67, 0x23, 0x77, 0x5c);
155
156static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
157
158/* Vendors */ 105/* Vendors */
159#define MEI_NFC_VENDOR_INSIDE 0x00 106#define MEI_NFC_VENDOR_INSIDE 0x00
160#define MEI_NFC_VENDOR_NXP 0x01 107#define MEI_NFC_VENDOR_NXP 0x01
@@ -163,27 +110,6 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
163#define MEI_NFC_VENDOR_INSIDE_UREAD 0x00 110#define MEI_NFC_VENDOR_INSIDE_UREAD 0x00
164#define MEI_NFC_VENDOR_NXP_PN544 0x01 111#define MEI_NFC_VENDOR_NXP_PN544 0x01
165 112
166static void mei_nfc_free(struct mei_nfc_dev *ndev)
167{
168 if (!ndev)
169 return;
170
171 if (ndev->cl) {
172 list_del(&ndev->cl->device_link);
173 mei_cl_unlink(ndev->cl);
174 kfree(ndev->cl);
175 }
176
177 if (ndev->cl_info) {
178 list_del(&ndev->cl_info->device_link);
179 mei_cl_unlink(ndev->cl_info);
180 kfree(ndev->cl_info);
181 }
182
183 mei_me_cl_put(ndev->me_cl);
184 kfree(ndev);
185}
186
187/** 113/**
188 * mei_nfc_if_version - get NFC interface version 114 * mei_nfc_if_version - get NFC interface version
189 * 115 *
@@ -264,177 +190,86 @@ static const char *mei_nfc_radio_name(struct mei_nfc_if_version *ver)
264 return NULL; 190 return NULL;
265} 191}
266 192
267static void mei_nfc_init(struct work_struct *work) 193/**
194 * mei_nfc - The nfc fixup function. The function retrieves nfc radio
195 * name and set is as device attribute so we can load
196 * the proper device driver for it
197 *
198 * @cldev: me client device (nfc)
199 */
200static void mei_nfc(struct mei_cl_device *cldev)
268{ 201{
269 struct mei_device *bus; 202 struct mei_device *bus;
270 struct mei_cl_device *cldev; 203 struct mei_cl *cl;
271 struct mei_nfc_dev *ndev; 204 struct mei_me_client *me_cl = NULL;
272 struct mei_cl *cl_info; 205 struct mei_nfc_if_version ver;
273 struct mei_me_client *me_cl_info; 206 const char *radio_name = NULL;
274 struct mei_nfc_if_version version; 207 int ret;
275 208
276 ndev = container_of(work, struct mei_nfc_dev, init_work); 209 bus = cldev->bus;
277 210
278 cl_info = ndev->cl_info; 211 dev_dbg(bus->dev, "running hook %s: %pUl match=%d\n",
279 bus = cl_info->dev; 212 __func__, mei_me_cl_uuid(cldev->me_cl), cldev->do_match);
280 213
281 mutex_lock(&bus->device_lock); 214 mutex_lock(&bus->device_lock);
282 215 /* we need to connect to INFO GUID */
283 /* check for valid client id */ 216 cl = mei_cl_alloc_linked(bus, MEI_HOST_CLIENT_ID_ANY);
284 me_cl_info = mei_me_cl_by_uuid(bus, &mei_nfc_info_guid); 217 if (IS_ERR(cl)) {
285 if (!me_cl_info) { 218 ret = PTR_ERR(cl);
286 mutex_unlock(&bus->device_lock); 219 cl = NULL;
287 dev_info(bus->dev, "nfc: failed to find the info client\n"); 220 dev_err(bus->dev, "nfc hook alloc failed %d\n", ret);
288 goto err; 221 goto out;
289 }
290
291 if (mei_cl_connect(cl_info, me_cl_info, NULL) < 0) {
292 mei_me_cl_put(me_cl_info);
293 mutex_unlock(&bus->device_lock);
294 dev_err(bus->dev, "Could not connect to the NFC INFO ME client");
295
296 goto err;
297 } 222 }
298 mei_me_cl_put(me_cl_info);
299 mutex_unlock(&bus->device_lock);
300 223
301 if (mei_nfc_if_version(cl_info, &version) < 0) { 224 me_cl = mei_me_cl_by_uuid(bus, &mei_nfc_info_guid);
302 dev_err(bus->dev, "Could not get the NFC interface version"); 225 if (!me_cl) {
303 226 ret = -ENOTTY;
304 goto err; 227 dev_err(bus->dev, "Cannot find nfc info %d\n", ret);
228 goto out;
305 } 229 }
306 230
307 ndev->fw_ivn = version.fw_ivn; 231 ret = mei_cl_connect(cl, me_cl, NULL);
308 ndev->vendor_id = version.vendor_id; 232 if (ret < 0) {
309 ndev->radio_type = version.radio_type; 233 dev_err(&cldev->dev, "Can't connect to the NFC INFO ME ret = %d\n",
310 234 ret);
311 dev_info(bus->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", 235 goto out;
312 ndev->fw_ivn, ndev->vendor_id, ndev->radio_type);
313
314 mutex_lock(&bus->device_lock);
315
316 if (mei_cl_disconnect(cl_info) < 0) {
317 mutex_unlock(&bus->device_lock);
318 dev_err(bus->dev, "Could not disconnect the NFC INFO ME client");
319
320 goto err;
321 } 236 }
322 237
323 mutex_unlock(&bus->device_lock); 238 mutex_unlock(&bus->device_lock);
324 239
325 ndev->bus_name = mei_nfc_radio_name(&version); 240 ret = mei_nfc_if_version(cl, &ver);
241 if (ret)
242 goto disconnect;
326 243
327 if (!ndev->bus_name) { 244 radio_name = mei_nfc_radio_name(&ver);
328 dev_err(bus->dev, "Could not build the bus ID name\n");
329 return;
330 }
331 245
332 cldev = mei_cl_add_device(bus, ndev->me_cl, ndev->cl, 246 if (!radio_name) {
333 ndev->bus_name); 247 ret = -ENOENT;
334 if (!cldev) { 248 dev_err(&cldev->dev, "Can't get the NFC interface version ret = %d\n",
335 dev_err(bus->dev, "Could not add the NFC device to the MEI bus\n"); 249 ret);
336 250 goto disconnect;
337 goto err;
338 } 251 }
339 252
340 cldev->priv_data = ndev; 253 dev_dbg(bus->dev, "nfc radio %s\n", radio_name);
341 254 strlcpy(cldev->name, radio_name, sizeof(cldev->name));
342
343 return;
344 255
345err: 256disconnect:
346 mutex_lock(&bus->device_lock); 257 mutex_lock(&bus->device_lock);
347 mei_nfc_free(ndev); 258 if (mei_cl_disconnect(cl) < 0)
348 mutex_unlock(&bus->device_lock); 259 dev_err(bus->dev, "Can't disconnect the NFC INFO ME\n");
349 260
350} 261 mei_cl_flush_queues(cl, NULL);
351 262
263out:
264 mei_cl_unlink(cl);
265 mutex_unlock(&bus->device_lock);
266 mei_me_cl_put(me_cl);
267 kfree(cl);
352 268
353int mei_nfc_host_init(struct mei_device *bus, struct mei_me_client *me_cl) 269 if (ret)
354{ 270 cldev->do_match = 0;
355 struct mei_nfc_dev *ndev;
356 struct mei_cl *cl_info, *cl;
357 int ret;
358
359
360 /* in case of internal reset bail out
361 * as the device is already setup
362 */
363 cl = mei_cl_bus_find_cl_by_uuid(bus, mei_nfc_guid);
364 if (cl)
365 return 0;
366
367 ndev = kzalloc(sizeof(struct mei_nfc_dev), GFP_KERNEL);
368 if (!ndev) {
369 ret = -ENOMEM;
370 goto err;
371 }
372
373 ndev->me_cl = mei_me_cl_get(me_cl);
374 if (!ndev->me_cl) {
375 ret = -ENODEV;
376 goto err;
377 }
378
379 cl_info = mei_cl_alloc_linked(bus, MEI_HOST_CLIENT_ID_ANY);
380 if (IS_ERR(cl_info)) {
381 ret = PTR_ERR(cl_info);
382 goto err;
383 }
384
385 list_add_tail(&cl_info->device_link, &bus->device_list);
386
387 ndev->cl_info = cl_info;
388
389 cl = mei_cl_alloc_linked(bus, MEI_HOST_CLIENT_ID_ANY);
390 if (IS_ERR(cl)) {
391 ret = PTR_ERR(cl);
392 goto err;
393 }
394
395 list_add_tail(&cl->device_link, &bus->device_list);
396
397 ndev->cl = cl;
398
399 INIT_WORK(&ndev->init_work, mei_nfc_init);
400 schedule_work(&ndev->init_work);
401
402 return 0;
403
404err:
405 mei_nfc_free(ndev);
406
407 return ret;
408}
409
410void mei_nfc_host_exit(struct mei_device *bus)
411{
412 struct mei_nfc_dev *ndev;
413 struct mei_cl *cl;
414 struct mei_cl_device *cldev;
415
416 cl = mei_cl_bus_find_cl_by_uuid(bus, mei_nfc_guid);
417 if (!cl)
418 return;
419
420 cldev = cl->cldev;
421 if (!cldev)
422 return;
423
424 ndev = (struct mei_nfc_dev *)cldev->priv_data;
425 if (ndev)
426 cancel_work_sync(&ndev->init_work);
427
428 cldev->priv_data = NULL;
429
430 /* Need to remove the device here
431 * since mei_nfc_free will unlink the clients
432 */
433 mei_cl_remove_device(cldev);
434 271
435 mutex_lock(&bus->device_lock); 272 dev_dbg(bus->dev, "end of fixup match = %d\n", cldev->do_match);
436 mei_nfc_free(ndev);
437 mutex_unlock(&bus->device_lock);
438} 273}
439 274
440#define MEI_FIXUP(_uuid, _hook) { _uuid, _hook } 275#define MEI_FIXUP(_uuid, _hook) { _uuid, _hook }
@@ -446,6 +281,7 @@ static struct mei_fixup {
446} mei_fixups[] = { 281} mei_fixups[] = {
447 MEI_FIXUP(MEI_UUID_ANY, number_of_connections), 282 MEI_FIXUP(MEI_UUID_ANY, number_of_connections),
448 MEI_FIXUP(MEI_UUID_NFC_INFO, blacklist), 283 MEI_FIXUP(MEI_UUID_NFC_INFO, blacklist),
284 MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
449}; 285};
450 286
451/** 287/**
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 7e51700515f4..3ab08e522fb8 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -309,34 +309,43 @@ EXPORT_SYMBOL_GPL(mei_cl_set_drvdata);
309 */ 309 */
310int mei_cl_enable_device(struct mei_cl_device *cldev) 310int mei_cl_enable_device(struct mei_cl_device *cldev)
311{ 311{
312 int err; 312 struct mei_device *bus = cldev->bus;
313 struct mei_device *bus; 313 struct mei_cl *cl;
314 struct mei_cl *cl = cldev->cl; 314 int ret;
315 315
316 if (cl == NULL) 316 cl = cldev->cl;
317 return -ENODEV;
318 317
319 bus = cl->dev; 318 if (!cl) {
319 mutex_lock(&bus->device_lock);
320 cl = mei_cl_alloc_linked(bus, MEI_HOST_CLIENT_ID_ANY);
321 mutex_unlock(&bus->device_lock);
322 if (IS_ERR(cl))
323 return PTR_ERR(cl);
324 /* update pointers */
325 cldev->cl = cl;
326 cl->cldev = cldev;
327 }
320 328
321 mutex_lock(&bus->device_lock); 329 mutex_lock(&bus->device_lock);
322
323 if (mei_cl_is_connected(cl)) { 330 if (mei_cl_is_connected(cl)) {
324 mutex_unlock(&bus->device_lock); 331 ret = 0;
325 dev_warn(bus->dev, "Already connected"); 332 goto out;
326 return -EBUSY;
327 } 333 }
328 334
329 err = mei_cl_connect(cl, cldev->me_cl, NULL); 335 if (!mei_me_cl_is_active(cldev->me_cl)) {
330 if (err < 0) { 336 dev_err(&cldev->dev, "me client is not active\n");
331 mutex_unlock(&bus->device_lock); 337 ret = -ENOTTY;
332 dev_err(bus->dev, "Could not connect to the ME client"); 338 goto out;
333
334 return err;
335 } 339 }
336 340
341 ret = mei_cl_connect(cl, cldev->me_cl, NULL);
342 if (ret < 0)
343 dev_err(&cldev->dev, "cannot connect\n");
344
345out:
337 mutex_unlock(&bus->device_lock); 346 mutex_unlock(&bus->device_lock);
338 347
339 return 0; 348 return ret;
340} 349}
341EXPORT_SYMBOL_GPL(mei_cl_enable_device); 350EXPORT_SYMBOL_GPL(mei_cl_enable_device);
342 351
@@ -350,14 +359,16 @@ EXPORT_SYMBOL_GPL(mei_cl_enable_device);
350 */ 359 */
351int mei_cl_disable_device(struct mei_cl_device *cldev) 360int mei_cl_disable_device(struct mei_cl_device *cldev)
352{ 361{
353 int err;
354 struct mei_device *bus; 362 struct mei_device *bus;
355 struct mei_cl *cl = cldev->cl; 363 struct mei_cl *cl;
364 int err;
356 365
357 if (cl == NULL) 366 if (!cldev || !cldev->cl)
358 return -ENODEV; 367 return -ENODEV;
359 368
360 bus = cl->dev; 369 cl = cldev->cl;
370
371 bus = cldev->bus;
361 372
362 cldev->event_cb = NULL; 373 cldev->event_cb = NULL;
363 374
@@ -370,18 +381,19 @@ int mei_cl_disable_device(struct mei_cl_device *cldev)
370 } 381 }
371 382
372 err = mei_cl_disconnect(cl); 383 err = mei_cl_disconnect(cl);
373 if (err < 0) { 384 if (err < 0)
374 dev_err(bus->dev, "Could not disconnect from the ME client"); 385 dev_err(bus->dev, "Could not disconnect from the ME client");
375 goto out;
376 }
377 386
387out:
378 /* Flush queues and remove any pending read */ 388 /* Flush queues and remove any pending read */
379 mei_cl_flush_queues(cl, NULL); 389 mei_cl_flush_queues(cl, NULL);
390 mei_cl_unlink(cl);
391
392 kfree(cl);
393 cldev->cl = NULL;
380 394
381out:
382 mutex_unlock(&bus->device_lock); 395 mutex_unlock(&bus->device_lock);
383 return err; 396 return err;
384
385} 397}
386EXPORT_SYMBOL_GPL(mei_cl_disable_device); 398EXPORT_SYMBOL_GPL(mei_cl_disable_device);
387 399
@@ -623,20 +635,6 @@ static struct device_type mei_cl_device_type = {
623 .release = mei_cl_dev_release, 635 .release = mei_cl_dev_release,
624}; 636};
625 637
626struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *bus,
627 uuid_le uuid)
628{
629 struct mei_cl *cl;
630
631 list_for_each_entry(cl, &bus->device_list, device_link) {
632 if (cl->cldev && cl->cldev->me_cl &&
633 !uuid_le_cmp(uuid, *mei_me_cl_uuid(cl->cldev->me_cl)))
634 return cl;
635 }
636
637 return NULL;
638}
639
640/** 638/**
641 * mei_cl_dev_alloc - initialize and allocate mei client device 639 * mei_cl_dev_alloc - initialize and allocate mei client device
642 * 640 *
@@ -707,45 +705,127 @@ static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
707 return ret; 705 return ret;
708} 706}
709 707
710struct mei_cl_device *mei_cl_add_device(struct mei_device *bus, 708/**
711 struct mei_me_client *me_cl, 709 * mei_cl_bus_dev_stop - stop the driver
712 struct mei_cl *cl, 710 *
713 const char *name) 711 * @cldev: me client device
712 */
713static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
714{
715 if (cldev->is_added)
716 device_release_driver(&cldev->dev);
717}
718
719/**
720 * mei_cl_bus_dev_destroy - destroy me client devices object
721 *
722 * @cldev: me client device
723 */
724static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
725{
726 if (!cldev->is_added)
727 return;
728
729 device_del(&cldev->dev);
730
731 mutex_lock(&cldev->bus->cl_bus_lock);
732 list_del_init(&cldev->bus_list);
733 mutex_unlock(&cldev->bus->cl_bus_lock);
734
735 cldev->is_added = 0;
736 put_device(&cldev->dev);
737}
738
739/**
740 * mei_cl_bus_remove_device - remove a devices form the bus
741 *
742 * @cldev: me client device
743 */
744static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
745{
746 mei_cl_bus_dev_stop(cldev);
747 mei_cl_bus_dev_destroy(cldev);
748}
749
750/**
751 * mei_cl_bus_remove_devices - remove all devices form the bus
752 *
753 * @bus: mei device
754 */
755void mei_cl_bus_remove_devices(struct mei_device *bus)
756{
757 struct mei_cl_device *cldev, *next;
758
759 list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
760 mei_cl_bus_remove_device(cldev);
761}
762
763
764/**
765 * mei_cl_dev_init - allocate and initializes an mei client devices
766 * based on me client
767 *
768 * @bus: mei device
769 * @me_cl: me client
770 */
771static void mei_cl_dev_init(struct mei_device *bus, struct mei_me_client *me_cl)
714{ 772{
715 struct mei_cl_device *cldev; 773 struct mei_cl_device *cldev;
716 int status; 774
775 dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));
776
777 if (me_cl->bus_added)
778 return;
717 779
718 cldev = mei_cl_dev_alloc(bus, me_cl); 780 cldev = mei_cl_dev_alloc(bus, me_cl);
719 if (!cldev) 781 if (!cldev)
720 return NULL; 782 return;
721 783
722 cldev->cl = cl; 784 mutex_lock(&cldev->bus->cl_bus_lock);
723 strlcpy(cldev->name, name, sizeof(cldev->name)); 785 me_cl->bus_added = true;
786 list_add_tail(&cldev->bus_list, &bus->device_list);
787 mutex_unlock(&cldev->bus->cl_bus_lock);
724 788
725 mei_cl_dev_setup(bus, cldev); 789}
726 790
727 status = mei_cl_bus_dev_add(cldev); 791/**
728 if (status) { 792 * mei_cl_bus_rescan - scan me clients list and add create
729 dev_err(bus->dev, "Failed to register MEI device\n"); 793 * devices for eligible clients
730 mei_me_cl_put(cldev->me_cl); 794 *
731 mei_dev_bus_put(bus); 795 * @bus: mei device
732 kfree(cldev); 796 */
733 return NULL; 797void mei_cl_bus_rescan(struct mei_device *bus)
734 } 798{
799 struct mei_cl_device *cldev, *n;
800 struct mei_me_client *me_cl;
735 801
736 cl->cldev = cldev; 802 down_read(&bus->me_clients_rwsem);
803 list_for_each_entry(me_cl, &bus->me_clients, list)
804 mei_cl_dev_init(bus, me_cl);
805 up_read(&bus->me_clients_rwsem);
737 806
738 dev_dbg(&cldev->dev, "client %s registered\n", name); 807 mutex_lock(&bus->cl_bus_lock);
808 list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
739 809
740 return cldev; 810 if (!mei_me_cl_is_active(cldev->me_cl)) {
741} 811 mei_cl_bus_remove_device(cldev);
742EXPORT_SYMBOL_GPL(mei_cl_add_device); 812 continue;
813 }
743 814
744void mei_cl_remove_device(struct mei_cl_device *cldev) 815 if (cldev->is_added)
745{ 816 continue;
746 device_unregister(&cldev->dev); 817
818 if (mei_cl_dev_setup(bus, cldev))
819 mei_cl_bus_dev_add(cldev);
820 else {
821 list_del_init(&cldev->bus_list);
822 put_device(&cldev->dev);
823 }
824 }
825 mutex_unlock(&bus->cl_bus_lock);
826
827 dev_dbg(bus->dev, "rescan end");
747} 828}
748EXPORT_SYMBOL_GPL(mei_cl_remove_device);
749 829
750int __mei_cl_driver_register(struct mei_cl_driver *cldrv, struct module *owner) 830int __mei_cl_driver_register(struct mei_cl_driver *cldrv, struct module *owner)
751{ 831{
@@ -773,6 +853,7 @@ void mei_cl_driver_unregister(struct mei_cl_driver *cldrv)
773} 853}
774EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); 854EXPORT_SYMBOL_GPL(mei_cl_driver_unregister);
775 855
856
776int __init mei_cl_bus_init(void) 857int __init mei_cl_bus_init(void)
777{ 858{
778 return bus_register(&mei_cl_bus_type); 859 return bus_register(&mei_cl_bus_type);
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 1987a201c7f3..9dacea7a9a60 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -558,7 +558,6 @@ void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
558 INIT_LIST_HEAD(&cl->rd_completed); 558 INIT_LIST_HEAD(&cl->rd_completed);
559 INIT_LIST_HEAD(&cl->rd_pending); 559 INIT_LIST_HEAD(&cl->rd_pending);
560 INIT_LIST_HEAD(&cl->link); 560 INIT_LIST_HEAD(&cl->link);
561 INIT_LIST_HEAD(&cl->device_link);
562 cl->writing_state = MEI_IDLE; 561 cl->writing_state = MEI_IDLE;
563 cl->state = MEI_FILE_INITIALIZING; 562 cl->state = MEI_FILE_INITIALIZING;
564 cl->dev = dev; 563 cl->dev = dev;
@@ -690,16 +689,12 @@ void mei_host_client_init(struct work_struct *work)
690 mei_wd_host_init(dev, me_cl); 689 mei_wd_host_init(dev, me_cl);
691 mei_me_cl_put(me_cl); 690 mei_me_cl_put(me_cl);
692 691
693 me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid);
694 if (me_cl)
695 mei_nfc_host_init(dev, me_cl);
696 mei_me_cl_put(me_cl);
697
698
699 dev->dev_state = MEI_DEV_ENABLED; 692 dev->dev_state = MEI_DEV_ENABLED;
700 dev->reset_count = 0; 693 dev->reset_count = 0;
701 mutex_unlock(&dev->device_lock); 694 mutex_unlock(&dev->device_lock);
702 695
696 mei_cl_bus_rescan(dev);
697
703 pm_runtime_mark_last_busy(dev->dev); 698 pm_runtime_mark_last_busy(dev->dev);
704 dev_dbg(dev->dev, "rpm: autosuspend\n"); 699 dev_dbg(dev->dev, "rpm: autosuspend\n");
705 pm_runtime_autosuspend(dev->dev); 700 pm_runtime_autosuspend(dev->dev);
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 15000e9231b1..e374661652cd 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -331,7 +331,7 @@ void mei_stop(struct mei_device *dev)
331 331
332 mei_cancel_work(dev); 332 mei_cancel_work(dev);
333 333
334 mei_nfc_host_exit(dev); 334 mei_cl_bus_remove_devices(dev);
335 335
336 mutex_lock(&dev->device_lock); 336 mutex_lock(&dev->device_lock);
337 337
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 7098dcaccc96..71c55f4cabb4 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -241,7 +241,6 @@ struct mei_cl_cb {
241 * @rd_completed: completed read 241 * @rd_completed: completed read
242 * 242 *
243 * @cldev: device on the mei client bus 243 * @cldev: device on the mei client bus
244 * @device_link: link to bus clients
245 */ 244 */
246struct mei_cl { 245struct mei_cl {
247 struct list_head link; 246 struct list_head link;
@@ -260,9 +259,7 @@ struct mei_cl {
260 struct list_head rd_pending; 259 struct list_head rd_pending;
261 struct list_head rd_completed; 260 struct list_head rd_completed;
262 261
263 /* MEI CL bus data */
264 struct mei_cl_device *cldev; 262 struct mei_cl_device *cldev;
265 struct list_head device_link;
266}; 263};
267 264
268/** struct mei_hw_ops 265/** struct mei_hw_ops
@@ -329,12 +326,7 @@ struct mei_hw_ops {
329}; 326};
330 327
331/* MEI bus API*/ 328/* MEI bus API*/
332 329void mei_cl_bus_rescan(struct mei_device *bus);
333struct mei_cl_device *mei_cl_add_device(struct mei_device *bus,
334 struct mei_me_client *me_cl,
335 struct mei_cl *cl,
336 const char *name);
337void mei_cl_remove_device(struct mei_cl_device *cldev);
338void mei_cl_dev_fixup(struct mei_cl_device *dev); 330void mei_cl_dev_fixup(struct mei_cl_device *dev);
339ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 331ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
340 bool blocking); 332 bool blocking);
@@ -343,7 +335,6 @@ void mei_cl_bus_rx_event(struct mei_cl *cl);
343void mei_cl_bus_remove_devices(struct mei_device *bus); 335void mei_cl_bus_remove_devices(struct mei_device *bus);
344int mei_cl_bus_init(void); 336int mei_cl_bus_init(void);
345void mei_cl_bus_exit(void); 337void mei_cl_bus_exit(void);
346struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *bus, uuid_le uuid);
347 338
348/** 339/**
349 * enum mei_pg_event - power gating transition events 340 * enum mei_pg_event - power gating transition events