summaryrefslogtreecommitdiff
path: root/drivers/usb/phy/phy-am335x-control.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-08-19 14:39:44 +0400
committerFelipe Balbi <balbi@ti.com>2013-10-01 18:31:11 +0400
commita12226394e7d19734d129766676a5668efd50d5c (patch)
tree29e62ed87e7641b9f2d210c661fd7b622fae171a /drivers/usb/phy/phy-am335x-control.c
parent4d175f340c9c055482688d2205038413dc7b6f1e (diff)
downloadlinux-a12226394e7d19734d129766676a5668efd50d5c.tar.xz
usb: phy: am335x: add wakeup support
This is based on George Cherian's patch which added power & wakeup support to am335x and does no longer apply since I took some if the code apart in favor of the multi instance support. This compiles and I boots and later it detects a device after I plug it in :) Could somebody please test it so it does what it should? Cc: George Cherian <george.cherian@ti.com> Reviewed-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy/phy-am335x-control.c')
-rw-r--r--drivers/usb/phy/phy-am335x-control.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c
index 22cf07d62e4c..0fac976b63b5 100644
--- a/drivers/usb/phy/phy-am335x-control.c
+++ b/drivers/usb/phy/phy-am335x-control.c
@@ -26,6 +26,41 @@ struct am335x_control_usb {
#define USBPHY_OTGVDET_EN (1 << 19)
#define USBPHY_OTGSESSEND_EN (1 << 20)
+#define AM335X_PHY0_WK_EN (1 << 0)
+#define AM335X_PHY1_WK_EN (1 << 8)
+
+static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on)
+{
+ struct am335x_control_usb *usb_ctrl;
+ u32 val;
+ u32 reg;
+
+ usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl);
+
+ switch (id) {
+ case 0:
+ reg = AM335X_PHY0_WK_EN;
+ break;
+ case 1:
+ reg = AM335X_PHY1_WK_EN;
+ break;
+ default:
+ WARN_ON(1);
+ return;
+ }
+
+ spin_lock(&usb_ctrl->lock);
+ val = readl(usb_ctrl->wkup);
+
+ if (on)
+ val |= reg;
+ else
+ val &= ~reg;
+
+ writel(val, usb_ctrl->wkup);
+ spin_unlock(&usb_ctrl->lock);
+}
+
static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
{
struct am335x_control_usb *usb_ctrl;
@@ -59,6 +94,7 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
static const struct phy_control ctrl_am335x = {
.phy_power = am335x_phy_power,
+ .phy_wkup = am335x_phy_wkup,
};
static const struct of_device_id omap_control_usb_id_table[] = {
@@ -117,6 +153,12 @@ static int am335x_control_usb_probe(struct platform_device *pdev)
ctrl_usb->phy_reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ctrl_usb->phy_reg))
return PTR_ERR(ctrl_usb->phy_reg);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wakeup");
+ ctrl_usb->wkup = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(ctrl_usb->wkup))
+ return PTR_ERR(ctrl_usb->wkup);
+
spin_lock_init(&ctrl_usb->lock);
ctrl_usb->phy_ctrl = *phy_ctrl;