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

gpio: pl061: convert driver to use gpiolib irqchip

This converts the PL061 driver to register its chained irq
handler and irqchip using the helpers in the gpiolib core.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+19 -62
+1
drivers/gpio/Kconfig
··· 247 247 bool "PrimeCell PL061 GPIO support" 248 248 depends on ARM_AMBA 249 249 select IRQ_DOMAIN 250 + select GPIOLIB_IRQCHIP 250 251 help 251 252 Say yes here to support the PrimeCell PL061 GPIO device 252 253
+18 -62
drivers/gpio/gpio-pl061.c
··· 15 15 #include <linux/io.h> 16 16 #include <linux/ioport.h> 17 17 #include <linux/irq.h> 18 - #include <linux/irqdomain.h> 19 18 #include <linux/irqchip/chained_irq.h> 20 19 #include <linux/bitops.h> 21 20 #include <linux/workqueue.h> ··· 52 53 spinlock_t lock; 53 54 54 55 void __iomem *base; 55 - struct irq_domain *domain; 56 56 struct gpio_chip gc; 57 57 58 58 #ifdef CONFIG_PM ··· 135 137 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 136 138 } 137 139 138 - static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) 139 - { 140 - struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 141 - 142 - return irq_create_mapping(chip->domain, offset); 143 - } 144 - 145 140 static int pl061_irq_type(struct irq_data *d, unsigned trigger) 146 141 { 147 - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 142 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 143 + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 148 144 int offset = irqd_to_hwirq(d); 149 145 unsigned long flags; 150 146 u8 gpiois, gpioibe, gpioiev; ··· 186 194 { 187 195 unsigned long pending; 188 196 int offset; 189 - struct pl061_gpio *chip = irq_desc_get_handler_data(desc); 197 + struct gpio_chip *gc = irq_desc_get_handler_data(desc); 198 + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 190 199 struct irq_chip *irqchip = irq_desc_get_chip(desc); 191 200 192 201 chained_irq_enter(irqchip, desc); ··· 196 203 writeb(pending, chip->base + GPIOIC); 197 204 if (pending) { 198 205 for_each_set_bit(offset, &pending, PL061_GPIO_NR) 199 - generic_handle_irq(pl061_to_irq(&chip->gc, offset)); 206 + generic_handle_irq(irq_find_mapping(gc->irqdomain, 207 + offset)); 200 208 } 201 209 202 210 chained_irq_exit(irqchip, desc); ··· 205 211 206 212 static void pl061_irq_mask(struct irq_data *d) 207 213 { 208 - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 214 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 215 + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 209 216 u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); 210 217 u8 gpioie; 211 218 ··· 218 223 219 224 static void pl061_irq_unmask(struct irq_data *d) 220 225 { 221 - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 226 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 227 + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 222 228 u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); 223 229 u8 gpioie; 224 230 ··· 229 233 spin_unlock(&chip->lock); 230 234 } 231 235 232 - static int pl061_irq_reqres(struct irq_data *d) 233 - { 234 - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 235 - 236 - if (gpio_lock_as_irq(&chip->gc, irqd_to_hwirq(d))) { 237 - dev_err(chip->gc.dev, 238 - "unable to lock HW IRQ %lu for IRQ\n", 239 - irqd_to_hwirq(d)); 240 - return -EINVAL; 241 - } 242 - return 0; 243 - } 244 - 245 - static void pl061_irq_relres(struct irq_data *d) 246 - { 247 - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 248 - 249 - gpio_unlock_as_irq(&chip->gc, irqd_to_hwirq(d)); 250 - } 251 - 252 236 static struct irq_chip pl061_irqchip = { 253 237 .name = "pl061", 254 238 .irq_mask = pl061_irq_mask, 255 239 .irq_unmask = pl061_irq_unmask, 256 240 .irq_set_type = pl061_irq_type, 257 - .irq_request_resources = pl061_irq_reqres, 258 - .irq_release_resources = pl061_irq_relres, 259 - }; 260 - 261 - static int pl061_irq_map(struct irq_domain *d, unsigned int irq, 262 - irq_hw_number_t hwirq) 263 - { 264 - struct pl061_gpio *chip = d->host_data; 265 - 266 - irq_set_chip_and_handler(irq, &pl061_irqchip, handle_simple_irq); 267 - irq_set_chip_data(irq, chip); 268 - irq_set_irq_type(irq, IRQ_TYPE_NONE); 269 - 270 - return 0; 271 - } 272 - 273 - static const struct irq_domain_ops pl061_domain_ops = { 274 - .map = pl061_irq_map, 275 - .xlate = irq_domain_xlate_twocell, 276 241 }; 277 242 278 243 static int pl061_probe(struct amba_device *adev, const struct amba_id *id) ··· 271 314 chip->gc.direction_output = pl061_direction_output; 272 315 chip->gc.get = pl061_get_value; 273 316 chip->gc.set = pl061_set_value; 274 - chip->gc.to_irq = pl061_to_irq; 275 317 chip->gc.ngpio = PL061_GPIO_NR; 276 318 chip->gc.label = dev_name(dev); 277 319 chip->gc.dev = dev; ··· 290 334 return -ENODEV; 291 335 } 292 336 293 - irq_set_chained_handler(irq, pl061_irq_handler); 294 - irq_set_handler_data(irq, chip); 295 - 296 - chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR, 297 - irq_base, &pl061_domain_ops, chip); 298 - if (!chip->domain) { 299 - dev_err(&adev->dev, "no irq domain\n"); 300 - return -ENODEV; 337 + ret = gpiochip_irqchip_add(&chip->gc, &pl061_irqchip, 338 + irq_base, handle_simple_irq, 339 + IRQ_TYPE_NONE); 340 + if (ret) { 341 + dev_info(&adev->dev, "could not add irqchip\n"); 342 + return ret; 301 343 } 344 + gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip, 345 + irq, pl061_irq_handler); 302 346 303 347 for (i = 0; i < PL061_GPIO_NR; i++) { 304 348 if (pdata) {