aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-07-28 10:29:22 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-08-16 08:43:56 -0400
commit8f903f8a342e466f3da33b21ae60f1b11626b81a (patch)
treec7a12a3a2d8dbfdc368242485e559afdd7a484c2
parent7ea46e0f9df44ce3dea5a54f7c182f98eeef7bee (diff)
pinctrl: imx: Use struct type for pins
The i.MX pinctrl driver uses 5 different arrays for storing the informations for pins. This requires five allocations. Instead, use a struct type which is more cache friendly, readable and requires less allocations. One array of integers is still needed since the pinctrl framework forces us to maintain it. This also adds checks whether the allocations are succesful which were missing. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pinctrl-imx.c79
-rw-r--r--drivers/pinctrl/pinctrl-imx.h36
2 files changed, 58 insertions, 57 deletions
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c
index 81ffb177cd30..3a1424518bcb 100644
--- a/drivers/pinctrl/pinctrl-imx.c
+++ b/drivers/pinctrl/pinctrl-imx.c
@@ -98,7 +98,7 @@ static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
98 if (selector >= info->ngroups) 98 if (selector >= info->ngroups)
99 return -EINVAL; 99 return -EINVAL;
100 100
101 *pins = info->groups[selector].pins; 101 *pins = info->groups[selector].pin_ids;
102 *npins = info->groups[selector].npins; 102 *npins = info->groups[selector].npins;
103 103
104 return 0; 104 return 0;
@@ -134,7 +134,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
134 } 134 }
135 135
136 for (i = 0; i < grp->npins; i++) { 136 for (i = 0; i < grp->npins; i++) {
137 if (!(grp->configs[i] & IMX_NO_PAD_CTL)) 137 if (!(grp->pins[i].config & IMX_NO_PAD_CTL))
138 map_num++; 138 map_num++;
139 } 139 }
140 140
@@ -159,11 +159,11 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
159 /* create config map */ 159 /* create config map */
160 new_map++; 160 new_map++;
161 for (i = j = 0; i < grp->npins; i++) { 161 for (i = j = 0; i < grp->npins; i++) {
162 if (!(grp->configs[i] & IMX_NO_PAD_CTL)) { 162 if (!(grp->pins[i].config & IMX_NO_PAD_CTL)) {
163 new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN; 163 new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN;
164 new_map[j].data.configs.group_or_pin = 164 new_map[j].data.configs.group_or_pin =
165 pin_get_name(pctldev, grp->pins[i]); 165 pin_get_name(pctldev, grp->pins[i].pin);
166 new_map[j].data.configs.configs = &grp->configs[i]; 166 new_map[j].data.configs.configs = &grp->pins[i].config;
167 new_map[j].data.configs.num_configs = 1; 167 new_map[j].data.configs.num_configs = 1;
168 j++; 168 j++;
169 } 169 }
@@ -197,28 +197,23 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
197 struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); 197 struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
198 const struct imx_pinctrl_soc_info *info = ipctl->info; 198 const struct imx_pinctrl_soc_info *info = ipctl->info;
199 const struct imx_pin_reg *pin_reg; 199 const struct imx_pin_reg *pin_reg;
200 const unsigned *pins, *mux, *input_val;
201 u16 *input_reg;
202 unsigned int npins, pin_id; 200 unsigned int npins, pin_id;
203 int i; 201 int i;
202 struct imx_pin_group *grp;
204 203
205 /* 204 /*
206 * Configure the mux mode for each pin in the group for a specific 205 * Configure the mux mode for each pin in the group for a specific
207 * function. 206 * function.
208 */ 207 */
209 pins = info->groups[group].pins; 208 grp = &info->groups[group];
210 npins = info->groups[group].npins; 209 npins = grp->npins;
211 mux = info->groups[group].mux_mode;
212 input_val = info->groups[group].input_val;
213 input_reg = info->groups[group].input_reg;
214
215 WARN_ON(!pins || !npins || !mux || !input_val || !input_reg);
216 210
217 dev_dbg(ipctl->dev, "enable function %s group %s\n", 211 dev_dbg(ipctl->dev, "enable function %s group %s\n",
218 info->functions[selector].name, info->groups[group].name); 212 info->functions[selector].name, grp->name);
219 213
220 for (i = 0; i < npins; i++) { 214 for (i = 0; i < npins; i++) {
221 pin_id = pins[i]; 215 struct imx_pin *pin = &grp->pins[i];
216 pin_id = pin->pin;
222 pin_reg = &info->pin_regs[pin_id]; 217 pin_reg = &info->pin_regs[pin_id];
223 218
224 if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->mux_reg) { 219 if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->mux_reg) {
@@ -231,13 +226,13 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
231 u32 reg; 226 u32 reg;
232 reg = readl(ipctl->base + pin_reg->mux_reg); 227 reg = readl(ipctl->base + pin_reg->mux_reg);
233 reg &= ~(0x7 << 20); 228 reg &= ~(0x7 << 20);
234 reg |= (mux[i] << 20); 229 reg |= (pin->mux_mode << 20);
235 writel(reg, ipctl->base + pin_reg->mux_reg); 230 writel(reg, ipctl->base + pin_reg->mux_reg);
236 } else { 231 } else {
237 writel(mux[i], ipctl->base + pin_reg->mux_reg); 232 writel(pin->mux_mode, ipctl->base + pin_reg->mux_reg);
238 } 233 }
239 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", 234 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
240 pin_reg->mux_reg, mux[i]); 235 pin_reg->mux_reg, pin->mux_mode);
241 236
242 /* 237 /*
243 * If the select input value begins with 0xff, it's a quirky 238 * If the select input value begins with 0xff, it's a quirky
@@ -252,8 +247,8 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
252 * in device tree, and then decode them here for setting 247 * in device tree, and then decode them here for setting
253 * up the select input bits in general purpose register. 248 * up the select input bits in general purpose register.
254 */ 249 */
255 if (input_val[i] >> 24 == 0xff) { 250 if (pin->input_val >> 24 == 0xff) {
256 u32 val = input_val[i]; 251 u32 val = pin->input_val;
257 u8 select = val & 0xff; 252 u8 select = val & 0xff;
258 u8 width = (val >> 8) & 0xff; 253 u8 width = (val >> 8) & 0xff;
259 u8 shift = (val >> 16) & 0xff; 254 u8 shift = (val >> 16) & 0xff;
@@ -262,19 +257,19 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
262 * The input_reg[i] here is actually some IOMUXC general 257 * The input_reg[i] here is actually some IOMUXC general
263 * purpose register, not regular select input register. 258 * purpose register, not regular select input register.
264 */ 259 */
265 val = readl(ipctl->base + input_reg[i]); 260 val = readl(ipctl->base + pin->input_val);
266 val &= ~mask; 261 val &= ~mask;
267 val |= select << shift; 262 val |= select << shift;
268 writel(val, ipctl->base + input_reg[i]); 263 writel(val, ipctl->base + pin->input_val);
269 } else if (input_reg[i]) { 264 } else if (pin->input_val) {
270 /* 265 /*
271 * Regular select input register can never be at offset 266 * Regular select input register can never be at offset
272 * 0, and we only print register value for regular case. 267 * 0, and we only print register value for regular case.
273 */ 268 */
274 writel(input_val[i], ipctl->base + input_reg[i]); 269 writel(pin->input_val, ipctl->base + pin->input_reg);
275 dev_dbg(ipctl->dev, 270 dev_dbg(ipctl->dev,
276 "==>select_input: offset 0x%x val 0x%x\n", 271 "==>select_input: offset 0x%x val 0x%x\n",
277 input_reg[i], input_val[i]); 272 pin->input_reg, pin->input_val);
278 } 273 }
279 } 274 }
280 275
@@ -403,8 +398,9 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
403 seq_printf(s, "\n"); 398 seq_printf(s, "\n");
404 grp = &info->groups[group]; 399 grp = &info->groups[group];
405 for (i = 0; i < grp->npins; i++) { 400 for (i = 0; i < grp->npins; i++) {
406 name = pin_get_name(pctldev, grp->pins[i]); 401 struct imx_pin *pin = &grp->pins[i];
407 ret = imx_pinconf_get(pctldev, grp->pins[i], &config); 402 name = pin_get_name(pctldev, pin->pin);
403 ret = imx_pinconf_get(pctldev, pin->pin, &config);
408 if (ret) 404 if (ret)
409 return; 405 return;
410 seq_printf(s, "%s: 0x%lx", name, config); 406 seq_printf(s, "%s: 0x%lx", name, config);
@@ -468,21 +464,19 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
468 } 464 }
469 465
470 grp->npins = size / pin_size; 466 grp->npins = size / pin_size;
471 grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 467 grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(struct imx_pin),
472 GFP_KERNEL);
473 grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
474 GFP_KERNEL); 468 GFP_KERNEL);
475 grp->input_reg = devm_kzalloc(info->dev, grp->npins * sizeof(u16), 469 grp->pin_ids = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
476 GFP_KERNEL);
477 grp->input_val = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
478 GFP_KERNEL);
479 grp->configs = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned long),
480 GFP_KERNEL); 470 GFP_KERNEL);
471 if (!grp->pins || ! grp->pin_ids)
472 return -ENOMEM;
473
481 for (i = 0; i < grp->npins; i++) { 474 for (i = 0; i < grp->npins; i++) {
482 u32 mux_reg = be32_to_cpu(*list++); 475 u32 mux_reg = be32_to_cpu(*list++);
483 u32 conf_reg; 476 u32 conf_reg;
484 unsigned int pin_id; 477 unsigned int pin_id;
485 struct imx_pin_reg *pin_reg; 478 struct imx_pin_reg *pin_reg;
479 struct imx_pin *pin = &grp->pins[i];
486 480
487 if (info->flags & SHARE_MUX_CONF_REG) 481 if (info->flags & SHARE_MUX_CONF_REG)
488 conf_reg = mux_reg; 482 conf_reg = mux_reg;
@@ -491,18 +485,19 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
491 485
492 pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4; 486 pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
493 pin_reg = &info->pin_regs[pin_id]; 487 pin_reg = &info->pin_regs[pin_id];
494 grp->pins[i] = pin_id; 488 pin->pin = pin_id;
489 grp->pin_ids[i] = pin_id;
495 pin_reg->mux_reg = mux_reg; 490 pin_reg->mux_reg = mux_reg;
496 pin_reg->conf_reg = conf_reg; 491 pin_reg->conf_reg = conf_reg;
497 grp->input_reg[i] = be32_to_cpu(*list++); 492 pin->input_reg = be32_to_cpu(*list++);
498 grp->mux_mode[i] = be32_to_cpu(*list++); 493 pin->mux_mode = be32_to_cpu(*list++);
499 grp->input_val[i] = be32_to_cpu(*list++); 494 pin->input_val = be32_to_cpu(*list++);
500 495
501 /* SION bit is in mux register */ 496 /* SION bit is in mux register */
502 config = be32_to_cpu(*list++); 497 config = be32_to_cpu(*list++);
503 if (config & IMX_PAD_SION) 498 if (config & IMX_PAD_SION)
504 grp->mux_mode[i] |= IOMUXC_CONFIG_SION; 499 pin->mux_mode |= IOMUXC_CONFIG_SION;
505 grp->configs[i] = config & ~IMX_PAD_SION; 500 pin->config = config & ~IMX_PAD_SION;
506 } 501 }
507 502
508#ifdef DEBUG 503#ifdef DEBUG
diff --git a/drivers/pinctrl/pinctrl-imx.h b/drivers/pinctrl/pinctrl-imx.h
index bcedd991c9f3..db408b057000 100644
--- a/drivers/pinctrl/pinctrl-imx.h
+++ b/drivers/pinctrl/pinctrl-imx.h
@@ -18,29 +18,35 @@
18struct platform_device; 18struct platform_device;
19 19
20/** 20/**
21 * struct imx_pin_group - describes a single i.MX pin
22 * @pin: the pin_id of this pin
23 * @mux_mode: the mux mode for this pin.
24 * @input_reg: the select input register offset for this pin if any
25 * 0 if no select input setting needed.
26 * @input_val: the select input value for this pin.
27 * @configs: the config for this pin.
28 */
29struct imx_pin {
30 unsigned int pin;
31 unsigned int mux_mode;
32 u16 input_reg;
33 unsigned int input_val;
34 unsigned long config;
35};
36
37/**
21 * struct imx_pin_group - describes an IMX pin group 38 * struct imx_pin_group - describes an IMX pin group
22 * @name: the name of this specific pin group 39 * @name: the name of this specific pin group
23 * @pins: an array of discrete physical pins used in this group, taken
24 * from the driver-local pin enumeration space
25 * @npins: the number of pins in this group array, i.e. the number of 40 * @npins: the number of pins in this group array, i.e. the number of
26 * elements in .pins so we can iterate over that array 41 * elements in .pins so we can iterate over that array
27 * @mux_mode: the mux mode for each pin in this group. The size of this 42 * @pin_ids: array of pin_ids. pinctrl forces us to maintain such an array
28 * array is the same as pins. 43 * @pins: array of pins
29 * @input_reg: select input register offset for this mux if any
30 * 0 if no select input setting needed.
31 * @input_val: the select input value for each pin in this group. The size of
32 * this array is the same as pins.
33 * @configs: the config for each pin in this group. The size of this
34 * array is the same as pins.
35 */ 44 */
36struct imx_pin_group { 45struct imx_pin_group {
37 const char *name; 46 const char *name;
38 unsigned int *pins;
39 unsigned npins; 47 unsigned npins;
40 unsigned int *mux_mode; 48 unsigned int *pin_ids;
41 u16 *input_reg; 49 struct imx_pin *pins;
42 unsigned int *input_val;
43 unsigned long *configs;
44}; 50};
45 51
46/** 52/**