summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/dwc3-omap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3/dwc3-omap.c')
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c155
1 files changed, 73 insertions, 82 deletions
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 08fffe6d1a9e..72cc92b3da02 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -37,11 +37,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/dwc3-omap.h>
#include <linux/dma-mapping.h>
#include <linux/ioport.h>
#include <linux/io.h>
@@ -74,8 +76,23 @@
/* SYSCONFIG REGISTER */
#define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16)
#define USBOTGSS_SYSCONFIG_STANDBYMODE(x) ((x) << 4)
+
+#define USBOTGSS_STANDBYMODE_FORCE_STANDBY 0
+#define USBOTGSS_STANDBYMODE_NO_STANDBY 1
+#define USBOTGSS_STANDBYMODE_SMART_STANDBY 2
+#define USBOTGSS_STANDBYMODE_SMART_WAKEUP 3
+
+#define USBOTGSS_STANDBYMODE_MASK (0x03 << 4)
+
#define USBOTGSS_SYSCONFIG_IDLEMODE(x) ((x) << 2)
+#define USBOTGSS_IDLEMODE_FORCE_IDLE 0
+#define USBOTGSS_IDLEMODE_NO_IDLE 1
+#define USBOTGSS_IDLEMODE_SMART_IDLE 2
+#define USBOTGSS_IDLEMODE_SMART_WAKEUP 3
+
+#define USBOTGSS_IDLEMODE_MASK (0x03 << 2)
+
/* IRQ_EOI REGISTER */
#define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0)
@@ -125,106 +142,51 @@ struct dwc3_omap {
u32 dma_status:1;
};
-#ifdef CONFIG_PM
-static int dwc3_omap_suspend(struct device *dev)
-{
- struct dwc3_omap *omap = dev_get_drvdata(dev);
-
- memcpy_fromio(omap->context, omap->base, omap->resource_size);
-
- return 0;
-}
-
-static int dwc3_omap_resume(struct device *dev)
-{
- struct dwc3_omap *omap = dev_get_drvdata(dev);
-
- memcpy_toio(omap->base, omap->context, omap->resource_size);
-
- return 0;
-}
-
-static int dwc3_omap_idle(struct device *dev)
-{
- struct dwc3_omap *omap = dev_get_drvdata(dev);
- u32 reg;
-
- /* stop DMA Engine */
- reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);
- reg &= ~(USBOTGSS_SYSCONFIG_DMADISABLE);
- dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg);
-
- return 0;
-}
-
-static UNIVERSAL_DEV_PM_OPS(dwc3_omap_pm_ops, dwc3_omap_suspend,
- dwc3_omap_resume, dwc3_omap_idle);
-
-#define DEV_PM_OPS (&dwc3_omap_pm_ops)
-#else
-#define DEV_PM_OPS NULL
-#endif
-
static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
{
struct dwc3_omap *omap = _omap;
u32 reg;
- u32 ctrl;
spin_lock(&omap->lock);
reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1);
- ctrl = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL);
if (reg & USBOTGSS_IRQ1_DMADISABLECLR) {
- dev_dbg(omap->base, "DMA Disable was Cleared\n");
+ dev_dbg(omap->dev, "DMA Disable was Cleared\n");
omap->dma_status = false;
}
if (reg & USBOTGSS_IRQ1_OEVT)
- dev_dbg(omap->base, "OTG Event\n");
+ dev_dbg(omap->dev, "OTG Event\n");
- if (reg & USBOTGSS_IRQ1_DRVVBUS_RISE) {
- dev_dbg(omap->base, "DRVVBUS Rise\n");
- ctrl |= USBOTGSS_UTMI_OTG_CTRL_DRVVBUS;
- }
+ if (reg & USBOTGSS_IRQ1_DRVVBUS_RISE)
+ dev_dbg(omap->dev, "DRVVBUS Rise\n");
- if (reg & USBOTGSS_IRQ1_CHRGVBUS_RISE) {
- dev_dbg(omap->base, "CHRGVBUS Rise\n");
- ctrl |= USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS;
- }
+ if (reg & USBOTGSS_IRQ1_CHRGVBUS_RISE)
+ dev_dbg(omap->dev, "CHRGVBUS Rise\n");
- if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_RISE) {
- dev_dbg(omap->base, "DISCHRGVBUS Rise\n");
- ctrl |= USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS;
- }
+ if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_RISE)
+ dev_dbg(omap->dev, "DISCHRGVBUS Rise\n");
- if (reg & USBOTGSS_IRQ1_IDPULLUP_RISE) {
- dev_dbg(omap->base, "IDPULLUP Rise\n");
- ctrl |= USBOTGSS_UTMI_OTG_CTRL_IDPULLUP;
- }
+ if (reg & USBOTGSS_IRQ1_IDPULLUP_RISE)
+ dev_dbg(omap->dev, "IDPULLUP Rise\n");
- if (reg & USBOTGSS_IRQ1_DRVVBUS_FALL) {
- dev_dbg(omap->base, "DRVVBUS Fall\n");
- ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_DRVVBUS;
- }
+ if (reg & USBOTGSS_IRQ1_DRVVBUS_FALL)
+ dev_dbg(omap->dev, "DRVVBUS Fall\n");
- if (reg & USBOTGSS_IRQ1_CHRGVBUS_FALL) {
- dev_dbg(omap->base, "CHRGVBUS Fall\n");
- ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS;
- }
+ if (reg & USBOTGSS_IRQ1_CHRGVBUS_FALL)
+ dev_dbg(omap->dev, "CHRGVBUS Fall\n");
- if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_FALL) {
- dev_dbg(omap->base, "DISCHRGVBUS Fall\n");
- ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS;
- }
+ if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_FALL)
+ dev_dbg(omap->dev, "DISCHRGVBUS Fall\n");
- if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL) {
- dev_dbg(omap->base, "IDPULLUP Fall\n");
- ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_IDPULLUP;
- }
+ if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL)
+ dev_dbg(omap->dev, "IDPULLUP Fall\n");
- dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL, ctrl);
+ dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg);
+
+ reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_0);
+ dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg);
spin_unlock(&omap->lock);
@@ -233,6 +195,7 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
static int __devinit dwc3_omap_probe(struct platform_device *pdev)
{
+ struct dwc3_omap_data *pdata = pdev->dev.platform_data;
struct platform_device *dwc3;
struct dwc3_omap *omap;
struct resource *res;
@@ -298,12 +261,41 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
omap->base = base;
omap->dwc3 = dwc3;
+ reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
+
+ if (!pdata) {
+ dev_dbg(&pdev->dev, "missing platform data\n");
+ } else {
+ switch (pdata->utmi_mode) {
+ case DWC3_OMAP_UTMI_MODE_SW:
+ reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+ break;
+ case DWC3_OMAP_UTMI_MODE_HW:
+ reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+ break;
+ default:
+ dev_dbg(&pdev->dev, "UNKNOWN utmi mode %d\n",
+ pdata->utmi_mode);
+ }
+ }
+
+ dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg);
+
/* check the DMA Status */
reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);
omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE);
+ /* Set No-Idle and No-Standby */
+ reg &= ~(USBOTGSS_STANDBYMODE_MASK
+ | USBOTGSS_IDLEMODE_MASK);
+
+ reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY)
+ | USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE));
+
+ dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg);
+
ret = request_irq(omap->irq, dwc3_omap_interrupt, 0,
- "dwc3-wrapper", omap);
+ "dwc3-omap", omap);
if (ret) {
dev_err(&pdev->dev, "failed to request IRQ #%d --> %d\n",
omap->irq, ret);
@@ -311,10 +303,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
}
/* enable all IRQs */
- dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, 0x01);
+ reg = USBOTGSS_IRQO_COREIRQ_ST;
+ dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg);
- reg = (USBOTGSS_IRQ1_DMADISABLECLR |
- USBOTGSS_IRQ1_OEVT |
+ reg = (USBOTGSS_IRQ1_OEVT |
USBOTGSS_IRQ1_DRVVBUS_RISE |
USBOTGSS_IRQ1_CHRGVBUS_RISE |
USBOTGSS_IRQ1_DISCHRGVBUS_RISE |
@@ -388,7 +380,6 @@ static struct platform_driver dwc3_omap_driver = {
.remove = __devexit_p(dwc3_omap_remove),
.driver = {
.name = "omap-dwc3",
- .pm = DEV_PM_OPS,
.of_match_table = of_dwc3_matach,
},
};