aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-04-11 14:53:09 -0400
committerStephen Warren <swarren@nvidia.com>2012-04-18 12:26:40 -0400
commit52f48fe00fcad83cd5fc4c961d851a3530fe032b (patch)
tree68fdb2a2580914f17b74374ad6b390027824c389 /drivers/pinctrl
parentecc295bbab6b9d1baf0c0a8c2d5a945b201df547 (diff)
pinctrl: tegra: refactor probe handling
Rather than having a single tegra-pinctrl driver that determines whether it's running on Tegra20 or Tegra30, instead have separate drivers for each that call into utility functions to implement the majority of the driver. This change is based on review feedback of the SPEAr pinctrl driver, which had originally copied to Tegra driver structure. This requires that the two drivers have unique names. Update a couple spots in arch/arm/mach-tegra for the name change. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c80
-rw-r--r--drivers/pinctrl/pinctrl-tegra.h23
-rw-r--r--drivers/pinctrl/pinctrl-tegra20.c40
-rw-r--r--drivers/pinctrl/pinctrl-tegra30.c40
4 files changed, 89 insertions, 94 deletions
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index f6eba9c3c9e2..3ac8ad3829e4 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the NVIDIA Tegra pinmux 2 * Driver for the NVIDIA Tegra pinmux
3 * 3 *
4 * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * Derived from code: 6 * Derived from code:
7 * Copyright (C) 2010 Google, Inc. 7 * Copyright (C) 2010 Google, Inc.
@@ -22,7 +22,8 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/of_device.h> 25#include <linux/of.h>
26#include <linux/platform_device.h>
26#include <linux/pinctrl/machine.h> 27#include <linux/pinctrl/machine.h>
27#include <linux/pinctrl/pinctrl.h> 28#include <linux/pinctrl/pinctrl.h>
28#include <linux/pinctrl/pinmux.h> 29#include <linux/pinctrl/pinmux.h>
@@ -31,10 +32,9 @@
31 32
32#include <mach/pinconf-tegra.h> 33#include <mach/pinconf-tegra.h>
33 34
35#include "core.h"
34#include "pinctrl-tegra.h" 36#include "pinctrl-tegra.h"
35 37
36#define DRIVER_NAME "tegra-pinmux"
37
38struct tegra_pmx { 38struct tegra_pmx {
39 struct device *dev; 39 struct device *dev;
40 struct pinctrl_dev *pctl; 40 struct pinctrl_dev *pctl;
@@ -87,7 +87,7 @@ static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
87 struct seq_file *s, 87 struct seq_file *s,
88 unsigned offset) 88 unsigned offset)
89{ 89{
90 seq_printf(s, " " DRIVER_NAME); 90 seq_printf(s, " %s", dev_name(pctldev->dev));
91} 91}
92 92
93static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps, 93static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
@@ -589,60 +589,29 @@ static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
589}; 589};
590 590
591static struct pinctrl_desc tegra_pinctrl_desc = { 591static struct pinctrl_desc tegra_pinctrl_desc = {
592 .name = DRIVER_NAME,
593 .pctlops = &tegra_pinctrl_ops, 592 .pctlops = &tegra_pinctrl_ops,
594 .pmxops = &tegra_pinmux_ops, 593 .pmxops = &tegra_pinmux_ops,
595 .confops = &tegra_pinconf_ops, 594 .confops = &tegra_pinconf_ops,
596 .owner = THIS_MODULE, 595 .owner = THIS_MODULE,
597}; 596};
598 597
599static struct of_device_id tegra_pinctrl_of_match[] __devinitdata = { 598int __devinit tegra_pinctrl_probe(struct platform_device *pdev,
600#ifdef CONFIG_PINCTRL_TEGRA20 599 const struct tegra_pinctrl_soc_data *soc_data)
601 {
602 .compatible = "nvidia,tegra20-pinmux",
603 .data = tegra20_pinctrl_init,
604 },
605#endif
606#ifdef CONFIG_PINCTRL_TEGRA30
607 {
608 .compatible = "nvidia,tegra30-pinmux",
609 .data = tegra30_pinctrl_init,
610 },
611#endif
612 {},
613};
614
615static int __devinit tegra_pinctrl_probe(struct platform_device *pdev)
616{ 600{
617 const struct of_device_id *match;
618 tegra_pinctrl_soc_initf initf = NULL;
619 struct tegra_pmx *pmx; 601 struct tegra_pmx *pmx;
620 struct resource *res; 602 struct resource *res;
621 int i; 603 int i;
622 604
623 match = of_match_device(tegra_pinctrl_of_match, &pdev->dev);
624 if (match)
625 initf = (tegra_pinctrl_soc_initf)match->data;
626#ifdef CONFIG_PINCTRL_TEGRA20
627 if (!initf)
628 initf = tegra20_pinctrl_init;
629#endif
630 if (!initf) {
631 dev_err(&pdev->dev,
632 "Could not determine SoC-specific init func\n");
633 return -EINVAL;
634 }
635
636 pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL); 605 pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
637 if (!pmx) { 606 if (!pmx) {
638 dev_err(&pdev->dev, "Can't alloc tegra_pmx\n"); 607 dev_err(&pdev->dev, "Can't alloc tegra_pmx\n");
639 return -ENOMEM; 608 return -ENOMEM;
640 } 609 }
641 pmx->dev = &pdev->dev; 610 pmx->dev = &pdev->dev;
642 611 pmx->soc = soc_data;
643 (*initf)(&pmx->soc);
644 612
645 tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios; 613 tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
614 tegra_pinctrl_desc.name = dev_name(&pdev->dev);
646 tegra_pinctrl_desc.pins = pmx->soc->pins; 615 tegra_pinctrl_desc.pins = pmx->soc->pins;
647 tegra_pinctrl_desc.npins = pmx->soc->npins; 616 tegra_pinctrl_desc.npins = pmx->soc->npins;
648 617
@@ -697,8 +666,9 @@ static int __devinit tegra_pinctrl_probe(struct platform_device *pdev)
697 666
698 return 0; 667 return 0;
699} 668}
669EXPORT_SYMBOL_GPL(tegra_pinctrl_probe);
700 670
701static int __devexit tegra_pinctrl_remove(struct platform_device *pdev) 671int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
702{ 672{
703 struct tegra_pmx *pmx = platform_get_drvdata(pdev); 673 struct tegra_pmx *pmx = platform_get_drvdata(pdev);
704 674
@@ -707,30 +677,4 @@ static int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
707 677
708 return 0; 678 return 0;
709} 679}
710 680EXPORT_SYMBOL_GPL(tegra_pinctrl_remove);
711static struct platform_driver tegra_pinctrl_driver = {
712 .driver = {
713 .name = DRIVER_NAME,
714 .owner = THIS_MODULE,
715 .of_match_table = tegra_pinctrl_of_match,
716 },
717 .probe = tegra_pinctrl_probe,
718 .remove = __devexit_p(tegra_pinctrl_remove),
719};
720
721static int __init tegra_pinctrl_init(void)
722{
723 return platform_driver_register(&tegra_pinctrl_driver);
724}
725arch_initcall(tegra_pinctrl_init);
726
727static void __exit tegra_pinctrl_exit(void)
728{
729 platform_driver_unregister(&tegra_pinctrl_driver);
730}
731module_exit(tegra_pinctrl_exit);
732
733MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
734MODULE_DESCRIPTION("NVIDIA Tegra pinctrl driver");
735MODULE_LICENSE("GPL v2");
736MODULE_DEVICE_TABLE(of, tegra_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-tegra.h b/drivers/pinctrl/pinctrl-tegra.h
index 782c795326ef..705c007a38cc 100644
--- a/drivers/pinctrl/pinctrl-tegra.h
+++ b/drivers/pinctrl/pinctrl-tegra.h
@@ -139,25 +139,8 @@ struct tegra_pinctrl_soc_data {
139 unsigned ngroups; 139 unsigned ngroups;
140}; 140};
141 141
142/** 142int tegra_pinctrl_probe(struct platform_device *pdev,
143 * tegra_pinctrl_soc_initf() - Retrieve pin controller details for a SoC. 143 const struct tegra_pinctrl_soc_data *soc_data);
144 * @soc_data: This pointer must be updated to point at a struct containing 144int tegra_pinctrl_remove(struct platform_device *pdev);
145 * details of the SoC.
146 */
147typedef void (*tegra_pinctrl_soc_initf)(
148 const struct tegra_pinctrl_soc_data **soc_data);
149
150/**
151 * tegra20_pinctrl_init() - Retrieve pin controller details for Tegra20
152 * @soc_data: This pointer will be updated to point at a struct containing
153 * details of Tegra20's pin controller.
154 */
155void tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
156/**
157 * tegra30_pinctrl_init() - Retrieve pin controller details for Tegra20
158 * @soc_data: This pointer will be updated to point at a struct containing
159 * details of Tegra30's pin controller.
160 */
161void tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
162 145
163#endif 146#endif
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
index f69ff96aa292..a74f9a568536 100644
--- a/drivers/pinctrl/pinctrl-tegra20.c
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Pinctrl data for the NVIDIA Tegra20 pinmux 2 * Pinctrl data for the NVIDIA Tegra20 pinmux
3 * 3 *
4 * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * Derived from code: 6 * Derived from code:
7 * Copyright (C) 2010 Google, Inc. 7 * Copyright (C) 2010 Google, Inc.
@@ -17,6 +17,8 @@
17 * more details. 17 * more details.
18 */ 18 */
19 19
20#include <linux/module.h>
21#include <linux/of.h>
20#include <linux/platform_device.h> 22#include <linux/platform_device.h>
21#include <linux/pinctrl/pinctrl.h> 23#include <linux/pinctrl/pinctrl.h>
22#include <linux/pinctrl/pinmux.h> 24#include <linux/pinctrl/pinmux.h>
@@ -2854,7 +2856,39 @@ static const struct tegra_pinctrl_soc_data tegra20_pinctrl = {
2854 .ngroups = ARRAY_SIZE(tegra20_groups), 2856 .ngroups = ARRAY_SIZE(tegra20_groups),
2855}; 2857};
2856 2858
2857void __devinit tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc) 2859static int __devinit tegra20_pinctrl_probe(struct platform_device *pdev)
2858{ 2860{
2859 *soc = &tegra20_pinctrl; 2861 return tegra_pinctrl_probe(pdev, &tegra20_pinctrl);
2860} 2862}
2863
2864static struct of_device_id tegra20_pinctrl_of_match[] __devinitdata = {
2865 { .compatible = "nvidia,tegra20-pinmux", },
2866 { },
2867};
2868
2869static struct platform_driver tegra20_pinctrl_driver = {
2870 .driver = {
2871 .name = "tegra20-pinctrl",
2872 .owner = THIS_MODULE,
2873 .of_match_table = tegra20_pinctrl_of_match,
2874 },
2875 .probe = tegra20_pinctrl_probe,
2876 .remove = __devexit_p(tegra_pinctrl_remove),
2877};
2878
2879static int __init tegra20_pinctrl_init(void)
2880{
2881 return platform_driver_register(&tegra20_pinctrl_driver);
2882}
2883arch_initcall(tegra20_pinctrl_init);
2884
2885static void __exit tegra20_pinctrl_exit(void)
2886{
2887 platform_driver_unregister(&tegra20_pinctrl_driver);
2888}
2889module_exit(tegra20_pinctrl_exit);
2890
2891MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
2892MODULE_DESCRIPTION("NVIDIA Tegra20 pinctrl driver");
2893MODULE_LICENSE("GPL v2");
2894MODULE_DEVICE_TABLE(of, tegra20_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 4d7571d4a431..0386fdf0da16 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Pinctrl data for the NVIDIA Tegra30 pinmux 2 * Pinctrl data for the NVIDIA Tegra30 pinmux
3 * 3 *
4 * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -13,6 +13,8 @@
13 * more details. 13 * more details.
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/of.h>
16#include <linux/platform_device.h> 18#include <linux/platform_device.h>
17#include <linux/pinctrl/pinctrl.h> 19#include <linux/pinctrl/pinctrl.h>
18#include <linux/pinctrl/pinmux.h> 20#include <linux/pinctrl/pinmux.h>
@@ -3720,7 +3722,39 @@ static const struct tegra_pinctrl_soc_data tegra30_pinctrl = {
3720 .ngroups = ARRAY_SIZE(tegra30_groups), 3722 .ngroups = ARRAY_SIZE(tegra30_groups),
3721}; 3723};
3722 3724
3723void __devinit tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc) 3725static int __devinit tegra30_pinctrl_probe(struct platform_device *pdev)
3724{ 3726{
3725 *soc = &tegra30_pinctrl; 3727 return tegra_pinctrl_probe(pdev, &tegra30_pinctrl);
3726} 3728}
3729
3730static struct of_device_id tegra30_pinctrl_of_match[] __devinitdata = {
3731 { .compatible = "nvidia,tegra30-pinmux", },
3732 { },
3733};
3734
3735static struct platform_driver tegra30_pinctrl_driver = {
3736 .driver = {
3737 .name = "tegra30-pinctrl",
3738 .owner = THIS_MODULE,
3739 .of_match_table = tegra30_pinctrl_of_match,
3740 },
3741 .probe = tegra30_pinctrl_probe,
3742 .remove = __devexit_p(tegra_pinctrl_remove),
3743};
3744
3745static int __init tegra30_pinctrl_init(void)
3746{
3747 return platform_driver_register(&tegra30_pinctrl_driver);
3748}
3749arch_initcall(tegra30_pinctrl_init);
3750
3751static void __exit tegra30_pinctrl_exit(void)
3752{
3753 platform_driver_unregister(&tegra30_pinctrl_driver);
3754}
3755module_exit(tegra30_pinctrl_exit);
3756
3757MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
3758MODULE_DESCRIPTION("NVIDIA Tegra30 pinctrl driver");
3759MODULE_LICENSE("GPL v2");
3760MODULE_DEVICE_TABLE(of, tegra30_pinctrl_of_match);