init.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Initialization protocol for ISHTP driver
  4. *
  5. * Copyright (c) 2003-2016, Intel Corporation.
  6. */
  7. #include <linux/devm-helpers.h>
  8. #include <linux/export.h>
  9. #include <linux/slab.h>
  10. #include <linux/sched.h>
  11. #include "ishtp-dev.h"
  12. #include "hbm.h"
  13. #include "client.h"
  14. #include "loader.h"
  15. /**
  16. * ishtp_dev_state_str() -Convert to string format
  17. * @state: state to convert
  18. *
  19. * Convert state to string for prints
  20. *
  21. * Return: character pointer to converted string
  22. */
  23. const char *ishtp_dev_state_str(int state)
  24. {
  25. switch (state) {
  26. case ISHTP_DEV_INITIALIZING:
  27. return "INITIALIZING";
  28. case ISHTP_DEV_INIT_CLIENTS:
  29. return "INIT_CLIENTS";
  30. case ISHTP_DEV_ENABLED:
  31. return "ENABLED";
  32. case ISHTP_DEV_RESETTING:
  33. return "RESETTING";
  34. case ISHTP_DEV_DISABLED:
  35. return "DISABLED";
  36. case ISHTP_DEV_POWER_DOWN:
  37. return "POWER_DOWN";
  38. case ISHTP_DEV_POWER_UP:
  39. return "POWER_UP";
  40. default:
  41. return "unknown";
  42. }
  43. }
  44. /**
  45. * ishtp_device_init() - ishtp device init
  46. * @dev: ISHTP device instance
  47. *
  48. * After ISHTP device is alloacted, this function is used to initialize
  49. * each field which includes spin lock, work struct and lists
  50. */
  51. void ishtp_device_init(struct ishtp_device *dev)
  52. {
  53. int ret;
  54. dev->dev_state = ISHTP_DEV_INITIALIZING;
  55. INIT_LIST_HEAD(&dev->cl_list);
  56. INIT_LIST_HEAD(&dev->device_list);
  57. dev->rd_msg_fifo_head = 0;
  58. dev->rd_msg_fifo_tail = 0;
  59. spin_lock_init(&dev->rd_msg_spinlock);
  60. init_waitqueue_head(&dev->wait_hbm_recvd_msg);
  61. init_waitqueue_head(&dev->wait_loader_recvd_msg);
  62. spin_lock_init(&dev->read_list_spinlock);
  63. spin_lock_init(&dev->device_lock);
  64. spin_lock_init(&dev->device_list_lock);
  65. spin_lock_init(&dev->cl_list_lock);
  66. spin_lock_init(&dev->fw_clients_lock);
  67. INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn);
  68. bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX);
  69. dev->open_handle_count = 0;
  70. /*
  71. * Reserving client ID 0 for ISHTP Bus Message communications
  72. */
  73. bitmap_set(dev->host_clients_map, 0, 1);
  74. INIT_LIST_HEAD(&dev->read_list.list);
  75. ret = devm_work_autocancel(dev->devc, &dev->work_fw_loader, ishtp_loader_work);
  76. if (ret)
  77. dev_err_probe(dev->devc, ret, "Failed to initialise FW loader work\n");
  78. }
  79. EXPORT_SYMBOL(ishtp_device_init);
  80. /**
  81. * ishtp_start() - Start ISH processing
  82. * @dev: ISHTP device instance
  83. *
  84. * Start ISHTP processing by sending query subscriber message
  85. *
  86. * Return: 0 on success else -ENODEV
  87. */
  88. int ishtp_start(struct ishtp_device *dev)
  89. {
  90. if (ishtp_hbm_start_wait(dev)) {
  91. dev_err(dev->devc, "HBM haven't started");
  92. goto err;
  93. }
  94. /* suspend & resume notification - send QUERY_SUBSCRIBERS msg */
  95. ishtp_query_subscribers(dev);
  96. return 0;
  97. err:
  98. dev_err(dev->devc, "link layer initialization failed.\n");
  99. dev->dev_state = ISHTP_DEV_DISABLED;
  100. return -ENODEV;
  101. }
  102. EXPORT_SYMBOL(ishtp_start);