forked from Minki/linux
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: Roger Quadros <rogerq@ti.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
662e469e91
commit
9f4a3ece05
@ -278,7 +278,7 @@ static int usbhs_runtime_resume(struct device *dev)
|
||||
|
||||
dev_dbg(dev, "usbhs_runtime_resume\n");
|
||||
|
||||
omap_tll_enable();
|
||||
omap_tll_enable(pdata);
|
||||
|
||||
if (!IS_ERR(omap->ehci_logic_fck))
|
||||
clk_enable(omap->ehci_logic_fck);
|
||||
@ -353,7 +353,7 @@ static int usbhs_runtime_suspend(struct device *dev)
|
||||
if (!IS_ERR(omap->ehci_logic_fck))
|
||||
clk_disable(omap->ehci_logic_fck);
|
||||
|
||||
omap_tll_disable();
|
||||
omap_tll_disable(pdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -527,6 +527,9 @@ static int usbhs_omap_probe(struct platform_device *pdev)
|
||||
|
||||
omap->pdata = pdata;
|
||||
|
||||
/* Initialize the TLL subsystem */
|
||||
omap_tll_init(pdata);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
platform_set_drvdata(pdev, omap);
|
||||
|
@ -1,8 +1,9 @@
|
||||
/**
|
||||
* 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: Roger Quadros <rogerq@ti.com>
|
||||
*
|
||||
* 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
|
||||
@ -105,8 +106,8 @@
|
||||
|
||||
struct usbtll_omap {
|
||||
int nch; /* num. of channels */
|
||||
struct usbhs_omap_platform_data *pdata;
|
||||
struct clk **ch_clk;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -210,14 +211,10 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
|
||||
static int usbtll_omap_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct usbhs_omap_platform_data *pdata = dev->platform_data;
|
||||
void __iomem *base;
|
||||
struct resource *res;
|
||||
struct usbtll_omap *tll;
|
||||
unsigned reg;
|
||||
int ret = 0;
|
||||
int i, ver;
|
||||
bool needs_tll;
|
||||
|
||||
dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
|
||||
|
||||
@ -227,16 +224,9 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(dev, "Platform data missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
tll->pdata = pdata;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_request_and_ioremap(dev, res);
|
||||
if (!base) {
|
||||
tll->base = devm_request_and_ioremap(dev, res);
|
||||
if (!tll->base) {
|
||||
ret = -EADDRNOTAVAIL;
|
||||
dev_err(dev, "Resource request/ioremap failed:%d\n", ret);
|
||||
return ret;
|
||||
@ -246,7 +236,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
ver = usbtll_read(base, OMAP_USBTLL_REVISION);
|
||||
ver = usbtll_read(tll->base, OMAP_USBTLL_REVISION);
|
||||
switch (ver) {
|
||||
case OMAP_USBTLL_REV1:
|
||||
case OMAP_USBTLL_REV4:
|
||||
@ -283,11 +273,77 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
||||
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;
|
||||
for (i = 0; i < tll->nch; i++)
|
||||
needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]);
|
||||
|
||||
pm_runtime_get_sync(tll_dev);
|
||||
|
||||
if (needs_tll) {
|
||||
void __iomem *base = tll->base;
|
||||
|
||||
/* Program Common TLL register */
|
||||
reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
|
||||
@ -336,51 +392,29 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
/* only after this can omap_tll_enable/disable work */
|
||||
spin_lock(&tll_lock);
|
||||
tll_dev = dev;
|
||||
pm_runtime_put_sync(tll_dev);
|
||||
|
||||
spin_unlock(&tll_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_alloc:
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_tll_init);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
|
||||
{
|
||||
struct usbtll_omap *tll = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
struct usbtll_omap *tll;
|
||||
|
||||
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]);
|
||||
if (!tll_dev) {
|
||||
spin_unlock(&tll_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
tll = dev_get_drvdata(tll_dev);
|
||||
|
||||
static int usbtll_runtime_resume(struct device *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++) {
|
||||
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
|
||||
@ -391,22 +425,31 @@ static int usbtll_runtime_resume(struct device *dev)
|
||||
|
||||
r = clk_enable(tll->ch_clk[i]);
|
||||
if (r) {
|
||||
dev_err(dev,
|
||||
dev_err(tll_dev,
|
||||
"Error enabling ch %d clock: %d\n", i, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&tll_lock);
|
||||
|
||||
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;
|
||||
struct usbtll_omap *tll;
|
||||
|
||||
dev_dbg(dev, "usbtll_runtime_suspend\n");
|
||||
spin_lock(&tll_lock);
|
||||
|
||||
if (!tll_dev) {
|
||||
spin_unlock(&tll_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
tll = dev_get_drvdata(tll_dev);
|
||||
|
||||
for (i = 0; i < tll->nch; i++) {
|
||||
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
|
||||
@ -415,61 +458,12 @@ static int usbtll_runtime_suspend(struct device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(tll_dev);
|
||||
|
||||
spin_unlock(&tll_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
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);
|
||||
|
||||
MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
|
||||
|
@ -1,2 +1,3 @@
|
||||
extern int omap_tll_enable(void);
|
||||
extern int omap_tll_disable(void);
|
||||
extern int omap_tll_init(struct usbhs_omap_platform_data *pdata);
|
||||
extern int omap_tll_enable(struct usbhs_omap_platform_data *pdata);
|
||||
extern int omap_tll_disable(struct usbhs_omap_platform_data *pdata);
|
||||
|
Loading…
Reference in New Issue
Block a user