• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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