Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ISHTP bus driver
0004  *
0005  * Copyright (c) 2012-2016, Intel Corporation.
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/device.h>
0012 #include <linux/sched.h>
0013 #include <linux/slab.h>
0014 #include "bus.h"
0015 #include "ishtp-dev.h"
0016 #include "client.h"
0017 #include "hbm.h"
0018 
0019 static int ishtp_use_dma;
0020 module_param_named(ishtp_use_dma, ishtp_use_dma, int, 0600);
0021 MODULE_PARM_DESC(ishtp_use_dma, "Use DMA to send messages");
0022 
0023 #define to_ishtp_cl_driver(d) container_of(d, struct ishtp_cl_driver, driver)
0024 #define to_ishtp_cl_device(d) container_of(d, struct ishtp_cl_device, dev)
0025 static bool ishtp_device_ready;
0026 
0027 /**
0028  * ishtp_recv() - process ishtp message
0029  * @dev: ishtp device
0030  *
0031  * If a message with valid header and size is received, then
0032  * this function calls appropriate handler. The host or firmware
0033  * address is zero, then they are host bus management message,
0034  * otherwise they are message fo clients.
0035  */
0036 void ishtp_recv(struct ishtp_device *dev)
0037 {
0038     uint32_t    msg_hdr;
0039     struct ishtp_msg_hdr    *ishtp_hdr;
0040 
0041     /* Read ISHTP header dword */
0042     msg_hdr = dev->ops->ishtp_read_hdr(dev);
0043     if (!msg_hdr)
0044         return;
0045 
0046     dev->ops->sync_fw_clock(dev);
0047 
0048     ishtp_hdr = (struct ishtp_msg_hdr *)&msg_hdr;
0049     dev->ishtp_msg_hdr = msg_hdr;
0050 
0051     /* Sanity check: ISHTP frag. length in header */
0052     if (ishtp_hdr->length > dev->mtu) {
0053         dev_err(dev->devc,
0054             "ISHTP hdr - bad length: %u; dropped [%08X]\n",
0055             (unsigned int)ishtp_hdr->length, msg_hdr);
0056         return;
0057     }
0058 
0059     /* ISHTP bus message */
0060     if (!ishtp_hdr->host_addr && !ishtp_hdr->fw_addr)
0061         recv_hbm(dev, ishtp_hdr);
0062     /* ISHTP fixed-client message */
0063     else if (!ishtp_hdr->host_addr)
0064         recv_fixed_cl_msg(dev, ishtp_hdr);
0065     else
0066         /* ISHTP client message */
0067         recv_ishtp_cl_msg(dev, ishtp_hdr);
0068 }
0069 EXPORT_SYMBOL(ishtp_recv);
0070 
0071 /**
0072  * ishtp_send_msg() - Send ishtp message
0073  * @dev: ishtp device
0074  * @hdr: Message header
0075  * @msg: Message contents
0076  * @ipc_send_compl: completion callback
0077  * @ipc_send_compl_prm: completion callback parameter
0078  *
0079  * Send a multi fragment message via IPC. After sending the first fragment
0080  * the completion callback is called to schedule transmit of next fragment.
0081  *
0082  * Return: This returns IPC send message status.
0083  */
0084 int ishtp_send_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
0085                void *msg, void(*ipc_send_compl)(void *),
0086                void *ipc_send_compl_prm)
0087 {
0088     unsigned char   ipc_msg[IPC_FULL_MSG_SIZE];
0089     uint32_t    drbl_val;
0090 
0091     drbl_val = dev->ops->ipc_get_header(dev, hdr->length +
0092                         sizeof(struct ishtp_msg_hdr),
0093                         1);
0094 
0095     memcpy(ipc_msg, &drbl_val, sizeof(uint32_t));
0096     memcpy(ipc_msg + sizeof(uint32_t), hdr, sizeof(uint32_t));
0097     memcpy(ipc_msg + 2 * sizeof(uint32_t), msg, hdr->length);
0098     return  dev->ops->write(dev, ipc_send_compl, ipc_send_compl_prm,
0099                 ipc_msg, 2 * sizeof(uint32_t) + hdr->length);
0100 }
0101 
0102 /**
0103  * ishtp_write_message() - Send ishtp single fragment message
0104  * @dev: ishtp device
0105  * @hdr: Message header
0106  * @buf: message data
0107  *
0108  * Send a single fragment message via IPC.  This returns IPC send message
0109  * status.
0110  *
0111  * Return: This returns IPC send message status.
0112  */
0113 int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
0114             void *buf)
0115 {
0116     return ishtp_send_msg(dev, hdr, buf, NULL, NULL);
0117 }
0118 
0119 /**
0120  * ishtp_fw_cl_by_uuid() - locate index of fw client
0121  * @dev: ishtp device
0122  * @uuid: uuid of the client to search
0123  *
0124  * Search firmware client using UUID.
0125  *
0126  * Return: fw client index or -ENOENT if not found
0127  */
0128 int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const guid_t *uuid)
0129 {
0130     unsigned int i;
0131 
0132     for (i = 0; i < dev->fw_clients_num; ++i) {
0133         if (guid_equal(uuid, &dev->fw_clients[i].props.protocol_name))
0134             return i;
0135     }
0136     return -ENOENT;
0137 }
0138 EXPORT_SYMBOL(ishtp_fw_cl_by_uuid);
0139 
0140 /**
0141  * ishtp_fw_cl_get_client() - return client information to client
0142  * @dev: the ishtp device structure
0143  * @uuid: uuid of the client to search
0144  *
0145  * Search firmware client using UUID and reture related client information.
0146  *
0147  * Return: pointer of client information on success, NULL on failure.
0148  */
0149 struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
0150                            const guid_t *uuid)
0151 {
0152     int i;
0153     unsigned long flags;
0154 
0155     spin_lock_irqsave(&dev->fw_clients_lock, flags);
0156     i = ishtp_fw_cl_by_uuid(dev, uuid);
0157     spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
0158     if (i < 0 || dev->fw_clients[i].props.fixed_address)
0159         return NULL;
0160 
0161     return &dev->fw_clients[i];
0162 }
0163 EXPORT_SYMBOL(ishtp_fw_cl_get_client);
0164 
0165 /**
0166  * ishtp_get_fw_client_id() - Get fw client id
0167  * @fw_client:  firmware client used to fetch the ID
0168  *
0169  * This interface is used to reset HW get FW client id.
0170  *
0171  * Return: firmware client id.
0172  */
0173 int ishtp_get_fw_client_id(struct ishtp_fw_client *fw_client)
0174 {
0175     return fw_client->client_id;
0176 }
0177 EXPORT_SYMBOL(ishtp_get_fw_client_id);
0178 
0179 /**
0180  * ishtp_fw_cl_by_id() - return index to fw_clients for client_id
0181  * @dev: the ishtp device structure
0182  * @client_id: fw client id to search
0183  *
0184  * Search firmware client using client id.
0185  *
0186  * Return: index on success, -ENOENT on failure.
0187  */
0188 int ishtp_fw_cl_by_id(struct ishtp_device *dev, uint8_t client_id)
0189 {
0190     int i, res = -ENOENT;
0191     unsigned long   flags;
0192 
0193     spin_lock_irqsave(&dev->fw_clients_lock, flags);
0194     for (i = 0; i < dev->fw_clients_num; i++) {
0195         if (dev->fw_clients[i].client_id == client_id) {
0196             res = i;
0197             break;
0198         }
0199     }
0200     spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
0201 
0202     return res;
0203 }
0204 
0205 /**
0206  * ishtp_cl_device_probe() - Bus probe() callback
0207  * @dev: the device structure
0208  *
0209  * This is a bus probe callback and calls the drive probe function.
0210  *
0211  * Return: Return value from driver probe() call.
0212  */
0213 static int ishtp_cl_device_probe(struct device *dev)
0214 {
0215     struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0216     struct ishtp_cl_driver *driver;
0217 
0218     if (!device)
0219         return 0;
0220 
0221     driver = to_ishtp_cl_driver(dev->driver);
0222     if (!driver || !driver->probe)
0223         return -ENODEV;
0224 
0225     return driver->probe(device);
0226 }
0227 
0228 /**
0229  * ishtp_cl_bus_match() - Bus match() callback
0230  * @dev: the device structure
0231  * @drv: the driver structure
0232  *
0233  * This is a bus match callback, called when a new ishtp_cl_device is
0234  * registered during ishtp bus client enumeration. Use the guid_t in
0235  * drv and dev to decide whether they match or not.
0236  *
0237  * Return: 1 if dev & drv matches, 0 otherwise.
0238  */
0239 static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
0240 {
0241     struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0242     struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
0243 
0244     return guid_equal(&driver->id[0].guid,
0245               &device->fw_client->props.protocol_name);
0246 }
0247 
0248 /**
0249  * ishtp_cl_device_remove() - Bus remove() callback
0250  * @dev: the device structure
0251  *
0252  * This is a bus remove callback and calls the drive remove function.
0253  * Since the ISH driver model supports only built in, this is
0254  * primarily can be called during pci driver init failure.
0255  *
0256  * Return: Return value from driver remove() call.
0257  */
0258 static void ishtp_cl_device_remove(struct device *dev)
0259 {
0260     struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0261     struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver);
0262 
0263     if (device->event_cb) {
0264         device->event_cb = NULL;
0265         cancel_work_sync(&device->event_work);
0266     }
0267 
0268     if (driver->remove)
0269         driver->remove(device);
0270 }
0271 
0272 /**
0273  * ishtp_cl_device_suspend() - Bus suspend callback
0274  * @dev:    device
0275  *
0276  * Called during device suspend process.
0277  *
0278  * Return: Return value from driver suspend() call.
0279  */
0280 static int ishtp_cl_device_suspend(struct device *dev)
0281 {
0282     struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0283     struct ishtp_cl_driver *driver;
0284     int ret = 0;
0285 
0286     if (!device)
0287         return 0;
0288 
0289     driver = to_ishtp_cl_driver(dev->driver);
0290     if (driver && driver->driver.pm) {
0291         if (driver->driver.pm->suspend)
0292             ret = driver->driver.pm->suspend(dev);
0293     }
0294 
0295     return ret;
0296 }
0297 
0298 /**
0299  * ishtp_cl_device_resume() - Bus resume callback
0300  * @dev:    device
0301  *
0302  * Called during device resume process.
0303  *
0304  * Return: Return value from driver resume() call.
0305  */
0306 static int ishtp_cl_device_resume(struct device *dev)
0307 {
0308     struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0309     struct ishtp_cl_driver *driver;
0310     int ret = 0;
0311 
0312     if (!device)
0313         return 0;
0314 
0315     driver = to_ishtp_cl_driver(dev->driver);
0316     if (driver && driver->driver.pm) {
0317         if (driver->driver.pm->resume)
0318             ret = driver->driver.pm->resume(dev);
0319     }
0320 
0321     return ret;
0322 }
0323 
0324 /**
0325  * ishtp_cl_device_reset() - Reset callback
0326  * @device: ishtp client device instance
0327  *
0328  * This is a callback when HW reset is done and the device need
0329  * reinit.
0330  *
0331  * Return: Return value from driver reset() call.
0332  */
0333 static int ishtp_cl_device_reset(struct ishtp_cl_device *device)
0334 {
0335     struct ishtp_cl_driver *driver;
0336     int ret = 0;
0337 
0338     device->event_cb = NULL;
0339     cancel_work_sync(&device->event_work);
0340 
0341     driver = to_ishtp_cl_driver(device->dev.driver);
0342     if (driver && driver->reset)
0343         ret = driver->reset(device);
0344 
0345     return ret;
0346 }
0347 
0348 static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
0349     char *buf)
0350 {
0351     int len;
0352 
0353     len = snprintf(buf, PAGE_SIZE, ISHTP_MODULE_PREFIX "%s\n", dev_name(dev));
0354     return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
0355 }
0356 static DEVICE_ATTR_RO(modalias);
0357 
0358 static struct attribute *ishtp_cl_dev_attrs[] = {
0359     &dev_attr_modalias.attr,
0360     NULL,
0361 };
0362 ATTRIBUTE_GROUPS(ishtp_cl_dev);
0363 
0364 static int ishtp_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
0365 {
0366     if (add_uevent_var(env, "MODALIAS=" ISHTP_MODULE_PREFIX "%s", dev_name(dev)))
0367         return -ENOMEM;
0368     return 0;
0369 }
0370 
0371 static const struct dev_pm_ops ishtp_cl_bus_dev_pm_ops = {
0372     /* Suspend callbacks */
0373     .suspend = ishtp_cl_device_suspend,
0374     .resume = ishtp_cl_device_resume,
0375     /* Hibernate callbacks */
0376     .freeze = ishtp_cl_device_suspend,
0377     .thaw = ishtp_cl_device_resume,
0378     .restore = ishtp_cl_device_resume,
0379 };
0380 
0381 static struct bus_type ishtp_cl_bus_type = {
0382     .name       = "ishtp",
0383     .dev_groups = ishtp_cl_dev_groups,
0384     .probe      = ishtp_cl_device_probe,
0385     .match      = ishtp_cl_bus_match,
0386     .remove     = ishtp_cl_device_remove,
0387     .pm     = &ishtp_cl_bus_dev_pm_ops,
0388     .uevent     = ishtp_cl_uevent,
0389 };
0390 
0391 static void ishtp_cl_dev_release(struct device *dev)
0392 {
0393     kfree(to_ishtp_cl_device(dev));
0394 }
0395 
0396 static const struct device_type ishtp_cl_device_type = {
0397     .release    = ishtp_cl_dev_release,
0398 };
0399 
0400 /**
0401  * ishtp_bus_add_device() - Function to create device on bus
0402  * @dev:    ishtp device
0403  * @uuid:   uuid of the client
0404  * @name:   Name of the client
0405  *
0406  * Allocate ISHTP bus client device, attach it to uuid
0407  * and register with ISHTP bus.
0408  *
0409  * Return: ishtp_cl_device pointer or NULL on failure
0410  */
0411 static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev,
0412                             guid_t uuid, char *name)
0413 {
0414     struct ishtp_cl_device *device;
0415     int status;
0416     unsigned long flags;
0417 
0418     spin_lock_irqsave(&dev->device_list_lock, flags);
0419     list_for_each_entry(device, &dev->device_list, device_link) {
0420         if (!strcmp(name, dev_name(&device->dev))) {
0421             device->fw_client = &dev->fw_clients[
0422                 dev->fw_client_presentation_num - 1];
0423             spin_unlock_irqrestore(&dev->device_list_lock, flags);
0424             ishtp_cl_device_reset(device);
0425             return device;
0426         }
0427     }
0428     spin_unlock_irqrestore(&dev->device_list_lock, flags);
0429 
0430     device = kzalloc(sizeof(struct ishtp_cl_device), GFP_KERNEL);
0431     if (!device)
0432         return NULL;
0433 
0434     device->dev.parent = dev->devc;
0435     device->dev.bus = &ishtp_cl_bus_type;
0436     device->dev.type = &ishtp_cl_device_type;
0437     device->ishtp_dev = dev;
0438 
0439     device->fw_client =
0440         &dev->fw_clients[dev->fw_client_presentation_num - 1];
0441 
0442     dev_set_name(&device->dev, "%s", name);
0443 
0444     spin_lock_irqsave(&dev->device_list_lock, flags);
0445     list_add_tail(&device->device_link, &dev->device_list);
0446     spin_unlock_irqrestore(&dev->device_list_lock, flags);
0447 
0448     status = device_register(&device->dev);
0449     if (status) {
0450         spin_lock_irqsave(&dev->device_list_lock, flags);
0451         list_del(&device->device_link);
0452         spin_unlock_irqrestore(&dev->device_list_lock, flags);
0453         dev_err(dev->devc, "Failed to register ISHTP client device\n");
0454         put_device(&device->dev);
0455         return NULL;
0456     }
0457 
0458     ishtp_device_ready = true;
0459 
0460     return device;
0461 }
0462 
0463 /**
0464  * ishtp_bus_remove_device() - Function to relase device on bus
0465  * @device: client device instance
0466  *
0467  * This is a counterpart of ishtp_bus_add_device.
0468  * Device is unregistered.
0469  * the device structure is freed in 'ishtp_cl_dev_release' function
0470  * Called only during error in pci driver init path.
0471  */
0472 static void ishtp_bus_remove_device(struct ishtp_cl_device *device)
0473 {
0474     device_unregister(&device->dev);
0475 }
0476 
0477 /**
0478  * ishtp_cl_driver_register() - Client driver register
0479  * @driver: the client driver instance
0480  * @owner:  Owner of this driver module
0481  *
0482  * Once a client driver is probed, it created a client
0483  * instance and registers with the bus.
0484  *
0485  * Return: Return value of driver_register or -ENODEV if not ready
0486  */
0487 int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
0488                  struct module *owner)
0489 {
0490     if (!ishtp_device_ready)
0491         return -ENODEV;
0492 
0493     driver->driver.name = driver->name;
0494     driver->driver.owner = owner;
0495     driver->driver.bus = &ishtp_cl_bus_type;
0496 
0497     return driver_register(&driver->driver);
0498 }
0499 EXPORT_SYMBOL(ishtp_cl_driver_register);
0500 
0501 /**
0502  * ishtp_cl_driver_unregister() - Client driver unregister
0503  * @driver: the client driver instance
0504  *
0505  * Unregister client during device removal process.
0506  */
0507 void ishtp_cl_driver_unregister(struct ishtp_cl_driver *driver)
0508 {
0509     driver_unregister(&driver->driver);
0510 }
0511 EXPORT_SYMBOL(ishtp_cl_driver_unregister);
0512 
0513 /**
0514  * ishtp_bus_event_work() - event work function
0515  * @work:   work struct pointer
0516  *
0517  * Once an event is received for a client this work
0518  * function is called. If the device has registered a
0519  * callback then the callback is called.
0520  */
0521 static void ishtp_bus_event_work(struct work_struct *work)
0522 {
0523     struct ishtp_cl_device *device;
0524 
0525     device = container_of(work, struct ishtp_cl_device, event_work);
0526 
0527     if (device->event_cb)
0528         device->event_cb(device);
0529 }
0530 
0531 /**
0532  * ishtp_cl_bus_rx_event() - schedule event work
0533  * @device: client device instance
0534  *
0535  * Once an event is received for a client this schedules
0536  * a work function to process.
0537  */
0538 void ishtp_cl_bus_rx_event(struct ishtp_cl_device *device)
0539 {
0540     if (!device || !device->event_cb)
0541         return;
0542 
0543     if (device->event_cb)
0544         schedule_work(&device->event_work);
0545 }
0546 
0547 /**
0548  * ishtp_register_event_cb() - Register callback
0549  * @device: client device instance
0550  * @event_cb:   Event processor for an client
0551  *
0552  * Register a callback for events, called from client driver
0553  *
0554  * Return: Return 0 or -EALREADY if already registered
0555  */
0556 int ishtp_register_event_cb(struct ishtp_cl_device *device,
0557     void (*event_cb)(struct ishtp_cl_device *))
0558 {
0559     if (device->event_cb)
0560         return -EALREADY;
0561 
0562     device->event_cb = event_cb;
0563     INIT_WORK(&device->event_work, ishtp_bus_event_work);
0564 
0565     return 0;
0566 }
0567 EXPORT_SYMBOL(ishtp_register_event_cb);
0568 
0569 /**
0570  * ishtp_get_device() - update usage count for the device
0571  * @cl_device:  client device instance
0572  *
0573  * Increment the usage count. The device can't be deleted
0574  */
0575 void ishtp_get_device(struct ishtp_cl_device *cl_device)
0576 {
0577     cl_device->reference_count++;
0578 }
0579 EXPORT_SYMBOL(ishtp_get_device);
0580 
0581 /**
0582  * ishtp_put_device() - decrement usage count for the device
0583  * @cl_device:  client device instance
0584  *
0585  * Decrement the usage count. The device can be deleted is count = 0
0586  */
0587 void ishtp_put_device(struct ishtp_cl_device *cl_device)
0588 {
0589     cl_device->reference_count--;
0590 }
0591 EXPORT_SYMBOL(ishtp_put_device);
0592 
0593 /**
0594  * ishtp_set_drvdata() - set client driver data
0595  * @cl_device:  client device instance
0596  * @data:   driver data need to be set
0597  *
0598  * Set client driver data to cl_device->driver_data.
0599  */
0600 void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data)
0601 {
0602     cl_device->driver_data = data;
0603 }
0604 EXPORT_SYMBOL(ishtp_set_drvdata);
0605 
0606 /**
0607  * ishtp_get_drvdata() - get client driver data
0608  * @cl_device:  client device instance
0609  *
0610  * Get client driver data from cl_device->driver_data.
0611  *
0612  * Return: pointer of driver data
0613  */
0614 void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device)
0615 {
0616     return cl_device->driver_data;
0617 }
0618 EXPORT_SYMBOL(ishtp_get_drvdata);
0619 
0620 /**
0621  * ishtp_dev_to_cl_device() - get ishtp_cl_device instance from device instance
0622  * @device: device instance
0623  *
0624  * Get ish_cl_device instance which embeds device instance in it.
0625  *
0626  * Return: pointer to ishtp_cl_device instance
0627  */
0628 struct ishtp_cl_device *ishtp_dev_to_cl_device(struct device *device)
0629 {
0630     return to_ishtp_cl_device(device);
0631 }
0632 EXPORT_SYMBOL(ishtp_dev_to_cl_device);
0633 
0634 /**
0635  * ishtp_bus_new_client() - Create a new client
0636  * @dev:    ISHTP device instance
0637  *
0638  * Once bus protocol enumerates a client, this is called
0639  * to add a device for the client.
0640  *
0641  * Return: 0 on success or error code on failure
0642  */
0643 int ishtp_bus_new_client(struct ishtp_device *dev)
0644 {
0645     int i;
0646     char    *dev_name;
0647     struct ishtp_cl_device  *cl_device;
0648     guid_t  device_uuid;
0649 
0650     /*
0651      * For all reported clients, create an unconnected client and add its
0652      * device to ISHTP bus.
0653      * If appropriate driver has loaded, this will trigger its probe().
0654      * Otherwise, probe() will be called when driver is loaded
0655      */
0656     i = dev->fw_client_presentation_num - 1;
0657     device_uuid = dev->fw_clients[i].props.protocol_name;
0658     dev_name = kasprintf(GFP_KERNEL, "{%pUL}", &device_uuid);
0659     if (!dev_name)
0660         return  -ENOMEM;
0661 
0662     cl_device = ishtp_bus_add_device(dev, device_uuid, dev_name);
0663     if (!cl_device) {
0664         kfree(dev_name);
0665         return  -ENOENT;
0666     }
0667 
0668     kfree(dev_name);
0669 
0670     return  0;
0671 }
0672 
0673 /**
0674  * ishtp_cl_device_bind() - bind a device
0675  * @cl:     ishtp client device
0676  *
0677  * Binds connected ishtp_cl to ISHTP bus device
0678  *
0679  * Return: 0 on success or fault code
0680  */
0681 int ishtp_cl_device_bind(struct ishtp_cl *cl)
0682 {
0683     struct ishtp_cl_device  *cl_device;
0684     unsigned long flags;
0685     int rv;
0686 
0687     if (!cl->fw_client_id || cl->state != ISHTP_CL_CONNECTED)
0688         return  -EFAULT;
0689 
0690     rv = -ENOENT;
0691     spin_lock_irqsave(&cl->dev->device_list_lock, flags);
0692     list_for_each_entry(cl_device, &cl->dev->device_list,
0693             device_link) {
0694         if (cl_device->fw_client &&
0695             cl_device->fw_client->client_id == cl->fw_client_id) {
0696             cl->device = cl_device;
0697             rv = 0;
0698             break;
0699         }
0700     }
0701     spin_unlock_irqrestore(&cl->dev->device_list_lock, flags);
0702     return  rv;
0703 }
0704 
0705 /**
0706  * ishtp_bus_remove_all_clients() - Remove all clients
0707  * @ishtp_dev:      ishtp device
0708  * @warm_reset:     Reset due to FW reset dure to errors or S3 suspend
0709  *
0710  * This is part of reset/remove flow. This function the main processing
0711  * only targets error processing, if the FW has forced reset or
0712  * error to remove connected clients. When warm reset the client devices are
0713  * not removed.
0714  */
0715 void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
0716                   bool warm_reset)
0717 {
0718     struct ishtp_cl_device  *cl_device, *n;
0719     struct ishtp_cl *cl;
0720     unsigned long   flags;
0721 
0722     spin_lock_irqsave(&ishtp_dev->cl_list_lock, flags);
0723     list_for_each_entry(cl, &ishtp_dev->cl_list, link) {
0724         cl->state = ISHTP_CL_DISCONNECTED;
0725 
0726         /*
0727          * Wake any pending process. The waiter would check dev->state
0728          * and determine that it's not enabled already,
0729          * and will return error to its caller
0730          */
0731         wake_up_interruptible(&cl->wait_ctrl_res);
0732 
0733         /* Disband any pending read/write requests and free rb */
0734         ishtp_cl_flush_queues(cl);
0735 
0736         /* Remove all free and in_process rings, both Rx and Tx */
0737         ishtp_cl_free_rx_ring(cl);
0738         ishtp_cl_free_tx_ring(cl);
0739 
0740         /*
0741          * Free client and ISHTP bus client device structures
0742          * don't free host client because it is part of the OS fd
0743          * structure
0744          */
0745     }
0746     spin_unlock_irqrestore(&ishtp_dev->cl_list_lock, flags);
0747 
0748     /* Release DMA buffers for client messages */
0749     ishtp_cl_free_dma_buf(ishtp_dev);
0750 
0751     /* remove bus clients */
0752     spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
0753     list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
0754                  device_link) {
0755         cl_device->fw_client = NULL;
0756         if (warm_reset && cl_device->reference_count)
0757             continue;
0758 
0759         list_del(&cl_device->device_link);
0760         spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
0761         ishtp_bus_remove_device(cl_device);
0762         spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
0763     }
0764     spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
0765 
0766     /* Free all client structures */
0767     spin_lock_irqsave(&ishtp_dev->fw_clients_lock, flags);
0768     kfree(ishtp_dev->fw_clients);
0769     ishtp_dev->fw_clients = NULL;
0770     ishtp_dev->fw_clients_num = 0;
0771     ishtp_dev->fw_client_presentation_num = 0;
0772     ishtp_dev->fw_client_index = 0;
0773     bitmap_zero(ishtp_dev->fw_clients_map, ISHTP_CLIENTS_MAX);
0774     spin_unlock_irqrestore(&ishtp_dev->fw_clients_lock, flags);
0775 }
0776 EXPORT_SYMBOL(ishtp_bus_remove_all_clients);
0777 
0778 /**
0779  * ishtp_reset_handler() - IPC reset handler
0780  * @dev:    ishtp device
0781  *
0782  * ISHTP Handler for IPC_RESET notification
0783  */
0784 void ishtp_reset_handler(struct ishtp_device *dev)
0785 {
0786     unsigned long   flags;
0787 
0788     /* Handle FW-initiated reset */
0789     dev->dev_state = ISHTP_DEV_RESETTING;
0790 
0791     /* Clear BH processing queue - no further HBMs */
0792     spin_lock_irqsave(&dev->rd_msg_spinlock, flags);
0793     dev->rd_msg_fifo_head = dev->rd_msg_fifo_tail = 0;
0794     spin_unlock_irqrestore(&dev->rd_msg_spinlock, flags);
0795 
0796     /* Handle ISH FW reset against upper layers */
0797     ishtp_bus_remove_all_clients(dev, true);
0798 }
0799 EXPORT_SYMBOL(ishtp_reset_handler);
0800 
0801 /**
0802  * ishtp_reset_compl_handler() - Reset completion handler
0803  * @dev:    ishtp device
0804  *
0805  * ISHTP handler for IPC_RESET sequence completion to start
0806  * host message bus start protocol sequence.
0807  */
0808 void ishtp_reset_compl_handler(struct ishtp_device *dev)
0809 {
0810     dev->dev_state = ISHTP_DEV_INIT_CLIENTS;
0811     dev->hbm_state = ISHTP_HBM_START;
0812     ishtp_hbm_start_req(dev);
0813 }
0814 EXPORT_SYMBOL(ishtp_reset_compl_handler);
0815 
0816 /**
0817  * ishtp_use_dma_transfer() - Function to use DMA
0818  *
0819  * This interface is used to enable usage of DMA
0820  *
0821  * Return non zero if DMA can be enabled
0822  */
0823 int ishtp_use_dma_transfer(void)
0824 {
0825     return ishtp_use_dma;
0826 }
0827 
0828 /**
0829  * ishtp_device() - Return device pointer
0830  * @device: ISH-TP client device instance
0831  *
0832  * This interface is used to return device pointer from ishtp_cl_device
0833  * instance.
0834  *
0835  * Return: device *.
0836  */
0837 struct device *ishtp_device(struct ishtp_cl_device *device)
0838 {
0839     return &device->dev;
0840 }
0841 EXPORT_SYMBOL(ishtp_device);
0842 
0843 /**
0844  * ishtp_wait_resume() - Wait for IPC resume
0845  *
0846  * Wait for IPC resume
0847  *
0848  * Return: resume complete or not
0849  */
0850 bool ishtp_wait_resume(struct ishtp_device *dev)
0851 {
0852     /* 50ms to get resume response */
0853     #define WAIT_FOR_RESUME_ACK_MS      50
0854 
0855     /* Waiting to get resume response */
0856     if (dev->resume_flag)
0857         wait_event_interruptible_timeout(dev->resume_wait,
0858                          !dev->resume_flag,
0859                          msecs_to_jiffies(WAIT_FOR_RESUME_ACK_MS));
0860 
0861     return (!dev->resume_flag);
0862 }
0863 EXPORT_SYMBOL_GPL(ishtp_wait_resume);
0864 
0865 /**
0866  * ishtp_get_pci_device() - Return PCI device dev pointer
0867  * This interface is used to return PCI device pointer
0868  * from ishtp_cl_device instance.
0869  * @device: ISH-TP client device instance
0870  *
0871  * Return: device *.
0872  */
0873 struct device *ishtp_get_pci_device(struct ishtp_cl_device *device)
0874 {
0875     return device->ishtp_dev->devc;
0876 }
0877 EXPORT_SYMBOL(ishtp_get_pci_device);
0878 
0879 /**
0880  * ishtp_trace_callback() - Return trace callback
0881  * @cl_device: ISH-TP client device instance
0882  *
0883  * This interface is used to return trace callback function pointer.
0884  *
0885  * Return: *ishtp_print_log()
0886  */
0887 ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device)
0888 {
0889     return cl_device->ishtp_dev->print_log;
0890 }
0891 EXPORT_SYMBOL(ishtp_trace_callback);
0892 
0893 /**
0894  * ish_hw_reset() - Call HW reset IPC callback
0895  * @dev:    ISHTP device instance
0896  *
0897  * This interface is used to reset HW in case of error.
0898  *
0899  * Return: value from IPC hw_reset callback
0900  */
0901 int ish_hw_reset(struct ishtp_device *dev)
0902 {
0903     return dev->ops->hw_reset(dev);
0904 }
0905 EXPORT_SYMBOL(ish_hw_reset);
0906 
0907 /**
0908  * ishtp_bus_register() - Function to register bus
0909  *
0910  * This register ishtp bus
0911  *
0912  * Return: Return output of bus_register
0913  */
0914 static int  __init ishtp_bus_register(void)
0915 {
0916     return bus_register(&ishtp_cl_bus_type);
0917 }
0918 
0919 /**
0920  * ishtp_bus_unregister() - Function to unregister bus
0921  *
0922  * This unregister ishtp bus
0923  */
0924 static void __exit ishtp_bus_unregister(void)
0925 {
0926     bus_unregister(&ishtp_cl_bus_type);
0927 }
0928 
0929 module_init(ishtp_bus_register);
0930 module_exit(ishtp_bus_unregister);
0931 
0932 MODULE_LICENSE("GPL");