aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-pl061.c
diff options
context:
space:
mode:
authorRob Herring <rob.herring@calxeda.com>2012-01-04 11:36:07 -0500
committerRob Herring <rob.herring@calxeda.com>2012-01-05 09:47:27 -0500
commit2de0dbc5f6830e7659083d1929f57cb88b16a3b6 (patch)
treed33e2c6bc9ebeb1241aacb97bde57cfa0f4f8fd2 /drivers/gpio/gpio-pl061.c
parent3ab52475447641a6facf6ee5450bea24e477b811 (diff)
gpio: pl061: remove combined interrupt
Drivers should not have a dependency on NR_IRQS. Doing so may break with SPARSE_IRQ enabled. As there are no in kernel users of the pl061 which have multiple instances with their interrupts combined to a single parent interrupt, remove this functionality. If this capability is needed later, it could be supported more cleanly by just using a devicetree property. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Reviewed-by: Viresh Kumar <viresh.kumar@st.com> Cc: Rajeev Kumar <rajeev-dlh.kumar@st.com> Acked-by: Baruch Siach <baruch@tkos.co.il> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio/gpio-pl061.c')
-rw-r--r--drivers/gpio/gpio-pl061.c44
1 files changed, 8 insertions, 36 deletions
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 96ff6b28e9ad..23065f6b3de1 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -12,7 +12,6 @@
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/list.h>
16#include <linux/io.h> 15#include <linux/io.h>
17#include <linux/ioport.h> 16#include <linux/ioport.h>
18#include <linux/irq.h> 17#include <linux/irq.h>
@@ -37,13 +36,6 @@
37#define PL061_GPIO_NR 8 36#define PL061_GPIO_NR 8
38 37
39struct pl061_gpio { 38struct pl061_gpio {
40 /* We use a list of pl061_gpio structs for each trigger IRQ in the main
41 * interrupts controller of the system. We need this to support systems
42 * in which more that one PL061s are connected to the same IRQ. The ISR
43 * interates through this list to find the source of the interrupt.
44 */
45 struct list_head list;
46
47 /* Each of the two spinlocks protects a different set of hardware 39 /* Each of the two spinlocks protects a different set of hardware
48 * regiters and data structurs. This decouples the code of the IRQ from 40 * regiters and data structurs. This decouples the code of the IRQ from
49 * the GPIO code. This also makes the case of a GPIO routine call from 41 * the GPIO code. This also makes the case of a GPIO routine call from
@@ -172,26 +164,20 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
172 164
173static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) 165static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
174{ 166{
175 struct list_head *chip_list = irq_get_handler_data(irq); 167 unsigned long pending;
176 struct list_head *ptr; 168 int offset;
177 struct pl061_gpio *chip; 169 struct pl061_gpio *chip = irq_desc_get_handler_data(desc);
178 struct irq_chip *irqchip = irq_desc_get_chip(desc); 170 struct irq_chip *irqchip = irq_desc_get_chip(desc);
179 171
180 chained_irq_enter(irqchip, desc); 172 chained_irq_enter(irqchip, desc);
181 list_for_each(ptr, chip_list) {
182 unsigned long pending;
183 int offset;
184
185 chip = list_entry(ptr, struct pl061_gpio, list);
186 pending = readb(chip->base + GPIOMIS);
187 writeb(pending, chip->base + GPIOIC);
188
189 if (pending == 0)
190 continue;
191 173
174 pending = readb(chip->base + GPIOMIS);
175 writeb(pending, chip->base + GPIOIC);
176 if (pending) {
192 for_each_set_bit(offset, &pending, PL061_GPIO_NR) 177 for_each_set_bit(offset, &pending, PL061_GPIO_NR)
193 generic_handle_irq(pl061_to_irq(&chip->gc, offset)); 178 generic_handle_irq(pl061_to_irq(&chip->gc, offset));
194 } 179 }
180
195 chained_irq_exit(irqchip, desc); 181 chained_irq_exit(irqchip, desc);
196} 182}
197 183
@@ -218,9 +204,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
218{ 204{
219 struct pl061_platform_data *pdata; 205 struct pl061_platform_data *pdata;
220 struct pl061_gpio *chip; 206 struct pl061_gpio *chip;
221 struct list_head *chip_list;
222 int ret, irq, i; 207 int ret, irq, i;
223 static DECLARE_BITMAP(init_irq, NR_IRQS);
224 208
225 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 209 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
226 if (chip == NULL) 210 if (chip == NULL)
@@ -251,7 +235,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
251 } 235 }
252 236
253 spin_lock_init(&chip->lock); 237 spin_lock_init(&chip->lock);
254 INIT_LIST_HEAD(&chip->list);
255 238
256 chip->gc.direction_input = pl061_direction_input; 239 chip->gc.direction_input = pl061_direction_input;
257 chip->gc.direction_output = pl061_direction_output; 240 chip->gc.direction_output = pl061_direction_output;
@@ -283,18 +266,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
283 goto iounmap; 266 goto iounmap;
284 } 267 }
285 irq_set_chained_handler(irq, pl061_irq_handler); 268 irq_set_chained_handler(irq, pl061_irq_handler);
286 if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */ 269 irq_set_handler_data(irq, chip);
287 chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL);
288 if (chip_list == NULL) {
289 clear_bit(irq, init_irq);
290 ret = -ENOMEM;
291 goto iounmap;
292 }
293 INIT_LIST_HEAD(chip_list);
294 irq_set_handler_data(irq, chip_list);
295 } else
296 chip_list = irq_get_handler_data(irq);
297 list_add(&chip->list, chip_list);
298 270
299 for (i = 0; i < PL061_GPIO_NR; i++) { 271 for (i = 0; i < PL061_GPIO_NR; i++) {
300 if (pdata) { 272 if (pdata) {