1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2012 Tilera Corporation. All Rights Reserved.
7 * Tilera TILE-Gx USB OHCI host controller driver.
10 #include <linux/irq.h>
11 #include <linux/platform_device.h>
12 #include <linux/usb/tilegx.h>
13 #include <linux/usb.h>
15 #include <asm/homecache.h>
17 #include <gxio/iorpc_usb_host.h>
18 #include <gxio/usb_host.h>
20 static void tilegx_start_ohc(void)
24 static void tilegx_stop_ohc(void)
28 static int tilegx_ohci_start(struct usb_hcd
*hcd
)
30 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
33 ret
= ohci_init(ohci
);
39 dev_err(hcd
->self
.controller
, "can't start %s\n",
48 static const struct hc_driver ohci_tilegx_hc_driver
= {
49 .description
= hcd_name
,
50 .product_desc
= "Tile-Gx OHCI",
51 .hcd_priv_size
= sizeof(struct ohci_hcd
),
54 * Generic hardware linkage.
57 .flags
= HCD_MEMORY
| HCD_LOCAL_MEM
| HCD_USB11
,
60 * Basic lifecycle operations.
62 .start
= tilegx_ohci_start
,
64 .shutdown
= ohci_shutdown
,
67 * Managing I/O requests and associated device resources.
69 .urb_enqueue
= ohci_urb_enqueue
,
70 .urb_dequeue
= ohci_urb_dequeue
,
71 .endpoint_disable
= ohci_endpoint_disable
,
76 .get_frame_number
= ohci_get_frame
,
81 .hub_status_data
= ohci_hub_status_data
,
82 .hub_control
= ohci_hub_control
,
83 .start_port_reset
= ohci_start_port_reset
,
86 static int ohci_hcd_tilegx_drv_probe(struct platform_device
*pdev
)
89 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
91 int my_cpu
= smp_processor_id();
98 * Try to initialize our GXIO context; if we can't, the device
101 if (gxio_usb_host_init(&pdata
->usb_ctx
, pdata
->dev_index
, 0) != 0)
104 hcd
= usb_create_hcd(&ohci_tilegx_hc_driver
, &pdev
->dev
,
105 dev_name(&pdev
->dev
));
112 * We don't use rsrc_start to map in our registers, but seems like
113 * we ought to set it to something, so we use the register VA.
116 (ulong
) gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
117 hcd
->rsrc_len
= gxio_usb_host_get_reg_len(&pdata
->usb_ctx
);
118 hcd
->regs
= gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
122 /* Create our IRQs and register them. */
123 pdata
->irq
= irq_alloc_hwirq(-1);
129 tile_irq_activate(pdata
->irq
, TILE_IRQ_PERCPU
);
131 /* Configure interrupts. */
132 ret
= gxio_usb_host_cfg_interrupt(&pdata
->usb_ctx
,
133 cpu_x(my_cpu
), cpu_y(my_cpu
),
134 KERNEL_PL
, pdata
->irq
);
140 /* Register all of our memory. */
141 pte
= pte_set_home(pte
, PAGE_HOME_HASH
);
142 ret
= gxio_usb_host_register_client_memory(&pdata
->usb_ctx
, pte
, 0);
148 ohci_hcd_init(hcd_to_ohci(hcd
));
150 ret
= usb_add_hcd(hcd
, pdata
->irq
, IRQF_SHARED
);
152 platform_set_drvdata(pdev
, hcd
);
153 device_wakeup_enable(hcd
->self
.controller
);
158 irq_free_hwirq(pdata
->irq
);
163 gxio_usb_host_destroy(&pdata
->usb_ctx
);
167 static int ohci_hcd_tilegx_drv_remove(struct platform_device
*pdev
)
169 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
170 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
175 gxio_usb_host_destroy(&pdata
->usb_ctx
);
176 irq_free_hwirq(pdata
->irq
);
181 static void ohci_hcd_tilegx_drv_shutdown(struct platform_device
*pdev
)
183 usb_hcd_platform_shutdown(pdev
);
184 ohci_hcd_tilegx_drv_remove(pdev
);
187 static struct platform_driver ohci_hcd_tilegx_driver
= {
188 .probe
= ohci_hcd_tilegx_drv_probe
,
189 .remove
= ohci_hcd_tilegx_drv_remove
,
190 .shutdown
= ohci_hcd_tilegx_drv_shutdown
,
192 .name
= "tilegx-ohci",
196 MODULE_ALIAS("platform:tilegx-ohci");