diff options
Diffstat (limited to 'drivers/pinctrl/sh-pfc')
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.c | 50 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.h | 3 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/gpio.c | 14 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 48 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/sh_pfc.h | 5 |
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 | ||
166 | static 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 | |||
182 | static void sh_pfc_write_config_reg(struct sh_pfc *pfc, | 166 | static 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 | ||
210 | static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, | 194 | static 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 | ||
277 | int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, | 260 | int 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 | ||
389 | static int sh_pfc_probe(struct platform_device *pdev) | 353 | static 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 | ||
54 | int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); | 54 | int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); |
55 | int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, | 55 | int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); |
56 | int cfg_mode); | ||
57 | 56 | ||
58 | extern struct sh_pfc_soc_info r8a7740_pinmux_info; | 57 | extern struct sh_pfc_soc_info r8a7740_pinmux_info; |
59 | extern struct sh_pfc_soc_info r8a7779_pinmux_info; | 58 | extern 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 | ||
301 | static void gpio_function_free(struct gpio_chip *gc, unsigned offset) | 298 | static 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 | ||
314 | static int gpio_function_setup(struct sh_pfc_chip *chip) | 302 | static 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: | |||
138 | static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, | 133 | static 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 | ||
156 | static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, | 138 | static 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 | ||
258 | static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, | 214 | static 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 | ||
85 | struct pinmux_cfg_reg { | 85 | struct 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 | ||
158 | enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; | 155 | enum { 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) |