[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