mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-28 07:04:00 +08:00
for_3.17-rc
Fix regressions to runtime PM on OMAP and other minor fixes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJT/wC9AAoJEA5ceFyATYLZyZ4QAJ0q0XT9hpsx5TAUcM8azeYG jRGm2SrkBQlxkCH8lS6PhJXGdbd8SR3H9l0ITPNed/Vwt0N5LBtBVmRWGDJNliGM E9RoBTBqohPlBozyORDoM8cs2RIVqj14WAhXjJUvq+6DAxw6rQ5UMnKJXiNf8Ui7 MGh9i0/JQvKNYLVvGACzo5Jb38c0fSR7irYcAQJstI77QnnJQ6pSTdseCV64F45L IFvLa+4gkqfi8vFHlVH5pSa6NRmq9x+q1fkDl/e+EcJjZ67xfAFuXGlvsM8m6B7F YzyNNiqpGW9KvRRhOfQCWadI0olgtPZS2XXS9pRgIDDDh38V9bkyv0aQJLGQrZlz ChQq2jnVifTo0MK93x4s28DUjETxhUQLZ0rtENiLaNHcpiFJRZxVdZ+q5ZTRN5JA oaqbty6FEyWlSIv80jIe4s55RpBxWIGr0PRLNnVRl4+GWKxQOjCnnY2CLxLpz0dN c/6TVJwIsZDQD6A895eBdjmTCF4oLdswtwHMn4P3g1vxNGjP0UwsJ3kGb59Zx7GO dopEtLCutMC8tcLUl2YJwEiPUSqAJlfeDJ7h0SRdhwE3jqsdnuwFOT2BRFlfM6qq P04SYd5W9r9MW9y5suUnuURddpqVYIe8wt405dSqY4+jP2pVzyjAMaBmuoVbOx4g Ejjp9CDLmsozs1wfiOsd =s/sJ -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
c156bf2cfc
13
MAINTAINERS
13
MAINTAINERS
@ -7912,6 +7912,19 @@ S: Supported
|
|||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
F: drivers/net/ethernet/samsung/sxgbe/
|
F: drivers/net/ethernet/samsung/sxgbe/
|
||||||
|
|
||||||
|
SAMSUNG USB2 PHY DRIVER
|
||||||
|
M: Kamil Debski <k.debski@samsung.com>
|
||||||
|
L: linux-kernel@vger.kernel.org
|
||||||
|
S: Supported
|
||||||
|
F: Documentation/devicetree/bindings/phy/samsung-phy.txt
|
||||||
|
F: Documentation/phy/samsung-usb2.txt
|
||||||
|
F: drivers/phy/phy-exynos4210-usb2.c
|
||||||
|
F: drivers/phy/phy-exynos4x12-usb2.c
|
||||||
|
F: drivers/phy/phy-exynos5250-usb2.c
|
||||||
|
F: drivers/phy/phy-s5pv210-usb2.c
|
||||||
|
F: drivers/phy/phy-samsung-usb2.c
|
||||||
|
F: drivers/phy/phy-samsung-usb2.h
|
||||||
|
|
||||||
SERIAL DRIVERS
|
SERIAL DRIVERS
|
||||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
L: linux-serial@vger.kernel.org
|
L: linux-serial@vger.kernel.org
|
||||||
|
@ -41,9 +41,9 @@ config PHY_MVEBU_SATA
|
|||||||
config PHY_MIPHY365X
|
config PHY_MIPHY365X
|
||||||
tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
|
tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
|
||||||
depends on ARCH_STI
|
depends on ARCH_STI
|
||||||
depends on GENERIC_PHY
|
|
||||||
depends on HAS_IOMEM
|
depends on HAS_IOMEM
|
||||||
depends on OF
|
depends on OF
|
||||||
|
select GENERIC_PHY
|
||||||
help
|
help
|
||||||
Enable this to support the miphy transceiver (for SATA/PCIE)
|
Enable this to support the miphy transceiver (for SATA/PCIE)
|
||||||
that is part of STMicroelectronics STiH41x SoC series.
|
that is part of STMicroelectronics STiH41x SoC series.
|
||||||
|
@ -542,6 +542,7 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
|
|||||||
},
|
},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match);
|
||||||
|
|
||||||
static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
|
static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/usb/otg.h>
|
#include <linux/usb/otg.h>
|
||||||
#include <linux/phy/phy.h>
|
#include <linux/phy/phy.h>
|
||||||
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/usb/musb-omap.h>
|
#include <linux/usb/musb-omap.h>
|
||||||
#include <linux/usb/ulpi.h>
|
#include <linux/usb/ulpi.h>
|
||||||
#include <linux/i2c/twl.h>
|
#include <linux/i2c/twl.h>
|
||||||
@ -422,37 +423,55 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl4030_phy_power_off(struct phy *phy)
|
static int twl4030_usb_runtime_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct twl4030_usb *twl = phy_get_drvdata(phy);
|
struct twl4030_usb *twl = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
dev_dbg(twl->dev, "%s\n", __func__);
|
||||||
if (twl->asleep)
|
if (twl->asleep)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
twl4030_phy_power(twl, 0);
|
twl4030_phy_power(twl, 0);
|
||||||
twl->asleep = 1;
|
twl->asleep = 1;
|
||||||
dev_dbg(twl->dev, "%s\n", __func__);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __twl4030_phy_power_on(struct twl4030_usb *twl)
|
static int twl4030_usb_runtime_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct twl4030_usb *twl = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
dev_dbg(twl->dev, "%s\n", __func__);
|
||||||
|
if (!twl->asleep)
|
||||||
|
return 0;
|
||||||
|
|
||||||
twl4030_phy_power(twl, 1);
|
twl4030_phy_power(twl, 1);
|
||||||
twl4030_i2c_access(twl, 1);
|
twl->asleep = 0;
|
||||||
twl4030_usb_set_mode(twl, twl->usb_mode);
|
|
||||||
if (twl->usb_mode == T2_USB_MODE_ULPI)
|
return 0;
|
||||||
twl4030_i2c_access(twl, 0);
|
}
|
||||||
|
|
||||||
|
static int twl4030_phy_power_off(struct phy *phy)
|
||||||
|
{
|
||||||
|
struct twl4030_usb *twl = phy_get_drvdata(phy);
|
||||||
|
|
||||||
|
dev_dbg(twl->dev, "%s\n", __func__);
|
||||||
|
pm_runtime_mark_last_busy(twl->dev);
|
||||||
|
pm_runtime_put_autosuspend(twl->dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl4030_phy_power_on(struct phy *phy)
|
static int twl4030_phy_power_on(struct phy *phy)
|
||||||
{
|
{
|
||||||
struct twl4030_usb *twl = phy_get_drvdata(phy);
|
struct twl4030_usb *twl = phy_get_drvdata(phy);
|
||||||
|
|
||||||
if (!twl->asleep)
|
|
||||||
return 0;
|
|
||||||
__twl4030_phy_power_on(twl);
|
|
||||||
twl->asleep = 0;
|
|
||||||
dev_dbg(twl->dev, "%s\n", __func__);
|
dev_dbg(twl->dev, "%s\n", __func__);
|
||||||
|
pm_runtime_get_sync(twl->dev);
|
||||||
|
twl4030_i2c_access(twl, 1);
|
||||||
|
twl4030_usb_set_mode(twl, twl->usb_mode);
|
||||||
|
if (twl->usb_mode == T2_USB_MODE_ULPI)
|
||||||
|
twl4030_i2c_access(twl, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX When VBUS gets driven after musb goes to A mode,
|
* XXX When VBUS gets driven after musb goes to A mode,
|
||||||
@ -558,8 +577,26 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
|
|||||||
* USB_LINK_VBUS state. musb_hdrc won't care until it
|
* USB_LINK_VBUS state. musb_hdrc won't care until it
|
||||||
* starts to handle softconnect right.
|
* starts to handle softconnect right.
|
||||||
*/
|
*/
|
||||||
|
if ((status == OMAP_MUSB_VBUS_VALID) ||
|
||||||
|
(status == OMAP_MUSB_ID_GROUND)) {
|
||||||
|
if (twl->asleep)
|
||||||
|
pm_runtime_get_sync(twl->dev);
|
||||||
|
} else {
|
||||||
|
if (!twl->asleep) {
|
||||||
|
pm_runtime_mark_last_busy(twl->dev);
|
||||||
|
pm_runtime_put_autosuspend(twl->dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
omap_musb_mailbox(status);
|
omap_musb_mailbox(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* don't schedule during sleep - irq works right then */
|
||||||
|
if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
|
||||||
|
cancel_delayed_work(&twl->id_workaround_work);
|
||||||
|
schedule_delayed_work(&twl->id_workaround_work, HZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irq)
|
||||||
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
|
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
@ -569,29 +606,8 @@ static void twl4030_id_workaround_work(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct twl4030_usb *twl = container_of(work, struct twl4030_usb,
|
struct twl4030_usb *twl = container_of(work, struct twl4030_usb,
|
||||||
id_workaround_work.work);
|
id_workaround_work.work);
|
||||||
enum omap_musb_vbus_id_status status;
|
|
||||||
bool status_changed = false;
|
|
||||||
|
|
||||||
status = twl4030_usb_linkstat(twl);
|
twl4030_usb_irq(0, twl);
|
||||||
|
|
||||||
spin_lock_irq(&twl->lock);
|
|
||||||
if (status >= 0 && status != twl->linkstat) {
|
|
||||||
twl->linkstat = status;
|
|
||||||
status_changed = true;
|
|
||||||
}
|
|
||||||
spin_unlock_irq(&twl->lock);
|
|
||||||
|
|
||||||
if (status_changed) {
|
|
||||||
dev_dbg(twl->dev, "handle missing status change to %d\n",
|
|
||||||
status);
|
|
||||||
omap_musb_mailbox(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't schedule during sleep - irq works right then */
|
|
||||||
if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
|
|
||||||
cancel_delayed_work(&twl->id_workaround_work);
|
|
||||||
schedule_delayed_work(&twl->id_workaround_work, HZ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl4030_phy_init(struct phy *phy)
|
static int twl4030_phy_init(struct phy *phy)
|
||||||
@ -599,22 +615,17 @@ static int twl4030_phy_init(struct phy *phy)
|
|||||||
struct twl4030_usb *twl = phy_get_drvdata(phy);
|
struct twl4030_usb *twl = phy_get_drvdata(phy);
|
||||||
enum omap_musb_vbus_id_status status;
|
enum omap_musb_vbus_id_status status;
|
||||||
|
|
||||||
/*
|
pm_runtime_get_sync(twl->dev);
|
||||||
* Start in sleep state, we'll get called through set_suspend()
|
|
||||||
* callback when musb is runtime resumed and it's time to start.
|
|
||||||
*/
|
|
||||||
__twl4030_phy_power(twl, 0);
|
|
||||||
twl->asleep = 1;
|
|
||||||
|
|
||||||
status = twl4030_usb_linkstat(twl);
|
status = twl4030_usb_linkstat(twl);
|
||||||
twl->linkstat = status;
|
twl->linkstat = status;
|
||||||
|
|
||||||
if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) {
|
if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)
|
||||||
omap_musb_mailbox(twl->linkstat);
|
omap_musb_mailbox(twl->linkstat);
|
||||||
twl4030_phy_power_on(phy);
|
|
||||||
}
|
|
||||||
|
|
||||||
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
|
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
|
||||||
|
pm_runtime_mark_last_busy(twl->dev);
|
||||||
|
pm_runtime_put_autosuspend(twl->dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,6 +661,11 @@ static const struct phy_ops ops = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct dev_pm_ops twl4030_usb_pm_ops = {
|
||||||
|
SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend,
|
||||||
|
twl4030_usb_runtime_resume, NULL)
|
||||||
|
};
|
||||||
|
|
||||||
static int twl4030_usb_probe(struct platform_device *pdev)
|
static int twl4030_usb_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
|
struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
|
||||||
@ -726,6 +742,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
|
ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
|
||||||
|
|
||||||
|
pm_runtime_use_autosuspend(&pdev->dev);
|
||||||
|
pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
|
||||||
|
pm_runtime_enable(&pdev->dev);
|
||||||
|
pm_runtime_get_sync(&pdev->dev);
|
||||||
|
|
||||||
/* Our job is to use irqs and status from the power module
|
/* Our job is to use irqs and status from the power module
|
||||||
* to keep the transceiver disabled when nothing's connected.
|
* to keep the transceiver disabled when nothing's connected.
|
||||||
*
|
*
|
||||||
@ -744,6 +765,9 @@ static int twl4030_usb_probe(struct platform_device *pdev)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(&pdev->dev);
|
||||||
|
pm_runtime_put_autosuspend(twl->dev);
|
||||||
|
|
||||||
dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
|
dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -753,6 +777,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
|
|||||||
struct twl4030_usb *twl = platform_get_drvdata(pdev);
|
struct twl4030_usb *twl = platform_get_drvdata(pdev);
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
|
pm_runtime_get_sync(twl->dev);
|
||||||
cancel_delayed_work(&twl->id_workaround_work);
|
cancel_delayed_work(&twl->id_workaround_work);
|
||||||
device_remove_file(twl->dev, &dev_attr_vbus);
|
device_remove_file(twl->dev, &dev_attr_vbus);
|
||||||
|
|
||||||
@ -772,9 +797,8 @@ static int twl4030_usb_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
/* disable complete OTG block */
|
/* disable complete OTG block */
|
||||||
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
|
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
|
||||||
|
pm_runtime_mark_last_busy(twl->dev);
|
||||||
if (!twl->asleep)
|
pm_runtime_put(twl->dev);
|
||||||
twl4030_phy_power(twl, 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -792,6 +816,7 @@ static struct platform_driver twl4030_usb_driver = {
|
|||||||
.remove = twl4030_usb_remove,
|
.remove = twl4030_usb_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "twl4030_usb",
|
.name = "twl4030_usb",
|
||||||
|
.pm = &twl4030_usb_pm_ops,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(twl4030_usb_id_table),
|
.of_match_table = of_match_ptr(twl4030_usb_id_table),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user