Commit 9f4a3ece authored by Roger Quadros's avatar Roger Quadros Committed by Samuel Ortiz

mfd: omap-usb-tll: Move configuration code to omap_tll_init()

This is because we want to get rid of platform_data usage from probe().
The only information we need is PORT_MODE, and this can be supplied
to us by the user (i.e. omap-usb-host.c).

We also move channel clock management from runtime PM handlers into
omap_tll_enable/disable().
Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 662e469e
...@@ -278,7 +278,7 @@ static int usbhs_runtime_resume(struct device *dev) ...@@ -278,7 +278,7 @@ static int usbhs_runtime_resume(struct device *dev)
dev_dbg(dev, "usbhs_runtime_resume\n"); dev_dbg(dev, "usbhs_runtime_resume\n");
omap_tll_enable(); omap_tll_enable(pdata);
if (!IS_ERR(omap->ehci_logic_fck)) if (!IS_ERR(omap->ehci_logic_fck))
clk_enable(omap->ehci_logic_fck); clk_enable(omap->ehci_logic_fck);
...@@ -353,7 +353,7 @@ static int usbhs_runtime_suspend(struct device *dev) ...@@ -353,7 +353,7 @@ static int usbhs_runtime_suspend(struct device *dev)
if (!IS_ERR(omap->ehci_logic_fck)) if (!IS_ERR(omap->ehci_logic_fck))
clk_disable(omap->ehci_logic_fck); clk_disable(omap->ehci_logic_fck);
omap_tll_disable(); omap_tll_disable(pdata);
return 0; return 0;
} }
...@@ -527,6 +527,9 @@ static int usbhs_omap_probe(struct platform_device *pdev) ...@@ -527,6 +527,9 @@ static int usbhs_omap_probe(struct platform_device *pdev)
omap->pdata = pdata; omap->pdata = pdata;
/* Initialize the TLL subsystem */
omap_tll_init(pdata);
pm_runtime_enable(dev); pm_runtime_enable(dev);
platform_set_drvdata(pdev, omap); platform_set_drvdata(pdev, omap);
......
/** /**
* omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI
* *
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com * Copyright (C) 2012-2013 Texas Instruments Incorporated - http://www.ti.com
* Author: Keshava Munegowda <keshava_mgowda@ti.com> * Author: Keshava Munegowda <keshava_mgowda@ti.com>
* Author: Roger Quadros <rogerq@ti.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 of * it under the terms of the GNU General Public License version 2 of
...@@ -105,8 +106,8 @@ ...@@ -105,8 +106,8 @@
struct usbtll_omap { struct usbtll_omap {
int nch; /* num. of channels */ int nch; /* num. of channels */
struct usbhs_omap_platform_data *pdata;
struct clk **ch_clk; struct clk **ch_clk;
void __iomem *base;
}; };
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -210,14 +211,10 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) ...@@ -210,14 +211,10 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
static int usbtll_omap_probe(struct platform_device *pdev) static int usbtll_omap_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct usbhs_omap_platform_data *pdata = dev->platform_data;
void __iomem *base;
struct resource *res; struct resource *res;
struct usbtll_omap *tll; struct usbtll_omap *tll;
unsigned reg;
int ret = 0; int ret = 0;
int i, ver; int i, ver;
bool needs_tll;
dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
...@@ -227,16 +224,9 @@ static int usbtll_omap_probe(struct platform_device *pdev) ...@@ -227,16 +224,9 @@ static int usbtll_omap_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
if (!pdata) {
dev_err(dev, "Platform data missing\n");
return -ENODEV;
}
tll->pdata = pdata;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_request_and_ioremap(dev, res); tll->base = devm_request_and_ioremap(dev, res);
if (!base) { if (!tll->base) {
ret = -EADDRNOTAVAIL; ret = -EADDRNOTAVAIL;
dev_err(dev, "Resource request/ioremap failed:%d\n", ret); dev_err(dev, "Resource request/ioremap failed:%d\n", ret);
return ret; return ret;
...@@ -246,7 +236,7 @@ static int usbtll_omap_probe(struct platform_device *pdev) ...@@ -246,7 +236,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
pm_runtime_enable(dev); pm_runtime_enable(dev);
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
ver = usbtll_read(base, OMAP_USBTLL_REVISION); ver = usbtll_read(tll->base, OMAP_USBTLL_REVISION);
switch (ver) { switch (ver) {
case OMAP_USBTLL_REV1: case OMAP_USBTLL_REV1:
case OMAP_USBTLL_REV4: case OMAP_USBTLL_REV4:
...@@ -283,11 +273,77 @@ static int usbtll_omap_probe(struct platform_device *pdev) ...@@ -283,11 +273,77 @@ static int usbtll_omap_probe(struct platform_device *pdev)
dev_dbg(dev, "can't get clock : %s\n", clkname); dev_dbg(dev, "can't get clock : %s\n", clkname);
} }
pm_runtime_put_sync(dev);
/* only after this can omap_tll_enable/disable work */
spin_lock(&tll_lock);
tll_dev = dev;
spin_unlock(&tll_lock);
return 0;
err_clk_alloc:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
return ret;
}
/**
* usbtll_omap_remove - shutdown processing for UHH & TLL HCDs
* @pdev: USB Host Controller being removed
*
* Reverses the effect of usbtll_omap_probe().
*/
static int usbtll_omap_remove(struct platform_device *pdev)
{
struct usbtll_omap *tll = platform_get_drvdata(pdev);
int i;
spin_lock(&tll_lock);
tll_dev = NULL;
spin_unlock(&tll_lock);
for (i = 0; i < tll->nch; i++)
if (!IS_ERR(tll->ch_clk[i]))
clk_put(tll->ch_clk[i]);
pm_runtime_disable(&pdev->dev);
return 0;
}
static struct platform_driver usbtll_omap_driver = {
.driver = {
.name = (char *)usbtll_driver_name,
.owner = THIS_MODULE,
},
.probe = usbtll_omap_probe,
.remove = usbtll_omap_remove,
};
int omap_tll_init(struct usbhs_omap_platform_data *pdata)
{
int i;
bool needs_tll;
unsigned reg;
struct usbtll_omap *tll;
spin_lock(&tll_lock);
if (!tll_dev) {
spin_unlock(&tll_lock);
return -ENODEV;
}
tll = dev_get_drvdata(tll_dev);
needs_tll = false; needs_tll = false;
for (i = 0; i < tll->nch; i++) for (i = 0; i < tll->nch; i++)
needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]); needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]);
pm_runtime_get_sync(tll_dev);
if (needs_tll) { if (needs_tll) {
void __iomem *base = tll->base;
/* Program Common TLL register */ /* Program Common TLL register */
reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
...@@ -336,51 +392,29 @@ static int usbtll_omap_probe(struct platform_device *pdev) ...@@ -336,51 +392,29 @@ static int usbtll_omap_probe(struct platform_device *pdev)
} }
} }
pm_runtime_put_sync(dev); pm_runtime_put_sync(tll_dev);
/* only after this can omap_tll_enable/disable work */
spin_lock(&tll_lock);
tll_dev = dev;
spin_unlock(&tll_lock); spin_unlock(&tll_lock);
return 0; return 0;
err_clk_alloc:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
return ret;
} }
EXPORT_SYMBOL_GPL(omap_tll_init);
/** int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
* usbtll_omap_remove - shutdown processing for UHH & TLL HCDs
* @pdev: USB Host Controller being removed
*
* Reverses the effect of usbtll_omap_probe().
*/
static int usbtll_omap_remove(struct platform_device *pdev)
{ {
struct usbtll_omap *tll = platform_get_drvdata(pdev);
int i; int i;
struct usbtll_omap *tll;
spin_lock(&tll_lock); spin_lock(&tll_lock);
tll_dev = NULL;
spin_unlock(&tll_lock);
for (i = 0; i < tll->nch; i++)
if (!IS_ERR(tll->ch_clk[i]))
clk_put(tll->ch_clk[i]);
pm_runtime_disable(&pdev->dev); if (!tll_dev) {
return 0; spin_unlock(&tll_lock);
} return -ENODEV;
}
static int usbtll_runtime_resume(struct device *dev) tll = dev_get_drvdata(tll_dev);
{
struct usbtll_omap *tll = dev_get_drvdata(dev);
struct usbhs_omap_platform_data *pdata = tll->pdata;
int i;
dev_dbg(dev, "usbtll_runtime_resume\n"); pm_runtime_get_sync(tll_dev);
for (i = 0; i < tll->nch; i++) { for (i = 0; i < tll->nch; i++) {
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
...@@ -391,22 +425,31 @@ static int usbtll_runtime_resume(struct device *dev) ...@@ -391,22 +425,31 @@ static int usbtll_runtime_resume(struct device *dev)
r = clk_enable(tll->ch_clk[i]); r = clk_enable(tll->ch_clk[i]);
if (r) { if (r) {
dev_err(dev, dev_err(tll_dev,
"Error enabling ch %d clock: %d\n", i, r); "Error enabling ch %d clock: %d\n", i, r);
} }
} }
} }
spin_unlock(&tll_lock);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(omap_tll_enable);
static int usbtll_runtime_suspend(struct device *dev) int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
{ {
struct usbtll_omap *tll = dev_get_drvdata(dev);
struct usbhs_omap_platform_data *pdata = tll->pdata;
int i; int i;
struct usbtll_omap *tll;
spin_lock(&tll_lock);
if (!tll_dev) {
spin_unlock(&tll_lock);
return -ENODEV;
}
dev_dbg(dev, "usbtll_runtime_suspend\n"); tll = dev_get_drvdata(tll_dev);
for (i = 0; i < tll->nch; i++) { for (i = 0; i < tll->nch; i++) {
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
...@@ -415,60 +458,11 @@ static int usbtll_runtime_suspend(struct device *dev) ...@@ -415,60 +458,11 @@ static int usbtll_runtime_suspend(struct device *dev)
} }
} }
return 0; pm_runtime_put_sync(tll_dev);
}
static const struct dev_pm_ops usbtllomap_dev_pm_ops = {
SET_RUNTIME_PM_OPS(usbtll_runtime_suspend,
usbtll_runtime_resume,
NULL)
};
static struct platform_driver usbtll_omap_driver = {
.driver = {
.name = (char *)usbtll_driver_name,
.owner = THIS_MODULE,
.pm = &usbtllomap_dev_pm_ops,
},
.probe = usbtll_omap_probe,
.remove = usbtll_omap_remove,
};
int omap_tll_enable(void)
{
int ret;
spin_lock(&tll_lock);
if (!tll_dev) {
pr_err("%s: OMAP USB TLL not initialized\n", __func__);
ret = -ENODEV;
} else {
ret = pm_runtime_get_sync(tll_dev);
}
spin_unlock(&tll_lock); spin_unlock(&tll_lock);
return ret; return 0;
}
EXPORT_SYMBOL_GPL(omap_tll_enable);
int omap_tll_disable(void)
{
int ret;
spin_lock(&tll_lock);
if (!tll_dev) {
pr_err("%s: OMAP USB TLL not initialized\n", __func__);
ret = -ENODEV;
} else {
ret = pm_runtime_put_sync(tll_dev);
}
spin_unlock(&tll_lock);
return ret;
} }
EXPORT_SYMBOL_GPL(omap_tll_disable); EXPORT_SYMBOL_GPL(omap_tll_disable);
......
extern int omap_tll_enable(void); extern int omap_tll_init(struct usbhs_omap_platform_data *pdata);
extern int omap_tll_disable(void); extern int omap_tll_enable(struct usbhs_omap_platform_data *pdata);
extern int omap_tll_disable(struct usbhs_omap_platform_data *pdata);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment