1 From 13e754b5fff5be1930e2b8fe534a52b608c9e479 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Mon, 3 Dec 2012 19:27:28 +0100
4 Subject: [PATCH] PINCTRL: lantiq: fixes
7 drivers/pinctrl/pinctrl-lantiq.c | 54 ++++++++++++++++++-----------
8 drivers/pinctrl/pinctrl-lantiq.h | 1 +
9 drivers/pinctrl/pinctrl-xway.c | 70 ++++++++++++++++++++++++++++++++++----
10 3 files changed, 99 insertions(+), 26 deletions(-)
12 --- a/drivers/pinctrl/pinctrl-lantiq.c
13 +++ b/drivers/pinctrl/pinctrl-lantiq.c
14 @@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(str
15 seq_printf(s, " %s", dev_name(pctldev->dev));
18 -static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
19 +static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
20 struct device_node *np,
21 struct pinctrl_map **map)
23 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
24 + struct property *pins = of_find_property(np, "lantiq,pins", NULL);
25 + struct property *groups = of_find_property(np, "lantiq,groups", NULL);
26 unsigned long configs[3];
27 unsigned num_configs = 0;
28 struct property *prop;
29 @@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map
33 + if (!pins && !groups) {
34 + dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
39 + if (pins && groups) {
40 + dev_err(pctldev->dev, "%s defines both pins and groups\n",
45 ret = of_property_read_string(np, "lantiq,function", &function);
47 + if (groups && !ret) {
48 of_property_for_each_string(np, "lantiq,groups", prop, group) {
49 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
50 (*map)->name = function;
51 @@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map
52 (*map)->data.mux.function = function;
55 - if (of_find_property(np, "lantiq,pins", NULL))
56 - dev_err(pctldev->dev,
57 - "%s mixes pins and groups settings\n",
62 for (i = 0; i < info->num_params; i++) {
63 @@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map
70 of_property_for_each_string(np, "lantiq,pins", prop, pin) {
71 (*map)->data.configs.configs = kmemdup(configs,
72 @@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map
73 (*map)->data.configs.num_configs = num_configs;
77 + of_property_for_each_string(np, "lantiq,groups", prop, group) {
78 + (*map)->data.configs.configs = kmemdup(configs,
79 + num_configs * sizeof(unsigned long),
81 + (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
82 + (*map)->name = group;
83 + (*map)->data.configs.group_or_pin = group;
84 + (*map)->data.configs.num_configs = num_configs;
89 static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
90 @@ -135,23 +153,19 @@ int ltq_pinctrl_dt_node_to_map(struct pi
92 struct pinctrl_map *tmp;
93 struct device_node *np;
98 for_each_child_of_node(np_config, np)
99 - *num_maps += ltq_pinctrl_dt_subnode_size(np);
100 - *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
101 + max_maps += ltq_pinctrl_dt_subnode_size(np);
102 + *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
107 - for_each_child_of_node(np_config, np) {
108 - ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
110 - ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
114 + for_each_child_of_node(np_config, np)
115 + ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
116 + *num_maps = ((int)(tmp - *map));
121 --- a/drivers/pinctrl/pinctrl-lantiq.h
122 +++ b/drivers/pinctrl/pinctrl-lantiq.h
123 @@ -34,6 +34,7 @@ enum ltq_pinconf_param {
124 LTQ_PINCONF_PARAM_OPEN_DRAIN,
125 LTQ_PINCONF_PARAM_DRIVE_CURRENT,
126 LTQ_PINCONF_PARAM_SLEW_RATE,
127 + LTQ_PINCONF_PARAM_OUTPUT,
130 struct ltq_cfg_param {
131 --- a/drivers/pinctrl/pinctrl-xway.c
132 +++ b/drivers/pinctrl/pinctrl-xway.c
133 @@ -443,7 +443,7 @@ static int xway_pinconf_get(struct pinct
136 *config = LTQ_PINCONF_PACK(param,
137 - !!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
138 + !gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
141 case LTQ_PINCONF_PARAM_PULL:
142 @@ -466,6 +466,11 @@ static int xway_pinconf_get(struct pinct
143 *config = LTQ_PINCONF_PACK(param, 1);
146 + case LTQ_PINCONF_PARAM_OUTPUT:
147 + reg = GPIO_DIR(pin);
148 + *config = LTQ_PINCONF_PACK(param,
149 + gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
152 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
154 @@ -489,7 +494,10 @@ static int xway_pinconf_set(struct pinct
158 - gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
160 + gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
162 + gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
165 case LTQ_PINCONF_PARAM_PULL:
166 @@ -515,6 +523,14 @@ static int xway_pinconf_set(struct pinct
167 dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
170 + case LTQ_PINCONF_PARAM_OUTPUT:
171 + reg = GPIO_DIR(pin);
173 + gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
175 + gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
179 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
181 @@ -522,9 +538,25 @@ static int xway_pinconf_set(struct pinct
185 +int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
187 + unsigned long config)
189 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
192 + for (i = 0; i < info->grps[selector].npins && !ret; i++)
193 + ret = xway_pinconf_set(pctldev,
194 + info->grps[selector].pins[i], config);
200 struct pinconf_ops xway_pinconf_ops = {
201 .pin_config_get = xway_pinconf_get,
202 .pin_config_set = xway_pinconf_set,
203 + .pin_config_group_set = xway_pinconf_group_set,
206 static struct pinctrl_desc xway_pctrl_desc = {
207 @@ -532,10 +564,9 @@ static struct pinctrl_desc xway_pctrl_de
208 .confops = &xway_pinconf_ops,
211 -static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
212 +static int mux_apply(struct ltq_pinmux_info *info,
215 - struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
216 int port = PORT(pin);
217 u32 alt1_reg = GPIO_ALT1(pin);
219 @@ -555,9 +586,18 @@ static inline int xway_mux_apply(struct
223 +static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
226 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
228 + return mux_apply(info, pin, mux);
231 static const struct ltq_cfg_param xway_cfg_params[] = {
232 {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
233 {"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
234 + {"lantiq,output", LTQ_PINCONF_PARAM_OUTPUT},
237 static struct ltq_pinmux_info xway_info = {
238 @@ -598,6 +638,10 @@ static int xway_gpio_dir_out(struct gpio
240 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
242 + if (PORT(pin) == PORT3)
243 + gpio_setbit(info->membase[0], GPIO3_OD, PORT_PIN(pin));
245 + gpio_setbit(info->membase[0], GPIO_OD(pin), PORT_PIN(pin));
246 gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
247 xway_gpio_set(chip, pin, val);
249 @@ -618,6 +662,18 @@ static void xway_gpio_free(struct gpio_c
250 pinctrl_free_gpio(gpio);
253 +static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
255 + struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
258 + for (i = 0; i < info->num_exin; i++)
259 + if (info->exin[i] == offset)
260 + return ltq_eiu_get_irq(i);
265 static struct gpio_chip xway_chip = {
266 .label = "gpio-xway",
267 .direction_input = xway_gpio_dir_in,
268 @@ -626,6 +682,7 @@ static struct gpio_chip xway_chip = {
269 .set = xway_gpio_set,
270 .request = xway_gpio_req,
271 .free = xway_gpio_free,
272 + .to_irq = xway_gpio_to_irq,