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.7-rc7 769 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 181void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, 182 struct pinctrl_map *map, unsigned num_maps) 183{ 184 int i; 185 186 for (i = 0; i < num_maps; i++) 187 if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) 188 kfree(map[i].data.configs.configs); 189 190 kfree(map); 191} 192 193static const struct cfg_param { 194 const char *property; 195 enum tegra_pinconf_param param; 196} cfg_params[] = { 197 {"nvidia,pull", TEGRA_PINCONF_PARAM_PULL}, 198 {"nvidia,tristate", TEGRA_PINCONF_PARAM_TRISTATE}, 199 {"nvidia,enable-input", TEGRA_PINCONF_PARAM_ENABLE_INPUT}, 200 {"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN}, 201 {"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK}, 202 {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET}, 203 {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE}, 204 {"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT}, 205 {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE}, 206 {"nvidia,pull-down-strength", TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH}, 207 {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH}, 208 {"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING}, 209 {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, 210}; 211 212int tegra_pinctrl_dt_subnode_to_map(struct device *dev, 213 struct device_node *np, 214 struct pinctrl_map **map, 215 unsigned *reserved_maps, 216 unsigned *num_maps) 217{ 218 int ret, i; 219 const char *function; 220 u32 val; 221 unsigned long config; 222 unsigned long *configs = NULL; 223 unsigned num_configs = 0; 224 unsigned reserve; 225 struct property *prop; 226 const char *group; 227 228 ret = of_property_read_string(np, "nvidia,function", &function); 229 if (ret < 0) { 230 /* EINVAL=missing, which is fine since it's optional */ 231 if (ret != -EINVAL) 232 dev_err(dev, 233 "could not parse property nvidia,function\n"); 234 function = NULL; 235 } 236 237 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 238 ret = of_property_read_u32(np, cfg_params[i].property, &val); 239 if (!ret) { 240 config = TEGRA_PINCONF_PACK(cfg_params[i].param, val); 241 ret = add_config(dev, &configs, &num_configs, config); 242 if (ret < 0) 243 goto exit; 244 /* EINVAL=missing, which is fine since it's optional */ 245 } else if (ret != -EINVAL) { 246 dev_err(dev, "could not parse property %s\n", 247 cfg_params[i].property); 248 } 249 } 250 251 reserve = 0; 252 if (function != NULL) 253 reserve++; 254 if (num_configs) 255 reserve++; 256 ret = of_property_count_strings(np, "nvidia,pins"); 257 if (ret < 0) { 258 dev_err(dev, "could not parse property nvidia,pins\n"); 259 goto exit; 260 } 261 reserve *= ret; 262 263 ret = reserve_map(dev, map, reserved_maps, num_maps, reserve); 264 if (ret < 0) 265 goto exit; 266 267 of_property_for_each_string(np, "nvidia,pins", prop, group) { 268 if (function) { 269 ret = add_map_mux(map, reserved_maps, num_maps, 270 group, function); 271 if (ret < 0) 272 goto exit; 273 } 274 275 if (num_configs) { 276 ret = add_map_configs(dev, map, reserved_maps, 277 num_maps, group, configs, 278 num_configs); 279 if (ret < 0) 280 goto exit; 281 } 282 } 283 284 ret = 0; 285 286exit: 287 kfree(configs); 288 return ret; 289} 290 291int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, 292 struct device_node *np_config, 293 struct pinctrl_map **map, unsigned *num_maps) 294{ 295 unsigned reserved_maps; 296 struct device_node *np; 297 int ret; 298 299 reserved_maps = 0; 300 *map = NULL; 301 *num_maps = 0; 302 303 for_each_child_of_node(np_config, np) { 304 ret = tegra_pinctrl_dt_subnode_to_map(pctldev->dev, np, map, 305 &reserved_maps, num_maps); 306 if (ret < 0) { 307 tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps); 308 return ret; 309 } 310 } 311 312 return 0; 313} 314 315static struct pinctrl_ops tegra_pinctrl_ops = { 316 .get_groups_count = tegra_pinctrl_get_groups_count, 317 .get_group_name = tegra_pinctrl_get_group_name, 318 .get_group_pins = tegra_pinctrl_get_group_pins, 319#ifdef CONFIG_DEBUG_FS 320 .pin_dbg_show = tegra_pinctrl_pin_dbg_show, 321#endif 322 .dt_node_to_map = tegra_pinctrl_dt_node_to_map, 323 .dt_free_map = tegra_pinctrl_dt_free_map, 324}; 325 326static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) 327{ 328 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 329 330 return pmx->soc->nfunctions; 331} 332 333static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 334 unsigned function) 335{ 336 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 337 338 return pmx->soc->functions[function].name; 339} 340 341static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, 342 unsigned function, 343 const char * const **groups, 344 unsigned * const num_groups) 345{ 346 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 347 348 *groups = pmx->soc->functions[function].groups; 349 *num_groups = pmx->soc->functions[function].ngroups; 350 351 return 0; 352} 353 354static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, 355 unsigned group) 356{ 357 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 358 const struct tegra_pingroup *g; 359 int i; 360 u32 val; 361 362 g = &pmx->soc->groups[group]; 363 364 if (WARN_ON(g->mux_reg < 0)) 365 return -EINVAL; 366 367 for (i = 0; i < ARRAY_SIZE(g->funcs); i++) { 368 if (g->funcs[i] == function) 369 break; 370 } 371 if (WARN_ON(i == ARRAY_SIZE(g->funcs))) 372 return -EINVAL; 373 374 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); 375 val &= ~(0x3 << g->mux_bit); 376 val |= i << g->mux_bit; 377 pmx_writel(pmx, val, g->mux_bank, g->mux_reg); 378 379 return 0; 380} 381 382static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, 383 unsigned function, unsigned group) 384{ 385 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 386 const struct tegra_pingroup *g; 387 u32 val; 388 389 g = &pmx->soc->groups[group]; 390 391 if (WARN_ON(g->mux_reg < 0)) 392 return; 393 394 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); 395 val &= ~(0x3 << g->mux_bit); 396 val |= g->func_safe << g->mux_bit; 397 pmx_writel(pmx, val, g->mux_bank, g->mux_reg); 398} 399 400static struct pinmux_ops tegra_pinmux_ops = { 401 .get_functions_count = tegra_pinctrl_get_funcs_count, 402 .get_function_name = tegra_pinctrl_get_func_name, 403 .get_function_groups = tegra_pinctrl_get_func_groups, 404 .enable = tegra_pinctrl_enable, 405 .disable = tegra_pinctrl_disable, 406}; 407 408static int tegra_pinconf_reg(struct tegra_pmx *pmx, 409 const struct tegra_pingroup *g, 410 enum tegra_pinconf_param param, 411 bool report_err, 412 s8 *bank, s16 *reg, s8 *bit, s8 *width) 413{ 414 switch (param) { 415 case TEGRA_PINCONF_PARAM_PULL: 416 *bank = g->pupd_bank; 417 *reg = g->pupd_reg; 418 *bit = g->pupd_bit; 419 *width = 2; 420 break; 421 case TEGRA_PINCONF_PARAM_TRISTATE: 422 *bank = g->tri_bank; 423 *reg = g->tri_reg; 424 *bit = g->tri_bit; 425 *width = 1; 426 break; 427 case TEGRA_PINCONF_PARAM_ENABLE_INPUT: 428 *bank = g->einput_bank; 429 *reg = g->einput_reg; 430 *bit = g->einput_bit; 431 *width = 1; 432 break; 433 case TEGRA_PINCONF_PARAM_OPEN_DRAIN: 434 *bank = g->odrain_bank; 435 *reg = g->odrain_reg; 436 *bit = g->odrain_bit; 437 *width = 1; 438 break; 439 case TEGRA_PINCONF_PARAM_LOCK: 440 *bank = g->lock_bank; 441 *reg = g->lock_reg; 442 *bit = g->lock_bit; 443 *width = 1; 444 break; 445 case TEGRA_PINCONF_PARAM_IORESET: 446 *bank = g->ioreset_bank; 447 *reg = g->ioreset_reg; 448 *bit = g->ioreset_bit; 449 *width = 1; 450 break; 451 case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE: 452 *bank = g->drv_bank; 453 *reg = g->drv_reg; 454 *bit = g->hsm_bit; 455 *width = 1; 456 break; 457 case TEGRA_PINCONF_PARAM_SCHMITT: 458 *bank = g->drv_bank; 459 *reg = g->drv_reg; 460 *bit = g->schmitt_bit; 461 *width = 1; 462 break; 463 case TEGRA_PINCONF_PARAM_LOW_POWER_MODE: 464 *bank = g->drv_bank; 465 *reg = g->drv_reg; 466 *bit = g->lpmd_bit; 467 *width = 2; 468 break; 469 case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH: 470 *bank = g->drv_bank; 471 *reg = g->drv_reg; 472 *bit = g->drvdn_bit; 473 *width = g->drvdn_width; 474 break; 475 case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH: 476 *bank = g->drv_bank; 477 *reg = g->drv_reg; 478 *bit = g->drvup_bit; 479 *width = g->drvup_width; 480 break; 481 case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING: 482 *bank = g->drv_bank; 483 *reg = g->drv_reg; 484 *bit = g->slwf_bit; 485 *width = g->slwf_width; 486 break; 487 case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING: 488 *bank = g->drv_bank; 489 *reg = g->drv_reg; 490 *bit = g->slwr_bit; 491 *width = g->slwr_width; 492 break; 493 default: 494 dev_err(pmx->dev, "Invalid config param %04x\n", param); 495 return -ENOTSUPP; 496 } 497 498 if (*reg < 0) { 499 if (report_err) 500 dev_err(pmx->dev, 501 "Config param %04x not supported on group %s\n", 502 param, g->name); 503 return -ENOTSUPP; 504 } 505 506 return 0; 507} 508 509static int tegra_pinconf_get(struct pinctrl_dev *pctldev, 510 unsigned pin, unsigned long *config) 511{ 512 dev_err(pctldev->dev, "pin_config_get op not supported\n"); 513 return -ENOTSUPP; 514} 515 516static int tegra_pinconf_set(struct pinctrl_dev *pctldev, 517 unsigned pin, unsigned long config) 518{ 519 dev_err(pctldev->dev, "pin_config_set op not supported\n"); 520 return -ENOTSUPP; 521} 522 523static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev, 524 unsigned group, unsigned long *config) 525{ 526 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 527 enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config); 528 u16 arg; 529 const struct tegra_pingroup *g; 530 int ret; 531 s8 bank, bit, width; 532 s16 reg; 533 u32 val, mask; 534 535 g = &pmx->soc->groups[group]; 536 537 ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, 538 &width); 539 if (ret < 0) 540 return ret; 541 542 val = pmx_readl(pmx, bank, reg); 543 mask = (1 << width) - 1; 544 arg = (val >> bit) & mask; 545 546 *config = TEGRA_PINCONF_PACK(param, arg); 547 548 return 0; 549} 550 551static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev, 552 unsigned group, unsigned long config) 553{ 554 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 555 enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config); 556 u16 arg = TEGRA_PINCONF_UNPACK_ARG(config); 557 const struct tegra_pingroup *g; 558 int ret; 559 s8 bank, bit, width; 560 s16 reg; 561 u32 val, mask; 562 563 g = &pmx->soc->groups[group]; 564 565 ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, 566 &width); 567 if (ret < 0) 568 return ret; 569 570 val = pmx_readl(pmx, bank, reg); 571 572 /* LOCK can't be cleared */ 573 if (param == TEGRA_PINCONF_PARAM_LOCK) { 574 if ((val & BIT(bit)) && !arg) { 575 dev_err(pctldev->dev, "LOCK bit cannot be cleared\n"); 576 return -EINVAL; 577 } 578 } 579 580 /* Special-case Boolean values; allow any non-zero as true */ 581 if (width == 1) 582 arg = !!arg; 583 584 /* Range-check user-supplied value */ 585 mask = (1 << width) - 1; 586 if (arg & ~mask) { 587 dev_err(pctldev->dev, 588 "config %lx: %x too big for %d bit register\n", 589 config, arg, width); 590 return -EINVAL; 591 } 592 593 /* Update register */ 594 val &= ~(mask << bit); 595 val |= arg << bit; 596 pmx_writel(pmx, val, bank, reg); 597 598 return 0; 599} 600 601#ifdef CONFIG_DEBUG_FS 602static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev, 603 struct seq_file *s, unsigned offset) 604{ 605} 606 607static const char *strip_prefix(const char *s) 608{ 609 const char *comma = strchr(s, ','); 610 if (!comma) 611 return s; 612 613 return comma + 1; 614} 615 616static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, 617 struct seq_file *s, unsigned group) 618{ 619 struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 620 const struct tegra_pingroup *g; 621 int i, ret; 622 s8 bank, bit, width; 623 s16 reg; 624 u32 val; 625 626 g = &pmx->soc->groups[group]; 627 628 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 629 ret = tegra_pinconf_reg(pmx, g, cfg_params[i].param, false, 630 &bank, &reg, &bit, &width); 631 if (ret < 0) 632 continue; 633 634 val = pmx_readl(pmx, bank, reg); 635 val >>= bit; 636 val &= (1 << width) - 1; 637 638 seq_printf(s, "\n\t%s=%u", 639 strip_prefix(cfg_params[i].property), val); 640 } 641} 642 643static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, 644 struct seq_file *s, 645 unsigned long config) 646{ 647 enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config); 648 u16 arg = TEGRA_PINCONF_UNPACK_ARG(config); 649 const char *pname = "unknown"; 650 int i; 651 652 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { 653 if (cfg_params[i].param == param) { 654 pname = cfg_params[i].property; 655 break; 656 } 657 } 658 659 seq_printf(s, "%s=%d", strip_prefix(pname), arg); 660} 661#endif 662 663struct pinconf_ops tegra_pinconf_ops = { 664 .pin_config_get = tegra_pinconf_get, 665 .pin_config_set = tegra_pinconf_set, 666 .pin_config_group_get = tegra_pinconf_group_get, 667 .pin_config_group_set = tegra_pinconf_group_set, 668#ifdef CONFIG_DEBUG_FS 669 .pin_config_dbg_show = tegra_pinconf_dbg_show, 670 .pin_config_group_dbg_show = tegra_pinconf_group_dbg_show, 671 .pin_config_config_dbg_show = tegra_pinconf_config_dbg_show, 672#endif 673}; 674 675static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = { 676 .name = "Tegra GPIOs", 677 .id = 0, 678 .base = 0, 679}; 680 681static struct pinctrl_desc tegra_pinctrl_desc = { 682 .pctlops = &tegra_pinctrl_ops, 683 .pmxops = &tegra_pinmux_ops, 684 .confops = &tegra_pinconf_ops, 685 .owner = THIS_MODULE, 686}; 687 688int __devinit tegra_pinctrl_probe(struct platform_device *pdev, 689 const struct tegra_pinctrl_soc_data *soc_data) 690{ 691 struct tegra_pmx *pmx; 692 struct resource *res; 693 int i; 694 695 pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL); 696 if (!pmx) { 697 dev_err(&pdev->dev, "Can't alloc tegra_pmx\n"); 698 return -ENOMEM; 699 } 700 pmx->dev = &pdev->dev; 701 pmx->soc = soc_data; 702 703 tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios; 704 tegra_pinctrl_desc.name = dev_name(&pdev->dev); 705 tegra_pinctrl_desc.pins = pmx->soc->pins; 706 tegra_pinctrl_desc.npins = pmx->soc->npins; 707 708 for (i = 0; ; i++) { 709 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 710 if (!res) 711 break; 712 } 713 pmx->nbanks = i; 714 715 pmx->regs = devm_kzalloc(&pdev->dev, pmx->nbanks * sizeof(*pmx->regs), 716 GFP_KERNEL); 717 if (!pmx->regs) { 718 dev_err(&pdev->dev, "Can't alloc regs pointer\n"); 719 return -ENODEV; 720 } 721 722 for (i = 0; i < pmx->nbanks; i++) { 723 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 724 if (!res) { 725 dev_err(&pdev->dev, "Missing MEM resource\n"); 726 return -ENODEV; 727 } 728 729 if (!devm_request_mem_region(&pdev->dev, res->start, 730 resource_size(res), 731 dev_name(&pdev->dev))) { 732 dev_err(&pdev->dev, 733 "Couldn't request MEM resource %d\n", i); 734 return -ENODEV; 735 } 736 737 pmx->regs[i] = devm_ioremap(&pdev->dev, res->start, 738 resource_size(res)); 739 if (!pmx->regs[i]) { 740 dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i); 741 return -ENODEV; 742 } 743 } 744 745 pmx->pctl = pinctrl_register(&tegra_pinctrl_desc, &pdev->dev, pmx); 746 if (!pmx->pctl) { 747 dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); 748 return -ENODEV; 749 } 750 751 pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range); 752 753 platform_set_drvdata(pdev, pmx); 754 755 dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n"); 756 757 return 0; 758} 759EXPORT_SYMBOL_GPL(tegra_pinctrl_probe); 760 761int __devexit tegra_pinctrl_remove(struct platform_device *pdev) 762{ 763 struct tegra_pmx *pmx = platform_get_drvdata(pdev); 764 765 pinctrl_unregister(pmx->pctl); 766 767 return 0; 768} 769EXPORT_SYMBOL_GPL(tegra_pinctrl_remove);