diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2014-04-23 17:08:02 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-05-28 04:42:04 -0400 |
commit | 294d1351ff47726f0f110b88e816cbafe89512fb (patch) | |
tree | f5964e4cad2aea5beaf74665fdd285778a36bcaf /drivers/pinctrl | |
parent | ca6c55189a631f3380ff0a28f90d920a84e60d7b (diff) |
pinctrl: sirf: switch to using allocated state container
This rewrites the SIRF pinctrl driver to allocate a state container
for the GPIO chip, just as is done for the pin controller, and
use the gpiochip_add_pin_range() to add the range from the gpiochip
side rather than adding the range from the pinctrl side.
All resulting changes are done in order to pass around a state
container rather than refer to a static global object.
Acked-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/sirf/pinctrl-sirf.c | 214 |
1 files changed, 121 insertions, 93 deletions
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index a4ea3f739ded..0e835219c42e 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c | |||
@@ -42,7 +42,6 @@ struct sirfsoc_gpio_chip { | |||
42 | struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; | 42 | struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct sirfsoc_gpio_chip sgpio_chip; | ||
46 | static DEFINE_SPINLOCK(sgpio_lock); | 45 | static DEFINE_SPINLOCK(sgpio_lock); |
47 | 46 | ||
48 | static struct sirfsoc_pin_group *sirfsoc_pin_groups; | 47 | static struct sirfsoc_pin_group *sirfsoc_pin_groups; |
@@ -255,17 +254,6 @@ static struct pinctrl_desc sirfsoc_pinmux_desc = { | |||
255 | .owner = THIS_MODULE, | 254 | .owner = THIS_MODULE, |
256 | }; | 255 | }; |
257 | 256 | ||
258 | /* | ||
259 | * Todo: bind irq_chip to every pinctrl_gpio_range | ||
260 | */ | ||
261 | static struct pinctrl_gpio_range sirfsoc_gpio_ranges = { | ||
262 | .name = "sirfsoc-gpio*", | ||
263 | .id = 0, | ||
264 | .base = 0, | ||
265 | .pin_base = 0, | ||
266 | .npins = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS, | ||
267 | }; | ||
268 | |||
269 | static void __iomem *sirfsoc_rsc_of_iomap(void) | 257 | static void __iomem *sirfsoc_rsc_of_iomap(void) |
270 | { | 258 | { |
271 | const struct of_device_id rsc_ids[] = { | 259 | const struct of_device_id rsc_ids[] = { |
@@ -289,9 +277,6 @@ static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc, | |||
289 | if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE) | 277 | if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE) |
290 | return -EINVAL; | 278 | return -EINVAL; |
291 | 279 | ||
292 | if (gc != &sgpio_chip.chip.gc) | ||
293 | return -EINVAL; | ||
294 | |||
295 | if (flags) | 280 | if (flags) |
296 | *flags = gpiospec->args[1]; | 281 | *flags = gpiospec->args[1]; |
297 | 282 | ||
@@ -354,9 +339,6 @@ static int sirfsoc_pinmux_probe(struct platform_device *pdev) | |||
354 | goto out_no_pmx; | 339 | goto out_no_pmx; |
355 | } | 340 | } |
356 | 341 | ||
357 | sirfsoc_gpio_ranges.gc = &sgpio_chip.chip.gc; | ||
358 | pinctrl_add_gpio_range(spmx->pmx, &sirfsoc_gpio_ranges); | ||
359 | |||
360 | dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); | 342 | dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); |
361 | 343 | ||
362 | return 0; | 344 | return 0; |
@@ -441,20 +423,28 @@ static int __init sirfsoc_pinmux_init(void) | |||
441 | } | 423 | } |
442 | arch_initcall(sirfsoc_pinmux_init); | 424 | arch_initcall(sirfsoc_pinmux_init); |
443 | 425 | ||
444 | static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio) | 426 | static inline struct sirfsoc_gpio_chip *to_sirfsoc_gpio(struct gpio_chip *gc) |
427 | { | ||
428 | return container_of(gc, struct sirfsoc_gpio_chip, chip.gc); | ||
429 | } | ||
430 | |||
431 | static inline struct sirfsoc_gpio_bank * | ||
432 | sirfsoc_gpio_to_bank(struct sirfsoc_gpio_chip *sgpio, unsigned int offset) | ||
445 | { | 433 | { |
446 | return &sgpio_chip.sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE]; | 434 | return &sgpio->sgpio_bank[offset / SIRFSOC_GPIO_BANK_SIZE]; |
447 | } | 435 | } |
448 | 436 | ||
449 | static inline int sirfsoc_gpio_to_bankoff(unsigned int gpio) | 437 | static inline int sirfsoc_gpio_to_bankoff(unsigned int offset) |
450 | { | 438 | { |
451 | return gpio % SIRFSOC_GPIO_BANK_SIZE; | 439 | return offset % SIRFSOC_GPIO_BANK_SIZE; |
452 | } | 440 | } |
453 | 441 | ||
454 | static void sirfsoc_gpio_irq_ack(struct irq_data *d) | 442 | static void sirfsoc_gpio_irq_ack(struct irq_data *d) |
455 | { | 443 | { |
456 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); | 444 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
457 | int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE; | 445 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); |
446 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); | ||
447 | int idx = sirfsoc_gpio_to_bankoff(d->hwirq); | ||
458 | u32 val, offset; | 448 | u32 val, offset; |
459 | unsigned long flags; | 449 | unsigned long flags; |
460 | 450 | ||
@@ -462,14 +452,16 @@ static void sirfsoc_gpio_irq_ack(struct irq_data *d) | |||
462 | 452 | ||
463 | spin_lock_irqsave(&sgpio_lock, flags); | 453 | spin_lock_irqsave(&sgpio_lock, flags); |
464 | 454 | ||
465 | val = readl(sgpio_chip.chip.regs + offset); | 455 | val = readl(sgpio->chip.regs + offset); |
466 | 456 | ||
467 | writel(val, sgpio_chip.chip.regs + offset); | 457 | writel(val, sgpio->chip.regs + offset); |
468 | 458 | ||
469 | spin_unlock_irqrestore(&sgpio_lock, flags); | 459 | spin_unlock_irqrestore(&sgpio_lock, flags); |
470 | } | 460 | } |
471 | 461 | ||
472 | static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_bank *bank, int idx) | 462 | static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio, |
463 | struct sirfsoc_gpio_bank *bank, | ||
464 | int idx) | ||
473 | { | 465 | { |
474 | u32 val, offset; | 466 | u32 val, offset; |
475 | unsigned long flags; | 467 | unsigned long flags; |
@@ -478,25 +470,29 @@ static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_bank *bank, int idx) | |||
478 | 470 | ||
479 | spin_lock_irqsave(&sgpio_lock, flags); | 471 | spin_lock_irqsave(&sgpio_lock, flags); |
480 | 472 | ||
481 | val = readl(sgpio_chip.chip.regs + offset); | 473 | val = readl(sgpio->chip.regs + offset); |
482 | val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; | 474 | val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; |
483 | val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; | 475 | val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; |
484 | writel(val, sgpio_chip.chip.regs + offset); | 476 | writel(val, sgpio->chip.regs + offset); |
485 | 477 | ||
486 | spin_unlock_irqrestore(&sgpio_lock, flags); | 478 | spin_unlock_irqrestore(&sgpio_lock, flags); |
487 | } | 479 | } |
488 | 480 | ||
489 | static void sirfsoc_gpio_irq_mask(struct irq_data *d) | 481 | static void sirfsoc_gpio_irq_mask(struct irq_data *d) |
490 | { | 482 | { |
491 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); | 483 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
484 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); | ||
485 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); | ||
492 | 486 | ||
493 | __sirfsoc_gpio_irq_mask(bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE); | 487 | __sirfsoc_gpio_irq_mask(sgpio, bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE); |
494 | } | 488 | } |
495 | 489 | ||
496 | static void sirfsoc_gpio_irq_unmask(struct irq_data *d) | 490 | static void sirfsoc_gpio_irq_unmask(struct irq_data *d) |
497 | { | 491 | { |
498 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); | 492 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
499 | int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE; | 493 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); |
494 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); | ||
495 | int idx = sirfsoc_gpio_to_bankoff(d->hwirq); | ||
500 | u32 val, offset; | 496 | u32 val, offset; |
501 | unsigned long flags; | 497 | unsigned long flags; |
502 | 498 | ||
@@ -504,18 +500,20 @@ static void sirfsoc_gpio_irq_unmask(struct irq_data *d) | |||
504 | 500 | ||
505 | spin_lock_irqsave(&sgpio_lock, flags); | 501 | spin_lock_irqsave(&sgpio_lock, flags); |
506 | 502 | ||
507 | val = readl(sgpio_chip.chip.regs + offset); | 503 | val = readl(sgpio->chip.regs + offset); |
508 | val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; | 504 | val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; |
509 | val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK; | 505 | val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK; |
510 | writel(val, sgpio_chip.chip.regs + offset); | 506 | writel(val, sgpio->chip.regs + offset); |
511 | 507 | ||
512 | spin_unlock_irqrestore(&sgpio_lock, flags); | 508 | spin_unlock_irqrestore(&sgpio_lock, flags); |
513 | } | 509 | } |
514 | 510 | ||
515 | static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | 511 | static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) |
516 | { | 512 | { |
517 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); | 513 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
518 | int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE; | 514 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); |
515 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); | ||
516 | int idx = sirfsoc_gpio_to_bankoff(d->hwirq); | ||
519 | u32 val, offset; | 517 | u32 val, offset; |
520 | unsigned long flags; | 518 | unsigned long flags; |
521 | 519 | ||
@@ -523,7 +521,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | |||
523 | 521 | ||
524 | spin_lock_irqsave(&sgpio_lock, flags); | 522 | spin_lock_irqsave(&sgpio_lock, flags); |
525 | 523 | ||
526 | val = readl(sgpio_chip.chip.regs + offset); | 524 | val = readl(sgpio->chip.regs + offset); |
527 | val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK); | 525 | val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK); |
528 | 526 | ||
529 | switch (type) { | 527 | switch (type) { |
@@ -551,7 +549,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | |||
551 | break; | 549 | break; |
552 | } | 550 | } |
553 | 551 | ||
554 | writel(val, sgpio_chip.chip.regs + offset); | 552 | writel(val, sgpio->chip.regs + offset); |
555 | 553 | ||
556 | spin_unlock_irqrestore(&sgpio_lock, flags); | 554 | spin_unlock_irqrestore(&sgpio_lock, flags); |
557 | 555 | ||
@@ -568,6 +566,8 @@ static struct irq_chip sirfsoc_irq_chip = { | |||
568 | 566 | ||
569 | static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | 567 | static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) |
570 | { | 568 | { |
569 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | ||
570 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc); | ||
571 | struct sirfsoc_gpio_bank *bank; | 571 | struct sirfsoc_gpio_bank *bank; |
572 | u32 status, ctrl; | 572 | u32 status, ctrl; |
573 | int idx = 0; | 573 | int idx = 0; |
@@ -583,7 +583,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | |||
583 | 583 | ||
584 | chained_irq_enter(chip, desc); | 584 | chained_irq_enter(chip, desc); |
585 | 585 | ||
586 | status = readl(sgpio_chip.chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); | 586 | status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); |
587 | if (!status) { | 587 | if (!status) { |
588 | printk(KERN_WARNING | 588 | printk(KERN_WARNING |
589 | "%s: gpio id %d status %#x no interrupt is flaged\n", | 589 | "%s: gpio id %d status %#x no interrupt is flaged\n", |
@@ -593,7 +593,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | |||
593 | } | 593 | } |
594 | 594 | ||
595 | while (status) { | 595 | while (status) { |
596 | ctrl = readl(sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx)); | 596 | ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx)); |
597 | 597 | ||
598 | /* | 598 | /* |
599 | * Here we must check whether the corresponding GPIO's interrupt | 599 | * Here we must check whether the corresponding GPIO's interrupt |
@@ -602,7 +602,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | |||
602 | if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { | 602 | if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { |
603 | pr_debug("%s: gpio id %d idx %d happens\n", | 603 | pr_debug("%s: gpio id %d idx %d happens\n", |
604 | __func__, bank->id, idx); | 604 | __func__, bank->id, idx); |
605 | generic_handle_irq(irq_find_mapping(sgpio_chip.chip.gc.irqdomain, idx + | 605 | generic_handle_irq(irq_find_mapping(gc->irqdomain, idx + |
606 | bank->id * SIRFSOC_GPIO_BANK_SIZE)); | 606 | bank->id * SIRFSOC_GPIO_BANK_SIZE)); |
607 | } | 607 | } |
608 | 608 | ||
@@ -613,18 +613,20 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | |||
613 | chained_irq_exit(chip, desc); | 613 | chained_irq_exit(chip, desc); |
614 | } | 614 | } |
615 | 615 | ||
616 | static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_bank *bank, unsigned ctrl_offset) | 616 | static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_chip *sgpio, |
617 | unsigned ctrl_offset) | ||
617 | { | 618 | { |
618 | u32 val; | 619 | u32 val; |
619 | 620 | ||
620 | val = readl(sgpio_chip.chip.regs + ctrl_offset); | 621 | val = readl(sgpio->chip.regs + ctrl_offset); |
621 | val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK; | 622 | val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK; |
622 | writel(val, sgpio_chip.chip.regs + ctrl_offset); | 623 | writel(val, sgpio->chip.regs + ctrl_offset); |
623 | } | 624 | } |
624 | 625 | ||
625 | static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) | 626 | static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) |
626 | { | 627 | { |
627 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); | 628 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); |
629 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); | ||
628 | unsigned long flags; | 630 | unsigned long flags; |
629 | 631 | ||
630 | if (pinctrl_request_gpio(chip->base + offset)) | 632 | if (pinctrl_request_gpio(chip->base + offset)) |
@@ -636,8 +638,8 @@ static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
636 | * default status: | 638 | * default status: |
637 | * set direction as input and mask irq | 639 | * set direction as input and mask irq |
638 | */ | 640 | */ |
639 | sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset)); | 641 | sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); |
640 | __sirfsoc_gpio_irq_mask(bank, offset); | 642 | __sirfsoc_gpio_irq_mask(sgpio, bank, offset); |
641 | 643 | ||
642 | spin_unlock_irqrestore(&bank->lock, flags); | 644 | spin_unlock_irqrestore(&bank->lock, flags); |
643 | 645 | ||
@@ -646,13 +648,14 @@ static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
646 | 648 | ||
647 | static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset) | 649 | static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset) |
648 | { | 650 | { |
649 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); | 651 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); |
652 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); | ||
650 | unsigned long flags; | 653 | unsigned long flags; |
651 | 654 | ||
652 | spin_lock_irqsave(&bank->lock, flags); | 655 | spin_lock_irqsave(&bank->lock, flags); |
653 | 656 | ||
654 | __sirfsoc_gpio_irq_mask(bank, offset); | 657 | __sirfsoc_gpio_irq_mask(sgpio, bank, offset); |
655 | sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset)); | 658 | sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); |
656 | 659 | ||
657 | spin_unlock_irqrestore(&bank->lock, flags); | 660 | spin_unlock_irqrestore(&bank->lock, flags); |
658 | 661 | ||
@@ -661,7 +664,8 @@ static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
661 | 664 | ||
662 | static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) | 665 | static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) |
663 | { | 666 | { |
664 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(gpio); | 667 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); |
668 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); | ||
665 | int idx = sirfsoc_gpio_to_bankoff(gpio); | 669 | int idx = sirfsoc_gpio_to_bankoff(gpio); |
666 | unsigned long flags; | 670 | unsigned long flags; |
667 | unsigned offset; | 671 | unsigned offset; |
@@ -670,22 +674,24 @@ static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) | |||
670 | 674 | ||
671 | spin_lock_irqsave(&bank->lock, flags); | 675 | spin_lock_irqsave(&bank->lock, flags); |
672 | 676 | ||
673 | sirfsoc_gpio_set_input(bank, offset); | 677 | sirfsoc_gpio_set_input(sgpio, offset); |
674 | 678 | ||
675 | spin_unlock_irqrestore(&bank->lock, flags); | 679 | spin_unlock_irqrestore(&bank->lock, flags); |
676 | 680 | ||
677 | return 0; | 681 | return 0; |
678 | } | 682 | } |
679 | 683 | ||
680 | static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_bank *bank, unsigned offset, | 684 | static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_chip *sgpio, |
681 | int value) | 685 | struct sirfsoc_gpio_bank *bank, |
686 | unsigned offset, | ||
687 | int value) | ||
682 | { | 688 | { |
683 | u32 out_ctrl; | 689 | u32 out_ctrl; |
684 | unsigned long flags; | 690 | unsigned long flags; |
685 | 691 | ||
686 | spin_lock_irqsave(&bank->lock, flags); | 692 | spin_lock_irqsave(&bank->lock, flags); |
687 | 693 | ||
688 | out_ctrl = readl(sgpio_chip.chip.regs + offset); | 694 | out_ctrl = readl(sgpio->chip.regs + offset); |
689 | if (value) | 695 | if (value) |
690 | out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; | 696 | out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; |
691 | else | 697 | else |
@@ -693,14 +699,15 @@ static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_bank *bank, unsig | |||
693 | 699 | ||
694 | out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; | 700 | out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; |
695 | out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK; | 701 | out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK; |
696 | writel(out_ctrl, sgpio_chip.chip.regs + offset); | 702 | writel(out_ctrl, sgpio->chip.regs + offset); |
697 | 703 | ||
698 | spin_unlock_irqrestore(&bank->lock, flags); | 704 | spin_unlock_irqrestore(&bank->lock, flags); |
699 | } | 705 | } |
700 | 706 | ||
701 | static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) | 707 | static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) |
702 | { | 708 | { |
703 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(gpio); | 709 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); |
710 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); | ||
704 | int idx = sirfsoc_gpio_to_bankoff(gpio); | 711 | int idx = sirfsoc_gpio_to_bankoff(gpio); |
705 | u32 offset; | 712 | u32 offset; |
706 | unsigned long flags; | 713 | unsigned long flags; |
@@ -709,7 +716,7 @@ static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, | |||
709 | 716 | ||
710 | spin_lock_irqsave(&sgpio_lock, flags); | 717 | spin_lock_irqsave(&sgpio_lock, flags); |
711 | 718 | ||
712 | sirfsoc_gpio_set_output(bank, offset, value); | 719 | sirfsoc_gpio_set_output(sgpio, bank, offset, value); |
713 | 720 | ||
714 | spin_unlock_irqrestore(&sgpio_lock, flags); | 721 | spin_unlock_irqrestore(&sgpio_lock, flags); |
715 | 722 | ||
@@ -718,13 +725,14 @@ static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, | |||
718 | 725 | ||
719 | static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset) | 726 | static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset) |
720 | { | 727 | { |
721 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); | 728 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); |
729 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); | ||
722 | u32 val; | 730 | u32 val; |
723 | unsigned long flags; | 731 | unsigned long flags; |
724 | 732 | ||
725 | spin_lock_irqsave(&bank->lock, flags); | 733 | spin_lock_irqsave(&bank->lock, flags); |
726 | 734 | ||
727 | val = readl(sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); | 735 | val = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); |
728 | 736 | ||
729 | spin_unlock_irqrestore(&bank->lock, flags); | 737 | spin_unlock_irqrestore(&bank->lock, flags); |
730 | 738 | ||
@@ -734,23 +742,25 @@ static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset) | |||
734 | static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, | 742 | static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, |
735 | int value) | 743 | int value) |
736 | { | 744 | { |
737 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(offset); | 745 | struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip); |
746 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); | ||
738 | u32 ctrl; | 747 | u32 ctrl; |
739 | unsigned long flags; | 748 | unsigned long flags; |
740 | 749 | ||
741 | spin_lock_irqsave(&bank->lock, flags); | 750 | spin_lock_irqsave(&bank->lock, flags); |
742 | 751 | ||
743 | ctrl = readl(sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); | 752 | ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); |
744 | if (value) | 753 | if (value) |
745 | ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; | 754 | ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; |
746 | else | 755 | else |
747 | ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; | 756 | ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; |
748 | writel(ctrl, sgpio_chip.chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); | 757 | writel(ctrl, sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); |
749 | 758 | ||
750 | spin_unlock_irqrestore(&bank->lock, flags); | 759 | spin_unlock_irqrestore(&bank->lock, flags); |
751 | } | 760 | } |
752 | 761 | ||
753 | static void sirfsoc_gpio_set_pullup(const u32 *pullups) | 762 | static void sirfsoc_gpio_set_pullup(struct sirfsoc_gpio_chip *sgpio, |
763 | const u32 *pullups) | ||
754 | { | 764 | { |
755 | int i, n; | 765 | int i, n; |
756 | const unsigned long *p = (const unsigned long *)pullups; | 766 | const unsigned long *p = (const unsigned long *)pullups; |
@@ -758,15 +768,16 @@ static void sirfsoc_gpio_set_pullup(const u32 *pullups) | |||
758 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { | 768 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { |
759 | for_each_set_bit(n, p + i, BITS_PER_LONG) { | 769 | for_each_set_bit(n, p + i, BITS_PER_LONG) { |
760 | u32 offset = SIRFSOC_GPIO_CTRL(i, n); | 770 | u32 offset = SIRFSOC_GPIO_CTRL(i, n); |
761 | u32 val = readl(sgpio_chip.chip.regs + offset); | 771 | u32 val = readl(sgpio->chip.regs + offset); |
762 | val |= SIRFSOC_GPIO_CTL_PULL_MASK; | 772 | val |= SIRFSOC_GPIO_CTL_PULL_MASK; |
763 | val |= SIRFSOC_GPIO_CTL_PULL_HIGH; | 773 | val |= SIRFSOC_GPIO_CTL_PULL_HIGH; |
764 | writel(val, sgpio_chip.chip.regs + offset); | 774 | writel(val, sgpio->chip.regs + offset); |
765 | } | 775 | } |
766 | } | 776 | } |
767 | } | 777 | } |
768 | 778 | ||
769 | static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns) | 779 | static void sirfsoc_gpio_set_pulldown(struct sirfsoc_gpio_chip *sgpio, |
780 | const u32 *pulldowns) | ||
770 | { | 781 | { |
771 | int i, n; | 782 | int i, n; |
772 | const unsigned long *p = (const unsigned long *)pulldowns; | 783 | const unsigned long *p = (const unsigned long *)pulldowns; |
@@ -774,10 +785,10 @@ static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns) | |||
774 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { | 785 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { |
775 | for_each_set_bit(n, p + i, BITS_PER_LONG) { | 786 | for_each_set_bit(n, p + i, BITS_PER_LONG) { |
776 | u32 offset = SIRFSOC_GPIO_CTRL(i, n); | 787 | u32 offset = SIRFSOC_GPIO_CTRL(i, n); |
777 | u32 val = readl(sgpio_chip.chip.regs + offset); | 788 | u32 val = readl(sgpio->chip.regs + offset); |
778 | val |= SIRFSOC_GPIO_CTL_PULL_MASK; | 789 | val |= SIRFSOC_GPIO_CTL_PULL_MASK; |
779 | val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; | 790 | val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; |
780 | writel(val, sgpio_chip.chip.regs + offset); | 791 | writel(val, sgpio->chip.regs + offset); |
781 | } | 792 | } |
782 | } | 793 | } |
783 | } | 794 | } |
@@ -785,6 +796,7 @@ static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns) | |||
785 | static int sirfsoc_gpio_probe(struct device_node *np) | 796 | static int sirfsoc_gpio_probe(struct device_node *np) |
786 | { | 797 | { |
787 | int i, err = 0; | 798 | int i, err = 0; |
799 | static struct sirfsoc_gpio_chip *sgpio; | ||
788 | struct sirfsoc_gpio_bank *bank; | 800 | struct sirfsoc_gpio_bank *bank; |
789 | void __iomem *regs; | 801 | void __iomem *regs; |
790 | struct platform_device *pdev; | 802 | struct platform_device *pdev; |
@@ -796,6 +808,10 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
796 | if (!pdev) | 808 | if (!pdev) |
797 | return -ENODEV; | 809 | return -ENODEV; |
798 | 810 | ||
811 | sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL); | ||
812 | if (!sgpio) | ||
813 | return -ENOMEM; | ||
814 | |||
799 | regs = of_iomap(np, 0); | 815 | regs = of_iomap(np, 0); |
800 | if (!regs) | 816 | if (!regs) |
801 | return -ENOMEM; | 817 | return -ENOMEM; |
@@ -803,30 +819,30 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
803 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) | 819 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) |
804 | is_marco = 1; | 820 | is_marco = 1; |
805 | 821 | ||
806 | sgpio_chip.chip.gc.request = sirfsoc_gpio_request; | 822 | sgpio->chip.gc.request = sirfsoc_gpio_request; |
807 | sgpio_chip.chip.gc.free = sirfsoc_gpio_free; | 823 | sgpio->chip.gc.free = sirfsoc_gpio_free; |
808 | sgpio_chip.chip.gc.direction_input = sirfsoc_gpio_direction_input; | 824 | sgpio->chip.gc.direction_input = sirfsoc_gpio_direction_input; |
809 | sgpio_chip.chip.gc.get = sirfsoc_gpio_get_value; | 825 | sgpio->chip.gc.get = sirfsoc_gpio_get_value; |
810 | sgpio_chip.chip.gc.direction_output = sirfsoc_gpio_direction_output; | 826 | sgpio->chip.gc.direction_output = sirfsoc_gpio_direction_output; |
811 | sgpio_chip.chip.gc.set = sirfsoc_gpio_set_value; | 827 | sgpio->chip.gc.set = sirfsoc_gpio_set_value; |
812 | sgpio_chip.chip.gc.base = 0; | 828 | sgpio->chip.gc.base = 0; |
813 | sgpio_chip.chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS; | 829 | sgpio->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS; |
814 | sgpio_chip.chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); | 830 | sgpio->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); |
815 | sgpio_chip.chip.gc.of_node = np; | 831 | sgpio->chip.gc.of_node = np; |
816 | sgpio_chip.chip.gc.of_xlate = sirfsoc_gpio_of_xlate; | 832 | sgpio->chip.gc.of_xlate = sirfsoc_gpio_of_xlate; |
817 | sgpio_chip.chip.gc.of_gpio_n_cells = 2; | 833 | sgpio->chip.gc.of_gpio_n_cells = 2; |
818 | sgpio_chip.chip.gc.dev = &pdev->dev; | 834 | sgpio->chip.gc.dev = &pdev->dev; |
819 | sgpio_chip.chip.regs = regs; | 835 | sgpio->chip.regs = regs; |
820 | sgpio_chip.is_marco = is_marco; | 836 | sgpio->is_marco = is_marco; |
821 | 837 | ||
822 | err = gpiochip_add(&sgpio_chip.chip.gc); | 838 | err = gpiochip_add(&sgpio->chip.gc); |
823 | if (err) { | 839 | if (err) { |
824 | dev_err(&pdev->dev, "%s: error in probe function with status %d\n", | 840 | dev_err(&pdev->dev, "%s: error in probe function with status %d\n", |
825 | np->full_name, err); | 841 | np->full_name, err); |
826 | goto out; | 842 | goto out; |
827 | } | 843 | } |
828 | 844 | ||
829 | err = gpiochip_irqchip_add(&sgpio_chip.chip.gc, | 845 | err = gpiochip_irqchip_add(&sgpio->chip.gc, |
830 | &sirfsoc_irq_chip, | 846 | &sirfsoc_irq_chip, |
831 | 0, handle_level_irq, | 847 | 0, handle_level_irq, |
832 | IRQ_TYPE_NONE); | 848 | IRQ_TYPE_NONE); |
@@ -837,30 +853,42 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
837 | } | 853 | } |
838 | 854 | ||
839 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { | 855 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { |
840 | bank = &sgpio_chip.sgpio_bank[i]; | 856 | bank = &sgpio->sgpio_bank[i]; |
841 | spin_lock_init(&bank->lock); | 857 | spin_lock_init(&bank->lock); |
842 | bank->parent_irq = platform_get_irq(pdev, i); | 858 | bank->parent_irq = platform_get_irq(pdev, i); |
843 | if (bank->parent_irq < 0) { | 859 | if (bank->parent_irq < 0) { |
844 | err = bank->parent_irq; | 860 | err = bank->parent_irq; |
845 | goto out; | 861 | goto out_banks; |
846 | } | 862 | } |
847 | 863 | ||
848 | gpiochip_set_chained_irqchip(&sgpio_chip.chip.gc, | 864 | gpiochip_set_chained_irqchip(&sgpio->chip.gc, |
849 | &sirfsoc_irq_chip, | 865 | &sirfsoc_irq_chip, |
850 | bank->parent_irq, | 866 | bank->parent_irq, |
851 | sirfsoc_gpio_handle_irq); | 867 | sirfsoc_gpio_handle_irq); |
852 | } | 868 | } |
853 | 869 | ||
870 | err = gpiochip_add_pin_range(&sgpio->chip.gc, dev_name(&pdev->dev), | ||
871 | 0, 0, SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS); | ||
872 | if (err) { | ||
873 | dev_err(&pdev->dev, | ||
874 | "could not add gpiochip pin range\n"); | ||
875 | goto out_no_range; | ||
876 | } | ||
877 | |||
854 | if (!of_property_read_u32_array(np, "sirf,pullups", pullups, | 878 | if (!of_property_read_u32_array(np, "sirf,pullups", pullups, |
855 | SIRFSOC_GPIO_NO_OF_BANKS)) | 879 | SIRFSOC_GPIO_NO_OF_BANKS)) |
856 | sirfsoc_gpio_set_pullup(pullups); | 880 | sirfsoc_gpio_set_pullup(sgpio, pullups); |
857 | 881 | ||
858 | if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns, | 882 | if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns, |
859 | SIRFSOC_GPIO_NO_OF_BANKS)) | 883 | SIRFSOC_GPIO_NO_OF_BANKS)) |
860 | sirfsoc_gpio_set_pulldown(pulldowns); | 884 | sirfsoc_gpio_set_pulldown(sgpio, pulldowns); |
861 | 885 | ||
862 | return 0; | 886 | return 0; |
863 | 887 | ||
888 | out_no_range: | ||
889 | out_banks: | ||
890 | if (gpiochip_remove(&sgpio->chip.gc)) | ||
891 | dev_err(&pdev->dev, "could not remove gpio chip\n"); | ||
864 | out: | 892 | out: |
865 | iounmap(regs); | 893 | iounmap(regs); |
866 | return err; | 894 | return err; |