Re: [try#1 PATCH 5/7] omap4: panda: add smsc95xx regulator and reset dependent on root hub

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/28/2012 02:59 PM, Andy Green wrote:
> This adds regulators which are controlled by the OMAP4 PandaBoard (ES)'s
> EHCI logical root hub existing.
> 
> The regulators are made a device_asset of the EHCI logical root hub by
> passing them through the hsusb -> mfd path.  Although the ehci-related
> platform_device is created at boot time, it is not instantiated until the
> ehci-hcd module is inserted if it is modular.
> 
> Since the regulator is an asset of the ehci-omap.0 device, it's turned on
> during successful probe and off when the device is removed.
> 
> Without power control, the ULPI PHY + SMSC9614 on the Panda eats 700-900mW
> all the time, which is around the same as the idle power of the SoC and
> rest of the board.
> 
> This allows us to start off with it depowered, and only power it if the
> ehci-hcd module is inserted.  When the module is removed, it's depowered
> again.
> 
> Signed-off-by: Andy Green <andy.green@xxxxxxxxxx>
> ---
>  arch/arm/mach-omap2/board-omap4panda.c |  100 ++++++++++++++++++++++++++------
>  arch/arm/mach-omap2/usb-host.c         |    1 
>  arch/arm/plat-omap/include/plat/usb.h  |    2 +
>  drivers/mfd/omap-usb-host.c            |    9 ++-
>  4 files changed, 89 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
> index bfcd397..52add03 100644
> --- a/arch/arm/mach-omap2/board-omap4panda.c
> +++ b/arch/arm/mach-omap2/board-omap4panda.c
> @@ -144,6 +144,15 @@ static struct platform_device *panda_devices[] __initdata = {
>  	&btwilink_device,
>  };
>  
> +static struct device_asset assets_ehci_omap0[] = {
> +	{
> +		.name = "reg-panda-smsc95xx",
> +		.pre_probe = regulator_asset_default_preprobe,
> +		.post_remove = regulator_asset_default_postremove,
> +	},
> +	{ }
> +};
> +
>  static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
>  	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
>  	.port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
> @@ -151,12 +160,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
>  	.phy_reset  = false,
>  	.reset_gpio_port[0]  = -EINVAL,
>  	.reset_gpio_port[1]  = -EINVAL,
> -	.reset_gpio_port[2]  = -EINVAL
> -};
> -
> -static struct gpio panda_ehci_gpios[] __initdata = {
> -	{ GPIO_HUB_POWER,	GPIOF_OUT_INIT_LOW,  "hub_power"  },
> -	{ GPIO_HUB_NRESET,	GPIOF_OUT_INIT_LOW,  "hub_nreset" },
> +	.reset_gpio_port[2]  = -EINVAL,
> +	.assets = assets_ehci_omap0,
>  };
>  
>  static void __init omap4_ehci_init(void)
> @@ -173,23 +178,76 @@ static void __init omap4_ehci_init(void)
>  	clk_set_rate(phy_ref_clk, 19200000);
>  	clk_prepare_enable(phy_ref_clk);
>  
> -	/* disable the power to the usb hub prior to init and reset phy+hub */
> -	ret = gpio_request_array(panda_ehci_gpios,
> -				 ARRAY_SIZE(panda_ehci_gpios));
> -	if (ret) {
> -		pr_err("Unable to initialize EHCI power/reset\n");
> -		return;
> -	}
> +	usbhs_init(&usbhs_bdata);
> +}
>  
> -	gpio_export(GPIO_HUB_POWER, 0);
> -	gpio_export(GPIO_HUB_NRESET, 0);
> -	gpio_set_value(GPIO_HUB_NRESET, 1);
> +/*
> + * hub_nreset also resets the ULPI PHY and is required after powering SMSC chip
> + *	ULPI PHY is always powered... need to do reset once for both once
> + * hub_power enables a 3.3V regulator for (hub + eth) chip
> + *	however there's no point having ULPI PHY in use alone
> + *	since it's only connected to the (hub + eth) chip
> + */
>  
> -	usbhs_init(&usbhs_bdata);
> +static struct regulator_init_data panda_hub = {
> +	.constraints = {
> +		.name = "vhub",
> +		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
> +	},
> +};
>  
> -	/* enable power to hub */
> -	gpio_set_value(GPIO_HUB_POWER, 1);
> -}
> +static struct fixed_voltage_config panda_vhub = {
> +	.supply_name = "vhub",
> +	.microvolts = 3300000,
> +	.gpio = GPIO_HUB_POWER,
> +	.startup_delay = 70000, /* 70msec */
> +	.enable_high = 1,
> +	.enabled_at_boot = 0,
> +	.init_data = &panda_hub,
> +};
> +
> +static struct platform_device omap_vhub_device = {
> +	.name		= "reg-fixed-voltage",
> +	.id		= 2,
> +	.dev = {
> +		.platform_data = &panda_vhub,
> +	},
> +};
> +
> +static struct regulator_init_data panda_ulpireset = {
> +	/*
> +	 * idea is that when operating ulpireset, regulator api will make
> +	 * sure that the hub+eth chip is powered, since it's the "parent"
> +	 */
> +	.supply_regulator = "vhub", /* we are a child of vhub */
> +	.constraints = {
> +		/*
> +		 * this magic string associates us with ehci-omap.0 root hub
> +		 * when the root hub logical device is up, we will power
> +		 * and reset [ ULPI PHY + [ HUB + ETH ] ]
> +		 */
> +		.name = "reg-panda-smsc95xx",
> +		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
> +	},
> +};
> +
> +static struct fixed_voltage_config panda_vulpireset = {
> +	.supply_name = "reg-panda-smsc95xx",
> +	.microvolts = 3300000,
> +	.gpio = GPIO_HUB_NRESET,
> +	.startup_delay = 70000, /* 70msec */
> +	.enable_high = 1,
> +	.enabled_at_boot = 0,
> +	.init_data = &panda_ulpireset,
> +};
> +
> +static struct platform_device omap_vulpireset_device = {
> +	.name		= "reg-fixed-voltage",
> +	.id		= 3,
> +	.dev = {
> +		.platform_data = &panda_vulpireset,
> +	},
> +};
>  
>  static struct omap_musb_board_data musb_board_data = {
>  	.interface_type		= MUSB_INTERFACE_UTMI,
> @@ -504,6 +562,8 @@ static void __init omap4_panda_init(void)
>  	omap4_panda_i2c_init();
>  	platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
>  	platform_device_register(&omap_vwlan_device);
> +	platform_device_register(&omap_vhub_device);
> +	platform_device_register(&omap_vulpireset_device);
>  	omap_serial_init();
>  	omap_sdrc_init(NULL, NULL);
>  	omap4_twl6030_hsmmc_init(mmc);
> diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
> index 98f3287..2a0fdf9 100644
> --- a/arch/arm/mach-omap2/usb-host.c
> +++ b/arch/arm/mach-omap2/usb-host.c
> @@ -501,6 +501,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
>  	}
>  	ehci_data.phy_reset = pdata->phy_reset;
>  	ohci_data.es2_compatibility = pdata->es2_compatibility;
> +	ehci_data.assets = pdata->assets;

Just wondering if it makes more sense to tie the regulator and clock
assets on the Panda to LAN95xx platform device instead of ehci_omap's
platform device.

The only thing we need to do is add a dummy platform device for the
LAN9xx chip and probe it in the smsc9xx driver.

The benefit of this is we can choose to power up/down the LAN9xx device
by insmod/rmmod smsc0xx driver and still have other OMAP USB ports
functional.

what do you think?

regards,
-roger

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux