aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy-am335x-control.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-08-19 06:39:44 -0400
committerFelipe Balbi <balbi@ti.com>2013-10-01 10:31:11 -0400
commita12226394e7d19734d129766676a5668efd50d5c (patch)
tree29e62ed87e7641b9f2d210c661fd7b622fae171a /drivers/usb/phy/phy-am335x-control.c
parent4d175f340c9c055482688d2205038413dc7b6f1e (diff)
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 {
26#define USBPHY_OTGVDET_EN (1 << 19) 26#define USBPHY_OTGVDET_EN (1 << 19)
27#define USBPHY_OTGSESSEND_EN (1 << 20) 27#define USBPHY_OTGSESSEND_EN (1 << 20)
28 28
29#define AM335X_PHY0_WK_EN (1 << 0)
30#define AM335X_PHY1_WK_EN (1 << 8)
31
32static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on)
33{
34 struct am335x_control_usb *usb_ctrl;
35 u32 val;
36 u32 reg;
37
38 usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl);
39
40 switch (id) {
41 case 0:
42 reg = AM335X_PHY0_WK_EN;
43 break;
44 case 1:
45 reg = AM335X_PHY1_WK_EN;
46 break;
47 default:
48 WARN_ON(1);
49 return;
50 }
51
52 spin_lock(&usb_ctrl->lock);
53 val = readl(usb_ctrl->wkup);
54
55 if (on)
56 val |= reg;
57 else
58 val &= ~reg;
59
60 writel(val, usb_ctrl->wkup);
61 spin_unlock(&usb_ctrl->lock);
62}
63
29static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) 64static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
30{ 65{
31 struct am335x_control_usb *usb_ctrl; 66 struct am335x_control_usb *usb_ctrl;
@@ -59,6 +94,7 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
59 94
60static const struct phy_control ctrl_am335x = { 95static const struct phy_control ctrl_am335x = {
61 .phy_power = am335x_phy_power, 96 .phy_power = am335x_phy_power,
97 .phy_wkup = am335x_phy_wkup,
62}; 98};
63 99
64static const struct of_device_id omap_control_usb_id_table[] = { 100static const struct of_device_id omap_control_usb_id_table[] = {
@@ -117,6 +153,12 @@ static int am335x_control_usb_probe(struct platform_device *pdev)
117 ctrl_usb->phy_reg = devm_ioremap_resource(&pdev->dev, res); 153 ctrl_usb->phy_reg = devm_ioremap_resource(&pdev->dev, res);
118 if (IS_ERR(ctrl_usb->phy_reg)) 154 if (IS_ERR(ctrl_usb->phy_reg))
119 return PTR_ERR(ctrl_usb->phy_reg); 155 return PTR_ERR(ctrl_usb->phy_reg);
156
157 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wakeup");
158 ctrl_usb->wkup = devm_ioremap_resource(&pdev->dev, res);
159 if (IS_ERR(ctrl_usb->wkup))
160 return PTR_ERR(ctrl_usb->wkup);
161
120 spin_lock_init(&ctrl_usb->lock); 162 spin_lock_init(&ctrl_usb->lock);
121 ctrl_usb->phy_ctrl = *phy_ctrl; 163 ctrl_usb->phy_ctrl = *phy_ctrl;
122 164