@ -11,6 +11,7 @@
# include <asm/io.h>
# include <dm.h>
# include "ehci.h"
# include <power/regulator.h>
/*
* Even though here we don ' t explicitly use " struct ehci_ctrl "
@ -22,10 +23,56 @@ struct generic_ehci {
struct clk * clocks ;
struct reset_ctl * resets ;
struct phy phy ;
# ifdef CONFIG_DM_REGULATOR
struct udevice * vbus_supply ;
# endif
int clock_count ;
int reset_count ;
} ;
# ifdef CONFIG_DM_REGULATOR
static int ehci_enable_vbus_supply ( struct udevice * dev )
{
struct generic_ehci * priv = dev_get_priv ( dev ) ;
int ret ;
ret = device_get_supply_regulator ( dev , " vbus-supply " ,
& priv - > vbus_supply ) ;
if ( ret & & ret ! = - ENOENT )
return ret ;
if ( priv - > vbus_supply ) {
ret = regulator_set_enable ( priv - > vbus_supply , true ) ;
if ( ret ) {
dev_err ( dev , " Error enabling VBUS supply \n " ) ;
return ret ;
}
} else {
dev_dbg ( dev , " No vbus supply \n " ) ;
}
return 0 ;
}
static int ehci_disable_vbus_supply ( struct generic_ehci * priv )
{
if ( priv - > vbus_supply )
return regulator_set_enable ( priv - > vbus_supply , false ) ;
else
return 0 ;
}
# else
static int ehci_enable_vbus_supply ( struct udevice * dev )
{
return 0 ;
}
static int ehci_disable_vbus_supply ( struct generic_ehci * priv )
{
return 0 ;
}
# endif
static int ehci_usb_probe ( struct udevice * dev )
{
struct generic_ehci * priv = dev_get_priv ( dev ) ;
@ -95,10 +142,14 @@ static int ehci_usb_probe(struct udevice *dev)
}
}
err = ehci_setup_phy ( dev , & priv - > phy , 0 ) ;
err = ehci_enable_vbus_supply ( dev ) ;
if ( err )
goto reset_err ;
err = ehci_setup_phy ( dev , & priv - > phy , 0 ) ;
if ( err )
goto regulator_err ;
hccr = map_physmem ( dev_read_addr ( dev ) , 0x100 , MAP_NOCACHE ) ;
hcor = ( struct ehci_hcor * ) ( ( uintptr_t ) hccr +
HC_LENGTH ( ehci_readl ( & hccr - > cr_capbase ) ) ) ;
@ -114,6 +165,11 @@ phy_err:
if ( ret )
dev_err ( dev , " failed to shutdown usb phy \n " ) ;
regulator_err :
ret = ehci_disable_vbus_supply ( priv ) ;
if ( ret )
dev_err ( dev , " failed to disable VBUS supply \n " ) ;
reset_err :
ret = reset_release_all ( priv - > resets , priv - > reset_count ) ;
if ( ret )
@ -139,6 +195,10 @@ static int ehci_usb_remove(struct udevice *dev)
if ( ret )
return ret ;
ret = ehci_disable_vbus_supply ( priv ) ;
if ( ret )
return ret ;
ret = reset_release_all ( priv - > resets , priv - > reset_count ) ;
if ( ret )
return ret ;