OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> |
2 | Date: Fri, 18 Dec 2015 07:51:08 +0100 |
||
3 | Subject: [PATCH] Revert "bcma: switch GPIO portions to use GPIOLIB_IRQCHIP" |
||
4 | MIME-Version: 1.0 |
||
5 | Content-Type: text/plain; charset=UTF-8 |
||
6 | Content-Transfer-Encoding: 8bit |
||
7 | |||
8 | This reverts commit 74f4e0cc61080f63f28e8d519bdf437957e64217. |
||
9 | |||
10 | On BCM47XX (MIPS) bcma_bus_get_host_dev returns NULL which results in: |
||
11 | [ 0.157054] missing gpiochip .dev parent pointer |
||
12 | [ 0.157287] bcma: bus0: Error registering GPIO driver: -22 |
||
13 | |||
14 | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> |
||
15 | --- |
||
16 | drivers/bcma/Kconfig | 2 +- |
||
17 | drivers/bcma/driver_gpio.c | 92 +++++++++++++++++++---------- |
||
18 | include/linux/bcma/bcma_driver_chipcommon.h | 1 + |
||
19 | 3 files changed, 64 insertions(+), 31 deletions(-) |
||
20 | |||
21 | --- a/drivers/bcma/Kconfig |
||
22 | +++ b/drivers/bcma/Kconfig |
||
23 | @@ -104,7 +104,7 @@ config BCMA_DRIVER_GMAC_CMN |
||
24 | config BCMA_DRIVER_GPIO |
||
25 | bool "BCMA GPIO driver" |
||
26 | depends on BCMA && GPIOLIB |
||
27 | - select GPIOLIB_IRQCHIP if BCMA_HOST_SOC |
||
28 | + select IRQ_DOMAIN if BCMA_HOST_SOC |
||
29 | help |
||
30 | Driver to provide access to the GPIO pins of the bcma bus. |
||
31 | |||
32 | --- a/drivers/bcma/driver_gpio.c |
||
33 | +++ b/drivers/bcma/driver_gpio.c |
||
34 | @@ -8,8 +8,10 @@ |
||
35 | * Licensed under the GNU/GPL. See COPYING for details. |
||
36 | */ |
||
37 | |||
38 | -#include <linux/gpio/driver.h> |
||
39 | +#include <linux/gpio.h> |
||
40 | +#include <linux/irq.h> |
||
41 | #include <linux/interrupt.h> |
||
42 | +#include <linux/irqdomain.h> |
||
43 | #include <linux/export.h> |
||
44 | #include <linux/bcma/bcma.h> |
||
45 | |||
46 | @@ -72,11 +74,19 @@ static void bcma_gpio_free(struct gpio_c |
||
47 | } |
||
48 | |||
49 | #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) |
||
50 | +static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) |
||
51 | +{ |
||
52 | + struct bcma_drv_cc *cc = gpiochip_get_data(chip); |
||
53 | + |
||
54 | + if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) |
||
55 | + return irq_find_mapping(cc->irq_domain, gpio); |
||
56 | + else |
||
57 | + return -EINVAL; |
||
58 | +} |
||
59 | |||
60 | static void bcma_gpio_irq_unmask(struct irq_data *d) |
||
61 | { |
||
62 | - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
||
63 | - struct bcma_drv_cc *cc = gpiochip_get_data(gc); |
||
64 | + struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); |
||
65 | int gpio = irqd_to_hwirq(d); |
||
66 | u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); |
||
67 | |||
68 | @@ -86,8 +96,7 @@ static void bcma_gpio_irq_unmask(struct |
||
69 | |||
70 | static void bcma_gpio_irq_mask(struct irq_data *d) |
||
71 | { |
||
72 | - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
||
73 | - struct bcma_drv_cc *cc = gpiochip_get_data(gc); |
||
74 | + struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); |
||
75 | int gpio = irqd_to_hwirq(d); |
||
76 | |||
77 | bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); |
||
78 | @@ -102,7 +111,6 @@ static struct irq_chip bcma_gpio_irq_chi |
||
79 | static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) |
||
80 | { |
||
81 | struct bcma_drv_cc *cc = dev_id; |
||
82 | - struct gpio_chip *gc = &cc->gpio; |
||
83 | u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN); |
||
84 | u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ); |
||
85 | u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL); |
||
86 | @@ -112,58 +120,81 @@ static irqreturn_t bcma_gpio_irq_handler |
||
87 | if (!irqs) |
||
88 | return IRQ_NONE; |
||
89 | |||
90 | - for_each_set_bit(gpio, &irqs, gc->ngpio) |
||
91 | - generic_handle_irq(irq_find_mapping(gc->irqdomain, gpio)); |
||
92 | + for_each_set_bit(gpio, &irqs, cc->gpio.ngpio) |
||
93 | + generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio)); |
||
94 | bcma_chipco_gpio_polarity(cc, irqs, val & irqs); |
||
95 | |||
96 | return IRQ_HANDLED; |
||
97 | } |
||
98 | |||
99 | -static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) |
||
100 | +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) |
||
101 | { |
||
102 | struct gpio_chip *chip = &cc->gpio; |
||
103 | - int hwirq, err; |
||
104 | + int gpio, hwirq, err; |
||
105 | |||
106 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) |
||
107 | return 0; |
||
108 | |||
109 | + cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, |
||
110 | + &irq_domain_simple_ops, cc); |
||
111 | + if (!cc->irq_domain) { |
||
112 | + err = -ENODEV; |
||
113 | + goto err_irq_domain; |
||
114 | + } |
||
115 | + for (gpio = 0; gpio < chip->ngpio; gpio++) { |
||
116 | + int irq = irq_create_mapping(cc->irq_domain, gpio); |
||
117 | + |
||
118 | + irq_set_chip_data(irq, cc); |
||
119 | + irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip, |
||
120 | + handle_simple_irq); |
||
121 | + } |
||
122 | + |
||
123 | hwirq = bcma_core_irq(cc->core, 0); |
||
124 | err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", |
||
125 | cc); |
||
126 | if (err) |
||
127 | - return err; |
||
128 | + goto err_req_irq; |
||
129 | |||
130 | bcma_chipco_gpio_intmask(cc, ~0, 0); |
||
131 | bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); |
||
132 | |||
133 | - err = gpiochip_irqchip_add(chip, |
||
134 | - &bcma_gpio_irq_chip, |
||
135 | - 0, |
||
136 | - handle_simple_irq, |
||
137 | - IRQ_TYPE_NONE); |
||
138 | - if (err) { |
||
139 | - free_irq(hwirq, cc); |
||
140 | - return err; |
||
141 | - } |
||
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_exit(struct bcma_drv_cc *cc) |
||
157 | +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) |
||
158 | { |
||
159 | + struct gpio_chip *chip = &cc->gpio; |
||
160 | + int gpio; |
||
161 | + |
||
162 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) |
||
163 | return; |
||
164 | |||
165 | bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); |
||
166 | free_irq(bcma_core_irq(cc->core, 0), cc); |
||
167 | + for (gpio = 0; gpio < chip->ngpio; gpio++) { |
||
168 | + int irq = irq_find_mapping(cc->irq_domain, gpio); |
||
169 | + |
||
170 | + irq_dispose_mapping(irq); |
||
171 | + } |
||
172 | + irq_domain_remove(cc->irq_domain); |
||
173 | } |
||
174 | #else |
||
175 | -static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) |
||
176 | +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) |
||
177 | { |
||
178 | return 0; |
||
179 | } |
||
180 | |||
181 | -static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc) |
||
182 | +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) |
||
183 | { |
||
184 | } |
||
185 | #endif |
||
186 | @@ -182,8 +213,9 @@ int bcma_gpio_init(struct bcma_drv_cc *c |
||
187 | chip->set = bcma_gpio_set_value; |
||
188 | chip->direction_input = bcma_gpio_direction_input; |
||
189 | chip->direction_output = bcma_gpio_direction_output; |
||
190 | - chip->owner = THIS_MODULE; |
||
191 | - chip->parent = bus->dev; |
||
192 | +#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) |
||
193 | + chip->to_irq = bcma_gpio_to_irq; |
||
194 | +#endif |
||
195 | #if IS_BUILTIN(CONFIG_OF) |
||
196 | chip->of_node = cc->core->dev.of_node; |
||
197 | #endif |
||
198 | @@ -212,13 +244,13 @@ int bcma_gpio_init(struct bcma_drv_cc *c |
||
199 | else |
||
200 | chip->base = -1; |
||
201 | |||
202 | - err = gpiochip_add_data(chip, cc); |
||
203 | + err = bcma_gpio_irq_domain_init(cc); |
||
204 | if (err) |
||
205 | return err; |
||
206 | |||
207 | - err = bcma_gpio_irq_init(cc); |
||
208 | + err = gpiochip_add_data(chip, cc); |
||
209 | if (err) { |
||
210 | - gpiochip_remove(chip); |
||
211 | + bcma_gpio_irq_domain_exit(cc); |
||
212 | return err; |
||
213 | } |
||
214 | |||
215 | @@ -227,7 +259,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c |
||
216 | |||
217 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) |
||
218 | { |
||
219 | - bcma_gpio_irq_exit(cc); |
||
220 | + bcma_gpio_irq_domain_exit(cc); |
||
221 | gpiochip_remove(&cc->gpio); |
||
222 | return 0; |
||
223 | } |
||
224 | --- a/include/linux/bcma/bcma_driver_chipcommon.h |
||
225 | +++ b/include/linux/bcma/bcma_driver_chipcommon.h |
||
226 | @@ -645,6 +645,7 @@ struct bcma_drv_cc { |
||
227 | spinlock_t gpio_lock; |
||
228 | #ifdef CONFIG_BCMA_DRIVER_GPIO |
||
229 | struct gpio_chip gpio; |
||
230 | + struct irq_domain *irq_domain; |
||
231 | #endif |
||
232 | }; |
||
233 |