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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc3 785 lines 19 kB view raw
1/* 2 * Driver for the NVIDIA Tegra pinmux 3 * 4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. 5 * 6 * Derived from code: 7 * Copyright (C) 2010 Google, Inc. 8 * Copyright (C) 2010 NVIDIA Corporation 9 * Copyright (C) 2009-2011 ST-Ericsson AB 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms and conditions of the GNU General Public License, 13 * version 2, as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * more details. 19 */ 20 21#include <linux/err.h> 22#include <linux/init.h> 23#include <linux/io.h> 24#include <linux/module.h> 25#include <linux/of.h> 26#include <linux/platform_device.h> 27#include <linux/pinctrl/machine.h> 28#include <linux/pinctrl/pinctrl.h> 29#include <linux/pinctrl/pinmux.h> 30#include <linux/pinctrl/pinconf.h> 31#include <linux/slab.h> 32 33#include "core.h" 34#include "pinctrl-tegra.h" 35 36struct tegra_pmx { 37 struct device *dev; 38 struct pinctrl_dev *pctl; 39 40 const struct tegra_pinctrl_soc_data *soc; 41 42 int nbanks; 43 void __iomem **regs; 44}; 45 46static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg) 47{ 48 return readl(pmx->regs[bank] + reg); 49} 50 51static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg) 52{ 53 writel(val, pmx->regs[bank] + reg); 54} 55 56static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) 57{ 58 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 59 60 return pmx->soc->ngroups; 61} 62 63static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 64 unsigned group) 65{ 66 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 67 68 return pmx->soc->groups[group].name; 69} 70 71static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 72 unsigned group, 73 const unsigned **pins, 74 unsigned *num_pins) 75{ 76 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 77 78 *pins = pmx->soc->groups[group].pins; 79 *num_pins = pmx->soc->groups[group].npins; 80 81 return 0; 82} 83 84#ifdef CONFIG_DEBUG_FS 85static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, 86 struct seq_file *s, 87 unsigned offset) 88{ 89 seq_printf(s, " %s", dev_name(pctldev->dev)); 90} 91#endif 92 93static int reserve_map(struct device *dev, struct pinctrl_map **map, 94 unsigned *reserved_maps, unsigned *num_maps, 95 unsigned reserve) 96{ 97 unsigned old_num = *reserved_maps; 98 unsigned new_num = *num_maps + reserve; 99 struct pinctrl_map *new_map; 100 101 if (old_num >= new_num) 102 return 0; 103 104 new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL); 105 if (!new_map) { 106 dev_err(dev, "krealloc(map) failed\n"); 107 return -ENOMEM; 108 } 109 110 memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map)); 111 112 *map = new_map; 113 *reserved_maps = new_num; 114 115 return 0; 116} 117 118static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps, 119 unsigned *num_maps, const char *group, 120 const char *function) 121{ 122 if (WARN_ON(*num_maps == *reserved_maps)) 123 return -ENOSPC; 124 125 (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; 126 (*map)[*num_maps].data.mux.group = group; 127 (*map)[*num_maps].data.mux.function = function; 128 (*num_maps)++; 129 130 return 0; 131} 132 133static int add_map_configs(struct device *dev, struct pinctrl_map **map, 134 unsigned *reserved_maps, unsigned *num_maps, 135 const char *group, unsigned long *configs, 136 unsigned num_configs) 137{ 138 unsigned long *dup_configs; 139 140 if (WARN_ON(*num_maps == *reserved_maps)) 141 return -ENOSPC; 142 143 dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs), 144 GFP_KERNEL); 145 if (!dup_configs) { 146 dev_err(dev, "kmemdup(configs) failed\n"); 147 return -ENOMEM; 148 } 149 150 (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP; 151 (*map)[*num_maps].data.configs.group_or_pin = group; 152 (*map)[*num_maps].data.configs.configs = dup_configs; 153 (*map)[*num_maps].data.configs.num_configs = num_configs; 154 (*num_maps)++; 155 156 return 0; 157} 158 159static int add_config(struct device *dev, unsigned long **configs, 160 unsigned *num_configs, unsigned long config) 161{ 162 unsigned old_num = *num_configs; 163 unsigned new_num = old_num + 1; 164 unsigned long *new_configs; 165 166 new_configs = krealloc(*configs, sizeof(*new_configs) * new_num, 167 GFP_KERNEL); 168 if (!new_configs) { 169 dev_err(dev, "krealloc(configs) failed\n"); 170 return -ENOMEM; 171 } 172 173 new_configs[old_num] = config; 174 175 *configs = new_configs; 176 *num_configs = new_num; 177 178 return 0; 179} 180 181static void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, 182 struct pinctrl_map *map, 183 unsigned num_maps) 184{ 185 int i; 186 187 for (i = 0; i < num_maps; i++) 188 if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) 189 kfree(map[i].data.configs.configs); 190 191 kfree(map); 192} 193 194static const struct cfg_param { 195 const char *property; 196 enum tegra_pinconf_param param; 197} cfg_params[] = { 198 {"nvidia,pull", TEGRA_PINCONF_PARAM_PULL}, 199 {"nvidia,tristate", TEGRA_PINCONF_PARAM_TRISTATE}, 200 {"nvidia,enable-input", TEGRA_PINCONF_PARAM_ENABLE_INPUT}, 201 {"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN}, 202 {"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK}, 203 {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET}, 204 {"nvidia,rcv-sel", TEGRA_PINCONF_PARAM_RCV_SEL}, 205 {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE}, 206 {"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT}, 207 {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE}, 208 {"nvidia,pull-down-strength", TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH}, 209 {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH}, 210 {"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING}, 211 {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, 212 {"nvidia,drive-type", TEGRA_PINCONF_PARAM_DRIVE_TYPE}, 213}; 214 215static int tegra_pinctrl_dt_subnode_to_map(struct device *dev, 216 struct device_node *np, 217 struct pinctrl_map **map, 218 unsigned *reserved_maps, 219 unsigned *num_maps) 220{ 221 int ret, i; 222 const char *function; 223 u32 val; 224 unsigned long config; 225 unsigned long *configs = NULL; 226 unsigned num_configs = 0; 227 unsigned reserve; 228 struct property *prop; 229 const char *group; 230 231 ret = of_property_read_string(np, "nvidia,function", &function); 232 if (ret < 0) { 233 /* EINVAL=missing, which is fine since it's optional */ 234 if (ret != -EINVAL) 235 dev_err(dev, 236 "could not parse property nvidia,function\n"); 237 function = NULL; 238 } 239 240 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 241 ret = of_property_read_u32(np, cfg_params[i].property, &val); 242 if (!ret) { 243 config = TEGRA_PINCONF_PACK(cfg_params[i].param, val); 244 ret = add_config(dev, &configs, &num_configs, config); 245 if (ret < 0) 246 goto exit; 247 /* EINVAL=missing, which is fine since it's optional */ 248 } else if (ret != -EINVAL) { 249 dev_err(dev, "could not parse property %s\n", 250 cfg_params[i].property); 251 } 252 } 253 254 reserve = 0; 255 if (function != NULL) 256 reserve++; 257 if (num_configs) 258 reserve++; 259 ret = of_property_count_strings(np, "nvidia,pins"); 260 if (ret < 0) { 261 dev_err(dev, "could not parse property nvidia,pins\n"); 262 goto exit; 263 } 264 reserve *= ret; 265 266 ret = reserve_map(dev, map, reserved_maps, num_maps, reserve); 267 if (ret < 0) 268 goto exit; 269 270 of_property_for_each_string(np, "nvidia,pins", prop, group) { 271 if (function) { 272 ret = add_map_mux(map, reserved_maps, num_maps, 273 group, function); 274 if (ret < 0) 275 goto exit; 276 } 277 278 if (num_configs) { 279 ret = add_map_configs(dev, map, reserved_maps, 280 num_maps, group, configs, 281 num_configs); 282 if (ret < 0) 283 goto exit; 284 } 285 } 286 287 ret = 0; 288 289exit: 290 kfree(configs); 291 return ret; 292} 293 294static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, 295 struct device_node *np_config, 296 struct pinctrl_map **map, 297 unsigned *num_maps) 298{ 299 unsigned reserved_maps; 300 struct device_node *np; 301 int ret; 302 303 reserved_maps = 0; 304 *map = NULL; 305 *num_maps = 0; 306 307 for_each_child_of_node(np_config, np) { 308 ret = tegra_pinctrl_dt_subnode_to_map(pctldev->dev, np, map, 309 &reserved_maps, num_maps); 310 if (ret < 0) { 311 tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps); 312 return ret; 313 } 314 } 315 316 return 0; 317} 318 319static struct pinctrl_ops tegra_pinctrl_ops = { 320 .get_groups_count = tegra_pinctrl_get_groups_count, 321 .get_group_name = tegra_pinctrl_get_group_name, 322 .get_group_pins = tegra_pinctrl_get_group_pins, 323#ifdef CONFIG_DEBUG_FS 324 .pin_dbg_show = tegra_pinctrl_pin_dbg_show, 325#endif 326 .dt_node_to_map = tegra_pinctrl_dt_node_to_map, 327 .dt_free_map = tegra_pinctrl_dt_free_map, 328}; 329 330static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) 331{ 332 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 333 334 return pmx->soc->nfunctions; 335} 336 337static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 338 unsigned function) 339{ 340 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 341 342 return pmx->soc->functions[function].name; 343} 344 345static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, 346 unsigned function, 347 const char * const **groups, 348 unsigned * const num_groups) 349{ 350 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 351 352 *groups = pmx->soc->functions[function].groups; 353 *num_groups = pmx->soc->functions[function].ngroups; 354 355 return 0; 356} 357 358static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, 359 unsigned group) 360{ 361 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 362 const struct tegra_pingroup *g; 363 int i; 364 u32 val; 365 366 g = &pmx->soc->groups[group]; 367 368 if (WARN_ON(g->mux_reg < 0)) 369 return -EINVAL; 370 371 for (i = 0; i < ARRAY_SIZE(g->funcs); i++) { 372 if (g->funcs[i] == function) 373 break; 374 } 375 if (WARN_ON(i == ARRAY_SIZE(g->funcs))) 376 return -EINVAL; 377 378 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); 379 val &= ~(0x3 << g->mux_bit); 380 val |= i << g->mux_bit; 381 pmx_writel(pmx, val, g->mux_bank, g->mux_reg); 382 383 return 0; 384} 385 386static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, 387 unsigned function, unsigned group) 388{ 389 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 390 const struct tegra_pingroup *g; 391 u32 val; 392 393 g = &pmx->soc->groups[group]; 394 395 if (WARN_ON(g->mux_reg < 0)) 396 return; 397 398 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); 399 val &= ~(0x3 << g->mux_bit); 400 val |= g->func_safe << g->mux_bit; 401 pmx_writel(pmx, val, g->mux_bank, g->mux_reg); 402} 403 404static struct pinmux_ops tegra_pinmux_ops = { 405 .get_functions_count = tegra_pinctrl_get_funcs_count, 406 .get_function_name = tegra_pinctrl_get_func_name, 407 .get_function_groups = tegra_pinctrl_get_func_groups, 408 .enable = tegra_pinctrl_enable, 409 .disable = tegra_pinctrl_disable, 410}; 411 412static int tegra_pinconf_reg(struct tegra_pmx *pmx, 413 const struct tegra_pingroup *g, 414 enum tegra_pinconf_param param, 415 bool report_err, 416 s8 *bank, s16 *reg, s8 *bit, s8 *width) 417{ 418 switch (param) { 419 case TEGRA_PINCONF_PARAM_PULL: 420 *bank = g->pupd_bank; 421 *reg = g->pupd_reg; 422 *bit = g->pupd_bit; 423 *width = 2; 424 break; 425 case TEGRA_PINCONF_PARAM_TRISTATE: 426 *bank = g->tri_bank; 427 *reg = g->tri_reg; 428 *bit = g->tri_bit; 429 *width = 1; 430 break; 431 case TEGRA_PINCONF_PARAM_ENABLE_INPUT: 432 *bank = g->einput_bank; 433 *reg = g->einput_reg; 434 *bit = g->einput_bit; 435 *width = 1; 436 break; 437 case TEGRA_PINCONF_PARAM_OPEN_DRAIN: 438 *bank = g->odrain_bank; 439 *reg = g->odrain_reg; 440 *bit = g->odrain_bit; 441 *width = 1; 442 break; 443 case TEGRA_PINCONF_PARAM_LOCK: 444 *bank = g->lock_bank; 445 *reg = g->lock_reg; 446 *bit = g->lock_bit; 447 *width = 1; 448 break; 449 case TEGRA_PINCONF_PARAM_IORESET: 450 *bank = g->ioreset_bank; 451 *reg = g->ioreset_reg; 452 *bit = g->ioreset_bit; 453 *width = 1; 454 break; 455 case TEGRA_PINCONF_PARAM_RCV_SEL: 456 *bank = g->rcv_sel_bank; 457 *reg = g->rcv_sel_reg; 458 *bit = g->rcv_sel_bit; 459 *width = 1; 460 break; 461 case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE: 462 *bank = g->drv_bank; 463 *reg = g->drv_reg; 464 *bit = g->hsm_bit; 465 *width = 1; 466 break; 467 case TEGRA_PINCONF_PARAM_SCHMITT: 468 *bank = g->drv_bank; 469 *reg = g->drv_reg; 470 *bit = g->schmitt_bit; 471 *width = 1; 472 break; 473 case TEGRA_PINCONF_PARAM_LOW_POWER_MODE: 474 *bank = g->drv_bank; 475 *reg = g->drv_reg; 476 *bit = g->lpmd_bit; 477 *width = 2; 478 break; 479 case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH: 480 *bank = g->drv_bank; 481 *reg = g->drv_reg; 482 *bit = g->drvdn_bit; 483 *width = g->drvdn_width; 484 break; 485 case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH: 486 *bank = g->drv_bank; 487 *reg = g->drv_reg; 488 *bit = g->drvup_bit; 489 *width = g->drvup_width; 490 break; 491 case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING: 492 *bank = g->drv_bank; 493 *reg = g->drv_reg; 494 *bit = g->slwf_bit; 495 *width = g->slwf_width; 496 break; 497 case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING: 498 *bank = g->drv_bank; 499 *reg = g->drv_reg; 500 *bit = g->slwr_bit; 501 *width = g->slwr_width; 502 break; 503 case TEGRA_PINCONF_PARAM_DRIVE_TYPE: 504 *bank = g->drvtype_bank; 505 *reg = g->drvtype_reg; 506 *bit = g->drvtype_bit; 507 *width = 2; 508 break; 509 default: 510 dev_err(pmx->dev, "Invalid config param %04x\n", param); 511 return -ENOTSUPP; 512 } 513 514 if (*reg < 0) { 515 if (report_err) 516 dev_err(pmx->dev, 517 "Config param %04x not supported on group %s\n", 518 param, g->name); 519 return -ENOTSUPP; 520 } 521 522 return 0; 523} 524 525static int tegra_pinconf_get(struct pinctrl_dev *pctldev, 526 unsigned pin, unsigned long *config) 527{ 528 dev_err(pctldev->dev, "pin_config_get op not supported\n"); 529 return -ENOTSUPP; 530} 531 532static int tegra_pinconf_set(struct pinctrl_dev *pctldev, 533 unsigned pin, unsigned long config) 534{ 535 dev_err(pctldev->dev, "pin_config_set op not supported\n"); 536 return -ENOTSUPP; 537} 538 539static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev, 540 unsigned group, unsigned long *config) 541{ 542 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 543 enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config); 544 u16 arg; 545 const struct tegra_pingroup *g; 546 int ret; 547 s8 bank, bit, width; 548 s16 reg; 549 u32 val, mask; 550 551 g = &pmx->soc->groups[group]; 552 553 ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, 554 &width); 555 if (ret < 0) 556 return ret; 557 558 val = pmx_readl(pmx, bank, reg); 559 mask = (1 << width) - 1; 560 arg = (val >> bit) & mask; 561 562 *config = TEGRA_PINCONF_PACK(param, arg); 563 564 return 0; 565} 566 567static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev, 568 unsigned group, unsigned long config) 569{ 570 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 571 enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config); 572 u16 arg = TEGRA_PINCONF_UNPACK_ARG(config); 573 const struct tegra_pingroup *g; 574 int ret; 575 s8 bank, bit, width; 576 s16 reg; 577 u32 val, mask; 578 579 g = &pmx->soc->groups[group]; 580 581 ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, 582 &width); 583 if (ret < 0) 584 return ret; 585 586 val = pmx_readl(pmx, bank, reg); 587 588 /* LOCK can't be cleared */ 589 if (param == TEGRA_PINCONF_PARAM_LOCK) { 590 if ((val & BIT(bit)) && !arg) { 591 dev_err(pctldev->dev, "LOCK bit cannot be cleared\n"); 592 return -EINVAL; 593 } 594 } 595 596 /* Special-case Boolean values; allow any non-zero as true */ 597 if (width == 1) 598 arg = !!arg; 599 600 /* Range-check user-supplied value */ 601 mask = (1 << width) - 1; 602 if (arg & ~mask) { 603 dev_err(pctldev->dev, 604 "config %lx: %x too big for %d bit register\n", 605 config, arg, width); 606 return -EINVAL; 607 } 608 609 /* Update register */ 610 val &= ~(mask << bit); 611 val |= arg << bit; 612 pmx_writel(pmx, val, bank, reg); 613 614 return 0; 615} 616 617#ifdef CONFIG_DEBUG_FS 618static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev, 619 struct seq_file *s, unsigned offset) 620{ 621} 622 623static const char *strip_prefix(const char *s) 624{ 625 const char *comma = strchr(s, ','); 626 if (!comma) 627 return s; 628 629 return comma + 1; 630} 631 632static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, 633 struct seq_file *s, unsigned group) 634{ 635 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 636 const struct tegra_pingroup *g; 637 int i, ret; 638 s8 bank, bit, width; 639 s16 reg; 640 u32 val; 641 642 g = &pmx->soc->groups[group]; 643 644 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 645 ret = tegra_pinconf_reg(pmx, g, cfg_params[i].param, false, 646 &bank, &reg, &bit, &width); 647 if (ret < 0) 648 continue; 649 650 val = pmx_readl(pmx, bank, reg); 651 val >>= bit; 652 val &= (1 << width) - 1; 653 654 seq_printf(s, "\n\t%s=%u", 655 strip_prefix(cfg_params[i].property), val); 656 } 657} 658 659static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, 660 struct seq_file *s, 661 unsigned long config) 662{ 663 enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config); 664 u16 arg = TEGRA_PINCONF_UNPACK_ARG(config); 665 const char *pname = "unknown"; 666 int i; 667 668 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 669 if (cfg_params[i].param == param) { 670 pname = cfg_params[i].property; 671 break; 672 } 673 } 674 675 seq_printf(s, "%s=%d", strip_prefix(pname), arg); 676} 677#endif 678 679static struct pinconf_ops tegra_pinconf_ops = { 680 .pin_config_get = tegra_pinconf_get, 681 .pin_config_set = tegra_pinconf_set, 682 .pin_config_group_get = tegra_pinconf_group_get, 683 .pin_config_group_set = tegra_pinconf_group_set, 684#ifdef CONFIG_DEBUG_FS 685 .pin_config_dbg_show = tegra_pinconf_dbg_show, 686 .pin_config_group_dbg_show = tegra_pinconf_group_dbg_show, 687 .pin_config_config_dbg_show = tegra_pinconf_config_dbg_show, 688#endif 689}; 690 691static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = { 692 .name = "Tegra GPIOs", 693 .id = 0, 694 .base = 0, 695}; 696 697static struct pinctrl_desc tegra_pinctrl_desc = { 698 .pctlops = &tegra_pinctrl_ops, 699 .pmxops = &tegra_pinmux_ops, 700 .confops = &tegra_pinconf_ops, 701 .owner = THIS_MODULE, 702}; 703 704int tegra_pinctrl_probe(struct platform_device *pdev, 705 const struct tegra_pinctrl_soc_data *soc_data) 706{ 707 struct tegra_pmx *pmx; 708 struct resource *res; 709 int i; 710 711 pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL); 712 if (!pmx) { 713 dev_err(&pdev->dev, "Can't alloc tegra_pmx\n"); 714 return -ENOMEM; 715 } 716 pmx->dev = &pdev->dev; 717 pmx->soc = soc_data; 718 719 tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios; 720 tegra_pinctrl_desc.name = dev_name(&pdev->dev); 721 tegra_pinctrl_desc.pins = pmx->soc->pins; 722 tegra_pinctrl_desc.npins = pmx->soc->npins; 723 724 for (i = 0; ; i++) { 725 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 726 if (!res) 727 break; 728 } 729 pmx->nbanks = i; 730 731 pmx->regs = devm_kzalloc(&pdev->dev, pmx->nbanks * sizeof(*pmx->regs), 732 GFP_KERNEL); 733 if (!pmx->regs) { 734 dev_err(&pdev->dev, "Can't alloc regs pointer\n"); 735 return -ENODEV; 736 } 737 738 for (i = 0; i < pmx->nbanks; i++) { 739 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 740 if (!res) { 741 dev_err(&pdev->dev, "Missing MEM resource\n"); 742 return -ENODEV; 743 } 744 745 if (!devm_request_mem_region(&pdev->dev, res->start, 746 resource_size(res), 747 dev_name(&pdev->dev))) { 748 dev_err(&pdev->dev, 749 "Couldn't request MEM resource %d\n", i); 750 return -ENODEV; 751 } 752 753 pmx->regs[i] = devm_ioremap(&pdev->dev, res->start, 754 resource_size(res)); 755 if (!pmx->regs[i]) { 756 dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i); 757 return -ENODEV; 758 } 759 } 760 761 pmx->pctl = pinctrl_register(&tegra_pinctrl_desc, &pdev->dev, pmx); 762 if (!pmx->pctl) { 763 dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); 764 return -ENODEV; 765 } 766 767 pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range); 768 769 platform_set_drvdata(pdev, pmx); 770 771 dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n"); 772 773 return 0; 774} 775EXPORT_SYMBOL_GPL(tegra_pinctrl_probe); 776 777int tegra_pinctrl_remove(struct platform_device *pdev) 778{ 779 struct tegra_pmx *pmx = platform_get_drvdata(pdev); 780 781 pinctrl_unregister(pmx->pctl); 782 783 return 0; 784} 785EXPORT_SYMBOL_GPL(tegra_pinctrl_remove);