History

pinctrl/msm: Setup GPIO chip in hierarchy

Some GPIOs are marked as wakeup capable and are routed to another interrupt controller that is an always-domain and can detect interrupts even when most of the SoC is powered off. The wakeup interrupt controller wakes up the GIC and replays the interrupt at the GIC. Setup the TLMM irqchip in hierarchy with the wakeup interrupt controller and ensure the wakeup GPIOs are handled correctly. Co-developed-by: Maulik Shah <mkshah@codeaurora.org> Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/1573855915-9841-9-git-send-email-ilina@codeaurora.org ---- Changes in v2: - Address review comments - Fix Co-developed-by tag Changes in v1: - Address minor review comments - Remove redundant call to set irq handler - Move irq_domain_qcom_handle_wakeup() to this patch Changes in RFC v2: - Rebase on top of GPIO hierarchy support in linux-next - Set the chained irq handler for summary line

Lina Iyer committed 7 years ago

Commit e35a6ae1 parent e71374c3 files · +137 −2Browse files

Unified · Split

3 files
  1. drivers/pinctrl/qcom/pinctrl-msm.c +110 −2
  2. drivers/pinctrl/qcom/pinctrl-msm.h +14 −0
  3. include/linux/soc/qcom/irq.h +13 −0
drivers/pinctrl/qcom/pinctrl-msm.c+110−2
@@ -23,6 +23,8 @@ · 22 unmodified lines
2323 #include <linux/pm.h>
2424 #include <linux/log2.h>
2525
26+#include <linux/soc/qcom/irq.h>
27+
2628 #include "../core.h"
2729 #include "../pinconf.h"
2830 #include "pinctrl-msm.h"
@@ -44,6 +46,7 @@ · 15 unmodified lines
4446 * @enabled_irqs: Bitmap of currently enabled irqs.
4547 * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
4648 * detection.
49+ * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
4750 * @soc; Reference to soc_data of platform specific data.
4851 * @regs: Base addresses for the TLMM tiles.
4952 */
@@ -61,6 +64,7 @@ struct msm_pinctrl { · 11 unmodified lines
6164
6265 DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
6366 DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
67+ DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
6468
6569 const struct msm_pinctrl_soc_data *soc;
6670 void __iomem *regs[MAX_NR_TILES];
@@ -707,6 +711,12 @@ static void msm_gpio_irq_mask(struct irq_data *d) · 640 unmodified lines
707711 unsigned long flags;
708712 u32 val;
709713
714+ if (d->parent_data)
715+ irq_chip_mask_parent(d);
716+
717+ if (test_bit(d->hwirq, pctrl->skip_wake_irqs))
718+ return;
719+
710720 g = &pctrl->soc->groups[d->hwirq];
711721
712722 raw_spin_lock_irqsave(&pctrl->lock, flags);
@@ -751,6 +761,12 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) · 38 unmodified lines
751761 unsigned long flags;
752762 u32 val;
753763
764+ if (d->parent_data)
765+ irq_chip_unmask_parent(d);
766+
767+ if (test_bit(d->hwirq, pctrl->skip_wake_irqs))
768+ return;
769+
754770 g = &pctrl->soc->groups[d->hwirq];
755771
756772 raw_spin_lock_irqsave(&pctrl->lock, flags);
@@ -778,10 +794,35 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) · 21 unmodified lines
778794
779795 static void msm_gpio_irq_enable(struct irq_data *d)
780796 {
797+ /*
798+ * Clear the interrupt that may be pending before we enable
799+ * the line.
800+ * This is especially a problem with the GPIOs routed to the
801+ * PDC. These GPIOs are direct-connect interrupts to the GIC.
802+ * Disabling the interrupt line at the PDC does not prevent
803+ * the interrupt from being latched at the GIC. The state at
804+ * GIC needs to be cleared before enabling.
805+ */
806+ if (d->parent_data) {
807+ irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0);
808+ irq_chip_enable_parent(d);
809+ }
781810
782811 msm_gpio_irq_clear_unmask(d, true);
783812 }
784813
814+static void msm_gpio_irq_disable(struct irq_data *d)
815+{
816+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
817+ struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
818+
819+ if (d->parent_data)
820+ irq_chip_disable_parent(d);
821+
822+ if (!test_bit(d->hwirq, pctrl->skip_wake_irqs))
823+ msm_gpio_irq_mask(d);
824+}
825+
785826 static void msm_gpio_irq_unmask(struct irq_data *d)
786827 {
787828 msm_gpio_irq_clear_unmask(d, false);
@@ -795,6 +836,9 @@ static void msm_gpio_irq_ack(struct irq_data *d) · 7 unmodified lines
795836 unsigned long flags;
796837 u32 val;
797838
839+ if (test_bit(d->hwirq, pctrl->skip_wake_irqs))
840+ return;
841+
798842 g = &pctrl->soc->groups[d->hwirq];
799843
800844 raw_spin_lock_irqsave(&pctrl->lock, flags);
@@ -820,6 +864,12 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) · 19 unmodified lines
820864 unsigned long flags;
821865 u32 val;
822866
867+ if (d->parent_data)
868+ irq_chip_set_type_parent(d, type);
869+
870+ if (test_bit(d->hwirq, pctrl->skip_wake_irqs))
871+ return 0;
872+
823873 g = &pctrl->soc->groups[d->hwirq];
824874
825875 raw_spin_lock_irqsave(&pctrl->lock, flags);
@@ -912,6 +962,15 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) · 86 unmodified lines
912962 struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
913963 unsigned long flags;
914964
965+ /*
966+ * While they may not wake up when the TLMM is powered off,
967+ * some GPIOs would like to wakeup the system from suspend
968+ * when TLMM is powered on. To allow that, enable the GPIO
969+ * summary line to be wakeup capable at GIC.
970+ */
971+ if (d->parent_data)
972+ irq_chip_set_wake_parent(d, on);
973+
915974 raw_spin_lock_irqsave(&pctrl->lock, flags);
916975
917976 irq_set_irq_wake(pctrl->irq, on);
@@ -990,6 +1049,30 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) · 72 unmodified lines
9901049 chained_irq_exit(chip, desc);
9911050 }
9921051
1052+static int msm_gpio_wakeirq(struct gpio_chip *gc,
1053+ unsigned int child,
1054+ unsigned int child_type,
1055+ unsigned int *parent,
1056+ unsigned int *parent_type)
1057+{
1058+ struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
1059+ const struct msm_gpio_wakeirq_map *map;
1060+ int i;
1061+
1062+ *parent = GPIO_NO_WAKE_IRQ;
1063+ *parent_type = IRQ_TYPE_EDGE_RISING;
1064+
1065+ for (i = 0; i < pctrl->soc->nwakeirq_map; i++) {
1066+ map = &pctrl->soc->wakeirq_map[i];
1067+ if (map->gpio == child) {
1068+ *parent = map->wakeirq;
1069+ break;
1070+ }
1071+ }
1072+
1073+ return 0;
1074+}
1075+
9931076 static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
9941077 {
9951078 if (pctrl->soc->reserved_gpios)
@@ -1002,8 +1085,10 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 6 unmodified lines
10021085 {
10031086 struct gpio_chip *chip;
10041087 struct gpio_irq_chip *girq;
1005− int ret;
1006− unsigned ngpio = pctrl->soc->ngpios;
1088+ int i, ret;
1089+ unsigned gpio, ngpio = pctrl->soc->ngpios;
1090+ struct device_node *np;
1091+ bool skip;
10071092
10081093 if (WARN_ON(ngpio > MAX_NR_GPIO))
10091094 return -EINVAL;
@@ -1020,17 +1105,40 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 10 unmodified lines
10201105
10211106 pctrl->irq_chip.name = "msmgpio";
10221107 pctrl->irq_chip.irq_enable = msm_gpio_irq_enable;
1108+ pctrl->irq_chip.irq_disable = msm_gpio_irq_disable;
10231109 pctrl->irq_chip.irq_mask = msm_gpio_irq_mask;
10241110 pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask;
10251111 pctrl->irq_chip.irq_ack = msm_gpio_irq_ack;
1112+ pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent;
10261113 pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type;
10271114 pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake;
10281115 pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres;
10291116 pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres;
10301117
1118+ np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0);
1119+ if (np) {
1120+ chip->irq.parent_domain = irq_find_matching_host(np,
1121+ DOMAIN_BUS_WAKEUP);
1122+ of_node_put(np);
1123+ if (!chip->irq.parent_domain)
1124+ return -EPROBE_DEFER;
1125+ chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq;
1126+
1127+ /*
1128+ * Let's skip handling the GPIOs, if the parent irqchip
1129+ * is handling the direct connect IRQ of the GPIO.
1130+ */
1131+ skip = irq_domain_qcom_handle_wakeup(chip->irq.parent_domain);
1132+ for (i = 0; skip && i < pctrl->soc->nwakeirq_map; i++) {
1133+ gpio = pctrl->soc->wakeirq_map[i].gpio;
1134+ set_bit(gpio, pctrl->skip_wake_irqs);
1135+ }
1136+ }
1137+
10311138 girq = &chip->irq;
10321139 girq->chip = &pctrl->irq_chip;
10331140 girq->parent_handler = msm_gpio_irq_handler;
1141+ girq->fwnode = pctrl->dev->fwnode;
10341142 girq->num_parents = 1;
10351143 girq->parents = devm_kcalloc(pctrl->dev, 1, sizeof(*girq->parents),
10361144 GFP_KERNEL);
drivers/pinctrl/qcom/pinctrl-msm.h+14−0
@@ -91,6 +91,16 @@ struct msm_pingroup { · 90 unmodified lines
9191 unsigned intr_detection_width:5;
9292 };
9393
94+/**
95+ * struct msm_gpio_wakeirq_map - Map of GPIOs and their wakeup pins
96+ * @gpio: The GPIOs that are wakeup capable
97+ * @wakeirq: The interrupt at the always-on interrupt controller
98+ */
99+struct msm_gpio_wakeirq_map {
100+ unsigned int gpio;
101+ unsigned int wakeirq;
102+};
103+
94104 /**
95105 * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration
96106 * @pins: An array describing all pins the pin controller affects.
@@ -101,6 +111,8 @@ struct msm_pingroup { · 4 unmodified lines
101111 * @ngroups: The numbmer of entries in @groups.
102112 * @ngpio: The number of pingroups the driver should expose as GPIOs.
103113 * @pull_no_keeper: The SoC does not support keeper bias.
114+ * @wakeirq_map: The map of wakeup capable GPIOs and the pin at PDC/MPM
115+ * @nwakeirq_map: The number of entries in @wakeirq_map
104116 */
105117 struct msm_pinctrl_soc_data {
106118 const struct pinctrl_pin_desc *pins;
@@ -114,6 +126,8 @@ struct msm_pinctrl_soc_data { · 7 unmodified lines
114126 const char *const *tiles;
115127 unsigned int ntiles;
116128 const int *reserved_gpios;
129+ const struct msm_gpio_wakeirq_map *wakeirq_map;
130+ unsigned int nwakeirq_map;
117131 };
118132
119133 extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;
include/linux/soc/qcom/irq.h+13−0
@@ -18,4 +18,17 @@ · 17 unmodified lines
1818 #define IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP (IRQ_DOMAIN_FLAG_NONCORE << 0)
1919 #define IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP (IRQ_DOMAIN_FLAG_NONCORE << 1)
2020
21+/**
22+ * irq_domain_qcom_handle_wakeup: Return if the domain handles interrupt
23+ * configuration
24+ * @d: irq domain
25+ *
26+ * This QCOM specific irq domain call returns if the interrupt controller
27+ * requires the interrupt be masked at the child interrupt controller.
28+ */
29+static inline bool irq_domain_qcom_handle_wakeup(const struct irq_domain *d)
30+{
31+ return (d->flags & IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP);
32+}
33+
2134 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t