.. | .. |
---|
42 | 42 | * struct pcs_func_vals - mux function register offset and value pair |
---|
43 | 43 | * @reg: register virtual address |
---|
44 | 44 | * @val: register value |
---|
| 45 | + * @mask: mask |
---|
45 | 46 | */ |
---|
46 | 47 | struct pcs_func_vals { |
---|
47 | 48 | void __iomem *reg; |
---|
.. | .. |
---|
83 | 84 | * @nvals: number of entries in vals array |
---|
84 | 85 | * @pgnames: array of pingroup names the function uses |
---|
85 | 86 | * @npgnames: number of pingroup names the function uses |
---|
| 87 | + * @conf: array of pin configurations |
---|
| 88 | + * @nconfs: number of pin configurations available |
---|
86 | 89 | * @node: list node |
---|
87 | 90 | */ |
---|
88 | 91 | struct pcs_function { |
---|
.. | .. |
---|
267 | 270 | writel(val, reg); |
---|
268 | 271 | } |
---|
269 | 272 | |
---|
| 273 | +static unsigned int pcs_pin_reg_offset_get(struct pcs_device *pcs, |
---|
| 274 | + unsigned int pin) |
---|
| 275 | +{ |
---|
| 276 | + unsigned int mux_bytes = pcs->width / BITS_PER_BYTE; |
---|
| 277 | + |
---|
| 278 | + if (pcs->bits_per_mux) { |
---|
| 279 | + unsigned int pin_offset_bytes; |
---|
| 280 | + |
---|
| 281 | + pin_offset_bytes = (pcs->bits_per_pin * pin) / BITS_PER_BYTE; |
---|
| 282 | + return (pin_offset_bytes / mux_bytes) * mux_bytes; |
---|
| 283 | + } |
---|
| 284 | + |
---|
| 285 | + return pin * mux_bytes; |
---|
| 286 | +} |
---|
| 287 | + |
---|
| 288 | +static unsigned int pcs_pin_shift_reg_get(struct pcs_device *pcs, |
---|
| 289 | + unsigned int pin) |
---|
| 290 | +{ |
---|
| 291 | + return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin; |
---|
| 292 | +} |
---|
| 293 | + |
---|
270 | 294 | static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, |
---|
271 | 295 | struct seq_file *s, |
---|
272 | 296 | unsigned pin) |
---|
273 | 297 | { |
---|
274 | 298 | struct pcs_device *pcs; |
---|
275 | | - unsigned val, mux_bytes; |
---|
| 299 | + unsigned int val; |
---|
276 | 300 | unsigned long offset; |
---|
277 | 301 | size_t pa; |
---|
278 | 302 | |
---|
279 | 303 | pcs = pinctrl_dev_get_drvdata(pctldev); |
---|
280 | 304 | |
---|
281 | | - mux_bytes = pcs->width / BITS_PER_BYTE; |
---|
282 | | - offset = pin * mux_bytes; |
---|
| 305 | + offset = pcs_pin_reg_offset_get(pcs, pin); |
---|
283 | 306 | val = pcs->read(pcs->base + offset); |
---|
| 307 | + |
---|
| 308 | + if (pcs->bits_per_mux) |
---|
| 309 | + val &= pcs->fmask << pcs_pin_shift_reg_get(pcs, pin); |
---|
| 310 | + |
---|
284 | 311 | pa = pcs->res->start + offset; |
---|
285 | 312 | |
---|
286 | 313 | seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME); |
---|
.. | .. |
---|
345 | 372 | if (!pcs->fmask) |
---|
346 | 373 | return 0; |
---|
347 | 374 | function = pinmux_generic_get_function(pctldev, fselector); |
---|
| 375 | + if (!function) |
---|
| 376 | + return -EINVAL; |
---|
348 | 377 | func = function->data; |
---|
349 | 378 | if (!func) |
---|
350 | 379 | return -EINVAL; |
---|
.. | .. |
---|
381 | 410 | struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); |
---|
382 | 411 | struct pcs_gpiofunc_range *frange = NULL; |
---|
383 | 412 | struct list_head *pos, *tmp; |
---|
384 | | - int mux_bytes = 0; |
---|
385 | 413 | unsigned data; |
---|
386 | 414 | |
---|
387 | 415 | /* If function mask is null, return directly. */ |
---|
.. | .. |
---|
389 | 417 | return -ENOTSUPP; |
---|
390 | 418 | |
---|
391 | 419 | list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { |
---|
| 420 | + u32 offset; |
---|
| 421 | + |
---|
392 | 422 | frange = list_entry(pos, struct pcs_gpiofunc_range, node); |
---|
393 | 423 | if (pin >= frange->offset + frange->npins |
---|
394 | 424 | || pin < frange->offset) |
---|
395 | 425 | continue; |
---|
396 | | - mux_bytes = pcs->width / BITS_PER_BYTE; |
---|
| 426 | + |
---|
| 427 | + offset = pcs_pin_reg_offset_get(pcs, pin); |
---|
397 | 428 | |
---|
398 | 429 | if (pcs->bits_per_mux) { |
---|
399 | | - int byte_num, offset, pin_shift; |
---|
400 | | - |
---|
401 | | - byte_num = (pcs->bits_per_pin * pin) / BITS_PER_BYTE; |
---|
402 | | - offset = (byte_num / mux_bytes) * mux_bytes; |
---|
403 | | - pin_shift = pin % (pcs->width / pcs->bits_per_pin) * |
---|
404 | | - pcs->bits_per_pin; |
---|
| 430 | + int pin_shift = pcs_pin_shift_reg_get(pcs, pin); |
---|
405 | 431 | |
---|
406 | 432 | data = pcs->read(pcs->base + offset); |
---|
407 | 433 | data &= ~(pcs->fmask << pin_shift); |
---|
408 | 434 | data |= frange->gpiofunc << pin_shift; |
---|
409 | 435 | pcs->write(data, pcs->base + offset); |
---|
410 | 436 | } else { |
---|
411 | | - data = pcs->read(pcs->base + pin * mux_bytes); |
---|
| 437 | + data = pcs->read(pcs->base + offset); |
---|
412 | 438 | data &= ~pcs->fmask; |
---|
413 | 439 | data |= frange->gpiofunc; |
---|
414 | | - pcs->write(data, pcs->base + pin * mux_bytes); |
---|
| 440 | + pcs->write(data, pcs->base + offset); |
---|
415 | 441 | } |
---|
416 | 442 | break; |
---|
417 | 443 | } |
---|
.. | .. |
---|
560 | 586 | case PIN_CONFIG_BIAS_PULL_UP: |
---|
561 | 587 | if (arg) |
---|
562 | 588 | pcs_pinconf_clear_bias(pctldev, pin); |
---|
563 | | - /* fall through */ |
---|
| 589 | + fallthrough; |
---|
564 | 590 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
---|
565 | 591 | data &= ~func->conf[i].mask; |
---|
566 | 592 | if (arg) |
---|
.. | .. |
---|
654 | 680 | * @pcs: pcs driver instance |
---|
655 | 681 | * @offset: register offset from base |
---|
656 | 682 | */ |
---|
657 | | -static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, |
---|
658 | | - unsigned pin_pos) |
---|
| 683 | +static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset) |
---|
659 | 684 | { |
---|
660 | 685 | struct pcs_soc_data *pcs_soc = &pcs->socdata; |
---|
661 | 686 | struct pinctrl_pin_desc *pin; |
---|
.. | .. |
---|
703 | 728 | |
---|
704 | 729 | mux_bytes = pcs->width / BITS_PER_BYTE; |
---|
705 | 730 | |
---|
706 | | - if (pcs->bits_per_mux) { |
---|
| 731 | + if (pcs->bits_per_mux && pcs->fmask) { |
---|
707 | 732 | pcs->bits_per_pin = fls(pcs->fmask); |
---|
708 | 733 | nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; |
---|
709 | 734 | num_pins_in_register = pcs->width / pcs->bits_per_pin; |
---|
.. | .. |
---|
724 | 749 | for (i = 0; i < pcs->desc.npins; i++) { |
---|
725 | 750 | unsigned offset; |
---|
726 | 751 | int res; |
---|
727 | | - int byte_num; |
---|
728 | | - int pin_pos = 0; |
---|
729 | 752 | |
---|
730 | | - if (pcs->bits_per_mux) { |
---|
731 | | - byte_num = (pcs->bits_per_pin * i) / BITS_PER_BYTE; |
---|
732 | | - offset = (byte_num / mux_bytes) * mux_bytes; |
---|
733 | | - pin_pos = i % num_pins_in_register; |
---|
734 | | - } else { |
---|
735 | | - offset = i * mux_bytes; |
---|
736 | | - } |
---|
737 | | - res = pcs_add_pin(pcs, offset, pin_pos); |
---|
| 753 | + offset = pcs_pin_reg_offset_get(pcs, i); |
---|
| 754 | + res = pcs_add_pin(pcs, offset); |
---|
738 | 755 | if (res < 0) { |
---|
739 | 756 | dev_err(pcs->dev, "error adding pins: %i\n", res); |
---|
740 | 757 | return res; |
---|
.. | .. |
---|
958 | 975 | } |
---|
959 | 976 | |
---|
960 | 977 | /** |
---|
961 | | - * smux_parse_one_pinctrl_entry() - parses a device tree mux entry |
---|
962 | | - * @pctldev: pin controller device |
---|
| 978 | + * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry |
---|
963 | 979 | * @pcs: pinctrl driver instance |
---|
964 | 980 | * @np: device node of the mux entry |
---|
965 | 981 | * @map: map entry |
---|
.. | .. |
---|
1011 | 1027 | if (res) |
---|
1012 | 1028 | return res; |
---|
1013 | 1029 | |
---|
1014 | | - if (pinctrl_spec.args_count < 2) { |
---|
| 1030 | + if (pinctrl_spec.args_count < 2 || pinctrl_spec.args_count > 3) { |
---|
1015 | 1031 | dev_err(pcs->dev, "invalid args_count for spec: %i\n", |
---|
1016 | 1032 | pinctrl_spec.args_count); |
---|
1017 | 1033 | break; |
---|
1018 | 1034 | } |
---|
1019 | 1035 | |
---|
1020 | | - /* Index plus one value cell */ |
---|
1021 | 1036 | offset = pinctrl_spec.args[0]; |
---|
1022 | 1037 | vals[found].reg = pcs->base + offset; |
---|
1023 | | - vals[found].val = pinctrl_spec.args[1]; |
---|
1024 | 1038 | |
---|
1025 | | - dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n", |
---|
1026 | | - pinctrl_spec.np->name, offset, pinctrl_spec.args[1]); |
---|
| 1039 | + switch (pinctrl_spec.args_count) { |
---|
| 1040 | + case 2: |
---|
| 1041 | + vals[found].val = pinctrl_spec.args[1]; |
---|
| 1042 | + break; |
---|
| 1043 | + case 3: |
---|
| 1044 | + vals[found].val = (pinctrl_spec.args[1] | pinctrl_spec.args[2]); |
---|
| 1045 | + break; |
---|
| 1046 | + } |
---|
| 1047 | + |
---|
| 1048 | + dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n", |
---|
| 1049 | + pinctrl_spec.np, offset, vals[found].val); |
---|
1027 | 1050 | |
---|
1028 | 1051 | pin = pcs_get_pin_by_offset(pcs, offset); |
---|
1029 | 1052 | if (pin < 0) { |
---|
1030 | 1053 | dev_err(pcs->dev, |
---|
1031 | | - "could not add functions for %s %ux\n", |
---|
1032 | | - np->name, offset); |
---|
| 1054 | + "could not add functions for %pOFn %ux\n", |
---|
| 1055 | + np, offset); |
---|
1033 | 1056 | break; |
---|
1034 | 1057 | } |
---|
1035 | 1058 | pins[found++] = pin; |
---|
.. | .. |
---|
1138 | 1161 | val = pinctrl_spec.args[1]; |
---|
1139 | 1162 | mask = pinctrl_spec.args[2]; |
---|
1140 | 1163 | |
---|
1141 | | - dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n", |
---|
1142 | | - pinctrl_spec.np->name, offset, val, mask); |
---|
| 1164 | + dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x mask: 0x%x\n", |
---|
| 1165 | + pinctrl_spec.np, offset, val, mask); |
---|
1143 | 1166 | |
---|
1144 | 1167 | /* Parse pins in each row from LSB */ |
---|
1145 | 1168 | while (mask) { |
---|
.. | .. |
---|
1151 | 1174 | |
---|
1152 | 1175 | if ((mask & mask_pos) == 0) { |
---|
1153 | 1176 | dev_err(pcs->dev, |
---|
1154 | | - "Invalid mask for %s at 0x%x\n", |
---|
1155 | | - np->name, offset); |
---|
| 1177 | + "Invalid mask for %pOFn at 0x%x\n", |
---|
| 1178 | + np, offset); |
---|
1156 | 1179 | break; |
---|
1157 | 1180 | } |
---|
1158 | 1181 | |
---|
.. | .. |
---|
1160 | 1183 | |
---|
1161 | 1184 | if (submask != mask_pos) { |
---|
1162 | 1185 | dev_warn(pcs->dev, |
---|
1163 | | - "Invalid submask 0x%x for %s at 0x%x\n", |
---|
1164 | | - submask, np->name, offset); |
---|
| 1186 | + "Invalid submask 0x%x for %pOFn at 0x%x\n", |
---|
| 1187 | + submask, np, offset); |
---|
1165 | 1188 | continue; |
---|
1166 | 1189 | } |
---|
1167 | 1190 | |
---|
.. | .. |
---|
1172 | 1195 | pin = pcs_get_pin_by_offset(pcs, offset); |
---|
1173 | 1196 | if (pin < 0) { |
---|
1174 | 1197 | dev_err(pcs->dev, |
---|
1175 | | - "could not add functions for %s %ux\n", |
---|
1176 | | - np->name, offset); |
---|
| 1198 | + "could not add functions for %pOFn %ux\n", |
---|
| 1199 | + np, offset); |
---|
1177 | 1200 | break; |
---|
1178 | 1201 | } |
---|
1179 | 1202 | pins[found++] = pin + pin_num_from_lsb; |
---|
.. | .. |
---|
1258 | 1281 | ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map, |
---|
1259 | 1282 | num_maps, pgnames); |
---|
1260 | 1283 | if (ret < 0) { |
---|
1261 | | - dev_err(pcs->dev, "no pins entries for %s\n", |
---|
1262 | | - np_config->name); |
---|
| 1284 | + dev_err(pcs->dev, "no pins entries for %pOFn\n", |
---|
| 1285 | + np_config); |
---|
1263 | 1286 | goto free_pgnames; |
---|
1264 | 1287 | } |
---|
1265 | 1288 | } else { |
---|
1266 | 1289 | ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, |
---|
1267 | 1290 | num_maps, pgnames); |
---|
1268 | 1291 | if (ret < 0) { |
---|
1269 | | - dev_err(pcs->dev, "no pins entries for %s\n", |
---|
1270 | | - np_config->name); |
---|
| 1292 | + dev_err(pcs->dev, "no pins entries for %pOFn\n", |
---|
| 1293 | + np_config); |
---|
1271 | 1294 | goto free_pgnames; |
---|
1272 | 1295 | } |
---|
1273 | 1296 | } |
---|
.. | .. |
---|
1347 | 1370 | } |
---|
1348 | 1371 | return ret; |
---|
1349 | 1372 | } |
---|
| 1373 | + |
---|
1350 | 1374 | /** |
---|
| 1375 | + * struct pcs_interrupt |
---|
1351 | 1376 | * @reg: virtual address of interrupt register |
---|
1352 | 1377 | * @hwirq: hardware irq number |
---|
1353 | 1378 | * @irq: virtual irq number |
---|
.. | .. |
---|
1362 | 1387 | |
---|
1363 | 1388 | /** |
---|
1364 | 1389 | * pcs_irq_set() - enables or disables an interrupt |
---|
| 1390 | + * @pcs_soc: SoC specific settings |
---|
| 1391 | + * @irq: interrupt |
---|
| 1392 | + * @enable: enable or disable the interrupt |
---|
1365 | 1393 | * |
---|
1366 | 1394 | * Note that this currently assumes one interrupt per pinctrl |
---|
1367 | 1395 | * register that is typically used for wake-up events. |
---|
.. | .. |
---|
1442 | 1470 | |
---|
1443 | 1471 | /** |
---|
1444 | 1472 | * pcs_irq_handle() - common interrupt handler |
---|
1445 | | - * @pcs_irq: interrupt data |
---|
| 1473 | + * @pcs_soc: SoC specific settings |
---|
1446 | 1474 | * |
---|
1447 | 1475 | * Note that this currently assumes we have one interrupt bit per |
---|
1448 | 1476 | * mux register. This interrupt is typically used for wake-up events. |
---|
.. | .. |
---|
1490 | 1518 | |
---|
1491 | 1519 | /** |
---|
1492 | 1520 | * pcs_irq_handle() - handler for the dedicated chained interrupt case |
---|
1493 | | - * @irq: interrupt |
---|
1494 | 1521 | * @desc: interrupt descriptor |
---|
1495 | 1522 | * |
---|
1496 | 1523 | * Use this if you have a separate interrupt for each |
---|