aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh/pfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sh/pfc.c')
-rw-r--r--drivers/sh/pfc.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
index 5481d19518f9..f975f4a33439 100644
--- a/drivers/sh/pfc.c
+++ b/drivers/sh/pfc.c
@@ -174,10 +174,19 @@ static void config_reg_helper(struct pinmux_info *gpioc,
174 unsigned long *maskp, 174 unsigned long *maskp,
175 unsigned long *posp) 175 unsigned long *posp)
176{ 176{
177 int k;
178
177 *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg); 179 *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
178 180
179 *maskp = (1 << crp->field_width) - 1; 181 if (crp->field_width) {
180 *posp = crp->reg_width - ((in_pos + 1) * crp->field_width); 182 *maskp = (1 << crp->field_width) - 1;
183 *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
184 } else {
185 *maskp = (1 << crp->var_field_width[in_pos]) - 1;
186 *posp = crp->reg_width;
187 for (k = 0; k <= in_pos; k++)
188 *posp -= crp->var_field_width[k];
189 }
181} 190}
182 191
183static int read_config_reg(struct pinmux_info *gpioc, 192static int read_config_reg(struct pinmux_info *gpioc,
@@ -303,8 +312,8 @@ static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
303 unsigned long **cntp) 312 unsigned long **cntp)
304{ 313{
305 struct pinmux_cfg_reg *config_reg; 314 struct pinmux_cfg_reg *config_reg;
306 unsigned long r_width, f_width; 315 unsigned long r_width, f_width, curr_width, ncomb;
307 int k, n; 316 int k, m, n, pos, bit_pos;
308 317
309 k = 0; 318 k = 0;
310 while (1) { 319 while (1) {
@@ -315,14 +324,27 @@ static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
315 324
316 if (!r_width) 325 if (!r_width)
317 break; 326 break;
318 for (n = 0; n < (r_width / f_width) * (1 << f_width); n++) { 327
319 if (config_reg->enum_ids[n] == enum_id) { 328 pos = 0;
320 *crp = config_reg; 329 m = 0;
321 *fieldp = n / (1 << f_width); 330 for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
322 *valuep = n % (1 << f_width); 331 if (f_width)
323 *cntp = &config_reg->cnt[n / (1 << f_width)]; 332 curr_width = f_width;
324 return 0; 333 else
334 curr_width = config_reg->var_field_width[m];
335
336 ncomb = 1 << curr_width;
337 for (n = 0; n < ncomb; n++) {
338 if (config_reg->enum_ids[pos + n] == enum_id) {
339 *crp = config_reg;
340 *fieldp = m;
341 *valuep = n;
342 *cntp = &config_reg->cnt[m];
343 return 0;
344 }
325 } 345 }
346 pos += ncomb;
347 m++;
326 } 348 }
327 k++; 349 k++;
328 } 350 }