ppc40x: remove 3.8 support
[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---