xhci: free xhci virtual devices with leaf nodes first
[pandora-kernel.git] / drivers / usb / host / ehci-octeon.c
1 /*
2  * EHCI HCD glue for Cavium Octeon II SOCs.
3  *
4  * Loosely based on ehci-au1xxx.c
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  *
10  * Copyright (C) 2010 Cavium Networks
11  *
12  */
13
14 #include <linux/platform_device.h>
15
16 #include <asm/octeon/octeon.h>
17 #include <asm/octeon/cvmx-uctlx-defs.h>
18
19 #define OCTEON_EHCI_HCD_NAME "octeon-ehci"
20
21 /* Common clock init code.  */
22 void octeon2_usb_clocks_start(void);
23 void octeon2_usb_clocks_stop(void);
24
25 static void ehci_octeon_start(void)
26 {
27         union cvmx_uctlx_ehci_ctl ehci_ctl;
28
29         octeon2_usb_clocks_start();
30
31         ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
32         /* Use 64-bit addressing. */
33         ehci_ctl.s.ehci_64b_addr_en = 1;
34         ehci_ctl.s.l2c_addr_msb = 0;
35         ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
36         ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
37         cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
38 }
39
40 static void ehci_octeon_stop(void)
41 {
42         octeon2_usb_clocks_stop();
43 }
44
45 static const struct hc_driver ehci_octeon_hc_driver = {
46         .description            = hcd_name,
47         .product_desc           = "Octeon EHCI",
48         .hcd_priv_size          = sizeof(struct ehci_hcd),
49
50         /*
51          * generic hardware linkage
52          */
53         .irq                    = ehci_irq,
54         .flags                  = HCD_MEMORY | HCD_USB2,
55
56         /*
57          * basic lifecycle operations
58          */
59         .reset                  = ehci_init,
60         .start                  = ehci_run,
61         .stop                   = ehci_stop,
62         .shutdown               = ehci_shutdown,
63
64         /*
65          * managing i/o requests and associated device resources
66          */
67         .urb_enqueue            = ehci_urb_enqueue,
68         .urb_dequeue            = ehci_urb_dequeue,
69         .endpoint_disable       = ehci_endpoint_disable,
70         .endpoint_reset         = ehci_endpoint_reset,
71
72         /*
73          * scheduling support
74          */
75         .get_frame_number       = ehci_get_frame,
76
77         /*
78          * root hub support
79          */
80         .hub_status_data        = ehci_hub_status_data,
81         .hub_control            = ehci_hub_control,
82         .bus_suspend            = ehci_bus_suspend,
83         .bus_resume             = ehci_bus_resume,
84         .relinquish_port        = ehci_relinquish_port,
85         .port_handed_over       = ehci_port_handed_over,
86
87         .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
88 };
89
90 static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64);
91
92 static int ehci_octeon_drv_probe(struct platform_device *pdev)
93 {
94         struct usb_hcd *hcd;
95         struct ehci_hcd *ehci;
96         struct resource *res_mem;
97         int irq;
98         int ret;
99
100         if (usb_disabled())
101                 return -ENODEV;
102
103         irq = platform_get_irq(pdev, 0);
104         if (irq < 0) {
105                 dev_err(&pdev->dev, "No irq assigned\n");
106                 return -ENODEV;
107         }
108
109         res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
110         if (res_mem == NULL) {
111                 dev_err(&pdev->dev, "No register space assigned\n");
112                 return -ENODEV;
113         }
114
115         /*
116          * We can DMA from anywhere. But the descriptors must be in
117          * the lower 4GB.
118          */
119         pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
120         pdev->dev.dma_mask = &ehci_octeon_dma_mask;
121
122         hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
123         if (!hcd)
124                 return -ENOMEM;
125
126         hcd->rsrc_start = res_mem->start;
127         hcd->rsrc_len = resource_size(res_mem);
128
129         if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
130                                 OCTEON_EHCI_HCD_NAME)) {
131                 dev_err(&pdev->dev, "request_mem_region failed\n");
132                 ret = -EBUSY;
133                 goto err1;
134         }
135
136         hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
137         if (!hcd->regs) {
138                 dev_err(&pdev->dev, "ioremap failed\n");
139                 ret = -ENOMEM;
140                 goto err2;
141         }
142
143         ehci_octeon_start();
144
145         ehci = hcd_to_ehci(hcd);
146
147         /* Octeon EHCI matches CPU endianness. */
148 #ifdef __BIG_ENDIAN
149         ehci->big_endian_mmio = 1;
150 #endif
151
152         ehci->caps = hcd->regs;
153         ehci->regs = hcd->regs +
154                 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
155         /* cache this readonly data; minimize chip reads */
156         ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
157
158         ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
159         if (ret) {
160                 dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
161                 goto err3;
162         }
163
164         platform_set_drvdata(pdev, hcd);
165
166         /* root ports should always stay powered */
167         ehci_port_power(ehci, 1);
168
169         return 0;
170 err3:
171         ehci_octeon_stop();
172
173         iounmap(hcd->regs);
174 err2:
175         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
176 err1:
177         usb_put_hcd(hcd);
178         return ret;
179 }
180
181 static int ehci_octeon_drv_remove(struct platform_device *pdev)
182 {
183         struct usb_hcd *hcd = platform_get_drvdata(pdev);
184
185         usb_remove_hcd(hcd);
186
187         ehci_octeon_stop();
188         iounmap(hcd->regs);
189         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
190         usb_put_hcd(hcd);
191
192         platform_set_drvdata(pdev, NULL);
193
194         return 0;
195 }
196
197 static struct platform_driver ehci_octeon_driver = {
198         .probe          = ehci_octeon_drv_probe,
199         .remove         = ehci_octeon_drv_remove,
200         .shutdown       = usb_hcd_platform_shutdown,
201         .driver = {
202                 .name   = OCTEON_EHCI_HCD_NAME,
203                 .owner  = THIS_MODULE,
204         }
205 };
206
207 MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME);