aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorGiuseppe Cavallaro <peppe.cavallaro@st.com>2014-03-12 04:50:06 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-03-12 10:15:34 -0400
commit4e6a609fb791ba8f01e624000086217a558a2a10 (patch)
treea81f23670cddcd49e587ed53c9c749a838a0bcb1 /drivers/pinctrl
parent051a58b4622f0e1b732acb750097c64bc00ddb93 (diff)
pinctrl: st: Enhance the controller to manage unavailable registers
This patch adds a new logic inside the st pinctrl to manage an unsupported scenario: some sysconfig are not available! This is the case of STiH407 where, although documented, the following registers from SYSCFG_FLASH have been removed from the SoC. SYSTEM_CONFIG3040 Output Enable pad control for all PIO Alternate Functions and SYSTEM_ CONFIG3050 Pull Up pad control for all PIO Alternate Functions Without managing this condition an imprecise external abort will be detect. To do this the patch also reviews the st_parse_syscfgs and other routines to manipulate the registers only if actually available. In any case, for example the st_parse_syscfgs detected an error condition but no action was made in the st_pctl_probe_dt. Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Acked-by: Srinivas Kandagatla <srinivas.kandagatla@st.com> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: Maxime Coquelin <maxime.coquelin@st.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-st.c104
1 files changed, 61 insertions, 43 deletions
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index 9fb66aa796aa..7073eaf7522a 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -410,25 +410,29 @@ static void st_pinconf_set_config(struct st_pio_control *pc,
410 unsigned int oe_value, pu_value, od_value; 410 unsigned int oe_value, pu_value, od_value;
411 unsigned long mask = BIT(pin); 411 unsigned long mask = BIT(pin);
412 412
413 regmap_field_read(output_enable, &oe_value); 413 if (output_enable) {
414 regmap_field_read(pull_up, &pu_value); 414 regmap_field_read(output_enable, &oe_value);
415 regmap_field_read(open_drain, &od_value); 415 oe_value &= ~mask;
416 416 if (config & ST_PINCONF_OE)
417 /* Clear old values */ 417 oe_value |= mask;
418 oe_value &= ~mask; 418 regmap_field_write(output_enable, oe_value);
419 pu_value &= ~mask; 419 }
420 od_value &= ~mask; 420
421 421 if (pull_up) {
422 if (config & ST_PINCONF_OE) 422 regmap_field_read(pull_up, &pu_value);
423 oe_value |= mask; 423 pu_value &= ~mask;
424 if (config & ST_PINCONF_PU) 424 if (config & ST_PINCONF_PU)
425 pu_value |= mask; 425 pu_value |= mask;
426 if (config & ST_PINCONF_OD) 426 regmap_field_write(pull_up, pu_value);
427 od_value |= mask; 427 }
428 428
429 regmap_field_write(output_enable, oe_value); 429 if (open_drain) {
430 regmap_field_write(pull_up, pu_value); 430 regmap_field_read(open_drain, &od_value);
431 regmap_field_write(open_drain, od_value); 431 od_value &= ~mask;
432 if (config & ST_PINCONF_OD)
433 od_value |= mask;
434 regmap_field_write(open_drain, od_value);
435 }
432} 436}
433 437
434static void st_pctl_set_function(struct st_pio_control *pc, 438static void st_pctl_set_function(struct st_pio_control *pc,
@@ -439,6 +443,9 @@ static void st_pctl_set_function(struct st_pio_control *pc,
439 int pin = st_gpio_pin(pin_id); 443 int pin = st_gpio_pin(pin_id);
440 int offset = pin * 4; 444 int offset = pin * 4;
441 445
446 if (!alt)
447 return;
448
442 regmap_field_read(alt, &val); 449 regmap_field_read(alt, &val);
443 val &= ~(0xf << offset); 450 val &= ~(0xf << offset);
444 val |= function << offset; 451 val |= function << offset;
@@ -576,17 +583,23 @@ static void st_pinconf_get_direction(struct st_pio_control *pc,
576{ 583{
577 unsigned int oe_value, pu_value, od_value; 584 unsigned int oe_value, pu_value, od_value;
578 585
579 regmap_field_read(pc->oe, &oe_value); 586 if (pc->oe) {
580 regmap_field_read(pc->pu, &pu_value); 587 regmap_field_read(pc->oe, &oe_value);
581 regmap_field_read(pc->od, &od_value); 588 if (oe_value & BIT(pin))
589 ST_PINCONF_PACK_OE(*config);
590 }
582 591
583 if (oe_value & BIT(pin)) 592 if (pc->pu) {
584 ST_PINCONF_PACK_OE(*config); 593 regmap_field_read(pc->pu, &pu_value);
585 if (pu_value & BIT(pin)) 594 if (pu_value & BIT(pin))
586 ST_PINCONF_PACK_PU(*config); 595 ST_PINCONF_PACK_PU(*config);
587 if (od_value & BIT(pin)) 596 }
588 ST_PINCONF_PACK_OD(*config);
589 597
598 if (pc->od) {
599 regmap_field_read(pc->od, &od_value);
600 if (od_value & BIT(pin))
601 ST_PINCONF_PACK_OD(*config);
602 }
590} 603}
591 604
592static int st_pinconf_get_retime_packed(struct st_pinctrl *info, 605static int st_pinconf_get_retime_packed(struct st_pinctrl *info,
@@ -1105,8 +1118,21 @@ static int st_pctl_dt_setup_retime(struct st_pinctrl *info,
1105 return -EINVAL; 1118 return -EINVAL;
1106} 1119}
1107 1120
1108static int st_parse_syscfgs(struct st_pinctrl *info, 1121
1109 int bank, struct device_node *np) 1122static struct regmap_field *st_pc_get_value(struct device *dev,
1123 struct regmap *regmap, int bank,
1124 int data, int lsb, int msb)
1125{
1126 struct reg_field reg = REG_FIELD((data + bank) * 4, lsb, msb);
1127
1128 if (data < 0)
1129 return NULL;
1130
1131 return devm_regmap_field_alloc(dev, regmap, reg);
1132}
1133
1134static void st_parse_syscfgs(struct st_pinctrl *info, int bank,
1135 struct device_node *np)
1110{ 1136{
1111 const struct st_pctl_data *data = info->data; 1137 const struct st_pctl_data *data = info->data;
1112 /** 1138 /**
@@ -1116,29 +1142,21 @@ static int st_parse_syscfgs(struct st_pinctrl *info,
1116 */ 1142 */
1117 int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK; 1143 int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK;
1118 int msb = lsb + ST_GPIO_PINS_PER_BANK - 1; 1144 int msb = lsb + ST_GPIO_PINS_PER_BANK - 1;
1119 struct reg_field alt_reg = REG_FIELD((data->alt + bank) * 4, 0, 31);
1120 struct reg_field oe_reg = REG_FIELD((data->oe + bank/4) * 4, lsb, msb);
1121 struct reg_field pu_reg = REG_FIELD((data->pu + bank/4) * 4, lsb, msb);
1122 struct reg_field od_reg = REG_FIELD((data->od + bank/4) * 4, lsb, msb);
1123 struct st_pio_control *pc = &info->banks[bank].pc; 1145 struct st_pio_control *pc = &info->banks[bank].pc;
1124 struct device *dev = info->dev; 1146 struct device *dev = info->dev;
1125 struct regmap *regmap = info->regmap; 1147 struct regmap *regmap = info->regmap;
1126 1148
1127 pc->alt = devm_regmap_field_alloc(dev, regmap, alt_reg); 1149 pc->alt = st_pc_get_value(dev, regmap, bank, data->alt, 0, 31);
1128 pc->oe = devm_regmap_field_alloc(dev, regmap, oe_reg); 1150 pc->oe = st_pc_get_value(dev, regmap, bank/4, data->oe, lsb, msb);
1129 pc->pu = devm_regmap_field_alloc(dev, regmap, pu_reg); 1151 pc->pu = st_pc_get_value(dev, regmap, bank/4, data->pu, lsb, msb);
1130 pc->od = devm_regmap_field_alloc(dev, regmap, od_reg); 1152 pc->od = st_pc_get_value(dev, regmap, bank/4, data->od, lsb, msb);
1131
1132 if (IS_ERR(pc->alt) || IS_ERR(pc->oe) ||
1133 IS_ERR(pc->pu) || IS_ERR(pc->od))
1134 return -EINVAL;
1135 1153
1136 /* retime avaiable for all pins by default */ 1154 /* retime avaiable for all pins by default */
1137 pc->rt_pin_mask = 0xff; 1155 pc->rt_pin_mask = 0xff;
1138 of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask); 1156 of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask);
1139 st_pctl_dt_setup_retime(info, bank, pc); 1157 st_pctl_dt_setup_retime(info, bank, pc);
1140 1158
1141 return 0; 1159 return;
1142} 1160}
1143 1161
1144/* 1162/*