diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-06-08 09:48:16 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-07-05 18:14:30 -0400 |
commit | 594fa265e084073443390c5b93d5410fd28e9bcd (patch) | |
tree | 42c0e5536ae2fd016159e1e1bd1f27f0a9f3cac2 /arch | |
parent | a19e3da5bc5fc6c10ab73f310bea80f3845b4531 (diff) |
of/gpio: stop using device_node data pointer to find gpio_chip
Currently the kernel uses the struct device_node.data pointer to resolve
a struct gpio_chip pointer from a device tree node. However, the .data
member doesn't provide any type checking and there aren't any rules
enforced on what it should be used for. There's no guarantee that the
data stored in it actually points to an gpio_chip pointer.
Instead of relying on the .data pointer, this patch modifies the code
to add a lookup function which scans through the registered gpio_chips
and returns the gpio_chip that has a pointer to the specified
device_node.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Anton Vorontsov <avorontsov@ru.mvista.com>
CC: Grant Likely <grant.likely@secretlab.ca>
CC: David Brownell <dbrownell@users.sourceforge.net>
CC: Bill Gatliff <bgat@billgatliff.com>
CC: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Jean Delvare <khali@linux-fr.org>
CC: linux-kernel@vger.kernel.org
CC: devicetree-discuss@lists.ozlabs.org
Diffstat (limited to 'arch')
-rw-r--r-- | arch/microblaze/kernel/reset.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | 23 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/gpio.c | 2 |
4 files changed, 6 insertions, 22 deletions
diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index 5476d3caf04..bd8ccab5cef 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c | |||
@@ -39,7 +39,7 @@ static int of_reset_gpio_handle(void) | |||
39 | goto err0; | 39 | goto err0; |
40 | } | 40 | } |
41 | 41 | ||
42 | gc = gpio->data; | 42 | gc = of_node_to_gpiochip(gpio); |
43 | if (!gc) { | 43 | if (!gc) { |
44 | pr_debug("%s: gpio controller %s isn't registered\n", | 44 | pr_debug("%s: gpio controller %s isn't registered\n", |
45 | root->full_name, gpio->full_name); | 45 | root->full_name, gpio->full_name); |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 3f2ee47f1d0..6e82bd27132 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c | |||
@@ -350,6 +350,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) | |||
350 | gpt->gc.base = -1; | 350 | gpt->gc.base = -1; |
351 | gpt->gc.of_gpio_n_cells = 2; | 351 | gpt->gc.of_gpio_n_cells = 2; |
352 | gpt->gc.of_xlate = of_gpio_simple_xlate; | 352 | gpt->gc.of_xlate = of_gpio_simple_xlate; |
353 | gpt->gc.of_node = node; | ||
353 | of_node_get(node); | 354 | of_node_get(node); |
354 | 355 | ||
355 | /* Setup external pin in GPIO mode */ | 356 | /* Setup external pin in GPIO mode */ |
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index e49f4bd2f99..f0dbace6185 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | struct mcu { | 36 | struct mcu { |
37 | struct mutex lock; | 37 | struct mutex lock; |
38 | struct device_node *np; | ||
39 | struct i2c_client *client; | 38 | struct i2c_client *client; |
40 | struct gpio_chip gc; | 39 | struct gpio_chip gc; |
41 | u8 reg_ctrl; | 40 | u8 reg_ctrl; |
@@ -79,7 +78,6 @@ static int mcu_gpiochip_add(struct mcu *mcu) | |||
79 | { | 78 | { |
80 | struct device_node *np; | 79 | struct device_node *np; |
81 | struct gpio_chip *gc = &mcu->gc; | 80 | struct gpio_chip *gc = &mcu->gc; |
82 | int ret; | ||
83 | 81 | ||
84 | np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); | 82 | np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); |
85 | if (!np) | 83 | if (!np) |
@@ -94,29 +92,14 @@ static int mcu_gpiochip_add(struct mcu *mcu) | |||
94 | gc->direction_output = mcu_gpio_dir_out; | 92 | gc->direction_output = mcu_gpio_dir_out; |
95 | gc->of_gpio_n_cells = 2; | 93 | gc->of_gpio_n_cells = 2; |
96 | gc->of_xlate = of_gpio_simple_xlate; | 94 | gc->of_xlate = of_gpio_simple_xlate; |
95 | gc->of_node = np; | ||
97 | 96 | ||
98 | mcu->np = np; | 97 | return gpiochip_add(gc); |
99 | |||
100 | /* | ||
101 | * We don't want to lose the node, its ->data and ->full_name... | ||
102 | * So, if succeeded, we don't put the node here. | ||
103 | */ | ||
104 | ret = gpiochip_add(gc); | ||
105 | if (ret) | ||
106 | of_node_put(np); | ||
107 | return ret; | ||
108 | } | 98 | } |
109 | 99 | ||
110 | static int mcu_gpiochip_remove(struct mcu *mcu) | 100 | static int mcu_gpiochip_remove(struct mcu *mcu) |
111 | { | 101 | { |
112 | int ret; | 102 | return gpiochip_remove(&mcu->gc); |
113 | |||
114 | ret = gpiochip_remove(&mcu->gc); | ||
115 | if (ret) | ||
116 | return ret; | ||
117 | of_node_put(mcu->np); | ||
118 | |||
119 | return 0; | ||
120 | } | 103 | } |
121 | 104 | ||
122 | static int __devinit mcu_probe(struct i2c_client *client, | 105 | static int __devinit mcu_probe(struct i2c_client *client, |
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 194478c2f4b..32e9440010a 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c | |||
@@ -167,7 +167,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) | |||
167 | goto err1; | 167 | goto err1; |
168 | } | 168 | } |
169 | 169 | ||
170 | gc = gpio_np->data; | 170 | gc = of_node_to_gpiochip(gpio_np); |
171 | if (!gc) { | 171 | if (!gc) { |
172 | pr_debug("%s: gpio controller %s isn't registered\n", | 172 | pr_debug("%s: gpio controller %s isn't registered\n", |
173 | np->full_name, gpio_np->full_name); | 173 | np->full_name, gpio_np->full_name); |