bus.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Intel Management Engine Interface (Intel MEI) Linux driver
  3. * Copyright (c) 2012-2013, Intel Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. */
  15. #include <linux/module.h>
  16. #include <linux/device.h>
  17. #include <linux/kernel.h>
  18. #include <linux/init.h>
  19. #include <linux/errno.h>
  20. #include <linux/slab.h>
  21. #include <linux/mutex.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/pci.h>
  24. #include <linux/mei_cl_bus.h>
  25. #include "mei_dev.h"
  26. #define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
  27. #define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
  28. static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
  29. {
  30. struct mei_cl_device *device = to_mei_cl_device(dev);
  31. struct mei_cl_driver *driver = to_mei_cl_driver(drv);
  32. const struct mei_cl_device_id *id;
  33. if (!device)
  34. return 0;
  35. if (!driver || !driver->id_table)
  36. return 0;
  37. id = driver->id_table;
  38. while (id->name[0]) {
  39. if (!strcmp(dev_name(dev), id->name))
  40. return 1;
  41. id++;
  42. }
  43. return 0;
  44. }
  45. static int mei_cl_device_probe(struct device *dev)
  46. {
  47. struct mei_cl_device *device = to_mei_cl_device(dev);
  48. struct mei_cl_driver *driver;
  49. struct mei_cl_device_id id;
  50. if (!device)
  51. return 0;
  52. driver = to_mei_cl_driver(dev->driver);
  53. if (!driver || !driver->probe)
  54. return -ENODEV;
  55. dev_dbg(dev, "Device probe\n");
  56. strncpy(id.name, dev_name(dev), MEI_CL_NAME_SIZE);
  57. return driver->probe(device, &id);
  58. }
  59. static int mei_cl_device_remove(struct device *dev)
  60. {
  61. struct mei_cl_device *device = to_mei_cl_device(dev);
  62. struct mei_cl_driver *driver;
  63. if (!device || !dev->driver)
  64. return 0;
  65. driver = to_mei_cl_driver(dev->driver);
  66. if (!driver->remove) {
  67. dev->driver = NULL;
  68. return 0;
  69. }
  70. return driver->remove(device);
  71. }
  72. static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
  73. char *buf)
  74. {
  75. int len;
  76. len = snprintf(buf, PAGE_SIZE, "mei:%s\n", dev_name(dev));
  77. return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
  78. }
  79. static struct device_attribute mei_cl_dev_attrs[] = {
  80. __ATTR_RO(modalias),
  81. __ATTR_NULL,
  82. };
  83. static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
  84. {
  85. if (add_uevent_var(env, "MODALIAS=mei:%s", dev_name(dev)))
  86. return -ENOMEM;
  87. return 0;
  88. }
  89. static struct bus_type mei_cl_bus_type = {
  90. .name = "mei",
  91. .dev_attrs = mei_cl_dev_attrs,
  92. .match = mei_cl_device_match,
  93. .probe = mei_cl_device_probe,
  94. .remove = mei_cl_device_remove,
  95. .uevent = mei_cl_uevent,
  96. };
  97. static void mei_cl_dev_release(struct device *dev)
  98. {
  99. kfree(to_mei_cl_device(dev));
  100. }
  101. static struct device_type mei_cl_device_type = {
  102. .release = mei_cl_dev_release,
  103. };
  104. struct mei_cl_device *mei_cl_add_device(struct mei_device *mei_device,
  105. uuid_le uuid, char *name)
  106. {
  107. struct mei_cl_device *device;
  108. int status;
  109. device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
  110. if (!device)
  111. return NULL;
  112. device->dev.parent = &mei_device->pdev->dev;
  113. device->dev.bus = &mei_cl_bus_type;
  114. device->dev.type = &mei_cl_device_type;
  115. dev_set_name(&device->dev, "%s", name);
  116. status = device_register(&device->dev);
  117. if (status)
  118. goto out_err;
  119. dev_dbg(&device->dev, "client %s registered\n", name);
  120. return device;
  121. out_err:
  122. dev_err(device->dev.parent, "Failed to register MEI client\n");
  123. kfree(device);
  124. return NULL;
  125. }
  126. EXPORT_SYMBOL_GPL(mei_cl_add_device);
  127. void mei_cl_remove_device(struct mei_cl_device *device)
  128. {
  129. device_unregister(&device->dev);
  130. }
  131. EXPORT_SYMBOL_GPL(mei_cl_remove_device);
  132. int __mei_cl_driver_register(struct mei_cl_driver *driver, struct module *owner)
  133. {
  134. int err;
  135. driver->driver.name = driver->name;
  136. driver->driver.owner = owner;
  137. driver->driver.bus = &mei_cl_bus_type;
  138. err = driver_register(&driver->driver);
  139. if (err)
  140. return err;
  141. pr_debug("mei: driver [%s] registered\n", driver->driver.name);
  142. return 0;
  143. }
  144. EXPORT_SYMBOL_GPL(__mei_cl_driver_register);
  145. void mei_cl_driver_unregister(struct mei_cl_driver *driver)
  146. {
  147. driver_unregister(&driver->driver);
  148. pr_debug("mei: driver [%s] unregistered\n", driver->driver.name);
  149. }
  150. EXPORT_SYMBOL_GPL(mei_cl_driver_unregister);