summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/stm32
diff options
context:
space:
mode:
authorAlexandre TORGUE <alexandre.torgue@st.com>2016-09-09 10:42:01 -0400
committerLinus Walleij <linus.walleij@linaro.org>2016-09-13 04:13:01 -0400
commit0eb9f683336d7eb99a3b75987620417c574ffb57 (patch)
treeca0b8af2ce94f49d0a34e7eb0d7896f305674a9a /drivers/pinctrl/stm32
parent23fb16194b95089b3cf5eb88d446662ee7da0f43 (diff)
pinctrl: Add IRQ support to STM32 gpios
This patch adds IRQ support to STM32 gpios. The EXTI controller has 16 lines dedicated to GPIOs. EXTI line n can be connected to only line n of one of the GPIO ports, for example EXTI0 can be connected to either PA0, or PB0, or PC0... This port selection is done by specifying the port number into System Config registers. Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/stm32')
-rw-r--r--drivers/pinctrl/stm32/Kconfig1
-rw-r--r--drivers/pinctrl/stm32/pinctrl-stm32.c163
2 files changed, 163 insertions, 1 deletions
diff --git a/drivers/pinctrl/stm32/Kconfig b/drivers/pinctrl/stm32/Kconfig
index 4c40dae384d1..24bc68308af2 100644
--- a/drivers/pinctrl/stm32/Kconfig
+++ b/drivers/pinctrl/stm32/Kconfig
@@ -6,6 +6,7 @@ config PINCTRL_STM32
6 select PINMUX 6 select PINMUX
7 select GENERIC_PINCONF 7 select GENERIC_PINCONF
8 select GPIOLIB 8 select GPIOLIB
9 select MFD_SYSCON
9 10
10config PINCTRL_STM32F429 11config PINCTRL_STM32F429
11 bool "STMicroelectronics STM32F429 pin control" if COMPILE_TEST && !MACH_STM32F429 12 bool "STMicroelectronics STM32F429 pin control" if COMPILE_TEST && !MACH_STM32F429
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 4ae596bf19b5..4f01025a0941 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -8,6 +8,8 @@
8#include <linux/clk.h> 8#include <linux/clk.h>
9#include <linux/gpio/driver.h> 9#include <linux/gpio/driver.h>
10#include <linux/io.h> 10#include <linux/io.h>
11#include <linux/irq.h>
12#include <linux/mfd/syscon.h>
11#include <linux/module.h> 13#include <linux/module.h>
12#include <linux/of.h> 14#include <linux/of.h>
13#include <linux/of_address.h> 15#include <linux/of_address.h>
@@ -20,6 +22,7 @@
20#include <linux/pinctrl/pinctrl.h> 22#include <linux/pinctrl/pinctrl.h>
21#include <linux/pinctrl/pinmux.h> 23#include <linux/pinctrl/pinmux.h>
22#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/regmap.h>
23#include <linux/reset.h> 26#include <linux/reset.h>
24#include <linux/slab.h> 27#include <linux/slab.h>
25 28
@@ -40,6 +43,7 @@
40#define STM32_GPIO_AFRH 0x24 43#define STM32_GPIO_AFRH 0x24
41 44
42#define STM32_GPIO_PINS_PER_BANK 16 45#define STM32_GPIO_PINS_PER_BANK 16
46#define STM32_GPIO_IRQ_LINE 16
43 47
44#define gpio_range_to_bank(chip) \ 48#define gpio_range_to_bank(chip) \
45 container_of(chip, struct stm32_gpio_bank, range) 49 container_of(chip, struct stm32_gpio_bank, range)
@@ -65,6 +69,8 @@ struct stm32_gpio_bank {
65 spinlock_t lock; 69 spinlock_t lock;
66 struct gpio_chip gpio_chip; 70 struct gpio_chip gpio_chip;
67 struct pinctrl_gpio_range range; 71 struct pinctrl_gpio_range range;
72 struct fwnode_handle *fwnode;
73 struct irq_domain *domain;
68}; 74};
69 75
70struct stm32_pinctrl { 76struct stm32_pinctrl {
@@ -77,6 +83,9 @@ struct stm32_pinctrl {
77 struct stm32_gpio_bank *banks; 83 struct stm32_gpio_bank *banks;
78 unsigned nbanks; 84 unsigned nbanks;
79 const struct stm32_pinctrl_match_data *match_data; 85 const struct stm32_pinctrl_match_data *match_data;
86 struct irq_domain *domain;
87 struct regmap *regmap;
88 struct regmap_field *irqmux[STM32_GPIO_PINS_PER_BANK];
80}; 89};
81 90
82static inline int stm32_gpio_pin(int gpio) 91static inline int stm32_gpio_pin(int gpio)
@@ -174,6 +183,20 @@ static int stm32_gpio_direction_output(struct gpio_chip *chip,
174 return 0; 183 return 0;
175} 184}
176 185
186
187static int stm32_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
188{
189 struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
190 struct irq_fwspec fwspec;
191
192 fwspec.fwnode = bank->fwnode;
193 fwspec.param_count = 2;
194 fwspec.param[0] = offset;
195 fwspec.param[1] = IRQ_TYPE_NONE;
196
197 return irq_create_fwspec_mapping(&fwspec);
198}
199
177static struct gpio_chip stm32_gpio_template = { 200static struct gpio_chip stm32_gpio_template = {
178 .request = stm32_gpio_request, 201 .request = stm32_gpio_request,
179 .free = stm32_gpio_free, 202 .free = stm32_gpio_free,
@@ -181,10 +204,92 @@ static struct gpio_chip stm32_gpio_template = {
181 .set = stm32_gpio_set, 204 .set = stm32_gpio_set,
182 .direction_input = stm32_gpio_direction_input, 205 .direction_input = stm32_gpio_direction_input,
183 .direction_output = stm32_gpio_direction_output, 206 .direction_output = stm32_gpio_direction_output,
207 .to_irq = stm32_gpio_to_irq,
184}; 208};
185 209
186/* Pinctrl functions */ 210static struct irq_chip stm32_gpio_irq_chip = {
211 .name = "stm32gpio",
212 .irq_eoi = irq_chip_eoi_parent,
213 .irq_mask = irq_chip_mask_parent,
214 .irq_unmask = irq_chip_unmask_parent,
215 .irq_set_type = irq_chip_set_type_parent,
216};
217
218static int stm32_gpio_domain_translate(struct irq_domain *d,
219 struct irq_fwspec *fwspec,
220 unsigned long *hwirq,
221 unsigned int *type)
222{
223 if ((fwspec->param_count != 2) ||
224 (fwspec->param[0] >= STM32_GPIO_IRQ_LINE))
225 return -EINVAL;
226
227 *hwirq = fwspec->param[0];
228 *type = fwspec->param[1];
229 return 0;
230}
187 231
232static void stm32_gpio_domain_activate(struct irq_domain *d,
233 struct irq_data *irq_data)
234{
235 struct stm32_gpio_bank *bank = d->host_data;
236 struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
237
238 regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->range.id);
239}
240
241static int stm32_gpio_domain_alloc(struct irq_domain *d,
242 unsigned int virq,
243 unsigned int nr_irqs, void *data)
244{
245 struct stm32_gpio_bank *bank = d->host_data;
246 struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
247 struct irq_fwspec *fwspec = data;
248 struct irq_fwspec parent_fwspec;
249 irq_hw_number_t hwirq;
250 int ret;
251
252 hwirq = fwspec->param[0];
253 parent_fwspec.fwnode = d->parent->fwnode;
254 parent_fwspec.param_count = 2;
255 parent_fwspec.param[0] = fwspec->param[0];
256 parent_fwspec.param[1] = fwspec->param[1];
257
258 irq_domain_set_hwirq_and_chip(d, virq, hwirq, &stm32_gpio_irq_chip,
259 bank);
260
261 ret = gpiochip_lock_as_irq(&bank->gpio_chip, hwirq);
262 if (ret) {
263 dev_err(pctl->dev, "Unable to configure STM32 %s%ld as IRQ\n",
264 bank->gpio_chip.label, hwirq);
265 return ret;
266 }
267
268 ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &parent_fwspec);
269 if (ret)
270 gpiochip_unlock_as_irq(&bank->gpio_chip, hwirq);
271
272 return ret;
273}
274
275static void stm32_gpio_domain_free(struct irq_domain *d, unsigned int virq,
276 unsigned int nr_irqs)
277{
278 struct stm32_gpio_bank *bank = d->host_data;
279 struct irq_data *data = irq_get_irq_data(virq);
280
281 irq_domain_free_irqs_common(d, virq, nr_irqs);
282 gpiochip_unlock_as_irq(&bank->gpio_chip, data->hwirq);
283}
284
285static const struct irq_domain_ops stm32_gpio_domain_ops = {
286 .translate = stm32_gpio_domain_translate,
287 .alloc = stm32_gpio_domain_alloc,
288 .free = stm32_gpio_domain_free,
289 .activate = stm32_gpio_domain_activate,
290};
291
292/* Pinctrl functions */
188static struct stm32_pinctrl_group * 293static struct stm32_pinctrl_group *
189stm32_pctrl_find_group_by_pin(struct stm32_pinctrl *pctl, u32 pin) 294stm32_pctrl_find_group_by_pin(struct stm32_pinctrl *pctl, u32 pin)
190{ 295{
@@ -857,6 +962,17 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
857 range->pin_base = range->base = range->id * STM32_GPIO_PINS_PER_BANK; 962 range->pin_base = range->base = range->id * STM32_GPIO_PINS_PER_BANK;
858 range->npins = bank->gpio_chip.ngpio; 963 range->npins = bank->gpio_chip.ngpio;
859 range->gc = &bank->gpio_chip; 964 range->gc = &bank->gpio_chip;
965
966 /* create irq hierarchical domain */
967 bank->fwnode = of_node_to_fwnode(np);
968
969 bank->domain = irq_domain_create_hierarchy(pctl->domain, 0,
970 STM32_GPIO_IRQ_LINE, bank->fwnode,
971 &stm32_gpio_domain_ops, bank);
972
973 if (!bank->domain)
974 return -ENODEV;
975
860 err = gpiochip_add_data(&bank->gpio_chip, bank); 976 err = gpiochip_add_data(&bank->gpio_chip, bank);
861 if (err) { 977 if (err) {
862 dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr); 978 dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr);
@@ -867,6 +983,47 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
867 return 0; 983 return 0;
868} 984}
869 985
986static int stm32_pctrl_dt_setup_irq(struct platform_device *pdev,
987 struct stm32_pinctrl *pctl)
988{
989 struct device_node *np = pdev->dev.of_node, *parent;
990 struct device *dev = &pdev->dev;
991 struct regmap *rm;
992 int offset, ret, i;
993
994 parent = of_irq_find_parent(np);
995 if (!parent)
996 return -ENXIO;
997
998 pctl->domain = irq_find_host(parent);
999 if (!pctl->domain)
1000 return -ENXIO;
1001
1002 pctl->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
1003 if (IS_ERR(pctl->regmap))
1004 return PTR_ERR(pctl->regmap);
1005
1006 rm = pctl->regmap;
1007
1008 ret = of_property_read_u32_index(np, "st,syscfg", 1, &offset);
1009 if (ret)
1010 return ret;
1011
1012 for (i = 0; i < STM32_GPIO_PINS_PER_BANK; i++) {
1013 struct reg_field mux;
1014
1015 mux.reg = offset + (i / 4) * 4;
1016 mux.lsb = (i % 4) * 4;
1017 mux.msb = mux.lsb + 3;
1018
1019 pctl->irqmux[i] = devm_regmap_field_alloc(dev, rm, mux);
1020 if (IS_ERR(pctl->irqmux[i]))
1021 return PTR_ERR(pctl->irqmux[i]);
1022 }
1023
1024 return 0;
1025}
1026
870static int stm32_pctrl_build_state(struct platform_device *pdev) 1027static int stm32_pctrl_build_state(struct platform_device *pdev)
871{ 1028{
872 struct stm32_pinctrl *pctl = platform_get_drvdata(pdev); 1029 struct stm32_pinctrl *pctl = platform_get_drvdata(pdev);
@@ -935,6 +1092,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
935 return -EINVAL; 1092 return -EINVAL;
936 } 1093 }
937 1094
1095 ret = stm32_pctrl_dt_setup_irq(pdev, pctl);
1096 if (ret)
1097 return ret;
1098
938 for_each_child_of_node(np, child) 1099 for_each_child_of_node(np, child)
939 if (of_property_read_bool(child, "gpio-controller")) 1100 if (of_property_read_bool(child, "gpio-controller"))
940 banks++; 1101 banks++;