2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
16 * Tilera TILE-Gx USB OHCI host controller driver.
19 #include <linux/irq.h>
20 #include <linux/platform_device.h>
21 #include <linux/usb/tilegx.h>
22 #include <linux/usb.h>
24 #include <asm/homecache.h>
26 #include <gxio/iorpc_usb_host.h>
27 #include <gxio/usb_host.h>
29 static void tilegx_start_ohc(void)
33 static void tilegx_stop_ohc(void)
37 static int tilegx_ohci_start(struct usb_hcd
*hcd
)
39 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
42 ret
= ohci_init(ohci
);
48 dev_err(hcd
->self
.controller
, "can't start %s\n",
57 static const struct hc_driver ohci_tilegx_hc_driver
= {
58 .description
= hcd_name
,
59 .product_desc
= "Tile-Gx OHCI",
60 .hcd_priv_size
= sizeof(struct ohci_hcd
),
63 * Generic hardware linkage.
66 .flags
= HCD_MEMORY
| HCD_LOCAL_MEM
| HCD_USB11
,
69 * Basic lifecycle operations.
71 .start
= tilegx_ohci_start
,
73 .shutdown
= ohci_shutdown
,
76 * Managing I/O requests and associated device resources.
78 .urb_enqueue
= ohci_urb_enqueue
,
79 .urb_dequeue
= ohci_urb_dequeue
,
80 .endpoint_disable
= ohci_endpoint_disable
,
85 .get_frame_number
= ohci_get_frame
,
90 .hub_status_data
= ohci_hub_status_data
,
91 .hub_control
= ohci_hub_control
,
92 .start_port_reset
= ohci_start_port_reset
,
95 static int ohci_hcd_tilegx_drv_probe(struct platform_device
*pdev
)
98 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
100 int my_cpu
= smp_processor_id();
107 * Try to initialize our GXIO context; if we can't, the device
110 if (gxio_usb_host_init(&pdata
->usb_ctx
, pdata
->dev_index
, 0) != 0)
113 hcd
= usb_create_hcd(&ohci_tilegx_hc_driver
, &pdev
->dev
,
114 dev_name(&pdev
->dev
));
121 * We don't use rsrc_start to map in our registers, but seems like
122 * we ought to set it to something, so we use the register VA.
125 (ulong
) gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
126 hcd
->rsrc_len
= gxio_usb_host_get_reg_len(&pdata
->usb_ctx
);
127 hcd
->regs
= gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
131 /* Create our IRQs and register them. */
132 pdata
->irq
= create_irq();
133 if (pdata
->irq
< 0) {
138 tile_irq_activate(pdata
->irq
, TILE_IRQ_PERCPU
);
140 /* Configure interrupts. */
141 ret
= gxio_usb_host_cfg_interrupt(&pdata
->usb_ctx
,
142 cpu_x(my_cpu
), cpu_y(my_cpu
),
143 KERNEL_PL
, pdata
->irq
);
149 /* Register all of our memory. */
150 pte
= pte_set_home(pte
, PAGE_HOME_HASH
);
151 ret
= gxio_usb_host_register_client_memory(&pdata
->usb_ctx
, pte
, 0);
157 ohci_hcd_init(hcd_to_ohci(hcd
));
159 ret
= usb_add_hcd(hcd
, pdata
->irq
, IRQF_SHARED
);
161 platform_set_drvdata(pdev
, hcd
);
162 device_wakeup_enable(hcd
->self
.controller
);
167 destroy_irq(pdata
->irq
);
172 gxio_usb_host_destroy(&pdata
->usb_ctx
);
176 static int ohci_hcd_tilegx_drv_remove(struct platform_device
*pdev
)
178 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
179 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
184 gxio_usb_host_destroy(&pdata
->usb_ctx
);
185 destroy_irq(pdata
->irq
);
190 static void ohci_hcd_tilegx_drv_shutdown(struct platform_device
*pdev
)
192 usb_hcd_platform_shutdown(pdev
);
193 ohci_hcd_tilegx_drv_remove(pdev
);
196 static struct platform_driver ohci_hcd_tilegx_driver
= {
197 .probe
= ohci_hcd_tilegx_drv_probe
,
198 .remove
= ohci_hcd_tilegx_drv_remove
,
199 .shutdown
= ohci_hcd_tilegx_drv_shutdown
,
201 .name
= "tilegx-ohci",
202 .owner
= THIS_MODULE
,
206 MODULE_ALIAS("platform:tilegx-ohci");