diff options
author | Rob Herring <rob.herring@calxeda.com> | 2012-01-04 11:36:07 -0500 |
---|---|---|
committer | Rob Herring <rob.herring@calxeda.com> | 2012-01-05 09:47:27 -0500 |
commit | 2de0dbc5f6830e7659083d1929f57cb88b16a3b6 (patch) | |
tree | d33e2c6bc9ebeb1241aacb97bde57cfa0f4f8fd2 /drivers/gpio/gpio-pl061.c | |
parent | 3ab52475447641a6facf6ee5450bea24e477b811 (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.c | 44 |
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 | ||
39 | struct pl061_gpio { | 38 | struct 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 | ||
173 | static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | 165 | static 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) { |