Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: imx: add VF610 support to imx pinctrl framework

On some platforms such as VF610, offset of mux and pad ctrl register
may be zero, and the mux_mode and config_val are in one 32-bit register.
This patch adds support to imx core pinctrl framework to handle these
cases.

Signed-off-by: Jingchang Lu <b35083@freescale.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Jingchang Lu and committed by
Linus Walleij
bf5a5309 7bbc87b8

+46 -11
+42 -11
drivers/pinctrl/pinctrl-imx.c
··· 221 221 pin_id = pins[i]; 222 222 pin_reg = &info->pin_regs[pin_id]; 223 223 224 - if (!pin_reg->mux_reg) { 224 + if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->mux_reg) { 225 225 dev_err(ipctl->dev, "Pin(%s) does not support mux function\n", 226 226 info->pins[pin_id].name); 227 227 return -EINVAL; 228 228 } 229 229 230 - writel(mux[i], ipctl->base + pin_reg->mux_reg); 230 + if (info->flags & SHARE_MUX_CONF_REG) { 231 + u32 reg; 232 + reg = readl(ipctl->base + pin_reg->mux_reg); 233 + reg &= ~(0x7 << 20); 234 + reg |= (mux[i] << 20); 235 + writel(reg, ipctl->base + pin_reg->mux_reg); 236 + } else { 237 + writel(mux[i], ipctl->base + pin_reg->mux_reg); 238 + } 231 239 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", 232 240 pin_reg->mux_reg, mux[i]); 233 241 ··· 295 287 const struct imx_pinctrl_soc_info *info = ipctl->info; 296 288 const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; 297 289 298 - if (!pin_reg->conf_reg) { 290 + if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) { 299 291 dev_err(info->dev, "Pin(%s) does not support config function\n", 300 292 info->pins[pin_id].name); 301 293 return -EINVAL; 302 294 } 303 295 304 296 *config = readl(ipctl->base + pin_reg->conf_reg); 297 + 298 + if (info->flags & SHARE_MUX_CONF_REG) 299 + *config &= 0xffff; 305 300 306 301 return 0; 307 302 } ··· 316 305 const struct imx_pinctrl_soc_info *info = ipctl->info; 317 306 const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; 318 307 319 - if (!pin_reg->conf_reg) { 308 + if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) { 320 309 dev_err(info->dev, "Pin(%s) does not support config function\n", 321 310 info->pins[pin_id].name); 322 311 return -EINVAL; ··· 325 314 dev_dbg(ipctl->dev, "pinconf set pin %s\n", 326 315 info->pins[pin_id].name); 327 316 328 - writel(config, ipctl->base + pin_reg->conf_reg); 317 + if (info->flags & SHARE_MUX_CONF_REG) { 318 + u32 reg; 319 + reg = readl(ipctl->base + pin_reg->conf_reg); 320 + reg &= ~0xffff; 321 + reg |= config; 322 + writel(reg, ipctl->base + pin_reg->conf_reg); 323 + } else { 324 + writel(config, ipctl->base + pin_reg->conf_reg); 325 + } 329 326 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", 330 327 pin_reg->conf_reg, config); 331 328 ··· 400 381 * 1 u32 CONFIG, so 24 types in total for each pin. 401 382 */ 402 383 #define FSL_PIN_SIZE 24 384 + #define SHARE_FSL_PIN_SIZE 20 403 385 404 386 static int imx_pinctrl_parse_groups(struct device_node *np, 405 387 struct imx_pin_group *grp, 406 388 struct imx_pinctrl_soc_info *info, 407 389 u32 index) 408 390 { 409 - int size; 391 + int size, pin_size; 410 392 const __be32 *list; 411 393 int i; 412 394 u32 config; 413 395 414 396 dev_dbg(info->dev, "group(%d): %s\n", index, np->name); 415 397 398 + if (info->flags & SHARE_MUX_CONF_REG) 399 + pin_size = SHARE_FSL_PIN_SIZE; 400 + else 401 + pin_size = FSL_PIN_SIZE; 416 402 /* Initialise group */ 417 403 grp->name = np->name; 418 404 ··· 427 403 */ 428 404 list = of_get_property(np, "fsl,pins", &size); 429 405 /* we do not check return since it's safe node passed down */ 430 - if (!size || size % FSL_PIN_SIZE) { 406 + if (!size || size % pin_size) { 431 407 dev_err(info->dev, "Invalid fsl,pins property\n"); 432 408 return -EINVAL; 433 409 } 434 410 435 - grp->npins = size / FSL_PIN_SIZE; 411 + grp->npins = size / pin_size; 436 412 grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 437 413 GFP_KERNEL); 438 414 grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), ··· 445 421 GFP_KERNEL); 446 422 for (i = 0; i < grp->npins; i++) { 447 423 u32 mux_reg = be32_to_cpu(*list++); 448 - u32 conf_reg = be32_to_cpu(*list++); 449 - unsigned int pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4; 450 - struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; 424 + u32 conf_reg; 425 + unsigned int pin_id; 426 + struct imx_pin_reg *pin_reg; 451 427 428 + if (info->flags & SHARE_MUX_CONF_REG) 429 + conf_reg = mux_reg; 430 + else 431 + conf_reg = be32_to_cpu(*list++); 432 + 433 + pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4; 434 + pin_reg = &info->pin_regs[pin_id]; 452 435 grp->pins[i] = pin_id; 453 436 pin_reg->mux_reg = mux_reg; 454 437 pin_reg->conf_reg = conf_reg;
+4
drivers/pinctrl/pinctrl-imx.h
··· 74 74 unsigned int ngroups; 75 75 struct imx_pmx_func *functions; 76 76 unsigned int nfunctions; 77 + unsigned int flags; 77 78 }; 79 + 80 + #define ZERO_OFFSET_VALID 0x1 81 + #define SHARE_MUX_CONF_REG 0x2 78 82 79 83 #define NO_MUX 0x0 80 84 #define NO_PAD 0x0