upgrade to 3.0 (magicbox ata and openrb usb is broken, but the current kernel didn...
[librecmc/librecmc.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