2008-07-24 13:27:36 +04:00
/*
* Copyright ( C ) 2005 - 2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux .
*
* The Inventra Controller Driver for Linux is free software ; you
* can redistribute it and / or modify it under the terms of the GNU
* General Public License version 2 as published by the Free Software
* Foundation .
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public
* License for more details .
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not ,
* write to the Free Software Foundation , Inc . , 59 Temple Place ,
* Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/list.h>
# include <linux/delay.h>
# include <linux/clk.h>
2012-06-26 16:10:32 +04:00
# include <linux/err.h>
2008-07-24 13:27:36 +04:00
# include <linux/io.h>
2008-09-11 12:53:23 +04:00
# include <linux/gpio.h>
2010-12-02 10:16:55 +03:00
# include <linux/platform_device.h>
# include <linux/dma-mapping.h>
2013-07-26 14:16:42 +04:00
# include <linux/usb/usb_phy_gen_xceiv.h>
2008-07-24 13:27:36 +04:00
2009-07-01 14:32:43 +04:00
# include <mach/cputype.h>
2012-05-25 05:50:18 +04:00
# include <mach/hardware.h>
2009-01-25 04:56:17 +03:00
2008-07-24 13:27:36 +04:00
# include <asm/mach-types.h>
# include "musb_core.h"
# ifdef CONFIG_MACH_DAVINCI_EVM
2009-12-15 14:29:57 +03:00
# define GPIO_nVBUS_DRV 160
2008-07-24 13:27:36 +04:00
# endif
# include "davinci.h"
# include "cppi_dma.h"
2009-02-25 02:31:54 +03:00
# define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR)
# define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
2010-12-02 10:38:12 +03:00
struct davinci_glue {
struct device * dev ;
struct platform_device * musb ;
2010-12-02 10:57:08 +03:00
struct clk * clk ;
2010-12-02 10:38:12 +03:00
} ;
2008-07-24 13:27:36 +04:00
/* REVISIT (PM) we should be able to keep the PHY in low power mode most
* of the time ( 24 MHZ oscillator and PLL off , etc ) by setting POWER . D0
* and , when in host mode , autosuspending idle root ports . . . PHYPLLON
* ( overriding SUSPENDM ? ) then likely needs to stay off .
*/
static inline void phy_on ( void )
{
2009-02-25 02:31:54 +03:00
u32 phy_ctrl = __raw_readl ( USB_PHY_CTRL ) ;
/* power everything up; start the on-chip PHY and its PLL */
phy_ctrl & = ~ ( USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN ) ;
phy_ctrl | = USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON ;
__raw_writel ( phy_ctrl , USB_PHY_CTRL ) ;
/* wait for PLL to lock before proceeding */
while ( ( __raw_readl ( USB_PHY_CTRL ) & USBPHY_PHYCLKGD ) = = 0 )
2008-07-24 13:27:36 +04:00
cpu_relax ( ) ;
}
static inline void phy_off ( void )
{
2009-02-25 02:31:54 +03:00
u32 phy_ctrl = __raw_readl ( USB_PHY_CTRL ) ;
/* powerdown the on-chip PHY, its PLL, and the OTG block */
phy_ctrl & = ~ ( USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON ) ;
phy_ctrl | = USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN ;
__raw_writel ( phy_ctrl , USB_PHY_CTRL ) ;
2008-07-24 13:27:36 +04:00
}
static int dma_off = 1 ;
2010-12-01 14:22:05 +03:00
static void davinci_musb_enable ( struct musb * musb )
2008-07-24 13:27:36 +04:00
{
u32 tmp , old , val ;
/* workaround: setup irqs through both register sets */
tmp = ( musb - > epmask & DAVINCI_USB_TX_ENDPTS_MASK )
< < DAVINCI_USB_TXINT_SHIFT ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_SET_REG , tmp ) ;
old = tmp ;
tmp = ( musb - > epmask & ( 0xfffe & DAVINCI_USB_RX_ENDPTS_MASK ) )
< < DAVINCI_USB_RXINT_SHIFT ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_SET_REG , tmp ) ;
tmp | = old ;
val = ~ MUSB_INTR_SOF ;
tmp | = ( ( val & 0x01ff ) < < DAVINCI_USB_USBINT_SHIFT ) ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_SET_REG , tmp ) ;
if ( is_dma_capable ( ) & & ! dma_off )
printk ( KERN_WARNING " %s %s: dma not reactivated \n " ,
__FILE__ , __func__ ) ;
else
dma_off = 0 ;
/* force a DRVVBUS irq so we can start polling for ID change */
2011-11-24 17:46:26 +04:00
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_SET_REG ,
2008-07-24 13:27:36 +04:00
DAVINCI_INTR_DRVVBUS < < DAVINCI_USB_USBINT_SHIFT ) ;
}
/*
* Disable the HDRC and flush interrupts
*/
2010-12-01 14:22:05 +03:00
static void davinci_musb_disable ( struct musb * musb )
2008-07-24 13:27:36 +04:00
{
/* because we don't set CTRLR.UINT, "important" to:
* - not read / write INTRUSB / INTRUSBE
* - ( except during initial setup , as workaround )
* - use INTSETR / INTCLRR instead
*/
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_CLR_REG ,
DAVINCI_USB_USBINT_MASK
| DAVINCI_USB_TXINT_MASK
| DAVINCI_USB_RXINT_MASK ) ;
musb_writeb ( musb - > mregs , MUSB_DEVCTL , 0 ) ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_EOI_REG , 0 ) ;
if ( is_dma_capable ( ) & & ! dma_off )
WARNING ( " dma still active \n " ) ;
}
# define portstate(stmt) stmt
2009-02-25 02:31:54 +03:00
/*
* VBUS SWITCHING IS BOARD - SPECIFIC . . . at least for the DM6446 EVM ,
* which doesn ' t wire DRVVBUS to the FET that switches it . Unclear
* if that ' s a problem with the DM6446 chip or just with that board .
*
* In either case , the DM355 EVM automates DRVVBUS the normal way ,
* when J10 is out , and TI documents it as handling OTG .
*/
2008-07-24 13:27:36 +04:00
# ifdef CONFIG_MACH_DAVINCI_EVM
2009-02-25 02:31:54 +03:00
static int vbus_state = - 1 ;
2008-07-24 13:27:36 +04:00
/* I2C operations are always synchronous, and require a task context.
* With unloaded systems , using the shared workqueue seems to suffice
* to satisfy the 100 msec A_WAIT_VRISE timeout . . .
*/
static void evm_deferred_drvvbus ( struct work_struct * ignored )
{
2008-09-11 12:53:23 +04:00
gpio_set_value_cansleep ( GPIO_nVBUS_DRV , vbus_state ) ;
2008-07-24 13:27:36 +04:00
vbus_state = ! vbus_state ;
}
# endif /* EVM */
2010-12-01 14:22:05 +03:00
static void davinci_musb_source_power ( struct musb * musb , int is_on , int immediate )
2008-07-24 13:27:36 +04:00
{
2009-02-25 02:31:54 +03:00
# ifdef CONFIG_MACH_DAVINCI_EVM
2008-07-24 13:27:36 +04:00
if ( is_on )
is_on = 1 ;
if ( vbus_state = = is_on )
return ;
vbus_state = ! is_on ; /* 0/1 vs "-1 == unknown/init" */
if ( machine_is_davinci_evm ( ) ) {
2009-02-25 02:31:54 +03:00
static DECLARE_WORK ( evm_vbus_work , evm_deferred_drvvbus ) ;
2008-07-24 13:27:36 +04:00
if ( immediate )
2008-09-11 12:53:23 +04:00
gpio_set_value_cansleep ( GPIO_nVBUS_DRV , vbus_state ) ;
2008-07-24 13:27:36 +04:00
else
schedule_work ( & evm_vbus_work ) ;
}
if ( immediate )
vbus_state = is_on ;
2009-02-25 02:31:54 +03:00
# endif
2008-07-24 13:27:36 +04:00
}
2010-12-01 14:22:05 +03:00
static void davinci_musb_set_vbus ( struct musb * musb , int is_on )
2008-07-24 13:27:36 +04:00
{
WARN_ON ( is_on & & is_peripheral_active ( musb ) ) ;
2010-12-01 14:22:05 +03:00
davinci_musb_source_power ( musb , is_on , 0 ) ;
2008-07-24 13:27:36 +04:00
}
# define POLL_SECONDS 2
static struct timer_list otg_workaround ;
static void otg_timer ( unsigned long _musb )
{
struct musb * musb = ( void * ) _musb ;
void __iomem * mregs = musb - > mregs ;
u8 devctl ;
unsigned long flags ;
/* We poll because DaVinci's won't expose several OTG-critical
* status change events ( from the transceiver ) otherwise .
*/
devctl = musb_readb ( mregs , MUSB_DEVCTL ) ;
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " poll devctl %02x (%s) \n " , devctl ,
2013-03-07 12:39:57 +04:00
usb_otg_state_string ( musb - > xceiv - > state ) ) ;
2008-07-24 13:27:36 +04:00
spin_lock_irqsave ( & musb - > lock , flags ) ;
2009-03-31 23:30:04 +04:00
switch ( musb - > xceiv - > state ) {
2008-07-24 13:27:36 +04:00
case OTG_STATE_A_WAIT_VFALL :
/* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
* seems to mis - handle session " start " otherwise ( or in our
* case " recover " ) , in routine " VBUS was valid by the time
* VBUSERR got reported during enumeration " cases.
*/
if ( devctl & MUSB_DEVCTL_VBUS ) {
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
break ;
}
2009-03-31 23:30:04 +04:00
musb - > xceiv - > state = OTG_STATE_A_WAIT_VRISE ;
2008-07-24 13:27:36 +04:00
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_SET_REG ,
MUSB_INTR_VBUSERROR < < DAVINCI_USB_USBINT_SHIFT ) ;
break ;
case OTG_STATE_B_IDLE :
2011-11-24 17:46:26 +04:00
/*
* There ' s no ID - changed IRQ , so we have no good way to tell
2008-07-24 13:27:36 +04:00
* when to switch to the A - Default state machine ( by setting
* the DEVCTL . SESSION flag ) .
*
* Workaround : whenever we ' re in B_IDLE , try setting the
* session flag every few seconds . If it works , ID was
* grounded and we ' re now in the A - Default state machine .
*
* NOTE setting the session flag is _supposed_ to trigger
* SRP , but clearly it doesn ' t .
*/
musb_writeb ( mregs , MUSB_DEVCTL ,
devctl | MUSB_DEVCTL_SESSION ) ;
devctl = musb_readb ( mregs , MUSB_DEVCTL ) ;
if ( devctl & MUSB_DEVCTL_BDEVICE )
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
else
2009-03-31 23:30:04 +04:00
musb - > xceiv - > state = OTG_STATE_A_IDLE ;
2008-07-24 13:27:36 +04:00
break ;
default :
break ;
}
spin_unlock_irqrestore ( & musb - > lock , flags ) ;
}
2010-12-01 14:22:05 +03:00
static irqreturn_t davinci_musb_interrupt ( int irq , void * __hci )
2008-07-24 13:27:36 +04:00
{
unsigned long flags ;
irqreturn_t retval = IRQ_NONE ;
struct musb * musb = __hci ;
2012-02-13 15:24:15 +04:00
struct usb_otg * otg = musb - > xceiv - > otg ;
2008-07-24 13:27:36 +04:00
void __iomem * tibase = musb - > ctrl_base ;
2009-03-27 22:59:46 +03:00
struct cppi * cppi ;
2008-07-24 13:27:36 +04:00
u32 tmp ;
spin_lock_irqsave ( & musb - > lock , flags ) ;
/* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through
* the Mentor registers ( except for setup ) , use the TI ones and EOI .
*
2010-02-12 23:58:11 +03:00
* Docs describe irq " vector " registers associated with the CPPI and
2008-07-24 13:27:36 +04:00
* USB EOI registers . These hold a bitmask corresponding to the
* current IRQ , not an irq handler address . Would using those bits
* resolve some of the races observed in this dispatch code ? ?
*/
/* CPPI interrupts share the same IRQ line, but have their own
* mask , state , " vector " , and EOI registers .
*/
2009-03-27 22:59:46 +03:00
cppi = container_of ( musb - > dma_controller , struct cppi , controller ) ;
if ( is_cppi_enabled ( ) & & musb - > dma_controller & & ! cppi - > irq )
retval = cppi_interrupt ( irq , __hci ) ;
2008-07-24 13:27:36 +04:00
/* ack and handle non-CPPI interrupts */
tmp = musb_readl ( tibase , DAVINCI_USB_INT_SRC_MASKED_REG ) ;
musb_writel ( tibase , DAVINCI_USB_INT_SRC_CLR_REG , tmp ) ;
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " IRQ %08x \n " , tmp ) ;
2008-07-24 13:27:36 +04:00
musb - > int_rx = ( tmp & DAVINCI_USB_RXINT_MASK )
> > DAVINCI_USB_RXINT_SHIFT ;
musb - > int_tx = ( tmp & DAVINCI_USB_TXINT_MASK )
> > DAVINCI_USB_TXINT_SHIFT ;
musb - > int_usb = ( tmp & DAVINCI_USB_USBINT_MASK )
> > DAVINCI_USB_USBINT_SHIFT ;
/* DRVVBUS irqs are the only proxy we have (a very poor one!) for
* DaVinci ' s missing ID change IRQ . We need an ID change IRQ to
* switch appropriately between halves of the OTG state machine .
* Managing DEVCTL . SESSION per Mentor docs requires we know its
* value , but DEVCTL . BDEVICE is invalid without DEVCTL . SESSION set .
* Also , DRVVBUS pulses for SRP ( but not at 5 V ) . . .
*/
if ( tmp & ( DAVINCI_INTR_DRVVBUS < < DAVINCI_USB_USBINT_SHIFT ) ) {
int drvvbus = musb_readl ( tibase , DAVINCI_USB_STAT_REG ) ;
void __iomem * mregs = musb - > mregs ;
u8 devctl = musb_readb ( mregs , MUSB_DEVCTL ) ;
int err = musb - > int_usb & MUSB_INTR_VBUSERROR ;
2011-11-24 17:46:26 +04:00
err = musb - > int_usb & MUSB_INTR_VBUSERROR ;
2008-07-24 13:27:36 +04:00
if ( err ) {
/* The Mentor core doesn't debounce VBUS as needed
* to cope with device connect current spikes . This
* means it ' s not uncommon for bus - powered devices
* to get VBUS errors during enumeration .
*
* This is a workaround , but newer RTL from Mentor
* seems to allow a better one : " re " starting sessions
* without waiting ( on EVM , a * * long * * time ) for VBUS
* to stop registering in devctl .
*/
musb - > int_usb & = ~ MUSB_INTR_VBUSERROR ;
2009-03-31 23:30:04 +04:00
musb - > xceiv - > state = OTG_STATE_A_WAIT_VFALL ;
2008-07-24 13:27:36 +04:00
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
WARNING ( " VBUS error workaround (delay coming) \n " ) ;
2011-11-24 17:46:26 +04:00
} else if ( drvvbus ) {
2008-07-24 13:27:36 +04:00
MUSB_HST_MODE ( musb ) ;
2012-02-13 15:24:15 +04:00
otg - > default_a = 1 ;
2009-03-31 23:30:04 +04:00
musb - > xceiv - > state = OTG_STATE_A_WAIT_VRISE ;
2008-07-24 13:27:36 +04:00
portstate ( musb - > port1_status | = USB_PORT_STAT_POWER ) ;
del_timer ( & otg_workaround ) ;
} else {
musb - > is_active = 0 ;
MUSB_DEV_MODE ( musb ) ;
2012-02-13 15:24:15 +04:00
otg - > default_a = 0 ;
2009-03-31 23:30:04 +04:00
musb - > xceiv - > state = OTG_STATE_B_IDLE ;
2008-07-24 13:27:36 +04:00
portstate ( musb - > port1_status & = ~ USB_PORT_STAT_POWER ) ;
}
2009-07-01 14:36:16 +04:00
/* NOTE: this must complete poweron within 100 msec
* ( OTG_TIME_A_WAIT_VRISE ) but we don ' t check for that .
*/
2010-12-01 14:22:05 +03:00
davinci_musb_source_power ( musb , drvvbus , 0 ) ;
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " VBUS %s (%s)%s, devctl %02x \n " ,
2008-07-24 13:27:36 +04:00
drvvbus ? " on " : " off " ,
2013-03-07 12:39:57 +04:00
usb_otg_state_string ( musb - > xceiv - > state ) ,
2008-07-24 13:27:36 +04:00
err ? " ERROR " : " " ,
devctl ) ;
retval = IRQ_HANDLED ;
}
if ( musb - > int_tx | | musb - > int_rx | | musb - > int_usb )
retval | = musb_interrupt ( musb ) ;
/* irq stays asserted until EOI is written */
musb_writel ( tibase , DAVINCI_USB_EOI_REG , 0 ) ;
/* poll for ID change */
2011-11-24 17:46:26 +04:00
if ( musb - > xceiv - > state = = OTG_STATE_B_IDLE )
2008-07-24 13:27:36 +04:00
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
spin_unlock_irqrestore ( & musb - > lock , flags ) ;
2009-03-27 22:52:43 +03:00
return retval ;
2008-07-24 13:27:36 +04:00
}
2010-12-01 14:22:05 +03:00
static int davinci_musb_set_mode ( struct musb * musb , u8 mode )
2008-11-24 14:06:47 +03:00
{
/* EVM can't do this (right?) */
return - EIO ;
}
2010-12-01 14:22:05 +03:00
static int davinci_musb_init ( struct musb * musb )
2008-07-24 13:27:36 +04:00
{
void __iomem * tibase = musb - > ctrl_base ;
u32 revision ;
2013-01-04 19:13:58 +04:00
int ret = - ENODEV ;
2008-07-24 13:27:36 +04:00
2009-03-31 23:30:04 +04:00
usb_nop_xceiv_register ( ) ;
2012-06-22 15:32:46 +04:00
musb - > xceiv = usb_get_phy ( USB_PHY_TYPE_USB2 ) ;
2013-01-04 19:13:58 +04:00
if ( IS_ERR_OR_NULL ( musb - > xceiv ) ) {
ret = - EPROBE_DEFER ;
2012-04-16 19:03:10 +04:00
goto unregister ;
2013-01-04 19:13:58 +04:00
}
2009-03-31 23:30:04 +04:00
2008-07-24 13:27:36 +04:00
musb - > mregs + = DAVINCI_BASE_OFFSET ;
/* returns zero if e.g. not clocked */
revision = musb_readl ( tibase , DAVINCI_USB_VERSION_REG ) ;
if ( revision = = 0 )
2009-03-31 23:30:04 +04:00
goto fail ;
2008-07-24 13:27:36 +04:00
2011-11-24 17:46:26 +04:00
setup_timer ( & otg_workaround , otg_timer , ( unsigned long ) musb ) ;
2008-07-24 13:27:36 +04:00
2010-12-01 14:22:05 +03:00
davinci_musb_source_power ( musb , 0 , 1 ) ;
2008-07-24 13:27:36 +04:00
2009-02-25 02:31:54 +03:00
/* dm355 EVM swaps D+/D- for signal integrity, and
* is clocked from the main 24 MHz crystal .
*/
if ( machine_is_davinci_dm355_evm ( ) ) {
u32 phy_ctrl = __raw_readl ( USB_PHY_CTRL ) ;
phy_ctrl & = ~ ( 3 < < 9 ) ;
phy_ctrl | = USBPHY_DATAPOL ;
__raw_writel ( phy_ctrl , USB_PHY_CTRL ) ;
}
2009-07-01 14:32:43 +04:00
/* On dm355, the default-A state machine needs DRVVBUS control.
* If we won ' t be a host , there ' s no need to turn it on .
*/
if ( cpu_is_davinci_dm355 ( ) ) {
u32 deepsleep = __raw_readl ( DM355_DEEPSLEEP ) ;
2011-11-24 17:46:26 +04:00
deepsleep & = ~ DRVVBUS_FORCE ;
2009-07-01 14:32:43 +04:00
__raw_writel ( deepsleep , DM355_DEEPSLEEP ) ;
}
2008-07-24 13:27:36 +04:00
/* reset the controller */
musb_writel ( tibase , DAVINCI_USB_CTRL_REG , 0x1 ) ;
/* start the on-chip PHY and its PLL */
phy_on ( ) ;
msleep ( 5 ) ;
/* NOTE: irqs are in mixed mode, not bypass to pure-musb */
pr_debug ( " DaVinci OTG revision %08x phy %03x control %02x \n " ,
2009-02-25 02:31:54 +03:00
revision , __raw_readl ( USB_PHY_CTRL ) ,
2008-07-24 13:27:36 +04:00
musb_readb ( tibase , DAVINCI_USB_CTRL_REG ) ) ;
2010-12-01 14:22:05 +03:00
musb - > isr = davinci_musb_interrupt ;
2008-07-24 13:27:36 +04:00
return 0 ;
2009-03-31 23:30:04 +04:00
fail :
2012-06-22 15:32:45 +04:00
usb_put_phy ( musb - > xceiv ) ;
2012-04-16 19:03:10 +04:00
unregister :
2009-03-31 23:30:04 +04:00
usb_nop_xceiv_unregister ( ) ;
2013-01-04 19:13:58 +04:00
return ret ;
2008-07-24 13:27:36 +04:00
}
2010-12-01 14:22:05 +03:00
static int davinci_musb_exit ( struct musb * musb )
2008-07-24 13:27:36 +04:00
{
2011-11-24 17:46:26 +04:00
del_timer_sync ( & otg_workaround ) ;
2008-07-24 13:27:36 +04:00
2009-07-01 14:32:43 +04:00
/* force VBUS off */
if ( cpu_is_davinci_dm355 ( ) ) {
u32 deepsleep = __raw_readl ( DM355_DEEPSLEEP ) ;
deepsleep & = ~ DRVVBUS_FORCE ;
deepsleep | = DRVVBUS_OVERRIDE ;
__raw_writel ( deepsleep , DM355_DEEPSLEEP ) ;
}
2010-12-01 14:22:05 +03:00
davinci_musb_source_power ( musb , 0 /*off*/ , 1 ) ;
2008-07-24 13:27:36 +04:00
/* delay, to avoid problems with module reload */
2011-11-24 17:46:26 +04:00
if ( musb - > xceiv - > otg - > default_a ) {
2008-07-24 13:27:36 +04:00
int maxdelay = 30 ;
u8 devctl , warn = 0 ;
/* if there's no peripheral connected, this can take a
* long time to fall , especially on EVM with huge C133 .
*/
do {
devctl = musb_readb ( musb - > mregs , MUSB_DEVCTL ) ;
if ( ! ( devctl & MUSB_DEVCTL_VBUS ) )
break ;
if ( ( devctl & MUSB_DEVCTL_VBUS ) ! = warn ) {
warn = devctl & MUSB_DEVCTL_VBUS ;
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " VBUS %d \n " ,
2008-07-24 13:27:36 +04:00
warn > > MUSB_DEVCTL_VBUS_SHIFT ) ;
}
msleep ( 1000 ) ;
maxdelay - - ;
} while ( maxdelay > 0 ) ;
/* in OTG mode, another host might be connected */
if ( devctl & MUSB_DEVCTL_VBUS )
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " VBUS off timeout (devctl %02x) \n " , devctl ) ;
2008-07-24 13:27:36 +04:00
}
phy_off ( ) ;
2009-02-21 00:45:17 +03:00
2012-06-22 15:32:45 +04:00
usb_put_phy ( musb - > xceiv ) ;
2009-03-31 23:30:04 +04:00
usb_nop_xceiv_unregister ( ) ;
2008-07-24 13:27:36 +04:00
return 0 ;
}
2010-12-01 14:22:05 +03:00
2010-12-02 10:48:58 +03:00
static const struct musb_platform_ops davinci_ops = {
2010-12-01 14:22:05 +03:00
. init = davinci_musb_init ,
. exit = davinci_musb_exit ,
. enable = davinci_musb_enable ,
. disable = davinci_musb_disable ,
. set_mode = davinci_musb_set_mode ,
. set_vbus = davinci_musb_set_vbus ,
} ;
2010-12-02 10:16:55 +03:00
2013-09-20 03:14:38 +04:00
static const struct platform_device_info davinci_dev_info = {
. name = " musb-hdrc " ,
. id = PLATFORM_DEVID_AUTO ,
. dma_mask = DMA_BIT_MASK ( 32 ) ,
} ;
2010-12-02 10:16:55 +03:00
2012-11-19 22:21:48 +04:00
static int davinci_probe ( struct platform_device * pdev )
2010-12-02 10:16:55 +03:00
{
2013-09-22 01:43:58 +04:00
struct resource musb_resources [ 3 ] ;
2013-07-30 12:03:12 +04:00
struct musb_hdrc_platform_data * pdata = dev_get_platdata ( & pdev - > dev ) ;
2010-12-02 10:16:55 +03:00
struct platform_device * musb ;
2010-12-02 10:38:12 +03:00
struct davinci_glue * glue ;
2013-09-20 03:14:38 +04:00
struct platform_device_info pinfo ;
2010-12-02 10:57:08 +03:00
struct clk * clk ;
2010-12-02 10:16:55 +03:00
int ret = - ENOMEM ;
2010-12-02 10:38:12 +03:00
glue = kzalloc ( sizeof ( * glue ) , GFP_KERNEL ) ;
if ( ! glue ) {
dev_err ( & pdev - > dev , " failed to allocate glue context \n " ) ;
goto err0 ;
}
2010-12-02 10:57:08 +03:00
clk = clk_get ( & pdev - > dev , " usb " ) ;
if ( IS_ERR ( clk ) ) {
dev_err ( & pdev - > dev , " failed to get clock \n " ) ;
ret = PTR_ERR ( clk ) ;
2012-08-31 15:09:49 +04:00
goto err3 ;
2010-12-02 10:57:08 +03:00
}
ret = clk_enable ( clk ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to enable clock \n " ) ;
2012-08-31 15:09:49 +04:00
goto err4 ;
2010-12-02 10:57:08 +03:00
}
2010-12-02 10:38:12 +03:00
glue - > dev = & pdev - > dev ;
2010-12-02 10:57:08 +03:00
glue - > clk = clk ;
2010-12-02 10:38:12 +03:00
2010-12-02 10:48:58 +03:00
pdata - > platform_ops = & davinci_ops ;
2010-12-02 10:38:12 +03:00
platform_set_drvdata ( pdev , glue ) ;
2010-12-02 10:16:55 +03:00
2013-04-24 18:21:42 +04:00
memset ( musb_resources , 0x00 , sizeof ( * musb_resources ) *
ARRAY_SIZE ( musb_resources ) ) ;
musb_resources [ 0 ] . name = pdev - > resource [ 0 ] . name ;
musb_resources [ 0 ] . start = pdev - > resource [ 0 ] . start ;
musb_resources [ 0 ] . end = pdev - > resource [ 0 ] . end ;
musb_resources [ 0 ] . flags = pdev - > resource [ 0 ] . flags ;
musb_resources [ 1 ] . name = pdev - > resource [ 1 ] . name ;
musb_resources [ 1 ] . start = pdev - > resource [ 1 ] . start ;
musb_resources [ 1 ] . end = pdev - > resource [ 1 ] . end ;
musb_resources [ 1 ] . flags = pdev - > resource [ 1 ] . flags ;
2013-09-22 01:43:58 +04:00
/*
* For DM6467 3 resources are passed . A placeholder for the 3 rd
* resource is always there , so it ' s safe to always copy it . . .
*/
musb_resources [ 2 ] . name = pdev - > resource [ 2 ] . name ;
musb_resources [ 2 ] . start = pdev - > resource [ 2 ] . start ;
musb_resources [ 2 ] . end = pdev - > resource [ 2 ] . end ;
musb_resources [ 2 ] . flags = pdev - > resource [ 2 ] . flags ;
2013-04-24 18:21:42 +04:00
2013-09-20 03:14:38 +04:00
pinfo = davinci_dev_info ;
pinfo . parent = & pdev - > dev ;
pinfo . res = musb_resources ;
pinfo . num_res = ARRAY_SIZE ( musb_resources ) ;
pinfo . data = pdata ;
pinfo . size_data = sizeof ( * pdata ) ;
glue - > musb = musb = platform_device_register_full ( & pinfo ) ;
if ( IS_ERR ( musb ) ) {
ret = PTR_ERR ( musb ) ;
dev_err ( & pdev - > dev , " failed to register musb device: %d \n " , ret ) ;
2012-08-31 15:09:49 +04:00
goto err5 ;
2010-12-02 10:16:55 +03:00
}
return 0 ;
2012-08-31 15:09:49 +04:00
err5 :
2010-12-02 10:57:08 +03:00
clk_disable ( clk ) ;
2012-08-31 15:09:49 +04:00
err4 :
2010-12-02 10:57:08 +03:00
clk_put ( clk ) ;
2012-08-31 15:09:49 +04:00
err3 :
2010-12-02 10:38:12 +03:00
kfree ( glue ) ;
2010-12-02 10:16:55 +03:00
err0 :
return ret ;
}
2012-11-19 22:26:20 +04:00
static int davinci_remove ( struct platform_device * pdev )
2010-12-02 10:16:55 +03:00
{
2010-12-02 10:38:12 +03:00
struct davinci_glue * glue = platform_get_drvdata ( pdev ) ;
2010-12-02 10:16:55 +03:00
2012-10-23 09:35:46 +04:00
platform_device_unregister ( glue - > musb ) ;
2010-12-02 10:57:08 +03:00
clk_disable ( glue - > clk ) ;
clk_put ( glue - > clk ) ;
2010-12-02 10:38:12 +03:00
kfree ( glue ) ;
2010-12-02 10:16:55 +03:00
return 0 ;
}
static struct platform_driver davinci_driver = {
2012-01-26 14:40:23 +04:00
. probe = davinci_probe ,
2012-11-19 22:21:08 +04:00
. remove = davinci_remove ,
2010-12-02 10:16:55 +03:00
. driver = {
. name = " musb-davinci " ,
} ,
} ;
MODULE_DESCRIPTION ( " DaVinci MUSB Glue Layer " ) ;
MODULE_AUTHOR ( " Felipe Balbi <balbi@ti.com> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
2012-10-10 22:37:07 +04:00
module_platform_driver ( davinci_driver ) ;