| .. | .. |
|---|
| 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); |
|---|
| .. | .. |
|---|
| 381 | 408 | struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); |
|---|
| 382 | 409 | struct pcs_gpiofunc_range *frange = NULL; |
|---|
| 383 | 410 | struct list_head *pos, *tmp; |
|---|
| 384 | | - int mux_bytes = 0; |
|---|
| 385 | 411 | unsigned data; |
|---|
| 386 | 412 | |
|---|
| 387 | 413 | /* If function mask is null, return directly. */ |
|---|
| .. | .. |
|---|
| 389 | 415 | return -ENOTSUPP; |
|---|
| 390 | 416 | |
|---|
| 391 | 417 | list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { |
|---|
| 418 | + u32 offset; |
|---|
| 419 | + |
|---|
| 392 | 420 | frange = list_entry(pos, struct pcs_gpiofunc_range, node); |
|---|
| 393 | 421 | if (pin >= frange->offset + frange->npins |
|---|
| 394 | 422 | || pin < frange->offset) |
|---|
| 395 | 423 | continue; |
|---|
| 396 | | - mux_bytes = pcs->width / BITS_PER_BYTE; |
|---|
| 424 | + |
|---|
| 425 | + offset = pcs_pin_reg_offset_get(pcs, pin); |
|---|
| 397 | 426 | |
|---|
| 398 | 427 | 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; |
|---|
| 428 | + int pin_shift = pcs_pin_shift_reg_get(pcs, pin); |
|---|
| 405 | 429 | |
|---|
| 406 | 430 | data = pcs->read(pcs->base + offset); |
|---|
| 407 | 431 | data &= ~(pcs->fmask << pin_shift); |
|---|
| 408 | 432 | data |= frange->gpiofunc << pin_shift; |
|---|
| 409 | 433 | pcs->write(data, pcs->base + offset); |
|---|
| 410 | 434 | } else { |
|---|
| 411 | | - data = pcs->read(pcs->base + pin * mux_bytes); |
|---|
| 435 | + data = pcs->read(pcs->base + offset); |
|---|
| 412 | 436 | data &= ~pcs->fmask; |
|---|
| 413 | 437 | data |= frange->gpiofunc; |
|---|
| 414 | | - pcs->write(data, pcs->base + pin * mux_bytes); |
|---|
| 438 | + pcs->write(data, pcs->base + offset); |
|---|
| 415 | 439 | } |
|---|
| 416 | 440 | break; |
|---|
| 417 | 441 | } |
|---|
| .. | .. |
|---|
| 560 | 584 | case PIN_CONFIG_BIAS_PULL_UP: |
|---|
| 561 | 585 | if (arg) |
|---|
| 562 | 586 | pcs_pinconf_clear_bias(pctldev, pin); |
|---|
| 563 | | - /* fall through */ |
|---|
| 587 | + fallthrough; |
|---|
| 564 | 588 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
|---|
| 565 | 589 | data &= ~func->conf[i].mask; |
|---|
| 566 | 590 | if (arg) |
|---|
| .. | .. |
|---|
| 654 | 678 | * @pcs: pcs driver instance |
|---|
| 655 | 679 | * @offset: register offset from base |
|---|
| 656 | 680 | */ |
|---|
| 657 | | -static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, |
|---|
| 658 | | - unsigned pin_pos) |
|---|
| 681 | +static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset) |
|---|
| 659 | 682 | { |
|---|
| 660 | 683 | struct pcs_soc_data *pcs_soc = &pcs->socdata; |
|---|
| 661 | 684 | struct pinctrl_pin_desc *pin; |
|---|
| .. | .. |
|---|
| 703 | 726 | |
|---|
| 704 | 727 | mux_bytes = pcs->width / BITS_PER_BYTE; |
|---|
| 705 | 728 | |
|---|
| 706 | | - if (pcs->bits_per_mux) { |
|---|
| 729 | + if (pcs->bits_per_mux && pcs->fmask) { |
|---|
| 707 | 730 | pcs->bits_per_pin = fls(pcs->fmask); |
|---|
| 708 | 731 | nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; |
|---|
| 709 | 732 | num_pins_in_register = pcs->width / pcs->bits_per_pin; |
|---|
| .. | .. |
|---|
| 724 | 747 | for (i = 0; i < pcs->desc.npins; i++) { |
|---|
| 725 | 748 | unsigned offset; |
|---|
| 726 | 749 | int res; |
|---|
| 727 | | - int byte_num; |
|---|
| 728 | | - int pin_pos = 0; |
|---|
| 729 | 750 | |
|---|
| 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); |
|---|
| 751 | + offset = pcs_pin_reg_offset_get(pcs, i); |
|---|
| 752 | + res = pcs_add_pin(pcs, offset); |
|---|
| 738 | 753 | if (res < 0) { |
|---|
| 739 | 754 | dev_err(pcs->dev, "error adding pins: %i\n", res); |
|---|
| 740 | 755 | return res; |
|---|
| .. | .. |
|---|
| 958 | 973 | } |
|---|
| 959 | 974 | |
|---|
| 960 | 975 | /** |
|---|
| 961 | | - * smux_parse_one_pinctrl_entry() - parses a device tree mux entry |
|---|
| 962 | | - * @pctldev: pin controller device |
|---|
| 976 | + * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry |
|---|
| 963 | 977 | * @pcs: pinctrl driver instance |
|---|
| 964 | 978 | * @np: device node of the mux entry |
|---|
| 965 | 979 | * @map: map entry |
|---|
| .. | .. |
|---|
| 1011 | 1025 | if (res) |
|---|
| 1012 | 1026 | return res; |
|---|
| 1013 | 1027 | |
|---|
| 1014 | | - if (pinctrl_spec.args_count < 2) { |
|---|
| 1028 | + if (pinctrl_spec.args_count < 2 || pinctrl_spec.args_count > 3) { |
|---|
| 1015 | 1029 | dev_err(pcs->dev, "invalid args_count for spec: %i\n", |
|---|
| 1016 | 1030 | pinctrl_spec.args_count); |
|---|
| 1017 | 1031 | break; |
|---|
| 1018 | 1032 | } |
|---|
| 1019 | 1033 | |
|---|
| 1020 | | - /* Index plus one value cell */ |
|---|
| 1021 | 1034 | offset = pinctrl_spec.args[0]; |
|---|
| 1022 | 1035 | vals[found].reg = pcs->base + offset; |
|---|
| 1023 | | - vals[found].val = pinctrl_spec.args[1]; |
|---|
| 1024 | 1036 | |
|---|
| 1025 | | - dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n", |
|---|
| 1026 | | - pinctrl_spec.np->name, offset, pinctrl_spec.args[1]); |
|---|
| 1037 | + switch (pinctrl_spec.args_count) { |
|---|
| 1038 | + case 2: |
|---|
| 1039 | + vals[found].val = pinctrl_spec.args[1]; |
|---|
| 1040 | + break; |
|---|
| 1041 | + case 3: |
|---|
| 1042 | + vals[found].val = (pinctrl_spec.args[1] | pinctrl_spec.args[2]); |
|---|
| 1043 | + break; |
|---|
| 1044 | + } |
|---|
| 1045 | + |
|---|
| 1046 | + dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n", |
|---|
| 1047 | + pinctrl_spec.np, offset, vals[found].val); |
|---|
| 1027 | 1048 | |
|---|
| 1028 | 1049 | pin = pcs_get_pin_by_offset(pcs, offset); |
|---|
| 1029 | 1050 | if (pin < 0) { |
|---|
| 1030 | 1051 | dev_err(pcs->dev, |
|---|
| 1031 | | - "could not add functions for %s %ux\n", |
|---|
| 1032 | | - np->name, offset); |
|---|
| 1052 | + "could not add functions for %pOFn %ux\n", |
|---|
| 1053 | + np, offset); |
|---|
| 1033 | 1054 | break; |
|---|
| 1034 | 1055 | } |
|---|
| 1035 | 1056 | pins[found++] = pin; |
|---|
| .. | .. |
|---|
| 1138 | 1159 | val = pinctrl_spec.args[1]; |
|---|
| 1139 | 1160 | mask = pinctrl_spec.args[2]; |
|---|
| 1140 | 1161 | |
|---|
| 1141 | | - dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n", |
|---|
| 1142 | | - pinctrl_spec.np->name, offset, val, mask); |
|---|
| 1162 | + dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x mask: 0x%x\n", |
|---|
| 1163 | + pinctrl_spec.np, offset, val, mask); |
|---|
| 1143 | 1164 | |
|---|
| 1144 | 1165 | /* Parse pins in each row from LSB */ |
|---|
| 1145 | 1166 | while (mask) { |
|---|
| .. | .. |
|---|
| 1151 | 1172 | |
|---|
| 1152 | 1173 | if ((mask & mask_pos) == 0) { |
|---|
| 1153 | 1174 | dev_err(pcs->dev, |
|---|
| 1154 | | - "Invalid mask for %s at 0x%x\n", |
|---|
| 1155 | | - np->name, offset); |
|---|
| 1175 | + "Invalid mask for %pOFn at 0x%x\n", |
|---|
| 1176 | + np, offset); |
|---|
| 1156 | 1177 | break; |
|---|
| 1157 | 1178 | } |
|---|
| 1158 | 1179 | |
|---|
| .. | .. |
|---|
| 1160 | 1181 | |
|---|
| 1161 | 1182 | if (submask != mask_pos) { |
|---|
| 1162 | 1183 | dev_warn(pcs->dev, |
|---|
| 1163 | | - "Invalid submask 0x%x for %s at 0x%x\n", |
|---|
| 1164 | | - submask, np->name, offset); |
|---|
| 1184 | + "Invalid submask 0x%x for %pOFn at 0x%x\n", |
|---|
| 1185 | + submask, np, offset); |
|---|
| 1165 | 1186 | continue; |
|---|
| 1166 | 1187 | } |
|---|
| 1167 | 1188 | |
|---|
| .. | .. |
|---|
| 1172 | 1193 | pin = pcs_get_pin_by_offset(pcs, offset); |
|---|
| 1173 | 1194 | if (pin < 0) { |
|---|
| 1174 | 1195 | dev_err(pcs->dev, |
|---|
| 1175 | | - "could not add functions for %s %ux\n", |
|---|
| 1176 | | - np->name, offset); |
|---|
| 1196 | + "could not add functions for %pOFn %ux\n", |
|---|
| 1197 | + np, offset); |
|---|
| 1177 | 1198 | break; |
|---|
| 1178 | 1199 | } |
|---|
| 1179 | 1200 | pins[found++] = pin + pin_num_from_lsb; |
|---|
| .. | .. |
|---|
| 1258 | 1279 | ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map, |
|---|
| 1259 | 1280 | num_maps, pgnames); |
|---|
| 1260 | 1281 | if (ret < 0) { |
|---|
| 1261 | | - dev_err(pcs->dev, "no pins entries for %s\n", |
|---|
| 1262 | | - np_config->name); |
|---|
| 1282 | + dev_err(pcs->dev, "no pins entries for %pOFn\n", |
|---|
| 1283 | + np_config); |
|---|
| 1263 | 1284 | goto free_pgnames; |
|---|
| 1264 | 1285 | } |
|---|
| 1265 | 1286 | } else { |
|---|
| 1266 | 1287 | ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, |
|---|
| 1267 | 1288 | num_maps, pgnames); |
|---|
| 1268 | 1289 | if (ret < 0) { |
|---|
| 1269 | | - dev_err(pcs->dev, "no pins entries for %s\n", |
|---|
| 1270 | | - np_config->name); |
|---|
| 1290 | + dev_err(pcs->dev, "no pins entries for %pOFn\n", |
|---|
| 1291 | + np_config); |
|---|
| 1271 | 1292 | goto free_pgnames; |
|---|
| 1272 | 1293 | } |
|---|
| 1273 | 1294 | } |
|---|
| .. | .. |
|---|
| 1347 | 1368 | } |
|---|
| 1348 | 1369 | return ret; |
|---|
| 1349 | 1370 | } |
|---|
| 1371 | + |
|---|
| 1350 | 1372 | /** |
|---|
| 1373 | + * struct pcs_interrupt |
|---|
| 1351 | 1374 | * @reg: virtual address of interrupt register |
|---|
| 1352 | 1375 | * @hwirq: hardware irq number |
|---|
| 1353 | 1376 | * @irq: virtual irq number |
|---|
| .. | .. |
|---|
| 1362 | 1385 | |
|---|
| 1363 | 1386 | /** |
|---|
| 1364 | 1387 | * pcs_irq_set() - enables or disables an interrupt |
|---|
| 1388 | + * @pcs_soc: SoC specific settings |
|---|
| 1389 | + * @irq: interrupt |
|---|
| 1390 | + * @enable: enable or disable the interrupt |
|---|
| 1365 | 1391 | * |
|---|
| 1366 | 1392 | * Note that this currently assumes one interrupt per pinctrl |
|---|
| 1367 | 1393 | * register that is typically used for wake-up events. |
|---|
| .. | .. |
|---|
| 1442 | 1468 | |
|---|
| 1443 | 1469 | /** |
|---|
| 1444 | 1470 | * pcs_irq_handle() - common interrupt handler |
|---|
| 1445 | | - * @pcs_irq: interrupt data |
|---|
| 1471 | + * @pcs_soc: SoC specific settings |
|---|
| 1446 | 1472 | * |
|---|
| 1447 | 1473 | * Note that this currently assumes we have one interrupt bit per |
|---|
| 1448 | 1474 | * mux register. This interrupt is typically used for wake-up events. |
|---|
| .. | .. |
|---|
| 1490 | 1516 | |
|---|
| 1491 | 1517 | /** |
|---|
| 1492 | 1518 | * pcs_irq_handle() - handler for the dedicated chained interrupt case |
|---|
| 1493 | | - * @irq: interrupt |
|---|
| 1494 | 1519 | * @desc: interrupt descriptor |
|---|
| 1495 | 1520 | * |
|---|
| 1496 | 1521 | * Use this if you have a separate interrupt for each |
|---|