diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-28 20:42:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-28 20:42:44 -0400 |
commit | 900915f9036fbf029d899432af96d39fcaaa7b54 (patch) | |
tree | 85a609000b692e6d2b277d83340026406508f6c1 | |
parent | f151f57bfd97fb8c76bbef9e181ecba5dd750f2a (diff) | |
parent | 72923e5488f0604fac8ef2c7e683fabd3b4c203b (diff) |
Merge tag 'pinctrl-v4.19-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Linus writes:
"Pin control fixes for v4.19:
- Fixes to x86 hardware:
- AMD interrupt debounce issues
- Faulty Intel cannonlake register offset
- Revert pin translation IRQ locking"
* tag 'pinctrl-v4.19-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
Revert "pinctrl: intel: Do pin translation when lock IRQ"
pinctrl: cannonlake: Fix HOSTSW_OWN register offset of H variant
pinctrl/amd: poll InterruptEnable bits in amd_gpio_irq_set_type
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cannonlake.c | 33 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 32 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-amd.c | 33 |
3 files changed, 43 insertions, 55 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c index 8d48371caaa2..e7f45d96b0cb 100644 --- a/drivers/pinctrl/intel/pinctrl-cannonlake.c +++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c | |||
@@ -15,10 +15,11 @@ | |||
15 | 15 | ||
16 | #include "pinctrl-intel.h" | 16 | #include "pinctrl-intel.h" |
17 | 17 | ||
18 | #define CNL_PAD_OWN 0x020 | 18 | #define CNL_PAD_OWN 0x020 |
19 | #define CNL_PADCFGLOCK 0x080 | 19 | #define CNL_PADCFGLOCK 0x080 |
20 | #define CNL_HOSTSW_OWN 0x0b0 | 20 | #define CNL_LP_HOSTSW_OWN 0x0b0 |
21 | #define CNL_GPI_IE 0x120 | 21 | #define CNL_H_HOSTSW_OWN 0x0c0 |
22 | #define CNL_GPI_IE 0x120 | ||
22 | 23 | ||
23 | #define CNL_GPP(r, s, e, g) \ | 24 | #define CNL_GPP(r, s, e, g) \ |
24 | { \ | 25 | { \ |
@@ -30,12 +31,12 @@ | |||
30 | 31 | ||
31 | #define CNL_NO_GPIO -1 | 32 | #define CNL_NO_GPIO -1 |
32 | 33 | ||
33 | #define CNL_COMMUNITY(b, s, e, g) \ | 34 | #define CNL_COMMUNITY(b, s, e, o, g) \ |
34 | { \ | 35 | { \ |
35 | .barno = (b), \ | 36 | .barno = (b), \ |
36 | .padown_offset = CNL_PAD_OWN, \ | 37 | .padown_offset = CNL_PAD_OWN, \ |
37 | .padcfglock_offset = CNL_PADCFGLOCK, \ | 38 | .padcfglock_offset = CNL_PADCFGLOCK, \ |
38 | .hostown_offset = CNL_HOSTSW_OWN, \ | 39 | .hostown_offset = (o), \ |
39 | .ie_offset = CNL_GPI_IE, \ | 40 | .ie_offset = CNL_GPI_IE, \ |
40 | .pin_base = (s), \ | 41 | .pin_base = (s), \ |
41 | .npins = ((e) - (s) + 1), \ | 42 | .npins = ((e) - (s) + 1), \ |
@@ -43,6 +44,12 @@ | |||
43 | .ngpps = ARRAY_SIZE(g), \ | 44 | .ngpps = ARRAY_SIZE(g), \ |
44 | } | 45 | } |
45 | 46 | ||
47 | #define CNLLP_COMMUNITY(b, s, e, g) \ | ||
48 | CNL_COMMUNITY(b, s, e, CNL_LP_HOSTSW_OWN, g) | ||
49 | |||
50 | #define CNLH_COMMUNITY(b, s, e, g) \ | ||
51 | CNL_COMMUNITY(b, s, e, CNL_H_HOSTSW_OWN, g) | ||
52 | |||
46 | /* Cannon Lake-H */ | 53 | /* Cannon Lake-H */ |
47 | static const struct pinctrl_pin_desc cnlh_pins[] = { | 54 | static const struct pinctrl_pin_desc cnlh_pins[] = { |
48 | /* GPP_A */ | 55 | /* GPP_A */ |
@@ -442,10 +449,10 @@ static const struct intel_function cnlh_functions[] = { | |||
442 | }; | 449 | }; |
443 | 450 | ||
444 | static const struct intel_community cnlh_communities[] = { | 451 | static const struct intel_community cnlh_communities[] = { |
445 | CNL_COMMUNITY(0, 0, 50, cnlh_community0_gpps), | 452 | CNLH_COMMUNITY(0, 0, 50, cnlh_community0_gpps), |
446 | CNL_COMMUNITY(1, 51, 154, cnlh_community1_gpps), | 453 | CNLH_COMMUNITY(1, 51, 154, cnlh_community1_gpps), |
447 | CNL_COMMUNITY(2, 155, 248, cnlh_community3_gpps), | 454 | CNLH_COMMUNITY(2, 155, 248, cnlh_community3_gpps), |
448 | CNL_COMMUNITY(3, 249, 298, cnlh_community4_gpps), | 455 | CNLH_COMMUNITY(3, 249, 298, cnlh_community4_gpps), |
449 | }; | 456 | }; |
450 | 457 | ||
451 | static const struct intel_pinctrl_soc_data cnlh_soc_data = { | 458 | static const struct intel_pinctrl_soc_data cnlh_soc_data = { |
@@ -803,9 +810,9 @@ static const struct intel_padgroup cnllp_community4_gpps[] = { | |||
803 | }; | 810 | }; |
804 | 811 | ||
805 | static const struct intel_community cnllp_communities[] = { | 812 | static const struct intel_community cnllp_communities[] = { |
806 | CNL_COMMUNITY(0, 0, 67, cnllp_community0_gpps), | 813 | CNLLP_COMMUNITY(0, 0, 67, cnllp_community0_gpps), |
807 | CNL_COMMUNITY(1, 68, 180, cnllp_community1_gpps), | 814 | CNLLP_COMMUNITY(1, 68, 180, cnllp_community1_gpps), |
808 | CNL_COMMUNITY(2, 181, 243, cnllp_community4_gpps), | 815 | CNLLP_COMMUNITY(2, 181, 243, cnllp_community4_gpps), |
809 | }; | 816 | }; |
810 | 817 | ||
811 | static const struct intel_pinctrl_soc_data cnllp_soc_data = { | 818 | static const struct intel_pinctrl_soc_data cnllp_soc_data = { |
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index ec8dafc94694..1ea3438ea67e 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c | |||
@@ -887,36 +887,6 @@ static const struct gpio_chip intel_gpio_chip = { | |||
887 | .set_config = gpiochip_generic_config, | 887 | .set_config = gpiochip_generic_config, |
888 | }; | 888 | }; |
889 | 889 | ||
890 | static int intel_gpio_irq_reqres(struct irq_data *d) | ||
891 | { | ||
892 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||
893 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); | ||
894 | int pin; | ||
895 | int ret; | ||
896 | |||
897 | pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL); | ||
898 | if (pin >= 0) { | ||
899 | ret = gpiochip_lock_as_irq(gc, pin); | ||
900 | if (ret) { | ||
901 | dev_err(pctrl->dev, "unable to lock HW IRQ %d for IRQ\n", | ||
902 | pin); | ||
903 | return ret; | ||
904 | } | ||
905 | } | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static void intel_gpio_irq_relres(struct irq_data *d) | ||
910 | { | ||
911 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||
912 | struct intel_pinctrl *pctrl = gpiochip_get_data(gc); | ||
913 | int pin; | ||
914 | |||
915 | pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL); | ||
916 | if (pin >= 0) | ||
917 | gpiochip_unlock_as_irq(gc, pin); | ||
918 | } | ||
919 | |||
920 | static void intel_gpio_irq_ack(struct irq_data *d) | 890 | static void intel_gpio_irq_ack(struct irq_data *d) |
921 | { | 891 | { |
922 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 892 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
@@ -1132,8 +1102,6 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) | |||
1132 | 1102 | ||
1133 | static struct irq_chip intel_gpio_irqchip = { | 1103 | static struct irq_chip intel_gpio_irqchip = { |
1134 | .name = "intel-gpio", | 1104 | .name = "intel-gpio", |
1135 | .irq_request_resources = intel_gpio_irq_reqres, | ||
1136 | .irq_release_resources = intel_gpio_irq_relres, | ||
1137 | .irq_enable = intel_gpio_irq_enable, | 1105 | .irq_enable = intel_gpio_irq_enable, |
1138 | .irq_ack = intel_gpio_irq_ack, | 1106 | .irq_ack = intel_gpio_irq_ack, |
1139 | .irq_mask = intel_gpio_irq_mask, | 1107 | .irq_mask = intel_gpio_irq_mask, |
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 41ccc759b8b8..1425c2874d40 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c | |||
@@ -348,21 +348,12 @@ static void amd_gpio_irq_enable(struct irq_data *d) | |||
348 | unsigned long flags; | 348 | unsigned long flags; |
349 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 349 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
350 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); | 350 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); |
351 | u32 mask = BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF); | ||
352 | 351 | ||
353 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); | 352 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); |
354 | pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | 353 | pin_reg = readl(gpio_dev->base + (d->hwirq)*4); |
355 | pin_reg |= BIT(INTERRUPT_ENABLE_OFF); | 354 | pin_reg |= BIT(INTERRUPT_ENABLE_OFF); |
356 | pin_reg |= BIT(INTERRUPT_MASK_OFF); | 355 | pin_reg |= BIT(INTERRUPT_MASK_OFF); |
357 | writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | 356 | writel(pin_reg, gpio_dev->base + (d->hwirq)*4); |
358 | /* | ||
359 | * When debounce logic is enabled it takes ~900 us before interrupts | ||
360 | * can be enabled. During this "debounce warm up" period the | ||
361 | * "INTERRUPT_ENABLE" bit will read as 0. Poll the bit here until it | ||
362 | * reads back as 1, signaling that interrupts are now enabled. | ||
363 | */ | ||
364 | while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask) | ||
365 | continue; | ||
366 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); | 357 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); |
367 | } | 358 | } |
368 | 359 | ||
@@ -426,7 +417,7 @@ static void amd_gpio_irq_eoi(struct irq_data *d) | |||
426 | static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 417 | static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
427 | { | 418 | { |
428 | int ret = 0; | 419 | int ret = 0; |
429 | u32 pin_reg; | 420 | u32 pin_reg, pin_reg_irq_en, mask; |
430 | unsigned long flags, irq_flags; | 421 | unsigned long flags, irq_flags; |
431 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 422 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
432 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); | 423 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); |
@@ -495,6 +486,28 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
495 | } | 486 | } |
496 | 487 | ||
497 | pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF; | 488 | pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF; |
489 | /* | ||
490 | * If WAKE_INT_MASTER_REG.MaskStsEn is set, a software write to the | ||
491 | * debounce registers of any GPIO will block wake/interrupt status | ||
492 | * generation for *all* GPIOs for a lenght of time that depends on | ||
493 | * WAKE_INT_MASTER_REG.MaskStsLength[11:0]. During this period the | ||
494 | * INTERRUPT_ENABLE bit will read as 0. | ||
495 | * | ||
496 | * We temporarily enable irq for the GPIO whose configuration is | ||
497 | * changing, and then wait for it to read back as 1 to know when | ||
498 | * debounce has settled and then disable the irq again. | ||
499 | * We do this polling with the spinlock held to ensure other GPIO | ||
500 | * access routines do not read an incorrect value for the irq enable | ||
501 | * bit of other GPIOs. We keep the GPIO masked while polling to avoid | ||
502 | * spurious irqs, and disable the irq again after polling. | ||
503 | */ | ||
504 | mask = BIT(INTERRUPT_ENABLE_OFF); | ||
505 | pin_reg_irq_en = pin_reg; | ||
506 | pin_reg_irq_en |= mask; | ||
507 | pin_reg_irq_en &= ~BIT(INTERRUPT_MASK_OFF); | ||
508 | writel(pin_reg_irq_en, gpio_dev->base + (d->hwirq)*4); | ||
509 | while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask) | ||
510 | continue; | ||
498 | writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | 511 | writel(pin_reg, gpio_dev->base + (d->hwirq)*4); |
499 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); | 512 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); |
500 | 513 | ||