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