diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/gpio-mpc8xxx.c | 30 | ||||
| -rw-r--r-- | drivers/gpio/gpio-tegra.c | 59 |
2 files changed, 52 insertions, 37 deletions
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 5cd04b65c556..e6568c19c939 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c | |||
| @@ -37,7 +37,7 @@ struct mpc8xxx_gpio_chip { | |||
| 37 | * open drain mode safely | 37 | * open drain mode safely |
| 38 | */ | 38 | */ |
| 39 | u32 data; | 39 | u32 data; |
| 40 | struct irq_host *irq; | 40 | struct irq_domain *irq; |
| 41 | void *of_dev_id_data; | 41 | void *of_dev_id_data; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| @@ -281,7 +281,7 @@ static struct irq_chip mpc8xxx_irq_chip = { | |||
| 281 | .irq_set_type = mpc8xxx_irq_set_type, | 281 | .irq_set_type = mpc8xxx_irq_set_type, |
| 282 | }; | 282 | }; |
| 283 | 283 | ||
| 284 | static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, | 284 | static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq, |
| 285 | irq_hw_number_t hw) | 285 | irq_hw_number_t hw) |
| 286 | { | 286 | { |
| 287 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; | 287 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; |
| @@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, | |||
| 296 | return 0; | 296 | return 0; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, | 299 | static struct irq_domain_ops mpc8xxx_gpio_irq_ops = { |
| 300 | const u32 *intspec, unsigned int intsize, | ||
| 301 | irq_hw_number_t *out_hwirq, | ||
| 302 | unsigned int *out_flags) | ||
| 303 | |||
| 304 | { | ||
| 305 | /* interrupt sense values coming from the device tree equal either | ||
| 306 | * EDGE_FALLING or EDGE_BOTH | ||
| 307 | */ | ||
| 308 | *out_hwirq = intspec[0]; | ||
| 309 | *out_flags = intspec[1]; | ||
| 310 | |||
| 311 | return 0; | ||
| 312 | } | ||
| 313 | |||
| 314 | static struct irq_host_ops mpc8xxx_gpio_irq_ops = { | ||
| 315 | .map = mpc8xxx_gpio_irq_map, | 300 | .map = mpc8xxx_gpio_irq_map, |
| 316 | .xlate = mpc8xxx_gpio_irq_xlate, | 301 | .xlate = irq_domain_xlate_twocell, |
| 317 | }; | 302 | }; |
| 318 | 303 | ||
| 319 | static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { | 304 | static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { |
| @@ -364,9 +349,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 364 | if (hwirq == NO_IRQ) | 349 | if (hwirq == NO_IRQ) |
| 365 | goto skip_irq; | 350 | goto skip_irq; |
| 366 | 351 | ||
| 367 | mpc8xxx_gc->irq = | 352 | mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS, |
| 368 | irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, | 353 | &mpc8xxx_gpio_irq_ops, mpc8xxx_gc); |
| 369 | &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); | ||
| 370 | if (!mpc8xxx_gc->irq) | 354 | if (!mpc8xxx_gc->irq) |
| 371 | goto skip_irq; | 355 | goto skip_irq; |
| 372 | 356 | ||
| @@ -374,8 +358,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 374 | if (id) | 358 | if (id) |
| 375 | mpc8xxx_gc->of_dev_id_data = id->data; | 359 | mpc8xxx_gc->of_dev_id_data = id->data; |
| 376 | 360 | ||
| 377 | mpc8xxx_gc->irq->host_data = mpc8xxx_gc; | ||
| 378 | |||
| 379 | /* ack and mask all irqs */ | 361 | /* ack and mask all irqs */ |
| 380 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); | 362 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); |
| 381 | out_be32(mm_gc->regs + GPIO_IMR, 0); | 363 | out_be32(mm_gc->regs + GPIO_IMR, 0); |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index bdc293791590..6f17671260e1 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
| 26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/irqdomain.h> | ||
| 28 | 29 | ||
| 29 | #include <asm/mach/irq.h> | 30 | #include <asm/mach/irq.h> |
| 30 | 31 | ||
| @@ -74,9 +75,10 @@ struct tegra_gpio_bank { | |||
| 74 | #endif | 75 | #endif |
| 75 | }; | 76 | }; |
| 76 | 77 | ||
| 77 | 78 | static struct irq_domain *irq_domain; | |
| 78 | static void __iomem *regs; | 79 | static void __iomem *regs; |
| 79 | static struct tegra_gpio_bank tegra_gpio_banks[7]; | 80 | static u32 tegra_gpio_bank_count; |
| 81 | static struct tegra_gpio_bank *tegra_gpio_banks; | ||
| 80 | 82 | ||
| 81 | static inline void tegra_gpio_writel(u32 val, u32 reg) | 83 | static inline void tegra_gpio_writel(u32 val, u32 reg) |
| 82 | { | 84 | { |
| @@ -139,7 +141,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
| 139 | 141 | ||
| 140 | static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 142 | static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
| 141 | { | 143 | { |
| 142 | return TEGRA_GPIO_TO_IRQ(offset); | 144 | return irq_find_mapping(irq_domain, offset); |
| 143 | } | 145 | } |
| 144 | 146 | ||
| 145 | static struct gpio_chip tegra_gpio_chip = { | 147 | static struct gpio_chip tegra_gpio_chip = { |
| @@ -155,28 +157,28 @@ static struct gpio_chip tegra_gpio_chip = { | |||
| 155 | 157 | ||
| 156 | static void tegra_gpio_irq_ack(struct irq_data *d) | 158 | static void tegra_gpio_irq_ack(struct irq_data *d) |
| 157 | { | 159 | { |
| 158 | int gpio = d->irq - INT_GPIO_BASE; | 160 | int gpio = d->hwirq; |
| 159 | 161 | ||
| 160 | tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); | 162 | tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); |
| 161 | } | 163 | } |
| 162 | 164 | ||
| 163 | static void tegra_gpio_irq_mask(struct irq_data *d) | 165 | static void tegra_gpio_irq_mask(struct irq_data *d) |
| 164 | { | 166 | { |
| 165 | int gpio = d->irq - INT_GPIO_BASE; | 167 | int gpio = d->hwirq; |
| 166 | 168 | ||
| 167 | tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0); | 169 | tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0); |
| 168 | } | 170 | } |
| 169 | 171 | ||
| 170 | static void tegra_gpio_irq_unmask(struct irq_data *d) | 172 | static void tegra_gpio_irq_unmask(struct irq_data *d) |
| 171 | { | 173 | { |
| 172 | int gpio = d->irq - INT_GPIO_BASE; | 174 | int gpio = d->hwirq; |
| 173 | 175 | ||
| 174 | tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1); | 176 | tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1); |
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 179 | static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
| 178 | { | 180 | { |
| 179 | int gpio = d->irq - INT_GPIO_BASE; | 181 | int gpio = d->hwirq; |
| 180 | struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); | 182 | struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); |
| 181 | int port = GPIO_PORT(gpio); | 183 | int port = GPIO_PORT(gpio); |
| 182 | int lvl_type; | 184 | int lvl_type; |
| @@ -273,7 +275,7 @@ void tegra_gpio_resume(void) | |||
| 273 | 275 | ||
| 274 | local_irq_save(flags); | 276 | local_irq_save(flags); |
| 275 | 277 | ||
| 276 | for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { | 278 | for (b = 0; b < tegra_gpio_bank_count; b++) { |
| 277 | struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; | 279 | struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; |
| 278 | 280 | ||
| 279 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { | 281 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { |
| @@ -296,7 +298,7 @@ void tegra_gpio_suspend(void) | |||
| 296 | int p; | 298 | int p; |
| 297 | 299 | ||
| 298 | local_irq_save(flags); | 300 | local_irq_save(flags); |
| 299 | for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { | 301 | for (b = 0; b < tegra_gpio_bank_count; b++) { |
| 300 | struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; | 302 | struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; |
| 301 | 303 | ||
| 302 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { | 304 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { |
| @@ -337,13 +339,44 @@ static struct lock_class_key gpio_lock_class; | |||
| 337 | 339 | ||
| 338 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) | 340 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) |
| 339 | { | 341 | { |
| 342 | int irq_base; | ||
| 340 | struct resource *res; | 343 | struct resource *res; |
| 341 | struct tegra_gpio_bank *bank; | 344 | struct tegra_gpio_bank *bank; |
| 342 | int gpio; | 345 | int gpio; |
| 343 | int i; | 346 | int i; |
| 344 | int j; | 347 | int j; |
| 345 | 348 | ||
| 346 | for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { | 349 | for (;;) { |
| 350 | res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); | ||
| 351 | if (!res) | ||
| 352 | break; | ||
| 353 | tegra_gpio_bank_count++; | ||
| 354 | } | ||
| 355 | if (!tegra_gpio_bank_count) { | ||
| 356 | dev_err(&pdev->dev, "Missing IRQ resource\n"); | ||
| 357 | return -ENODEV; | ||
| 358 | } | ||
| 359 | |||
| 360 | tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32; | ||
| 361 | |||
| 362 | tegra_gpio_banks = devm_kzalloc(&pdev->dev, | ||
| 363 | tegra_gpio_bank_count * sizeof(*tegra_gpio_banks), | ||
| 364 | GFP_KERNEL); | ||
| 365 | if (!tegra_gpio_banks) { | ||
| 366 | dev_err(&pdev->dev, "Couldn't allocate bank structure\n"); | ||
| 367 | return -ENODEV; | ||
| 368 | } | ||
| 369 | |||
| 370 | irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0); | ||
| 371 | if (irq_base < 0) { | ||
| 372 | dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); | ||
| 373 | return -ENODEV; | ||
| 374 | } | ||
| 375 | irq_domain = irq_domain_add_legacy(pdev->dev.of_node, | ||
| 376 | tegra_gpio_chip.ngpio, irq_base, 0, | ||
| 377 | &irq_domain_simple_ops, NULL); | ||
| 378 | |||
| 379 | for (i = 0; i < tegra_gpio_bank_count; i++) { | ||
| 347 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); | 380 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); |
| 348 | if (!res) { | 381 | if (!res) { |
| 349 | dev_err(&pdev->dev, "Missing IRQ resource\n"); | 382 | dev_err(&pdev->dev, "Missing IRQ resource\n"); |
| @@ -380,8 +413,8 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 380 | 413 | ||
| 381 | gpiochip_add(&tegra_gpio_chip); | 414 | gpiochip_add(&tegra_gpio_chip); |
| 382 | 415 | ||
| 383 | for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) { | 416 | for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { |
| 384 | int irq = TEGRA_GPIO_TO_IRQ(gpio); | 417 | int irq = irq_find_mapping(irq_domain, gpio); |
| 385 | /* No validity check; all Tegra GPIOs are valid IRQs */ | 418 | /* No validity check; all Tegra GPIOs are valid IRQs */ |
| 386 | 419 | ||
| 387 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; | 420 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; |
| @@ -393,7 +426,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 393 | set_irq_flags(irq, IRQF_VALID); | 426 | set_irq_flags(irq, IRQF_VALID); |
| 394 | } | 427 | } |
| 395 | 428 | ||
| 396 | for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { | 429 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
| 397 | bank = &tegra_gpio_banks[i]; | 430 | bank = &tegra_gpio_banks[i]; |
| 398 | 431 | ||
| 399 | irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler); | 432 | irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler); |
