diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2015-08-13 18:21:45 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-08-18 02:08:47 -0400 |
commit | 74f4e0cc61080f63f28e8d519bdf437957e64217 (patch) | |
tree | 4c12a5b2cc3a09f240698c796abb17ca3002c5fb /drivers/bcma | |
parent | 1165dd900cc8de3addbc8bef7e6196b07799d25e (diff) |
bcma: switch GPIO portions to use GPIOLIB_IRQCHIP
This switches the BCMA GPIO driver to use GPIOLIB_IRQCHIP to
handle its interrupts instead of rolling its own copy of the
irqdomain handling etc.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/bcma')
-rw-r--r-- | drivers/bcma/Kconfig | 2 | ||||
-rw-r--r-- | drivers/bcma/driver_gpio.c | 92 |
2 files changed, 31 insertions, 63 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index be5fffb6da24..023d448ed3fa 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig | |||
@@ -92,7 +92,7 @@ config BCMA_DRIVER_GMAC_CMN | |||
92 | config BCMA_DRIVER_GPIO | 92 | config BCMA_DRIVER_GPIO |
93 | bool "BCMA GPIO driver" | 93 | bool "BCMA GPIO driver" |
94 | depends on BCMA && GPIOLIB | 94 | depends on BCMA && GPIOLIB |
95 | select IRQ_DOMAIN if BCMA_HOST_SOC | 95 | select GPIOLIB_IRQCHIP if BCMA_HOST_SOC |
96 | help | 96 | help |
97 | Driver to provide access to the GPIO pins of the bcma bus. | 97 | Driver to provide access to the GPIO pins of the bcma bus. |
98 | 98 | ||
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 5f6018e7cd4c..504899a72966 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c | |||
@@ -8,10 +8,8 @@ | |||
8 | * Licensed under the GNU/GPL. See COPYING for details. | 8 | * Licensed under the GNU/GPL. See COPYING for details. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/gpio.h> | 11 | #include <linux/gpio/driver.h> |
12 | #include <linux/irq.h> | ||
13 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
14 | #include <linux/irqdomain.h> | ||
15 | #include <linux/export.h> | 13 | #include <linux/export.h> |
16 | #include <linux/bcma/bcma.h> | 14 | #include <linux/bcma/bcma.h> |
17 | 15 | ||
@@ -79,19 +77,11 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio) | |||
79 | } | 77 | } |
80 | 78 | ||
81 | #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) | 79 | #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) |
82 | static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | ||
83 | { | ||
84 | struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); | ||
85 | |||
86 | if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) | ||
87 | return irq_find_mapping(cc->irq_domain, gpio); | ||
88 | else | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | 80 | ||
92 | static void bcma_gpio_irq_unmask(struct irq_data *d) | 81 | static void bcma_gpio_irq_unmask(struct irq_data *d) |
93 | { | 82 | { |
94 | struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); | 83 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
84 | struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc); | ||
95 | int gpio = irqd_to_hwirq(d); | 85 | int gpio = irqd_to_hwirq(d); |
96 | u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); | 86 | u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); |
97 | 87 | ||
@@ -101,7 +91,8 @@ static void bcma_gpio_irq_unmask(struct irq_data *d) | |||
101 | 91 | ||
102 | static void bcma_gpio_irq_mask(struct irq_data *d) | 92 | static void bcma_gpio_irq_mask(struct irq_data *d) |
103 | { | 93 | { |
104 | struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); | 94 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
95 | struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc); | ||
105 | int gpio = irqd_to_hwirq(d); | 96 | int gpio = irqd_to_hwirq(d); |
106 | 97 | ||
107 | bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); | 98 | bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); |
@@ -116,6 +107,7 @@ static struct irq_chip bcma_gpio_irq_chip = { | |||
116 | static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) | 107 | static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) |
117 | { | 108 | { |
118 | struct bcma_drv_cc *cc = dev_id; | 109 | struct bcma_drv_cc *cc = dev_id; |
110 | struct gpio_chip *gc = &cc->gpio; | ||
119 | u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN); | 111 | u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN); |
120 | u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ); | 112 | u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ); |
121 | u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL); | 113 | u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL); |
@@ -125,81 +117,58 @@ static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) | |||
125 | if (!irqs) | 117 | if (!irqs) |
126 | return IRQ_NONE; | 118 | return IRQ_NONE; |
127 | 119 | ||
128 | for_each_set_bit(gpio, &irqs, cc->gpio.ngpio) | 120 | for_each_set_bit(gpio, &irqs, gc->ngpio) |
129 | generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio)); | 121 | generic_handle_irq(irq_find_mapping(gc->irqdomain, gpio)); |
130 | bcma_chipco_gpio_polarity(cc, irqs, val & irqs); | 122 | bcma_chipco_gpio_polarity(cc, irqs, val & irqs); |
131 | 123 | ||
132 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
133 | } | 125 | } |
134 | 126 | ||
135 | static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) | 127 | static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) |
136 | { | 128 | { |
137 | struct gpio_chip *chip = &cc->gpio; | 129 | struct gpio_chip *chip = &cc->gpio; |
138 | int gpio, hwirq, err; | 130 | int hwirq, err; |
139 | 131 | ||
140 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) | 132 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) |
141 | return 0; | 133 | return 0; |
142 | 134 | ||
143 | cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, | ||
144 | &irq_domain_simple_ops, cc); | ||
145 | if (!cc->irq_domain) { | ||
146 | err = -ENODEV; | ||
147 | goto err_irq_domain; | ||
148 | } | ||
149 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
150 | int irq = irq_create_mapping(cc->irq_domain, gpio); | ||
151 | |||
152 | irq_set_chip_data(irq, cc); | ||
153 | irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip, | ||
154 | handle_simple_irq); | ||
155 | } | ||
156 | |||
157 | hwirq = bcma_core_irq(cc->core, 0); | 135 | hwirq = bcma_core_irq(cc->core, 0); |
158 | err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", | 136 | err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", |
159 | cc); | 137 | cc); |
160 | if (err) | 138 | if (err) |
161 | goto err_req_irq; | 139 | return err; |
162 | 140 | ||
163 | bcma_chipco_gpio_intmask(cc, ~0, 0); | 141 | bcma_chipco_gpio_intmask(cc, ~0, 0); |
164 | bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); | 142 | bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); |
165 | 143 | ||
166 | return 0; | 144 | err = gpiochip_irqchip_add(chip, |
167 | 145 | &bcma_gpio_irq_chip, | |
168 | err_req_irq: | 146 | 0, |
169 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | 147 | handle_simple_irq, |
170 | int irq = irq_find_mapping(cc->irq_domain, gpio); | 148 | IRQ_TYPE_NONE); |
171 | 149 | if (err) { | |
172 | irq_dispose_mapping(irq); | 150 | free_irq(hwirq, cc); |
151 | return err; | ||
173 | } | 152 | } |
174 | irq_domain_remove(cc->irq_domain); | 153 | |
175 | err_irq_domain: | 154 | return 0; |
176 | return err; | ||
177 | } | 155 | } |
178 | 156 | ||
179 | static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) | 157 | static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc) |
180 | { | 158 | { |
181 | struct gpio_chip *chip = &cc->gpio; | ||
182 | int gpio; | ||
183 | |||
184 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) | 159 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) |
185 | return; | 160 | return; |
186 | 161 | ||
187 | bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); | 162 | bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); |
188 | free_irq(bcma_core_irq(cc->core, 0), cc); | 163 | free_irq(bcma_core_irq(cc->core, 0), cc); |
189 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
190 | int irq = irq_find_mapping(cc->irq_domain, gpio); | ||
191 | |||
192 | irq_dispose_mapping(irq); | ||
193 | } | ||
194 | irq_domain_remove(cc->irq_domain); | ||
195 | } | 164 | } |
196 | #else | 165 | #else |
197 | static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) | 166 | static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) |
198 | { | 167 | { |
199 | return 0; | 168 | return 0; |
200 | } | 169 | } |
201 | 170 | ||
202 | static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) | 171 | static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc) |
203 | { | 172 | { |
204 | } | 173 | } |
205 | #endif | 174 | #endif |
@@ -218,9 +187,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
218 | chip->set = bcma_gpio_set_value; | 187 | chip->set = bcma_gpio_set_value; |
219 | chip->direction_input = bcma_gpio_direction_input; | 188 | chip->direction_input = bcma_gpio_direction_input; |
220 | chip->direction_output = bcma_gpio_direction_output; | 189 | chip->direction_output = bcma_gpio_direction_output; |
221 | #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) | 190 | chip->owner = THIS_MODULE; |
222 | chip->to_irq = bcma_gpio_to_irq; | 191 | chip->dev = bcma_bus_get_host_dev(bus); |
223 | #endif | ||
224 | #if IS_BUILTIN(CONFIG_OF) | 192 | #if IS_BUILTIN(CONFIG_OF) |
225 | if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) | 193 | if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) |
226 | chip->of_node = cc->core->dev.of_node; | 194 | chip->of_node = cc->core->dev.of_node; |
@@ -248,13 +216,13 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
248 | else | 216 | else |
249 | chip->base = -1; | 217 | chip->base = -1; |
250 | 218 | ||
251 | err = bcma_gpio_irq_domain_init(cc); | 219 | err = gpiochip_add(chip); |
252 | if (err) | 220 | if (err) |
253 | return err; | 221 | return err; |
254 | 222 | ||
255 | err = gpiochip_add(chip); | 223 | err = bcma_gpio_irq_init(cc); |
256 | if (err) { | 224 | if (err) { |
257 | bcma_gpio_irq_domain_exit(cc); | 225 | gpiochip_remove(chip); |
258 | return err; | 226 | return err; |
259 | } | 227 | } |
260 | 228 | ||
@@ -263,7 +231,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
263 | 231 | ||
264 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) | 232 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) |
265 | { | 233 | { |
266 | bcma_gpio_irq_domain_exit(cc); | 234 | bcma_gpio_irq_exit(cc); |
267 | gpiochip_remove(&cc->gpio); | 235 | gpiochip_remove(&cc->gpio); |
268 | return 0; | 236 | return 0; |
269 | } | 237 | } |