025-bcma_backport.patch 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. --- a/drivers/bcma/Kconfig
  2. +++ b/drivers/bcma/Kconfig
  3. @@ -75,6 +75,7 @@ config BCMA_DRIVER_GMAC_CMN
  4. config BCMA_DRIVER_GPIO
  5. bool "BCMA GPIO driver"
  6. depends on BCMA && GPIOLIB
  7. + select IRQ_DOMAIN if BCMA_HOST_SOC
  8. help
  9. Driver to provide access to the GPIO pins of the bcma bus.
  10. --- a/drivers/bcma/bcma_private.h
  11. +++ b/drivers/bcma/bcma_private.h
  12. @@ -33,8 +33,6 @@ int __init bcma_bus_early_register(struc
  13. int bcma_bus_suspend(struct bcma_bus *bus);
  14. int bcma_bus_resume(struct bcma_bus *bus);
  15. #endif
  16. -struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
  17. - u8 unit);
  18. /* scan.c */
  19. int bcma_bus_scan(struct bcma_bus *bus);
  20. --- a/drivers/bcma/driver_chipcommon_sflash.c
  21. +++ b/drivers/bcma/driver_chipcommon_sflash.c
  22. @@ -38,7 +38,7 @@ static const struct bcma_sflash_tbl_e bc
  23. { "M25P32", 0x15, 0x10000, 64, },
  24. { "M25P64", 0x16, 0x10000, 128, },
  25. { "M25FL128", 0x17, 0x10000, 256, },
  26. - { 0 },
  27. + { NULL },
  28. };
  29. static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
  30. @@ -56,7 +56,7 @@ static const struct bcma_sflash_tbl_e bc
  31. { "SST25VF016", 0x41, 0x1000, 512, },
  32. { "SST25VF032", 0x4a, 0x1000, 1024, },
  33. { "SST25VF064", 0x4b, 0x1000, 2048, },
  34. - { 0 },
  35. + { NULL },
  36. };
  37. static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
  38. @@ -67,7 +67,7 @@ static const struct bcma_sflash_tbl_e bc
  39. { "AT45DB161", 0x2c, 512, 4096, },
  40. { "AT45DB321", 0x34, 512, 8192, },
  41. { "AT45DB642", 0x3c, 1024, 8192, },
  42. - { 0 },
  43. + { NULL },
  44. };
  45. static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode)
  46. --- a/drivers/bcma/driver_gpio.c
  47. +++ b/drivers/bcma/driver_gpio.c
  48. @@ -9,6 +9,9 @@
  49. */
  50. #include <linux/gpio.h>
  51. +#include <linux/irq.h>
  52. +#include <linux/interrupt.h>
  53. +#include <linux/irqdomain.h>
  54. #include <linux/export.h>
  55. #include <linux/bcma/bcma.h>
  56. @@ -73,19 +76,136 @@ static void bcma_gpio_free(struct gpio_c
  57. bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
  58. }
  59. +#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
  60. static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
  61. {
  62. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  63. if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
  64. - return bcma_core_irq(cc->core);
  65. + return irq_find_mapping(cc->irq_domain, gpio);
  66. else
  67. return -EINVAL;
  68. }
  69. +static void bcma_gpio_irq_unmask(struct irq_data *d)
  70. +{
  71. + struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
  72. + int gpio = irqd_to_hwirq(d);
  73. + u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
  74. +
  75. + bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
  76. + bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
  77. +}
  78. +
  79. +static void bcma_gpio_irq_mask(struct irq_data *d)
  80. +{
  81. + struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
  82. + int gpio = irqd_to_hwirq(d);
  83. +
  84. + bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
  85. +}
  86. +
  87. +static struct irq_chip bcma_gpio_irq_chip = {
  88. + .name = "BCMA-GPIO",
  89. + .irq_mask = bcma_gpio_irq_mask,
  90. + .irq_unmask = bcma_gpio_irq_unmask,
  91. +};
  92. +
  93. +static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
  94. +{
  95. + struct bcma_drv_cc *cc = dev_id;
  96. + u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
  97. + u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
  98. + u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
  99. + unsigned long irqs = (val ^ pol) & mask;
  100. + int gpio;
  101. +
  102. + if (!irqs)
  103. + return IRQ_NONE;
  104. +
  105. + for_each_set_bit(gpio, &irqs, cc->gpio.ngpio)
  106. + generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio));
  107. + bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
  108. +
  109. + return IRQ_HANDLED;
  110. +}
  111. +
  112. +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
  113. +{
  114. + struct gpio_chip *chip = &cc->gpio;
  115. + int gpio, hwirq, err;
  116. +
  117. + if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
  118. + return 0;
  119. +
  120. + cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
  121. + &irq_domain_simple_ops, cc);
  122. + if (!cc->irq_domain) {
  123. + err = -ENODEV;
  124. + goto err_irq_domain;
  125. + }
  126. + for (gpio = 0; gpio < chip->ngpio; gpio++) {
  127. + int irq = irq_create_mapping(cc->irq_domain, gpio);
  128. +
  129. + irq_set_chip_data(irq, cc);
  130. + irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
  131. + handle_simple_irq);
  132. + }
  133. +
  134. + hwirq = bcma_core_irq(cc->core);
  135. + err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
  136. + cc);
  137. + if (err)
  138. + goto err_req_irq;
  139. +
  140. + bcma_chipco_gpio_intmask(cc, ~0, 0);
  141. + bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
  142. +
  143. + return 0;
  144. +
  145. +err_req_irq:
  146. + for (gpio = 0; gpio < chip->ngpio; gpio++) {
  147. + int irq = irq_find_mapping(cc->irq_domain, gpio);
  148. +
  149. + irq_dispose_mapping(irq);
  150. + }
  151. + irq_domain_remove(cc->irq_domain);
  152. +err_irq_domain:
  153. + return err;
  154. +}
  155. +
  156. +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
  157. +{
  158. + struct gpio_chip *chip = &cc->gpio;
  159. + int gpio;
  160. +
  161. + if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
  162. + return;
  163. +
  164. + bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
  165. + free_irq(bcma_core_irq(cc->core), cc);
  166. + for (gpio = 0; gpio < chip->ngpio; gpio++) {
  167. + int irq = irq_find_mapping(cc->irq_domain, gpio);
  168. +
  169. + irq_dispose_mapping(irq);
  170. + }
  171. + irq_domain_remove(cc->irq_domain);
  172. +}
  173. +#else
  174. +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
  175. +{
  176. + return 0;
  177. +}
  178. +
  179. +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
  180. +{
  181. +}
  182. +#endif
  183. +
  184. int bcma_gpio_init(struct bcma_drv_cc *cc)
  185. {
  186. struct gpio_chip *chip = &cc->gpio;
  187. + int err;
  188. chip->label = "bcma_gpio";
  189. chip->owner = THIS_MODULE;
  190. @@ -95,7 +215,9 @@ int bcma_gpio_init(struct bcma_drv_cc *c
  191. chip->set = bcma_gpio_set_value;
  192. chip->direction_input = bcma_gpio_direction_input;
  193. chip->direction_output = bcma_gpio_direction_output;
  194. +#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
  195. chip->to_irq = bcma_gpio_to_irq;
  196. +#endif
  197. chip->ngpio = 16;
  198. /* There is just one SoC in one device and its GPIO addresses should be
  199. * deterministic to address them more easily. The other buses could get
  200. @@ -105,10 +227,21 @@ int bcma_gpio_init(struct bcma_drv_cc *c
  201. else
  202. chip->base = -1;
  203. - return gpiochip_add(chip);
  204. + err = bcma_gpio_irq_domain_init(cc);
  205. + if (err)
  206. + return err;
  207. +
  208. + err = gpiochip_add(chip);
  209. + if (err) {
  210. + bcma_gpio_irq_domain_exit(cc);
  211. + return err;
  212. + }
  213. +
  214. + return 0;
  215. }
  216. int bcma_gpio_unregister(struct bcma_drv_cc *cc)
  217. {
  218. + bcma_gpio_irq_domain_exit(cc);
  219. return gpiochip_remove(&cc->gpio);
  220. }
  221. --- a/drivers/bcma/host_pci.c
  222. +++ b/drivers/bcma/host_pci.c
  223. @@ -238,7 +238,6 @@ static void bcma_host_pci_remove(struct
  224. pci_release_regions(dev);
  225. pci_disable_device(dev);
  226. kfree(bus);
  227. - pci_set_drvdata(dev, NULL);
  228. }
  229. #ifdef CONFIG_PM_SLEEP
  230. @@ -270,7 +269,7 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc
  231. #endif /* CONFIG_PM_SLEEP */
  232. -static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
  233. +static const struct pci_device_id bcma_pci_bridge_tbl[] = {
  234. { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
  235. { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
  236. { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
  237. --- a/drivers/bcma/main.c
  238. +++ b/drivers/bcma/main.c
  239. @@ -78,18 +78,6 @@ static u16 bcma_cc_core_id(struct bcma_b
  240. return BCMA_CORE_CHIPCOMMON;
  241. }
  242. -struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
  243. -{
  244. - struct bcma_device *core;
  245. -
  246. - list_for_each_entry(core, &bus->cores, list) {
  247. - if (core->id.id == coreid)
  248. - return core;
  249. - }
  250. - return NULL;
  251. -}
  252. -EXPORT_SYMBOL_GPL(bcma_find_core);
  253. -
  254. struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
  255. u8 unit)
  256. {
  257. @@ -101,6 +89,7 @@ struct bcma_device *bcma_find_core_unit(
  258. }
  259. return NULL;
  260. }
  261. +EXPORT_SYMBOL_GPL(bcma_find_core_unit);
  262. bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
  263. int timeout)
  264. @@ -176,6 +165,7 @@ static int bcma_register_cores(struct bc
  265. bcma_err(bus,
  266. "Could not register dev for core 0x%03X\n",
  267. core->id.id);
  268. + put_device(&core->dev);
  269. continue;
  270. }
  271. core->dev_registered = true;
  272. --- a/include/linux/bcma/bcma.h
  273. +++ b/include/linux/bcma/bcma.h
  274. @@ -418,7 +418,14 @@ static inline void bcma_maskset16(struct
  275. bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
  276. }
  277. -extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
  278. +extern struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
  279. + u8 unit);
  280. +static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus,
  281. + u16 coreid)
  282. +{
  283. + return bcma_find_core_unit(bus, coreid, 0);
  284. +}
  285. +
  286. extern bool bcma_core_is_enabled(struct bcma_device *core);
  287. extern void bcma_core_disable(struct bcma_device *core, u32 flags);
  288. extern int bcma_core_enable(struct bcma_device *core, u32 flags);
  289. --- a/include/linux/bcma/bcma_driver_chipcommon.h
  290. +++ b/include/linux/bcma/bcma_driver_chipcommon.h
  291. @@ -640,6 +640,7 @@ struct bcma_drv_cc {
  292. spinlock_t gpio_lock;
  293. #ifdef CONFIG_BCMA_DRIVER_GPIO
  294. struct gpio_chip gpio;
  295. + struct irq_domain *irq_domain;
  296. #endif
  297. };