mfd: omap-usb-tll: serialize access to TLL device

Get rid of the unnecessary spin_lock_irqsave/restore() as there is
no interrupt handler for this driver. Instead we serialize access
to tll_dev using a global spinlock.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Roger Quadros 2012-11-26 16:56:26 +02:00
Родитель 7ed8619141
Коммит 6675144668
1 изменённых файлов: 27 добавлений и 26 удалений

Просмотреть файл

@ -103,14 +103,13 @@ struct usbtll_omap {
int nch; /* num. of channels */ int nch; /* num. of channels */
struct usbhs_omap_platform_data *pdata; struct usbhs_omap_platform_data *pdata;
struct clk **ch_clk; struct clk **ch_clk;
/* secure the register updates */
spinlock_t lock;
}; };
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static const char usbtll_driver_name[] = USBTLL_DRIVER_NAME; static const char usbtll_driver_name[] = USBTLL_DRIVER_NAME;
static struct device *tll_dev; static struct device *tll_dev;
static DEFINE_SPINLOCK(tll_lock); /* serialize access to tll_dev */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -212,7 +211,6 @@ static int usbtll_omap_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
struct usbtll_omap *tll; struct usbtll_omap *tll;
unsigned reg; unsigned reg;
unsigned long flags;
int ret = 0; int ret = 0;
int i, ver; int i, ver;
bool needs_tll; bool needs_tll;
@ -230,8 +228,6 @@ static int usbtll_omap_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
spin_lock_init(&tll->lock);
tll->pdata = pdata; tll->pdata = pdata;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -246,8 +242,6 @@ 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);
spin_lock_irqsave(&tll->lock, flags);
ver = usbtll_read(base, OMAP_USBTLL_REVISION); ver = usbtll_read(base, OMAP_USBTLL_REVISION);
switch (ver) { switch (ver) {
case OMAP_USBTLL_REV1: case OMAP_USBTLL_REV1:
@ -265,8 +259,6 @@ static int usbtll_omap_probe(struct platform_device *pdev)
break; break;
} }
spin_unlock_irqrestore(&tll->lock, flags);
tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]), tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
GFP_KERNEL); GFP_KERNEL);
if (!tll->ch_clk) { if (!tll->ch_clk) {
@ -286,8 +278,6 @@ 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);
} }
spin_lock_irqsave(&tll->lock, flags);
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]);
@ -332,10 +322,11 @@ static int usbtll_omap_probe(struct platform_device *pdev)
} }
} }
spin_unlock_irqrestore(&tll->lock, flags);
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
/* only after this can omap_tll_enable/disable work */ /* only after this can omap_tll_enable/disable work */
spin_lock(&tll_lock);
tll_dev = dev; tll_dev = dev;
spin_unlock(&tll_lock);
return 0; return 0;
@ -357,7 +348,9 @@ static int usbtll_omap_remove(struct platform_device *pdev)
struct usbtll_omap *tll = platform_get_drvdata(pdev); struct usbtll_omap *tll = platform_get_drvdata(pdev);
int i; int i;
spin_lock(&tll_lock);
tll_dev = NULL; tll_dev = NULL;
spin_unlock(&tll_lock);
for (i = 0; i < tll->nch; i++) for (i = 0; i < tll->nch; i++)
if (!IS_ERR(tll->ch_clk[i])) if (!IS_ERR(tll->ch_clk[i]))
@ -371,13 +364,10 @@ static int usbtll_runtime_resume(struct device *dev)
{ {
struct usbtll_omap *tll = dev_get_drvdata(dev); struct usbtll_omap *tll = dev_get_drvdata(dev);
struct usbhs_omap_platform_data *pdata = tll->pdata; struct usbhs_omap_platform_data *pdata = tll->pdata;
unsigned long flags;
int i; int i;
dev_dbg(dev, "usbtll_runtime_resume\n"); dev_dbg(dev, "usbtll_runtime_resume\n");
spin_lock_irqsave(&tll->lock, flags);
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])) {
int r; int r;
@ -393,8 +383,6 @@ static int usbtll_runtime_resume(struct device *dev)
} }
} }
spin_unlock_irqrestore(&tll->lock, flags);
return 0; return 0;
} }
@ -402,13 +390,10 @@ static int usbtll_runtime_suspend(struct device *dev)
{ {
struct usbtll_omap *tll = dev_get_drvdata(dev); struct usbtll_omap *tll = dev_get_drvdata(dev);
struct usbhs_omap_platform_data *pdata = tll->pdata; struct usbhs_omap_platform_data *pdata = tll->pdata;
unsigned long flags;
int i; int i;
dev_dbg(dev, "usbtll_runtime_suspend\n"); dev_dbg(dev, "usbtll_runtime_suspend\n");
spin_lock_irqsave(&tll->lock, flags);
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])) {
if (!IS_ERR(tll->ch_clk[i])) if (!IS_ERR(tll->ch_clk[i]))
@ -416,8 +401,6 @@ static int usbtll_runtime_suspend(struct device *dev)
} }
} }
spin_unlock_irqrestore(&tll->lock, flags);
return 0; return 0;
} }
@ -439,21 +422,39 @@ static struct platform_driver usbtll_omap_driver = {
int omap_tll_enable(void) int omap_tll_enable(void)
{ {
int ret;
spin_lock(&tll_lock);
if (!tll_dev) { if (!tll_dev) {
pr_err("%s: OMAP USB TLL not initialized\n", __func__); pr_err("%s: OMAP USB TLL not initialized\n", __func__);
return -ENODEV; ret = -ENODEV;
} else {
ret = pm_runtime_get_sync(tll_dev);
} }
return pm_runtime_get_sync(tll_dev);
spin_unlock(&tll_lock);
return ret;
} }
EXPORT_SYMBOL_GPL(omap_tll_enable); EXPORT_SYMBOL_GPL(omap_tll_enable);
int omap_tll_disable(void) int omap_tll_disable(void)
{ {
int ret;
spin_lock(&tll_lock);
if (!tll_dev) { if (!tll_dev) {
pr_err("%s: OMAP USB TLL not initialized\n", __func__); pr_err("%s: OMAP USB TLL not initialized\n", __func__);
return -ENODEV; ret = -ENODEV;
} else {
ret = pm_runtime_put_sync(tll_dev);
} }
return pm_runtime_put_sync(tll_dev);
spin_unlock(&tll_lock);
return ret;
} }
EXPORT_SYMBOL_GPL(omap_tll_disable); EXPORT_SYMBOL_GPL(omap_tll_disable);