aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/gpio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-15 11:07:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-15 11:07:35 -0400
commit5f2434a66dfa4701b81b79a78eaf9c32da0f8839 (patch)
tree8c38f1fb0d0fbcd15e496df89be00ad8c4918a43 /drivers/of/gpio.c
parent278429cff8809958d25415ba0ed32b59866ab1a8 (diff)
parent6dc6472581f693b5fc95aebedf67b4960fb85cf0 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (158 commits) powerpc: Fix CHRP PCI config access for indirect_pci powerpc/chrp: Fix detection of Python PCI host bridge on IBM CHRPs powerpc: Fix 32-bit SMP boot on CHRP powerpc: Fix link errors on 32-bit machines using legacy DMA powerpc/pci: Improve detection of unassigned bridge resources hvc_console: Fix free_irq in spinlocked section powerpc: Get USE_STRICT_MM_TYPECHECKS working again powerpc: Reflect the used arguments in machine_init() prototype powerpc: Fix DMA offset for non-coherent DMA powerpc: fix fsl_upm nand driver modular build powerpc/83xx: add NAND support for the MPC8360E-RDK boards powerpc: FPGA support for GE Fanuc SBC610 i2c: MPC8349E-mITX Power Management and GPIO expander driver powerpc: reserve two DMA channels for audio in MPC8610 HPCD device tree powerpc: document the "fsl,ssi-dma-channel" compatible property powerpc: disable CHRP and PMAC support in various defconfigs OF: add fsl,mcu-mpc8349emitx to the exception list powerpc/83xx: add DS1374 RTC support for the MPC837xE-MDS boards powerpc: remove support for bootmem-allocated memory for the DIU driver powerpc: remove non-dependent load fsl_booke PTE_64BIT ...
Diffstat (limited to 'drivers/of/gpio.c')
-rw-r--r--drivers/of/gpio.c81
1 files changed, 19 insertions, 62 deletions
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 1c9cab844f10..7cd7301b5839 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -28,78 +28,35 @@
28 */ 28 */
29int of_get_gpio(struct device_node *np, int index) 29int of_get_gpio(struct device_node *np, int index)
30{ 30{
31 int ret = -EINVAL; 31 int ret;
32 struct device_node *gc; 32 struct device_node *gc;
33 struct of_gpio_chip *of_gc = NULL; 33 struct of_gpio_chip *of_gc = NULL;
34 int size; 34 int size;
35 const u32 *gpios;
36 u32 nr_cells;
37 int i;
38 const void *gpio_spec; 35 const void *gpio_spec;
39 const u32 *gpio_cells; 36 const u32 *gpio_cells;
40 int gpio_index = 0;
41 37
42 gpios = of_get_property(np, "gpios", &size); 38 ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
43 if (!gpios) { 39 &gc, &gpio_spec);
44 ret = -ENOENT; 40 if (ret) {
41 pr_debug("%s: can't parse gpios property\n", __func__);
45 goto err0; 42 goto err0;
46 } 43 }
47 nr_cells = size / sizeof(u32);
48
49 for (i = 0; i < nr_cells; gpio_index++) {
50 const phandle *gpio_phandle;
51
52 gpio_phandle = gpios + i;
53 gpio_spec = gpio_phandle + 1;
54
55 /* one cell hole in the gpios = <>; */
56 if (!*gpio_phandle) {
57 if (gpio_index == index)
58 return -ENOENT;
59 i++;
60 continue;
61 }
62
63 gc = of_find_node_by_phandle(*gpio_phandle);
64 if (!gc) {
65 pr_debug("%s: could not find phandle for gpios\n",
66 np->full_name);
67 goto err0;
68 }
69
70 of_gc = gc->data;
71 if (!of_gc) {
72 pr_debug("%s: gpio controller %s isn't registered\n",
73 np->full_name, gc->full_name);
74 goto err1;
75 }
76
77 gpio_cells = of_get_property(gc, "#gpio-cells", &size);
78 if (!gpio_cells || size != sizeof(*gpio_cells) ||
79 *gpio_cells != of_gc->gpio_cells) {
80 pr_debug("%s: wrong #gpio-cells for %s\n",
81 np->full_name, gc->full_name);
82 goto err1;
83 }
84
85 /* Next phandle is at phandle cells + #gpio-cells */
86 i += sizeof(*gpio_phandle) / sizeof(u32) + *gpio_cells;
87 if (i >= nr_cells + 1) {
88 pr_debug("%s: insufficient gpio-spec length\n",
89 np->full_name);
90 goto err1;
91 }
92
93 if (gpio_index == index)
94 break;
95
96 of_gc = NULL;
97 of_node_put(gc);
98 }
99 44
45 of_gc = gc->data;
100 if (!of_gc) { 46 if (!of_gc) {
101 ret = -ENOENT; 47 pr_debug("%s: gpio controller %s isn't registered\n",
102 goto err0; 48 np->full_name, gc->full_name);
49 ret = -ENODEV;
50 goto err1;
51 }
52
53 gpio_cells = of_get_property(gc, "#gpio-cells", &size);
54 if (!gpio_cells || size != sizeof(*gpio_cells) ||
55 *gpio_cells != of_gc->gpio_cells) {
56 pr_debug("%s: wrong #gpio-cells for %s\n",
57 np->full_name, gc->full_name);
58 ret = -EINVAL;
59 goto err1;
103 } 60 }
104 61
105 ret = of_gc->xlate(of_gc, np, gpio_spec); 62 ret = of_gc->xlate(of_gc, np, gpio_spec);