linux: update 3.0 to 3.0.9
[openwrt/staging/wigyori.git] / target / linux / ppc40x / patches / 120-usb-isp116x-hcd-add-of-binding.patch
1 --- a/drivers/usb/host/isp116x-hcd.c
2 +++ b/drivers/usb/host/isp116x-hcd.c
3 @@ -1535,6 +1535,7 @@ static struct hc_driver isp116x_hc_drive
4
5 /*----------------------------------------------------------------*/
6
7 +#ifdef CONFIG_USB_ISP116X_HCD_PLATFORM
8 static int isp116x_remove(struct platform_device *pdev)
9 {
10 struct usb_hcd *hcd = platform_get_drvdata(pdev);
11 @@ -1708,22 +1709,253 @@ static struct platform_driver isp116x_dr
12 },
13 };
14
15 +static inline int isp116x_platform_register(void)
16 +{
17 + return platform_driver_register(&isp116x_driver);
18 +}
19 +
20 +static inline void isp116x_platform_unregister(void)
21 +{
22 + platform_driver_unregister(&isp116x_driver);
23 +}
24 +#else
25 +static inline int isp116x_platform_register(void) { return 0; };
26 +static void isp116x_platform_unregister(void) {};
27 +#endif /* CONFIG_USB_ISP116X_PLATFORM */
28 +
29 +/*-----------------------------------------------------------------*/
30 +
31 +#ifdef CONFIG_USB_ISP116X_HCD_OF
32 +
33 +#include <linux/of.h>
34 +#include <linux/of_device.h>
35 +#include <linux/of_platform.h>
36 +
37 +#ifdef USE_PLATFORM_DELAY
38 +static void isp116x_of_delay(struct device *ddev, int delay)
39 +{
40 + ndelay(delay);
41 +}
42 +#else
43 +#define isp116x_of_delay NULL
44 +#endif
45 +
46 +static int __devinit isp116x_of_probe(struct of_device *op,
47 + const struct of_device_id *match)
48 +{
49 + struct device_node *dn = op->node;
50 + struct usb_hcd *hcd;
51 + struct isp116x *isp116x;
52 + struct resource addr, data, ires;
53 + struct isp116x_platform_data *board;
54 + void __iomem *addr_reg;
55 + void __iomem *data_reg;
56 + int irq;
57 + int ret = 0;
58 + unsigned long irqflags;
59 +
60 + ret = of_address_to_resource(dn, 0, &data);
61 + if (ret)
62 + return ret;
63 +
64 + ret = of_address_to_resource(dn, 1, &addr);
65 + if (ret)
66 + return ret;
67 +
68 + ret = of_irq_to_resource(dn, 1, &ires);
69 + if (ret)
70 + return ret;
71 +
72 + irqflags = ires.flags & IRQF_TRIGGER_MASK;
73 +
74 + board = kzalloc(sizeof(struct isp116x_platform_data), GFP_KERNEL);
75 + if (board == NULL)
76 + return -ENOMEM;
77 +
78 + if (!request_mem_region(addr.start, resource_size(&addr), hcd_name)) {
79 + ret = -EBUSY;
80 + goto err_free_board;
81 + }
82 +
83 + addr_reg = ioremap_nocache(addr.start, resource_size(&addr));
84 + if (addr_reg == NULL) {
85 + ret = -ENOMEM;
86 + goto err_release_addr;
87 + }
88 +
89 + if (!request_mem_region(data.start, resource_size(&data), hcd_name)) {
90 + ret = -EBUSY;
91 + goto err_unmap_addr;
92 + }
93 +
94 + data_reg = ioremap_nocache(data.start, resource_size(&data));
95 + if (data_reg == NULL) {
96 + ret = -ENOMEM;
97 + goto err_release_data;
98 + }
99 +
100 + irq = irq_of_parse_and_map(op->node, 0);
101 + if (irq == NO_IRQ) {
102 + ret = -EINVAL;
103 + goto err_unmap_data;
104 + }
105 +
106 + /* allocate and initialize hcd */
107 + hcd = usb_create_hcd(&isp116x_hc_driver, &op->dev, dev_name(&op->dev));
108 + if (!hcd) {
109 + ret = -ENOMEM;
110 + goto err_irq_dispose;
111 + }
112 +
113 + /* this rsrc_start is bogus */
114 + hcd->rsrc_start = addr.start;
115 + isp116x = hcd_to_isp116x(hcd);
116 + isp116x->data_reg = data_reg;
117 + isp116x->addr_reg = addr_reg;
118 + isp116x->board = board;
119 + spin_lock_init(&isp116x->lock);
120 + INIT_LIST_HEAD(&isp116x->async);
121 +
122 + board->delay = isp116x_of_delay;
123 + if (of_get_property(dn, "sel15Kres", NULL))
124 + board->sel15Kres = 1;
125 + if (of_get_property(dn, "oc_enable", NULL))
126 + board->oc_enable = 1;
127 + if (of_get_property(dn, "remote_wakeup_enable", NULL))
128 + board->remote_wakeup_enable = 1;
129 +
130 + if (of_get_property(dn, "int_act_high", NULL))
131 + board->int_act_high = 1;
132 + if (of_get_property(dn, "int_edge_triggered", NULL))
133 + board->int_edge_triggered = 1;
134 +
135 + ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
136 + if (ret)
137 + goto err_put_hcd;
138 +
139 + ret = create_debug_file(isp116x);
140 + if (ret) {
141 + ERR("Couldn't create debugfs entry\n");
142 + goto err_remove_hcd;
143 + }
144 +
145 + return 0;
146 +
147 + err_remove_hcd:
148 + usb_remove_hcd(hcd);
149 + err_put_hcd:
150 + usb_put_hcd(hcd);
151 + err_irq_dispose:
152 + irq_dispose_mapping(irq);
153 + err_unmap_data:
154 + iounmap(data_reg);
155 + err_release_data:
156 + release_mem_region(data.start, resource_size(&data));
157 + err_unmap_addr:
158 + iounmap(addr_reg);
159 + err_release_addr:
160 + release_mem_region(addr.start, resource_size(&addr));
161 + err_free_board:
162 + kfree(board);
163 + return ret;
164 +}
165 +
166 +static __devexit int isp116x_of_remove(struct of_device *op)
167 +{
168 + struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
169 + struct isp116x *isp116x;
170 + struct resource res;
171 +
172 + if (!hcd)
173 + return 0;
174 +
175 + dev_set_drvdata(&op->dev, NULL);
176 +
177 + isp116x = hcd_to_isp116x(hcd);
178 + remove_debug_file(isp116x);
179 + usb_remove_hcd(hcd);
180 +
181 + irq_dispose_mapping(hcd->irq);
182 +
183 + iounmap(isp116x->data_reg);
184 + (void) of_address_to_resource(op->node, 0, &res);
185 + release_mem_region(res.start, resource_size(&res));
186 +
187 + iounmap(isp116x->addr_reg);
188 + (void) of_address_to_resource(op->node, 1, &res);
189 + release_mem_region(res.start, resource_size(&res));
190 +
191 + kfree(isp116x->board);
192 + usb_put_hcd(hcd);
193 +
194 + return 0;
195 +}
196 +
197 +static struct of_device_id isp116x_of_match[] = {
198 + { .compatible = "isp116x-hcd", },
199 + {},
200 +};
201 +
202 +static struct of_platform_driver isp116x_of_platform_driver = {
203 + .owner = THIS_MODULE,
204 + .name = "isp116x-hcd-of",
205 + .match_table = isp116x_of_match,
206 + .probe = isp116x_of_probe,
207 + .remove = __devexit_p(isp116x_of_remove),
208 + .driver = {
209 + .name = "isp116x-hcd-of",
210 + .owner = THIS_MODULE,
211 + },
212 +};
213 +
214 +static int __init isp116x_of_register(void)
215 +{
216 + return of_register_platform_driver(&isp116x_of_platform_driver);
217 +}
218 +
219 +static void __exit isp116x_of_unregister(void)
220 +{
221 + of_unregister_platform_driver(&isp116x_of_platform_driver);
222 +}
223 +
224 +MODULE_DEVICE_TABLE(of, isp116x_of_match);
225 +
226 +#else
227 +static inline int isp116x_of_register(void) { return 0; };
228 +static void isp116x_of_unregister(void) {};
229 +#endif /* CONFIG_USB_ISP116X_HCD_OF */
230 +
231 /*-----------------------------------------------------------------*/
232
233 static int __init isp116x_init(void)
234 {
235 + int ret;
236 +
237 if (usb_disabled())
238 return -ENODEV;
239
240 INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION);
241 - return platform_driver_register(&isp116x_driver);
242 + ret = isp116x_platform_register();
243 + if (ret)
244 + return ret;
245 +
246 + ret = isp116x_of_register();
247 + if (ret)
248 + goto err_platform_unregister;
249 +
250 + return 0;
251 +
252 + err_platform_unregister:
253 + isp116x_platform_unregister();
254 + return ret;
255 }
256
257 module_init(isp116x_init);
258
259 static void __exit isp116x_cleanup(void)
260 {
261 - platform_driver_unregister(&isp116x_driver);
262 + isp116x_of_unregister();
263 + isp116x_platform_unregister();
264 }
265
266 module_exit(isp116x_cleanup);
267 --- a/drivers/usb/host/Kconfig
268 +++ b/drivers/usb/host/Kconfig
269 @@ -242,6 +242,24 @@ config USB_ISP116X_HCD
270 To compile this driver as a module, choose M here: the
271 module will be called isp116x-hcd.
272
273 +config USB_ISP116X_HCD_PLATFORM
274 + bool "ISP116X support for controllers on platform bus"
275 + depends on USB_ISP116X_HCD
276 + default n if PPC_OF
277 + default y
278 + ---help---
279 + Enables support for the ISP116x USB controller present on the
280 + platform bus.
281 +
282 +config USB_ISP116X_HCD_OF
283 + bool "ISP116X support for controllers on OF platform bus"
284 + depends on USB_ISP116X_HCD && PPC_OF
285 + default y if PPC_OF
286 + default n
287 + ---help---
288 + Enables support for the ISP116x USB controller present on the
289 + OpenFirmware platform bus.
290 +
291 config USB_ISP1760_HCD
292 tristate "ISP 1760 HCD support"
293 depends on USB && EXPERIMENTAL