ohci-nxp.c (30330b8fedba32e6bfeda8040311a11b84053c97) ohci-nxp.c (22d9d8e8316d7f69046c8805ce9aa8d9c43d4e5b)
1/*
2 * driver for NXP USB Host devices
3 *
4 * Currently supported OHCI host devices:
5 * - NXP LPC32xx
6 *
7 * Authors: Dmitry Chigirev <source@mvista.com>
8 * Vitaly Wool <vitalywool@gmail.com>

--- 5 unchanged lines hidden (view full) ---

14 * This driver is intended for engineering development purposes only
15 *
16 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
17 * the terms of the GNU General Public License version 2. This program
18 * is licensed "as is" without any warranty of any kind, whether express
19 * or implied.
20 */
21#include <linux/clk.h>
1/*
2 * driver for NXP USB Host devices
3 *
4 * Currently supported OHCI host devices:
5 * - NXP LPC32xx
6 *
7 * Authors: Dmitry Chigirev <source@mvista.com>
8 * Vitaly Wool <vitalywool@gmail.com>

--- 5 unchanged lines hidden (view full) ---

14 * This driver is intended for engineering development purposes only
15 *
16 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
17 * the terms of the GNU General Public License version 2. This program
18 * is licensed "as is" without any warranty of any kind, whether express
19 * or implied.
20 */
21#include <linux/clk.h>
22#include <linux/dma-mapping.h>
23#include <linux/io.h>
22#include <linux/platform_device.h>
24#include <linux/i2c.h>
23#include <linux/i2c.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/of.h>
24#include <linux/of.h>
28#include <linux/platform_device.h>
29#include <linux/usb/isp1301.h>
25#include <linux/usb/isp1301.h>
30#include <linux/usb.h>
31#include <linux/usb/hcd.h>
32
26
33#include "ohci.h"
34
35
36#include <mach/hardware.h>
37#include <asm/mach-types.h>
38#include <asm/io.h>
39
40#include <mach/platform.h>
41#include <mach/irqs.h>
42
43#define USB_CONFIG_BASE 0x31020000

--- 17 unchanged lines hidden (view full) ---

61#ifndef start_int_set_falling_edge
62#define start_int_set_falling_edge(irq)
63#define start_int_set_rising_edge(irq)
64#define start_int_ack(irq)
65#define start_int_mask(irq)
66#define start_int_umask(irq)
67#endif
68
27#include <mach/hardware.h>
28#include <asm/mach-types.h>
29#include <asm/io.h>
30
31#include <mach/platform.h>
32#include <mach/irqs.h>
33
34#define USB_CONFIG_BASE 0x31020000

--- 17 unchanged lines hidden (view full) ---

52#ifndef start_int_set_falling_edge
53#define start_int_set_falling_edge(irq)
54#define start_int_set_rising_edge(irq)
55#define start_int_ack(irq)
56#define start_int_mask(irq)
57#define start_int_umask(irq)
58#endif
59
69#define DRIVER_DESC "OHCI NXP driver"
70
71static const char hcd_name[] = "ohci-nxp";
72static struct hc_driver __read_mostly ohci_nxp_hc_driver;
73
74static struct i2c_client *isp1301_i2c_client;
75
76extern int usb_disabled(void);
77
78static struct clk *usb_pll_clk;
79static struct clk *usb_dev_clk;
80static struct clk *usb_otg_clk;
81

--- 59 unchanged lines hidden (view full) ---

141
142static inline void isp1301_vbus_off(void)
143{
144 i2c_smbus_write_byte_data(isp1301_i2c_client,
145 ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR,
146 OTG1_VBUS_DRV);
147}
148
60static struct i2c_client *isp1301_i2c_client;
61
62extern int usb_disabled(void);
63
64static struct clk *usb_pll_clk;
65static struct clk *usb_dev_clk;
66static struct clk *usb_otg_clk;
67

--- 59 unchanged lines hidden (view full) ---

