diff options
-rw-r--r-- | Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt | 135 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.c | 64 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 116 |
3 files changed, 314 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt new file mode 100644 index 000000000000..8264cbcdd418 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt | |||
@@ -0,0 +1,135 @@ | |||
1 | * Renesas Pin Function Controller (GPIO and Pin Mux/Config) | ||
2 | |||
3 | The Pin Function Controller (PFC) is a Pin Mux/Config controller. On SH7372, | ||
4 | SH73A0, R8A73A4 and R8A7740 it also acts as a GPIO controller. | ||
5 | |||
6 | |||
7 | Pin Control | ||
8 | ----------- | ||
9 | |||
10 | Required Properties: | ||
11 | |||
12 | - compatible: should be one of the following. | ||
13 | - "renesas,pfc-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible pin-controller. | ||
14 | - "renesas,pfc-r8a7740": for R8A7740 (R-Mobile A1) compatible pin-controller. | ||
15 | - "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller. | ||
16 | - "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller. | ||
17 | - "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller. | ||
18 | - "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller. | ||
19 | - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller. | ||
20 | |||
21 | - reg: Base address and length of each memory resource used by the pin | ||
22 | controller hardware module. | ||
23 | |||
24 | Optional properties: | ||
25 | |||
26 | - #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden | ||
27 | otherwise. Should be 3. | ||
28 | |||
29 | The PFC node also acts as a container for pin configuration nodes. Please refer | ||
30 | to pinctrl-bindings.txt in this directory for the definition of the term "pin | ||
31 | configuration node" and for the common pinctrl bindings used by client devices. | ||
32 | |||
33 | Each pin configuration node represents desired functions to select on a pin | ||
34 | group or a list of pin groups. The functions and pin groups can be specified | ||
35 | directly in the pin configuration node, or grouped in child subnodes. Several | ||
36 | functions can thus be referenced as a single pin configuration node by client | ||
37 | devices. | ||
38 | |||
39 | A configuration node or subnode must contain a function and reference at least | ||
40 | one pin group. | ||
41 | |||
42 | All pin configuration nodes and subnodes names are ignored. All of those nodes | ||
43 | are parsed through phandles and processed purely based on their content. | ||
44 | |||
45 | Pin Configuration Node Properties: | ||
46 | |||
47 | - renesas,groups : An array of strings, each string containing the name of a pin | ||
48 | group. | ||
49 | |||
50 | - renesas,function: A string containing the name of the function to mux to the | ||
51 | pin group(s) specified by the renesas,groups property | ||
52 | |||
53 | Valid values for pin, group and function names can be found in the group and | ||
54 | function arrays of the PFC data file corresponding to the SoC | ||
55 | (drivers/pinctrl/sh-pfc/pfc-*.c) | ||
56 | |||
57 | |||
58 | GPIO | ||
59 | ---- | ||
60 | |||
61 | On SH7372, SH73A0, R8A73A4 and R8A7740 the PFC node is also a GPIO controller | ||
62 | node. | ||
63 | |||
64 | Required Properties: | ||
65 | |||
66 | - gpio-controller: Marks the device node as a gpio controller. | ||
67 | |||
68 | - #gpio-cells: Should be 2. The first cell is the GPIO number and the second | ||
69 | cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the | ||
70 | GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported. | ||
71 | |||
72 | The syntax of the gpio specifier used by client nodes should be the following | ||
73 | with values derived from the SoC user manual. | ||
74 | |||
75 | <[phandle of the gpio controller node] | ||
76 | [pin number within the gpio controller] | ||
77 | [flags]> | ||
78 | |||
79 | On other mach-shmobile platforms GPIO is handled by the gpio-rcar driver. | ||
80 | Please refer to Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt | ||
81 | for documentation of the GPIO device tree bindings on those platforms. | ||
82 | |||
83 | |||
84 | Examples | ||
85 | -------- | ||
86 | |||
87 | Example 1: SH73A0 (SH-Mobile AG5) pin controller node | ||
88 | |||
89 | pfc: pfc@e6050000 { | ||
90 | compatible = "renesas,pfc-sh73a0"; | ||
91 | reg = <0xe6050000 0x8000>, | ||
92 | <0xe605801c 0x1c>; | ||
93 | gpio-controller; | ||
94 | #gpio-cells = <2>; | ||
95 | }; | ||
96 | |||
97 | Example 2: A GPIO LED node that references a GPIO | ||
98 | |||
99 | #include <dt-bindings/gpio/gpio.h> | ||
100 | |||
101 | leds { | ||
102 | compatible = "gpio-leds"; | ||
103 | led1 { | ||
104 | gpios = <&pfc 20 GPIO_ACTIVE_LOW>; | ||
105 | }; | ||
106 | }; | ||
107 | |||
108 | Example 3: KZM-A9-GT (SH-Mobile AG5) default pin state hog and pin control maps | ||
109 | for the MMCIF and SCIFA4 devices | ||
110 | |||
111 | &pfc { | ||
112 | pinctrl-0 = <&scifa4_pins>; | ||
113 | pinctrl-names = "default"; | ||
114 | |||
115 | mmcif_pins: mmcif { | ||
116 | renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0"; | ||
117 | renesas,function = "mmc0"; | ||
118 | }; | ||
119 | |||
120 | scifa4_pins: scifa4 { | ||
121 | renesas,groups = "scifa4_data", "scifa4_ctrl"; | ||
122 | renesas,function = "scifa4"; | ||
123 | }; | ||
124 | }; | ||
125 | |||
126 | Example 4: KZM-A9-GT (SH-Mobile AG5) default pin state for the MMCIF device | ||
127 | |||
128 | &mmcif { | ||
129 | pinctrl-0 = <&mmcif_pins>; | ||
130 | pinctrl-names = "default"; | ||
131 | |||
132 | bus-width = <8>; | ||
133 | vmmc-supply = <®_1p8v>; | ||
134 | status = "okay"; | ||
135 | }; | ||
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 13f40c59ebfb..4eea849a1ad8 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
21 | #include <linux/pinctrl/machine.h> | 23 | #include <linux/pinctrl/machine.h> |
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -348,13 +350,72 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | |||
348 | return 0; | 350 | return 0; |
349 | } | 351 | } |
350 | 352 | ||
353 | #ifdef CONFIG_OF | ||
354 | static const struct of_device_id sh_pfc_of_table[] = { | ||
355 | #ifdef CONFIG_PINCTRL_PFC_R8A73A4 | ||
356 | { | ||
357 | .compatible = "renesas,pfc-r8a73a4", | ||
358 | .data = &r8a73a4_pinmux_info, | ||
359 | }, | ||
360 | #endif | ||
361 | #ifdef CONFIG_PINCTRL_PFC_R8A7740 | ||
362 | { | ||
363 | .compatible = "renesas,pfc-r8a7740", | ||
364 | .data = &r8a7740_pinmux_info, | ||
365 | }, | ||
366 | #endif | ||
367 | #ifdef CONFIG_PINCTRL_PFC_R8A7778 | ||
368 | { | ||
369 | .compatible = "renesas,pfc-r8a7778", | ||
370 | .data = &r8a7778_pinmux_info, | ||
371 | }, | ||
372 | #endif | ||
373 | #ifdef CONFIG_PINCTRL_PFC_R8A7779 | ||
374 | { | ||
375 | .compatible = "renesas,pfc-r8a7779", | ||
376 | .data = &r8a7779_pinmux_info, | ||
377 | }, | ||
378 | #endif | ||
379 | #ifdef CONFIG_PINCTRL_PFC_R8A7790 | ||
380 | { | ||
381 | .compatible = "renesas,pfc-r8a7790", | ||
382 | .data = &r8a7790_pinmux_info, | ||
383 | }, | ||
384 | #endif | ||
385 | #ifdef CONFIG_PINCTRL_PFC_SH7372 | ||
386 | { | ||
387 | .compatible = "renesas,pfc-sh7372", | ||
388 | .data = &sh7372_pinmux_info, | ||
389 | }, | ||
390 | #endif | ||
391 | #ifdef CONFIG_PINCTRL_PFC_SH73A0 | ||
392 | { | ||
393 | .compatible = "renesas,pfc-sh73a0", | ||
394 | .data = &sh73a0_pinmux_info, | ||
395 | }, | ||
396 | #endif | ||
397 | { }, | ||
398 | }; | ||
399 | MODULE_DEVICE_TABLE(of, sh_pfc_of_table); | ||
400 | #endif | ||
401 | |||
351 | static int sh_pfc_probe(struct platform_device *pdev) | 402 | static int sh_pfc_probe(struct platform_device *pdev) |
352 | { | 403 | { |
404 | const struct platform_device_id *platid = platform_get_device_id(pdev); | ||
405 | #ifdef CONFIG_OF | ||
406 | struct device_node *np = pdev->dev.of_node; | ||
407 | #endif | ||
353 | const struct sh_pfc_soc_info *info; | 408 | const struct sh_pfc_soc_info *info; |
354 | struct sh_pfc *pfc; | 409 | struct sh_pfc *pfc; |
355 | int ret; | 410 | int ret; |
356 | 411 | ||
357 | info = (void *)pdev->id_entry->driver_data; | 412 | #ifdef CONFIG_OF |
413 | if (np) | ||
414 | info = of_match_device(sh_pfc_of_table, &pdev->dev)->data; | ||
415 | else | ||
416 | #endif | ||
417 | info = platid ? (const void *)platid->driver_data : NULL; | ||
418 | |||
358 | if (info == NULL) | 419 | if (info == NULL) |
359 | return -ENODEV; | 420 | return -ENODEV; |
360 | 421 | ||
@@ -480,6 +541,7 @@ static struct platform_driver sh_pfc_driver = { | |||
480 | .driver = { | 541 | .driver = { |
481 | .name = DRV_NAME, | 542 | .name = DRV_NAME, |
482 | .owner = THIS_MODULE, | 543 | .owner = THIS_MODULE, |
544 | .of_match_table = of_match_ptr(sh_pfc_of_table), | ||
483 | }, | 545 | }, |
484 | }; | 546 | }; |
485 | 547 | ||
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 3492ec9a33b7..7e32bb8c08dd 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c | |||
@@ -14,7 +14,9 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/of.h> | ||
17 | #include <linux/pinctrl/consumer.h> | 18 | #include <linux/pinctrl/consumer.h> |
19 | #include <linux/pinctrl/machine.h> | ||
18 | #include <linux/pinctrl/pinconf.h> | 20 | #include <linux/pinctrl/pinconf.h> |
19 | #include <linux/pinctrl/pinconf-generic.h> | 21 | #include <linux/pinctrl/pinconf-generic.h> |
20 | #include <linux/pinctrl/pinctrl.h> | 22 | #include <linux/pinctrl/pinctrl.h> |
@@ -72,11 +74,125 @@ static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, | |||
72 | seq_printf(s, "%s", DRV_NAME); | 74 | seq_printf(s, "%s", DRV_NAME); |
73 | } | 75 | } |
74 | 76 | ||
77 | static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, | ||
78 | struct pinctrl_map **map, | ||
79 | unsigned int *num_maps, unsigned int *index) | ||
80 | { | ||
81 | struct pinctrl_map *maps = *map; | ||
82 | unsigned int nmaps = *num_maps; | ||
83 | unsigned int idx = *index; | ||
84 | const char *function = NULL; | ||
85 | struct property *prop; | ||
86 | const char *group; | ||
87 | int ret; | ||
88 | |||
89 | /* Parse the function and configuration properties. At least a function | ||
90 | * or one configuration must be specified. | ||
91 | */ | ||
92 | ret = of_property_read_string(np, "renesas,function", &function); | ||
93 | if (ret < 0 && ret != -EINVAL) { | ||
94 | dev_err(dev, "Invalid function in DT\n"); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | if (!function) { | ||
99 | dev_err(dev, "DT node must contain at least one function\n"); | ||
100 | goto done; | ||
101 | } | ||
102 | |||
103 | /* Count the number of groups and reallocate mappings. */ | ||
104 | ret = of_property_count_strings(np, "renesas,groups"); | ||
105 | if (ret < 0 && ret != -EINVAL) { | ||
106 | dev_err(dev, "Invalid pin groups list in DT\n"); | ||
107 | goto done; | ||
108 | } | ||
109 | |||
110 | if (!ret) { | ||
111 | dev_err(dev, "No group provided in DT node\n"); | ||
112 | ret = -ENODEV; | ||
113 | goto done; | ||
114 | } | ||
115 | |||
116 | nmaps += ret; | ||
117 | |||
118 | maps = krealloc(maps, sizeof(*maps) * nmaps, GFP_KERNEL); | ||
119 | if (maps == NULL) { | ||
120 | ret = -ENOMEM; | ||
121 | goto done; | ||
122 | } | ||
123 | |||
124 | *map = maps; | ||
125 | *num_maps = nmaps; | ||
126 | |||
127 | /* Iterate over pins and groups and create the mappings. */ | ||
128 | of_property_for_each_string(np, "renesas,groups", prop, group) { | ||
129 | maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; | ||
130 | maps[idx].data.mux.group = group; | ||
131 | maps[idx].data.mux.function = function; | ||
132 | idx++; | ||
133 | } | ||
134 | |||
135 | ret = 0; | ||
136 | |||
137 | done: | ||
138 | *index = idx; | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | static void sh_pfc_dt_free_map(struct pinctrl_dev *pctldev, | ||
143 | struct pinctrl_map *map, unsigned num_maps) | ||
144 | { | ||
145 | kfree(map); | ||
146 | } | ||
147 | |||
148 | static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
149 | struct device_node *np, | ||
150 | struct pinctrl_map **map, unsigned *num_maps) | ||
151 | { | ||
152 | struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); | ||
153 | struct device *dev = pmx->pfc->dev; | ||
154 | struct device_node *child; | ||
155 | unsigned int index; | ||
156 | int ret; | ||
157 | |||
158 | *map = NULL; | ||
159 | *num_maps = 0; | ||
160 | index = 0; | ||
161 | |||
162 | for_each_child_of_node(np, child) { | ||
163 | ret = sh_pfc_dt_subnode_to_map(dev, child, map, num_maps, | ||
164 | &index); | ||
165 | if (ret < 0) | ||
166 | goto done; | ||
167 | } | ||
168 | |||
169 | /* If no mapping has been found in child nodes try the config node. */ | ||
170 | if (*num_maps == 0) { | ||
171 | ret = sh_pfc_dt_subnode_to_map(dev, np, map, num_maps, &index); | ||
172 | if (ret < 0) | ||
173 | goto done; | ||
174 | } | ||
175 | |||
176 | if (*num_maps) | ||
177 | return 0; | ||
178 | |||
179 | dev_err(dev, "no mapping found in node %s\n", np->full_name); | ||
180 | ret = -EINVAL; | ||
181 | |||
182 | done: | ||
183 | if (ret < 0) | ||
184 | sh_pfc_dt_free_map(pctldev, *map, *num_maps); | ||
185 | |||
186 | return ret; | ||
187 | } | ||
188 | |||
75 | static const struct pinctrl_ops sh_pfc_pinctrl_ops = { | 189 | static const struct pinctrl_ops sh_pfc_pinctrl_ops = { |
76 | .get_groups_count = sh_pfc_get_groups_count, | 190 | .get_groups_count = sh_pfc_get_groups_count, |
77 | .get_group_name = sh_pfc_get_group_name, | 191 | .get_group_name = sh_pfc_get_group_name, |
78 | .get_group_pins = sh_pfc_get_group_pins, | 192 | .get_group_pins = sh_pfc_get_group_pins, |
79 | .pin_dbg_show = sh_pfc_pin_dbg_show, | 193 | .pin_dbg_show = sh_pfc_pin_dbg_show, |
194 | .dt_node_to_map = sh_pfc_dt_node_to_map, | ||
195 | .dt_free_map = sh_pfc_dt_free_map, | ||
80 | }; | 196 | }; |
81 | 197 | ||
82 | static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev) | 198 | static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev) |