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