Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'pinctrl-v5.8-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fix from Linus Walleij:
"A single last minute pin control fix to the Qualcomm driver fixing
missing dual edge PCH interrupts"

* tag 'pinctrl-v5.8-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
pinctrl: qcom: Handle broken/missing PDC dual edge IRQs on sc7180

+79 -2
+2
drivers/pinctrl/qcom/Kconfig
··· 7 7 select PINCONF 8 8 select GENERIC_PINCONF 9 9 select GPIOLIB_IRQCHIP 10 + select IRQ_DOMAIN_HIERARCHY 11 + select IRQ_FASTEOI_HIERARCHY_HANDLERS 10 12 11 13 config PINCTRL_APQ8064 12 14 tristate "Qualcomm APQ8064 pin controller driver"
+72 -2
drivers/pinctrl/qcom/pinctrl-msm.c
··· 832 832 msm_gpio_irq_clear_unmask(d, false); 833 833 } 834 834 835 + /** 836 + * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent. 837 + * @d: The irq dta. 838 + * 839 + * This is much like msm_gpio_update_dual_edge_pos() but for IRQs that are 840 + * normally handled by the parent irqchip. The logic here is slightly 841 + * different due to what's easy to do with our parent, but in principle it's 842 + * the same. 843 + */ 844 + static void msm_gpio_update_dual_edge_parent(struct irq_data *d) 845 + { 846 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 847 + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); 848 + const struct msm_pingroup *g = &pctrl->soc->groups[d->hwirq]; 849 + int loop_limit = 100; 850 + unsigned int val; 851 + unsigned int type; 852 + 853 + /* Read the value and make a guess about what edge we need to catch */ 854 + val = msm_readl_io(pctrl, g) & BIT(g->in_bit); 855 + type = val ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; 856 + 857 + do { 858 + /* Set the parent to catch the next edge */ 859 + irq_chip_set_type_parent(d, type); 860 + 861 + /* 862 + * Possibly the line changed between when we last read "val" 863 + * (and decided what edge we needed) and when set the edge. 864 + * If the value didn't change (or changed and then changed 865 + * back) then we're done. 866 + */ 867 + val = msm_readl_io(pctrl, g) & BIT(g->in_bit); 868 + if (type == IRQ_TYPE_EDGE_RISING) { 869 + if (!val) 870 + return; 871 + type = IRQ_TYPE_EDGE_FALLING; 872 + } else if (type == IRQ_TYPE_EDGE_FALLING) { 873 + if (val) 874 + return; 875 + type = IRQ_TYPE_EDGE_RISING; 876 + } 877 + } while (loop_limit-- > 0); 878 + dev_warn_once(pctrl->dev, "dual-edge irq failed to stabilize\n"); 879 + } 880 + 835 881 static void msm_gpio_irq_ack(struct irq_data *d) 836 882 { 837 883 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); ··· 886 840 unsigned long flags; 887 841 u32 val; 888 842 889 - if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) 843 + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { 844 + if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) 845 + msm_gpio_update_dual_edge_parent(d); 890 846 return; 847 + } 891 848 892 849 g = &pctrl->soc->groups[d->hwirq]; 893 850 ··· 909 860 raw_spin_unlock_irqrestore(&pctrl->lock, flags); 910 861 } 911 862 863 + static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d, 864 + unsigned int type) 865 + { 866 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 867 + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); 868 + 869 + return type == IRQ_TYPE_EDGE_BOTH && 870 + pctrl->soc->wakeirq_dual_edge_errata && d->parent_data && 871 + test_bit(d->hwirq, pctrl->skip_wake_irqs); 872 + } 873 + 912 874 static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) 913 875 { 914 876 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); ··· 928 868 unsigned long flags; 929 869 u32 val; 930 870 871 + if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) { 872 + set_bit(d->hwirq, pctrl->dual_edge_irqs); 873 + irq_set_handler_locked(d, handle_fasteoi_ack_irq); 874 + msm_gpio_update_dual_edge_parent(d); 875 + return 0; 876 + } 877 + 931 878 if (d->parent_data) 932 879 irq_chip_set_type_parent(d, type); 933 880 934 - if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) 881 + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { 882 + clear_bit(d->hwirq, pctrl->dual_edge_irqs); 883 + irq_set_handler_locked(d, handle_fasteoi_irq); 935 884 return 0; 885 + } 936 886 937 887 g = &pctrl->soc->groups[d->hwirq]; 938 888
+4
drivers/pinctrl/qcom/pinctrl-msm.h
··· 113 113 * @pull_no_keeper: The SoC does not support keeper bias. 114 114 * @wakeirq_map: The map of wakeup capable GPIOs and the pin at PDC/MPM 115 115 * @nwakeirq_map: The number of entries in @wakeirq_map 116 + * @wakeirq_dual_edge_errata: If true then GPIOs using the wakeirq_map need 117 + * to be aware that their parent can't handle dual 118 + * edge interrupts. 116 119 */ 117 120 struct msm_pinctrl_soc_data { 118 121 const struct pinctrl_pin_desc *pins; ··· 131 128 const int *reserved_gpios; 132 129 const struct msm_gpio_wakeirq_map *wakeirq_map; 133 130 unsigned int nwakeirq_map; 131 + bool wakeirq_dual_edge_errata; 134 132 }; 135 133 136 134 extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;
+1
drivers/pinctrl/qcom/pinctrl-sc7180.c
··· 1147 1147 .ntiles = ARRAY_SIZE(sc7180_tiles), 1148 1148 .wakeirq_map = sc7180_pdc_map, 1149 1149 .nwakeirq_map = ARRAY_SIZE(sc7180_pdc_map), 1150 + .wakeirq_dual_edge_errata = true, 1150 1151 }; 1151 1152 1152 1153 static int sc7180_pinctrl_probe(struct platform_device *pdev)