aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-tegra.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-04-23 12:05:22 -0400
committerStephen Warren <swarren@nvidia.com>2012-04-25 17:21:47 -0400
commitaef7704c6cc36db9618603b22194def441d30432 (patch)
treed560e29b90c0fcfadaeb1d41e3ba39a379e8496c /drivers/pinctrl/pinctrl-tegra.c
parentb5badbaad16b44f1d5508701295fa682308da701 (diff)
pinctrl: tegra: error reporting cleanup
Print an explicit error message in various failure cases to allow easier diagnosis. WARN_ON() some internal failures that users/clients shouldn't be able to trigger. Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/pinctrl/pinctrl-tegra.c')
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index df52d75c0db0..b6934867d8d3 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -92,8 +92,9 @@ static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
92} 92}
93#endif 93#endif
94 94
95static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps, 95static int reserve_map(struct device *dev, struct pinctrl_map **map,
96 unsigned *num_maps, unsigned reserve) 96 unsigned *reserved_maps, unsigned *num_maps,
97 unsigned reserve)
97{ 98{
98 unsigned old_num = *reserved_maps; 99 unsigned old_num = *reserved_maps;
99 unsigned new_num = *num_maps + reserve; 100 unsigned new_num = *num_maps + reserve;
@@ -103,8 +104,10 @@ static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
103 return 0; 104 return 0;
104 105
105 new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL); 106 new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
106 if (!new_map) 107 if (!new_map) {
108 dev_err(dev, "krealloc(map) failed\n");
107 return -ENOMEM; 109 return -ENOMEM;
110 }
108 111
109 memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map)); 112 memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
110 113
@@ -118,7 +121,7 @@ static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
118 unsigned *num_maps, const char *group, 121 unsigned *num_maps, const char *group,
119 const char *function) 122 const char *function)
120{ 123{
121 if (*num_maps == *reserved_maps) 124 if (WARN_ON(*num_maps == *reserved_maps))
122 return -ENOSPC; 125 return -ENOSPC;
123 126
124 (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; 127 (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
@@ -129,19 +132,22 @@ static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
129 return 0; 132 return 0;
130} 133}
131 134
132static int add_map_configs(struct pinctrl_map **map, unsigned *reserved_maps, 135static int add_map_configs(struct device *dev, struct pinctrl_map **map,
133 unsigned *num_maps, const char *group, 136 unsigned *reserved_maps, unsigned *num_maps,
134 unsigned long *configs, unsigned num_configs) 137 const char *group, unsigned long *configs,
138 unsigned num_configs)
135{ 139{
136 unsigned long *dup_configs; 140 unsigned long *dup_configs;
137 141
138 if (*num_maps == *reserved_maps) 142 if (WARN_ON(*num_maps == *reserved_maps))
139 return -ENOSPC; 143 return -ENOSPC;
140 144
141 dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs), 145 dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
142 GFP_KERNEL); 146 GFP_KERNEL);
143 if (!dup_configs) 147 if (!dup_configs) {
148 dev_err(dev, "kmemdup(configs) failed\n");
144 return -ENOMEM; 149 return -ENOMEM;
150 }
145 151
146 (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP; 152 (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
147 (*map)[*num_maps].data.configs.group_or_pin = group; 153 (*map)[*num_maps].data.configs.group_or_pin = group;
@@ -152,8 +158,8 @@ static int add_map_configs(struct pinctrl_map **map, unsigned *reserved_maps,
152 return 0; 158 return 0;
153} 159}
154 160
155static int add_config(unsigned long **configs, unsigned *num_configs, 161static int add_config(struct device *dev, unsigned long **configs,
156 unsigned long config) 162 unsigned *num_configs, unsigned long config)
157{ 163{
158 unsigned old_num = *num_configs; 164 unsigned old_num = *num_configs;
159 unsigned new_num = old_num + 1; 165 unsigned new_num = old_num + 1;
@@ -161,8 +167,10 @@ static int add_config(unsigned long **configs, unsigned *num_configs,
161 167
162 new_configs = krealloc(*configs, sizeof(*new_configs) * new_num, 168 new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
163 GFP_KERNEL); 169 GFP_KERNEL);
164 if (!new_configs) 170 if (!new_configs) {
171 dev_err(dev, "krealloc(configs) failed\n");
165 return -ENOMEM; 172 return -ENOMEM;
173 }
166 174
167 new_configs[old_num] = config; 175 new_configs[old_num] = config;
168 176
@@ -203,7 +211,8 @@ static const struct cfg_param {
203 {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, 211 {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
204}; 212};
205 213
206int tegra_pinctrl_dt_subnode_to_map(struct device_node *np, 214int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
215 struct device_node *np,
207 struct pinctrl_map **map, 216 struct pinctrl_map **map,
208 unsigned *reserved_maps, 217 unsigned *reserved_maps,
209 unsigned *num_maps) 218 unsigned *num_maps)
@@ -219,16 +228,25 @@ int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
219 const char *group; 228 const char *group;
220 229
221 ret = of_property_read_string(np, "nvidia,function", &function); 230 ret = of_property_read_string(np, "nvidia,function", &function);
222 if (ret < 0) 231 if (ret < 0) {
232 /* EINVAL=missing, which is fine since it's optional */
233 if (ret != -EINVAL)
234 dev_err(dev,
235 "could not parse property nvidia,function\n");
223 function = NULL; 236 function = NULL;
237 }
224 238
225 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 239 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
226 ret = of_property_read_u32(np, cfg_params[i].property, &val); 240 ret = of_property_read_u32(np, cfg_params[i].property, &val);
227 if (!ret) { 241 if (!ret) {
228 config = TEGRA_PINCONF_PACK(cfg_params[i].param, val); 242 config = TEGRA_PINCONF_PACK(cfg_params[i].param, val);
229 ret = add_config(&configs, &num_configs, config); 243 ret = add_config(dev, &configs, &num_configs, config);
230 if (ret < 0) 244 if (ret < 0)
231 goto exit; 245 goto exit;
246 /* EINVAL=missing, which is fine since it's optional */
247 } else if (ret != -EINVAL) {
248 dev_err(dev, "could not parse property %s\n",
249 cfg_params[i].property);
232 } 250 }
233 } 251 }
234 252
@@ -238,11 +256,13 @@ int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
238 if (num_configs) 256 if (num_configs)
239 reserve++; 257 reserve++;
240 ret = of_property_count_strings(np, "nvidia,pins"); 258 ret = of_property_count_strings(np, "nvidia,pins");
241 if (ret < 0) 259 if (ret < 0) {
260 dev_err(dev, "could not parse property nvidia,pins\n");
242 goto exit; 261 goto exit;
262 }
243 reserve *= ret; 263 reserve *= ret;
244 264
245 ret = reserve_map(map, reserved_maps, num_maps, reserve); 265 ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
246 if (ret < 0) 266 if (ret < 0)
247 goto exit; 267 goto exit;
248 268
@@ -255,8 +275,9 @@ int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
255 } 275 }
256 276
257 if (num_configs) { 277 if (num_configs) {
258 ret = add_map_configs(map, reserved_maps, num_maps, 278 ret = add_map_configs(dev, map, reserved_maps,
259 group, configs, num_configs); 279 num_maps, group, configs,
280 num_configs);
260 if (ret < 0) 281 if (ret < 0)
261 goto exit; 282 goto exit;
262 } 283 }
@@ -282,8 +303,8 @@ int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
282 *num_maps = 0; 303 *num_maps = 0;
283 304
284 for_each_child_of_node(np_config, np) { 305 for_each_child_of_node(np_config, np) {
285 ret = tegra_pinctrl_dt_subnode_to_map(np, map, &reserved_maps, 306 ret = tegra_pinctrl_dt_subnode_to_map(pctldev->dev, np, map,
286 num_maps); 307 &reserved_maps, num_maps);
287 if (ret < 0) { 308 if (ret < 0) {
288 tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps); 309 tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps);
289 return ret; 310 return ret;
@@ -342,14 +363,14 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
342 363
343 g = &pmx->soc->groups[group]; 364 g = &pmx->soc->groups[group];
344 365
345 if (g->mux_reg < 0) 366 if (WARN_ON(g->mux_reg < 0))
346 return -EINVAL; 367 return -EINVAL;
347 368
348 for (i = 0; i < ARRAY_SIZE(g->funcs); i++) { 369 for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
349 if (g->funcs[i] == function) 370 if (g->funcs[i] == function)
350 break; 371 break;
351 } 372 }
352 if (i == ARRAY_SIZE(g->funcs)) 373 if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
353 return -EINVAL; 374 return -EINVAL;
354 375
355 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); 376 val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
@@ -369,7 +390,7 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
369 390
370 g = &pmx->soc->groups[group]; 391 g = &pmx->soc->groups[group];
371 392
372 if (g->mux_reg < 0) 393 if (WARN_ON(g->mux_reg < 0))
373 return; 394 return;
374 395
375 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); 396 val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
@@ -490,12 +511,14 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
490static int tegra_pinconf_get(struct pinctrl_dev *pctldev, 511static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
491 unsigned pin, unsigned long *config) 512 unsigned pin, unsigned long *config)
492{ 513{
514 dev_err(pctldev->dev, "pin_config_get op not supported\n");
493 return -ENOTSUPP; 515 return -ENOTSUPP;
494} 516}
495 517
496static int tegra_pinconf_set(struct pinctrl_dev *pctldev, 518static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
497 unsigned pin, unsigned long config) 519 unsigned pin, unsigned long config)
498{ 520{
521 dev_err(pctldev->dev, "pin_config_set op not supported\n");
499 return -ENOTSUPP; 522 return -ENOTSUPP;
500} 523}
501 524
@@ -550,8 +573,10 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
550 573
551 /* LOCK can't be cleared */ 574 /* LOCK can't be cleared */
552 if (param == TEGRA_PINCONF_PARAM_LOCK) { 575 if (param == TEGRA_PINCONF_PARAM_LOCK) {
553 if ((val & BIT(bit)) && !arg) 576 if ((val & BIT(bit)) && !arg) {
577 dev_err(pctldev->dev, "LOCK bit cannot be cleared\n");
554 return -EINVAL; 578 return -EINVAL;
579 }
555 } 580 }
556 581
557 /* Special-case Boolean values; allow any non-zero as true */ 582 /* Special-case Boolean values; allow any non-zero as true */
@@ -560,8 +585,12 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
560 585
561 /* Range-check user-supplied value */ 586 /* Range-check user-supplied value */
562 mask = (1 << width) - 1; 587 mask = (1 << width) - 1;
563 if (arg & ~mask) 588 if (arg & ~mask) {
589 dev_err(pctldev->dev,
590 "config %lx: %x too big for %d bit register\n",
591 config, arg, width);
564 return -EINVAL; 592 return -EINVAL;
593 }
565 594
566 /* Update register */ 595 /* Update register */
567 val &= ~(mask << bit); 596 val &= ~(mask << bit);