diff options
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 7 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_soc.h | 5 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/Kconfig | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/gpio.c | 195 | ||||
-rw-r--r-- | arch/powerpc/sysdev/simple_gpio.c | 155 | ||||
-rw-r--r-- | arch/powerpc/sysdev/simple_gpio.h | 12 |
7 files changed, 374 insertions, 4 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 5afce115ab1..b33b28a6fe1 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) | |||
17 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o | 17 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o |
18 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o | 18 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o |
19 | obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o | 19 | obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o |
20 | obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o | ||
20 | obj-$(CONFIG_RAPIDIO) += fsl_rio.o | 21 | obj-$(CONFIG_RAPIDIO) += fsl_rio.o |
21 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o | 22 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o |
22 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ | 23 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index d5f9ae0f1b7..f611d0369cc 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -29,7 +29,8 @@ | |||
29 | 29 | ||
30 | #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) | 30 | #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) |
31 | /* atmu setup for fsl pci/pcie controller */ | 31 | /* atmu setup for fsl pci/pcie controller */ |
32 | void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) | 32 | static void __init setup_pci_atmu(struct pci_controller *hose, |
33 | struct resource *rsrc) | ||
33 | { | 34 | { |
34 | struct ccsr_pci __iomem *pci; | 35 | struct ccsr_pci __iomem *pci; |
35 | int i; | 36 | int i; |
@@ -86,7 +87,7 @@ void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) | |||
86 | out_be32(&pci->piw[2].piwar, PIWAR_2G); | 87 | out_be32(&pci->piw[2].piwar, PIWAR_2G); |
87 | } | 88 | } |
88 | 89 | ||
89 | void __init setup_pci_cmd(struct pci_controller *hose) | 90 | static void __init setup_pci_cmd(struct pci_controller *hose) |
90 | { | 91 | { |
91 | u16 cmd; | 92 | u16 cmd; |
92 | int cap_x; | 93 | int cap_x; |
@@ -130,7 +131,7 @@ static void __init quirk_fsl_pcie_header(struct pci_dev *dev) | |||
130 | return ; | 131 | return ; |
131 | } | 132 | } |
132 | 133 | ||
133 | int __init fsl_pcie_check_link(struct pci_controller *hose) | 134 | static int __init fsl_pcie_check_link(struct pci_controller *hose) |
134 | { | 135 | { |
135 | u32 val; | 136 | u32 val; |
136 | early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); | 137 | early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); |
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 60f7f227327..9c744e4285a 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h | |||
@@ -5,8 +5,13 @@ | |||
5 | #include <asm/mmu.h> | 5 | #include <asm/mmu.h> |
6 | 6 | ||
7 | extern phys_addr_t get_immrbase(void); | 7 | extern phys_addr_t get_immrbase(void); |
8 | #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) | ||
8 | extern u32 get_brgfreq(void); | 9 | extern u32 get_brgfreq(void); |
9 | extern u32 get_baudrate(void); | 10 | extern u32 get_baudrate(void); |
11 | #else | ||
12 | static inline u32 get_brgfreq(void) { return -1; } | ||
13 | static inline u32 get_baudrate(void) { return -1; } | ||
14 | #endif | ||
10 | extern u32 fsl_get_sys_freq(void); | 15 | extern u32 fsl_get_sys_freq(void); |
11 | 16 | ||
12 | struct spi_board_info; | 17 | struct spi_board_info; |
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index 76ffbc48d4b..41ac3dfac98 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig | |||
@@ -22,5 +22,6 @@ config UCC | |||
22 | 22 | ||
23 | config QE_USB | 23 | config QE_USB |
24 | bool | 24 | bool |
25 | default y if USB_GADGET_FSL_QE | ||
25 | help | 26 | help |
26 | QE USB Host Controller support | 27 | QE USB Controller support |
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 8e5a0bc36d0..3485288dce3 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/err.h> | ||
17 | #include <linux/io.h> | 18 | #include <linux/io.h> |
18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
@@ -24,8 +25,14 @@ struct qe_gpio_chip { | |||
24 | struct of_mm_gpio_chip mm_gc; | 25 | struct of_mm_gpio_chip mm_gc; |
25 | spinlock_t lock; | 26 | spinlock_t lock; |
26 | 27 | ||
28 | unsigned long pin_flags[QE_PIO_PINS]; | ||
29 | #define QE_PIN_REQUESTED 0 | ||
30 | |||
27 | /* shadowed data register to clear/set bits safely */ | 31 | /* shadowed data register to clear/set bits safely */ |
28 | u32 cpdata; | 32 | u32 cpdata; |
33 | |||
34 | /* saved_regs used to restore dedicated functions */ | ||
35 | struct qe_pio_regs saved_regs; | ||
29 | }; | 36 | }; |
30 | 37 | ||
31 | static inline struct qe_gpio_chip * | 38 | static inline struct qe_gpio_chip * |
@@ -40,6 +47,12 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) | |||
40 | struct qe_pio_regs __iomem *regs = mm_gc->regs; | 47 | struct qe_pio_regs __iomem *regs = mm_gc->regs; |
41 | 48 | ||
42 | qe_gc->cpdata = in_be32(®s->cpdata); | 49 | qe_gc->cpdata = in_be32(®s->cpdata); |
50 | qe_gc->saved_regs.cpdata = qe_gc->cpdata; | ||
51 | qe_gc->saved_regs.cpdir1 = in_be32(®s->cpdir1); | ||
52 | qe_gc->saved_regs.cpdir2 = in_be32(®s->cpdir2); | ||
53 | qe_gc->saved_regs.cppar1 = in_be32(®s->cppar1); | ||
54 | qe_gc->saved_regs.cppar2 = in_be32(®s->cppar2); | ||
55 | qe_gc->saved_regs.cpodr = in_be32(®s->cpodr); | ||
43 | } | 56 | } |
44 | 57 | ||
45 | static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) | 58 | static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) |
@@ -103,6 +116,188 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
103 | return 0; | 116 | return 0; |
104 | } | 117 | } |
105 | 118 | ||
119 | struct qe_pin { | ||
120 | /* | ||
121 | * The qe_gpio_chip name is unfortunate, we should change that to | ||
122 | * something like qe_pio_controller. Someday. | ||
123 | */ | ||
124 | struct qe_gpio_chip *controller; | ||
125 | int num; | ||
126 | }; | ||
127 | |||
128 | /** | ||
129 | * qe_pin_request - Request a QE pin | ||
130 | * @np: device node to get a pin from | ||
131 | * @index: index of a pin in the device tree | ||
132 | * Context: non-atomic | ||
133 | * | ||
134 | * This function return qe_pin so that you could use it with the rest of | ||
135 | * the QE Pin Multiplexing API. | ||
136 | */ | ||
137 | struct qe_pin *qe_pin_request(struct device_node *np, int index) | ||
138 | { | ||
139 | struct qe_pin *qe_pin; | ||
140 | struct device_node *gc; | ||
141 | struct of_gpio_chip *of_gc = NULL; | ||
142 | struct of_mm_gpio_chip *mm_gc; | ||
143 | struct qe_gpio_chip *qe_gc; | ||
144 | int err; | ||
145 | int size; | ||
146 | const void *gpio_spec; | ||
147 | const u32 *gpio_cells; | ||
148 | unsigned long flags; | ||
149 | |||
150 | qe_pin = kzalloc(sizeof(*qe_pin), GFP_KERNEL); | ||
151 | if (!qe_pin) { | ||
152 | pr_debug("%s: can't allocate memory\n", __func__); | ||
153 | return ERR_PTR(-ENOMEM); | ||
154 | } | ||
155 | |||
156 | err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, | ||
157 | &gc, &gpio_spec); | ||
158 | if (err) { | ||
159 | pr_debug("%s: can't parse gpios property\n", __func__); | ||
160 | goto err0; | ||
161 | } | ||
162 | |||
163 | if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) { | ||
164 | pr_debug("%s: tried to get a non-qe pin\n", __func__); | ||
165 | err = -EINVAL; | ||
166 | goto err1; | ||
167 | } | ||
168 | |||
169 | of_gc = gc->data; | ||
170 | if (!of_gc) { | ||
171 | pr_debug("%s: gpio controller %s isn't registered\n", | ||
172 | np->full_name, gc->full_name); | ||
173 | err = -ENODEV; | ||
174 | goto err1; | ||
175 | } | ||
176 | |||
177 | gpio_cells = of_get_property(gc, "#gpio-cells", &size); | ||
178 | if (!gpio_cells || size != sizeof(*gpio_cells) || | ||
179 | *gpio_cells != of_gc->gpio_cells) { | ||
180 | pr_debug("%s: wrong #gpio-cells for %s\n", | ||
181 | np->full_name, gc->full_name); | ||
182 | err = -EINVAL; | ||
183 | goto err1; | ||
184 | } | ||
185 | |||
186 | err = of_gc->xlate(of_gc, np, gpio_spec, NULL); | ||
187 | if (err < 0) | ||
188 | goto err1; | ||
189 | |||
190 | mm_gc = to_of_mm_gpio_chip(&of_gc->gc); | ||
191 | qe_gc = to_qe_gpio_chip(mm_gc); | ||
192 | |||
193 | spin_lock_irqsave(&qe_gc->lock, flags); | ||
194 | |||
195 | if (test_and_set_bit(QE_PIN_REQUESTED, &qe_gc->pin_flags[err]) == 0) { | ||
196 | qe_pin->controller = qe_gc; | ||
197 | qe_pin->num = err; | ||
198 | err = 0; | ||
199 | } else { | ||
200 | err = -EBUSY; | ||
201 | } | ||
202 | |||
203 | spin_unlock_irqrestore(&qe_gc->lock, flags); | ||
204 | |||
205 | if (!err) | ||
206 | return qe_pin; | ||
207 | err1: | ||
208 | of_node_put(gc); | ||
209 | err0: | ||
210 | kfree(qe_pin); | ||
211 | pr_debug("%s failed with status %d\n", __func__, err); | ||
212 | return ERR_PTR(err); | ||
213 | } | ||
214 | EXPORT_SYMBOL(qe_pin_request); | ||
215 | |||
216 | /** | ||
217 | * qe_pin_free - Free a pin | ||
218 | * @qe_pin: pointer to the qe_pin structure | ||
219 | * Context: any | ||
220 | * | ||
221 | * This function frees the qe_pin structure and makes a pin available | ||
222 | * for further qe_pin_request() calls. | ||
223 | */ | ||
224 | void qe_pin_free(struct qe_pin *qe_pin) | ||
225 | { | ||
226 | struct qe_gpio_chip *qe_gc = qe_pin->controller; | ||
227 | unsigned long flags; | ||
228 | const int pin = qe_pin->num; | ||
229 | |||
230 | spin_lock_irqsave(&qe_gc->lock, flags); | ||
231 | test_and_clear_bit(QE_PIN_REQUESTED, &qe_gc->pin_flags[pin]); | ||
232 | spin_unlock_irqrestore(&qe_gc->lock, flags); | ||
233 | |||
234 | kfree(qe_pin); | ||
235 | } | ||
236 | EXPORT_SYMBOL(qe_pin_free); | ||
237 | |||
238 | /** | ||
239 | * qe_pin_set_dedicated - Revert a pin to a dedicated peripheral function mode | ||
240 | * @qe_pin: pointer to the qe_pin structure | ||
241 | * Context: any | ||
242 | * | ||
243 | * This function resets a pin to a dedicated peripheral function that | ||
244 | * has been set up by the firmware. | ||
245 | */ | ||
246 | void qe_pin_set_dedicated(struct qe_pin *qe_pin) | ||
247 | { | ||
248 | struct qe_gpio_chip *qe_gc = qe_pin->controller; | ||
249 | struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; | ||
250 | struct qe_pio_regs *sregs = &qe_gc->saved_regs; | ||
251 | int pin = qe_pin->num; | ||
252 | u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1)); | ||
253 | u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2); | ||
254 | bool second_reg = pin > (QE_PIO_PINS / 2) - 1; | ||
255 | unsigned long flags; | ||
256 | |||
257 | spin_lock_irqsave(&qe_gc->lock, flags); | ||
258 | |||
259 | if (second_reg) { | ||
260 | clrsetbits_be32(®s->cpdir2, mask2, sregs->cpdir2 & mask2); | ||
261 | clrsetbits_be32(®s->cppar2, mask2, sregs->cppar2 & mask2); | ||
262 | } else { | ||
263 | clrsetbits_be32(®s->cpdir1, mask2, sregs->cpdir1 & mask2); | ||
264 | clrsetbits_be32(®s->cppar1, mask2, sregs->cppar1 & mask2); | ||
265 | } | ||
266 | |||
267 | if (sregs->cpdata & mask1) | ||
268 | qe_gc->cpdata |= mask1; | ||
269 | else | ||
270 | qe_gc->cpdata &= ~mask1; | ||
271 | |||
272 | out_be32(®s->cpdata, qe_gc->cpdata); | ||
273 | clrsetbits_be32(®s->cpodr, mask1, sregs->cpodr & mask1); | ||
274 | |||
275 | spin_unlock_irqrestore(&qe_gc->lock, flags); | ||
276 | } | ||
277 | EXPORT_SYMBOL(qe_pin_set_dedicated); | ||
278 | |||
279 | /** | ||
280 | * qe_pin_set_gpio - Set a pin to the GPIO mode | ||
281 | * @qe_pin: pointer to the qe_pin structure | ||
282 | * Context: any | ||
283 | * | ||
284 | * This function sets a pin to the GPIO mode. | ||
285 | */ | ||
286 | void qe_pin_set_gpio(struct qe_pin *qe_pin) | ||
287 | { | ||
288 | struct qe_gpio_chip *qe_gc = qe_pin->controller; | ||
289 | struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; | ||
290 | unsigned long flags; | ||
291 | |||
292 | spin_lock_irqsave(&qe_gc->lock, flags); | ||
293 | |||
294 | /* Let's make it input by default, GPIO API is able to change that. */ | ||
295 | __par_io_config_pin(regs, qe_pin->num, QE_PIO_DIR_IN, 0, 0, 0); | ||
296 | |||
297 | spin_unlock_irqrestore(&qe_gc->lock, flags); | ||
298 | } | ||
299 | EXPORT_SYMBOL(qe_pin_set_gpio); | ||
300 | |||
106 | static int __init qe_add_gpiochips(void) | 301 | static int __init qe_add_gpiochips(void) |
107 | { | 302 | { |
108 | struct device_node *np; | 303 | struct device_node *np; |
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c new file mode 100644 index 00000000000..43c4569e24b --- /dev/null +++ b/arch/powerpc/sysdev/simple_gpio.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * Simple Memory-Mapped GPIOs | ||
3 | * | ||
4 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
5 | * | ||
6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_gpio.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <asm/prom.h> | ||
25 | #include "simple_gpio.h" | ||
26 | |||
27 | struct u8_gpio_chip { | ||
28 | struct of_mm_gpio_chip mm_gc; | ||
29 | spinlock_t lock; | ||
30 | |||
31 | /* shadowed data register to clear/set bits safely */ | ||
32 | u8 data; | ||
33 | }; | ||
34 | |||
35 | static struct u8_gpio_chip *to_u8_gpio_chip(struct of_mm_gpio_chip *mm_gc) | ||
36 | { | ||
37 | return container_of(mm_gc, struct u8_gpio_chip, mm_gc); | ||
38 | } | ||
39 | |||
40 | static u8 u8_pin2mask(unsigned int pin) | ||
41 | { | ||
42 | return 1 << (8 - 1 - pin); | ||
43 | } | ||
44 | |||
45 | static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
46 | { | ||
47 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
48 | |||
49 | return in_8(mm_gc->regs) & u8_pin2mask(gpio); | ||
50 | } | ||
51 | |||
52 | static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
53 | { | ||
54 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
55 | struct u8_gpio_chip *u8_gc = to_u8_gpio_chip(mm_gc); | ||
56 | unsigned long flags; | ||
57 | |||
58 | spin_lock_irqsave(&u8_gc->lock, flags); | ||
59 | |||
60 | if (val) | ||
61 | u8_gc->data |= u8_pin2mask(gpio); | ||
62 | else | ||
63 | u8_gc->data &= ~u8_pin2mask(gpio); | ||
64 | |||
65 | out_8(mm_gc->regs, u8_gc->data); | ||
66 | |||
67 | spin_unlock_irqrestore(&u8_gc->lock, flags); | ||
68 | } | ||
69 | |||
70 | static int u8_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
71 | { | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int u8_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
76 | { | ||
77 | u8_gpio_set(gc, gpio, val); | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static void u8_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) | ||
82 | { | ||
83 | struct u8_gpio_chip *u8_gc = to_u8_gpio_chip(mm_gc); | ||
84 | |||
85 | u8_gc->data = in_8(mm_gc->regs); | ||
86 | } | ||
87 | |||
88 | static int __init u8_simple_gpiochip_add(struct device_node *np) | ||
89 | { | ||
90 | int ret; | ||
91 | struct u8_gpio_chip *u8_gc; | ||
92 | struct of_mm_gpio_chip *mm_gc; | ||
93 | struct of_gpio_chip *of_gc; | ||
94 | struct gpio_chip *gc; | ||
95 | |||
96 | u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); | ||
97 | if (!u8_gc) | ||
98 | return -ENOMEM; | ||
99 | |||
100 | spin_lock_init(&u8_gc->lock); | ||
101 | |||
102 | mm_gc = &u8_gc->mm_gc; | ||
103 | of_gc = &mm_gc->of_gc; | ||
104 | gc = &of_gc->gc; | ||
105 | |||
106 | mm_gc->save_regs = u8_gpio_save_regs; | ||
107 | of_gc->gpio_cells = 2; | ||
108 | gc->ngpio = 8; | ||
109 | gc->direction_input = u8_gpio_dir_in; | ||
110 | gc->direction_output = u8_gpio_dir_out; | ||
111 | gc->get = u8_gpio_get; | ||
112 | gc->set = u8_gpio_set; | ||
113 | |||
114 | ret = of_mm_gpiochip_add(np, mm_gc); | ||
115 | if (ret) | ||
116 | goto err; | ||
117 | return 0; | ||
118 | err: | ||
119 | kfree(u8_gc); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | void __init simple_gpiochip_init(const char *compatible) | ||
124 | { | ||
125 | struct device_node *np; | ||
126 | |||
127 | for_each_compatible_node(np, NULL, compatible) { | ||
128 | int ret; | ||
129 | struct resource r; | ||
130 | |||
131 | ret = of_address_to_resource(np, 0, &r); | ||
132 | if (ret) | ||
133 | goto err; | ||
134 | |||
135 | switch (resource_size(&r)) { | ||
136 | case 1: | ||
137 | ret = u8_simple_gpiochip_add(np); | ||
138 | if (ret) | ||
139 | goto err; | ||
140 | break; | ||
141 | default: | ||
142 | /* | ||
143 | * Whenever you need support for GPIO bank width > 1, | ||
144 | * please just turn u8_ code into huge macros, and | ||
145 | * construct needed uX_ code with it. | ||
146 | */ | ||
147 | ret = -ENOSYS; | ||
148 | goto err; | ||
149 | } | ||
150 | continue; | ||
151 | err: | ||
152 | pr_err("%s: registration failed, status %d\n", | ||
153 | np->full_name, ret); | ||
154 | } | ||
155 | } | ||
diff --git a/arch/powerpc/sysdev/simple_gpio.h b/arch/powerpc/sysdev/simple_gpio.h new file mode 100644 index 00000000000..3a7b0c513c7 --- /dev/null +++ b/arch/powerpc/sysdev/simple_gpio.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __SYSDEV_SIMPLE_GPIO_H | ||
2 | #define __SYSDEV_SIMPLE_GPIO_H | ||
3 | |||
4 | #include <linux/errno.h> | ||
5 | |||
6 | #ifdef CONFIG_SIMPLE_GPIO | ||
7 | extern void simple_gpiochip_init(const char *compatible); | ||
8 | #else | ||
9 | static inline void simple_gpiochip_init(const char *compatible) {} | ||
10 | #endif /* CONFIG_SIMPLE_GPIO */ | ||
11 | |||
12 | #endif /* __SYSDEV_SIMPLE_GPIO_H */ | ||