| @@ -10,6 +10,7 @@ · 9 unmodified lines |
| 10 | 10 | #include <linux/gpio/driver.h> |
| 11 | 11 | #include <linux/init.h> |
| 12 | 12 | #include <linux/interrupt.h> |
| 13 | +#include <linux/spinlock.h> |
| 13 | 14 | #include <linux/io.h> |
| 14 | 15 | #include <linux/module.h> |
| 15 | 16 | #include <linux/platform_device.h> |
| @@ -21,6 +22,9 @@ · 5 unmodified lines |
| 21 | 22 | /* Maximum banks */ |
| 22 | 23 | #define ZYNQ_GPIO_MAX_BANK 4 |
| 23 | 24 | #define ZYNQMP_GPIO_MAX_BANK 6 |
| 25 | +#define VERSAL_GPIO_MAX_BANK 4 |
| 26 | +#define PMC_GPIO_MAX_BANK 5 |
| 27 | +#define VERSAL_UNUSED_BANKS 2 |
| 24 | 28 | |
| 25 | 29 | #define ZYNQ_GPIO_BANK0_NGPIO 32 |
| 26 | 30 | #define ZYNQ_GPIO_BANK1_NGPIO 22 |
| @@ -95,6 +99,7 @@ · 68 unmodified lines |
| 95 | 99 | /* set to differentiate zynq from zynqmp, 0=zynqmp, 1=zynq */ |
| 96 | 100 | #define ZYNQ_GPIO_QUIRK_IS_ZYNQ BIT(0) |
| 97 | 101 | #define GPIO_QUIRK_DATA_RO_BUG BIT(1) |
| 102 | +#define GPIO_QUIRK_VERSAL BIT(2) |
| 98 | 103 | |
| 99 | 104 | struct gpio_regs { |
| 100 | 105 | u32 datamsw[ZYNQMP_GPIO_MAX_BANK]; |
| @@ -116,6 +121,7 @@ struct gpio_regs { · 15 unmodified lines |
| 116 | 121 | * @irq: interrupt for the GPIO device |
| 117 | 122 | * @p_data: pointer to platform data |
| 118 | 123 | * @context: context registers |
| 124 | + * @dirlock: lock used for direction in/out synchronization |
| 119 | 125 | */ |
| 120 | 126 | struct zynq_gpio { |
| 121 | 127 | struct gpio_chip chip; |
| @@ -124,6 +130,7 @@ struct zynq_gpio { · 2 unmodified lines |
| 124 | 130 | int irq; |
| 125 | 131 | const struct zynq_platform_data *p_data; |
| 126 | 132 | struct gpio_regs context; |
| 133 | + spinlock_t dirlock; /* lock */ |
| 127 | 134 | }; |
| 128 | 135 | |
| 129 | 136 | /** |
| @@ -196,6 +203,8 @@ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, · 66 unmodified lines |
| 196 | 203 | gpio->p_data->bank_min[bank]; |
| 197 | 204 | return; |
| 198 | 205 | } |
| 206 | + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) |
| 207 | + bank = bank + VERSAL_UNUSED_BANKS; |
| 199 | 208 | } |
| 200 | 209 | |
| 201 | 210 | /* default */ |
| @@ -297,6 +306,7 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) · 95 unmodified lines |
| 297 | 306 | { |
| 298 | 307 | u32 reg; |
| 299 | 308 | unsigned int bank_num, bank_pin_num; |
| 309 | + unsigned long flags; |
| 300 | 310 | struct zynq_gpio *gpio = gpiochip_get_data(chip); |
| 301 | 311 | |
| 302 | 312 | zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); |
| @@ -310,9 +320,11 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) · 7 unmodified lines |
| 310 | 320 | return -EINVAL; |
| 311 | 321 | |
| 312 | 322 | /* clear the bit in direction mode reg to set the pin as input */ |
| 323 | + spin_lock_irqsave(&gpio->dirlock, flags); |
| 313 | 324 | reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
| 314 | 325 | reg &= ~BIT(bank_pin_num); |
| 315 | 326 | writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
| 327 | + spin_unlock_irqrestore(&gpio->dirlock, flags); |
| 316 | 328 | |
| 317 | 329 | return 0; |
| 318 | 330 | } |
| @@ -334,11 +346,13 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, · 15 unmodified lines |
| 334 | 346 | { |
| 335 | 347 | u32 reg; |
| 336 | 348 | unsigned int bank_num, bank_pin_num; |
| 349 | + unsigned long flags; |
| 337 | 350 | struct zynq_gpio *gpio = gpiochip_get_data(chip); |
| 338 | 351 | |
| 339 | 352 | zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); |
| 340 | 353 | |
| 341 | 354 | /* set the GPIO pin as output */ |
| 355 | + spin_lock_irqsave(&gpio->dirlock, flags); |
| 342 | 356 | reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
| 343 | 357 | reg |= BIT(bank_pin_num); |
| 344 | 358 | writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
| @@ -347,6 +361,7 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, · 2 unmodified lines |
| 347 | 361 | reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); |
| 348 | 362 | reg |= BIT(bank_pin_num); |
| 349 | 363 | writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); |
| 364 | + spin_unlock_irqrestore(&gpio->dirlock, flags); |
| 350 | 365 | |
| 351 | 366 | /* set the state of the pin */ |
| 352 | 367 | zynq_gpio_set_value(chip, pin, state); |
| @@ -647,6 +662,8 @@ static void zynq_gpio_irqhandler(struct irq_desc *desc) · 294 unmodified lines |
| 647 | 662 | int_enb = readl_relaxed(gpio->base_addr + |
| 648 | 663 | ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); |
| 649 | 664 | zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb); |
| 665 | + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) |
| 666 | + bank_num = bank_num + VERSAL_UNUSED_BANKS; |
| 650 | 667 | } |
| 651 | 668 | |
| 652 | 669 | chained_irq_exit(irqchip, desc); |
| @@ -676,6 +693,8 @@ static void zynq_gpio_save_context(struct zynq_gpio *gpio) · 23 unmodified lines |
| 676 | 693 | gpio->context.int_any[bank_num] = |
| 677 | 694 | readl_relaxed(gpio->base_addr + |
| 678 | 695 | ZYNQ_GPIO_INTANY_OFFSET(bank_num)); |
| 696 | + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) |
| 697 | + bank_num = bank_num + VERSAL_UNUSED_BANKS; |
| 679 | 698 | } |
| 680 | 699 | } |
| 681 | 700 | |
| @@ -707,6 +726,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) · 25 unmodified lines |
| 707 | 726 | writel_relaxed(~(gpio->context.int_en[bank_num]), |
| 708 | 727 | gpio->base_addr + |
| 709 | 728 | ZYNQ_GPIO_INTEN_OFFSET(bank_num)); |
| 729 | + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) |
| 730 | + bank_num = bank_num + VERSAL_UNUSED_BANKS; |
| 710 | 731 | } |
| 711 | 732 | } |
| 712 | 733 | |
| @@ -715,6 +736,9 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev) · 2 unmodified lines |
| 715 | 736 | struct zynq_gpio *gpio = dev_get_drvdata(dev); |
| 716 | 737 | struct irq_data *data = irq_get_irq_data(gpio->irq); |
| 717 | 738 | |
| 739 | + if (!device_may_wakeup(dev)) |
| 740 | + disable_irq(gpio->irq); |
| 741 | + |
| 718 | 742 | if (!irqd_is_wakeup_set(data)) { |
| 719 | 743 | zynq_gpio_save_context(gpio); |
| 720 | 744 | return pm_runtime_force_suspend(dev); |
| @@ -729,6 +753,9 @@ static int __maybe_unused zynq_gpio_resume(struct device *dev) · 8 unmodified lines |
| 729 | 753 | struct irq_data *data = irq_get_irq_data(gpio->irq); |
| 730 | 754 | int ret; |
| 731 | 755 | |
| 756 | + if (!device_may_wakeup(dev)) |
| 757 | + enable_irq(gpio->irq); |
| 758 | + |
| 732 | 759 | if (!irqd_is_wakeup_set(data)) { |
| 733 | 760 | ret = pm_runtime_force_resume(dev); |
| 734 | 761 | zynq_gpio_restore_context(gpio); |
| @@ -778,6 +805,31 @@ static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { · 43 unmodified lines |
| 778 | 805 | zynq_gpio_runtime_resume, NULL) |
| 779 | 806 | }; |
| 780 | 807 | |
| 808 | +static const struct zynq_platform_data versal_gpio_def = { |
| 809 | + .label = "versal_gpio", |
| 810 | + .quirks = GPIO_QUIRK_VERSAL, |
| 811 | + .ngpio = 58, |
| 812 | + .max_bank = VERSAL_GPIO_MAX_BANK, |
| 813 | + .bank_min[0] = 0, |
| 814 | + .bank_max[0] = 25, /* 0 to 25 are connected to MIOs (26 pins) */ |
| 815 | + .bank_min[3] = 26, |
| 816 | + .bank_max[3] = 57, /* Bank 3 is connected to FMIOs (32 pins) */ |
| 817 | +}; |
| 818 | + |
| 819 | +static const struct zynq_platform_data pmc_gpio_def = { |
| 820 | + .label = "pmc_gpio", |
| 821 | + .ngpio = 116, |
| 822 | + .max_bank = PMC_GPIO_MAX_BANK, |
| 823 | + .bank_min[0] = 0, |
| 824 | + .bank_max[0] = 25, /* 0 to 25 are connected to MIOs (26 pins) */ |
| 825 | + .bank_min[1] = 26, |
| 826 | + .bank_max[1] = 51, /* Bank 1 are connected to MIOs (26 pins) */ |
| 827 | + .bank_min[3] = 52, |
| 828 | + .bank_max[3] = 83, /* Bank 3 is connected to EMIOs (32 pins) */ |
| 829 | + .bank_min[4] = 84, |
| 830 | + .bank_max[4] = 115, /* Bank 4 is connected to EMIOs (32 pins) */ |
| 831 | +}; |
| 832 | + |
| 781 | 833 | static const struct zynq_platform_data zynqmp_gpio_def = { |
| 782 | 834 | .label = "zynqmp_gpio", |
| 783 | 835 | .quirks = GPIO_QUIRK_DATA_RO_BUG, |
| @@ -815,6 +867,8 @@ static const struct zynq_platform_data zynq_gpio_def = { · 31 unmodified lines |
| 815 | 867 | static const struct of_device_id zynq_gpio_of_match[] = { |
| 816 | 868 | { .compatible = "xlnx,zynq-gpio-1.0", .data = &zynq_gpio_def }, |
| 817 | 869 | { .compatible = "xlnx,zynqmp-gpio-1.0", .data = &zynqmp_gpio_def }, |
| 870 | + { .compatible = "xlnx,versal-gpio-1.0", .data = &versal_gpio_def }, |
| 871 | + { .compatible = "xlnx,pmc-gpio-1.0", .data = &pmc_gpio_def }, |
| 818 | 872 | { /* end of table */ } |
| 819 | 873 | }; |
| 820 | 874 | MODULE_DEVICE_TABLE(of, zynq_gpio_of_match); |
| @@ -876,7 +930,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) · 55 unmodified lines |
| 876 | 930 | /* Retrieve GPIO clock */ |
| 877 | 931 | gpio->clk = devm_clk_get(&pdev->dev, NULL); |
| 878 | 932 | if (IS_ERR(gpio->clk)) { |
| 879 | | − dev_err(&pdev->dev, "input clock not found.\n"); |
| 933 | + if (PTR_ERR(gpio->clk) != -EPROBE_DEFER) |
| 934 | + dev_err(&pdev->dev, "input clock not found.\n"); |
| 880 | 935 | return PTR_ERR(gpio->clk); |
| 881 | 936 | } |
| 882 | 937 | ret = clk_prepare_enable(gpio->clk); |
| @@ -885,6 +940,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) · 2 unmodified lines |
| 885 | 940 | return ret; |
| 886 | 941 | } |
| 887 | 942 | |
| 943 | + spin_lock_init(&gpio->dirlock); |
| 944 | + |
| 888 | 945 | pm_runtime_set_active(&pdev->dev); |
| 889 | 946 | pm_runtime_enable(&pdev->dev); |
| 890 | 947 | ret = pm_runtime_get_sync(&pdev->dev); |
| @@ -892,9 +949,12 @@ static int zynq_gpio_probe(struct platform_device *pdev) · 1 unmodified line |
| 892 | 949 | goto err_pm_dis; |
| 893 | 950 | |
| 894 | 951 | /* disable interrupts for all banks */ |
| 895 | | − for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) |
| 952 | + for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { |
| 896 | 953 | writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + |
| 897 | 954 | ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); |
| 955 | + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) |
| 956 | + bank_num = bank_num + VERSAL_UNUSED_BANKS; |
| 957 | + } |
| 898 | 958 | |
| 899 | 959 | /* Set up the GPIO irqchip */ |
| 900 | 960 | girq = &chip->irq; |
| @@ -919,6 +979,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) · 18 unmodified lines |
| 919 | 979 | goto err_pm_put; |
| 920 | 980 | } |
| 921 | 981 | |
| 982 | + irq_set_status_flags(gpio->irq, IRQ_DISABLE_UNLAZY); |
| 983 | + device_init_wakeup(&pdev->dev, 1); |
| 922 | 984 | pm_runtime_put(&pdev->dev); |
| 923 | 985 | |
| 924 | 986 | return 0; |