pdev_bus.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (C) 2007 Google, Inc.
  3. * Copyright (C) 2011 Intel, Inc.
  4. * Copyright (C) 2013 Intel, Inc.
  5. *
  6. * This software is licensed under the terms of the GNU General Public
  7. * License version 2, as published by the Free Software Foundation, and
  8. * may be copied, distributed, and modified under those terms.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/irq.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/slab.h>
  22. #include <linux/io.h>
  23. #define PDEV_BUS_OP_DONE (0x00)
  24. #define PDEV_BUS_OP_REMOVE_DEV (0x04)
  25. #define PDEV_BUS_OP_ADD_DEV (0x08)
  26. #define PDEV_BUS_OP_INIT (0x00)
  27. #define PDEV_BUS_OP (0x00)
  28. #define PDEV_BUS_GET_NAME (0x04)
  29. #define PDEV_BUS_NAME_LEN (0x08)
  30. #define PDEV_BUS_ID (0x0c)
  31. #define PDEV_BUS_IO_BASE (0x10)
  32. #define PDEV_BUS_IO_SIZE (0x14)
  33. #define PDEV_BUS_IRQ (0x18)
  34. #define PDEV_BUS_IRQ_COUNT (0x1c)
  35. #define PDEV_BUS_GET_NAME_HIGH (0x20)
  36. struct pdev_bus_dev {
  37. struct list_head list;
  38. struct platform_device pdev;
  39. struct resource resources[0];
  40. };
  41. static void goldfish_pdev_worker(struct work_struct *work);
  42. static void __iomem *pdev_bus_base;
  43. static unsigned long pdev_bus_addr;
  44. static unsigned long pdev_bus_len;
  45. static u32 pdev_bus_irq;
  46. static LIST_HEAD(pdev_bus_new_devices);
  47. static LIST_HEAD(pdev_bus_registered_devices);
  48. static LIST_HEAD(pdev_bus_removed_devices);
  49. static DECLARE_WORK(pdev_bus_worker, goldfish_pdev_worker);
  50. static void goldfish_pdev_worker(struct work_struct *work)
  51. {
  52. int ret;
  53. struct pdev_bus_dev *pos, *n;
  54. list_for_each_entry_safe(pos, n, &pdev_bus_removed_devices, list) {
  55. list_del(&pos->list);
  56. platform_device_unregister(&pos->pdev);
  57. kfree(pos);
  58. }
  59. list_for_each_entry_safe(pos, n, &pdev_bus_new_devices, list) {
  60. list_del(&pos->list);
  61. ret = platform_device_register(&pos->pdev);
  62. if (ret)
  63. pr_err("goldfish_pdev_worker failed to register device, %s\n",
  64. pos->pdev.name);
  65. list_add_tail(&pos->list, &pdev_bus_registered_devices);
  66. }
  67. }
  68. static void goldfish_pdev_remove(void)
  69. {
  70. struct pdev_bus_dev *pos, *n;
  71. u32 base;
  72. base = readl(pdev_bus_base + PDEV_BUS_IO_BASE);
  73. list_for_each_entry_safe(pos, n, &pdev_bus_new_devices, list) {
  74. if (pos->resources[0].start == base) {
  75. list_del(&pos->list);
  76. kfree(pos);
  77. return;
  78. }
  79. }
  80. list_for_each_entry_safe(pos, n, &pdev_bus_registered_devices, list) {
  81. if (pos->resources[0].start == base) {
  82. list_del(&pos->list);
  83. list_add_tail(&pos->list, &pdev_bus_removed_devices);
  84. schedule_work(&pdev_bus_worker);
  85. return;
  86. }
  87. };
  88. pr_err("goldfish_pdev_remove could not find device at %x\n", base);
  89. }
  90. static int goldfish_new_pdev(void)
  91. {
  92. struct pdev_bus_dev *dev;
  93. u32 name_len;
  94. u32 irq = -1, irq_count;
  95. int resource_count = 2;
  96. u32 base;
  97. char *name;
  98. base = readl(pdev_bus_base + PDEV_BUS_IO_BASE);
  99. irq_count = readl(pdev_bus_base + PDEV_BUS_IRQ_COUNT);
  100. name_len = readl(pdev_bus_base + PDEV_BUS_NAME_LEN);
  101. if (irq_count)
  102. resource_count++;
  103. dev = kzalloc(sizeof(*dev) +
  104. sizeof(struct resource) * resource_count +
  105. name_len + 1 + sizeof(*dev->pdev.dev.dma_mask), GFP_ATOMIC);
  106. if (dev == NULL)
  107. return -ENOMEM;
  108. dev->pdev.num_resources = resource_count;
  109. dev->pdev.resource = (struct resource *)(dev + 1);
  110. dev->pdev.name = name = (char *)(dev->pdev.resource + resource_count);
  111. dev->pdev.dev.coherent_dma_mask = ~0;
  112. dev->pdev.dev.dma_mask = (void *)(dev->pdev.name + name_len + 1);
  113. *dev->pdev.dev.dma_mask = ~0;
  114. #ifdef CONFIG_64BIT
  115. writel((u32)((u64)name>>32), pdev_bus_base + PDEV_BUS_GET_NAME_HIGH);
  116. #endif
  117. writel((u32)(unsigned long)name, pdev_bus_base + PDEV_BUS_GET_NAME);
  118. name[name_len] = '\0';
  119. dev->pdev.id = readl(pdev_bus_base + PDEV_BUS_ID);
  120. dev->pdev.resource[0].start = base;
  121. dev->pdev.resource[0].end = base +
  122. readl(pdev_bus_base + PDEV_BUS_IO_SIZE) - 1;
  123. dev->pdev.resource[0].flags = IORESOURCE_MEM;
  124. if (irq_count) {
  125. irq = readl(pdev_bus_base + PDEV_BUS_IRQ);
  126. dev->pdev.resource[1].start = irq;
  127. dev->pdev.resource[1].end = irq + irq_count - 1;
  128. dev->pdev.resource[1].flags = IORESOURCE_IRQ;
  129. }
  130. pr_debug("goldfish_new_pdev %s at %x irq %d\n", name, base, irq);
  131. list_add_tail(&dev->list, &pdev_bus_new_devices);
  132. schedule_work(&pdev_bus_worker);
  133. return 0;
  134. }
  135. static irqreturn_t goldfish_pdev_bus_interrupt(int irq, void *dev_id)
  136. {
  137. irqreturn_t ret = IRQ_NONE;
  138. while (1) {
  139. u32 op = readl(pdev_bus_base + PDEV_BUS_OP);
  140. switch (op) {
  141. case PDEV_BUS_OP_REMOVE_DEV:
  142. goldfish_pdev_remove();
  143. ret = IRQ_HANDLED;
  144. break;
  145. case PDEV_BUS_OP_ADD_DEV:
  146. goldfish_new_pdev();
  147. ret = IRQ_HANDLED;
  148. break;
  149. case PDEV_BUS_OP_DONE:
  150. default:
  151. return ret;
  152. }
  153. }
  154. }
  155. static int goldfish_pdev_bus_probe(struct platform_device *pdev)
  156. {
  157. int ret;
  158. struct resource *r;
  159. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  160. if (r == NULL)
  161. return -EINVAL;
  162. pdev_bus_addr = r->start;
  163. pdev_bus_len = resource_size(r);
  164. pdev_bus_base = ioremap(pdev_bus_addr, pdev_bus_len);
  165. if (pdev_bus_base == NULL) {
  166. ret = -ENOMEM;
  167. dev_err(&pdev->dev, "unable to map Goldfish MMIO.\n");
  168. goto free_resources;
  169. }
  170. r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  171. if (r == NULL) {
  172. ret = -ENOENT;
  173. goto free_map;
  174. }
  175. pdev_bus_irq = r->start;
  176. ret = request_irq(pdev_bus_irq, goldfish_pdev_bus_interrupt,
  177. IRQF_SHARED, "goldfish_pdev_bus", pdev);
  178. if (ret) {
  179. dev_err(&pdev->dev, "unable to request Goldfish IRQ\n");
  180. goto free_map;
  181. }
  182. writel(PDEV_BUS_OP_INIT, pdev_bus_base + PDEV_BUS_OP);
  183. return 0;
  184. free_map:
  185. iounmap(pdev_bus_base);
  186. free_resources:
  187. release_mem_region(pdev_bus_addr, pdev_bus_len);
  188. return ret;
  189. }
  190. static struct platform_driver goldfish_pdev_bus_driver = {
  191. .probe = goldfish_pdev_bus_probe,
  192. .driver = {
  193. .name = "goldfish_pdev_bus"
  194. }
  195. };
  196. builtin_platform_driver(goldfish_pdev_bus_driver);