aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sh-pfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/sh-pfc')
-rw-r--r--drivers/pinctrl/sh-pfc/core.c50
-rw-r--r--drivers/pinctrl/sh-pfc/core.h3
-rw-r--r--drivers/pinctrl/sh-pfc/gpio.c14
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c48
-rw-r--r--drivers/pinctrl/sh-pfc/sh_pfc.h5
5 files changed, 12 insertions, 108 deletions
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
index 19735012ffb4..e2864ec900f4 100644
--- a/drivers/pinctrl/sh-pfc/core.c
+++ b/drivers/pinctrl/sh-pfc/core.c
@@ -163,22 +163,6 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
163 } 163 }
164} 164}
165 165
166static int sh_pfc_read_config_reg(struct sh_pfc *pfc,
167 struct pinmux_cfg_reg *crp,
168 unsigned long field)
169{
170 void __iomem *mapped_reg;
171 unsigned long mask, pos;
172
173 sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
174
175 pr_debug("read_reg: addr = %lx, field = %ld, "
176 "r_width = %ld, f_width = %ld\n",
177 crp->reg, field, crp->reg_width, crp->field_width);
178
179 return (sh_pfc_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
180}
181
182static void sh_pfc_write_config_reg(struct sh_pfc *pfc, 166static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
183 struct pinmux_cfg_reg *crp, 167 struct pinmux_cfg_reg *crp,
184 unsigned long field, unsigned long value) 168 unsigned long field, unsigned long value)
@@ -209,7 +193,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
209 193
210static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, 194static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id,
211 struct pinmux_cfg_reg **crp, int *fieldp, 195 struct pinmux_cfg_reg **crp, int *fieldp,
212 int *valuep, unsigned long **cntp) 196 int *valuep)
213{ 197{
214 struct pinmux_cfg_reg *config_reg; 198 struct pinmux_cfg_reg *config_reg;
215 unsigned long r_width, f_width, curr_width, ncomb; 199 unsigned long r_width, f_width, curr_width, ncomb;
@@ -239,7 +223,6 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id,
239 *crp = config_reg; 223 *crp = config_reg;
240 *fieldp = m; 224 *fieldp = m;
241 *valuep = n; 225 *valuep = n;
242 *cntp = &config_reg->cnt[m];
243 return 0; 226 return 0;
244 } 227 }
245 } 228 }
@@ -274,14 +257,12 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos,
274 return -1; 257 return -1;
275} 258}
276 259
277int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, 260int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
278 int cfg_mode)
279{ 261{
280 struct pinmux_cfg_reg *cr = NULL; 262 struct pinmux_cfg_reg *cr = NULL;
281 pinmux_enum_t enum_id; 263 pinmux_enum_t enum_id;
282 struct pinmux_range *range; 264 struct pinmux_range *range;
283 int in_range, pos, field, value; 265 int in_range, pos, field, value;
284 unsigned long *cntp;
285 266
286 switch (pinmux_type) { 267 switch (pinmux_type) {
287 268
@@ -306,7 +287,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type,
306 break; 287 break;
307 288
308 default: 289 default:
309 goto out_err; 290 return -1;
310 } 291 }
311 292
312 pos = 0; 293 pos = 0;
@@ -316,7 +297,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type,
316 while (1) { 297 while (1) {
317 pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); 298 pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
318 if (pos <= 0) 299 if (pos <= 0)
319 goto out_err; 300 return -1;
320 301
321 if (!enum_id) 302 if (!enum_id)
322 break; 303 break;
@@ -360,30 +341,13 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type,
360 continue; 341 continue;
361 342
362 if (sh_pfc_get_config_reg(pfc, enum_id, &cr, 343 if (sh_pfc_get_config_reg(pfc, enum_id, &cr,
363 &field, &value, &cntp) != 0) 344 &field, &value) != 0)
364 goto out_err; 345 return -1;
365
366 switch (cfg_mode) {
367 case GPIO_CFG_DRYRUN:
368 if (!*cntp ||
369 (sh_pfc_read_config_reg(pfc, cr, field) != value))
370 continue;
371 break;
372
373 case GPIO_CFG_REQ:
374 sh_pfc_write_config_reg(pfc, cr, field, value);
375 *cntp = *cntp + 1;
376 break;
377 346
378 case GPIO_CFG_FREE: 347 sh_pfc_write_config_reg(pfc, cr, field, value);
379 *cntp = *cntp - 1;
380 break;
381 }
382 } 348 }
383 349
384 return 0; 350 return 0;
385 out_err:
386 return -1;
387} 351}
388 352
389static int sh_pfc_probe(struct platform_device *pdev) 353static int sh_pfc_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h
index 6db54aa083f2..7b2b4f0accfc 100644
--- a/drivers/pinctrl/sh-pfc/core.h
+++ b/drivers/pinctrl/sh-pfc/core.h
@@ -52,8 +52,7 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
52 unsigned long data); 52 unsigned long data);
53 53
54int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); 54int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
55int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, 55int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
56 int cfg_mode);
57 56
58extern struct sh_pfc_soc_info r8a7740_pinmux_info; 57extern struct sh_pfc_soc_info r8a7740_pinmux_info;
59extern struct sh_pfc_soc_info r8a7779_pinmux_info; 58extern struct sh_pfc_soc_info r8a7779_pinmux_info;
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index ce074b22f426..761a0dad0450 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -285,10 +285,7 @@ static int gpio_function_request(struct gpio_chip *gc, unsigned offset)
285 285
286 spin_lock_irqsave(&pfc->lock, flags); 286 spin_lock_irqsave(&pfc->lock, flags);
287 287
288 if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_DRYRUN)) 288 if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION))
289 goto done;
290
291 if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_REQ))
292 goto done; 289 goto done;
293 290
294 ret = 0; 291 ret = 0;
@@ -300,15 +297,6 @@ done:
300 297
301static void gpio_function_free(struct gpio_chip *gc, unsigned offset) 298static void gpio_function_free(struct gpio_chip *gc, unsigned offset)
302{ 299{
303 struct sh_pfc *pfc = gpio_to_pfc(gc);
304 unsigned int mark = pfc->info->func_gpios[offset].enum_id;
305 unsigned long flags;
306
307 spin_lock_irqsave(&pfc->lock, flags);
308
309 sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE);
310
311 spin_unlock_irqrestore(&pfc->lock, flags);
312} 300}
313 301
314static int gpio_function_setup(struct sh_pfc_chip *chip) 302static int gpio_function_setup(struct sh_pfc_chip *chip)
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
index ef5cf5d8298f..9978ad1818fd 100644
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -119,12 +119,7 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector,
119 spin_lock_irqsave(&pfc->lock, flags); 119 spin_lock_irqsave(&pfc->lock, flags);
120 120
121 for (i = 0; i < grp->nr_pins; ++i) { 121 for (i = 0; i < grp->nr_pins; ++i) {
122 if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, 122 if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION))
123 GPIO_CFG_DRYRUN))
124 goto done;
125
126 if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION,
127 GPIO_CFG_REQ))
128 goto done; 123 goto done;
129 } 124 }
130 125
@@ -138,19 +133,6 @@ done:
138static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, 133static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector,
139 unsigned group) 134 unsigned group)
140{ 135{
141 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
142 struct sh_pfc *pfc = pmx->pfc;
143 const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
144 unsigned long flags;
145 unsigned int i;
146
147 spin_lock_irqsave(&pfc->lock, flags);
148
149 for (i = 0; i < grp->nr_pins; ++i)
150 sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION,
151 GPIO_CFG_FREE);
152
153 spin_unlock_irqrestore(&pfc->lock, flags);
154} 136}
155 137
156static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, 138static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset,
@@ -166,32 +148,18 @@ static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset,
166 148
167 spin_lock_irqsave(&pfc->lock, flags); 149 spin_lock_irqsave(&pfc->lock, flags);
168 150
169 /*
170 * See if the present config needs to first be de-configured.
171 */
172 switch (cfg->type) { 151 switch (cfg->type) {
173 case PINMUX_TYPE_GPIO: 152 case PINMUX_TYPE_GPIO:
174 break;
175 case PINMUX_TYPE_OUTPUT: 153 case PINMUX_TYPE_OUTPUT:
176 case PINMUX_TYPE_INPUT: 154 case PINMUX_TYPE_INPUT:
177 case PINMUX_TYPE_INPUT_PULLUP: 155 case PINMUX_TYPE_INPUT_PULLUP:
178 case PINMUX_TYPE_INPUT_PULLDOWN: 156 case PINMUX_TYPE_INPUT_PULLDOWN:
179 sh_pfc_config_mux(pfc, mark, cfg->type, GPIO_CFG_FREE);
180 break; 157 break;
181 default: 158 default:
182 goto err; 159 goto err;
183 } 160 }
184 161
185 /* 162 if (sh_pfc_config_mux(pfc, mark, new_type) != 0)
186 * Dry run
187 */
188 if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_DRYRUN) != 0)
189 goto err;
190
191 /*
192 * Request
193 */
194 if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_REQ) != 0)
195 goto err; 163 goto err;
196 164
197 cfg->type = new_type; 165 cfg->type = new_type;
@@ -241,18 +209,6 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
241 struct pinctrl_gpio_range *range, 209 struct pinctrl_gpio_range *range,
242 unsigned offset) 210 unsigned offset)
243{ 211{
244 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
245 struct sh_pfc *pfc = pmx->pfc;
246 int idx = sh_pfc_get_pin_index(pfc, offset);
247 struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
248 struct sh_pfc_pin *pin = &pfc->info->pins[idx];
249 unsigned long flags;
250
251 spin_lock_irqsave(&pfc->lock, flags);
252
253 sh_pfc_config_mux(pfc, pin->enum_id, cfg->type, GPIO_CFG_FREE);
254
255 spin_unlock_irqrestore(&pfc->lock, flags);
256} 212}
257 213
258static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, 214static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
index 6a4a62fd39ec..19da3b7c57f1 100644
--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
+++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
@@ -84,19 +84,16 @@ struct pinmux_func {
84 84
85struct pinmux_cfg_reg { 85struct pinmux_cfg_reg {
86 unsigned long reg, reg_width, field_width; 86 unsigned long reg, reg_width, field_width;
87 unsigned long *cnt;
88 pinmux_enum_t *enum_ids; 87 pinmux_enum_t *enum_ids;
89 unsigned long *var_field_width; 88 unsigned long *var_field_width;
90}; 89};
91 90
92#define PINMUX_CFG_REG(name, r, r_width, f_width) \ 91#define PINMUX_CFG_REG(name, r, r_width, f_width) \
93 .reg = r, .reg_width = r_width, .field_width = f_width, \ 92 .reg = r, .reg_width = r_width, .field_width = f_width, \
94 .cnt = (unsigned long [r_width / f_width]) {}, \
95 .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) 93 .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)])
96 94
97#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \ 95#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
98 .reg = r, .reg_width = r_width, \ 96 .reg = r, .reg_width = r_width, \
99 .cnt = (unsigned long [r_width]) {}, \
100 .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \ 97 .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
101 .enum_ids = (pinmux_enum_t []) 98 .enum_ids = (pinmux_enum_t [])
102 99
@@ -155,7 +152,7 @@ struct sh_pfc_soc_info {
155 unsigned long unlock_reg; 152 unsigned long unlock_reg;
156}; 153};
157 154
158enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; 155enum { GPIO_CFG_REQ, GPIO_CFG_FREE };
159 156
160/* helper macro for port */ 157/* helper macro for port */
161#define PORT_1(fn, pfx, sfx) fn(pfx, sfx) 158#define PORT_1(fn, pfx, sfx) fn(pfx, sfx)