• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * drivers/usb/host/ehci-sunxi.c
3  * (C) Copyright 2010-2015
4  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
5  * yangnaitian, 2011-5-24, create this file
6  * javen, 2011-6-26, add suspend and resume
7  * javen, 2011-7-18, move clock and power operations out from driver
8  *
9  * SoftWinner EHCI Driver
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  */
17 
18 #include <linux/platform_device.h>
19 #include <linux/time.h>
20 #include <linux/timer.h>
21 #include <linux/clk.h>
22 #include <linux/notifier.h>
23 #include <linux/suspend.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/phy/phy.h>
27 #include <linux/usb.h>
28 #include <linux/usb/hcd.h>
29 #include <linux/regulator/consumer.h>
30 #include "ehci.h"
31 #include "sunxi-hci.h"
32 
33 #define DRIVER_DESC "EHCI SUNXI driver"
34 
35 #define  SUNXI_EHCI_NAME	"sunxi-ehci"
36 static const char ehci_name[] = SUNXI_EHCI_NAME;
37 
38 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI0)
39 #define  SUNXI_EHCI0_OF_MATCH	"allwinner,sunxi-ehci0"
40 #else
41 #define  SUNXI_EHCI0_OF_MATCH   "null"
42 #endif
43 
44 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI1)
45 #define  SUNXI_EHCI1_OF_MATCH	"allwinner,sunxi-ehci1"
46 #else
47 #define  SUNXI_EHCI1_OF_MATCH   "null"
48 #endif
49 
50 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI2)
51 #define  SUNXI_EHCI2_OF_MATCH	"allwinner,sunxi-ehci2"
52 #else
53 #define  SUNXI_EHCI2_OF_MATCH   "null"
54 #endif
55 
56 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI3)
57 #define  SUNXI_EHCI3_OF_MATCH	"allwinner,sunxi-ehci3"
58 #else
59 #define  SUNXI_EHCI3_OF_MATCH   "null"
60 #endif
61 
62 static struct sunxi_hci_hcd *g_sunxi_ehci[4];
63 static u32 ehci_first_probe[4] = {1, 1, 1, 1};
64 static u32 ehci_enable[4] = {1, 1, 1, 1};
65 static atomic_t ehci_in_standby;
66 
67 #if IS_ENABLED(CONFIG_PM)
68 static void sunxi_ehci_resume_work(struct work_struct *work);
69 #endif
70 
71 int sunxi_usb_disable_ehci(__u32 usbc_no);
72 int sunxi_usb_enable_ehci(__u32 usbc_no);
73 
ehci_set_interrupt_enable(const struct ehci_hcd * ehci,void __iomem * regs,u32 enable)74 static void  ehci_set_interrupt_enable(const struct ehci_hcd *ehci,
75 		void __iomem *regs, u32 enable)
76 {
77 	ehci_writel(ehci, enable & 0x3f, (regs + EHCI_OPR_USBINTR));
78 }
79 
ehci_disable_periodic_schedule(const struct ehci_hcd * ehci,void __iomem * regs)80 static void ehci_disable_periodic_schedule(const struct ehci_hcd *ehci,
81 		void __iomem *regs)
82 {
83 	u32 reg_val = 0;
84 
85 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
86 	reg_val	&= ~(0x1<<4);
87 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
88 }
89 
ehci_disable_async_schedule(const struct ehci_hcd * ehci,void __iomem * regs)90 static void ehci_disable_async_schedule(const struct ehci_hcd *ehci,
91 		void __iomem *regs)
92 {
93 	unsigned int reg_val = 0;
94 
95 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
96 	reg_val &= ~(0x1<<5);
97 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
98 }
99 
ehci_set_config_flag(const struct ehci_hcd * ehci,void __iomem * regs)100 static void ehci_set_config_flag(const struct ehci_hcd *ehci,
101 		void __iomem *regs)
102 {
103 	ehci_writel(ehci, 0x1, (regs + EHCI_OPR_CFGFLAG));
104 }
105 
ehci_test_stop(const struct ehci_hcd * ehci,void __iomem * regs)106 static void ehci_test_stop(const struct ehci_hcd *ehci,
107 		void __iomem *regs)
108 {
109 	unsigned int reg_val = 0;
110 
111 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
112 	reg_val &= (~0x1);
113 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
114 }
115 
ehci_test_reset(const struct ehci_hcd * ehci,void __iomem * regs)116 static void ehci_test_reset(const struct ehci_hcd *ehci,
117 		void __iomem *regs)
118 {
119 	u32 reg_val = 0;
120 
121 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
122 	reg_val	|= (0x1<<1);
123 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
124 }
125 
ehci_test_reset_complete(const struct ehci_hcd * ehci,void __iomem * regs)126 static unsigned int ehci_test_reset_complete(const struct ehci_hcd *ehci,
127 		void __iomem *regs)
128 {
129 
130 	unsigned int reg_val = 0;
131 
132 	reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
133 	reg_val &= (0x1<<1);
134 
135 	return !reg_val;
136 }
137 
ehci_start(const struct ehci_hcd * ehci,void __iomem * regs)138 static void ehci_start(const struct ehci_hcd *ehci, void __iomem *regs)
139 {
140 	unsigned int reg_val = 0;
141 
142 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
143 	reg_val	|= 0x1;
144 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
145 }
146 
ehci_is_halt(const struct ehci_hcd * ehci,void __iomem * regs)147 static unsigned int ehci_is_halt(const struct ehci_hcd *ehci,
148 		void __iomem *regs)
149 {
150 	unsigned int reg_val = 0;
151 
152 	reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBSTS))  >> 12;
153 	reg_val &= 0x1;
154 	return reg_val;
155 }
156 
ehci_port_control(const struct ehci_hcd * ehci,void __iomem * regs,u32 port_no,u32 control)157 static void ehci_port_control(const struct ehci_hcd *ehci,
158 		void __iomem *regs, u32 port_no, u32 control)
159 {
160 	ehci_writel(ehci, control, (regs + EHCI_OPR_USBCMD + (port_no<<2)));
161 }
162 
ehci_put_port_suspend(const struct ehci_hcd * ehci,void __iomem * regs)163 static void  ehci_put_port_suspend(const struct ehci_hcd *ehci,
164 		void __iomem *regs)
165 {
166 	unsigned int reg_val = 0;
167 
168 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_PORTSC));
169 	reg_val	|= (0x01<<7);
170 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_PORTSC));
171 }
172 
ehci_test_mode(const struct ehci_hcd * ehci,void __iomem * regs,u32 test_mode)173 static void ehci_test_mode(const struct ehci_hcd *ehci,
174 		void __iomem *regs, u32 test_mode)
175 {
176 	unsigned int reg_val = 0;
177 
178 	reg_val =  ehci_readl(ehci, (regs + EHCI_OPR_PORTSC));
179 	reg_val &= ~(0x0f<<16);
180 	reg_val |= test_mode;
181 	ehci_writel(ehci, reg_val, (regs + EHCI_OPR_PORTSC));
182 }
183 
__ehci_ed_test(const struct ehci_hcd * ehci,void __iomem * regs,__u32 test_mode)184 static void __ehci_ed_test(const struct ehci_hcd *ehci,
185 		void __iomem *regs, __u32 test_mode)
186 {
187 	ehci_set_interrupt_enable(ehci, regs, 0x00);
188 	ehci_disable_periodic_schedule(ehci, regs);
189 	ehci_disable_async_schedule(ehci, regs);
190 
191 	ehci_set_config_flag(ehci, regs);
192 
193 	ehci_test_stop(ehci, regs);
194 	ehci_test_reset(ehci, regs);
195 
196 	/* Wait until EHCI reset complete. */
197 	while (!ehci_test_reset_complete(ehci, regs))
198 		;
199 
200 	if (!ehci_is_halt(ehci, regs))
201 		DMSG_ERR("%s_%d\n", __func__, __LINE__);
202 
203 	ehci_start(ehci, regs);
204 	/* Wait until EHCI to be not halt. */
205 	while (ehci_is_halt(ehci, regs))
206 		;
207 
208 	/* Ehci start, config to test. */
209 	ehci_set_config_flag(ehci, regs);
210 	ehci_port_control(ehci, regs, 0, EHCI_PORTSC_POWER);
211 
212 	ehci_disable_periodic_schedule(ehci, regs);
213 	ehci_disable_async_schedule(ehci, regs);
214 
215 	/* Put port suspend. */
216 	ehci_put_port_suspend(ehci, regs);
217 
218 	ehci_test_stop(ehci, regs);
219 
220 	while ((!ehci_is_halt(ehci, regs)))
221 		;
222 
223 	/* Test pack. */
224 	DMSG_INFO("Start Host Test,mode:0x%x!\n", test_mode);
225 	ehci_test_mode(ehci, regs, test_mode);
226 	DMSG_INFO("End Host Test,mode:0x%x!\n", test_mode);
227 }
228 
show_ed_test(struct device * dev,struct device_attribute * attr,char * buf)229 static ssize_t show_ed_test(struct device *dev,
230 		struct device_attribute *attr, char *buf)
231 {
232 	return sprintf(buf, "USB2.0 host test mode:\n"
233 				"echo:\ntest_j_state\ntest_k_state\ntest_se0_nak\n"
234 				"test_pack\ntest_force_enable\ntest_mask\n\n");
235 }
236 
ehci_ed_test(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)237 static ssize_t ehci_ed_test(struct device *dev, struct device_attribute *attr,
238 		const char *buf, size_t count)
239 {
240 	__u32 test_mode = 0;
241 	struct usb_hcd *hcd = NULL;
242 	struct ehci_hcd *ehci = NULL;
243 
244 	if (dev == NULL) {
245 		DMSG_PANIC("ERR: Argment is invalid\n");
246 		return 0;
247 	}
248 
249 	hcd = dev_get_drvdata(dev);
250 	if (hcd == NULL) {
251 		DMSG_PANIC("ERR: hcd is null\n");
252 		return 0;
253 	}
254 
255 	ehci = hcd_to_ehci(hcd);
256 	if (ehci == NULL) {
257 		DMSG_PANIC("ERR: ehci is null\n");
258 		return 0;
259 	}
260 
261 	mutex_lock(&dev->mutex);
262 
263 	DMSG_INFO("ehci_ed_test:%s\n", buf);
264 
265 	if (!strncmp(buf, "test_not_operating", 18)) {
266 		test_mode = EHCI_PORTSC_PTC_DIS;
267 		DMSG_INFO("test_mode:0x%x\n", test_mode);
268 	} else if (!strncmp(buf, "test_j_state", 12)) {
269 		test_mode = EHCI_PORTSC_PTC_J;
270 		DMSG_INFO("test_mode:0x%x\n", test_mode);
271 	} else if (!strncmp(buf, "test_k_state", 12)) {
272 		test_mode = EHCI_PORTSC_PTC_K;
273 		DMSG_INFO("test_mode:0x%x\n", test_mode);
274 	} else if (!strncmp(buf, "test_se0_nak", 12)) {
275 		test_mode = EHCI_PORTSC_PTC_SE0NAK;
276 		DMSG_INFO("test_mode:0x%x\n", test_mode);
277 	} else if (!strncmp(buf, "test_pack", 9)) {
278 		test_mode = EHCI_PORTSC_PTC_PACKET;
279 		DMSG_INFO("test_mode:0x%x\n", test_mode);
280 	} else if (!strncmp(buf, "test_force_enable", 17)) {
281 		test_mode = EHCI_PORTSC_PTC_FORCE;
282 		DMSG_INFO("test_mode:0x%x\n", test_mode);
283 	} else if (!strncmp(buf, "test_mask", 9)) {
284 		test_mode = EHCI_PORTSC_PTC_MASK;
285 		DMSG_INFO("test_mode:0x%x\n", test_mode);
286 	} else {
287 		DMSG_PANIC("ERR: test_mode Argment is invalid\n");
288 		mutex_unlock(&dev->mutex);
289 		return count;
290 	}
291 
292 	DMSG_INFO("regs: 0x%p\n", hcd->regs);
293 	__ehci_ed_test(ehci, hcd->regs, test_mode);
294 
295 	mutex_unlock(&dev->mutex);
296 
297 	return count;
298 }
299 
300 static DEVICE_ATTR(ed_test, 0644, show_ed_test, ehci_ed_test);
301 
show_phy_threshold(struct device * dev,struct device_attribute * attr,char * buf)302 static ssize_t show_phy_threshold(struct device *dev,
303 		struct device_attribute *attr, char *buf)
304 {
305 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
306 
307 	sunxi_ehci = dev->platform_data;
308 
309 	return sprintf(buf, "threshold:0x%x\n",
310 			usb_phyx_tp_read(sunxi_ehci, 0x2a, 2));
311 }
312 
ehci_phy_threshold(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)313 static ssize_t ehci_phy_threshold(struct device *dev,
314 		struct device_attribute *attr, const char *buf, size_t count)
315 {
316 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
317 	int val = 0;
318 	int err;
319 
320 	err = kstrtoint(buf, 16, &val);
321 	if (err != 0)
322 		return -EINVAL;
323 
324 	if (dev == NULL) {
325 		DMSG_PANIC("ERR: Argment is invalid\n");
326 		return 0;
327 	}
328 	sunxi_ehci = dev->platform_data;
329 
330 	if ((val >= 0) && (val <= 0x3)) {
331 		usb_phyx_tp_write(sunxi_ehci, 0x2a, val, 2);
332 	} else {
333 		DMSG_PANIC("adjust disconnect threshold 0x%x is fail, value:0x0~0x3\n", val);
334 		return count;
335 	}
336 
337 	DMSG_INFO("adjust succeed: threshold val:0x%x, no:%x\n",
338 			usb_phyx_tp_read(sunxi_ehci, 0x2a, 2),
339 			sunxi_ehci->usbc_no);
340 
341 	return count;
342 }
343 
344 static DEVICE_ATTR(phy_threshold, 0644, show_phy_threshold, ehci_phy_threshold);
345 
show_phy_range(struct device * dev,struct device_attribute * attr,char * buf)346 static ssize_t show_phy_range(struct device *dev,
347 		struct device_attribute *attr, char *buf)
348 {
349 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
350 
351 	sunxi_ehci = dev->platform_data;
352 #if defined(CONFIG_ARCH_SUN8IW17) | defined(CONFIG_ARCH_SUN8IW11)
353 	DMSG_INFO("PHY's rate and range:0x0~0x1f\n");
354 	return sprintf(buf, "rate:0x%x\n",
355 		usb_phyx_tp_read(sunxi_ehci, 0x20, 5));
356 #else
357 	DMSG_INFO("PHY's rate and range:0x0~0x3ff\n");
358 	return sprintf(buf, "rate:0x%x\n",
359 		usb_phyx_read(sunxi_ehci));
360 #endif
361 }
362 
ehci_phy_range(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)363 static ssize_t ehci_phy_range(struct device *dev, struct device_attribute *attr,
364 		const char *buf, size_t count)
365 {
366 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
367 	int val = 0;
368 	int err;
369 
370 	if (dev == NULL) {
371 		DMSG_PANIC("ERR: Argment is invalid\n");
372 		return 0;
373 	}
374 
375 	err = kstrtoint(buf, 16, &val);
376 	if (err != 0)
377 		return -EINVAL;
378 
379 	sunxi_ehci = dev->platform_data;
380 
381 
382 #if defined(CONFIG_ARCH_SUN8IW17) || defined(CONFIG_ARCH_SUN8IW11)
383 	DMSG_INFO("adjust PHY's rate and range:0x0~0x1f\n");
384 	if ((val >= 0) && (val <= 0x1f)) {
385 		usb_phyx_tp_write(sunxi_ehci, 0x20, val, 5);
386 	} else {
387 		DMSG_PANIC("adjust PHY's rate and range 0x%x is fail, value:0x0~0x1f\n", val);
388 		return count;
389 	}
390 
391 	DMSG_INFO("adjust succeed:,rate val:0x%x, no:%d\n",
392 			usb_phyx_tp_read(sunxi_ehci, 0x20, 5),
393 			sunxi_ehci->usbc_no);
394 #else
395 	DMSG_INFO("adjust PHY's rate and range:0x0~0x3ff\n");
396 	if ((val >= 0x0) && (val <= 0x3ff)) {
397 		usb_phyx_write(sunxi_ehci, val);
398 	} else {
399 		DMSG_PANIC("adjust PHY's paraments 0x%x is fail! value:0x0~0x3ff\n", val);
400 		return count;
401 	}
402 
403 	DMSG_INFO("adjust succeed:,PHY's paraments :0x%x, no:%d\n",
404 		usb_phyx_read(sunxi_ehci), sunxi_ehci->usbc_no);
405 #endif
406 
407 	return count;
408 }
409 
410 static DEVICE_ATTR(phy_range, 0644, show_phy_range, ehci_phy_range);
411 
ehci_enable_show(struct device * dev,struct device_attribute * attr,char * buf)412 static ssize_t ehci_enable_show(struct device *dev,
413 		struct device_attribute *attr, char *buf)
414 {
415 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
416 
417 	if (dev == NULL) {
418 		DMSG_PANIC("ERR: Argment is invalid\n");
419 		return 0;
420 	}
421 
422 	sunxi_ehci = dev->platform_data;
423 	if (sunxi_ehci == NULL) {
424 		DMSG_PANIC("ERR: sw_ehci is null\n");
425 		return 0;
426 	}
427 
428 	return sprintf(buf, "ehci:%d, probe:%u\n",
429 			sunxi_ehci->usbc_no, sunxi_ehci->probe);
430 }
431 
ehci_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)432 static ssize_t ehci_enable_store(struct device *dev,
433 		struct device_attribute *attr, const char *buf, size_t count)
434 {
435 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
436 	int value = 0;
437 	int err;
438 
439 	if (dev == NULL) {
440 		DMSG_PANIC("ERR: Argment is invalid\n");
441 		return 0;
442 	}
443 
444 	sunxi_ehci = dev->platform_data;
445 	if (sunxi_ehci == NULL) {
446 		DMSG_PANIC("ERR: sw_ehci is null\n");
447 		return 0;
448 	}
449 
450 	ehci_first_probe[sunxi_ehci->usbc_no] = 0;
451 
452 	err = kstrtoint(buf, 10, &value);
453 	if (err != 0)
454 		return -EINVAL;
455 	if (value == 1) {
456 		ehci_enable[sunxi_ehci->usbc_no] = 0;
457 		sunxi_ehci->hsic_enable_flag = 1;
458 		sunxi_usb_enable_ehci(sunxi_ehci->usbc_no);
459 
460 		if (sunxi_ehci->usbc_no == HCI0_USBC_NO)
461 			sunxi_set_host_vbus(sunxi_ehci, 1);
462 
463 		if (sunxi_ehci->hsic_ctrl_flag)
464 			sunxi_set_host_hisc_rdy(sunxi_ehci, 1);
465 	} else if (value == 0) {
466 		if (sunxi_ehci->hsic_ctrl_flag)
467 			sunxi_set_host_hisc_rdy(sunxi_ehci, 0);
468 
469 		ehci_enable[sunxi_ehci->usbc_no] = 1;
470 		sunxi_usb_disable_ehci(sunxi_ehci->usbc_no);
471 		sunxi_ehci->hsic_enable_flag = 0;
472 		ehci_enable[sunxi_ehci->usbc_no] = 0;
473 	} else {
474 		DMSG_INFO("unknown value (%d)\n", value);
475 	}
476 
477 	return count;
478 }
479 
480 static DEVICE_ATTR(ehci_enable, 0664, ehci_enable_show, ehci_enable_store);
481 
sunxi_hcd_board_set_vbus(struct sunxi_hci_hcd * sunxi_ehci,int is_on)482 static void sunxi_hcd_board_set_vbus(
483 		struct sunxi_hci_hcd *sunxi_ehci, int is_on)
484 {
485 	sunxi_ehci->set_power(sunxi_ehci, is_on);
486 }
487 
sunxi_hcd_board_set_passby(struct sunxi_hci_hcd * sunxi_ehci,int is_on)488 static void sunxi_hcd_board_set_passby(struct sunxi_hci_hcd *sunxi_ehci,
489 						int is_on)
490 {
491 	sunxi_ehci->usb_passby(sunxi_ehci, is_on);
492 }
493 
open_ehci_clock(struct sunxi_hci_hcd * sunxi_ehci)494 static int open_ehci_clock(struct sunxi_hci_hcd *sunxi_ehci)
495 {
496 	return sunxi_ehci->open_clock(sunxi_ehci, 0);
497 }
498 
close_ehci_clock(struct sunxi_hci_hcd * sunxi_ehci)499 static int close_ehci_clock(struct sunxi_hci_hcd *sunxi_ehci)
500 {
501 	return sunxi_ehci->close_clock(sunxi_ehci, 0);
502 }
503 
sunxi_start_ehci(struct sunxi_hci_hcd * sunxi_ehci)504 static void sunxi_start_ehci(struct sunxi_hci_hcd *sunxi_ehci)
505 {
506 	open_ehci_clock(sunxi_ehci);
507 	sunxi_hcd_board_set_passby(sunxi_ehci, 1);
508 	sunxi_hcd_board_set_vbus(sunxi_ehci, 1);
509 }
510 
sunxi_stop_ehci(struct sunxi_hci_hcd * sunxi_ehci)511 static void sunxi_stop_ehci(struct sunxi_hci_hcd *sunxi_ehci)
512 {
513 	sunxi_hcd_board_set_vbus(sunxi_ehci, 0);
514 	sunxi_hcd_board_set_passby(sunxi_ehci, 0);
515 	close_ehci_clock(sunxi_ehci);
516 }
517 
sunxi_ehci_pm_notify(struct notifier_block * nb,unsigned long mode,void * _unused)518 static int sunxi_ehci_pm_notify(struct notifier_block *nb,
519 				unsigned long mode, void *_unused)
520 {
521 	switch (mode) {
522 	case PM_HIBERNATION_PREPARE:
523 	case PM_RESTORE_PREPARE:
524 	case PM_SUSPEND_PREPARE:
525 		atomic_set(&ehci_in_standby, 1);
526 		break;
527 	case PM_POST_HIBERNATION:
528 	case PM_POST_RESTORE:
529 	case PM_POST_SUSPEND:
530 		atomic_set(&ehci_in_standby, 0);
531 		sunxi_hci_standby_completion(SUNXI_USB_EHCI);
532 		break;
533 	default:
534 		break;
535 	}
536 
537 	return 0;
538 }
539 
540 static struct notifier_block sunxi_ehci_pm_nb = {
541 	.notifier_call = sunxi_ehci_pm_notify,
542 };
543 
544 static struct hc_driver sunxi_ehci_hc_driver;
545 
sunxi_insmod_ehci(struct platform_device * pdev)546 int sunxi_insmod_ehci(struct platform_device *pdev)
547 {
548 	struct usb_hcd *hcd	= NULL;
549 	struct ehci_hcd *ehci	= NULL;
550 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
551 	struct device *dev = NULL;
552 	int ret = 0;
553 
554 	sunxi_ehci = pdev->dev.platform_data;
555 	if (!sunxi_ehci) {
556 		DMSG_PANIC("ERR: sunxi_ehci is null\n");
557 		ret = -ENOMEM;
558 		goto ERR1;
559 	}
560 
561 	sunxi_ehci->pdev = pdev;
562 	g_sunxi_ehci[sunxi_ehci->usbc_no] = sunxi_ehci;
563 
564 	DMSG_INFO("[%s%d]: probe, pdev->name: %s, sunxi_ehci: 0x%px, 0x:%px, irq_no:%x\n",
565 		ehci_name, sunxi_ehci->usbc_no, pdev->name,
566 		sunxi_ehci, sunxi_ehci->usb_vbase, sunxi_ehci->irq_no);
567 
568 	/* get io resource */
569 	sunxi_ehci->ehci_base		= sunxi_ehci->usb_vbase;
570 	sunxi_ehci->ehci_reg_length	= SUNXI_USB_EHCI_LEN;
571 
572 	/* not init ehci, when driver probe */
573 	if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
574 		if (sunxi_ehci->port_type != USB_PORT_TYPE_HOST) {
575 			if (ehci_first_probe[sunxi_ehci->usbc_no]) {
576 				ehci_first_probe[sunxi_ehci->usbc_no] = 0;
577 				DMSG_INFO("[%s%d]: Not init ehci0\n",
578 					  ehci_name, sunxi_ehci->usbc_no);
579 				return 0;
580 			}
581 		}
582 	}
583 
584 	/* creat a usb_hcd for the ehci controller */
585 	hcd = usb_create_hcd(&sunxi_ehci_hc_driver, &pdev->dev, ehci_name);
586 	if (!hcd) {
587 		DMSG_PANIC("ERR: usb_create_hcd failed\n");
588 		ret = -ENOMEM;
589 		goto ERR2;
590 	}
591 
592 	hcd->rsrc_start = sunxi_ehci->usb_base_res->start;
593 	hcd->rsrc_len	= SUNXI_USB_EHCI_LEN;
594 	hcd->regs	= sunxi_ehci->ehci_base;
595 	sunxi_ehci->hcd = hcd;
596 
597 	dev = &pdev->dev;
598 	sunxi_ehci->supply = regulator_get(dev, "drvvbus");
599 
600 	if (IS_ERR(sunxi_ehci->supply)) {
601 		DMSG_PANIC("%s()%d WARN: get supply failed\n", __func__, __LINE__);
602 		sunxi_ehci->supply = NULL;
603 	}
604 
605 	sunxi_ehci->hci_regulator = regulator_get(dev, "hci");
606 	if (IS_ERR(sunxi_ehci->hci_regulator)) {
607 		DMSG_PANIC("%s()%d WARN: get hci regulator failed\n", __func__, __LINE__);
608 		sunxi_ehci->hci_regulator = NULL;
609 	}
610 	/* echi start to work */
611 	sunxi_start_ehci(sunxi_ehci);
612 
613 	ehci = hcd_to_ehci(hcd);
614 	ehci->caps = hcd->regs;
615 	ehci->regs = hcd->regs +
616 			HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase));
617 
618 	/* cache this readonly data, minimize chip reads */
619 	ehci->hcs_params = readl(&ehci->caps->hcs_params);
620 
621 	ret = usb_add_hcd(hcd, sunxi_ehci->irq_no, IRQF_SHARED);
622 	if (ret != 0) {
623 		DMSG_PANIC("ERR: usb_add_hcd failed\n");
624 		ret = -ENOMEM;
625 		goto ERR3;
626 	}
627 
628 	device_wakeup_enable(hcd->self.controller);
629 	platform_set_drvdata(pdev, hcd);
630 
631 	device_create_file(&pdev->dev, &dev_attr_ed_test);
632 	device_create_file(&pdev->dev, &dev_attr_phy_threshold);
633 	device_create_file(&pdev->dev, &dev_attr_phy_range);
634 
635 #ifndef USB_SYNC_SUSPEND
636 	device_enable_async_suspend(&pdev->dev);
637 #endif
638 
639 #if IS_ENABLED(CONFIG_PM)
640 	if (!sunxi_ehci->wakeup_suspend)
641 		INIT_WORK(&sunxi_ehci->resume_work, sunxi_ehci_resume_work);
642 #endif
643 
644 	sunxi_ehci->probe = 1;
645 
646 	return 0;
647 
648 ERR3:
649 	sunxi_stop_ehci(sunxi_ehci);
650 	usb_put_hcd(hcd);
651 
652 ERR2:
653 	sunxi_ehci->hcd = NULL;
654 	g_sunxi_ehci[sunxi_ehci->usbc_no] = NULL;
655 
656 ERR1:
657 
658 	return ret;
659 }
660 
sunxi_rmmod_ehci(struct platform_device * pdev)661 int sunxi_rmmod_ehci(struct platform_device *pdev)
662 {
663 
664 	struct usb_hcd *hcd = NULL;
665 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
666 	unsigned long time_left;
667 
668 	if (pdev == NULL) {
669 		DMSG_PANIC("ERR: Argment is invalid\n");
670 		return -1;
671 	}
672 
673 	hcd = platform_get_drvdata(pdev);
674 	if (hcd == NULL) {
675 		DMSG_PANIC("ERR: hcd is null\n");
676 		return -1;
677 	}
678 
679 	sunxi_ehci = pdev->dev.platform_data;
680 	if (sunxi_ehci == NULL) {
681 		DMSG_PANIC("ERR: sunxi_ehci is null\n");
682 		return -1;
683 	}
684 
685 	if (atomic_read(&ehci_in_standby)) {
686 		reinit_completion(&sunxi_ehci->standby_complete);
687 		DMSG_INFO("INFO: sunxi_ehci disable, waiting until standby finish\n");
688 		time_left = wait_for_completion_timeout(&sunxi_ehci->standby_complete,
689 						msecs_to_jiffies(STANDBY_TIMEOUT));
690 		if (time_left)
691 			DMSG_INFO("INFO: sunxi_ehci disable time_left = %lu\n", time_left);
692 		else
693 			DMSG_PANIC("ERR: sunxi_ehci waiting standby failed, go on disable\n");
694 
695 	}
696 
697 	sunxi_ehci->probe = 0;
698 
699 #ifndef USB_SYNC_SUSPEND
700 	device_disable_async_suspend(&pdev->dev);
701 #endif
702 
703 	DMSG_INFO("[%s%d]: remove, pdev->name: %s, sunxi_ehci: 0x%px\n",
704 		ehci_name, sunxi_ehci->usbc_no, pdev->name, sunxi_ehci);
705 
706 	device_remove_file(&pdev->dev, &dev_attr_ed_test);
707 	device_remove_file(&pdev->dev, &dev_attr_phy_threshold);
708 	device_remove_file(&pdev->dev, &dev_attr_phy_range);
709 
710 	device_wakeup_disable(hcd->self.controller);
711 
712 	usb_remove_hcd(hcd);
713 
714 #if IS_ENABLED(CONFIG_PM)
715 	if (!sunxi_ehci->wakeup_suspend)
716 		if (!IS_ERR_OR_NULL(&sunxi_ehci->resume_work))
717 			cancel_work_sync(&sunxi_ehci->resume_work);
718 #endif
719 
720 	sunxi_stop_ehci(sunxi_ehci);
721 
722 	usb_put_hcd(hcd);
723 
724 	if (sunxi_ehci->supply)
725 		regulator_put(sunxi_ehci->supply);
726 
727 	sunxi_ehci->hcd = NULL;
728 
729 	return 0;
730 }
731 
sunxi_ehci_hcd_probe(struct platform_device * pdev)732 static int sunxi_ehci_hcd_probe(struct platform_device *pdev)
733 {
734 	int ret = 0;
735 #if defined(CONFIG_ARCH_SUN50IW10)
736 	int val = 0;
737 #endif
738 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
739 	if (pdev == NULL) {
740 		DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
741 		return -1;
742 	}
743 
744 	/* if usb is disabled, can not probe */
745 	if (usb_disabled()) {
746 		DMSG_PANIC("ERR: usb hcd is disabled\n");
747 		return -ENODEV;
748 	}
749 
750 	ret = init_sunxi_hci(pdev, SUNXI_USB_EHCI);
751 	if (ret != 0) {
752 		dev_err(&pdev->dev, "init_sunxi_hci is fail\n");
753 		return -1;
754 	}
755 
756 	sunxi_insmod_ehci(pdev);
757 
758 	sunxi_ehci = pdev->dev.platform_data;
759 	if (sunxi_ehci == NULL) {
760 		DMSG_PANIC("ERR: %s, sunxi_ehci is null\n", __func__);
761 		return -1;
762 	}
763 
764 	if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
765 		ret = register_pm_notifier(&sunxi_ehci_pm_nb);
766 		if (ret) {
767 			DMSG_PANIC("ERR: %s, can not register suspend notifier\n", __func__);
768 			return -1;
769 		}
770 	}
771 
772 	init_completion(&sunxi_ehci->standby_complete);
773 
774 /* keep common circuit configuration when usb0 enable only*/
775 #if defined(CONFIG_ARCH_SUN50IW10)
776 	if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
777 		val = readl(sunxi_ehci->usb_ccmu_config + 0x0A8C);
778 		val |= (SUNXI_CCMU_USBEHCI1_GATING_OFFSET
779 			| SUNXI_CCMU_USBEHCI1_RST_OFFSET);
780 		writel(val, sunxi_ehci->usb_ccmu_config + 0x0A8C);
781 
782 		val = readl(sunxi_ehci->usb_ccmu_config + 0x0A74);
783 		val |= (SUNXI_CCMU_SCLK_GATING_USBPHY1_OFFSET
784 			| SUNXI_CCMU_USBPHY1_RST_OFFSET
785 			| SUNXI_CCMU_SCLK_GATING_OHCI1_OFFSET);
786 		writel(val, sunxi_ehci->usb_ccmu_config + 0x0A74);
787 
788 		/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
789 		val = USBC_Readl(sunxi_ehci->usb_common_phy_config
790 				 + SUNXI_HCI_PHY_CTRL);
791 		val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
792 		USBC_Writel(val, sunxi_ehci->usb_common_phy_config
793 			    + SUNXI_HCI_PHY_CTRL);
794 	}
795 #endif
796 
797 	if (ehci_enable[sunxi_ehci->usbc_no]) {
798 		device_create_file(&pdev->dev, &dev_attr_ehci_enable);
799 		ehci_enable[sunxi_ehci->usbc_no] = 0;
800 	}
801 
802 	return 0;
803 }
804 
sunxi_ehci_hcd_remove(struct platform_device * pdev)805 static int sunxi_ehci_hcd_remove(struct platform_device *pdev)
806 {
807 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
808 	int ret = 0;
809 #if defined(CONFIG_ARCH_SUN50IW10)
810 	int val = 0;
811 #endif
812 
813 	if (pdev == NULL) {
814 		DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
815 		return -1;
816 	}
817 
818 	sunxi_ehci = pdev->dev.platform_data;
819 	if (sunxi_ehci == NULL) {
820 		DMSG_PANIC("ERR: %s, sunxi_ehci is null\n", __func__);
821 		return -1;
822 	}
823 
824 	if (ehci_enable[sunxi_ehci->usbc_no] == 0) {
825 		device_remove_file(&pdev->dev, &dev_attr_ehci_enable);
826 		ehci_enable[sunxi_ehci->usbc_no] = 1;
827 	}
828 
829 /* reset common circuit configuration*/
830 #if defined(CONFIG_ARCH_SUN50IW10)
831 	if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
832 		val = readl(sunxi_ehci->usb_ccmu_config + 0x0A8C);
833 		val &= ~(SUNXI_CCMU_USBEHCI1_GATING_OFFSET
834 			 | SUNXI_CCMU_USBEHCI1_RST_OFFSET);
835 		writel(val, sunxi_ehci->usb_ccmu_config + 0x0A8C);
836 
837 		val = readl(sunxi_ehci->usb_ccmu_config + 0x0A74);
838 		val &= ~(SUNXI_CCMU_SCLK_GATING_USBPHY1_OFFSET
839 			| SUNXI_CCMU_USBPHY1_RST_OFFSET
840 			| SUNXI_CCMU_SCLK_GATING_OHCI1_OFFSET);
841 		writel(val, sunxi_ehci->usb_ccmu_config + 0x0A74);
842 
843 		/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
844 		val = USBC_Readl(sunxi_ehci->usb_common_phy_config
845 				 + SUNXI_HCI_PHY_CTRL);
846 		val |= (0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
847 		USBC_Writel(val, sunxi_ehci->usb_common_phy_config
848 			    + SUNXI_HCI_PHY_CTRL);
849 	}
850 #endif
851 
852 	if (sunxi_ehci->usbc_no == HCI0_USBC_NO)
853 		unregister_pm_notifier(&sunxi_ehci_pm_nb);
854 
855 	if (sunxi_ehci->probe == 1) {
856 		ret = sunxi_rmmod_ehci(pdev);
857 		if (ret == 0)
858 			exit_sunxi_hci(sunxi_ehci);
859 
860 		return ret;
861 	} else
862 		return 0;
863 
864 }
865 
sunxi_ehci_hcd_shutdown(struct platform_device * pdev)866 static void sunxi_ehci_hcd_shutdown(struct platform_device *pdev)
867 {
868 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
869 
870 	if (pdev == NULL) {
871 		DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
872 		return;
873 	}
874 
875 	sunxi_ehci = pdev->dev.platform_data;
876 	if (sunxi_ehci == NULL) {
877 		DMSG_PANIC("ERR: %s, is null\n", __func__);
878 		return;
879 	}
880 
881 	if (sunxi_ehci->probe == 0) {
882 		DMSG_INFO("%s, %s is disable, need not shutdown\n",
883 			 __func__, sunxi_ehci->hci_name);
884 		return;
885 	}
886 
887 	DMSG_INFO("[%s]: ehci shutdown start\n", sunxi_ehci->hci_name);
888 	usb_hcd_platform_shutdown(pdev);
889 
890 	/**
891 	 * disable usb otg INTUSBE, to solve usb0 device mode
892 	 * catch audio udev on reboot system is fail.
893 	 */
894 	if (sunxi_ehci->usbc_no == 0) {
895 		if (sunxi_ehci->otg_vbase) {
896 			writel(0, (sunxi_ehci->otg_vbase
897 						+ SUNXI_USBC_REG_INTUSBE));
898 		}
899 	}
900 	sunxi_hcd_board_set_vbus(sunxi_ehci, 0);
901 	DMSG_INFO("[%s]: ehci shutdown end\n", sunxi_ehci->hci_name);
902 }
903 
904 #if IS_ENABLED(CONFIG_PM)
905 
sunxi_ehci_hcd_suspend(struct device * dev)906 static int sunxi_ehci_hcd_suspend(struct device *dev)
907 {
908 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
909 	struct usb_hcd *hcd = NULL;
910 	struct ehci_hcd *ehci = NULL;
911 	int val = 0;
912 
913 	if (dev == NULL) {
914 		DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
915 		return 0;
916 	}
917 
918 	hcd = dev_get_drvdata(dev);
919 	if (hcd == NULL) {
920 		DMSG_PANIC("ERR: hcd is null\n");
921 		return 0;
922 	}
923 
924 	sunxi_ehci = dev->platform_data;
925 	if (sunxi_ehci == NULL) {
926 		DMSG_PANIC("ERR: sunxi_ehci is null\n");
927 		return 0;
928 	}
929 
930 	if (sunxi_ehci->no_suspend) {
931 		DMSG_INFO("[%s]:ehci is being enable, stop system suspend\n",
932 			sunxi_ehci->hci_name);
933 		return -1;
934 	}
935 
936 	if (sunxi_ehci->probe == 0) {
937 		DMSG_INFO("[%s]: is disable, can not suspend\n",
938 			sunxi_ehci->hci_name);
939 		return 0;
940 	}
941 
942 	ehci = hcd_to_ehci(hcd);
943 	if (ehci == NULL) {
944 		DMSG_PANIC("ERR: ehci is null\n");
945 		return 0;
946 	}
947 
948 	if (sunxi_ehci->wakeup_suspend == USB_STANDBY) {
949 		DMSG_INFO("[%s] usb suspend\n", sunxi_ehci->hci_name);
950 		disable_irq(sunxi_ehci->irq_no);
951 		/*phy reg, offset:0x18 bit0 bit1 bit2, set 1*/
952 		val = ehci_readl(ehci, &ehci->regs->intr_enable);
953 		val |= (0x7 << 0);
954 		ehci_writel(ehci, val, &ehci->regs->intr_enable);
955 
956 #if IS_ENABLED(SUNXI_USB_STANDBY_LOW_POW_MODE)
957 		/*phy reg, offset:0x10 bit4 bit5, set 0*/
958 		val = ehci_readl(ehci, &ehci->regs->command);
959 		val &= ~(0x30);
960 		ehci_writel(ehci, val, &ehci->regs->command);
961 		/*enable standby irq*/
962 #endif
963 		enter_usb_standby(sunxi_ehci);
964 
965 	} else {
966 		DMSG_INFO("[%s]super suspend\n", sunxi_ehci->hci_name);
967 
968 		ehci_suspend(hcd, device_may_wakeup(dev));
969 		cancel_work_sync(&sunxi_ehci->resume_work);
970 		sunxi_stop_ehci(sunxi_ehci);
971 	}
972 
973 	return 0;
974 }
975 
sunxi_ehci_resume_work(struct work_struct * work)976 static void sunxi_ehci_resume_work(struct work_struct *work)
977 {
978 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
979 
980 	sunxi_ehci = container_of(work, struct sunxi_hci_hcd, resume_work);
981 
982 	sunxi_hcd_board_set_vbus(sunxi_ehci, 1);
983 }
984 
sunxi_ehci_hcd_resume(struct device * dev)985 static int sunxi_ehci_hcd_resume(struct device *dev)
986 {
987 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
988 	struct usb_hcd *hcd = NULL;
989 	struct ehci_hcd *ehci = NULL;
990 	int __maybe_unused val = 0;
991 
992 	if (dev == NULL) {
993 		DMSG_PANIC("ERR: Argment is invalid\n");
994 		return 0;
995 	}
996 
997 	hcd = dev_get_drvdata(dev);
998 	if (hcd == NULL) {
999 		DMSG_PANIC("ERR: hcd is null\n");
1000 		return 0;
1001 	}
1002 
1003 	sunxi_ehci = dev->platform_data;
1004 	if (sunxi_ehci == NULL) {
1005 		DMSG_PANIC("ERR: sunxi_ehci is null\n");
1006 		return 0;
1007 	}
1008 
1009 	if (sunxi_ehci->probe == 0) {
1010 		DMSG_INFO("[%s]: is disable, can not resume\n",
1011 			sunxi_ehci->hci_name);
1012 		return 0;
1013 	}
1014 
1015 	ehci = hcd_to_ehci(hcd);
1016 	if (ehci == NULL) {
1017 		DMSG_PANIC("ERR: ehci is null\n");
1018 		return 0;
1019 	}
1020 
1021 	if (sunxi_ehci->wakeup_suspend == USB_STANDBY) {
1022 		DMSG_INFO("[%s]usb resume\n", sunxi_ehci->hci_name);
1023 
1024 		exit_usb_standby(sunxi_ehci);
1025 #if IS_ENABLED(SUNXI_USB_STANDBY_LOW_POW_MODE)
1026 		val = ehci_readl(ehci, &ehci->regs->command);
1027 		val |= 0x30;
1028 		ehci_writel(ehci, val, &ehci->regs->command);
1029 
1030 #endif
1031 		enable_irq(sunxi_ehci->irq_no);
1032 	} else {
1033 		DMSG_INFO("[%s]super resume\n", sunxi_ehci->hci_name);
1034 
1035 		open_ehci_clock(sunxi_ehci);
1036 		sunxi_hcd_board_set_passby(sunxi_ehci, 1);
1037 		ehci_resume(hcd, false);
1038 
1039 #if defined(CONFIG_ARCH_SUN50IW10)
1040 		if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
1041 			/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
1042 			val = USBC_Readl(sunxi_ehci->usb_common_phy_config
1043 					 + SUNXI_HCI_PHY_CTRL);
1044 			val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
1045 			USBC_Writel(val, sunxi_ehci->usb_common_phy_config
1046 				    + SUNXI_HCI_PHY_CTRL);
1047 		}
1048 #endif
1049 
1050 		schedule_work(&sunxi_ehci->resume_work);
1051 	}
1052 
1053 	return 0;
1054 }
1055 
1056 static const struct dev_pm_ops  aw_ehci_pmops = {
1057 	.suspend	= sunxi_ehci_hcd_suspend,
1058 	.resume		= sunxi_ehci_hcd_resume,
1059 };
1060 
1061 #define SUNXI_EHCI_PMOPS	(&aw_ehci_pmops)
1062 
1063 #else
1064 
1065 #define SUNXI_EHCI_PMOPS	NULL
1066 
1067 #endif
1068 
1069 
1070 static const struct of_device_id sunxi_ehci_match[] = {
1071 	{.compatible = SUNXI_EHCI0_OF_MATCH, },
1072 	{.compatible = SUNXI_EHCI1_OF_MATCH, },
1073 	{.compatible = SUNXI_EHCI2_OF_MATCH, },
1074 	{.compatible = SUNXI_EHCI3_OF_MATCH, },
1075 	{},
1076 };
1077 MODULE_DEVICE_TABLE(of, sunxi_ehci_match);
1078 
1079 static struct platform_driver sunxi_ehci_hcd_driver = {
1080 	.probe  = sunxi_ehci_hcd_probe,
1081 	.remove	= sunxi_ehci_hcd_remove,
1082 	.shutdown = sunxi_ehci_hcd_shutdown,
1083 	.driver = {
1084 			.name	= ehci_name,
1085 			.pm	= SUNXI_EHCI_PMOPS,
1086 			.of_match_table = sunxi_ehci_match,
1087 		}
1088 };
1089 
sunxi_usb_disable_ehci(__u32 usbc_no)1090 int sunxi_usb_disable_ehci(__u32 usbc_no)
1091 {
1092 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
1093 
1094 	sunxi_ehci = g_sunxi_ehci[usbc_no];
1095 	if (sunxi_ehci == NULL) {
1096 		DMSG_PANIC("ERR: sunxi_ehci is null\n");
1097 		return -1;
1098 	}
1099 
1100 	if (sunxi_ehci->probe == 0) {
1101 		DMSG_PANIC("ERR: sunxi_ehci is disable, can not disable again\n");
1102 		return -1;
1103 	}
1104 
1105 	sunxi_ehci->probe = 0;
1106 
1107 	DMSG_INFO("[%s]: sunxi_usb_disable_ehci\n", sunxi_ehci->hci_name);
1108 
1109 	sunxi_rmmod_ehci(sunxi_ehci->pdev);
1110 
1111 	return 0;
1112 }
1113 EXPORT_SYMBOL(sunxi_usb_disable_ehci);
1114 
sunxi_usb_enable_ehci(__u32 usbc_no)1115 int sunxi_usb_enable_ehci(__u32 usbc_no)
1116 {
1117 	struct sunxi_hci_hcd *sunxi_ehci = NULL;
1118 #if defined(CONFIG_ARCH_SUN50IW10)
1119 	int val;
1120 #endif
1121 
1122 	sunxi_ehci = g_sunxi_ehci[usbc_no];
1123 	if (sunxi_ehci == NULL) {
1124 		DMSG_PANIC("ERR: sunxi_ehci is null\n");
1125 		return -1;
1126 	}
1127 
1128 	if (sunxi_ehci->probe == 1) {
1129 		DMSG_PANIC("ERR: sunxi_ehci is already enable, can not enable again\n");
1130 		return -1;
1131 	}
1132 
1133 	sunxi_ehci->no_suspend = 1;
1134 
1135 	DMSG_INFO("[%s]: sunxi_usb_enable_ehci\n", sunxi_ehci->hci_name);
1136 
1137 #if defined(CONFIG_ARCH_SUN50IW10)
1138 		if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
1139 			/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
1140 			val = USBC_Readl(sunxi_ehci->usb_common_phy_config
1141 					 + SUNXI_HCI_PHY_CTRL);
1142 			val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
1143 			USBC_Writel(val, sunxi_ehci->usb_common_phy_config
1144 				    + SUNXI_HCI_PHY_CTRL);
1145 		}
1146 #endif
1147 
1148 	sunxi_insmod_ehci(sunxi_ehci->pdev);
1149 
1150 	sunxi_ehci->no_suspend = 0;
1151 
1152 	return 0;
1153 }
1154 EXPORT_SYMBOL(sunxi_usb_enable_ehci);
1155 
sunxi_ehci_hcd_init(void)1156 static int __init sunxi_ehci_hcd_init(void)
1157 {
1158 	if (usb_disabled()) {
1159 		DMSG_ERR(KERN_ERR "%s nousb\n", ehci_name);
1160 		return -ENODEV;
1161 	}
1162 
1163 	DMSG_INFO(KERN_INFO "%s: " DRIVER_DESC "\n", ehci_name);
1164 	ehci_init_driver(&sunxi_ehci_hc_driver, NULL);
1165 	return platform_driver_register(&sunxi_ehci_hcd_driver);
1166 }
1167 module_init(sunxi_ehci_hcd_init);
1168 
sunxi_ehci_hcd_cleanup(void)1169 static void __exit sunxi_ehci_hcd_cleanup(void)
1170 {
1171 	platform_driver_unregister(&sunxi_ehci_hcd_driver);
1172 }
1173 module_exit(sunxi_ehci_hcd_cleanup);
1174 
1175 MODULE_DESCRIPTION(DRIVER_DESC);
1176 MODULE_LICENSE("GPL v2");
1177 MODULE_ALIAS("platform:" SUNXI_EHCI_NAME);
1178 MODULE_AUTHOR("javen");
1179 MODULE_VERSION("1.0.9");
1180