Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Linus Walleij and committed by
Kalle Valo
74f4e0cc 1165dd90

+31 -64
+1 -1
drivers/bcma/Kconfig
··· 92 92 config BCMA_DRIVER_GPIO 93 93 bool "BCMA GPIO driver" 94 94 depends on BCMA && GPIOLIB 95 - select IRQ_DOMAIN if BCMA_HOST_SOC 95 + select GPIOLIB_IRQCHIP if BCMA_HOST_SOC 96 96 help 97 97 Driver to provide access to the GPIO pins of the bcma bus. 98 98
+30 -62
drivers/bcma/driver_gpio.c
··· 8 8 * Licensed under the GNU/GPL. See COPYING for details. 9 9 */ 10 10 11 - #include <linux/gpio.h> 12 - #include <linux/irq.h> 11 + #include <linux/gpio/driver.h> 13 12 #include <linux/interrupt.h> 14 - #include <linux/irqdomain.h> 15 13 #include <linux/export.h> 16 14 #include <linux/bcma/bcma.h> 17 15 ··· 77 79 } 78 80 79 81 #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) 80 - static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) 81 - { 82 - struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 83 - 84 - if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) 85 - return irq_find_mapping(cc->irq_domain, gpio); 86 - else 87 - return -EINVAL; 88 - } 89 82 90 83 static void bcma_gpio_irq_unmask(struct irq_data *d) 91 84 { 92 - struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); 85 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 86 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc); 93 87 int gpio = irqd_to_hwirq(d); 94 88 u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); 95 89 ··· 91 101 92 102 static void bcma_gpio_irq_mask(struct irq_data *d) 93 103 { 94 - struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); 104 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 105 + struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc); 95 106 int gpio = irqd_to_hwirq(d); 96 107 97 108 bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); ··· 107 116 static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) 108 117 { 109 118 struct bcma_drv_cc *cc = dev_id; 119 + struct gpio_chip *gc = &cc->gpio; 110 120 u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN); 111 121 u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ); 112 122 u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL); ··· 117 125 if (!irqs) 118 126 return IRQ_NONE; 119 127 120 - for_each_set_bit(gpio, &irqs, cc->gpio.ngpio) 121 - generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio)); 128 + for_each_set_bit(gpio, &irqs, gc->ngpio) 129 + generic_handle_irq(irq_find_mapping(gc->irqdomain, gpio)); 122 130 bcma_chipco_gpio_polarity(cc, irqs, val & irqs); 123 131 124 132 return IRQ_HANDLED; 125 133 } 126 134 127 - static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) 135 + static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) 128 136 { 129 137 struct gpio_chip *chip = &cc->gpio; 130 - int gpio, hwirq, err; 138 + int hwirq, err; 131 139 132 140 if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) 133 141 return 0; 134 - 135 - cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, 136 - &irq_domain_simple_ops, cc); 137 - if (!cc->irq_domain) { 138 - err = -ENODEV; 139 - goto err_irq_domain; 140 - } 141 - for (gpio = 0; gpio < chip->ngpio; gpio++) { 142 - int irq = irq_create_mapping(cc->irq_domain, gpio); 143 - 144 - irq_set_chip_data(irq, cc); 145 - irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip, 146 - handle_simple_irq); 147 - } 148 142 149 143 hwirq = bcma_core_irq(cc->core, 0); 150 144 err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", 151 145 cc); 152 146 if (err) 153 - goto err_req_irq; 147 + return err; 154 148 155 149 bcma_chipco_gpio_intmask(cc, ~0, 0); 156 150 bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); 157 151 158 - return 0; 159 - 160 - err_req_irq: 161 - for (gpio = 0; gpio < chip->ngpio; gpio++) { 162 - int irq = irq_find_mapping(cc->irq_domain, gpio); 163 - 164 - irq_dispose_mapping(irq); 152 + err = gpiochip_irqchip_add(chip, 153 + &bcma_gpio_irq_chip, 154 + 0, 155 + handle_simple_irq, 156 + IRQ_TYPE_NONE); 157 + if (err) { 158 + free_irq(hwirq, cc); 159 + return err; 165 160 } 166 - irq_domain_remove(cc->irq_domain); 167 - err_irq_domain: 168 - return err; 161 + 162 + return 0; 169 163 } 170 164 171 - static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) 165 + static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc) 172 166 { 173 - struct gpio_chip *chip = &cc->gpio; 174 - int gpio; 175 - 176 167 if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) 177 168 return; 178 169 179 170 bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); 180 171 free_irq(bcma_core_irq(cc->core, 0), cc); 181 - for (gpio = 0; gpio < chip->ngpio; gpio++) { 182 - int irq = irq_find_mapping(cc->irq_domain, gpio); 183 - 184 - irq_dispose_mapping(irq); 185 - } 186 - irq_domain_remove(cc->irq_domain); 187 172 } 188 173 #else 189 - static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) 174 + static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) 190 175 { 191 176 return 0; 192 177 } 193 178 194 - static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) 179 + static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc) 195 180 { 196 181 } 197 182 #endif ··· 187 218 chip->set = bcma_gpio_set_value; 188 219 chip->direction_input = bcma_gpio_direction_input; 189 220 chip->direction_output = bcma_gpio_direction_output; 190 - #if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) 191 - chip->to_irq = bcma_gpio_to_irq; 192 - #endif 221 + chip->owner = THIS_MODULE; 222 + chip->dev = bcma_bus_get_host_dev(bus); 193 223 #if IS_BUILTIN(CONFIG_OF) 194 224 if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) 195 225 chip->of_node = cc->core->dev.of_node; ··· 216 248 else 217 249 chip->base = -1; 218 250 219 - err = bcma_gpio_irq_domain_init(cc); 251 + err = gpiochip_add(chip); 220 252 if (err) 221 253 return err; 222 254 223 - err = gpiochip_add(chip); 255 + err = bcma_gpio_irq_init(cc); 224 256 if (err) { 225 - bcma_gpio_irq_domain_exit(cc); 257 + gpiochip_remove(chip); 226 258 return err; 227 259 } 228 260 ··· 231 263 232 264 int bcma_gpio_unregister(struct bcma_drv_cc *cc) 233 265 { 234 - bcma_gpio_irq_domain_exit(cc); 266 + bcma_gpio_irq_exit(cc); 235 267 gpiochip_remove(&cc->gpio); 236 268 return 0; 237 269 }
-1
include/linux/bcma/bcma_driver_chipcommon.h
··· 640 640 spinlock_t gpio_lock; 641 641 #ifdef CONFIG_BCMA_DRIVER_GPIO 642 642 struct gpio_chip gpio; 643 - struct irq_domain *irq_domain; 644 643 #endif 645 644 }; 646 645