[PATCH] [RFC][ARM] pxa: rework pxa3xx-ulpi driver calls for ohci-pxa27x

Igor Grinberg grinberg at compulab.co.il
Sun Oct 3 08:22:34 EDT 2010


 Eric, David, Marek,

Any comments on this?

On 09/20/10 16:48, Igor Grinberg wrote:
>  ping
>
> On 09/07/10 17:14, Igor Grinberg wrote:
>> This patch reworks Marek's quick fix for pxa3xx-u2d crash when ULPI not
>> used by:
>> 1) Introducing the struct u2d_hc_ops for start/stop the U2DC Host mode.
>> 2) Enabling the Host functionality only when ULPI is used.
>>
>> Signed-off-by: Igor Grinberg <grinberg at compulab.co.il>
>> ---
>>  arch/arm/mach-pxa/cm-x300.c                 |    1 +
>>  arch/arm/mach-pxa/include/mach/ohci.h       |    2 +
>>  arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h |   12 +++--
>>  arch/arm/mach-pxa/pxa3xx-ulpi.c             |   66 +++++++++++++++++++--------
>>  drivers/usb/host/ohci-pxa27x.c              |    8 ++--
>>  5 files changed, 62 insertions(+), 27 deletions(-)
>>
>> diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
>> index 8e0b562..952b475 100644
>> --- a/arch/arm/mach-pxa/cm-x300.c
>> +++ b/arch/arm/mach-pxa/cm-x300.c
>> @@ -566,6 +566,7 @@ static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
>>  
>>  static void __init cm_x300_init_ohci(void)
>>  {
>> +	cm_x300_ohci_platform_data.u2d_hc_ops = pxa3xx_get_u2d_hc_ops();
>>  	pxa_set_ohci_info(&cm_x300_ohci_platform_data);
>>  }
>>  #else
>> diff --git a/arch/arm/mach-pxa/include/mach/ohci.h b/arch/arm/mach-pxa/include/mach/ohci.h
>> index 95b6e2a..0924e26 100644
>> --- a/arch/arm/mach-pxa/include/mach/ohci.h
>> +++ b/arch/arm/mach-pxa/include/mach/ohci.h
>> @@ -29,6 +29,8 @@ struct pxaohci_platform_data {
>>  #define PMM_PERPORT_MODE       3
>>  
>>  	int power_budget;
>> +
>> +	struct pxa3xx_u2d_hc_ops *u2d_hc_ops;
>>  };
>>  
>>  extern void pxa_set_ohci_info(struct pxaohci_platform_data *info);
>> diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
>> index 9d82cb6..6f37f43 100644
>> --- a/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
>> +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
>> @@ -25,10 +25,14 @@ struct pxa3xx_u2d_platform_data {
>>  };
>>  
>>  
>> -/* Start PXA3xx U2D host */
>> -int pxa3xx_u2d_start_hc(struct usb_bus *host);
>> -/* Stop PXA3xx U2D host */
>> -void pxa3xx_u2d_stop_hc(struct usb_bus *host);
>> +struct pxa3xx_u2d_hc_ops {
>> +	/* Start PXA3xx U2D host */
>> +	int (*start_hc)(struct usb_bus *host);
>> +	/* Stop PXA3xx U2D host */
>> +	void (*stop_hc)(struct usb_bus *host);
>> +};
>> +
>> +struct pxa3xx_u2d_hc_ops *pxa3xx_get_u2d_hc_ops(void);
>>  
>>  extern void pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info);
>>  
>> diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
>> index ce7168b..7e76cbe 100644
>> --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c
>> +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
>> @@ -234,27 +234,18 @@ static void pxa310_otg_exit(void)
>>  {
>>  	kfree(u2d->otg);
>>  }
>> -#else
>> -static inline void pxa310_u2d_setup_otg_hc(void) {}
>> -static inline int pxa310_start_otg_hc(struct usb_bus *host)
>> -{
>> -	return 0;
>> -}
>> -static inline void pxa310_stop_otg_hc(void) {}
>> -static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
>> -{
>> -	return 0;
>> -}
>> -static inline void pxa310_otg_exit(void) {}
>> -#endif /* CONFIG_PXA310_ULPI */
>>  
>> -int pxa3xx_u2d_start_hc(struct usb_bus *host)
>> +static int pxa3xx_u2d_start_hc(struct usb_bus *host)
>>  {
>>  	int err = 0;
>>  
>> -	/* In case the PXA3xx ULPI isn't used, do nothing. */
>> -	if (!u2d)
>> +	if (!u2d) {
>> +		pr_err("%s: Error: u2d struct is not initialized! "
>> +		       "ULPI enabed, but pxa3xx-u2d device not registered?",
>> +		       __func__);
>> +
>>  		return 0;
>> +	}
>>  
>>  	clk_enable(u2d->clk);
>>  
>> @@ -266,11 +257,15 @@ int pxa3xx_u2d_start_hc(struct usb_bus *host)
>>  	return err;
>>  }
>>  
>> -void pxa3xx_u2d_stop_hc(struct usb_bus *host)
>> +static void pxa3xx_u2d_stop_hc(struct usb_bus *host)
>>  {
>> -	/* In case the PXA3xx ULPI isn't used, do nothing. */
>> -	if (!u2d)
>> +	if (!u2d) {
>> +		pr_err("%s: Error: u2d struct is not initialized! "
>> +		       "ULPI enabed, but pxa3xx-u2d device not registered?",
>> +		       __func__);
>> +
>>  		return;
>> +	}
>>  
>>  	if (cpu_is_pxa310())
>>  		pxa310_stop_otg_hc();
>> @@ -278,6 +273,39 @@ void pxa3xx_u2d_stop_hc(struct usb_bus *host)
>>  	clk_disable(u2d->clk);
>>  }
>>  
>> +static struct pxa3xx_u2d_hc_ops u2d_hc_ops = {
>> +	.start_hc	= pxa3xx_u2d_start_hc,
>> +	.stop_hc	= pxa3xx_u2d_stop_hc,
>> +};
>> +
>> +struct pxa3xx_u2d_hc_ops *pxa3xx_get_u2d_hc_ops(void)
>> +{
>> +	return &u2d_hc_ops;
>> +}
>> +#else
>> +static inline void pxa310_u2d_setup_otg_hc(void) {}
>> +static inline int pxa310_start_otg_hc(struct usb_bus *host)
>> +{
>> +	return 0;
>> +}
>> +static inline void pxa310_stop_otg_hc(void) {}
>> +static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
>> +{
>> +	return 0;
>> +}
>> +static inline void pxa310_otg_exit(void) {}
>> +static inline int pxa3xx_u2d_start_hc(struct usb_bus *host)
>> +{
>> +	return 0;
>> +}
>> +static inline void pxa3xx_u2d_stop_hc(struct usb_bus *host) {}
>> +
>> +struct pxa3xx_u2d_hc_ops *pxa3xx_get_u2d_hc_ops(void)
>> +{
>> +	return NULL;
>> +}
>> +#endif /* CONFIG_PXA310_ULPI */
>> +
>>  static int pxa3xx_u2d_probe(struct platform_device *pdev)
>>  {
>>  	struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
>> diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
>> index afef7b0..61ff775 100644
>> --- a/drivers/usb/host/ohci-pxa27x.c
>> +++ b/drivers/usb/host/ohci-pxa27x.c
>> @@ -236,8 +236,8 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
>>  	if (retval < 0)
>>  		return retval;
>>  
>> -	if (cpu_is_pxa3xx())
>> -		pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
>> +	if (cpu_is_pxa3xx() && inf->u2d_hc_ops)
>> +		inf->u2d_hc_ops->start_hc(&ohci_to_hcd(&ohci->ohci)->self);
>>  
>>  	uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
>>  	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
>> @@ -255,8 +255,8 @@ static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
>>  
>>  	inf = dev->platform_data;
>>  
>> -	if (cpu_is_pxa3xx())
>> -		pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
>> +	if (cpu_is_pxa3xx() && inf->u2d_hc_ops)
>> +		inf->u2d_hc_ops->stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
>>  
>>  	if (inf->exit)
>>  		inf->exit(dev);

-- 
Regards,
Igor.




More information about the linux-arm-kernel mailing list