hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
....@@ -1,17 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 and
6
- * only version 2 as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
14
-#include <linux/gpio.h>
6
+#include <linux/gpio/driver.h>
7
+#include <linux/interrupt.h>
158 #include <linux/module.h>
169 #include <linux/of.h>
1710 #include <linux/of_irq.h>
....@@ -136,7 +129,6 @@
136129 /**
137130 * struct pmic_gpio_pad - keep current GPIO settings
138131 * @base: Address base in SPMI device.
139
- * @irq: IRQ number which this GPIO generate.
140132 * @is_enabled: Set to false when GPIO should be put in high Z state.
141133 * @out_value: Cached pin output value
142134 * @have_buffer: Set to true if GPIO output could be configured in push-pull,
....@@ -156,7 +148,6 @@
156148 */
157149 struct pmic_gpio_pad {
158150 u16 base;
159
- int irq;
160151 bool is_enabled;
161152 bool out_value;
162153 bool have_buffer;
....@@ -179,6 +170,7 @@
179170 struct regmap *map;
180171 struct pinctrl_dev *ctrl;
181172 struct gpio_chip chip;
173
+ struct irq_chip irq;
182174 };
183175
184176 static const struct pinconf_generic_params pmic_gpio_bindings[] = {
....@@ -674,11 +666,11 @@
674666 else
675667 seq_printf(s, " %-4s",
676668 pad->output_enabled ? "out" : "in");
669
+ seq_printf(s, " %-4s", pad->out_value ? "high" : "low");
677670 seq_printf(s, " %-7s", pmic_gpio_functions[function]);
678671 seq_printf(s, " vin-%d", pad->power_source);
679672 seq_printf(s, " %-27s", biases[pad->pullup]);
680673 seq_printf(s, " %-10s", buffer_types[pad->buffer_type]);
681
- seq_printf(s, " %-4s", pad->out_value ? "high" : "low");
682674 seq_printf(s, " %-7s", strengths[pad->strength]);
683675 seq_printf(s, " atest-%d", pad->atest);
684676 seq_printf(s, " dtest-%d", pad->dtest_buffer);
....@@ -758,16 +750,6 @@
758750 return gpio_desc->args[0] - PMIC_GPIO_PHYSICAL_OFFSET;
759751 }
760752
761
-static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
762
-{
763
- struct pmic_gpio_state *state = gpiochip_get_data(chip);
764
- struct pmic_gpio_pad *pad;
765
-
766
- pad = state->ctrl->desc->pins[pin].drv_data;
767
-
768
- return pad->irq;
769
-}
770
-
771753 static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
772754 {
773755 struct pmic_gpio_state *state = gpiochip_get_data(chip);
....@@ -787,7 +769,6 @@
787769 .request = gpiochip_generic_request,
788770 .free = gpiochip_generic_free,
789771 .of_xlate = pmic_gpio_of_xlate,
790
- .to_irq = pmic_gpio_to_irq,
791772 .dbg_show = pmic_gpio_dbg_show,
792773 };
793774
....@@ -813,11 +794,13 @@
813794 switch (subtype) {
814795 case PMIC_GPIO_SUBTYPE_GPIO_4CH:
815796 pad->have_buffer = true;
797
+ fallthrough;
816798 case PMIC_GPIO_SUBTYPE_GPIOC_4CH:
817799 pad->num_sources = 4;
818800 break;
819801 case PMIC_GPIO_SUBTYPE_GPIO_8CH:
820802 pad->have_buffer = true;
803
+ fallthrough;
821804 case PMIC_GPIO_SUBTYPE_GPIOC_8CH:
822805 pad->num_sources = 8;
823806 break;
....@@ -935,13 +918,53 @@
935918 return 0;
936919 }
937920
921
+static int pmic_gpio_domain_translate(struct irq_domain *domain,
922
+ struct irq_fwspec *fwspec,
923
+ unsigned long *hwirq,
924
+ unsigned int *type)
925
+{
926
+ struct pmic_gpio_state *state = container_of(domain->host_data,
927
+ struct pmic_gpio_state,
928
+ chip);
929
+
930
+ if (fwspec->param_count != 2 ||
931
+ fwspec->param[0] < 1 || fwspec->param[0] > state->chip.ngpio)
932
+ return -EINVAL;
933
+
934
+ *hwirq = fwspec->param[0] - PMIC_GPIO_PHYSICAL_OFFSET;
935
+ *type = fwspec->param[1];
936
+
937
+ return 0;
938
+}
939
+
940
+static unsigned int pmic_gpio_child_offset_to_irq(struct gpio_chip *chip,
941
+ unsigned int offset)
942
+{
943
+ return offset + PMIC_GPIO_PHYSICAL_OFFSET;
944
+}
945
+
946
+static int pmic_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
947
+ unsigned int child_hwirq,
948
+ unsigned int child_type,
949
+ unsigned int *parent_hwirq,
950
+ unsigned int *parent_type)
951
+{
952
+ *parent_hwirq = child_hwirq + 0xc0;
953
+ *parent_type = child_type;
954
+
955
+ return 0;
956
+}
957
+
938958 static int pmic_gpio_probe(struct platform_device *pdev)
939959 {
960
+ struct irq_domain *parent_domain;
961
+ struct device_node *parent_node;
940962 struct device *dev = &pdev->dev;
941963 struct pinctrl_pin_desc *pindesc;
942964 struct pinctrl_desc *pctrldesc;
943965 struct pmic_gpio_pad *pad, *pads;
944966 struct pmic_gpio_state *state;
967
+ struct gpio_irq_chip *girq;
945968 int ret, npins, i;
946969 u32 reg;
947970
....@@ -951,13 +974,7 @@
951974 return ret;
952975 }
953976
954
- npins = platform_irq_count(pdev);
955
- if (!npins)
956
- return -EINVAL;
957
- if (npins < 0)
958
- return npins;
959
-
960
- BUG_ON(npins > ARRAY_SIZE(pmic_gpio_groups));
977
+ npins = (uintptr_t) device_get_match_data(&pdev->dev);
961978
962979 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
963980 if (!state)
....@@ -999,10 +1016,6 @@
9991016 pindesc->number = i;
10001017 pindesc->name = pmic_gpio_groups[i];
10011018
1002
- pad->irq = platform_get_irq(pdev, i);
1003
- if (pad->irq < 0)
1004
- return pad->irq;
1005
-
10061019 pad->base = reg + i * PMIC_GPIO_ADDRESS_RANGE;
10071020
10081021 ret = pmic_gpio_populate(state, pad);
....@@ -1021,6 +1034,34 @@
10211034 state->ctrl = devm_pinctrl_register(dev, pctrldesc, state);
10221035 if (IS_ERR(state->ctrl))
10231036 return PTR_ERR(state->ctrl);
1037
+
1038
+ parent_node = of_irq_find_parent(state->dev->of_node);
1039
+ if (!parent_node)
1040
+ return -ENXIO;
1041
+
1042
+ parent_domain = irq_find_host(parent_node);
1043
+ of_node_put(parent_node);
1044
+ if (!parent_domain)
1045
+ return -ENXIO;
1046
+
1047
+ state->irq.name = "spmi-gpio",
1048
+ state->irq.irq_ack = irq_chip_ack_parent,
1049
+ state->irq.irq_mask = irq_chip_mask_parent,
1050
+ state->irq.irq_unmask = irq_chip_unmask_parent,
1051
+ state->irq.irq_set_type = irq_chip_set_type_parent,
1052
+ state->irq.irq_set_wake = irq_chip_set_wake_parent,
1053
+ state->irq.flags = IRQCHIP_MASK_ON_SUSPEND,
1054
+
1055
+ girq = &state->chip.irq;
1056
+ girq->chip = &state->irq;
1057
+ girq->default_type = IRQ_TYPE_NONE;
1058
+ girq->handler = handle_level_irq;
1059
+ girq->fwnode = of_node_to_fwnode(state->dev->of_node);
1060
+ girq->parent_domain = parent_domain;
1061
+ girq->child_to_parent_hwirq = pmic_gpio_child_to_parent_hwirq;
1062
+ girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
1063
+ girq->child_offset_to_irq = pmic_gpio_child_offset_to_irq;
1064
+ girq->child_irq_domain_ops.translate = pmic_gpio_domain_translate;
10241065
10251066 ret = gpiochip_add_data(&state->chip, state);
10261067 if (ret) {
....@@ -1063,12 +1104,31 @@
10631104 }
10641105
10651106 static const struct of_device_id pmic_gpio_of_match[] = {
1066
- { .compatible = "qcom,pm8916-gpio" }, /* 4 GPIO's */
1067
- { .compatible = "qcom,pm8941-gpio" }, /* 36 GPIO's */
1068
- { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
1069
- { .compatible = "qcom,pmi8994-gpio" }, /* 10 GPIO's */
1070
- { .compatible = "qcom,pma8084-gpio" }, /* 22 GPIO's */
1071
- { .compatible = "qcom,spmi-gpio" }, /* Generic */
1107
+ { .compatible = "qcom,pm8005-gpio", .data = (void *) 4 },
1108
+ { .compatible = "qcom,pm8916-gpio", .data = (void *) 4 },
1109
+ { .compatible = "qcom,pm8941-gpio", .data = (void *) 36 },
1110
+ /* pm8950 has 8 GPIOs with holes on 3 */
1111
+ { .compatible = "qcom,pm8950-gpio", .data = (void *) 8 },
1112
+ { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 },
1113
+ { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 },
1114
+ { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 },
1115
+ { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 },
1116
+ { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 },
1117
+ { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 },
1118
+ /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */
1119
+ { .compatible = "qcom,pms405-gpio", .data = (void *) 12 },
1120
+ /* pm660 has 13 GPIOs with holes on 1, 5, 6, 7, 8 and 10 */
1121
+ { .compatible = "qcom,pm660-gpio", .data = (void *) 13 },
1122
+ /* pm660l has 12 GPIOs with holes on 1, 2, 10, 11 and 12 */
1123
+ { .compatible = "qcom,pm660l-gpio", .data = (void *) 12 },
1124
+ /* pm8150 has 10 GPIOs with holes on 2, 5, 7 and 8 */
1125
+ { .compatible = "qcom,pm8150-gpio", .data = (void *) 10 },
1126
+ /* pm8150b has 12 GPIOs with holes on 3, r and 7 */
1127
+ { .compatible = "qcom,pm8150b-gpio", .data = (void *) 12 },
1128
+ /* pm8150l has 12 GPIOs with holes on 7 */
1129
+ { .compatible = "qcom,pm8150l-gpio", .data = (void *) 12 },
1130
+ { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 },
1131
+ { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 },
10721132 { },
10731133 };
10741134