1b88dfdda0a979b2c874f767de048a086e15bab0
[openwrt.git] / target / linux / generic / patches-3.12 / 025-bcma_backport.patch
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  
11 --- a/drivers/bcma/bcma_private.h
12 +++ b/drivers/bcma/bcma_private.h
13 @@ -33,8 +33,6 @@ int __init bcma_bus_early_register(struc
14  int bcma_bus_suspend(struct bcma_bus *bus);
15  int bcma_bus_resume(struct bcma_bus *bus);
16  #endif
17 -struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
18 -                                       u8 unit);
19  
20  /* scan.c */
21  int bcma_bus_scan(struct bcma_bus *bus);
22 --- a/drivers/bcma/driver_chipcommon_sflash.c
23 +++ b/drivers/bcma/driver_chipcommon_sflash.c
24 @@ -38,7 +38,7 @@ static const struct bcma_sflash_tbl_e bc
25         { "M25P32", 0x15, 0x10000, 64, },
26         { "M25P64", 0x16, 0x10000, 128, },
27         { "M25FL128", 0x17, 0x10000, 256, },
28 -       { 0 },
29 +       { NULL },
30  };
31  
32  static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
33 @@ -56,7 +56,7 @@ static const struct bcma_sflash_tbl_e bc
34         { "SST25VF016", 0x41, 0x1000, 512, },
35         { "SST25VF032", 0x4a, 0x1000, 1024, },
36         { "SST25VF064", 0x4b, 0x1000, 2048, },
37 -       { 0 },
38 +       { NULL },
39  };
40  
41  static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
42 @@ -67,7 +67,7 @@ static const struct bcma_sflash_tbl_e bc
43         { "AT45DB161", 0x2c, 512, 4096, },
44         { "AT45DB321", 0x34, 512, 8192, },
45         { "AT45DB642", 0x3c, 1024, 8192, },
46 -       { 0 },
47 +       { NULL },
48  };
49  
50  static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode)
51 --- a/drivers/bcma/driver_gpio.c
52 +++ b/drivers/bcma/driver_gpio.c
53 @@ -9,6 +9,9 @@
54   */
55  
56  #include <linux/gpio.h>
57 +#include <linux/irq.h>
58 +#include <linux/interrupt.h>
59 +#include <linux/irqdomain.h>
60  #include <linux/export.h>
61  #include <linux/bcma/bcma.h>
62  
63 @@ -73,19 +76,136 @@ static void bcma_gpio_free(struct gpio_c
64         bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
65  }
66  
67 +#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
68  static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
69  {
70         struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
71  
72         if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
73 -               return bcma_core_irq(cc->core);
74 +               return irq_find_mapping(cc->irq_domain, gpio);
75         else
76                 return -EINVAL;
77  }
78  
79 +static void bcma_gpio_irq_unmask(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 +       u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
84 +
85 +       bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
86 +       bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
87 +}
88 +
89 +static void bcma_gpio_irq_mask(struct irq_data *d)
90 +{
91 +       struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
92 +       int gpio = irqd_to_hwirq(d);
93 +
94 +       bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
95 +}
96 +
97 +static struct irq_chip bcma_gpio_irq_chip = {
98 +       .name           = "BCMA-GPIO",
99 +       .irq_mask       = bcma_gpio_irq_mask,
100 +       .irq_unmask     = bcma_gpio_irq_unmask,
101 +};
102 +
103 +static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
104 +{
105 +       struct bcma_drv_cc *cc = dev_id;
106 +       u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
107 +       u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
108 +       u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
109 +       unsigned long irqs = (val ^ pol) & mask;
110 +       int gpio;
111 +
112 +       if (!irqs)
113 +               return IRQ_NONE;
114 +
115 +       for_each_set_bit(gpio, &irqs, cc->gpio.ngpio)
116 +               generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio));
117 +       bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
118 +
119 +       return IRQ_HANDLED;
120 +}
121 +
122 +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
123 +{
124 +       struct gpio_chip *chip = &cc->gpio;
125 +       int gpio, hwirq, err;
126 +
127 +       if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
128 +               return 0;
129 +
130 +       cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
131 +                                              &irq_domain_simple_ops, cc);
132 +       if (!cc->irq_domain) {
133 +               err = -ENODEV;
134 +               goto err_irq_domain;
135 +       }
136 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
137 +               int irq = irq_create_mapping(cc->irq_domain, gpio);
138 +
139 +               irq_set_chip_data(irq, cc);
140 +               irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
141 +                                        handle_simple_irq);
142 +       }
143 +
144 +       hwirq = bcma_core_irq(cc->core);
145 +       err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
146 +                         cc);
147 +       if (err)
148 +               goto err_req_irq;
149 +
150 +       bcma_chipco_gpio_intmask(cc, ~0, 0);
151 +       bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
152 +
153 +       return 0;
154 +
155 +err_req_irq:
156 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
157 +               int irq = irq_find_mapping(cc->irq_domain, gpio);
158 +
159 +               irq_dispose_mapping(irq);
160 +       }
161 +       irq_domain_remove(cc->irq_domain);
162 +err_irq_domain:
163 +       return err;
164 +}
165 +
166 +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
167 +{
168 +       struct gpio_chip *chip = &cc->gpio;
169 +       int gpio;
170 +
171 +       if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
172 +               return;
173 +
174 +       bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
175 +       free_irq(bcma_core_irq(cc->core), cc);
176 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
177 +               int irq = irq_find_mapping(cc->irq_domain, gpio);
178 +
179 +               irq_dispose_mapping(irq);
180 +       }
181 +       irq_domain_remove(cc->irq_domain);
182 +}
183 +#else
184 +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
185 +{
186 +       return 0;
187 +}
188 +
189 +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
190 +{
191 +}
192 +#endif
193 +
194  int bcma_gpio_init(struct bcma_drv_cc *cc)
195  {
196         struct gpio_chip *chip = &cc->gpio;
197 +       int err;
198  
199         chip->label             = "bcma_gpio";
200         chip->owner             = THIS_MODULE;
201 @@ -95,8 +215,17 @@ int bcma_gpio_init(struct bcma_drv_cc *c
202         chip->set               = bcma_gpio_set_value;
203         chip->direction_input   = bcma_gpio_direction_input;
204         chip->direction_output  = bcma_gpio_direction_output;
205 +#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
206         chip->to_irq            = bcma_gpio_to_irq;
207 -       chip->ngpio             = 16;
208 +#endif
209 +       switch (cc->core->bus->chipinfo.id) {
210 +       case BCMA_CHIP_ID_BCM5357:
211 +               chip->ngpio     = 32;
212 +               break;
213 +       default:
214 +               chip->ngpio     = 16;
215 +       }
216 +
217         /* There is just one SoC in one device and its GPIO addresses should be
218          * deterministic to address them more easily. The other buses could get
219          * a random base number. */
220 @@ -105,10 +234,21 @@ int bcma_gpio_init(struct bcma_drv_cc *c
221         else
222                 chip->base              = -1;
223  
224 -       return gpiochip_add(chip);
225 +       err = bcma_gpio_irq_domain_init(cc);
226 +       if (err)
227 +               return err;
228 +
229 +       err = gpiochip_add(chip);
230 +       if (err) {
231 +               bcma_gpio_irq_domain_exit(cc);
232 +               return err;
233 +       }
234 +
235 +       return 0;
236  }
237  
238  int bcma_gpio_unregister(struct bcma_drv_cc *cc)
239  {
240 +       bcma_gpio_irq_domain_exit(cc);
241         return gpiochip_remove(&cc->gpio);
242  }
243 --- a/drivers/bcma/host_pci.c
244 +++ b/drivers/bcma/host_pci.c
245 @@ -188,8 +188,11 @@ static int bcma_host_pci_probe(struct pc
246                 pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
247  
248         /* SSB needed additional powering up, do we have any AMBA PCI cards? */
249 -       if (!pci_is_pcie(dev))
250 -               bcma_err(bus, "PCI card detected, report problems.\n");
251 +       if (!pci_is_pcie(dev)) {
252 +               bcma_err(bus, "PCI card detected, they are not supported.\n");
253 +               err = -ENXIO;
254 +               goto err_pci_release_regions;
255 +       }
256  
257         /* Map MMIO */
258         err = -ENOMEM;
259 @@ -235,7 +238,6 @@ static void bcma_host_pci_remove(struct
260         pci_release_regions(dev);
261         pci_disable_device(dev);
262         kfree(bus);
263 -       pci_set_drvdata(dev, NULL);
264  }
265  
266  #ifdef CONFIG_PM_SLEEP
267 @@ -267,8 +269,9 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc
268  
269  #endif /* CONFIG_PM_SLEEP */
270  
271 -static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
272 +static const struct pci_device_id bcma_pci_bridge_tbl[] = {
273         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
274 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
275         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
276         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
277         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
278 --- a/drivers/bcma/main.c
279 +++ b/drivers/bcma/main.c
280 @@ -30,28 +30,37 @@ static ssize_t manuf_show(struct device
281         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
282         return sprintf(buf, "0x%03X\n", core->id.manuf);
283  }
284 +static DEVICE_ATTR_RO(manuf);
285 +
286  static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
287  {
288         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
289         return sprintf(buf, "0x%03X\n", core->id.id);
290  }
291 +static DEVICE_ATTR_RO(id);
292 +
293  static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
294  {
295         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
296         return sprintf(buf, "0x%02X\n", core->id.rev);
297  }
298 +static DEVICE_ATTR_RO(rev);
299 +
300  static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
301  {
302         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
303         return sprintf(buf, "0x%X\n", core->id.class);
304  }
305 -static struct device_attribute bcma_device_attrs[] = {
306 -       __ATTR_RO(manuf),
307 -       __ATTR_RO(id),
308 -       __ATTR_RO(rev),
309 -       __ATTR_RO(class),
310 -       __ATTR_NULL,
311 +static DEVICE_ATTR_RO(class);
312 +
313 +static struct attribute *bcma_device_attrs[] = {
314 +       &dev_attr_manuf.attr,
315 +       &dev_attr_id.attr,
316 +       &dev_attr_rev.attr,
317 +       &dev_attr_class.attr,
318 +       NULL,
319  };
320 +ATTRIBUTE_GROUPS(bcma_device);
321  
322  static struct bus_type bcma_bus_type = {
323         .name           = "bcma",
324 @@ -59,7 +68,7 @@ static struct bus_type bcma_bus_type = {
325         .probe          = bcma_device_probe,
326         .remove         = bcma_device_remove,
327         .uevent         = bcma_device_uevent,
328 -       .dev_attrs      = bcma_device_attrs,
329 +       .dev_groups     = bcma_device_groups,
330  };
331  
332  static u16 bcma_cc_core_id(struct bcma_bus *bus)
333 @@ -69,18 +78,6 @@ static u16 bcma_cc_core_id(struct bcma_b
334         return BCMA_CORE_CHIPCOMMON;
335  }
336  
337 -struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
338 -{
339 -       struct bcma_device *core;
340 -
341 -       list_for_each_entry(core, &bus->cores, list) {
342 -               if (core->id.id == coreid)
343 -                       return core;
344 -       }
345 -       return NULL;
346 -}
347 -EXPORT_SYMBOL_GPL(bcma_find_core);
348 -
349  struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
350                                         u8 unit)
351  {
352 @@ -92,6 +89,7 @@ struct bcma_device *bcma_find_core_unit(
353         }
354         return NULL;
355  }
356 +EXPORT_SYMBOL_GPL(bcma_find_core_unit);
357  
358  bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
359                      int timeout)
360 @@ -167,6 +165,7 @@ static int bcma_register_cores(struct bc
361                         bcma_err(bus,
362                                  "Could not register dev for core 0x%03X\n",
363                                  core->id.id);
364 +                       put_device(&core->dev);
365                         continue;
366                 }
367                 core->dev_registered = true;
368 --- a/include/linux/bcma/bcma.h
369 +++ b/include/linux/bcma/bcma.h
370 @@ -418,7 +418,14 @@ static inline void bcma_maskset16(struct
371         bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
372  }
373  
374 -extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
375 +extern struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
376 +                                              u8 unit);
377 +static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus,
378 +                                                u16 coreid)
379 +{
380 +       return bcma_find_core_unit(bus, coreid, 0);
381 +}
382 +
383  extern bool bcma_core_is_enabled(struct bcma_device *core);
384  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
385  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
386 --- a/include/linux/bcma/bcma_driver_chipcommon.h
387 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
388 @@ -640,6 +640,7 @@ struct bcma_drv_cc {
389         spinlock_t gpio_lock;
390  #ifdef CONFIG_BCMA_DRIVER_GPIO
391         struct gpio_chip gpio;
392 +       struct irq_domain *irq_domain;
393  #endif
394  };
395