diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2013-08-19 06:39:44 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-10-01 10:31:11 -0400 |
commit | a12226394e7d19734d129766676a5668efd50d5c (patch) | |
tree | 29e62ed87e7641b9f2d210c661fd7b622fae171a /drivers/usb/phy/phy-am335x-control.c | |
parent | 4d175f340c9c055482688d2205038413dc7b6f1e (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.c | 42 |
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 | |||
32 | static 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 | |||
29 | static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) | 64 | static 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 | ||
60 | static const struct phy_control ctrl_am335x = { | 95 | static 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 | ||
64 | static const struct of_device_id omap_control_usb_id_table[] = { | 100 | 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) | |||
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 | ||