root/drivers/hid/intel-ish-hid/ishtp/bus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ishtp_recv
  2. ishtp_send_msg
  3. ishtp_write_message
  4. ishtp_fw_cl_by_uuid
  5. ishtp_fw_cl_get_client
  6. ishtp_get_fw_client_id
  7. ishtp_fw_cl_by_id
  8. ishtp_cl_device_probe
  9. ishtp_cl_bus_match
  10. ishtp_cl_device_remove
  11. ishtp_cl_device_suspend
  12. ishtp_cl_device_resume
  13. ishtp_cl_device_reset
  14. modalias_show
  15. ishtp_cl_uevent
  16. ishtp_cl_dev_release
  17. ishtp_bus_add_device
  18. ishtp_bus_remove_device
  19. ishtp_cl_driver_register
  20. ishtp_cl_driver_unregister
  21. ishtp_bus_event_work
  22. ishtp_cl_bus_rx_event
  23. ishtp_register_event_cb
  24. ishtp_get_device
  25. ishtp_put_device
  26. ishtp_set_drvdata
  27. ishtp_get_drvdata
  28. ishtp_dev_to_cl_device
  29. ishtp_bus_new_client
  30. ishtp_cl_device_bind
  31. ishtp_bus_remove_all_clients
  32. ishtp_reset_handler
  33. ishtp_reset_compl_handler
  34. ishtp_use_dma_transfer
  35. ishtp_device
  36. ishtp_get_pci_device
  37. ishtp_trace_callback
  38. ish_hw_reset
  39. ishtp_bus_register
  40. ishtp_bus_unregister

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * ISHTP bus driver
   4  *
   5  * Copyright (c) 2012-2016, Intel Corporation.
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/init.h>
  10 #include <linux/kernel.h>
  11 #include <linux/device.h>
  12 #include <linux/sched.h>
  13 #include <linux/slab.h>
  14 #include "bus.h"
  15 #include "ishtp-dev.h"
  16 #include "client.h"
  17 #include "hbm.h"
  18 
  19 static int ishtp_use_dma;
  20 module_param_named(ishtp_use_dma, ishtp_use_dma, int, 0600);
  21 MODULE_PARM_DESC(ishtp_use_dma, "Use DMA to send messages");
  22 
  23 #define to_ishtp_cl_driver(d) container_of(d, struct ishtp_cl_driver, driver)
  24 #define to_ishtp_cl_device(d) container_of(d, struct ishtp_cl_device, dev)
  25 static bool ishtp_device_ready;
  26 
  27 /**
  28  * ishtp_recv() - process ishtp message
  29  * @dev: ishtp device
  30  *
  31  * If a message with valid header and size is received, then
  32  * this function calls appropriate handler. The host or firmware
  33  * address is zero, then they are host bus management message,
  34  * otherwise they are message fo clients.
  35  */
  36 void ishtp_recv(struct ishtp_device *dev)
  37 {
  38         uint32_t        msg_hdr;
  39         struct ishtp_msg_hdr    *ishtp_hdr;
  40 
  41         /* Read ISHTP header dword */
  42         msg_hdr = dev->ops->ishtp_read_hdr(dev);
  43         if (!msg_hdr)
  44                 return;
  45 
  46         dev->ops->sync_fw_clock(dev);
  47 
  48         ishtp_hdr = (struct ishtp_msg_hdr *)&msg_hdr;
  49         dev->ishtp_msg_hdr = msg_hdr;
  50 
  51         /* Sanity check: ISHTP frag. length in header */
  52         if (ishtp_hdr->length > dev->mtu) {
  53                 dev_err(dev->devc,
  54                         "ISHTP hdr - bad length: %u; dropped [%08X]\n",
  55                         (unsigned int)ishtp_hdr->length, msg_hdr);
  56                 return;
  57         }
  58 
  59         /* ISHTP bus message */
  60         if (!ishtp_hdr->host_addr && !ishtp_hdr->fw_addr)
  61                 recv_hbm(dev, ishtp_hdr);
  62         /* ISHTP fixed-client message */
  63         else if (!ishtp_hdr->host_addr)
  64                 recv_fixed_cl_msg(dev, ishtp_hdr);
  65         else
  66                 /* ISHTP client message */
  67                 recv_ishtp_cl_msg(dev, ishtp_hdr);
  68 }
  69 EXPORT_SYMBOL(ishtp_recv);
  70 
  71 /**
  72  * ishtp_send_msg() - Send ishtp message
  73  * @dev: ishtp device
  74  * @hdr: Message header
  75  * @msg: Message contents
  76  * @ipc_send_compl: completion callback
  77  * @ipc_send_compl_prm: completion callback parameter
  78  *
  79  * Send a multi fragment message via IPC. After sending the first fragment
  80  * the completion callback is called to schedule transmit of next fragment.
  81  *
  82  * Return: This returns IPC send message status.
  83  */
  84 int ishtp_send_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
  85                        void *msg, void(*ipc_send_compl)(void *),
  86                        void *ipc_send_compl_prm)
  87 {
  88         unsigned char   ipc_msg[IPC_FULL_MSG_SIZE];
  89         uint32_t        drbl_val;
  90 
  91         drbl_val = dev->ops->ipc_get_header(dev, hdr->length +
  92                                             sizeof(struct ishtp_msg_hdr),
  93                                             1);
  94 
  95         memcpy(ipc_msg, &drbl_val, sizeof(uint32_t));
  96         memcpy(ipc_msg + sizeof(uint32_t), hdr, sizeof(uint32_t));
  97         memcpy(ipc_msg + 2 * sizeof(uint32_t), msg, hdr->length);
  98         return  dev->ops->write(dev, ipc_send_compl, ipc_send_compl_prm,
  99                                 ipc_msg, 2 * sizeof(uint32_t) + hdr->length);
 100 }
 101 
 102 /**
 103  * ishtp_write_message() - Send ishtp single fragment message
 104  * @dev: ishtp device
 105  * @hdr: Message header
 106  * @buf: message data
 107  *
 108  * Send a single fragment message via IPC.  This returns IPC send message
 109  * status.
 110  *
 111  * Return: This returns IPC send message status.
 112  */
 113 int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
 114                         void *buf)
 115 {
 116         return ishtp_send_msg(dev, hdr, buf, NULL, NULL);
 117 }
 118 
 119 /**
 120  * ishtp_fw_cl_by_uuid() - locate index of fw client
 121  * @dev: ishtp device
 122  * @uuid: uuid of the client to search
 123  *
 124  * Search firmware client using UUID.
 125  *
 126  * Return: fw client index or -ENOENT if not found
 127  */
 128 int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const guid_t *uuid)
 129 {
 130         unsigned int i;
 131 
 132         for (i = 0; i < dev->fw_clients_num; ++i) {
 133                 if (guid_equal(uuid, &dev->fw_clients[i].props.protocol_name))
 134                         return i;
 135         }
 136         return -ENOENT;
 137 }
 138 EXPORT_SYMBOL(ishtp_fw_cl_by_uuid);
 139 
 140 /**
 141  * ishtp_fw_cl_get_client() - return client information to client
 142  * @dev: the ishtp device structure
 143  * @uuid: uuid of the client to search
 144  *
 145  * Search firmware client using UUID and reture related client information.
 146  *
 147  * Return: pointer of client information on success, NULL on failure.
 148  */
 149 struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
 150                                                const guid_t *uuid)
 151 {
 152         int i;
 153         unsigned long flags;
 154 
 155         spin_lock_irqsave(&dev->fw_clients_lock, flags);
 156         i = ishtp_fw_cl_by_uuid(dev, uuid);
 157         spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
 158         if (i < 0 || dev->fw_clients[i].props.fixed_address)
 159                 return NULL;
 160 
 161         return &dev->fw_clients[i];
 162 }
 163 EXPORT_SYMBOL(ishtp_fw_cl_get_client);
 164 
 165 /**
 166  * ishtp_get_fw_client_id() - Get fw client id
 167  *
 168  * This interface is used to reset HW get FW client id.
 169  *
 170  * Return: firmware client id.
 171  */
 172 int ishtp_get_fw_client_id(struct ishtp_fw_client *fw_client)
 173 {
 174         return fw_client->client_id;
 175 }
 176 EXPORT_SYMBOL(ishtp_get_fw_client_id);
 177 
 178 /**
 179  * ishtp_fw_cl_by_id() - return index to fw_clients for client_id
 180  * @dev: the ishtp device structure
 181  * @client_id: fw client id to search
 182  *
 183  * Search firmware client using client id.
 184  *
 185  * Return: index on success, -ENOENT on failure.
 186  */
 187 int ishtp_fw_cl_by_id(struct ishtp_device *dev, uint8_t client_id)
 188 {
 189         int i, res = -ENOENT;
 190         unsigned long   flags;
 191 
 192         spin_lock_irqsave(&dev->fw_clients_lock, flags);
 193         for (i = 0; i < dev->fw_clients_num; i++) {
 194                 if (dev->fw_clients[i].client_id == client_id) {
 195                         res = i;
 196                         break;
 197                 }
 198         }
 199         spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
 200 
 201         return res;
 202 }
 203 
 204 /**
 205  * ishtp_cl_device_probe() - Bus probe() callback
 206  * @dev: the device structure
 207  *
 208  * This is a bus probe callback and calls the drive probe function.
 209  *
 210  * Return: Return value from driver probe() call.
 211  */
 212 static int ishtp_cl_device_probe(struct device *dev)
 213 {
 214         struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
 215         struct ishtp_cl_driver *driver;
 216 
 217         if (!device)
 218                 return 0;
 219 
 220         driver = to_ishtp_cl_driver(dev->driver);
 221         if (!driver || !driver->probe)
 222                 return -ENODEV;
 223 
 224         return driver->probe(device);
 225 }
 226 
 227 /**
 228  * ishtp_cl_bus_match() - Bus match() callback
 229  * @dev: the device structure
 230  * @drv: the driver structure
 231  *
 232  * This is a bus match callback, called when a new ishtp_cl_device is
 233  * registered during ishtp bus client enumeration. Use the guid_t in
 234  * drv and dev to decide whether they match or not.
 235  *
 236  * Return: 1 if dev & drv matches, 0 otherwise.
 237  */
 238 static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
 239 {
 240         struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
 241         struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
 242 
 243         return guid_equal(driver->guid,
 244                           &device->fw_client->props.protocol_name);
 245 }
 246 
 247 /**
 248  * ishtp_cl_device_remove() - Bus remove() callback
 249  * @dev: the device structure
 250  *
 251  * This is a bus remove callback and calls the drive remove function.
 252  * Since the ISH driver model supports only built in, this is
 253  * primarily can be called during pci driver init failure.
 254  *
 255  * Return: Return value from driver remove() call.
 256  */
 257 static int ishtp_cl_device_remove(struct device *dev)
 258 {
 259         struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
 260         struct ishtp_cl_driver *driver;
 261 
 262         if (!device || !dev->driver)
 263                 return 0;
 264 
 265         if (device->event_cb) {
 266                 device->event_cb = NULL;
 267                 cancel_work_sync(&device->event_work);
 268         }
 269 
 270         driver = to_ishtp_cl_driver(dev->driver);
 271         if (!driver->remove) {
 272                 dev->driver = NULL;
 273 
 274                 return 0;
 275         }
 276 
 277         return driver->remove(device);
 278 }
 279 
 280 /**
 281  * ishtp_cl_device_suspend() - Bus suspend callback
 282  * @dev:        device
 283  *
 284  * Called during device suspend process.
 285  *
 286  * Return: Return value from driver suspend() call.
 287  */
 288 static int ishtp_cl_device_suspend(struct device *dev)
 289 {
 290         struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
 291         struct ishtp_cl_driver *driver;
 292         int ret = 0;
 293 
 294         if (!device)
 295                 return 0;
 296 
 297         driver = to_ishtp_cl_driver(dev->driver);
 298         if (driver && driver->driver.pm) {
 299                 if (driver->driver.pm->suspend)
 300                         ret = driver->driver.pm->suspend(dev);
 301         }
 302 
 303         return ret;
 304 }
 305 
 306 /**
 307  * ishtp_cl_device_resume() - Bus resume callback
 308  * @dev:        device
 309  *
 310  * Called during device resume process.
 311  *
 312  * Return: Return value from driver resume() call.
 313  */
 314 static int ishtp_cl_device_resume(struct device *dev)
 315 {
 316         struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
 317         struct ishtp_cl_driver *driver;
 318         int ret = 0;
 319 
 320         if (!device)
 321                 return 0;
 322 
 323         /*
 324          * When ISH needs hard reset, it is done asynchrnously, hence bus
 325          * resume will  be called before full ISH resume
 326          */
 327         if (device->ishtp_dev->resume_flag)
 328                 return 0;
 329 
 330         driver = to_ishtp_cl_driver(dev->driver);
 331         if (driver && driver->driver.pm) {
 332                 if (driver->driver.pm->resume)
 333                         ret = driver->driver.pm->resume(dev);
 334         }
 335 
 336         return ret;
 337 }
 338 
 339 /**
 340  * ishtp_cl_device_reset() - Reset callback
 341  * @device:     ishtp client device instance
 342  *
 343  * This is a callback when HW reset is done and the device need
 344  * reinit.
 345  *
 346  * Return: Return value from driver reset() call.
 347  */
 348 static int ishtp_cl_device_reset(struct ishtp_cl_device *device)
 349 {
 350         struct ishtp_cl_driver *driver;
 351         int ret = 0;
 352 
 353         device->event_cb = NULL;
 354         cancel_work_sync(&device->event_work);
 355 
 356         driver = to_ishtp_cl_driver(device->dev.driver);
 357         if (driver && driver->reset)
 358                 ret = driver->reset(device);
 359 
 360         return ret;
 361 }
 362 
 363 static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 364         char *buf)
 365 {
 366         int len;
 367 
 368         len = snprintf(buf, PAGE_SIZE, "ishtp:%s\n", dev_name(dev));
 369         return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 370 }
 371 static DEVICE_ATTR_RO(modalias);
 372 
 373 static struct attribute *ishtp_cl_dev_attrs[] = {
 374         &dev_attr_modalias.attr,
 375         NULL,
 376 };
 377 ATTRIBUTE_GROUPS(ishtp_cl_dev);
 378 
 379 static int ishtp_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
 380 {
 381         if (add_uevent_var(env, "MODALIAS=ishtp:%s", dev_name(dev)))
 382                 return -ENOMEM;
 383         return 0;
 384 }
 385 
 386 static const struct dev_pm_ops ishtp_cl_bus_dev_pm_ops = {
 387         /* Suspend callbacks */
 388         .suspend = ishtp_cl_device_suspend,
 389         .resume = ishtp_cl_device_resume,
 390         /* Hibernate callbacks */
 391         .freeze = ishtp_cl_device_suspend,
 392         .thaw = ishtp_cl_device_resume,
 393         .restore = ishtp_cl_device_resume,
 394 };
 395 
 396 static struct bus_type ishtp_cl_bus_type = {
 397         .name           = "ishtp",
 398         .dev_groups     = ishtp_cl_dev_groups,
 399         .probe          = ishtp_cl_device_probe,
 400         .match          = ishtp_cl_bus_match,
 401         .remove         = ishtp_cl_device_remove,
 402         .pm             = &ishtp_cl_bus_dev_pm_ops,
 403         .uevent         = ishtp_cl_uevent,
 404 };
 405 
 406 static void ishtp_cl_dev_release(struct device *dev)
 407 {
 408         kfree(to_ishtp_cl_device(dev));
 409 }
 410 
 411 static const struct device_type ishtp_cl_device_type = {
 412         .release        = ishtp_cl_dev_release,
 413 };
 414 
 415 /**
 416  * ishtp_bus_add_device() - Function to create device on bus
 417  * @dev:        ishtp device
 418  * @uuid:       uuid of the client
 419  * @name:       Name of the client
 420  *
 421  * Allocate ISHTP bus client device, attach it to uuid
 422  * and register with ISHTP bus.
 423  *
 424  * Return: ishtp_cl_device pointer or NULL on failure
 425  */
 426 static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev,
 427                                                     guid_t uuid, char *name)
 428 {
 429         struct ishtp_cl_device *device;
 430         int status;
 431         unsigned long flags;
 432 
 433         spin_lock_irqsave(&dev->device_list_lock, flags);
 434         list_for_each_entry(device, &dev->device_list, device_link) {
 435                 if (!strcmp(name, dev_name(&device->dev))) {
 436                         device->fw_client = &dev->fw_clients[
 437                                 dev->fw_client_presentation_num - 1];
 438                         spin_unlock_irqrestore(&dev->device_list_lock, flags);
 439                         ishtp_cl_device_reset(device);
 440                         return device;
 441                 }
 442         }
 443         spin_unlock_irqrestore(&dev->device_list_lock, flags);
 444 
 445         device = kzalloc(sizeof(struct ishtp_cl_device), GFP_KERNEL);
 446         if (!device)
 447                 return NULL;
 448 
 449         device->dev.parent = dev->devc;
 450         device->dev.bus = &ishtp_cl_bus_type;
 451         device->dev.type = &ishtp_cl_device_type;
 452         device->ishtp_dev = dev;
 453 
 454         device->fw_client =
 455                 &dev->fw_clients[dev->fw_client_presentation_num - 1];
 456 
 457         dev_set_name(&device->dev, "%s", name);
 458 
 459         spin_lock_irqsave(&dev->device_list_lock, flags);
 460         list_add_tail(&device->device_link, &dev->device_list);
 461         spin_unlock_irqrestore(&dev->device_list_lock, flags);
 462 
 463         status = device_register(&device->dev);
 464         if (status) {
 465                 spin_lock_irqsave(&dev->device_list_lock, flags);
 466                 list_del(&device->device_link);
 467                 spin_unlock_irqrestore(&dev->device_list_lock, flags);
 468                 dev_err(dev->devc, "Failed to register ISHTP client device\n");
 469                 put_device(&device->dev);
 470                 return NULL;
 471         }
 472 
 473         ishtp_device_ready = true;
 474 
 475         return device;
 476 }
 477 
 478 /**
 479  * ishtp_bus_remove_device() - Function to relase device on bus
 480  * @device:     client device instance
 481  *
 482  * This is a counterpart of ishtp_bus_add_device.
 483  * Device is unregistered.
 484  * the device structure is freed in 'ishtp_cl_dev_release' function
 485  * Called only during error in pci driver init path.
 486  */
 487 static void ishtp_bus_remove_device(struct ishtp_cl_device *device)
 488 {
 489         device_unregister(&device->dev);
 490 }
 491 
 492 /**
 493  * ishtp_cl_driver_register() - Client driver register
 494  * @driver:     the client driver instance
 495  * @owner:      Owner of this driver module
 496  *
 497  * Once a client driver is probed, it created a client
 498  * instance and registers with the bus.
 499  *
 500  * Return: Return value of driver_register or -ENODEV if not ready
 501  */
 502 int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
 503                              struct module *owner)
 504 {
 505         int err;
 506 
 507         if (!ishtp_device_ready)
 508                 return -ENODEV;
 509 
 510         driver->driver.name = driver->name;
 511         driver->driver.owner = owner;
 512         driver->driver.bus = &ishtp_cl_bus_type;
 513 
 514         err = driver_register(&driver->driver);
 515         if (err)
 516                 return err;
 517 
 518         return 0;
 519 }
 520 EXPORT_SYMBOL(ishtp_cl_driver_register);
 521 
 522 /**
 523  * ishtp_cl_driver_unregister() - Client driver unregister
 524  * @driver:     the client driver instance
 525  *
 526  * Unregister client during device removal process.
 527  */
 528 void ishtp_cl_driver_unregister(struct ishtp_cl_driver *driver)
 529 {
 530         driver_unregister(&driver->driver);
 531 }
 532 EXPORT_SYMBOL(ishtp_cl_driver_unregister);
 533 
 534 /**
 535  * ishtp_bus_event_work() - event work function
 536  * @work:       work struct pointer
 537  *
 538  * Once an event is received for a client this work
 539  * function is called. If the device has registered a
 540  * callback then the callback is called.
 541  */
 542 static void ishtp_bus_event_work(struct work_struct *work)
 543 {
 544         struct ishtp_cl_device *device;
 545 
 546         device = container_of(work, struct ishtp_cl_device, event_work);
 547 
 548         if (device->event_cb)
 549                 device->event_cb(device);
 550 }
 551 
 552 /**
 553  * ishtp_cl_bus_rx_event() - schedule event work
 554  * @device:     client device instance
 555  *
 556  * Once an event is received for a client this schedules
 557  * a work function to process.
 558  */
 559 void ishtp_cl_bus_rx_event(struct ishtp_cl_device *device)
 560 {
 561         if (!device || !device->event_cb)
 562                 return;
 563 
 564         if (device->event_cb)
 565                 schedule_work(&device->event_work);
 566 }
 567 
 568 /**
 569  * ishtp_register_event_cb() - Register callback
 570  * @device:     client device instance
 571  * @event_cb:   Event processor for an client
 572  *
 573  * Register a callback for events, called from client driver
 574  *
 575  * Return: Return 0 or -EALREADY if already registered
 576  */
 577 int ishtp_register_event_cb(struct ishtp_cl_device *device,
 578         void (*event_cb)(struct ishtp_cl_device *))
 579 {
 580         if (device->event_cb)
 581                 return -EALREADY;
 582 
 583         device->event_cb = event_cb;
 584         INIT_WORK(&device->event_work, ishtp_bus_event_work);
 585 
 586         return 0;
 587 }
 588 EXPORT_SYMBOL(ishtp_register_event_cb);
 589 
 590 /**
 591  * ishtp_get_device() - update usage count for the device
 592  * @cl_device:  client device instance
 593  *
 594  * Increment the usage count. The device can't be deleted
 595  */
 596 void ishtp_get_device(struct ishtp_cl_device *cl_device)
 597 {
 598         cl_device->reference_count++;
 599 }
 600 EXPORT_SYMBOL(ishtp_get_device);
 601 
 602 /**
 603  * ishtp_put_device() - decrement usage count for the device
 604  * @cl_device:  client device instance
 605  *
 606  * Decrement the usage count. The device can be deleted is count = 0
 607  */
 608 void ishtp_put_device(struct ishtp_cl_device *cl_device)
 609 {
 610         cl_device->reference_count--;
 611 }
 612 EXPORT_SYMBOL(ishtp_put_device);
 613 
 614 /**
 615  * ishtp_set_drvdata() - set client driver data
 616  * @cl_device:  client device instance
 617  * @data:       driver data need to be set
 618  *
 619  * Set client driver data to cl_device->driver_data.
 620  */
 621 void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data)
 622 {
 623         cl_device->driver_data = data;
 624 }
 625 EXPORT_SYMBOL(ishtp_set_drvdata);
 626 
 627 /**
 628  * ishtp_get_drvdata() - get client driver data
 629  * @cl_device:  client device instance
 630  *
 631  * Get client driver data from cl_device->driver_data.
 632  *
 633  * Return: pointer of driver data
 634  */
 635 void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device)
 636 {
 637         return cl_device->driver_data;
 638 }
 639 EXPORT_SYMBOL(ishtp_get_drvdata);
 640 
 641 /**
 642  * ishtp_dev_to_cl_device() - get ishtp_cl_device instance from device instance
 643  * @device: device instance
 644  *
 645  * Get ish_cl_device instance which embeds device instance in it.
 646  *
 647  * Return: pointer to ishtp_cl_device instance
 648  */
 649 struct ishtp_cl_device *ishtp_dev_to_cl_device(struct device *device)
 650 {
 651         return to_ishtp_cl_device(device);
 652 }
 653 EXPORT_SYMBOL(ishtp_dev_to_cl_device);
 654 
 655 /**
 656  * ishtp_bus_new_client() - Create a new client
 657  * @dev:        ISHTP device instance
 658  *
 659  * Once bus protocol enumerates a client, this is called
 660  * to add a device for the client.
 661  *
 662  * Return: 0 on success or error code on failure
 663  */
 664 int ishtp_bus_new_client(struct ishtp_device *dev)
 665 {
 666         int     i;
 667         char    *dev_name;
 668         struct ishtp_cl_device  *cl_device;
 669         guid_t  device_uuid;
 670 
 671         /*
 672          * For all reported clients, create an unconnected client and add its
 673          * device to ISHTP bus.
 674          * If appropriate driver has loaded, this will trigger its probe().
 675          * Otherwise, probe() will be called when driver is loaded
 676          */
 677         i = dev->fw_client_presentation_num - 1;
 678         device_uuid = dev->fw_clients[i].props.protocol_name;
 679         dev_name = kasprintf(GFP_KERNEL, "{%pUL}", &device_uuid);
 680         if (!dev_name)
 681                 return  -ENOMEM;
 682 
 683         cl_device = ishtp_bus_add_device(dev, device_uuid, dev_name);
 684         if (!cl_device) {
 685                 kfree(dev_name);
 686                 return  -ENOENT;
 687         }
 688 
 689         kfree(dev_name);
 690 
 691         return  0;
 692 }
 693 
 694 /**
 695  * ishtp_cl_device_bind() - bind a device
 696  * @cl:         ishtp client device
 697  *
 698  * Binds connected ishtp_cl to ISHTP bus device
 699  *
 700  * Return: 0 on success or fault code
 701  */
 702 int ishtp_cl_device_bind(struct ishtp_cl *cl)
 703 {
 704         struct ishtp_cl_device  *cl_device;
 705         unsigned long flags;
 706         int     rv;
 707 
 708         if (!cl->fw_client_id || cl->state != ISHTP_CL_CONNECTED)
 709                 return  -EFAULT;
 710 
 711         rv = -ENOENT;
 712         spin_lock_irqsave(&cl->dev->device_list_lock, flags);
 713         list_for_each_entry(cl_device, &cl->dev->device_list,
 714                         device_link) {
 715                 if (cl_device->fw_client &&
 716                     cl_device->fw_client->client_id == cl->fw_client_id) {
 717                         cl->device = cl_device;
 718                         rv = 0;
 719                         break;
 720                 }
 721         }
 722         spin_unlock_irqrestore(&cl->dev->device_list_lock, flags);
 723         return  rv;
 724 }
 725 
 726 /**
 727  * ishtp_bus_remove_all_clients() - Remove all clients
 728  * @ishtp_dev:          ishtp device
 729  * @warm_reset:         Reset due to FW reset dure to errors or S3 suspend
 730  *
 731  * This is part of reset/remove flow. This function the main processing
 732  * only targets error processing, if the FW has forced reset or
 733  * error to remove connected clients. When warm reset the client devices are
 734  * not removed.
 735  */
 736 void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
 737                                   bool warm_reset)
 738 {
 739         struct ishtp_cl_device  *cl_device, *n;
 740         struct ishtp_cl *cl;
 741         unsigned long   flags;
 742 
 743         spin_lock_irqsave(&ishtp_dev->cl_list_lock, flags);
 744         list_for_each_entry(cl, &ishtp_dev->cl_list, link) {
 745                 cl->state = ISHTP_CL_DISCONNECTED;
 746 
 747                 /*
 748                  * Wake any pending process. The waiter would check dev->state
 749                  * and determine that it's not enabled already,
 750                  * and will return error to its caller
 751                  */
 752                 wake_up_interruptible(&cl->wait_ctrl_res);
 753 
 754                 /* Disband any pending read/write requests and free rb */
 755                 ishtp_cl_flush_queues(cl);
 756 
 757                 /* Remove all free and in_process rings, both Rx and Tx */
 758                 ishtp_cl_free_rx_ring(cl);
 759                 ishtp_cl_free_tx_ring(cl);
 760 
 761                 /*
 762                  * Free client and ISHTP bus client device structures
 763                  * don't free host client because it is part of the OS fd
 764                  * structure
 765                  */
 766         }
 767         spin_unlock_irqrestore(&ishtp_dev->cl_list_lock, flags);
 768 
 769         /* Release DMA buffers for client messages */
 770         ishtp_cl_free_dma_buf(ishtp_dev);
 771 
 772         /* remove bus clients */
 773         spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
 774         list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
 775                                  device_link) {
 776                 cl_device->fw_client = NULL;
 777                 if (warm_reset && cl_device->reference_count)
 778                         continue;
 779 
 780                 list_del(&cl_device->device_link);
 781                 spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
 782                 ishtp_bus_remove_device(cl_device);
 783                 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
 784         }
 785         spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
 786 
 787         /* Free all client structures */
 788         spin_lock_irqsave(&ishtp_dev->fw_clients_lock, flags);
 789         kfree(ishtp_dev->fw_clients);
 790         ishtp_dev->fw_clients = NULL;
 791         ishtp_dev->fw_clients_num = 0;
 792         ishtp_dev->fw_client_presentation_num = 0;
 793         ishtp_dev->fw_client_index = 0;
 794         bitmap_zero(ishtp_dev->fw_clients_map, ISHTP_CLIENTS_MAX);
 795         spin_unlock_irqrestore(&ishtp_dev->fw_clients_lock, flags);
 796 }
 797 EXPORT_SYMBOL(ishtp_bus_remove_all_clients);
 798 
 799 /**
 800  * ishtp_reset_handler() - IPC reset handler
 801  * @dev:        ishtp device
 802  *
 803  * ISHTP Handler for IPC_RESET notification
 804  */
 805 void ishtp_reset_handler(struct ishtp_device *dev)
 806 {
 807         unsigned long   flags;
 808 
 809         /* Handle FW-initiated reset */
 810         dev->dev_state = ISHTP_DEV_RESETTING;
 811 
 812         /* Clear BH processing queue - no further HBMs */
 813         spin_lock_irqsave(&dev->rd_msg_spinlock, flags);
 814         dev->rd_msg_fifo_head = dev->rd_msg_fifo_tail = 0;
 815         spin_unlock_irqrestore(&dev->rd_msg_spinlock, flags);
 816 
 817         /* Handle ISH FW reset against upper layers */
 818         ishtp_bus_remove_all_clients(dev, true);
 819 }
 820 EXPORT_SYMBOL(ishtp_reset_handler);
 821 
 822 /**
 823  * ishtp_reset_compl_handler() - Reset completion handler
 824  * @dev:        ishtp device
 825  *
 826  * ISHTP handler for IPC_RESET sequence completion to start
 827  * host message bus start protocol sequence.
 828  */
 829 void ishtp_reset_compl_handler(struct ishtp_device *dev)
 830 {
 831         dev->dev_state = ISHTP_DEV_INIT_CLIENTS;
 832         dev->hbm_state = ISHTP_HBM_START;
 833         ishtp_hbm_start_req(dev);
 834 }
 835 EXPORT_SYMBOL(ishtp_reset_compl_handler);
 836 
 837 /**
 838  * ishtp_use_dma_transfer() - Function to use DMA
 839  *
 840  * This interface is used to enable usage of DMA
 841  *
 842  * Return non zero if DMA can be enabled
 843  */
 844 int ishtp_use_dma_transfer(void)
 845 {
 846         return ishtp_use_dma;
 847 }
 848 
 849 /**
 850  * ishtp_device() - Return device pointer
 851  *
 852  * This interface is used to return device pointer from ishtp_cl_device
 853  * instance.
 854  *
 855  * Return: device *.
 856  */
 857 struct device *ishtp_device(struct ishtp_cl_device *device)
 858 {
 859         return &device->dev;
 860 }
 861 EXPORT_SYMBOL(ishtp_device);
 862 
 863 /**
 864  * ishtp_get_pci_device() - Return PCI device dev pointer
 865  * This interface is used to return PCI device pointer
 866  * from ishtp_cl_device instance.
 867  *
 868  * Return: device *.
 869  */
 870 struct device *ishtp_get_pci_device(struct ishtp_cl_device *device)
 871 {
 872         return device->ishtp_dev->devc;
 873 }
 874 EXPORT_SYMBOL(ishtp_get_pci_device);
 875 
 876 /**
 877  * ishtp_trace_callback() - Return trace callback
 878  *
 879  * This interface is used to return trace callback function pointer.
 880  *
 881  * Return: void *.
 882  */
 883 void *ishtp_trace_callback(struct ishtp_cl_device *cl_device)
 884 {
 885         return cl_device->ishtp_dev->print_log;
 886 }
 887 EXPORT_SYMBOL(ishtp_trace_callback);
 888 
 889 /**
 890  * ish_hw_reset() - Call HW reset IPC callback
 891  *
 892  * This interface is used to reset HW in case of error.
 893  *
 894  * Return: value from IPC hw_reset callback
 895  */
 896 int ish_hw_reset(struct ishtp_device *dev)
 897 {
 898         return dev->ops->hw_reset(dev);
 899 }
 900 EXPORT_SYMBOL(ish_hw_reset);
 901 
 902 /**
 903  * ishtp_bus_register() - Function to register bus
 904  *
 905  * This register ishtp bus
 906  *
 907  * Return: Return output of bus_register
 908  */
 909 static int  __init ishtp_bus_register(void)
 910 {
 911         return bus_register(&ishtp_cl_bus_type);
 912 }
 913 
 914 /**
 915  * ishtp_bus_unregister() - Function to unregister bus
 916  *
 917  * This unregister ishtp bus
 918  */
 919 static void __exit ishtp_bus_unregister(void)
 920 {
 921         bus_unregister(&ishtp_cl_bus_type);
 922 }
 923 
 924 module_init(ishtp_bus_register);
 925 module_exit(ishtp_bus_unregister);
 926 
 927 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */