diff options
| author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-04-28 16:41:20 +0900 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-29 17:24:35 -0700 | 
| commit | b002ff6e268b6024d6927a1ce330a14ca162b6ab (patch) | |
| tree | 83bd5dde6f872396cd42762b59f96cf9c024d30a /drivers/usb/renesas_usbhs/common.c | |
| parent | bc57381e634782009b1cb2e86b18013699ada576 (diff) | |
| download | olio-linux-3.10-b002ff6e268b6024d6927a1ce330a14ca162b6ab.tar.xz olio-linux-3.10-b002ff6e268b6024d6927a1ce330a14ca162b6ab.zip  | |
usb: renesas_usbhs: add autonomy mode
Current renesas_usbhs was designed to save power when USB is not connected.
And it assumed platform uses callback to notify connection/disconnection
by external interrupt.
But some SuperH / platform board doesn't have such feature.
This patch adds autonomy mode which detect USB connection/disconnection
by internal interrupt.
But power will be always ON when autonomy mode is selected.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/renesas_usbhs/common.c')
| -rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 36 | 
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 9a75a45687b..34e68e0205c 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -21,6 +21,14 @@  #include <linux/sysfs.h>  #include "./common.h" +#define USBHSF_RUNTIME_PWCTRL	(1 << 0) + +/* status */ +#define usbhsc_flags_init(p)   do {(p)->flags = 0; } while (0) +#define usbhsc_flags_set(p, b) ((p)->flags |=  (b)) +#define usbhsc_flags_clr(p, b) ((p)->flags &= ~(b)) +#define usbhsc_flags_has(p, b) ((p)->flags &   (b)) +  /*   * platform call back   * @@ -203,7 +211,8 @@ static void usbhsc_notify_hotplug(struct work_struct *work)  		dev_dbg(&pdev->dev, "%s enable\n", __func__);  		/* power on */ -		usbhsc_power_ctrl(priv, enable); +		if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) +			usbhsc_power_ctrl(priv, enable);  		/* module start */  		usbhs_mod_call(priv, start, priv); @@ -215,7 +224,8 @@ static void usbhsc_notify_hotplug(struct work_struct *work)  		usbhs_mod_call(priv, stop, priv);  		/* power off */ -		usbhsc_power_ctrl(priv, enable); +		if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) +			usbhsc_power_ctrl(priv, enable);  		usbhs_mod_change(priv, -1); @@ -252,8 +262,7 @@ static int __devinit usbhs_probe(struct platform_device *pdev)  	/* check platform information */  	if (!info || -	    !info->platform_callback.get_id || -	    !info->platform_callback.get_vbus) { +	    !info->platform_callback.get_id) {  		dev_err(&pdev->dev, "no platform information\n");  		return -EINVAL;  	} @@ -296,6 +305,11 @@ static int __devinit usbhs_probe(struct platform_device *pdev)  		priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type);  	} +	/* FIXME */ +	/* runtime power control ? */ +	if (priv->pfunc->get_vbus) +		usbhsc_flags_set(priv, USBHSF_RUNTIME_PWCTRL); +  	/*  	 * priv settings  	 */ @@ -338,10 +352,16 @@ static int __devinit usbhs_probe(struct platform_device *pdev)  	/* reset phy for connection */  	usbhs_platform_call(priv, phy_reset, pdev); +	/* power control */ +	pm_runtime_enable(&pdev->dev); +	if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) { +		usbhsc_power_ctrl(priv, 1); +		usbhs_mod_autonomy_mode(priv); +	} +  	/*  	 * manual call notify_hotplug for cold plug  	 */ -	pm_runtime_enable(&pdev->dev);  	ret = usbhsc_drvcllbck_notify_hotplug(pdev);  	if (ret < 0)  		goto probe_end_call_remove; @@ -376,9 +396,11 @@ static int __devexit usbhs_remove(struct platform_device *pdev)  	dfunc->notify_hotplug = NULL; -	pm_runtime_disable(&pdev->dev); +	/* power off */ +	if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) +		usbhsc_power_ctrl(priv, 0); -	usbhsc_bus_ctrl(priv, 0); +	pm_runtime_disable(&pdev->dev);  	usbhs_platform_call(priv, hardware_exit, pdev);  	usbhs_pipe_remove(priv);  |