• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/usb/host/ohci-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  * OHCI 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/signal.h>
20 #include <linux/time.h>
21 #include <linux/timer.h>
22 #include <linux/clk.h>
23 #include <linux/notifier.h>
24 #include <linux/suspend.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/phy/phy.h>
28 #include <linux/usb.h>
29 #include <linux/usb/hcd.h>
30 #include "ohci.h"
31 #include "sunxi-hci.h"
32 
33 #define DRIVER_DESC "OHCI SUNXI driver"
34 
35 #define   SUNXI_OHCI_NAME	"sunxi-ohci"
36 static const char ohci_name[] = SUNXI_OHCI_NAME;
37 
38 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI0)
39 #define  SUNXI_OHCI0_OF_MATCH	"allwinner,sunxi-ohci0"
40 #else
41 #define  SUNXI_OHCI0_OF_MATCH	"null"
42 #endif
43 
44 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI1)
45 #define  SUNXI_OHCI1_OF_MATCH	"allwinner,sunxi-ohci1"
46 #else
47 #define  SUNXI_OHCI1_OF_MATCH	"null"
48 #endif
49 
50 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI2)
51 #define  SUNXI_OHCI2_OF_MATCH	"allwinner,sunxi-ohci2"
52 #else
53 #define  SUNXI_OHCI2_OF_MATCH	"null"
54 #endif
55 
56 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI3)
57 #define  SUNXI_OHCI3_OF_MATCH	"allwinner,sunxi-ohci3"
58 #else
59 #define  SUNXI_OHCI3_OF_MATCH	"null"
60 #endif
61 
62 static struct sunxi_hci_hcd *g_sunxi_ohci[4];
63 static u32 ohci_first_probe[4] = {1, 1, 1, 1};
64 static u32 ohci_enable[4] = {1, 1, 1, 1};
65 static atomic_t ohci_in_standby;
66 
67 #if IS_ENABLED(CONFIG_PM)
68 static void sunxi_ohci_resume_work(struct work_struct *work);
69 #endif
70 
71 int sunxi_usb_disable_ohci(__u32 usbc_no);
72 int sunxi_usb_enable_ohci(__u32 usbc_no);
73 
ohci_enable_show(struct device * dev,struct device_attribute * attr,char * buf)74 static ssize_t ohci_enable_show(struct device *dev,
75 		struct device_attribute *attr, char *buf)
76 {
77 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
78 
79 	if (dev == NULL) {
80 		DMSG_PANIC("ERR: Argment is invalid\n");
81 		return 0;
82 	}
83 
84 	sunxi_ohci = dev->platform_data;
85 	if (sunxi_ohci == NULL) {
86 		DMSG_PANIC("ERR: sw_ohci is null\n");
87 		return 0;
88 	}
89 
90 	return sprintf(buf, "ohci:%d,probe:%u\n",
91 			sunxi_ohci->usbc_no, sunxi_ohci->probe);
92 }
93 
ohci_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)94 static ssize_t ohci_enable_store(struct device *dev,
95 		struct device_attribute *attr,
96 		const char *buf, size_t count)
97 {
98 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
99 	int value = 0;
100 	int err;
101 
102 	if (dev == NULL) {
103 		DMSG_PANIC("ERR: Argment is invalid\n");
104 		return 0;
105 	}
106 
107 	sunxi_ohci = dev->platform_data;
108 	if (sunxi_ohci == NULL) {
109 		DMSG_PANIC("ERR: sw_ohci is null\n");
110 		return 0;
111 	}
112 
113 	ohci_first_probe[sunxi_ohci->usbc_no] = 0;
114 
115 	err = kstrtoint(buf, 10, &value);
116 	if (err != 0)
117 		return -EINVAL;
118 	if (value == 1) {
119 		ohci_enable[sunxi_ohci->usbc_no] = 0;
120 		sunxi_usb_enable_ohci(sunxi_ohci->usbc_no);
121 
122 		if (sunxi_ohci->usbc_no == HCI0_USBC_NO)
123 			sunxi_set_host_vbus(sunxi_ohci, 1);
124 
125 	} else if (value == 0) {
126 		ohci_enable[sunxi_ohci->usbc_no] = 1;
127 		sunxi_usb_disable_ohci(sunxi_ohci->usbc_no);
128 		ohci_enable[sunxi_ohci->usbc_no] = 0;
129 	} else {
130 		DMSG_INFO("unknown value (%d)\n", value);
131 	}
132 
133 	return count;
134 }
135 
136 static DEVICE_ATTR(ohci_enable, 0644, ohci_enable_show, ohci_enable_store);
137 
open_ohci_clock(struct sunxi_hci_hcd * sunxi_ohci)138 static int open_ohci_clock(struct sunxi_hci_hcd *sunxi_ohci)
139 {
140 	return sunxi_ohci->open_clock(sunxi_ohci, 1);
141 }
142 
close_ohci_clock(struct sunxi_hci_hcd * sunxi_ohci)143 static int close_ohci_clock(struct sunxi_hci_hcd *sunxi_ohci)
144 {
145 	return sunxi_ohci->close_clock(sunxi_ohci, 1);
146 }
147 
sunxi_ohci_set_vbus(struct sunxi_hci_hcd * sunxi_ohci,int is_on)148 static void sunxi_ohci_set_vbus(struct sunxi_hci_hcd *sunxi_ohci, int is_on)
149 {
150 	sunxi_ohci->set_power(sunxi_ohci, is_on);
151 }
152 
sunxi_ohci_set_passby(struct sunxi_hci_hcd * sunxi_ohci,int is_on)153 static void sunxi_ohci_set_passby(struct sunxi_hci_hcd *sunxi_ohci, int is_on)
154 {
155 	sunxi_ohci->usb_passby(sunxi_ohci, is_on);
156 }
157 
sunxi_start_ohci(struct sunxi_hci_hcd * sunxi_ohci)158 static void sunxi_start_ohci(struct sunxi_hci_hcd *sunxi_ohci)
159 {
160 	open_ohci_clock(sunxi_ohci);
161 	sunxi_ohci_set_passby(sunxi_ohci, 1);
162 	sunxi_ohci_set_vbus(sunxi_ohci, 1);
163 }
164 
sunxi_stop_ohci(struct sunxi_hci_hcd * sunxi_ohci)165 static void sunxi_stop_ohci(struct sunxi_hci_hcd *sunxi_ohci)
166 {
167 	sunxi_ohci_set_vbus(sunxi_ohci, 0);
168 	sunxi_ohci_set_passby(sunxi_ohci, 0);
169 	close_ohci_clock(sunxi_ohci);
170 }
171 
sunxi_ohci_pm_notify(struct notifier_block * nb,unsigned long mode,void * _unused)172 static int sunxi_ohci_pm_notify(struct notifier_block *nb,
173 				unsigned long mode, void *_unused)
174 {
175 	switch (mode) {
176 	case PM_HIBERNATION_PREPARE:
177 	case PM_RESTORE_PREPARE:
178 	case PM_SUSPEND_PREPARE:
179 		atomic_set(&ohci_in_standby, 1);
180 		break;
181 	case PM_POST_HIBERNATION:
182 	case PM_POST_RESTORE:
183 	case PM_POST_SUSPEND:
184 		atomic_set(&ohci_in_standby, 0);
185 		sunxi_hci_standby_completion(SUNXI_USB_OHCI);
186 		break;
187 	default:
188 		break;
189 	}
190 
191 	return 0;
192 }
193 
194 static struct notifier_block sunxi_ohci_pm_nb = {
195 	.notifier_call = sunxi_ohci_pm_notify,
196 };
197 
198 static struct hc_driver sunxi_ohci_hc_driver;
199 
sunxi_insmod_ohci(struct platform_device * pdev)200 static int sunxi_insmod_ohci(struct platform_device *pdev)
201 {
202 	int ret;
203 	struct usb_hcd *hcd = NULL;
204 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
205 	struct device *dev = NULL;
206 
207 	if (pdev == NULL) {
208 		DMSG_PANIC("ERR: Argment is invaild\n");
209 		return -1;
210 	}
211 
212 	/* if usb is disabled, can not probe */
213 	if (usb_disabled()) {
214 		DMSG_PANIC("ERR: usb hcd is disabled\n");
215 		return -ENODEV;
216 	}
217 
218 	sunxi_ohci = pdev->dev.platform_data;
219 	if (!sunxi_ohci) {
220 		DMSG_PANIC("ERR: sunxi_ohci is null\n");
221 		ret = -ENOMEM;
222 		goto ERR1;
223 	}
224 
225 	sunxi_ohci->pdev = pdev;
226 	g_sunxi_ohci[sunxi_ohci->usbc_no] = sunxi_ohci;
227 
228 	DMSG_INFO("[%s%d]: probe, pdev->name: %s, sunxi_ohci: 0x%px\n",
229 		ohci_name, sunxi_ohci->usbc_no, pdev->name, sunxi_ohci);
230 
231 	sunxi_ohci->ohci_base = sunxi_ohci->usb_vbase +
232 					SUNXI_USB_OHCI_BASE_OFFSET;
233 
234 	sunxi_ohci->ohci_reg_length = SUNXI_USB_OHCI_LEN;
235 
236 	/* not init ohci, when driver probe */
237 	if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
238 		if (sunxi_ohci->port_type != USB_PORT_TYPE_HOST) {
239 			if (ohci_first_probe[sunxi_ohci->usbc_no]) {
240 				ohci_first_probe[sunxi_ohci->usbc_no] = 0;
241 				DMSG_INFO("[%s%d]: Not init ohci0\n",
242 					  ohci_name, sunxi_ohci->usbc_no);
243 				return 0;
244 			}
245 		}
246 	}
247 
248 	/* creat a usb_hcd for the ohci controller */
249 	hcd = usb_create_hcd(&sunxi_ohci_hc_driver, &pdev->dev, ohci_name);
250 	if (!hcd) {
251 		DMSG_PANIC("ERR: usb_ohci_create_hcd failed\n");
252 		ret = -ENOMEM;
253 		goto ERR2;
254 	}
255 
256 	hcd->rsrc_start = sunxi_ohci->usb_base_res->start;
257 	hcd->rsrc_len	= SUNXI_USB_OHCI_LEN;
258 	hcd->regs	= sunxi_ohci->ohci_base;
259 	sunxi_ohci->hcd	= hcd;
260 
261 	dev = &pdev->dev;
262 	sunxi_ohci->supply = regulator_get(dev, "drvvbus");
263 
264 	if (IS_ERR(sunxi_ohci->supply)) {
265 		DMSG_PANIC("%s()%d WARN: get supply failed\n", __func__, __LINE__);
266 		sunxi_ohci->supply = NULL;
267 	}
268 
269 	sunxi_ohci->hci_regulator = regulator_get(dev, "hci");
270 	if (IS_ERR(sunxi_ohci->hci_regulator)) {
271 		DMSG_PANIC("%s()%d WARN: get hci regulator failed\n", __func__, __LINE__);
272 		sunxi_ohci->hci_regulator = NULL;
273 	}
274 	/* ochi start to work */
275 	sunxi_start_ohci(sunxi_ohci);
276 
277 	ret = usb_add_hcd(hcd, sunxi_ohci->irq_no, IRQF_SHARED);
278 	if (ret != 0) {
279 		DMSG_PANIC("ERR: usb_add_hcd failed\n");
280 		ret = -ENOMEM;
281 		goto ERR3;
282 	}
283 
284 	device_wakeup_enable(hcd->self.controller);
285 	platform_set_drvdata(pdev, hcd);
286 
287 #ifndef USB_SYNC_SUSPEND
288 	device_enable_async_suspend(&pdev->dev);
289 #endif
290 
291 #if IS_ENABLED(CONFIG_PM)
292 	if (!sunxi_ohci->wakeup_suspend)
293 		INIT_WORK(&sunxi_ohci->resume_work, sunxi_ohci_resume_work);
294 #endif
295 
296 	sunxi_ohci->probe = 1;
297 
298 	return 0;
299 
300 ERR3:
301 	sunxi_stop_ohci(sunxi_ohci);
302 	usb_put_hcd(hcd);
303 
304 ERR2:
305 	sunxi_ohci->hcd = NULL;
306 
307 ERR1:
308 	return ret;
309 }
310 
sunxi_rmmod_ohci(struct platform_device * pdev)311 static int sunxi_rmmod_ohci(struct platform_device *pdev)
312 {
313 	struct usb_hcd *hcd = NULL;
314 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
315 	unsigned long time_left;
316 
317 	if (pdev == NULL) {
318 		DMSG_PANIC("ERR: Argment is invalid\n");
319 		return -1;
320 	}
321 
322 	hcd = platform_get_drvdata(pdev);
323 	if (hcd == NULL) {
324 		DMSG_PANIC("ERR: hcd is null\n");
325 		return -1;
326 	}
327 
328 	sunxi_ohci = pdev->dev.platform_data;
329 	if (sunxi_ohci == NULL) {
330 		DMSG_PANIC("ERR: sunxi_ohci is null\n");
331 		return -1;
332 	}
333 
334 	if (atomic_read(&ohci_in_standby)) {
335 		reinit_completion(&sunxi_ohci->standby_complete);
336 		DMSG_INFO("INFO: sunxi_ohci disable, waiting until standby finish\n");
337 		time_left = wait_for_completion_timeout(&sunxi_ohci->standby_complete,
338 						msecs_to_jiffies(STANDBY_TIMEOUT));
339 		if (time_left)
340 			DMSG_INFO("INFO: sunxi_ohci disable time_left = %lu\n", time_left);
341 		else
342 			DMSG_PANIC("ERR: sunxi_ohci waiting standby failed, go on disable\n");
343 
344 	}
345 
346 	sunxi_ohci->probe = 0;
347 
348 #ifndef USB_SYNC_SUSPEND
349 	device_disable_async_suspend(&pdev->dev);
350 #endif
351 
352 	device_wakeup_disable(hcd->self.controller);
353 
354 	DMSG_INFO("[%s%d]: remove, pdev->name: %s, sunxi_ohci: 0x%px\n",
355 		ohci_name, sunxi_ohci->usbc_no, pdev->name, sunxi_ohci);
356 	usb_remove_hcd(hcd);
357 
358 #if IS_ENABLED(CONFIG_PM)
359 	if (!sunxi_ohci->wakeup_suspend)
360 		if (!IS_ERR_OR_NULL(&sunxi_ohci->resume_work))
361 			cancel_work_sync(&sunxi_ohci->resume_work);
362 #endif
363 
364 	sunxi_stop_ohci(sunxi_ohci);
365 
366 	usb_put_hcd(hcd);
367 
368 	if (sunxi_ohci->supply)
369 		regulator_put(sunxi_ohci->supply);
370 
371 	sunxi_ohci->hcd = NULL;
372 
373 	return 0;
374 }
375 
sunxi_ohci_hcd_probe(struct platform_device * pdev)376 static int sunxi_ohci_hcd_probe(struct platform_device *pdev)
377 {
378 	int ret = 0;
379 #if defined(CONFIG_ARCH_SUN50IW10)
380 	int val = 0;
381 #endif
382 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
383 
384 	if (pdev == NULL) {
385 		DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
386 		return -1;
387 	}
388 
389 	/* if usb is disabled, can not probe */
390 	if (usb_disabled()) {
391 		DMSG_PANIC("ERR: usb hcd is disabled\n");
392 		return -ENODEV;
393 	}
394 
395 	ret = init_sunxi_hci(pdev, SUNXI_USB_OHCI);
396 	if (ret != 0) {
397 		dev_err(&pdev->dev, "init_sunxi_hci is fail\n");
398 		return -1;
399 	}
400 
401 	sunxi_insmod_ohci(pdev);
402 
403 	sunxi_ohci = pdev->dev.platform_data;
404 	if (sunxi_ohci == NULL) {
405 		DMSG_PANIC("ERR: %s, sunxi_ohci is null\n", __func__);
406 		return -1;
407 	}
408 
409 	if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
410 		ret = register_pm_notifier(&sunxi_ohci_pm_nb);
411 		if (ret) {
412 			DMSG_PANIC("ERR: %s, can not register suspend notifier\n", __func__);
413 			return -1;
414 		}
415 	}
416 
417 	init_completion(&sunxi_ohci->standby_complete);
418 
419 /* keep common circuit configuration when usb0 enable only*/
420 #if defined(CONFIG_ARCH_SUN50IW10)
421 	if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
422 		val = readl(sunxi_ohci->usb_ccmu_config + 0x0A8C);
423 		val |= (SUNXI_CCMU_USBEHCI1_GATING_OFFSET
424 			| SUNXI_CCMU_USBEHCI1_RST_OFFSET);
425 		writel(val, sunxi_ohci->usb_ccmu_config + 0x0A8C);
426 
427 		val = readl(sunxi_ohci->usb_ccmu_config + 0x0A74);
428 		val |= (SUNXI_CCMU_SCLK_GATING_USBPHY1_OFFSET
429 			| SUNXI_CCMU_USBPHY1_RST_OFFSET
430 			| SUNXI_CCMU_SCLK_GATING_OHCI1_OFFSET);
431 		writel(val, sunxi_ohci->usb_ccmu_config + 0x0A74);
432 
433 		/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
434 		val = USBC_Readl(sunxi_ohci->usb_common_phy_config
435 				 + SUNXI_HCI_PHY_CTRL);
436 		val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
437 		USBC_Writel(val, sunxi_ohci->usb_common_phy_config
438 			    + SUNXI_HCI_PHY_CTRL);
439 	}
440 #endif
441 
442 	if (ohci_enable[sunxi_ohci->usbc_no]) {
443 		device_create_file(&pdev->dev, &dev_attr_ohci_enable);
444 		ohci_enable[sunxi_ohci->usbc_no] = 0;
445 	}
446 
447 	return 0;
448 }
449 
sunxi_ohci_hcd_remove(struct platform_device * pdev)450 static int sunxi_ohci_hcd_remove(struct platform_device *pdev)
451 {
452 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
453 	int ret = 0;
454 #if defined(CONFIG_ARCH_SUN50IW10)
455 	int val = 0;
456 #endif
457 
458 	if (pdev == NULL) {
459 		DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
460 		return -1;
461 	}
462 
463 	sunxi_ohci = pdev->dev.platform_data;
464 	if (sunxi_ohci == NULL) {
465 		DMSG_PANIC("ERR: %s, sunxi_ohci is null\n", __func__);
466 		return -1;
467 	}
468 
469 	if (ohci_enable[sunxi_ohci->usbc_no] == 0)
470 		device_remove_file(&pdev->dev, &dev_attr_ohci_enable);
471 
472 /* reset common circuit configuration*/
473 #if defined(CONFIG_ARCH_SUN50IW10)
474 	if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
475 		val = readl(sunxi_ohci->usb_ccmu_config + 0x0A8C);
476 		val &= ~(SUNXI_CCMU_USBEHCI1_GATING_OFFSET
477 			 | SUNXI_CCMU_USBEHCI1_RST_OFFSET);
478 		writel(val, sunxi_ohci->usb_ccmu_config + 0x0A8C);
479 
480 		val = readl(sunxi_ohci->usb_ccmu_config + 0x0A74);
481 		val &= ~(SUNXI_CCMU_SCLK_GATING_USBPHY1_OFFSET
482 			| SUNXI_CCMU_USBPHY1_RST_OFFSET
483 			| SUNXI_CCMU_SCLK_GATING_OHCI1_OFFSET);
484 		writel(val, sunxi_ohci->usb_ccmu_config + 0x0A74);
485 
486 		/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
487 		val = USBC_Readl(sunxi_ohci->usb_common_phy_config
488 				 + SUNXI_HCI_PHY_CTRL);
489 		val |= (0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
490 		USBC_Writel(val, sunxi_ohci->usb_common_phy_config
491 			    + SUNXI_HCI_PHY_CTRL);
492 	}
493 #endif
494 
495 	if (sunxi_ohci->usbc_no == HCI0_USBC_NO)
496 		unregister_pm_notifier(&sunxi_ohci_pm_nb);
497 
498 	if (sunxi_ohci->probe == 1) {
499 		ret = sunxi_rmmod_ohci(pdev);
500 		if (ret == 0)
501 			exit_sunxi_hci(sunxi_ohci);
502 
503 
504 		return ret;
505 	} else
506 		return 0;
507 }
508 
sunxi_ohci_hcd_shutdown(struct platform_device * pdev)509 static void sunxi_ohci_hcd_shutdown(struct platform_device *pdev)
510 {
511 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
512 
513 	sunxi_ohci = pdev->dev.platform_data;
514 	if (sunxi_ohci == NULL) {
515 		DMSG_PANIC("ERR: %s sunxi_ohci is null\n", __func__);
516 		return;
517 	}
518 
519 	if (sunxi_ohci->probe == 0) {
520 		DMSG_INFO("%s, %s is disable, need not shutdown\n",
521 			__func__, sunxi_ohci->hci_name);
522 		return;
523 	}
524 
525 	DMSG_INFO("[%s]: ohci shutdown start\n", sunxi_ohci->hci_name);
526 
527 	usb_hcd_platform_shutdown(pdev);
528 
529 	/**
530 	 * disable usb otg INTUSBE, to solve usb0 device mode
531 	 * catch audio udev on reboot system is fail.
532 	 */
533 	if (sunxi_ohci->usbc_no == 0) {
534 		if (sunxi_ohci->otg_vbase) {
535 			writel(0, (sunxi_ohci->otg_vbase
536 						+ SUNXI_USBC_REG_INTUSBE));
537 		}
538 	}
539 	sunxi_ohci_set_vbus(sunxi_ohci, 0);
540 	DMSG_INFO("[%s]: ohci shutdown end\n", sunxi_ohci->hci_name);
541 }
542 
543 #if IS_ENABLED(CONFIG_PM)
544 
sunxi_ohci_hcd_suspend(struct device * dev)545 static int sunxi_ohci_hcd_suspend(struct device *dev)
546 {
547 	struct sunxi_hci_hcd *sunxi_ohci  = NULL;
548 	struct usb_hcd *hcd	= NULL;
549 	struct ohci_hcd	*ohci	= NULL;
550 	int val = 0;
551 
552 	if (dev == NULL) {
553 		DMSG_PANIC("ERR: Argment is invalid\n");
554 		return 0;
555 	}
556 
557 	hcd = dev_get_drvdata(dev);
558 	if (hcd == NULL) {
559 		DMSG_PANIC("ERR: hcd is null\n");
560 		return 0;
561 	}
562 
563 	sunxi_ohci = dev->platform_data;
564 	if (sunxi_ohci == NULL) {
565 		DMSG_PANIC("ERR: sunxi_ohci is null\n");
566 		return 0;
567 	}
568 
569 	if (sunxi_ohci->no_suspend) {
570 		DMSG_INFO("[%s]:ohci is being enable, stop system suspend\n",
571 			sunxi_ohci->hci_name);
572 		return -1;
573 	}
574 
575 	if (sunxi_ohci->probe == 0) {
576 		DMSG_INFO("[%s]: is disable, can not suspend\n",
577 			sunxi_ohci->hci_name);
578 		return 0;
579 	}
580 
581 	ohci = hcd_to_ohci(hcd);
582 	if (ohci == NULL) {
583 		DMSG_PANIC("ERR: ohci is null\n");
584 		return 0;
585 	}
586 
587 	if (sunxi_ohci->wakeup_suspend == USB_STANDBY) {
588 		DMSG_INFO("[%s] usb suspend\n", sunxi_ohci->hci_name);
589 		disable_irq(sunxi_ohci->irq_no);
590 		val = ohci_readl(ohci, &ohci->regs->control);
591 		val |= OHCI_CTRL_RWE;
592 		ohci_writel(ohci, val,  &ohci->regs->control);
593 
594 		val = ohci_readl(ohci, &ohci->regs->intrenable);
595 		val |= OHCI_INTR_RD;
596 		val |= OHCI_INTR_MIE;
597 		ohci_writel(ohci, val, &ohci->regs->intrenable);
598 
599 #if IS_ENABLED(SUNXI_USB_STANDBY_LOW_POW_MODE)
600 		val = ohci_readl(ohci, &ohci->regs->control);
601 		val |= OHCI_USB_SUSPEND;
602 		ohci_writel(ohci, val, &ohci->regs->control);
603 #endif
604 		enter_usb_standby(sunxi_ohci);
605 
606 		if (sunxi_ohci->clk_usbohci12m && sunxi_ohci->clk_losc)
607 			clk_set_parent(sunxi_ohci->clk_usbohci12m,
608 					sunxi_ohci->clk_losc);
609 	} else {
610 		DMSG_INFO("[%s]super suspend\n", sunxi_ohci->hci_name);
611 
612 		/**
613 		 * Root hub was already suspended. Disable irq emission and
614 		 * mark HW unaccessible, bail out if RH has been resumed. Use
615 		 * the spinlock to properly synchronize with possible pending
616 		 * RH suspend or resume activity.
617 		 *
618 		 * This is still racy as hcd->state is manipulated outside of
619 		 * any locks =P But that will be a different fix.
620 		 */
621 		ohci_suspend(hcd, device_may_wakeup(dev));
622 
623 		cancel_work_sync(&sunxi_ohci->resume_work);
624 		sunxi_stop_ohci(sunxi_ohci);
625 
626 	}
627 
628 	return 0;
629 }
630 
sunxi_ohci_resume_work(struct work_struct * work)631 static void sunxi_ohci_resume_work(struct work_struct *work)
632 {
633 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
634 
635 	sunxi_ohci = container_of(work, struct sunxi_hci_hcd, resume_work);
636 
637 	sunxi_ohci_set_vbus(sunxi_ohci, 1);
638 }
639 
sunxi_ohci_hcd_resume(struct device * dev)640 static int sunxi_ohci_hcd_resume(struct device *dev)
641 {
642 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
643 	struct usb_hcd *hcd = NULL;
644 	struct ohci_hcd	*ohci	= NULL;
645 	int __maybe_unused val = 0;
646 
647 	if (dev == NULL) {
648 		DMSG_PANIC("ERR: Argment is invalid\n");
649 		return 0;
650 	}
651 
652 	hcd = dev_get_drvdata(dev);
653 	if (hcd == NULL) {
654 		DMSG_PANIC("ERR: hcd is null\n");
655 		return 0;
656 	}
657 
658 	sunxi_ohci = dev->platform_data;
659 	if (sunxi_ohci == NULL) {
660 		DMSG_PANIC("ERR: sunxi_ohci is null\n");
661 		return 0;
662 	}
663 
664 	if (sunxi_ohci->probe == 0) {
665 		DMSG_INFO("[%s]: is disable, can not resume\n",
666 			sunxi_ohci->hci_name);
667 		return 0;
668 	}
669 
670 	ohci = hcd_to_ohci(hcd);
671 	if (ohci == NULL) {
672 		DMSG_PANIC("ERR: ohci is null\n");
673 		return 0;
674 	}
675 
676 	if (sunxi_ohci->wakeup_suspend == USB_STANDBY) {
677 		DMSG_INFO("[%s]usb resume\n", sunxi_ohci->hci_name);
678 
679 		if (sunxi_ohci->clk_usbohci12m && sunxi_ohci->clk_hoscx2)
680 			clk_set_parent(sunxi_ohci->clk_usbohci12m,
681 					sunxi_ohci->clk_hoscx2);
682 
683 		exit_usb_standby(sunxi_ohci);
684 #if IS_ENABLED(SUNXI_USB_STANDBY_LOW_POW_MODE)
685 		val = ohci_readl(ohci, &ohci->regs->control);
686 		val &= ~(OHCI_USB_SUSPEND);
687 		val |= OHCI_USB_RESUME;
688 		ohci_writel(ohci, val, &ohci->regs->control);
689 #endif
690 		enable_irq(sunxi_ohci->irq_no);
691 	} else {
692 		DMSG_INFO("[%s]super resume\n", sunxi_ohci->hci_name);
693 		open_ohci_clock(sunxi_ohci);
694 		sunxi_ohci_set_passby(sunxi_ohci, 1);
695 		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
696 		ohci_resume(hcd, false);
697 
698 #if defined(CONFIG_ARCH_SUN50IW10)
699 		if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
700 			/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
701 			val = USBC_Readl(sunxi_ohci->usb_common_phy_config
702 					 + SUNXI_HCI_PHY_CTRL);
703 			val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
704 			USBC_Writel(val, sunxi_ohci->usb_common_phy_config
705 				    + SUNXI_HCI_PHY_CTRL);
706 		}
707 #endif
708 
709 		schedule_work(&sunxi_ohci->resume_work);
710 	}
711 
712 	return 0;
713 }
714 
715 static const struct dev_pm_ops sunxi_ohci_pmops = {
716 	.suspend	= sunxi_ohci_hcd_suspend,
717 	.resume		= sunxi_ohci_hcd_resume,
718 };
719 
720 #define SUNXI_OHCI_PMOPS (&sunxi_ohci_pmops)
721 
722 #else
723 
724 #define SUNXI_OHCI_PMOPS NULL
725 
726 #endif
727 
728 static const struct of_device_id sunxi_ohci_match[] = {
729 	{.compatible = SUNXI_OHCI0_OF_MATCH, },
730 	{.compatible = SUNXI_OHCI1_OF_MATCH, },
731 	{.compatible = SUNXI_OHCI2_OF_MATCH, },
732 	{.compatible = SUNXI_OHCI3_OF_MATCH, },
733 	{},
734 };
735 MODULE_DEVICE_TABLE(of, sunxi_ohci_match);
736 
737 
738 static struct platform_driver sunxi_ohci_hcd_driver = {
739 	.probe		= sunxi_ohci_hcd_probe,
740 	.remove		= sunxi_ohci_hcd_remove,
741 	.shutdown	= sunxi_ohci_hcd_shutdown,
742 	.driver		= {
743 		.name	= ohci_name,
744 		.owner	= THIS_MODULE,
745 		.pm	= SUNXI_OHCI_PMOPS,
746 		.of_match_table = sunxi_ohci_match,
747 	},
748 };
749 
sunxi_usb_disable_ohci(__u32 usbc_no)750 int sunxi_usb_disable_ohci(__u32 usbc_no)
751 {
752 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
753 
754 	sunxi_ohci = g_sunxi_ohci[usbc_no];
755 	if (sunxi_ohci == NULL) {
756 		DMSG_PANIC("ERR: sunxi_ohci is null\n");
757 		return -1;
758 	}
759 
760 	if (sunxi_ohci->probe == 0) {
761 		DMSG_PANIC("ERR: sunxi_ohci is disable, can not disable again\n");
762 		return -1;
763 	}
764 
765 	sunxi_ohci->probe = 0;
766 
767 	DMSG_INFO("[%s]: sunxi_usb_disable_ohci\n", sunxi_ohci->hci_name);
768 
769 	sunxi_rmmod_ohci(sunxi_ohci->pdev);
770 
771 	return 0;
772 }
773 EXPORT_SYMBOL(sunxi_usb_disable_ohci);
774 
sunxi_usb_enable_ohci(__u32 usbc_no)775 int sunxi_usb_enable_ohci(__u32 usbc_no)
776 {
777 	struct sunxi_hci_hcd *sunxi_ohci = NULL;
778 #if defined(CONFIG_ARCH_SUN50IW10)
779 	int val;
780 #endif
781 
782 	sunxi_ohci = g_sunxi_ohci[usbc_no];
783 	if (sunxi_ohci == NULL) {
784 		DMSG_PANIC("ERR: sunxi_ohci is null\n");
785 		return -1;
786 	}
787 
788 	if (sunxi_ohci->probe == 1) {
789 		DMSG_PANIC("ERR: sunxi_ohci is already enable, can not enable again\n");
790 		return -1;
791 	}
792 
793 	sunxi_ohci->no_suspend = 1;
794 
795 	DMSG_INFO("[%s]: sunxi_usb_enable_ohci\n", sunxi_ohci->hci_name);
796 
797 #if defined(CONFIG_ARCH_SUN50IW10)
798 		if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
799 			/*phy reg, offset:0x10 bit3 set 0, enable siddq*/
800 			val = USBC_Readl(sunxi_ohci->usb_common_phy_config
801 					 + SUNXI_HCI_PHY_CTRL);
802 			val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
803 			USBC_Writel(val, sunxi_ohci->usb_common_phy_config
804 				    + SUNXI_HCI_PHY_CTRL);
805 		}
806 #endif
807 
808 	sunxi_insmod_ohci(sunxi_ohci->pdev);
809 
810 	sunxi_ohci->no_suspend = 0;
811 
812 	return 0;
813 }
814 EXPORT_SYMBOL(sunxi_usb_enable_ohci);
815 
sunxi_ohci_hcd_init(void)816 static int __init sunxi_ohci_hcd_init(void)
817 {
818 	if (usb_disabled()) {
819 		DMSG_ERR(KERN_ERR "%s nousb\n", ohci_name);
820 		return -ENODEV;
821 	}
822 
823 	DMSG_INFO(KERN_INFO "%s: " DRIVER_DESC "\n", ohci_name);
824 	ohci_init_driver(&sunxi_ohci_hc_driver, NULL);
825 	return platform_driver_register(&sunxi_ohci_hcd_driver);
826 }
827 module_init(sunxi_ohci_hcd_init);
828 
sunxi_ohci_hcd_cleanup(void)829 static void __exit sunxi_ohci_hcd_cleanup(void)
830 {
831 	platform_driver_unregister(&sunxi_ohci_hcd_driver);
832 }
833 module_exit(sunxi_ohci_hcd_cleanup);
834 
835 MODULE_DESCRIPTION(DRIVER_DESC);
836 MODULE_LICENSE("GPL v2");
837 MODULE_ALIAS("platform:" SUNXI_OHCI_NAME);
838 MODULE_AUTHOR("javen");
839 MODULE_VERSION("1.0.9");
840