Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-3.17-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-linus

Kishon writes:

for_3.17-rc

Fix regressions to runtime PM on OMAP and other minor fixes.

+91 -52
+13
MAINTAINERS
··· 7912 7912 L: netdev@vger.kernel.org 7913 7913 F: drivers/net/ethernet/samsung/sxgbe/ 7914 7914 7915 + SAMSUNG USB2 PHY DRIVER 7916 + M: Kamil Debski <k.debski@samsung.com> 7917 + L: linux-kernel@vger.kernel.org 7918 + S: Supported 7919 + F: Documentation/devicetree/bindings/phy/samsung-phy.txt 7920 + F: Documentation/phy/samsung-usb2.txt 7921 + F: drivers/phy/phy-exynos4210-usb2.c 7922 + F: drivers/phy/phy-exynos4x12-usb2.c 7923 + F: drivers/phy/phy-exynos5250-usb2.c 7924 + F: drivers/phy/phy-s5pv210-usb2.c 7925 + F: drivers/phy/phy-samsung-usb2.c 7926 + F: drivers/phy/phy-samsung-usb2.h 7927 + 7915 7928 SERIAL DRIVERS 7916 7929 M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 7917 7930 L: linux-serial@vger.kernel.org
+1 -1
drivers/phy/Kconfig
··· 41 41 config PHY_MIPHY365X 42 42 tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series" 43 43 depends on ARCH_STI 44 - depends on GENERIC_PHY 45 44 depends on HAS_IOMEM 46 45 depends on OF 46 + select GENERIC_PHY 47 47 help 48 48 Enable this to support the miphy transceiver (for SATA/PCIE) 49 49 that is part of STMicroelectronics STiH41x SoC series.
+1
drivers/phy/phy-exynos5-usbdrd.c
··· 542 542 }, 543 543 { }, 544 544 }; 545 + MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match); 545 546 546 547 static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) 547 548 {
+76 -51
drivers/phy/phy-twl4030-usb.c
··· 34 34 #include <linux/delay.h> 35 35 #include <linux/usb/otg.h> 36 36 #include <linux/phy/phy.h> 37 + #include <linux/pm_runtime.h> 37 38 #include <linux/usb/musb-omap.h> 38 39 #include <linux/usb/ulpi.h> 39 40 #include <linux/i2c/twl.h> ··· 423 422 } 424 423 } 425 424 426 - static int twl4030_phy_power_off(struct phy *phy) 425 + static int twl4030_usb_runtime_suspend(struct device *dev) 427 426 { 428 - struct twl4030_usb *twl = phy_get_drvdata(phy); 427 + struct twl4030_usb *twl = dev_get_drvdata(dev); 429 428 429 + dev_dbg(twl->dev, "%s\n", __func__); 430 430 if (twl->asleep) 431 431 return 0; 432 432 433 433 twl4030_phy_power(twl, 0); 434 434 twl->asleep = 1; 435 - dev_dbg(twl->dev, "%s\n", __func__); 435 + 436 436 return 0; 437 437 } 438 438 439 - static void __twl4030_phy_power_on(struct twl4030_usb *twl) 439 + static int twl4030_usb_runtime_resume(struct device *dev) 440 440 { 441 + struct twl4030_usb *twl = dev_get_drvdata(dev); 442 + 443 + dev_dbg(twl->dev, "%s\n", __func__); 444 + if (!twl->asleep) 445 + return 0; 446 + 441 447 twl4030_phy_power(twl, 1); 442 - twl4030_i2c_access(twl, 1); 443 - twl4030_usb_set_mode(twl, twl->usb_mode); 444 - if (twl->usb_mode == T2_USB_MODE_ULPI) 445 - twl4030_i2c_access(twl, 0); 448 + twl->asleep = 0; 449 + 450 + return 0; 451 + } 452 + 453 + static int twl4030_phy_power_off(struct phy *phy) 454 + { 455 + struct twl4030_usb *twl = phy_get_drvdata(phy); 456 + 457 + dev_dbg(twl->dev, "%s\n", __func__); 458 + pm_runtime_mark_last_busy(twl->dev); 459 + pm_runtime_put_autosuspend(twl->dev); 460 + 461 + return 0; 446 462 } 447 463 448 464 static int twl4030_phy_power_on(struct phy *phy) 449 465 { 450 466 struct twl4030_usb *twl = phy_get_drvdata(phy); 451 467 452 - if (!twl->asleep) 453 - return 0; 454 - __twl4030_phy_power_on(twl); 455 - twl->asleep = 0; 456 468 dev_dbg(twl->dev, "%s\n", __func__); 469 + pm_runtime_get_sync(twl->dev); 470 + twl4030_i2c_access(twl, 1); 471 + twl4030_usb_set_mode(twl, twl->usb_mode); 472 + if (twl->usb_mode == T2_USB_MODE_ULPI) 473 + twl4030_i2c_access(twl, 0); 457 474 458 475 /* 459 476 * XXX When VBUS gets driven after musb goes to A mode, ··· 577 558 * USB_LINK_VBUS state. musb_hdrc won't care until it 578 559 * starts to handle softconnect right. 579 560 */ 580 - omap_musb_mailbox(status); 581 - } 582 - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); 583 - 584 - return IRQ_HANDLED; 585 - } 586 - 587 - static void twl4030_id_workaround_work(struct work_struct *work) 588 - { 589 - struct twl4030_usb *twl = container_of(work, struct twl4030_usb, 590 - id_workaround_work.work); 591 - enum omap_musb_vbus_id_status status; 592 - bool status_changed = false; 593 - 594 - status = twl4030_usb_linkstat(twl); 595 - 596 - spin_lock_irq(&twl->lock); 597 - if (status >= 0 && status != twl->linkstat) { 598 - twl->linkstat = status; 599 - status_changed = true; 600 - } 601 - spin_unlock_irq(&twl->lock); 602 - 603 - if (status_changed) { 604 - dev_dbg(twl->dev, "handle missing status change to %d\n", 605 - status); 561 + if ((status == OMAP_MUSB_VBUS_VALID) || 562 + (status == OMAP_MUSB_ID_GROUND)) { 563 + if (twl->asleep) 564 + pm_runtime_get_sync(twl->dev); 565 + } else { 566 + if (!twl->asleep) { 567 + pm_runtime_mark_last_busy(twl->dev); 568 + pm_runtime_put_autosuspend(twl->dev); 569 + } 570 + } 606 571 omap_musb_mailbox(status); 607 572 } 608 573 ··· 595 592 cancel_delayed_work(&twl->id_workaround_work); 596 593 schedule_delayed_work(&twl->id_workaround_work, HZ); 597 594 } 595 + 596 + if (irq) 597 + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); 598 + 599 + return IRQ_HANDLED; 600 + } 601 + 602 + static void twl4030_id_workaround_work(struct work_struct *work) 603 + { 604 + struct twl4030_usb *twl = container_of(work, struct twl4030_usb, 605 + id_workaround_work.work); 606 + 607 + twl4030_usb_irq(0, twl); 598 608 } 599 609 600 610 static int twl4030_phy_init(struct phy *phy) ··· 615 599 struct twl4030_usb *twl = phy_get_drvdata(phy); 616 600 enum omap_musb_vbus_id_status status; 617 601 618 - /* 619 - * Start in sleep state, we'll get called through set_suspend() 620 - * callback when musb is runtime resumed and it's time to start. 621 - */ 622 - __twl4030_phy_power(twl, 0); 623 - twl->asleep = 1; 624 - 602 + pm_runtime_get_sync(twl->dev); 625 603 status = twl4030_usb_linkstat(twl); 626 604 twl->linkstat = status; 627 605 628 - if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { 606 + if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) 629 607 omap_musb_mailbox(twl->linkstat); 630 - twl4030_phy_power_on(phy); 631 - } 632 608 633 609 sysfs_notify(&twl->dev->kobj, NULL, "vbus"); 610 + pm_runtime_mark_last_busy(twl->dev); 611 + pm_runtime_put_autosuspend(twl->dev); 612 + 634 613 return 0; 635 614 } 636 615 ··· 659 648 .power_on = twl4030_phy_power_on, 660 649 .power_off = twl4030_phy_power_off, 661 650 .owner = THIS_MODULE, 651 + }; 652 + 653 + static const struct dev_pm_ops twl4030_usb_pm_ops = { 654 + SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend, 655 + twl4030_usb_runtime_resume, NULL) 662 656 }; 663 657 664 658 static int twl4030_usb_probe(struct platform_device *pdev) ··· 742 726 743 727 ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); 744 728 729 + pm_runtime_use_autosuspend(&pdev->dev); 730 + pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); 731 + pm_runtime_enable(&pdev->dev); 732 + pm_runtime_get_sync(&pdev->dev); 733 + 745 734 /* Our job is to use irqs and status from the power module 746 735 * to keep the transceiver disabled when nothing's connected. 747 736 * ··· 765 744 return status; 766 745 } 767 746 747 + pm_runtime_mark_last_busy(&pdev->dev); 748 + pm_runtime_put_autosuspend(twl->dev); 749 + 768 750 dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); 769 751 return 0; 770 752 } ··· 777 753 struct twl4030_usb *twl = platform_get_drvdata(pdev); 778 754 int val; 779 755 756 + pm_runtime_get_sync(twl->dev); 780 757 cancel_delayed_work(&twl->id_workaround_work); 781 758 device_remove_file(twl->dev, &dev_attr_vbus); 782 759 ··· 797 772 798 773 /* disable complete OTG block */ 799 774 twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); 800 - 801 - if (!twl->asleep) 802 - twl4030_phy_power(twl, 0); 775 + pm_runtime_mark_last_busy(twl->dev); 776 + pm_runtime_put(twl->dev); 803 777 804 778 return 0; 805 779 } ··· 816 792 .remove = twl4030_usb_remove, 817 793 .driver = { 818 794 .name = "twl4030_usb", 795 + .pm = &twl4030_usb_pm_ops, 819 796 .owner = THIS_MODULE, 820 797 .of_match_table = of_match_ptr(twl4030_usb_id_table), 821 798 },