1 /*
2 * drivers/usb/host/xhci_sunxi.c
3 * (C) Copyright 2010-2015
4 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
5 * wangjx, 2016-9-9, create this file
6 *
7 * SoftWinner XHCI Driver
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 */
15
16 #include <linux/platform_device.h>
17 #include <linux/time.h>
18 #include <linux/timer.h>
19 #include <linux/dma-mapping.h>
20
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23
24 #include <linux/slab.h>
25 #include <linux/ioport.h>
26 #include <linux/io.h>
27
28 #include <linux/clk.h>
29 #include "sunxi-hci.h"
30 #include "xhci.h"
31
32 #if IS_ENABLED(CONFIG_PM)
33 static void sunxi_xhci_resume_work(struct work_struct *work);
34 #endif
35
36 #define SUNXI_XHCI_NAME "sunxi-xhci"
37 static const char xhci_name[] = SUNXI_XHCI_NAME;
38 #define SUNXI_ALIGN_MASK (16 - 1)
39
40 #if IS_ENABLED(CONFIG_USB_SUNXI_XHCI)
41 #define SUNXI_XHCI_OF_MATCH "allwinner,sunxi-xhci"
42 #else
43 #define SUNXI_XHCI_OF_MATCH "NULL"
44 #endif
45
46 static void sunxi_xhci_open_clock(struct sunxi_hci_hcd *sunxi_xhci);
47 static void sunxi_set_mode(struct sunxi_hci_hcd *sunxi_xhci, u32 mode);
48 static void sunxi_core_soft_reset(void __iomem *regs);
49 static int sunxi_core_open_phy(void __iomem *regs);
50
51 static struct sunxi_hci_hcd *g_sunxi_xhci;
52 static struct sunxi_hci_hcd *g_dev_data;
53
xhci_enable_show(struct device * dev,struct device_attribute * attr,char * buf)54 static ssize_t xhci_enable_show(struct device *dev,
55 struct device_attribute *attr, char *buf)
56 {
57 struct sunxi_hci_hcd *sunxi_xhci = NULL;
58
59 if (dev == NULL) {
60 DMSG_PANIC("Argment is invalid\n");
61 return 0;
62 }
63
64 sunxi_xhci = dev->platform_data;
65 if (sunxi_xhci == NULL) {
66 DMSG_PANIC("sunxi_xhci is null\n");
67 return 0;
68 }
69
70 return sprintf(buf, "xhci:%d, probe:%u\n",
71 sunxi_xhci->usbc_no, sunxi_xhci->probe);
72 }
73
xhci_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)74 static ssize_t xhci_enable_store(struct device *dev,
75 struct device_attribute *attr,
76 const char *buf, size_t count)
77 {
78 struct sunxi_hci_hcd *sunxi_xhci = NULL;
79 int value = 0;
80 int ret = 0;
81
82 if (dev == NULL) {
83 DMSG_PANIC("Argment is invalid\n");
84 return count;
85 }
86
87 sunxi_xhci = dev->platform_data;
88 if (sunxi_xhci == NULL) {
89 DMSG_PANIC("sunxi_xhci is null\n");
90 return count;
91 }
92
93 ret = kstrtoint(buf, 10, &value);
94 if (ret != 0)
95 return -EINVAL;
96 if (value == 1)
97 sunxi_usb_enable_xhci();
98 else if (value == 0)
99 sunxi_usb_disable_xhci();
100 else
101 DMSG_INFO("unknown value (%d)\n", value);
102
103 return count;
104 }
105
106 static DEVICE_ATTR(xhci_enable, 0664, xhci_enable_show, xhci_enable_store);
107
xhci_host2_test_mode(void __iomem * regs,int param)108 static int xhci_host2_test_mode(void __iomem *regs, int param)
109 {
110 int reg_value = 0;
111
112 switch (param) {
113 case TEST_J:
114 DMSG_INFO("xhci_host2_test_mode: TEST_J\n");
115 break;
116 case TEST_K:
117 DMSG_INFO("xhci_host2_test_mode: TEST_K\n");
118 break;
119 case TEST_SE0_NAK:
120 DMSG_INFO("xhci_host2_test_mode: TEST_SE0_NAK\n");
121 break;
122 case TEST_PACKET:
123 DMSG_INFO("xhci_host2_test_mode: TEST_PACKET\n");
124 break;
125 case TEST_FORCE_EN:
126 DMSG_INFO("xhci_host2_test_mode: TEST_FORCE_EN\n");
127 break;
128
129 default:
130 DMSG_INFO("not support test mode(%d)\n", param);
131 return -1;
132 }
133
134 reg_value = USBC_Readl(regs + XHCI_OP_REGS_HCPORT1SC);
135 reg_value &= ~(0x1 << 9);
136 USBC_Writel(reg_value, regs + XHCI_OP_REGS_HCPORT1SC);
137 msleep(20);
138
139 reg_value = USBC_Readl(regs + XHCI_OP_REGS_HCUSBCMD);
140 reg_value &= ~(0x1 << 0);
141 USBC_Writel(reg_value, regs + XHCI_OP_REGS_HCUSBCMD);
142 msleep(20);
143
144 reg_value = USBC_Readl(regs + XHCI_OP_REGS_HCUSBSTS);
145 reg_value &= ~(0x1 << 0);
146 USBC_Writel(reg_value, regs + XHCI_OP_REGS_HCUSBSTS);
147 msleep(20);
148 DMSG_INFO("Halted: 0x%x, param: %d\n",
149 USBC_Readl(regs + XHCI_OP_REGS_HCUSBSTS), param);
150
151 reg_value = USBC_Readl(regs + XHCI_OP_REGS_HCPORT1PMSC);
152 reg_value |= (param << 28);
153 USBC_Writel(reg_value, regs + XHCI_OP_REGS_HCPORT1PMSC);
154 msleep(20);
155 DMSG_INFO("test_code: %x\n",
156 USBC_Readl(regs + XHCI_OP_REGS_HCPORT1PMSC));
157
158 return 0;
159 }
160
ed_test_show(struct device * dev,struct device_attribute * attr,char * buf)161 static ssize_t ed_test_show(struct device *dev,
162 struct device_attribute *attr, char *buf)
163 {
164 struct sunxi_hci_hcd *sunxi_xhci = NULL;
165 struct sunxi_hci_hcd *dev_data = NULL;
166
167 if (dev == NULL) {
168 DMSG_PANIC("Argment is invalid\n");
169 return 0;
170 }
171
172 sunxi_xhci = g_sunxi_xhci;
173 dev_data = g_dev_data;
174 if (sunxi_xhci == NULL) {
175 DMSG_PANIC("sunxi_xhci is null\n");
176 return 0;
177 }
178
179 return sprintf(buf, "USB2.0 host test mode:\n"
180 "echo:\ntest_j_state\ntest_k_state\ntest_se0_nak\n"
181 "test_pack\ntest_force_enable\n\n"
182 "USB3.0 host test mode:\n"
183 "echo:\ntest_host3\n");
184 }
185
ed_test_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)186 static ssize_t ed_test_store(struct device *dev,
187 struct device_attribute *attr,
188 const char *buf, size_t count)
189 {
190 struct sunxi_hci_hcd *sunxi_xhci = NULL;
191 struct sunxi_hci_hcd *dev_data = NULL;
192 struct usb_hcd *hcd = NULL;
193 u32 testmode = 0;
194
195 if (dev == NULL) {
196 DMSG_PANIC("Argment is invalid\n");
197 return count;
198 }
199
200 sunxi_xhci = g_sunxi_xhci;
201 dev_data = g_dev_data;
202 if (sunxi_xhci == NULL) {
203 DMSG_PANIC("sunxi_xhci is null\n");
204 return count;
205 }
206
207 if (dev_data->probe == 0) {
208 DMSG_INFO("[%s]: is disable, can not enter test mode\n",
209 dev_data->hci_name);
210 return count;
211 }
212
213 hcd = dev_get_drvdata(&sunxi_xhci->pdev->dev);
214 if (hcd == NULL) {
215 DMSG_PANIC("xhci hcd is null\n");
216 return count;
217 }
218
219 /* USB3.0 test mode */
220 if (!strncmp(buf, "test_host3", 10)) {
221 DMSG_INFO("xhci usb3.0 host test mode\n");
222 sunxi_usb_disable_xhci();
223 sunxi_xhci_open_clock(dev_data);
224 sunxi_core_open_phy(sunxi_xhci->regs);
225 sunxi_core_soft_reset(sunxi_xhci->regs);
226 sunxi_set_mode(sunxi_xhci, SUNXI_GCTL_PRTCAP_HOST);
227 return count;
228 }
229
230 /* USB2.0 test mode */
231 if (!strncmp(buf, "test_j_state", 12))
232 testmode = TEST_J;
233 else if (!strncmp(buf, "test_k_state", 12))
234 testmode = TEST_K;
235 else if (!strncmp(buf, "test_se0_nak", 12))
236 testmode = TEST_SE0_NAK;
237 else if (!strncmp(buf, "test_pack", 9))
238 testmode = TEST_PACKET;
239 else if (!strncmp(buf, "test_force_enable", 17))
240 testmode = TEST_FORCE_EN;
241 else
242 testmode = 0;
243
244 xhci_host2_test_mode(hcd->regs, testmode);
245
246 return count;
247 }
248
249 static DEVICE_ATTR(ed_test, 0664, ed_test_show, ed_test_store);
250
251 /**
252 * sunxi_core_soft_reset - Issues core soft reset and PHY reset
253 * @sunxi_xhci: pointer to our context structure
254 */
sunxi_core_soft_reset(void __iomem * regs)255 static void sunxi_core_soft_reset(void __iomem *regs)
256 {
257 int reg = 0;
258
259 /* Before Resetting PHY, put Core in Reset */
260 reg = USBC_Readl(regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
261 reg |= SUNXI_GCTL_CORESOFTRESET;
262 USBC_Writel(reg, regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
263
264 /* Assert USB3 PHY reset */
265 reg = USBC_Readl(regs + (SUNXI_GUSB3PIPECTL(0) - SUNXI_GLOBALS_REGS_START));
266 reg |= SUNXI_USB3PIPECTL_PHYSOFTRST;
267 USBC_Writel(reg, regs + (SUNXI_GUSB3PIPECTL(0) - SUNXI_GLOBALS_REGS_START));
268
269 /* Assert USB2 PHY reset */
270 reg = USBC_Readl(regs + (SUNXI_GUSB2PHYCFG(0) - SUNXI_GLOBALS_REGS_START));
271 reg |= SUNXI_USB2PHYCFG_PHYSOFTRST;
272 USBC_Writel(reg, regs + (SUNXI_GUSB2PHYCFG(0) - SUNXI_GLOBALS_REGS_START));
273
274 mdelay(100);
275
276 /* Clear USB3 PHY reset */
277 reg = USBC_Readl(regs + (SUNXI_GUSB3PIPECTL(0) - SUNXI_GLOBALS_REGS_START));
278 reg &= ~SUNXI_USB3PIPECTL_PHYSOFTRST;
279 USBC_Writel(reg, regs + (SUNXI_GUSB3PIPECTL(0) - SUNXI_GLOBALS_REGS_START));
280
281 /* Clear USB2 PHY reset */
282 reg = USBC_Readl(regs + (SUNXI_GUSB2PHYCFG(0) - SUNXI_GLOBALS_REGS_START));
283 reg &= ~SUNXI_USB2PHYCFG_PHYSOFTRST;
284 USBC_Writel(reg, regs + (SUNXI_GUSB2PHYCFG(0) - SUNXI_GLOBALS_REGS_START));
285
286 mdelay(100);
287
288 /* After PHYs are stable we can take Core out of reset state */
289 reg = USBC_Readl(regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
290 reg &= ~SUNXI_GCTL_CORESOFTRESET;
291 USBC_Writel(reg, regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
292 }
293
sunxi_core_open_phy(void __iomem * regs)294 static int sunxi_core_open_phy(void __iomem *regs)
295 {
296 int reg_val = 0;
297
298 reg_val = USBC_Readl(regs + (SUNXI_PHY_EXTERNAL_CONTROL - SUNXI_GLOBALS_REGS_START));
299 reg_val |= SUNXI_PEC_EXTERN_VBUS; /* Use extern vbus to phy */
300 reg_val |= SUNXI_PEC_SSC_EN; /* SSC_EN */
301 reg_val |= SUNXI_PEC_REF_SSP_EN; /*REF_SSP_EN */
302 USBC_Writel(reg_val, regs + (SUNXI_PHY_EXTERNAL_CONTROL - SUNXI_GLOBALS_REGS_START));
303
304 reg_val = USBC_Readl(regs + (SUNXI_PIPE_CLOCK_CONTROL - SUNXI_GLOBALS_REGS_START));
305 reg_val |= SUNXI_PPC_PIPE_CLK_OPEN; /* open PIPE clock */
306 USBC_Writel(reg_val, regs + (SUNXI_PIPE_CLOCK_CONTROL - SUNXI_GLOBALS_REGS_START));
307
308 reg_val = USBC_Readl(regs + (SUNXI_APP - SUNXI_GLOBALS_REGS_START));
309 reg_val |= SUNXI_APP_FOCE_VBUS; /* open PIPE clock */
310 USBC_Writel(reg_val, regs + (SUNXI_APP - SUNXI_GLOBALS_REGS_START));
311
312 /* It is set 0x0047fc87 on bare-metal.*/
313 USBC_Writel(0x0047fc57, regs + (SUNXI_PHY_TUNE_LOW - SUNXI_GLOBALS_REGS_START));
314
315 reg_val = USBC_Readl(regs + (SUNXI_PHY_TUNE_HIGH - SUNXI_GLOBALS_REGS_START));
316 reg_val |= SUNXI_TXVBOOSTLVL(0x7);
317 reg_val |= SUNXI_LOS_BIAS(0x7);
318
319 reg_val &= ~(SUNXI_TX_SWING_FULL(0x7f));
320 reg_val |= SUNXI_TX_SWING_FULL(0x55);
321
322 reg_val &= ~(SUNXI_TX_DEEMPH_6DB(0x3f));
323 reg_val |= SUNXI_TX_DEEMPH_6DB(0x20);
324
325 reg_val &= ~(SUNXI_TX_DEEMPH_3P5DB(0x3f));
326 reg_val |= SUNXI_TX_DEEMPH_3P5DB(0x15);
327 USBC_Writel(reg_val, regs + (SUNXI_PHY_TUNE_HIGH - SUNXI_GLOBALS_REGS_START));
328
329 /* Enable USB2.0 PHY Suspend mode. */
330 reg_val = USBC_Readl(regs + (SUNXI_GUSB2PHYCFG(0) - SUNXI_GLOBALS_REGS_START));
331 reg_val |= SUNXI_USB2PHYCFG_SUSPHY;
332 USBC_Writel(reg_val, regs + (SUNXI_GUSB2PHYCFG(0) - SUNXI_GLOBALS_REGS_START));
333
334 /* Enable SOFITPSYNC for suspend. */
335 reg_val = USBC_Readl(regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
336 reg_val |= SUNXI_GCTL_SOFITPSYNC;
337 USBC_Writel(reg_val, regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
338
339 return 0;
340 }
341
sunxi_xhci_open_clock(struct sunxi_hci_hcd * sunxi_xhci)342 static void sunxi_xhci_open_clock(struct sunxi_hci_hcd *sunxi_xhci)
343 {
344 sunxi_xhci->open_clock(sunxi_xhci, 0);
345 }
346
sunxi_xhci_set_vbus(struct sunxi_hci_hcd * sunxi_xhci,int is_on)347 static void sunxi_xhci_set_vbus(struct sunxi_hci_hcd *sunxi_xhci, int is_on)
348 {
349 sunxi_xhci->set_power(sunxi_xhci, is_on);
350 }
351
sunxi_start_xhci(struct sunxi_hci_hcd * sunxi_xhci)352 static void sunxi_start_xhci(struct sunxi_hci_hcd *sunxi_xhci)
353 {
354 sunxi_xhci->open_clock(sunxi_xhci, 1);
355 sunxi_xhci->set_power(sunxi_xhci, 1);
356 }
357
sunxi_stop_xhci(struct sunxi_hci_hcd * sunxi_xhci)358 static void sunxi_stop_xhci(struct sunxi_hci_hcd *sunxi_xhci)
359 {
360 sunxi_xhci->set_power(sunxi_xhci, 0);
361 sunxi_xhci->close_clock(sunxi_xhci, 0);
362 }
363
sunxi_set_mode(struct sunxi_hci_hcd * sunxi_xhci,u32 mode)364 static void sunxi_set_mode(struct sunxi_hci_hcd *sunxi_xhci, u32 mode)
365 {
366 u32 reg;
367
368 reg = USBC_Readl(sunxi_xhci->regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
369 reg &= ~(SUNXI_GCTL_PRTCAPDIR(SUNXI_GCTL_PRTCAP_OTG));
370 reg |= SUNXI_GCTL_PRTCAPDIR(mode);
371 USBC_Writel(reg, sunxi_xhci->regs + (SUNXI_GLOBALS_REGS_GCTL - SUNXI_GLOBALS_REGS_START));
372 }
373
xhci_host_init(struct sunxi_hci_hcd * sunxi_xhci)374 int xhci_host_init(struct sunxi_hci_hcd *sunxi_xhci)
375 {
376 struct platform_device *xhci;
377 int ret;
378
379 xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
380 if (!xhci) {
381 dev_err(sunxi_xhci->dev, "couldn't allocate xHCI device\n");
382 ret = -ENOMEM;
383 goto err0;
384 }
385
386 dma_set_coherent_mask(&xhci->dev, sunxi_xhci->dev->coherent_dma_mask);
387
388 xhci->dev.parent = sunxi_xhci->dev;
389 xhci->dev.dma_mask = sunxi_xhci->dev->dma_mask;
390 xhci->dev.dma_parms = sunxi_xhci->dev->dma_parms;
391 xhci->dev.archdata.dma_ops = sunxi_xhci->dev->archdata.dma_ops;
392 xhci->dev.archdata.dma_coherent = sunxi_xhci->dev->archdata.dma_coherent;
393
394 sunxi_xhci->pdev = xhci;
395
396 ret = platform_device_add_resources(xhci, sunxi_xhci->xhci_resources,
397 XHCI_RESOURCES_NUM);
398 if (ret) {
399 dev_err(sunxi_xhci->dev, "couldn't add resources to xHCI device\n");
400 goto err1;
401 }
402
403 ret = platform_device_add(xhci);
404 if (ret) {
405 dev_err(sunxi_xhci->dev, "failed to register xHCI device\n");
406 goto err1;
407 }
408
409 return 0;
410
411 err1:
412 platform_device_put(xhci);
413
414 err0:
415 return ret;
416 }
417
xhci_host_exit(struct sunxi_hci_hcd * sunxi_xhci)418 void xhci_host_exit(struct sunxi_hci_hcd *sunxi_xhci)
419 {
420 platform_device_unregister(sunxi_xhci->pdev);
421 }
422
sunxi_xhci_hcd_probe(struct platform_device * pdev)423 static int sunxi_xhci_hcd_probe(struct platform_device *pdev)
424 {
425 int ret = 0;
426 struct sunxi_hci_hcd *sunxi_xhci = NULL;
427 void *mem;
428
429 struct device *dev = &pdev->dev;
430
431 struct resource *res;
432 void __iomem *regs;
433
434 if (pdev == NULL) {
435 DMSG_PANIC("%s, Argment is invalid\n", __func__);
436 return -1;
437 }
438
439 /* if usb is disabled, can not probe */
440 if (usb_disabled()) {
441 DMSG_PANIC("usb hcd is disabled\n");
442 return -ENODEV;
443 }
444
445 mem = devm_kzalloc(dev, sizeof(*sunxi_xhci) + SUNXI_ALIGN_MASK, GFP_KERNEL);
446 if (!mem) {
447 dev_err(dev, "not enough memory\n");
448 return -ENOMEM;
449 }
450 sunxi_xhci = PTR_ALIGN(mem, SUNXI_ALIGN_MASK + 1);
451 sunxi_xhci->mem = mem;
452
453 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
454 if (!res) {
455 dev_err(dev, "missing IRQ\n");
456 return -ENODEV;
457 }
458 sunxi_xhci->xhci_resources[1].start = res->start;
459 sunxi_xhci->xhci_resources[1].end = res->end;
460 sunxi_xhci->xhci_resources[1].flags = res->flags;
461 sunxi_xhci->xhci_resources[1].name = res->name;
462
463 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
464 if (!res) {
465 dev_err(dev, "missing memory resource\n");
466 return -ENODEV;
467 }
468 sunxi_xhci->xhci_resources[0].start = res->start;
469 sunxi_xhci->xhci_resources[0].end = sunxi_xhci->xhci_resources[0].start +
470 XHCI_REGS_END;
471 sunxi_xhci->xhci_resources[0].flags = res->flags;
472 sunxi_xhci->xhci_resources[0].name = res->name;
473
474 /*
475 * Request memory region but exclude xHCI regs,
476 * since it will be requested by the xhci-plat driver.
477 */
478 res = devm_request_mem_region(dev, res->start + SUNXI_GLOBALS_REGS_START,
479 resource_size(res) - SUNXI_GLOBALS_REGS_START,
480 dev_name(dev));
481 if (!res) {
482 dev_err(dev, "can't request mem region\n");
483 return -ENOMEM;
484 }
485
486 regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
487 if (!regs) {
488 dev_err(dev, "ioremap failed\n");
489 return -ENOMEM;
490 }
491
492 spin_lock_init(&sunxi_xhci->lock);
493
494 sunxi_xhci->regs = regs;
495 sunxi_xhci->regs_size = resource_size(res);
496 sunxi_xhci->dev = dev;
497
498 dev->dma_mask = dev->parent->dma_mask;
499 dev->dma_parms = dev->parent->dma_parms;
500 dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
501
502 ret = init_sunxi_hci(pdev, SUNXI_USB_XHCI);
503 if (ret != 0) {
504 dev_err(&pdev->dev, "init_sunxi_hci is fail\n");
505 return 0;
506 }
507
508 platform_set_drvdata(pdev, sunxi_xhci);
509
510 sunxi_start_xhci(pdev->dev.platform_data);
511 sunxi_core_open_phy(sunxi_xhci->regs);
512 sunxi_set_mode(sunxi_xhci, SUNXI_GCTL_PRTCAP_HOST);
513
514 xhci_host_init(sunxi_xhci);
515
516 device_create_file(&pdev->dev, &dev_attr_xhci_enable);
517 device_create_file(&pdev->dev, &dev_attr_ed_test);
518
519 g_sunxi_xhci = sunxi_xhci;
520 g_dev_data = pdev->dev.platform_data;
521
522 g_dev_data->probe = 1;
523
524 #if IS_ENABLED(CONFIG_PM)
525 if (!g_dev_data->wakeup_suspend)
526 INIT_WORK(&g_dev_data->resume_work, sunxi_xhci_resume_work);
527 #endif
528
529 return 0;
530 }
531
sunxi_xhci_hcd_remove(struct platform_device * pdev)532 static int sunxi_xhci_hcd_remove(struct platform_device *pdev)
533 {
534 struct sunxi_hci_hcd *sunxi_xhci = NULL;
535 struct sunxi_hci_hcd *dev_data = NULL;
536
537 if (pdev == NULL) {
538 DMSG_PANIC("%s, Argment is invalid\n", __func__);
539 return -1;
540 }
541
542 sunxi_xhci = g_sunxi_xhci;
543 dev_data = g_dev_data;
544 if (sunxi_xhci == NULL) {
545 DMSG_PANIC("%s, sunxi_xhci is null\n", __func__);
546 return -1;
547 }
548
549 device_remove_file(&pdev->dev, &dev_attr_xhci_enable);
550
551 xhci_host_exit(sunxi_xhci);
552 sunxi_stop_xhci(dev_data);
553
554 dev_data->probe = 0;
555
556 return 0;
557 }
558
sunxi_xhci_hcd_shutdown(struct platform_device * pdev)559 static void sunxi_xhci_hcd_shutdown(struct platform_device *pdev)
560 {
561 struct sunxi_hci_hcd *sunxi_xhci = NULL;
562 struct sunxi_hci_hcd *dev_data = NULL;
563
564 if (pdev == NULL) {
565 DMSG_PANIC("%s, Argment is invalid\n", __func__);
566 return;
567 }
568
569 sunxi_xhci = g_sunxi_xhci;
570 dev_data = g_dev_data;
571 if (sunxi_xhci == NULL) {
572 DMSG_PANIC("%s, is null\n", __func__);
573 return;
574 }
575
576 if (dev_data->probe == 0) {
577 DMSG_INFO("%s, %s is disable, need not shutdown\n", __func__, sunxi_xhci->hci_name);
578 return;
579 }
580
581 DMSG_INFO("[%s]: xhci shutdown start\n", sunxi_xhci->hci_name);
582
583 usb_hcd_platform_shutdown(sunxi_xhci->pdev);
584
585 DMSG_INFO("[%s]: xhci shutdown end\n", sunxi_xhci->hci_name);
586
587 return;
588 }
589
sunxi_usb_disable_xhci(void)590 int sunxi_usb_disable_xhci(void)
591 {
592 struct sunxi_hci_hcd *sunxi_xhci = NULL;
593 struct sunxi_hci_hcd *dev_data = NULL;
594
595 sunxi_xhci = g_sunxi_xhci;
596 dev_data = g_dev_data;
597 if (sunxi_xhci == NULL || dev_data == NULL) {
598 DMSG_PANIC("sunxi_xhci is null\n");
599 return -1;
600 }
601
602 if (dev_data->probe == 0) {
603 DMSG_PANIC("sunxi_xhci is disable, can not disable again\n");
604 return -1;
605 }
606
607 dev_data->probe = 0;
608
609 DMSG_INFO("[%s]: sunxi_usb_disable_xhci\n", sunxi_xhci->hci_name);
610
611 xhci_host_exit(sunxi_xhci);
612 sunxi_stop_xhci(dev_data);
613
614 return 0;
615 }
616 EXPORT_SYMBOL(sunxi_usb_disable_xhci);
617
sunxi_usb_enable_xhci(void)618 int sunxi_usb_enable_xhci(void)
619 {
620 struct sunxi_hci_hcd *sunxi_xhci = NULL;
621 struct sunxi_hci_hcd *dev_data = NULL;
622
623 sunxi_xhci = g_sunxi_xhci;
624 dev_data = g_dev_data;
625 if (sunxi_xhci == NULL || dev_data == NULL) {
626 DMSG_PANIC("sunxi_xhci is null\n");
627 return -1;
628 }
629
630 if (dev_data->probe == 1) {
631 DMSG_PANIC("sunxi_xhci is already enable, can not enable again\n");
632 return -1;
633 }
634
635 dev_data->probe = 1;
636
637 DMSG_INFO("[%s]: sunxi_usb_enable_xhci\n", sunxi_xhci->hci_name);
638
639 sunxi_start_xhci(dev_data);
640 sunxi_core_open_phy(sunxi_xhci->regs);
641 sunxi_set_mode(sunxi_xhci, SUNXI_GCTL_PRTCAP_HOST);
642
643 xhci_host_init(sunxi_xhci);
644
645 return 0;
646 }
647 EXPORT_SYMBOL(sunxi_usb_enable_xhci);
648
649 #if IS_ENABLED(CONFIG_PM)
sunxi_xhci_hcd_suspend(struct device * dev)650 static int sunxi_xhci_hcd_suspend(struct device *dev)
651 {
652 struct sunxi_hci_hcd *sunxi_xhci = NULL;
653 struct sunxi_hci_hcd *dev_data = NULL;
654 struct usb_hcd *hcd = NULL;
655 struct xhci_hcd *xhci = NULL;
656
657 if (dev == NULL) {
658 DMSG_PANIC("%s, Argment is invalid\n", __func__);
659 return 0;
660 }
661
662 sunxi_xhci = g_sunxi_xhci;
663 dev_data = g_dev_data;
664 if (sunxi_xhci == NULL) {
665 DMSG_PANIC("sunxi_xhci is null\n");
666 return 0;
667 }
668
669 if (dev_data->probe == 0) {
670 DMSG_INFO("[%s]: is disable, need not suspend\n",
671 dev_data->hci_name);
672 return 0;
673 }
674
675 hcd = dev_get_drvdata(&sunxi_xhci->pdev->dev);
676 if (hcd == NULL) {
677 DMSG_PANIC("xhci hcd is null\n");
678 return 0;
679 }
680
681 xhci = hcd_to_xhci(hcd);
682 if (xhci == NULL) {
683 DMSG_PANIC("xhci is null\n");
684 return 0;
685 }
686
687 if (dev_data->wakeup_suspend) {
688 DMSG_INFO("[%s]: not suspend\n", dev_data->hci_name);
689 } else {
690 DMSG_INFO("[%s]: sunxi_xhci_hcd_suspend\n", dev_data->hci_name);
691
692 xhci_suspend(xhci, false);
693 sunxi_stop_xhci(dev_data);
694
695 cancel_work_sync(&dev_data->resume_work);
696 }
697
698 return 0;
699 }
700
sunxi_xhci_resume_work(struct work_struct * work)701 static void sunxi_xhci_resume_work(struct work_struct *work)
702 {
703 struct sunxi_hci_hcd *dev_data = NULL;
704
705 dev_data = container_of(work, struct sunxi_hci_hcd, resume_work);
706
707 /* Waiting hci to resume. */
708 msleep(5000);
709
710 sunxi_xhci_set_vbus(dev_data, 1);
711 }
712
sunxi_xhci_hcd_resume(struct device * dev)713 static int sunxi_xhci_hcd_resume(struct device *dev)
714 {
715 struct sunxi_hci_hcd *sunxi_xhci = NULL;
716 struct sunxi_hci_hcd *dev_data = NULL;
717 struct usb_hcd *hcd = NULL;
718 struct xhci_hcd *xhci = NULL;
719
720 if (dev == NULL) {
721 DMSG_PANIC("Argment is invalid\n");
722 return 0;
723 }
724
725 sunxi_xhci = g_sunxi_xhci;
726 dev_data = g_dev_data;
727 if (sunxi_xhci == NULL) {
728 DMSG_PANIC("sunxi_xhci is null\n");
729 return 0;
730 }
731
732 if (dev_data->probe == 0) {
733 DMSG_INFO("[%s]: is disable, need not resume\n",
734 dev_data->hci_name);
735 return 0;
736 }
737
738 hcd = dev_get_drvdata(&sunxi_xhci->pdev->dev);
739 if (hcd == NULL) {
740 DMSG_PANIC("xhci hcd is null\n");
741 return 0;
742 }
743
744 xhci = hcd_to_xhci(hcd);
745 if (xhci == NULL) {
746 DMSG_PANIC("xhci is null\n");
747 return 0;
748 }
749
750 if (dev_data->wakeup_suspend) {
751 DMSG_INFO("[%s]: controller not suspend, need not resume\n",
752 dev_data->hci_name);
753 } else {
754 DMSG_INFO("[%s]: sunxi_xhci_hcd_resume\n", dev_data->hci_name);
755
756 sunxi_xhci_open_clock(dev_data);
757 sunxi_core_open_phy(sunxi_xhci->regs);
758 sunxi_set_mode(sunxi_xhci, SUNXI_GCTL_PRTCAP_HOST);
759 xhci_resume(xhci, false);
760
761 schedule_work(&dev_data->resume_work);
762 }
763
764 return 0;
765 }
766
767 static const struct dev_pm_ops xhci_pmops = {
768 .suspend = sunxi_xhci_hcd_suspend,
769 .resume = sunxi_xhci_hcd_resume,
770 };
771 #endif
772
773 static const struct of_device_id sunxi_xhci_match[] = {
774 {.compatible = SUNXI_XHCI_OF_MATCH, },
775 {},
776 };
777 MODULE_DEVICE_TABLE(of, sunxi_xhci_match);
778
779 static struct platform_driver sunxi_xhci_hcd_driver = {
780 .probe = sunxi_xhci_hcd_probe,
781 .remove = sunxi_xhci_hcd_remove,
782 .shutdown = sunxi_xhci_hcd_shutdown,
783 .driver = {
784 .name = xhci_name,
785 .owner = THIS_MODULE,
786 #if IS_ENABLED(CONFIG_PM)
787 .pm = &xhci_pmops,
788 #endif
789 .of_match_table = sunxi_xhci_match,
790 }
791 };
792
793 module_platform_driver(sunxi_xhci_hcd_driver);
794
795 MODULE_ALIAS("platform:sunxi xhci");
796 MODULE_AUTHOR("wangjx <wangjx@allwinnertech.com>");
797 MODULE_LICENSE("Dual BSD/GPL");
798 MODULE_DESCRIPTION("Allwinnertech Xhci Controller Driver");
799