Re: [PATCH v5 2/3] usb: chipidea: add freescale imx28 special write register method

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

 



On Fri, Nov 22, 2013 at 10:53:55AM +0100, Marc Kleine-Budde wrote:
> From: Peter Chen <peter.chen@xxxxxxxxxxxxx>
> 
> According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB
> register error issue", All USB register write operations must
> use the ARM SWP instruction. So, we implement special hw_write
> and hw_test_and_clear for imx28.
> 
> Discussion for it at below:
> http://marc.info/?l=linux-usb&m=137996395529294&w=2
> 
> Signed-off-by: Peter Chen <peter.chen@xxxxxxxxxxxxx>
> Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
> ---
>  drivers/usb/chipidea/ci.h    | 26 ++++++++++++++++++++++++--
>  drivers/usb/chipidea/core.c  |  2 ++
>  drivers/usb/chipidea/host.c  |  1 +
>  include/linux/usb/chipidea.h |  1 +
>  4 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index 1c94fc5..f2855be 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -173,6 +173,8 @@ struct ci_hdrc {
>  	struct dentry			*debugfs;
>  	bool				id_event;
>  	bool				b_sess_valid_event;
> +	/* imx28 needs swp instruction for writing */
> +	bool				imx28_write_fix;
>  };

Please remove the comment, and add it to the kernel doc style comment
above.

Peter


>  
>  static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
> @@ -253,6 +255,26 @@ static inline u32 hw_read(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask)
>  	return ioread32(ci->hw_bank.regmap[reg]) & mask;
>  }
>  
> +#ifdef CONFIG_SOC_IMX28
> +static inline void imx28_ci_writel(u32 val, void __iomem *addr)
> +{
> +	__asm__ ("swp %0, %0, [%1]" : : "r"(val), "r"(addr));
> +}
> +#else
> +static inline void imx28_ci_writel(u32 val, void __iomem *addr)
> +{
> +}
> +#endif
> +
> +static inline void __hw_write(struct ci_hdrc *ci, u32 val,
> +		void __iomem *addr)
> +{
> +	if (IS_ENABLED(CONFIG_SOC_IMX28) && ci->imx28_write_fix)
> +		imx28_ci_writel(val, addr);
> +	else
> +		iowrite32(val, addr);
> +}
> +
>  /**
>   * hw_write: writes to a hw register
>   * @reg:  register index
> @@ -266,7 +288,7 @@ static inline void hw_write(struct ci_hdrc *ci, enum ci_hw_regs reg,
>  		data = (ioread32(ci->hw_bank.regmap[reg]) & ~mask)
>  			| (data & mask);
>  
> -	iowrite32(data, ci->hw_bank.regmap[reg]);
> +	__hw_write(ci, data, ci->hw_bank.regmap[reg]);
>  }
>  
>  /**
> @@ -281,7 +303,7 @@ static inline u32 hw_test_and_clear(struct ci_hdrc *ci, enum ci_hw_regs reg,
>  {
>  	u32 val = ioread32(ci->hw_bank.regmap[reg]) & mask;
>  
> -	iowrite32(val, ci->hw_bank.regmap[reg]);
> +	__hw_write(ci, val, ci->hw_bank.regmap[reg]);
>  	return val;
>  }
>  
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 98f45f1..40e1ed1 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -531,6 +531,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  
>  	ci->dev = dev;
>  	ci->platdata = dev->platform_data;
> +	ci->imx28_write_fix = !!(ci->platdata->flags &
> +		CI_HDRC_IMX28_WRITE_FIX);
>  
>  	ret = hw_device_init(ci, base);
>  	if (ret < 0) {
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index 59e6020..06fd042 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -65,6 +65,7 @@ static int host_start(struct ci_hdrc *ci)
>  	ehci->caps = ci->hw_bank.cap;
>  	ehci->has_hostpc = ci->hw_bank.lpm;
>  	ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
> +	ehci->imx28_write_fix = ci->imx28_write_fix;
>  
>  	if (ci->platdata->reg_vbus) {
>  		ret = regulator_enable(ci->platdata->reg_vbus);
> diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
> index 7d39967..708bd11 100644
> --- a/include/linux/usb/chipidea.h
> +++ b/include/linux/usb/chipidea.h
> @@ -24,6 +24,7 @@ struct ci_hdrc_platform_data {
>  	 * but otg is not supported (no register otgsc).
>  	 */
>  #define CI_HDRC_DUAL_ROLE_NOT_OTG	BIT(4)
> +#define CI_HDRC_IMX28_WRITE_FIX		BIT(5)
>  	enum usb_dr_mode	dr_mode;
>  #define CI_HDRC_CONTROLLER_RESET_EVENT		0
>  #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
> -- 
> 1.8.4.2
> 
> 

-- 

Best Regards,
Peter Chen

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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux