From: Ravi Babu <ravibabu@ti.com>
To: linux-usb@vger.kernel.org
Cc: linux-omap@vger.kernel.org, balbi@ti.com,
grant.likely@secretlab.ca, devicetree-discuss@lists.ozlabs.org,
tony@atomide.com, ajayguptaj@gmail.com
Subject: [PATCH v7 03/11] usb: musb: am335x: add support for dual instance
Date: Thu, 2 Aug 2012 17:42:46 +0530 [thread overview]
Message-ID: <1343909574-15633-4-git-send-email-ravibabu@ti.com> (raw)
In-Reply-To: <1343909574-15633-1-git-send-email-ravibabu@ti.com>
From: Ajay Kumar Gupta <ajay.gupta@ti.com>
AM335x and TI81xx platform has dual musb controller so updating the
musb_dspc.c to support the same.
Changes:
- Moved otg_workaround timer to glue structure
- Moved static local variable last_timer to glue structure
- PHY on/off related cleanups
Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
Signed-off-by: Ravi Babu <ravibabu@ti.com>
---
drivers/usb/musb/musb_dsps.c | 113 +++++++++++++++++++++++++-----------------
1 files changed, 67 insertions(+), 46 deletions(-)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 2174699..7a09d55 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -105,6 +105,8 @@ struct dsps_musb_wrapper {
/* miscellaneous stuff */
u32 musb_core_offset;
u8 poll_seconds;
+ /* number of musb instances */
+ u8 instances;
};
/**
@@ -112,16 +114,18 @@ struct dsps_musb_wrapper {
*/
struct dsps_glue {
struct device *dev;
- struct platform_device *musb; /* child musb pdev */
+ struct platform_device *musb[2]; /* child musb pdev */
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
- struct timer_list timer; /* otg_workaround timer */
- u32 __iomem *usb_ctrl;
+ struct timer_list timer[2]; /* otg_workaround timer */
+ unsigned long last_timer[2]; /* last timer data for each instance */
+ u32 __iomem *usb_ctrl[2];
u8 usbss_rev;
};
/**
* musb_dsps_phy_control - phy on/off
* @glue: struct dsps_glue *
+ * @id: musb instance
* @on: flag for phy to be switched on or off
*
* This is to enable the PHY using usb_ctrl register in system control
@@ -130,11 +134,11 @@ struct dsps_glue {
* XXX: This function will be removed once we have a seperate driver for
* control module
*/
-static void musb_dsps_phy_control(struct dsps_glue *glue, u8 on)
+static void musb_dsps_phy_control(struct dsps_glue *glue, u8 id, u8 on)
{
u32 usbphycfg;
- usbphycfg = __raw_readl(glue->usb_ctrl);
+ usbphycfg = __raw_readl(glue->usb_ctrl[id]);
if (on) {
if (glue->usbss_rev == MUSB_USBSS_REV_816X) {
@@ -157,7 +161,7 @@ static void musb_dsps_phy_control(struct dsps_glue *glue, u8 on)
glue->usbss_rev == MUSB_USBSS_REV_33XX)
usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
}
- __raw_writel(usbphycfg, glue->usb_ctrl);
+ __raw_writel(usbphycfg, glue->usb_ctrl[id]);
}
/**
* dsps_musb_enable - enable interrupts
@@ -207,8 +211,8 @@ static void otg_timer(unsigned long _musb)
struct musb *musb = (void *)_musb;
void __iomem *mregs = musb->mregs;
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
u8 devctl;
unsigned long flags;
@@ -247,7 +251,7 @@ static void otg_timer(unsigned long _musb)
devctl = dsps_readb(mregs, MUSB_DEVCTL);
if (devctl & MUSB_DEVCTL_BDEVICE)
- mod_timer(&glue->timer,
+ mod_timer(&glue->timer[pdev->id],
jiffies + wrp->poll_seconds * HZ);
else
musb->xceiv->state = OTG_STATE_A_IDLE;
@@ -261,9 +265,8 @@ static void otg_timer(unsigned long _musb)
static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
{
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
- static unsigned long last_timer;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
if (!is_otg_enabled(musb))
return;
@@ -276,22 +279,23 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
dev_dbg(musb->controller, "%s active, deleting timer\n",
otg_state_string(musb->xceiv->state));
- del_timer(&glue->timer);
- last_timer = jiffies;
+ del_timer(&glue->timer[pdev->id]);
+ glue->last_timer[pdev->id] = jiffies;
return;
}
- if (time_after(last_timer, timeout) && timer_pending(&glue->timer)) {
+ if (time_after(glue->last_timer[pdev->id], timeout) &&
+ timer_pending(&glue->timer[pdev->id])) {
dev_dbg(musb->controller,
"Longer idle timer already pending, ignoring...\n");
return;
}
- last_timer = timeout;
+ glue->last_timer[pdev->id] = timeout;
dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
otg_state_string(musb->xceiv->state),
jiffies_to_msecs(timeout - jiffies));
- mod_timer(&glue->timer, timeout);
+ mod_timer(&glue->timer[pdev->id], timeout);
}
static irqreturn_t dsps_interrupt(int irq, void *hci)
@@ -299,8 +303,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
struct musb *musb = hci;
void __iomem *reg_base = musb->ctrl_base;
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
unsigned long flags;
irqreturn_t ret = IRQ_NONE;
@@ -360,7 +364,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
*/
musb->int_usb &= ~MUSB_INTR_VBUSERROR;
musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
- mod_timer(&glue->timer,
+ mod_timer(&glue->timer[pdev->id],
jiffies + wrp->poll_seconds * HZ);
WARNING("VBUS error workaround (delay coming)\n");
} else if (is_host_enabled(musb) && drvvbus) {
@@ -368,7 +372,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
MUSB_HST_MODE(musb);
musb->xceiv->otg->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
- del_timer(&glue->timer);
+ del_timer(&glue->timer[pdev->id]);
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
@@ -395,7 +399,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
/* Poll for ID change */
if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
- mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+ mod_timer(&glue->timer[pdev->id],
+ jiffies + wrp->poll_seconds * HZ);
spin_unlock_irqrestore(&musb->lock, flags);
@@ -405,8 +410,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
static int dsps_musb_init(struct musb *musb)
{
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
void __iomem *reg_base = musb->ctrl_base;
u32 rev, val;
@@ -429,13 +434,14 @@ static int dsps_musb_init(struct musb *musb)
}
if (is_host_enabled(musb))
- setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
+ setup_timer(&glue->timer[pdev->id], otg_timer,
+ (unsigned long) musb);
/* Reset the musb */
dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
/* Start the on-chip PHY and its PLL. */
- musb_dsps_phy_control(glue, 1);
+ musb_dsps_phy_control(glue, pdev->id, 1);
musb->isr = dsps_interrupt;
@@ -457,14 +463,14 @@ err0:
static int dsps_musb_exit(struct musb *musb)
{
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
if (is_host_enabled(musb))
- del_timer_sync(&glue->timer);
+ del_timer_sync(&glue->timer[pdev->id]);
/* Shutdown the on-chip PHY and its PLL. */
- musb_dsps_phy_control(glue, 0);
+ musb_dsps_phy_control(glue, pdev->id, 0);
/* NOP driver needs change if supporting dual instance */
usb_put_phy(musb->xceiv);
@@ -504,8 +510,8 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
goto err0;
}
- glue->usb_ctrl = devm_request_and_ioremap(&pdev->dev, res);
- if (glue->usb_ctrl == NULL) {
+ glue->usb_ctrl[id] = devm_request_and_ioremap(&pdev->dev, res);
+ if (glue->usb_ctrl[id] == NULL) {
dev_err(dev, "Failed to obtain usb_ctrl%d memory\n", id);
ret = -ENODEV;
goto err0;
@@ -554,7 +560,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
musb->dev.dma_mask = &musb_dmamask;
musb->dev.coherent_dma_mask = musb_dmamask;
- glue->musb = musb;
+ glue->musb[id] = musb;
pdata->platform_ops = &dsps_ops;
@@ -586,11 +592,11 @@ err0:
return ret;
}
-static void __devexit dsps_delete_musb_pdev(struct dsps_glue *glue)
+static void __devexit dsps_delete_musb_pdev(struct dsps_glue *glue, u8 id)
{
- musb_put_id(glue->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ musb_put_id(glue->dev, glue->musb[id]->id);
+ platform_device_del(glue->musb[id]);
+ platform_device_put(glue->musb[id]);
}
static int __devinit dsps_probe(struct platform_device *pdev)
@@ -601,7 +607,7 @@ static int __devinit dsps_probe(struct platform_device *pdev)
struct dsps_glue *glue;
struct resource *iomem;
u32 __iomem *usbss;
- int ret;
+ int ret, i;
/* allocate glue */
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
@@ -645,11 +651,16 @@ static int __devinit dsps_probe(struct platform_device *pdev)
goto err2;
}
- /* create the child platform device for first instances of musb */
- ret = dsps_create_musb_pdev(glue, 0);
- if (ret != 0) {
- dev_err(&pdev->dev, "failed to create child pdev\n");
- goto err3;
+ /* create the child platform device for all instances of musb */
+ for (i = 0; i < wrp->instances ; i++) {
+ ret = dsps_create_musb_pdev(glue, i);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to create child pdev\n");
+ /* release resources of previously created instances */
+ for (i--; i >= 0 ; i--)
+ dsps_delete_musb_pdev(glue, i);
+ goto err3;
+ }
}
/* read the usbss revision register */
@@ -670,9 +681,12 @@ err0:
static int __devexit dsps_remove(struct platform_device *pdev)
{
struct dsps_glue *glue = platform_get_drvdata(pdev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ int i;
/* delete the child platform device */
- dsps_delete_musb_pdev(glue);
+ for (i = 0; i < wrp->instances ; i++)
+ dsps_delete_musb_pdev(glue, i);
/* disable usbss clocks */
pm_runtime_put(&pdev->dev);
@@ -687,9 +701,12 @@ static int dsps_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev->parent);
struct dsps_glue *glue = platform_get_drvdata(pdev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ int i;
/* Shutdown the on-chip PHY and its PLL. */
- musb_dsps_phy_control(glue, 0);
+ for (i = 0 ; i < wrp->instances ; i++)
+ musb_dsps_phy_control(glue, i, 0);
return 0;
}
@@ -698,9 +715,12 @@ static int dsps_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev->parent);
struct dsps_glue *glue = platform_get_drvdata(pdev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ int i;
/* Start the on-chip PHY and its PLL. */
- musb_dsps_phy_control(glue, 1);
+ for (i = 0 ; i < wrp->instances ; i++)
+ musb_dsps_phy_control(glue, i, 1);
return 0;
}
@@ -736,6 +756,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
.rxep_bitmap = (0xfffe << 16),
.musb_core_offset = 0x400,
.poll_seconds = 2,
+ .instances = 2,
};
static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
--
1.7.0.4
next prev parent reply other threads:[~2012-08-02 12:13 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-02 12:12 [PATCH v7 00/11] usb: musb: adding multi instance support Ravi Babu
2012-08-02 12:12 ` Ravi Babu [this message]
2012-08-02 12:12 ` [PATCH v7 04/11] usb: otg: nop: add support for multiple tranceiver Ravi Babu
2012-08-02 12:12 ` [PATCH v7 07/11] usb: otg: nop: add dt support Ravi Babu
[not found] ` <1343909574-15633-1-git-send-email-ravibabu-l0cyMroinI0@public.gmane.org>
2012-08-02 12:12 ` [PATCH v7 01/11] usb: musb: add musb_ida for multi instance support Ravi Babu
2012-08-02 12:12 ` [PATCH v7 02/11] usb: musb: kill global and static for multi instance Ravi Babu
2012-08-02 12:12 ` [PATCH v7 05/11] usb: musb: dsps: add dt support Ravi Babu
2012-08-02 12:12 ` [PATCH v7 06/11] arm/dts: am33xx: Add dt data for usbss Ravi Babu
2012-08-02 12:12 ` [PATCH v7 08/11] arm/dts: am33xx: add dt data for usb nop phy Ravi Babu
2012-08-02 12:12 ` [PATCH v7 09/11] usb: musb: dsps: remove explicit NOP device creation Ravi Babu
2012-08-02 12:12 ` [PATCH v7 10/11] usb: musb: dsps: get the PHY using phandle api Ravi Babu
2012-08-02 22:08 ` [PATCH v7 00/11] usb: musb: adding multi instance support Daniel Mack
[not found] ` <501AFA6B.4010005-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-08-03 0:54 ` B, Ravi
[not found] ` <6C6B28D4DC342643927BEAFCE8707BF63E9DB6AE-Er742YJ7I/eIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2012-08-03 8:19 ` Daniel Mack
2012-08-03 8:43 ` Ajay Gupta
[not found] ` <F20D4CDD972CFA4D89D3A083D2D561967FF1F67DE3-kdsAE/FnitNDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-08-03 8:53 ` B, Ravi
2012-08-03 9:02 ` Daniel Mack
[not found] ` <501B93AB.7050501-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-08-03 9:07 ` Hiremath, Vaibhav
[not found] ` <79CD15C6BA57404B839C016229A409A83EA7F4A3-Er742YJ7I/eIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2012-08-03 11:41 ` Daniel Mack
2012-08-03 11:48 ` B, Ravi
2012-08-03 12:35 ` Koen Kooi
[not found] ` <501BB8F2.8030909-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-08-03 15:48 ` Hiremath, Vaibhav
2012-08-03 16:01 ` Koen Kooi
2012-08-05 19:52 ` Daniel Mack
2012-08-06 6:40 ` Hiremath, Vaibhav
2012-08-15 14:39 ` Christopher Harvey
2012-08-02 12:12 ` [PATCH v7 11/11] arm/dts: am33xx: add phy phandle to usbss Ravi Babu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343909574-15633-4-git-send-email-ravibabu@ti.com \
--to=ravibabu@ti.com \
--cc=ajayguptaj@gmail.com \
--cc=balbi@ti.com \
--cc=devicetree-discuss@lists.ozlabs.org \
--cc=grant.likely@secretlab.ca \
--cc=linux-omap@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).