.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * at91 pinctrl driver based on at91 pinmux core |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> |
---|
5 | | - * |
---|
6 | | - * Under GPLv2 only |
---|
7 | 6 | */ |
---|
8 | 7 | |
---|
9 | 8 | #include <linux/clk.h> |
---|
.. | .. |
---|
16 | 15 | #include <linux/slab.h> |
---|
17 | 16 | #include <linux/interrupt.h> |
---|
18 | 17 | #include <linux/io.h> |
---|
19 | | -#include <linux/gpio.h> |
---|
| 18 | +#include <linux/gpio/driver.h> |
---|
20 | 19 | #include <linux/pinctrl/machine.h> |
---|
21 | 20 | #include <linux/pinctrl/pinconf.h> |
---|
22 | 21 | #include <linux/pinctrl/pinctrl.h> |
---|
.. | .. |
---|
59 | 58 | #define OUTPUT (1 << 7) |
---|
60 | 59 | #define OUTPUT_VAL_SHIFT 8 |
---|
61 | 60 | #define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT) |
---|
| 61 | +#define SLEWRATE_SHIFT 9 |
---|
| 62 | +#define SLEWRATE_MASK 0x1 |
---|
| 63 | +#define SLEWRATE (SLEWRATE_MASK << SLEWRATE_SHIFT) |
---|
62 | 64 | #define DEBOUNCE (1 << 16) |
---|
63 | 65 | #define DEBOUNCE_VAL_SHIFT 17 |
---|
64 | 66 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) |
---|
65 | 67 | |
---|
66 | | -/** |
---|
| 68 | +/* |
---|
67 | 69 | * These defines will translated the dt binding settings to our internal |
---|
68 | 70 | * settings. They are not necessarily the same value as the register setting. |
---|
69 | 71 | * The actual drive strength current of low, medium and high must be looked up |
---|
.. | .. |
---|
72 | 74 | * DRIVE_STRENGTH_DEFAULT is just a placeholder to avoid changing the drive |
---|
73 | 75 | * strength when there is no dt config for it. |
---|
74 | 76 | */ |
---|
75 | | -#define DRIVE_STRENGTH_DEFAULT (0 << DRIVE_STRENGTH_SHIFT) |
---|
76 | | -#define DRIVE_STRENGTH_LOW (1 << DRIVE_STRENGTH_SHIFT) |
---|
77 | | -#define DRIVE_STRENGTH_MED (2 << DRIVE_STRENGTH_SHIFT) |
---|
78 | | -#define DRIVE_STRENGTH_HI (3 << DRIVE_STRENGTH_SHIFT) |
---|
| 77 | +enum drive_strength_bit { |
---|
| 78 | + DRIVE_STRENGTH_BIT_DEF, |
---|
| 79 | + DRIVE_STRENGTH_BIT_LOW, |
---|
| 80 | + DRIVE_STRENGTH_BIT_MED, |
---|
| 81 | + DRIVE_STRENGTH_BIT_HI, |
---|
| 82 | +}; |
---|
| 83 | + |
---|
| 84 | +#define DRIVE_STRENGTH_BIT_MSK(name) (DRIVE_STRENGTH_BIT_##name << \ |
---|
| 85 | + DRIVE_STRENGTH_SHIFT) |
---|
| 86 | + |
---|
| 87 | +enum slewrate_bit { |
---|
| 88 | + SLEWRATE_BIT_ENA, |
---|
| 89 | + SLEWRATE_BIT_DIS, |
---|
| 90 | +}; |
---|
| 91 | + |
---|
| 92 | +#define SLEWRATE_BIT_MSK(name) (SLEWRATE_BIT_##name << SLEWRATE_SHIFT) |
---|
79 | 93 | |
---|
80 | 94 | /** |
---|
81 | 95 | * struct at91_pmx_func - describes AT91 pinmux functions |
---|
.. | .. |
---|
147 | 161 | * @set_pulldown: enable/disable pulldown |
---|
148 | 162 | * @get_schmitt_trig: get schmitt trigger status |
---|
149 | 163 | * @disable_schmitt_trig: disable schmitt trigger |
---|
| 164 | + * @get_drivestrength: get driver strength |
---|
| 165 | + * @set_drivestrength: set driver strength |
---|
| 166 | + * @get_slewrate: get slew rate |
---|
| 167 | + * @set_slewrate: set slew rate |
---|
150 | 168 | * @irq_type: return irq type |
---|
151 | 169 | */ |
---|
152 | 170 | struct at91_pinctrl_mux_ops { |
---|
.. | .. |
---|
166 | 184 | unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin); |
---|
167 | 185 | void (*set_drivestrength)(void __iomem *pio, unsigned pin, |
---|
168 | 186 | u32 strength); |
---|
| 187 | + unsigned (*get_slewrate)(void __iomem *pio, unsigned pin); |
---|
| 188 | + void (*set_slewrate)(void __iomem *pio, unsigned pin, u32 slewrate); |
---|
169 | 189 | /* irq */ |
---|
170 | 190 | int (*irq_type)(struct irq_data *d, unsigned type); |
---|
171 | 191 | }; |
---|
.. | .. |
---|
263 | 283 | */ |
---|
264 | 284 | grp = at91_pinctrl_find_group_by_name(info, np->name); |
---|
265 | 285 | if (!grp) { |
---|
266 | | - dev_err(info->dev, "unable to find group for node %s\n", |
---|
267 | | - np->name); |
---|
| 286 | + dev_err(info->dev, "unable to find group for node %pOFn\n", |
---|
| 287 | + np); |
---|
268 | 288 | return -EINVAL; |
---|
269 | 289 | } |
---|
270 | 290 | |
---|
.. | .. |
---|
551 | 571 | /* SAMA5 strength is 1:1 with our defines, |
---|
552 | 572 | * except 0 is equivalent to low per datasheet */ |
---|
553 | 573 | if (!tmp) |
---|
554 | | - tmp = DRIVE_STRENGTH_LOW; |
---|
| 574 | + tmp = DRIVE_STRENGTH_BIT_MSK(LOW); |
---|
555 | 575 | |
---|
556 | 576 | return tmp; |
---|
557 | 577 | } |
---|
.. | .. |
---|
564 | 584 | |
---|
565 | 585 | /* strength is inverse in SAM9x5s hardware with the pinctrl defines |
---|
566 | 586 | * hardware: 0 = hi, 1 = med, 2 = low, 3 = rsvd */ |
---|
567 | | - tmp = DRIVE_STRENGTH_HI - tmp; |
---|
| 587 | + tmp = DRIVE_STRENGTH_BIT_MSK(HI) - tmp; |
---|
568 | 588 | |
---|
569 | 589 | return tmp; |
---|
| 590 | +} |
---|
| 591 | + |
---|
| 592 | +static unsigned at91_mux_sam9x60_get_drivestrength(void __iomem *pio, |
---|
| 593 | + unsigned pin) |
---|
| 594 | +{ |
---|
| 595 | + unsigned tmp = readl_relaxed(pio + SAM9X60_PIO_DRIVER1); |
---|
| 596 | + |
---|
| 597 | + if (tmp & BIT(pin)) |
---|
| 598 | + return DRIVE_STRENGTH_BIT_HI; |
---|
| 599 | + |
---|
| 600 | + return DRIVE_STRENGTH_BIT_LOW; |
---|
| 601 | +} |
---|
| 602 | + |
---|
| 603 | +static unsigned at91_mux_sam9x60_get_slewrate(void __iomem *pio, unsigned pin) |
---|
| 604 | +{ |
---|
| 605 | + unsigned tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR); |
---|
| 606 | + |
---|
| 607 | + if ((tmp & BIT(pin))) |
---|
| 608 | + return SLEWRATE_BIT_ENA; |
---|
| 609 | + |
---|
| 610 | + return SLEWRATE_BIT_DIS; |
---|
570 | 611 | } |
---|
571 | 612 | |
---|
572 | 613 | static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength) |
---|
.. | .. |
---|
600 | 641 | |
---|
601 | 642 | /* strength is inverse on SAM9x5s with our defines |
---|
602 | 643 | * 0 = hi, 1 = med, 2 = low, 3 = rsvd */ |
---|
603 | | - setting = DRIVE_STRENGTH_HI - setting; |
---|
| 644 | + setting = DRIVE_STRENGTH_BIT_MSK(HI) - setting; |
---|
604 | 645 | |
---|
605 | 646 | set_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin, |
---|
606 | 647 | setting); |
---|
| 648 | +} |
---|
| 649 | + |
---|
| 650 | +static void at91_mux_sam9x60_set_drivestrength(void __iomem *pio, unsigned pin, |
---|
| 651 | + u32 setting) |
---|
| 652 | +{ |
---|
| 653 | + unsigned int tmp; |
---|
| 654 | + |
---|
| 655 | + if (setting <= DRIVE_STRENGTH_BIT_DEF || |
---|
| 656 | + setting == DRIVE_STRENGTH_BIT_MED || |
---|
| 657 | + setting > DRIVE_STRENGTH_BIT_HI) |
---|
| 658 | + return; |
---|
| 659 | + |
---|
| 660 | + tmp = readl_relaxed(pio + SAM9X60_PIO_DRIVER1); |
---|
| 661 | + |
---|
| 662 | + /* Strength is 0: low, 1: hi */ |
---|
| 663 | + if (setting == DRIVE_STRENGTH_BIT_LOW) |
---|
| 664 | + tmp &= ~BIT(pin); |
---|
| 665 | + else |
---|
| 666 | + tmp |= BIT(pin); |
---|
| 667 | + |
---|
| 668 | + writel_relaxed(tmp, pio + SAM9X60_PIO_DRIVER1); |
---|
| 669 | +} |
---|
| 670 | + |
---|
| 671 | +static void at91_mux_sam9x60_set_slewrate(void __iomem *pio, unsigned pin, |
---|
| 672 | + u32 setting) |
---|
| 673 | +{ |
---|
| 674 | + unsigned int tmp; |
---|
| 675 | + |
---|
| 676 | + if (setting < SLEWRATE_BIT_ENA || setting > SLEWRATE_BIT_DIS) |
---|
| 677 | + return; |
---|
| 678 | + |
---|
| 679 | + tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR); |
---|
| 680 | + |
---|
| 681 | + if (setting == SLEWRATE_BIT_DIS) |
---|
| 682 | + tmp &= ~BIT(pin); |
---|
| 683 | + else |
---|
| 684 | + tmp |= BIT(pin); |
---|
| 685 | + |
---|
| 686 | + writel_relaxed(tmp, pio + SAM9X60_PIO_SLEWR); |
---|
607 | 687 | } |
---|
608 | 688 | |
---|
609 | 689 | static struct at91_pinctrl_mux_ops at91rm9200_ops = { |
---|
.. | .. |
---|
631 | 711 | .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, |
---|
632 | 712 | .get_drivestrength = at91_mux_sam9x5_get_drivestrength, |
---|
633 | 713 | .set_drivestrength = at91_mux_sam9x5_set_drivestrength, |
---|
| 714 | + .irq_type = alt_gpio_irq_type, |
---|
| 715 | +}; |
---|
| 716 | + |
---|
| 717 | +static const struct at91_pinctrl_mux_ops sam9x60_ops = { |
---|
| 718 | + .get_periph = at91_mux_pio3_get_periph, |
---|
| 719 | + .mux_A_periph = at91_mux_pio3_set_A_periph, |
---|
| 720 | + .mux_B_periph = at91_mux_pio3_set_B_periph, |
---|
| 721 | + .mux_C_periph = at91_mux_pio3_set_C_periph, |
---|
| 722 | + .mux_D_periph = at91_mux_pio3_set_D_periph, |
---|
| 723 | + .get_deglitch = at91_mux_pio3_get_deglitch, |
---|
| 724 | + .set_deglitch = at91_mux_pio3_set_deglitch, |
---|
| 725 | + .get_debounce = at91_mux_pio3_get_debounce, |
---|
| 726 | + .set_debounce = at91_mux_pio3_set_debounce, |
---|
| 727 | + .get_pulldown = at91_mux_pio3_get_pulldown, |
---|
| 728 | + .set_pulldown = at91_mux_pio3_set_pulldown, |
---|
| 729 | + .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, |
---|
| 730 | + .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, |
---|
| 731 | + .get_drivestrength = at91_mux_sam9x60_get_drivestrength, |
---|
| 732 | + .set_drivestrength = at91_mux_sam9x60_set_drivestrength, |
---|
| 733 | + .get_slewrate = at91_mux_sam9x60_get_slewrate, |
---|
| 734 | + .set_slewrate = at91_mux_sam9x60_set_slewrate, |
---|
634 | 735 | .irq_type = alt_gpio_irq_type, |
---|
635 | 736 | }; |
---|
636 | 737 | |
---|
.. | .. |
---|
893 | 994 | if (info->ops->get_drivestrength) |
---|
894 | 995 | *config |= (info->ops->get_drivestrength(pio, pin) |
---|
895 | 996 | << DRIVE_STRENGTH_SHIFT); |
---|
| 997 | + if (info->ops->get_slewrate) |
---|
| 998 | + *config |= (info->ops->get_slewrate(pio, pin) << SLEWRATE_SHIFT); |
---|
896 | 999 | if (at91_mux_get_output(pio, pin, &out)) |
---|
897 | 1000 | *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT); |
---|
898 | 1001 | |
---|
.. | .. |
---|
944 | 1047 | info->ops->set_drivestrength(pio, pin, |
---|
945 | 1048 | (config & DRIVE_STRENGTH) |
---|
946 | 1049 | >> DRIVE_STRENGTH_SHIFT); |
---|
| 1050 | + if (info->ops->set_slewrate) |
---|
| 1051 | + info->ops->set_slewrate(pio, pin, |
---|
| 1052 | + (config & SLEWRATE) >> SLEWRATE_SHIFT); |
---|
947 | 1053 | |
---|
948 | 1054 | } /* for each config */ |
---|
949 | 1055 | |
---|
.. | .. |
---|
959 | 1065 | } \ |
---|
960 | 1066 | } while (0) |
---|
961 | 1067 | |
---|
962 | | -#define DBG_SHOW_FLAG_MASKED(mask,flag) do { \ |
---|
| 1068 | +#define DBG_SHOW_FLAG_MASKED(mask, flag, name) do { \ |
---|
963 | 1069 | if ((config & mask) == flag) { \ |
---|
964 | 1070 | if (num_conf) \ |
---|
965 | 1071 | seq_puts(s, "|"); \ |
---|
966 | | - seq_puts(s, #flag); \ |
---|
| 1072 | + seq_puts(s, #name); \ |
---|
967 | 1073 | num_conf++; \ |
---|
968 | 1074 | } \ |
---|
969 | 1075 | } while (0) |
---|
.. | .. |
---|
981 | 1087 | DBG_SHOW_FLAG(PULL_DOWN); |
---|
982 | 1088 | DBG_SHOW_FLAG(DIS_SCHMIT); |
---|
983 | 1089 | DBG_SHOW_FLAG(DEGLITCH); |
---|
984 | | - DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_LOW); |
---|
985 | | - DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_MED); |
---|
986 | | - DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_HI); |
---|
| 1090 | + DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_BIT_MSK(LOW), |
---|
| 1091 | + DRIVE_STRENGTH_LOW); |
---|
| 1092 | + DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_BIT_MSK(MED), |
---|
| 1093 | + DRIVE_STRENGTH_MED); |
---|
| 1094 | + DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_BIT_MSK(HI), |
---|
| 1095 | + DRIVE_STRENGTH_HI); |
---|
| 1096 | + DBG_SHOW_FLAG(SLEWRATE); |
---|
987 | 1097 | DBG_SHOW_FLAG(DEBOUNCE); |
---|
988 | 1098 | if (config & DEBOUNCE) { |
---|
989 | 1099 | val = config >> DEBOUNCE_VAL_SHIFT; |
---|
.. | .. |
---|
1071 | 1181 | const __be32 *list; |
---|
1072 | 1182 | int i, j; |
---|
1073 | 1183 | |
---|
1074 | | - dev_dbg(info->dev, "group(%d): %s\n", index, np->name); |
---|
| 1184 | + dev_dbg(info->dev, "group(%d): %pOFn\n", index, np); |
---|
1075 | 1185 | |
---|
1076 | 1186 | /* Initialise group */ |
---|
1077 | 1187 | grp->name = np->name; |
---|
.. | .. |
---|
1122 | 1232 | static u32 grp_index; |
---|
1123 | 1233 | u32 i = 0; |
---|
1124 | 1234 | |
---|
1125 | | - dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); |
---|
| 1235 | + dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np); |
---|
1126 | 1236 | |
---|
1127 | 1237 | func = &info->functions[index]; |
---|
1128 | 1238 | |
---|
.. | .. |
---|
1155 | 1265 | { .compatible = "atmel,sama5d3-pinctrl", .data = &sama5d3_ops }, |
---|
1156 | 1266 | { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops }, |
---|
1157 | 1267 | { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops }, |
---|
| 1268 | + { .compatible = "microchip,sam9x60-pinctrl", .data = &sam9x60_ops }, |
---|
1158 | 1269 | { /* sentinel */ } |
---|
1159 | 1270 | }; |
---|
1160 | 1271 | |
---|
.. | .. |
---|
1306 | 1417 | u32 osr; |
---|
1307 | 1418 | |
---|
1308 | 1419 | osr = readl_relaxed(pio + PIO_OSR); |
---|
1309 | | - return !(osr & mask); |
---|
| 1420 | + if (osr & mask) |
---|
| 1421 | + return GPIO_LINE_DIRECTION_OUT; |
---|
| 1422 | + |
---|
| 1423 | + return GPIO_LINE_DIRECTION_IN; |
---|
1310 | 1424 | } |
---|
1311 | 1425 | |
---|
1312 | 1426 | static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
---|
.. | .. |
---|
1375 | 1489 | int i; |
---|
1376 | 1490 | struct at91_gpio_chip *at91_gpio = gpiochip_get_data(chip); |
---|
1377 | 1491 | void __iomem *pio = at91_gpio->regbase; |
---|
| 1492 | + const char *gpio_label; |
---|
1378 | 1493 | |
---|
1379 | | - for (i = 0; i < chip->ngpio; i++) { |
---|
| 1494 | + for_each_requested_gpio(chip, i, gpio_label) { |
---|
1380 | 1495 | unsigned mask = pin_to_mask(i); |
---|
1381 | | - const char *gpio_label; |
---|
1382 | 1496 | |
---|
1383 | | - gpio_label = gpiochip_is_requested(chip, i); |
---|
1384 | | - if (!gpio_label) |
---|
1385 | | - continue; |
---|
1386 | 1497 | mode = at91_gpio->ops->get_periph(pio, mask); |
---|
1387 | 1498 | seq_printf(s, "[%s] GPIO%s%d: ", |
---|
1388 | 1499 | gpio_label, chip->label, i); |
---|
.. | .. |
---|
1487 | 1598 | return 0; |
---|
1488 | 1599 | case IRQ_TYPE_NONE: |
---|
1489 | 1600 | default: |
---|
1490 | | - pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); |
---|
| 1601 | + pr_warn("AT91: No type for GPIO irq offset %d\n", d->irq); |
---|
1491 | 1602 | return -EINVAL; |
---|
1492 | 1603 | } |
---|
1493 | 1604 | |
---|
.. | .. |
---|
1615 | 1726 | struct at91_gpio_chip *prev = NULL; |
---|
1616 | 1727 | struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); |
---|
1617 | 1728 | struct irq_chip *gpio_irqchip; |
---|
1618 | | - int ret, i; |
---|
| 1729 | + struct gpio_irq_chip *girq; |
---|
| 1730 | + int i; |
---|
1619 | 1731 | |
---|
1620 | | - gpio_irqchip = devm_kzalloc(&pdev->dev, sizeof(*gpio_irqchip), GFP_KERNEL); |
---|
| 1732 | + gpio_irqchip = devm_kzalloc(&pdev->dev, sizeof(*gpio_irqchip), |
---|
| 1733 | + GFP_KERNEL); |
---|
1621 | 1734 | if (!gpio_irqchip) |
---|
1622 | 1735 | return -ENOMEM; |
---|
1623 | 1736 | |
---|
.. | .. |
---|
1639 | 1752 | * handler will perform the actual work of handling the parent |
---|
1640 | 1753 | * interrupt. |
---|
1641 | 1754 | */ |
---|
1642 | | - ret = gpiochip_irqchip_add(&at91_gpio->chip, |
---|
1643 | | - gpio_irqchip, |
---|
1644 | | - 0, |
---|
1645 | | - handle_edge_irq, |
---|
1646 | | - IRQ_TYPE_NONE); |
---|
1647 | | - if (ret) { |
---|
1648 | | - dev_err(&pdev->dev, "at91_gpio.%d: Couldn't add irqchip to gpiochip.\n", |
---|
1649 | | - at91_gpio->pioc_idx); |
---|
1650 | | - return ret; |
---|
1651 | | - } |
---|
| 1755 | + girq = &at91_gpio->chip.irq; |
---|
| 1756 | + girq->chip = gpio_irqchip; |
---|
| 1757 | + girq->default_type = IRQ_TYPE_NONE; |
---|
| 1758 | + girq->handler = handle_edge_irq; |
---|
1652 | 1759 | |
---|
1653 | | - /* The top level handler handles one bank of GPIOs, except |
---|
| 1760 | + /* |
---|
| 1761 | + * The top level handler handles one bank of GPIOs, except |
---|
1654 | 1762 | * on some SoC it can handle up to three... |
---|
1655 | 1763 | * We only set up the handler for the first of the list. |
---|
1656 | 1764 | */ |
---|
1657 | 1765 | gpiochip_prev = irq_get_handler_data(at91_gpio->pioc_virq); |
---|
1658 | 1766 | if (!gpiochip_prev) { |
---|
1659 | | - /* Then register the chain on the parent IRQ */ |
---|
1660 | | - gpiochip_set_chained_irqchip(&at91_gpio->chip, |
---|
1661 | | - gpio_irqchip, |
---|
1662 | | - at91_gpio->pioc_virq, |
---|
1663 | | - gpio_irq_handler); |
---|
| 1767 | + girq->parent_handler = gpio_irq_handler; |
---|
| 1768 | + girq->num_parents = 1; |
---|
| 1769 | + girq->parents = devm_kcalloc(&pdev->dev, 1, |
---|
| 1770 | + sizeof(*girq->parents), |
---|
| 1771 | + GFP_KERNEL); |
---|
| 1772 | + if (!girq->parents) |
---|
| 1773 | + return -ENOMEM; |
---|
| 1774 | + girq->parents[0] = at91_gpio->pioc_virq; |
---|
1664 | 1775 | return 0; |
---|
1665 | 1776 | } |
---|
1666 | 1777 | |
---|
1667 | 1778 | prev = gpiochip_get_data(gpiochip_prev); |
---|
1668 | | - |
---|
1669 | 1779 | /* we can only have 2 banks before */ |
---|
1670 | 1780 | for (i = 0; i < 2; i++) { |
---|
1671 | 1781 | if (prev->next) { |
---|
.. | .. |
---|
1697 | 1807 | static const struct of_device_id at91_gpio_of_match[] = { |
---|
1698 | 1808 | { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, |
---|
1699 | 1809 | { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, |
---|
| 1810 | + { .compatible = "microchip,sam9x60-gpio", .data = &sam9x60_ops }, |
---|
1700 | 1811 | { /* sentinel */ } |
---|
1701 | 1812 | }; |
---|
1702 | 1813 | |
---|
1703 | 1814 | static int at91_gpio_probe(struct platform_device *pdev) |
---|
1704 | 1815 | { |
---|
1705 | 1816 | struct device_node *np = pdev->dev.of_node; |
---|
1706 | | - struct resource *res; |
---|
1707 | 1817 | struct at91_gpio_chip *at91_chip = NULL; |
---|
1708 | 1818 | struct gpio_chip *chip; |
---|
1709 | 1819 | struct pinctrl_gpio_range *range; |
---|
.. | .. |
---|
1731 | 1841 | goto err; |
---|
1732 | 1842 | } |
---|
1733 | 1843 | |
---|
1734 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1735 | | - at91_chip->regbase = devm_ioremap_resource(&pdev->dev, res); |
---|
| 1844 | + at91_chip->regbase = devm_platform_ioremap_resource(pdev, 0); |
---|
1736 | 1845 | if (IS_ERR(at91_chip->regbase)) { |
---|
1737 | 1846 | ret = PTR_ERR(at91_chip->regbase); |
---|
1738 | 1847 | goto err; |
---|
.. | .. |
---|
1782 | 1891 | } |
---|
1783 | 1892 | |
---|
1784 | 1893 | for (i = 0; i < chip->ngpio; i++) |
---|
1785 | | - names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); |
---|
| 1894 | + names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); |
---|
1786 | 1895 | |
---|
1787 | 1896 | chip->names = (const char *const *)names; |
---|
1788 | 1897 | |
---|
.. | .. |
---|
1794 | 1903 | range->npins = chip->ngpio; |
---|
1795 | 1904 | range->gc = chip; |
---|
1796 | 1905 | |
---|
| 1906 | + ret = at91_gpio_of_irq_setup(pdev, at91_chip); |
---|
| 1907 | + if (ret) |
---|
| 1908 | + goto gpiochip_add_err; |
---|
| 1909 | + |
---|
1797 | 1910 | ret = gpiochip_add_data(chip, at91_chip); |
---|
1798 | 1911 | if (ret) |
---|
1799 | 1912 | goto gpiochip_add_err; |
---|
.. | .. |
---|
1801 | 1914 | gpio_chips[alias_idx] = at91_chip; |
---|
1802 | 1915 | gpio_banks = max(gpio_banks, alias_idx + 1); |
---|
1803 | 1916 | |
---|
1804 | | - ret = at91_gpio_of_irq_setup(pdev, at91_chip); |
---|
1805 | | - if (ret) |
---|
1806 | | - goto irq_setup_err; |
---|
1807 | | - |
---|
1808 | 1917 | dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase); |
---|
1809 | 1918 | |
---|
1810 | 1919 | return 0; |
---|
1811 | 1920 | |
---|
1812 | | -irq_setup_err: |
---|
1813 | | - gpiochip_remove(chip); |
---|
1814 | 1921 | gpiochip_add_err: |
---|
1815 | 1922 | clk_enable_err: |
---|
1816 | 1923 | clk_disable_unprepare(at91_chip->clock); |
---|