On Wed, Sep 09, 2015 at 10:18:39AM +0800, Li Jun wrote: > Add imx7d usb support. > > Signed-off-by: Li Jun <jun.li@xxxxxxxxxxxxx> > --- > drivers/usb/chipidea/ci_hdrc_imx.c | 7 ++++ > drivers/usb/chipidea/usbmisc_imx.c | 62 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 69 insertions(+) > > diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c > index 867e9f3..f9deea5 100644 > --- a/drivers/usb/chipidea/ci_hdrc_imx.c > +++ b/drivers/usb/chipidea/ci_hdrc_imx.c > @@ -56,12 +56,19 @@ static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = { > CI_HDRC_DISABLE_HOST_STREAMING, > }; > > +static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = { > + .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | > + CI_HDRC_TURN_VBUS_EARLY_ON | > + CI_HDRC_DISABLE_HOST_STREAMING, > +}; > + For imx7, it uses v2.5 core, we don't need to disable stream mode for host. The reason for i.mx to disable host stream mode is below issue (see 8022d3d51c6fb14736e26fd13caca91a38e07580) TAR 9000378958 Title: Non-Double Word Aligned Buffer Address Sometimes Causes Host to Hang on OUT Retry At v2.5 core, this bug has fixed by IP vendor. > static const struct of_device_id ci_hdrc_imx_dt_ids[] = { > { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, > { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data}, > { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data}, > { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data}, > { .compatible = "fsl,imx6sx-usb", .data = &imx6sl_usb_data}, > + { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); > diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c > index 5ddab30..f3a4753 100644 > --- a/drivers/usb/chipidea/usbmisc_imx.c > +++ b/drivers/usb/chipidea/usbmisc_imx.c > @@ -72,6 +72,14 @@ > > #define VF610_OVER_CUR_DIS BIT(7) > > +#define MX7D_USBNC_USB_CTRL2 0x4 > +#define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3 > +#define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0) > +#define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0) > +#define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1) > +#define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) > +#define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) > + > struct usbmisc_ops { > /* It's called once when probe a usb device */ > int (*init)(struct imx_usbmisc_data *data); > @@ -324,6 +332,55 @@ static int usbmisc_vf610_init(struct imx_usbmisc_data *data) > return 0; > } > > +static int usbmisc_imx7d_set_wakeup > + (struct imx_usbmisc_data *data, bool enabled) > +{ > + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > + unsigned long flags; > + u32 val; > + u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE | > + MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP); > + > + spin_lock_irqsave(&usbmisc->lock, flags); > + val = readl(usbmisc->base); > + if (enabled) { > + writel(val | wakeup_setting, usbmisc->base); > + } else { > + if (val & MX6_BM_WAKEUP_INTR) > + dev_dbg(data->dev, "wakeup int\n"); > + writel(val & ~wakeup_setting, usbmisc->base); > + } > + spin_unlock_irqrestore(&usbmisc->lock, flags); > + > + return 0; > +} > + > +static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) > +{ > + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > + unsigned long flags; > + u32 reg; > + > + if (data->index >= 1) > + return -EINVAL; > + > + spin_lock_irqsave(&usbmisc->lock, flags); > + if (data->disable_oc) { > + reg = readl(usbmisc->base); > + writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base); > + } > + > + reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); > + reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; > + writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, > + usbmisc->base + MX7D_USBNC_USB_CTRL2); > + spin_unlock_irqrestore(&usbmisc->lock, flags); > + > + usbmisc_imx7d_set_wakeup(data, false); > + > + return 0; > +} > + > static const struct usbmisc_ops imx25_usbmisc_ops = { > .init = usbmisc_imx25_init, > .post = usbmisc_imx25_post, > @@ -351,6 +408,11 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = { > .init = usbmisc_imx6sx_init, > }; > > +static const struct usbmisc_ops imx7d_usbmisc_ops = { > + .init = usbmisc_imx7d_init, > + .set_wakeup = usbmisc_imx7d_set_wakeup, > +}; > + > int imx_usbmisc_init(struct imx_usbmisc_data *data) > { > struct imx_usbmisc *usbmisc; > -- > 1.7.9.5 > -- 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