Root/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
294

Archive Download this file



interactive