127
128static inline void isp1301_vbus_off(void)
129{
130 i2c_smbus_write_byte_data(isp1301_i2c_client,
131 ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR,
132 OTG1_VBUS_DRV);
133}
134
149static void ohci_nxp_start_hc(void)
135static void nxp_start_hc(void)
150{
151 unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
152 __raw_writel(tmp, USB_OTG_STAT_CONTROL);
153 isp1301_vbus_on();
154}
155
136{
137 unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
138 __raw_writel(tmp, USB_OTG_STAT_CONTROL);
139 isp1301_vbus_on();
140}
141
156static void ohci_nxp_stop_hc(void)
142static void nxp_stop_hc(void)
157{
158 unsigned long tmp;
159 isp1301_vbus_off();
160 tmp = __raw_readl(USB_OTG_STAT_CONTROL) & ~HOST_EN;
161 __raw_writel(tmp, USB_OTG_STAT_CONTROL);
162}
163
143{
144 unsigned long tmp;
145 isp1301_vbus_off();
146 tmp = __raw_readl(USB_OTG_STAT_CONTROL) & ~HOST_EN;
147 __raw_writel(tmp, USB_OTG_STAT_CONTROL);
148}
149
164static int ohci_hcd_nxp_probe(struct platform_device *pdev)
150static int ohci_nxp_start(struct usb_hcd *hcd)
165{
151{
152 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
153 int ret;
154
155 if ((ret = ohci_init(ohci)) < 0)
156 return ret;
157
158 if ((ret = ohci_run(ohci)) < 0) {
159 dev_err(hcd->self.controller, "can't start\n");
160 ohci_stop(hcd);
161 return ret;
162 }
163 return 0;
164}
165
166static const struct hc_driver ohci_nxp_hc_driver = {
167 .description = hcd_name,
168 .product_desc = "nxp OHCI",
169
170 /*
171 * generic hardware linkage
172 */
173 .irq = ohci_irq,
174 .flags = HCD_USB11 | HCD_MEMORY,
175
176 .hcd_priv_size = sizeof(struct ohci_hcd),
177 /*
178 * basic lifecycle operations
179 */
180 .start = ohci_nxp_start,
181 .stop = ohci_stop,
182 .shutdown = ohci_shutdown,
183
184 /*
185 * managing i/o requests and associated device resources
186 */
187 .urb_enqueue = ohci_urb_enqueue,
188 .urb_dequeue = ohci_urb_dequeue,
189 .endpoint_disable = ohci_endpoint_disable,
190
191 /*
192 * scheduling support
193 */
194 .get_frame_number = ohci_get_frame,
195
196 /*
197 * root hub support
198 */
199 .hub_status_data = ohci_hub_status_data,
200 .hub_control = ohci_hub_control,
201#ifdef CONFIG_PM
202 .bus_suspend = ohci_bus_suspend,
203 .bus_resume = ohci_bus_resume,
204#endif
205 .start_port_reset = ohci_start_port_reset,
206};
207
208static int usb_hcd_nxp_probe(struct platform_device *pdev)
209{
166 struct usb_hcd *hcd = 0;
210 struct usb_hcd *hcd = 0;
211 struct ohci_hcd *ohci;
167 const struct hc_driver *driver = &ohci_nxp_hc_driver;
168 struct resource *res;
169 int ret = 0, irq;
170 struct device_node *isp1301_node;
171
172 if (pdev->dev.of_node) {
173 isp1301_node = of_parse_phandle(pdev->dev.of_node,
174 "transceiver", 0);
175 } else {
176 isp1301_node = NULL;
177 }
178
179 isp1301_i2c_client = isp1301_get_client(isp1301_node);
180 if (!isp1301_i2c_client) {
181 return -EPROBE_DEFER;
182 }
183
212 const struct hc_driver *driver = &ohci_nxp_hc_driver;
213 struct resource *res;
214 int ret = 0, irq;
215 struct device_node *isp1301_node;
216
217 if (pdev->dev.of_node) {
218 isp1301_node = of_parse_phandle(pdev->dev.of_node,
219 "transceiver", 0);
220 } else {
221 isp1301_node = NULL;
222 }
223
224 isp1301_i2c_client = isp1301_get_client(isp1301_node);
225 if (!isp1301_i2c_client) {
226 return -EPROBE_DEFER;
227 }
228
184 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
185 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
229 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
230 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
231 if (ret)
232 goto fail_disable;
186
187 dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
188 if (usb_disabled()) {
189 dev_err(&pdev->dev, "USB is disabled\n");
190 ret = -ENODEV;
191 goto fail_disable;
192 }
193

--- 69 unchanged lines hidden (view full) ---

263 hcd->rsrc_len = resource_size(res);
264
265 irq = platform_get_irq(pdev, 0);
266 if (irq < 0) {
267 ret = -ENXIO;
268 goto fail_resource;
269 }
270
233
234 dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
235 if (usb_disabled()) {
236 dev_err(&pdev->dev, "USB is disabled\n");
237 ret = -ENODEV;
238 goto fail_disable;
239 }
240

--- 69 unchanged lines hidden (view full) ---

310 hcd->rsrc_len = resource_size(res);
311
312 irq = platform_get_irq(pdev, 0);
313 if (irq < 0) {
314 ret = -ENXIO;
315 goto fail_resource;
316 }
317
271 ohci_nxp_start_hc();
318 nxp_start_hc();
272 platform_set_drvdata(pdev, hcd);
319 platform_set_drvdata(pdev, hcd);
320 ohci = hcd_to_ohci(hcd);
321 ohci_hcd_init(ohci);
273
274 dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
275 ret = usb_add_hcd(hcd, irq, 0);
276 if (ret == 0)
277 return ret;
278
322
323 dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
324 ret = usb_add_hcd(hcd, irq, 0);
325 if (ret == 0)
326 return ret;
327
279 ohci_nxp_stop_hc();
328 nxp_stop_hc();
280fail_resource:
281 usb_put_hcd(hcd);
282fail_hcd:
283 clk_disable(usb_otg_clk);
284fail_otgen:
285 clk_put(usb_otg_clk);
286fail_otg:
287 clk_disable(usb_dev_clk);

--- 5 unchanged lines hidden (view full) ---

293fail_pllen:
294 clk_put(usb_pll_clk);
295fail_pll:
296fail_disable:
297 isp1301_i2c_client = NULL;
298 return ret;
299}
300
329fail_resource:
330 usb_put_hcd(hcd);
331fail_hcd:
332 clk_disable(usb_otg_clk);
333fail_otgen:
334 clk_put(usb_otg_clk);
335fail_otg:
336 clk_disable(usb_dev_clk);

--- 5 unchanged lines hidden (view full) ---

342fail_pllen:
343 clk_put(usb_pll_clk);
344fail_pll:
345fail_disable:
346 isp1301_i2c_client = NULL;
347 return ret;
348}
349
301static int ohci_hcd_nxp_remove(struct platform_device *pdev)
350static int usb_hcd_nxp_remove(struct platform_device *pdev)
302{
303 struct usb_hcd *hcd = platform_get_drvdata(pdev);
304
305 usb_remove_hcd(hcd);
351{
352 struct usb_hcd *hcd = platform_get_drvdata(pdev);
353
354 usb_remove_hcd(hcd);
306 ohci_nxp_stop_hc();
355 nxp_stop_hc();
307 usb_put_hcd(hcd);
308 clk_disable(usb_pll_clk);
309 clk_put(usb_pll_clk);
310 clk_disable(usb_dev_clk);
311 clk_put(usb_dev_clk);
312 i2c_unregister_device(isp1301_i2c_client);
313 isp1301_i2c_client = NULL;
314
315 return 0;
316}
317
318/* work with hotplug and coldplug */
319MODULE_ALIAS("platform:usb-ohci");
320
321#ifdef CONFIG_OF
356 usb_put_hcd(hcd);
357 clk_disable(usb_pll_clk);
358 clk_put(usb_pll_clk);
359 clk_disable(usb_dev_clk);
360 clk_put(usb_dev_clk);
361 i2c_unregister_device(isp1301_i2c_client);
362 isp1301_i2c_client = NULL;
363
364 return 0;
365}
366
367/* work with hotplug and coldplug */
368MODULE_ALIAS("platform:usb-ohci");
369
370#ifdef CONFIG_OF
322static const struct of_device_id ohci_hcd_nxp_match[] = {
371static const struct of_device_id usb_hcd_nxp_match[] = {
323 { .compatible = "nxp,ohci-nxp" },
324 {},
325};
372 { .compatible = "nxp,ohci-nxp" },
373 {},
374};
326MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);
375MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match);
327#endif
328
376#endif
377
329static struct platform_driver ohci_hcd_nxp_driver = {
378static struct platform_driver usb_hcd_nxp_driver = {
330 .driver = {
331 .name = "usb-ohci",
332 .owner = THIS_MODULE,
379 .driver = {
380 .name = "usb-ohci",
381 .owner = THIS_MODULE,
333 .of_match_table = of_match_ptr(ohci_hcd_nxp_match),
382 .of_match_table = of_match_ptr(usb_hcd_nxp_match),
334 },
383 },
335 .probe = ohci_hcd_nxp_probe,
336 .remove = ohci_hcd_nxp_remove,
384 .probe = usb_hcd_nxp_probe,
385 .remove = usb_hcd_nxp_remove,
337};
338
386};
387
339static int __init ohci_nxp_init(void)
340{
341 if (usb_disabled())
342 return -ENODEV;
343
344 pr_info("%s: " DRIVER_DESC "\n", hcd_name);
345
346 ohci_init_driver(&ohci_nxp_hc_driver, NULL);
347 return platform_driver_register(&ohci_hcd_nxp_driver);
348}
349module_init(ohci_nxp_init);
350
351static void __exit ohci_nxp_cleanup(void)
352{
353 platform_driver_unregister(&ohci_hcd_nxp_driver);
354}
355module_exit(ohci_nxp_cleanup);
356
357MODULE_DESCRIPTION(DRIVER_DESC);
358MODULE_LICENSE("GPL v2");