From 22835b807e7ca946a4d1fbd4c7af56aa09cd273e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 12:05:12 -0500 Subject: usb: gadget: remove unnecessary 'driver' argument now that no UDC driver relies on the extra 'driver' argument to ->udc_stop(), we can safely remove it. This commit is based on previous work by Robert Baldyga which can be found at [1]; however that patch turned out to have a high probability of regressing many UDC drivers because of a blind search & replace s/driver/$udc->driver/ which caused the 'driver' argument to stop_activity() to be a valid non-NULL pointer when it should be NULL, thus causing UDCs to mistakenly call gadget driver's ->disconnect() callback. [1] http://markmail.org/message/x5zneg4xea4zntab Acked-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 0444d3f8971a..f4397b29891f 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1544,8 +1544,7 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on) static int ci_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); -static int ci_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver); +static int ci_udc_stop(struct usb_gadget *gadget); /** * Device operations part of the API to the USB controller hardware, * which don't involve endpoints (or i/o) @@ -1682,8 +1681,7 @@ static int ci_udc_start(struct usb_gadget *gadget, /** * ci_udc_stop: unregister a gadget driver */ -static int ci_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int ci_udc_stop(struct usb_gadget *gadget) { struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); unsigned long flags; -- cgit v1.2.3 From e47d92545c2972bcf3711e7db80f481e402163c7 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:13 +0100 Subject: usb: move the OTG state from the USB PHY to the OTG structure Before using the PHY framework instead of the USB PHY one, we need to move the OTG state into another place, since it won't be available when USB PHY isn't used. This patch moves the OTG state into the OTG structure, and makes all the needed modifications in the drivers using the OTG state. [ balbi@ti.com : fix build regressions with phy-tahvo.c, musb_dsps.c, phy-isp1301-omap, and chipidea's debug.c ] Acked-by: Kishon Vijay Abraham I Acked-by: Peter Chen Signed-off-by: Antoine Tenart Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/debug.c | 2 +- drivers/usb/chipidea/otg_fsm.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 795d6538d630..f038804d13dd 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -220,7 +220,7 @@ static int ci_otg_show(struct seq_file *s, void *unused) /* ------ State ----- */ seq_printf(s, "OTG state: %s\n\n", - usb_otg_state_string(ci->transceiver->state)); + usb_otg_state_string(ci->transceiver->otg->state)); /* ------ State Machine Variables ----- */ seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop); diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index caaabc58021e..8cb2508a6b71 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -328,7 +328,7 @@ static void b_ssend_srp_tmout_func(void *ptr, unsigned long indicator) set_tmout(ci, indicator); /* only vbus fall below B_sess_vld in b_idle state */ - if (ci->transceiver->state == OTG_STATE_B_IDLE) + if (ci->fsm.otg->state == OTG_STATE_B_IDLE) ci_otg_queue_work(ci); } @@ -582,11 +582,11 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) * when there is no gadget class driver */ if (ci->fsm.id && !(ci->driver) && - ci->transceiver->state < OTG_STATE_A_IDLE) + ci->fsm.otg->state < OTG_STATE_A_IDLE) return 0; if (otg_statemachine(&ci->fsm)) { - if (ci->transceiver->state == OTG_STATE_A_IDLE) { + if (ci->fsm.otg->state == OTG_STATE_A_IDLE) { /* * Further state change for cases: * a_idle to b_idle; or @@ -600,7 +600,7 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) ci_otg_queue_work(ci); if (ci->id_event) ci->id_event = false; - } else if (ci->transceiver->state == OTG_STATE_B_IDLE) { + } else if (ci->fsm.otg->state == OTG_STATE_B_IDLE) { if (ci->fsm.b_sess_vld) { ci->fsm.power_up = 0; /* @@ -627,7 +627,7 @@ static void ci_otg_fsm_event(struct ci_hdrc *ci) otg_bsess_vld = hw_read_otgsc(ci, OTGSC_BSV); port_conn = hw_read(ci, OP_PORTSC, PORTSC_CCS); - switch (ci->transceiver->state) { + switch (ci->fsm.otg->state) { case OTG_STATE_A_WAIT_BCON: if (port_conn) { fsm->b_conn = 1; @@ -794,7 +794,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) ci->transceiver->otg = ci->fsm.otg; ci->fsm.power_up = 1; ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; - ci->transceiver->state = OTG_STATE_UNDEFINED; + ci->fsm.otg->state = OTG_STATE_UNDEFINED; ci->fsm.ops = &ci_otg_ops; mutex_init(&ci->fsm.lock); -- cgit v1.2.3 From 19c1eac2685b62640ca2386a0a885ac2152668c8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:14 +0100 Subject: usb: rename phy to usb_phy in OTG This patch prepares the introduction of the generic PHY support in the USB OTG common functions. The USB PHY member of the OTG structure is renamed to 'usb_phy' and modifications are done in all drivers accessing it. Renaming this pointer will allow to keep the compatibility for USB PHY drivers. Signed-off-by: Antoine Tenart Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/otg_fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 8cb2508a6b71..d8490e758a74 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -788,7 +788,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) return -ENOMEM; } - otg->phy = ci->transceiver; + otg->usb_phy = ci->transceiver; otg->gadget = &ci->gadget; ci->fsm.otg = otg; ci->transceiver->otg = ci->fsm.otg; -- cgit v1.2.3 From ef44cb4226d132146e44f8ea562a16b27ff61126 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:16 +0100 Subject: usb: allow to supply the PHY in the drivers when using HCD This patch modify the generic code handling PHYs to allow them to be supplied from the drivers. This adds checks to ensure no PHY was already there when looking for one in the generic code. This also makes sure we do not modify its state in the generic HCD functions, it was provided by the driver. Signed-off-by: Antoine Tenart Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/ci.h | 5 +++-- drivers/usb/chipidea/ci_hdrc_imx.c | 2 +- drivers/usb/chipidea/ci_hdrc_msm.c | 8 ++++---- drivers/usb/chipidea/core.c | 20 ++++++++++---------- drivers/usb/chipidea/debug.c | 2 +- drivers/usb/chipidea/host.c | 7 ++++--- drivers/usb/chipidea/otg_fsm.c | 16 +++------------- drivers/usb/chipidea/udc.c | 4 ++-- 8 files changed, 28 insertions(+), 36 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index ea40626e0246..9015139a8027 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -161,7 +161,7 @@ struct hw_bank { * @test_mode: the selected test mode * @platdata: platform specific information supplied by parent device * @vbus_active: is VBUS active - * @transceiver: pointer to USB PHY, if any + * @usb_phy: pointer to USB PHY, if any * @hcd: pointer to usb_hcd for ehci host driver * @debugfs: root dentry for this controller in debugfs * @id_event: indicates there is an id event, and handled at ci_otg_work @@ -177,6 +177,7 @@ struct ci_hdrc { struct ci_role_driver *roles[CI_ROLE_END]; enum ci_role role; bool is_otg; + struct usb_otg otg; struct otg_fsm fsm; struct ci_otg_fsm_timer_list *fsm_timer; struct work_struct work; @@ -201,7 +202,7 @@ struct ci_hdrc { struct ci_hdrc_platform_data *platdata; int vbus_active; - struct usb_phy *transceiver; + struct usb_phy *usb_phy; struct usb_hcd *hcd; struct dentry *debugfs; bool id_event; diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index a7ab0f15926e..6f8b1b1045b5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -147,7 +147,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } - pdata.phy = data->phy; + pdata.usb_phy = data->phy; if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX) pdata.flags |= CI_HDRC_IMX28_WRITE_FIX; diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 4935ac38fd00..3edf969ed797 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -26,15 +26,15 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); writel(0, USB_AHBBURST); writel(0, USB_AHBMODE); - usb_phy_init(ci->transceiver); + usb_phy_init(ci->usb_phy); break; case CI_HDRC_CONTROLLER_STOPPED_EVENT: dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n"); /* - * Put the transceiver in non-driving mode. Otherwise host + * Put the phy in non-driving mode. Otherwise host * may not detect soft-disconnection. */ - usb_phy_notify_disconnect(ci->transceiver, USB_SPEED_UNKNOWN); + usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN); break; default: dev_dbg(dev, "unknown ci_hdrc event\n"); @@ -68,7 +68,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (IS_ERR(phy)) return PTR_ERR(phy); - ci_hdrc_msm_platdata.phy = phy; + ci_hdrc_msm_platdata.usb_phy = phy; plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource, pdev->num_resources, diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9bdc6bd73432..30f89426bf05 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -312,7 +312,7 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_UTMI: case USBPHY_INTERFACE_MODE_UTMIW: case USBPHY_INTERFACE_MODE_HSIC: - ret = usb_phy_init(ci->transceiver); + ret = usb_phy_init(ci->usb_phy); if (ret) return ret; hw_phymode_configure(ci); @@ -320,12 +320,12 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_ULPI: case USBPHY_INTERFACE_MODE_SERIAL: hw_phymode_configure(ci); - ret = usb_phy_init(ci->transceiver); + ret = usb_phy_init(ci->usb_phy); if (ret) return ret; break; default: - ret = usb_phy_init(ci->transceiver); + ret = usb_phy_init(ci->usb_phy); } return ret; @@ -605,13 +605,13 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENODEV; } - if (ci->platdata->phy) - ci->transceiver = ci->platdata->phy; + if (ci->platdata->usb_phy) + ci->usb_phy = ci->platdata->usb_phy; else - ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - if (IS_ERR(ci->transceiver)) { - ret = PTR_ERR(ci->transceiver); + if (IS_ERR(ci->usb_phy)) { + ret = PTR_ERR(ci->usb_phy); /* * if -ENXIO is returned, it means PHY layer wasn't * enabled, so it makes no sense to return -EPROBE_DEFER @@ -728,7 +728,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) stop: ci_role_destroy(ci); deinit_phy: - usb_phy_shutdown(ci->transceiver); + usb_phy_shutdown(ci->usb_phy); return ret; } @@ -741,7 +741,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) free_irq(ci->irq, ci); ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); - usb_phy_shutdown(ci->transceiver); + usb_phy_shutdown(ci->usb_phy); return 0; } diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index f038804d13dd..268e4236e84c 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -220,7 +220,7 @@ static int ci_otg_show(struct seq_file *s, void *unused) /* ------ State ----- */ seq_printf(s, "OTG state: %s\n\n", - usb_otg_state_string(ci->transceiver->otg->state)); + usb_otg_state_string(ci->otg.state)); /* ------ State Machine Variables ----- */ seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop); diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebde7b6ce687..789809f680aa 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -59,7 +59,7 @@ static int host_start(struct ci_hdrc *ci) hcd->has_tt = 1; hcd->power_budget = ci->platdata->power_budget; - hcd->usb_phy = ci->transceiver; + hcd->usb_phy = ci->usb_phy; hcd->tpl_support = ci->platdata->tpl_support; ehci = hcd_to_ehci(hcd); @@ -86,10 +86,11 @@ static int host_start(struct ci_hdrc *ci) if (ret) { goto disable_reg; } else { - struct usb_otg *otg = ci->transceiver->otg; + struct usb_otg *otg = &ci->otg; ci->hcd = hcd; - if (otg) { + + if (ci_otg_is_fsm_mode(ci)) { otg->host = &hcd->self; hcd->self.otg_port = 1; } diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index d8490e758a74..862d7cb01b92 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -778,20 +778,10 @@ void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci) int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) { int retval = 0; - struct usb_otg *otg; - otg = devm_kzalloc(ci->dev, - sizeof(struct usb_otg), GFP_KERNEL); - if (!otg) { - dev_err(ci->dev, - "Failed to allocate usb_otg structure for ci hdrc otg!\n"); - return -ENOMEM; - } - - otg->usb_phy = ci->transceiver; - otg->gadget = &ci->gadget; - ci->fsm.otg = otg; - ci->transceiver->otg = ci->fsm.otg; + ci->otg.usb_phy = ci->usb_phy; + ci->otg.gadget = &ci->gadget; + ci->fsm.otg = &ci->otg; ci->fsm.power_up = 1; ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; ci->fsm.otg->state = OTG_STATE_UNDEFINED; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index f4397b29891f..a2d80ab3d9c4 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1519,8 +1519,8 @@ static int ci_udc_vbus_draw(struct usb_gadget *_gadget, unsigned ma) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); - if (ci->transceiver) - return usb_phy_set_power(ci->transceiver, ma); + if (ci->usb_phy) + return usb_phy_set_power(ci->usb_phy, ma); return -ENOTSUPP; } -- cgit v1.2.3 From 1e5e2d3d055436c114e2f16145b83339aed024ff Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:19 +0100 Subject: usb: chipidea: add support to the generic PHY framework This patch adds support of the PHY framework for ChipIdea drivers. Changes are done in both the ChipIdea common code and in the drivers accessing the PHY. This is done by adding a new PHY member in ChipIdea's structures and by taking care of it in the code. Signed-off-by: Antoine Tenart Acked-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/ci.h | 5 ++- drivers/usb/chipidea/core.c | 83 +++++++++++++++++++++++++++++++++--------- drivers/usb/chipidea/host.c | 5 ++- drivers/usb/chipidea/otg_fsm.c | 6 ++- 4 files changed, 78 insertions(+), 21 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 9015139a8027..5bbfcc73cf70 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -161,7 +161,8 @@ struct hw_bank { * @test_mode: the selected test mode * @platdata: platform specific information supplied by parent device * @vbus_active: is VBUS active - * @usb_phy: pointer to USB PHY, if any + * @phy: pointer to PHY, if any + * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework * @hcd: pointer to usb_hcd for ehci host driver * @debugfs: root dentry for this controller in debugfs * @id_event: indicates there is an id event, and handled at ci_otg_work @@ -202,6 +203,8 @@ struct ci_hdrc { struct ci_hdrc_platform_data *platdata; int vbus_active; + struct phy *phy; + /* old usb_phy interface */ struct usb_phy *usb_phy; struct usb_hcd *hcd; struct dentry *debugfs; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 30f89426bf05..60578d9c896d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,49 @@ static void hw_phymode_configure(struct ci_hdrc *ci) } } +/** + * _ci_usb_phy_init: initialize phy taking in account both phy and usb_phy + * interfaces + * @ci: the controller + * + * This function returns an error code if the phy failed to init + */ +static int _ci_usb_phy_init(struct ci_hdrc *ci) +{ + int ret; + + if (ci->phy) { + ret = phy_init(ci->phy); + if (ret) + return ret; + + ret = phy_power_on(ci->phy); + if (ret) { + phy_exit(ci->phy); + return ret; + } + } else { + ret = usb_phy_init(ci->usb_phy); + } + + return ret; +} + +/** + * _ci_usb_phy_exit: deinitialize phy taking in account both phy and usb_phy + * interfaces + * @ci: the controller + */ +static void ci_usb_phy_exit(struct ci_hdrc *ci) +{ + if (ci->phy) { + phy_power_off(ci->phy); + phy_exit(ci->phy); + } else { + usb_phy_shutdown(ci->usb_phy); + } +} + /** * ci_usb_phy_init: initialize phy according to different phy type * @ci: the controller @@ -312,7 +356,7 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_UTMI: case USBPHY_INTERFACE_MODE_UTMIW: case USBPHY_INTERFACE_MODE_HSIC: - ret = usb_phy_init(ci->usb_phy); + ret = _ci_usb_phy_init(ci); if (ret) return ret; hw_phymode_configure(ci); @@ -320,12 +364,12 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_ULPI: case USBPHY_INTERFACE_MODE_SERIAL: hw_phymode_configure(ci); - ret = usb_phy_init(ci->usb_phy); + ret = _ci_usb_phy_init(ci); if (ret) return ret; break; default: - ret = usb_phy_init(ci->usb_phy); + ret = _ci_usb_phy_init(ci); } return ret; @@ -605,23 +649,26 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENODEV; } - if (ci->platdata->usb_phy) + if (ci->platdata->phy) { + ci->phy = ci->platdata->phy; + } else if (ci->platdata->usb_phy) { ci->usb_phy = ci->platdata->usb_phy; - else + } else { + ci->phy = devm_phy_get(dev, "usb-phy"); ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - if (IS_ERR(ci->usb_phy)) { - ret = PTR_ERR(ci->usb_phy); - /* - * if -ENXIO is returned, it means PHY layer wasn't - * enabled, so it makes no sense to return -EPROBE_DEFER - * in that case, since no PHY driver will ever probe. - */ - if (ret == -ENXIO) - return ret; + /* if both generic PHY and USB PHY layers aren't enabled */ + if (PTR_ERR(ci->phy) == -ENOSYS && + PTR_ERR(ci->usb_phy) == -ENXIO) + return -ENXIO; + + if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) + return -EPROBE_DEFER; - dev_err(dev, "no usb2 phy configured\n"); - return -EPROBE_DEFER; + if (IS_ERR(ci->phy)) + ci->phy = NULL; + else if (IS_ERR(ci->usb_phy)) + ci->usb_phy = NULL; } ret = ci_usb_phy_init(ci); @@ -728,7 +775,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) stop: ci_role_destroy(ci); deinit_phy: - usb_phy_shutdown(ci->usb_phy); + ci_usb_phy_exit(ci); return ret; } @@ -741,7 +788,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) free_irq(ci->irq, ci); ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); - usb_phy_shutdown(ci->usb_phy); + ci_usb_phy_exit(ci); return 0; } diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 789809f680aa..4f8eb40ad93a 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -59,8 +59,11 @@ static int host_start(struct ci_hdrc *ci) hcd->has_tt = 1; hcd->power_budget = ci->platdata->power_budget; - hcd->usb_phy = ci->usb_phy; hcd->tpl_support = ci->platdata->tpl_support; + if (ci->phy) + hcd->phy = ci->phy; + else + hcd->usb_phy = ci->usb_phy; ehci = hcd_to_ehci(hcd); ehci->caps = ci->hw_bank.cap; diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 862d7cb01b92..3c2ab1ae00fc 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -779,7 +779,11 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) { int retval = 0; - ci->otg.usb_phy = ci->usb_phy; + if (ci->phy) + ci->otg.phy = ci->phy; + else + ci->otg.usb_phy = ci->usb_phy; + ci->otg.gadget = &ci->gadget; ci->fsm.otg = &ci->otg; ci->fsm.power_up = 1; -- cgit v1.2.3 From c8679a2fb8decc949c848ca58f93ff7fb619931a Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Mon, 13 Oct 2014 09:53:04 +0800 Subject: usb: chipidea: host: add portpower override This patch adds an external portpower override callback, only single port regulator control is supported now. Signed-off-by: Michael Grzeschik Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/host.c | 67 +++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 21 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebde7b6ce687..33027abb5349 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -34,6 +34,44 @@ static struct hc_driver __read_mostly ci_ehci_hc_driver; +struct ehci_ci_priv { + struct regulator *reg_vbus; +}; + +static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; + struct device *dev = hcd->self.controller; + struct ci_hdrc *ci = dev_get_drvdata(dev); + int ret = 0; + int port = HCS_N_PORTS(ehci->hcs_params); + + if (priv->reg_vbus && !ci_otg_is_fsm_mode(ci)) { + if (port > 1) { + dev_warn(dev, + "Not support multi-port regulator control\n"); + return 0; + } + if (enable) + ret = regulator_enable(priv->reg_vbus); + else + ret = regulator_disable(priv->reg_vbus); + if (ret) { + dev_err(dev, + "Failed to %s vbus regulator, ret=%d\n", + enable ? "enable" : "disable", ret); + return ret; + } + } + return 0; +}; + +static const struct ehci_driver_overrides ehci_ci_overrides = { + .extra_priv_size = sizeof(struct ehci_ci_priv), + .port_power = ehci_ci_portpower, +}; + static irqreturn_t host_irq(struct ci_hdrc *ci) { return usb_hcd_irq(ci->irq, ci->hcd); @@ -43,6 +81,7 @@ static int host_start(struct ci_hdrc *ci) { struct usb_hcd *hcd; struct ehci_hcd *ehci; + struct ehci_ci_priv *priv; int ret; if (usb_disabled()) @@ -68,23 +107,15 @@ static int host_start(struct ci_hdrc *ci) ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; ehci->imx28_write_fix = ci->imx28_write_fix; - /* - * vbus is always on if host is not in OTG FSM mode, - * otherwise should be controlled by OTG FSM - */ - if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { - ret = regulator_enable(ci->platdata->reg_vbus); - if (ret) { - dev_err(ci->dev, - "Failed to enable vbus regulator, ret=%d\n", - ret); - goto put_hcd; - } - } + priv = (struct ehci_ci_priv *)ehci->priv; + priv->reg_vbus = NULL; + + if (ci->platdata->reg_vbus) + priv->reg_vbus = ci->platdata->reg_vbus; ret = usb_add_hcd(hcd, 0, 0); if (ret) { - goto disable_reg; + goto put_hcd; } else { struct usb_otg *otg = ci->transceiver->otg; @@ -100,10 +131,6 @@ static int host_start(struct ci_hdrc *ci) return ret; -disable_reg: - if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) - regulator_disable(ci->platdata->reg_vbus); - put_hcd: usb_put_hcd(hcd); @@ -117,8 +144,6 @@ static void host_stop(struct ci_hdrc *ci) if (hcd) { usb_remove_hcd(hcd); usb_put_hcd(hcd); - if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) - regulator_disable(ci->platdata->reg_vbus); } } @@ -146,7 +171,7 @@ int ci_hdrc_host_init(struct ci_hdrc *ci) rdrv->name = "host"; ci->roles[CI_ROLE_HOST] = rdrv; - ehci_init_driver(&ci_ehci_hc_driver, NULL); + ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides); return 0; } -- cgit v1.2.3 From 51f1741fcc166dd93d38c7a3212f195d84aa67df Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:55:55 +0800 Subject: usb: chipidea: otg_fsm: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/otg_fsm.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index caaabc58021e..e683595f9e69 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -782,11 +782,8 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) otg = devm_kzalloc(ci->dev, sizeof(struct usb_otg), GFP_KERNEL); - if (!otg) { - dev_err(ci->dev, - "Failed to allocate usb_otg structure for ci hdrc otg!\n"); + if (!otg) return -ENOMEM; - } otg->phy = ci->transceiver; otg->gadget = &ci->gadget; @@ -801,11 +798,8 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) ci->fsm_timer = devm_kzalloc(ci->dev, sizeof(struct ci_otg_fsm_timer_list), GFP_KERNEL); - if (!ci->fsm_timer) { - dev_err(ci->dev, - "Failed to allocate timer structure for ci hdrc otg!\n"); + if (!ci->fsm_timer) return -ENOMEM; - } INIT_LIST_HEAD(&ci->fsm_timer->active_timers); retval = ci_otg_init_timers(ci); -- cgit v1.2.3 From afbe47758a5931aa1ddd71da53189092f564b230 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:27:58 +0800 Subject: usb: chipidea: gadget: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index a2d80ab3d9c4..bdaa7bac6f4a 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -692,10 +692,8 @@ __acquires(ci->lock) int retval; spin_unlock(&ci->lock); - if (ci->gadget.speed != USB_SPEED_UNKNOWN) { - if (ci->driver) - ci->driver->disconnect(&ci->gadget); - } + if (ci->gadget.speed != USB_SPEED_UNKNOWN) + usb_gadget_udc_reset(&ci->gadget, ci->driver); retval = _gadget_stop_activity(&ci->gadget); if (retval) @@ -709,8 +707,6 @@ __acquires(ci->lock) if (ci->status == NULL) retval = -ENOMEM; - usb_gadget_set_state(&ci->gadget, USB_STATE_DEFAULT); - done: spin_lock(&ci->lock); -- cgit v1.2.3 From 4c503dd5fbdc33118d27f60e5c364d364980d4fd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:22 +0800 Subject: usb: chipidea: using devm_request_irq to instead of request_irq Using devm_request_irq to instead of request_irq. Suggested-by: Arnd Bergmann Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 60578d9c896d..5de1507b798c 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -759,8 +759,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ci); - ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name, - ci); + ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, + ci->platdata->name, ci); if (ret) goto stop; @@ -771,7 +771,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (!ret) return 0; - free_irq(ci->irq, ci); stop: ci_role_destroy(ci); deinit_phy: @@ -785,7 +784,6 @@ static int ci_hdrc_remove(struct platform_device *pdev) struct ci_hdrc *ci = platform_get_drvdata(pdev); dbg_remove_files(ci); - free_irq(ci->irq, ci); ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); ci_usb_phy_exit(ci); -- cgit v1.2.3 From d0f992498e82e656646ad833e3f32ad69cd093e7 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:23 +0800 Subject: usb: chipidea: core: Remove unneeded OOM message MM core code already complains when devm_kzalloc() fails, so no need to print the error locally. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5de1507b798c..cde3d24ebd10 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -633,10 +633,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) return PTR_ERR(base); ci = devm_kzalloc(dev, sizeof(*ci), GFP_KERNEL); - if (!ci) { - dev_err(dev, "can't allocate device\n"); + if (!ci) return -ENOMEM; - } ci->dev = dev; ci->platdata = dev_get_platdata(dev); -- cgit v1.2.3 From 73529828cf896df5017255136b4dc2386dff0850 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:24 +0800 Subject: usb: chipidea: ci_hdrc_imx.c: Remove unneeded OOM message MM core code already complains when devm_kzalloc() fails, so no need to print the error locally. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 6f8b1b1045b5..8b1482aa1291 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -115,10 +115,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) { - dev_err(&pdev->dev, "Failed to allocate ci_hdrc-imx data!\n"); + if (!data) return -ENOMEM; - } data->usbmisc_data = usbmisc_get_init_data(&pdev->dev); if (IS_ERR(data->usbmisc_data)) -- cgit v1.2.3 From 8d1dc4d055faafafca3edd8499aeeef3f77803e4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:25 +0800 Subject: usb: chipidea: usbmisc_imx: Move the reading of USB_PHY_CTRL If 'evdo' property is not defined, then reading the MX25_USB_PHY_CTRL_OFFSET register is an unneeded operation. Move the reading of MX25_USB_PHY_CTRL_OFFSET inside the 'evdo' if block code, where it is actually used. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 926c997ef310..29200ebdd357 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -117,10 +117,9 @@ static int usbmisc_imx25_post(struct imx_usbmisc_data *data) if (data->index > 2) return -EINVAL; - reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; - if (data->evdo) { spin_lock_irqsave(&usbmisc->lock, flags); + reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; val = readl(reg); writel(val | MX25_BM_EXTERNAL_VBUS_DIVIDER, reg); spin_unlock_irqrestore(&usbmisc->lock, flags); -- cgit v1.2.3 From 4a1d6cf156dcf436e5037375007116197f03bfb1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:26 +0800 Subject: usb: chipidea: usbmisc_imx: Read MX53_USB_OTG_PHY_CTRL_1_OFFSET directly There is no need to do an intermediate step for reading the MX53_USB_OTG_PHY_CTRL_1_OFFSET register. Read it directly instead. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 29200ebdd357..58591e9dcede 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -171,8 +171,7 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) return -EINVAL; /* Select a 24 MHz reference clock for the PHY */ - reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET; - val = readl(reg); + val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK; val |= MX53_USB_PLL_DIV_24_MHZ; writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); -- cgit v1.2.3 From 6d037db6409c33738c7153e87ae1cf682ca2851b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:27 +0800 Subject: usb: chipidea: remove the unnecessary delay after clear portsc.phcd The individual PHY driver should take this responsibility if it needs to delay between clear portsc.phcd and let the phy leave low power mode. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index cde3d24ebd10..d87caea261d9 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -196,18 +196,12 @@ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable) enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC; bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm))); - if (enable && !lpm) { + if (enable && !lpm) hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), PORTSC_PHCD(ci->hw_bank.lpm)); - } else if (!enable && lpm) { + else if (!enable && lpm) hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), 0); - /* - * the PHY needs some time (less - * than 1ms) to leave low power mode. - */ - usleep_range(1000, 1100); - } } static int hw_device_init(struct ci_hdrc *ci, void __iomem *base) -- cgit v1.2.3 From b82613cf09455d9a50fbb144ef07b68225f2b452 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:28 +0800 Subject: usb: chipidea: add hw_wait_phy_stable for getting stable status The phy needs some delay to output the stable status from low power mode. And for OTGSC, the status inputs are debounced using a 1 ms time constant, so, delay 2ms for controller to get the stable status(like vbus and id) when the phy leaves low power. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index d87caea261d9..fe3880541efd 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -190,6 +190,17 @@ u8 hw_port_test_get(struct ci_hdrc *ci) return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC); } +static void hw_wait_phy_stable(void) +{ + /* + * The phy needs some delay to output the stable status from low + * power mode. And for OTGSC, the status inputs are debounced + * using a 1 ms time constant, so, delay 2ms for controller to get + * the stable status, like vbus and id when the phy leaves low power. + */ + usleep_range(2000, 2500); +} + /* The PHY enters/leaves low power mode */ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable) { @@ -351,7 +362,9 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_UTMIW: case USBPHY_INTERFACE_MODE_HSIC: ret = _ci_usb_phy_init(ci); - if (ret) + if (!ret) + hw_wait_phy_stable(); + else return ret; hw_phymode_configure(ci); break; @@ -364,6 +377,8 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) break; default: ret = _ci_usb_phy_init(ci); + if (!ret) + hw_wait_phy_stable(); } return ret; @@ -667,13 +682,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (ret) { dev_err(dev, "unable to init phy: %d\n", ret); return ret; - } else { - /* - * The delay to sync PHY's status, the maximum delay is - * 2ms since the otgsc uses 1ms timer to debounce the - * PHY's input - */ - usleep_range(2000, 2500); } ci->hw_bank.phys = res->start; -- cgit v1.2.3 From 8076932ff2fc0f6db0172420e6b148a8b2e8c805 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:29 +0800 Subject: usb: chipidea: add system power management support Add system power management support Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index fe3880541efd..bd74f27a95e5 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -791,11 +791,59 @@ static int ci_hdrc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static void ci_controller_suspend(struct ci_hdrc *ci) +{ + ci_hdrc_enter_lpm(ci, true); + + if (ci->usb_phy) + usb_phy_set_suspend(ci->usb_phy, 1); +} + +static int ci_controller_resume(struct device *dev) +{ + struct ci_hdrc *ci = dev_get_drvdata(dev); + + dev_dbg(dev, "at %s\n", __func__); + + ci_hdrc_enter_lpm(ci, false); + + if (ci->usb_phy) { + usb_phy_set_suspend(ci->usb_phy, 0); + usb_phy_set_wakeup(ci->usb_phy, false); + hw_wait_phy_stable(); + } + + return 0; +} + +static int ci_suspend(struct device *dev) +{ + struct ci_hdrc *ci = dev_get_drvdata(dev); + + if (ci->wq) + flush_workqueue(ci->wq); + + ci_controller_suspend(ci); + + return 0; +} + +static int ci_resume(struct device *dev) +{ + return ci_controller_resume(dev); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops ci_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume) +}; static struct platform_driver ci_hdrc_driver = { .probe = ci_hdrc_probe, .remove = ci_hdrc_remove, .driver = { .name = "ci_hdrc", + .pm = &ci_pm_ops, .owner = THIS_MODULE, }, }; -- cgit v1.2.3 From 2558c1f53bbbb5848fd5910918b97b03249d3885 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:30 +0800 Subject: usb: chipidea: imx: add system power management support Add basic system power management support Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 8b1482aa1291..75421c2187f5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -208,6 +208,41 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int imx_controller_suspend(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + + dev_dbg(dev, "at %s\n", __func__); + + clk_disable_unprepare(data->clk); + + return 0; +} + +static int imx_controller_resume(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + + dev_dbg(dev, "at %s\n", __func__); + + return clk_prepare_enable(data->clk); +} + +static int ci_hdrc_imx_suspend(struct device *dev) +{ + return imx_controller_suspend(dev); +} + +static int ci_hdrc_imx_resume(struct device *dev) +{ + return imx_controller_resume(dev); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume) +}; static struct platform_driver ci_hdrc_imx_driver = { .probe = ci_hdrc_imx_probe, .remove = ci_hdrc_imx_remove, @@ -215,6 +250,7 @@ static struct platform_driver ci_hdrc_imx_driver = { .name = "imx_usb", .owner = THIS_MODULE, .of_match_table = ci_hdrc_imx_dt_ids, + .pm = &ci_hdrc_imx_pm_ops, }, }; -- cgit v1.2.3 From 947c88592f17bd299ff677049c3cda36cc6f93dd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:31 +0800 Subject: usb: chipidea: remove flag CI_HDRC_REQUIRE_TRANSCEIVER Now, USB PHY is mandatory for chipidea core, the flag CI_HDRC_REQUIRE_TRANSCEIVER is useless. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 3 +-- drivers/usb/chipidea/ci_hdrc_msm.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 75421c2187f5..450a168974d5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -106,8 +106,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) struct ci_hdrc_platform_data pdata = { .name = dev_name(&pdev->dev), .capoffset = DEF_CAPOFFSET, - .flags = CI_HDRC_REQUIRE_TRANSCEIVER | - CI_HDRC_DISABLE_STREAMING, + .flags = CI_HDRC_DISABLE_STREAMING, }; int ret; const struct of_device_id *of_id = diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 3edf969ed797..d79ecc08a1be 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -46,7 +46,6 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { .name = "ci_hdrc_msm", .capoffset = DEF_CAPOFFSET, .flags = CI_HDRC_REGS_SHARED | - CI_HDRC_REQUIRE_TRANSCEIVER | CI_HDRC_DISABLE_STREAMING, .notify_event = ci_hdrc_msm_notify_event, -- cgit v1.2.3 From cdd278f21eea55412dd0c5bc468bbdfb0639879b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:32 +0800 Subject: usb: chipidea: add controller reset API Add controller reset API, currently it is used for device mode only. It may be used for host/otg driver in future. Ususally, we need this API for dual-role switch and back from hibernation suspend to let the controller at default state. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index bd74f27a95e5..48b25d9ebf82 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -385,20 +385,44 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) } /** - * hw_device_reset: resets chip (execute without interruption) + * hw_controller_reset: do controller reset * @ci: the controller * * This function returns an error code */ +static int hw_controller_reset(struct ci_hdrc *ci) +{ + int count = 0; + + hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST); + while (hw_read(ci, OP_USBCMD, USBCMD_RST)) { + udelay(10); + if (count++ > 1000) + return -ETIMEDOUT; + } + + return 0; +} + +/** + * hw_device_reset: resets chip (execute without interruption) + * @ci: the controller + * + * This function returns an error code + */ int hw_device_reset(struct ci_hdrc *ci, u32 mode) { + int ret; + /* should flush & stop before reset */ hw_write(ci, OP_ENDPTFLUSH, ~0, ~0); hw_write(ci, OP_USBCMD, USBCMD_RS, 0); - hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST); - while (hw_read(ci, OP_USBCMD, USBCMD_RST)) - udelay(10); /* not RTOS friendly */ + ret = hw_controller_reset(ci); + if (ret) { + dev_err(ci->dev, "error resetting controller, ret=%d\n", ret); + return ret; + } if (ci->platdata->notify_event) ci->platdata->notify_event(ci, -- cgit v1.2.3 From 5b1573005a91dc448e6919d6bec076bedc7e1919 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:33 +0800 Subject: usb: chipidea: parameter 'mode' isn't needed for hw_device_reset The hw_device_reset is dedicated to be used at device mode initializaiton, so delete the parameter 'mode'. For host driver, the ehci driver will handle all things. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci.h | 2 +- drivers/usb/chipidea/core.c | 8 ++++---- drivers/usb/chipidea/otg_fsm.c | 2 +- drivers/usb/chipidea/udc.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 5bbfcc73cf70..65913d48f0c8 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -352,7 +352,7 @@ u32 hw_read_intr_enable(struct ci_hdrc *ci); u32 hw_read_intr_status(struct ci_hdrc *ci); -int hw_device_reset(struct ci_hdrc *ci, u32 mode); +int hw_device_reset(struct ci_hdrc *ci); int hw_port_test_set(struct ci_hdrc *ci, u8 mode); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 48b25d9ebf82..e43be34f04b9 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -410,7 +410,7 @@ static int hw_controller_reset(struct ci_hdrc *ci) * * This function returns an error code */ -int hw_device_reset(struct ci_hdrc *ci, u32 mode) +int hw_device_reset(struct ci_hdrc *ci) { int ret; @@ -440,12 +440,12 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode) /* USBMODE should be configured step by step */ hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); - hw_write(ci, OP_USBMODE, USBMODE_CM, mode); + hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC); /* HW >= 2.3 */ hw_write(ci, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); - if (hw_read(ci, OP_USBMODE, USBMODE_CM) != mode) { - pr_err("cannot enter in %s mode", ci_role(ci)->name); + if (hw_read(ci, OP_USBMODE, USBMODE_CM) != USBMODE_CM_DC) { + pr_err("cannot enter in %s device mode", ci_role(ci)->name); pr_err("lpm = %i", ci->hw_bank.lpm); return -ENODEV; } diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 368cc8e94fd6..7ef124db657a 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -543,7 +543,7 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on) ci_role_start(ci, CI_ROLE_HOST); } else { ci_role_stop(ci); - hw_device_reset(ci, USBMODE_CM_DC); + hw_device_reset(ci); ci_role_start(ci, CI_ROLE_GADGET); } mutex_lock(&fsm->lock); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index bdaa7bac6f4a..4fe18ce3bd5a 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1471,7 +1471,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) if (gadget_ready) { if (is_active) { pm_runtime_get_sync(&_gadget->dev); - hw_device_reset(ci, USBMODE_CM_DC); + hw_device_reset(ci); hw_device_state(ci, ci->ep0out->qh.dma); usb_gadget_set_state(_gadget, USB_STATE_POWERED); } else { @@ -1660,7 +1660,7 @@ static int ci_udc_start(struct usb_gadget *gadget, pm_runtime_get_sync(&ci->gadget.dev); if (ci->vbus_active) { spin_lock_irqsave(&ci->lock, flags); - hw_device_reset(ci, USBMODE_CM_DC); + hw_device_reset(ci); } else { pm_runtime_put_sync(&ci->gadget.dev); return retval; -- cgit v1.2.3 From 14b4099c074f2ddf4d84b22d370170e61b527529 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:34 +0800 Subject: usb: chipidea: remove duplicate dev_set_drvdata for host_start The core driver has already done it, besides, move set driver data operation just after ci has allocated successfully in case some code (like ci_role_start) want to access this driver data. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/host.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index e43be34f04b9..de1e4a84aa93 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -669,6 +669,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (!ci) return -ENOMEM; + platform_set_drvdata(pdev, ci); ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & @@ -782,7 +783,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) } } - platform_set_drvdata(pdev, ci); ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name, ci); if (ret) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 48731d0bab35..c1694cff1eaf 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -91,7 +91,6 @@ static int host_start(struct ci_hdrc *ci) if (!hcd) return -ENOMEM; - dev_set_drvdata(ci->dev, ci); hcd->rsrc_start = ci->hw_bank.phys; hcd->rsrc_len = ci->hw_bank.size; hcd->regs = ci->hw_bank.abs; -- cgit v1.2.3 From 21a5b579cb63364b90e545e7e0a4bccb027711e8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 26 Nov 2014 13:44:35 +0800 Subject: usb: chipidea: fix phy handling The generic plaftorm device for ChipIdea drivers is probed by calling ci_hdrc_probe. The device structure used is not the one of the specific ChipIdea driver but the one of the generic ChipIdea platform device. This results in not being able to probe the PHYs as we're not using the right device structure. Since all ChipIdea drivers are retrieving their PHYs in their specific driver code, this didn't impact any of them yet. Fixes it using the right device structure (dev->parent). Signed-off-by: Antoine Tenart Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index de1e4a84aa93..068e0c6acc3f 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -686,8 +686,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } else if (ci->platdata->usb_phy) { ci->usb_phy = ci->platdata->usb_phy; } else { - ci->phy = devm_phy_get(dev, "usb-phy"); - ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + ci->phy = devm_phy_get(dev->parent, "usb-phy"); + ci->usb_phy = devm_usb_get_phy(dev->parent, USB_PHY_TYPE_USB2); /* if both generic PHY and USB PHY layers aren't enabled */ if (PTR_ERR(ci->phy) == -ENOSYS && -- cgit v1.2.3 From 10a062cefcfb1f6154a66f9872efc11543eeb3f8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 26 Nov 2014 13:44:36 +0800 Subject: usb: chipidea: add a usb2 driver for ci13xxx Add a USB2 ChipIdea driver for ci13xxx, with optional PHY, clock and DMA mask, to support USB2 ChipIdea controllers that don't need specific functions. Tested on the Marvell Berlin SoCs USB controllers. Signed-off-by: Antoine Tenart Tested-by: Soren Brinkmann Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/Makefile | 1 + drivers/usb/chipidea/ci_hdrc_usb2.c | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 drivers/usb/chipidea/ci_hdrc_usb2.c (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 2f099c7df7b5..1fc86a2ca22d 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -10,6 +10,7 @@ ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o # Glue/Bridge layers go here +obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_usb2.o obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_msm.o obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c new file mode 100644 index 000000000000..61d8e55df1bd --- /dev/null +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Tenart + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ci.h" + +struct ci_hdrc_usb2_priv { + struct platform_device *ci_pdev; + struct clk *clk; +}; + +static struct ci_hdrc_platform_data ci_default_pdata = { + .capoffset = DEF_CAPOFFSET, + .flags = CI_HDRC_DISABLE_STREAMING, +}; + +static int ci_hdrc_usb2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ci_hdrc_usb2_priv *priv; + struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev); + int ret; + + if (!ci_pdata) + ci_pdata = &ci_default_pdata; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->clk = devm_clk_get(dev, NULL); + if (!IS_ERR(priv->clk)) { + ret = clk_prepare_enable(priv->clk); + if (ret) { + dev_err(dev, "failed to enable the clock: %d\n", ret); + return ret; + } + } + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + goto clk_err; + + ci_pdata->name = dev_name(dev); + + priv->ci_pdev = ci_hdrc_add_device(dev, pdev->resource, + pdev->num_resources, ci_pdata); + if (IS_ERR(priv->ci_pdev)) { + ret = PTR_ERR(priv->ci_pdev); + if (ret != -EPROBE_DEFER) + dev_err(dev, + "failed to register ci_hdrc platform device: %d\n", + ret); + goto clk_err; + } + + platform_set_drvdata(pdev, priv); + + pm_runtime_no_callbacks(dev); + pm_runtime_enable(dev); + + return 0; + +clk_err: + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + return ret; +} + +static int ci_hdrc_usb2_remove(struct platform_device *pdev) +{ + struct ci_hdrc_usb2_priv *priv = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + ci_hdrc_remove_device(priv->ci_pdev); + clk_disable_unprepare(priv->clk); + + return 0; +} + +static const struct of_device_id ci_hdrc_usb2_of_match[] = { + { .compatible = "chipidea,usb2" }, + { } +}; +MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match); + +static struct platform_driver ci_hdrc_usb2_driver = { + .probe = ci_hdrc_usb2_probe, + .remove = ci_hdrc_usb2_remove, + .driver = { + .name = "chipidea-usb2", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ci_hdrc_usb2_of_match), + }, +}; +module_platform_driver(ci_hdrc_usb2_driver); + +MODULE_DESCRIPTION("ChipIdea HDRC USB2 binding for ci13xxx"); +MODULE_AUTHOR("Antoine Tenart "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 6629467ba5502cac22d31950e207a0334f2a0de5 Mon Sep 17 00:00:00 2001 From: Mickael Maison Date: Wed, 26 Nov 2014 13:44:38 +0800 Subject: usb: chipidea: Fixed a few typos in comments Fixed typos in comments of 2 drivers/usb/chipidea files Signed-off-by: Mickael Maison Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/otg_fsm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 068e0c6acc3f..e14eafb2a05e 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -549,7 +549,7 @@ static int ci_get_platdata(struct device *dev, if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) { return -EPROBE_DEFER; } else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) { - /* no vbus regualator is needed */ + /* no vbus regulator is needed */ platdata->reg_vbus = NULL; } else if (IS_ERR(platdata->reg_vbus)) { dev_err(dev, "Getting regulator error: %ld\n", diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 7ef124db657a..562e581f6765 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -303,7 +303,7 @@ static void a_wait_vfall_tmout_func(void *ptr, unsigned long indicator) set_tmout(ci, indicator); /* Disable port power */ hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP, 0); - /* Clear exsiting DP irq */ + /* Clear existing DP irq */ hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS); /* Enable data pulse irq */ hw_write_otgsc(ci, OTGSC_DPIE, OTGSC_DPIE); @@ -663,7 +663,7 @@ static void ci_otg_fsm_event(struct ci_hdrc *ci) fsm->b_bus_suspend = 1; /* * Init a timer to know how long this suspend - * will contine, if time out, indicates B no longer + * will continue, if time out, indicates B no longer * wants to be host role */ ci_otg_add_timer(ci, A_BIDL_ADIS); -- cgit v1.2.3 From 67c3c5e28e9bc1dd244829ba7eac8a446da96ff3 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Thu, 27 Nov 2014 03:16:33 +0800 Subject: usb: chipidea: fix platform_no_drv_owner.cocci warnings drivers/usb/chipidea/ci_hdrc_usb2.c:108:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Cc: Antoine Tenart Cc: Peter Chen Signed-off-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_usb2.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb/chipidea') diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index 61d8e55df1bd..45844c951788 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -105,7 +105,6 @@ static struct platform_driver ci_hdrc_usb2_driver = { .remove = ci_hdrc_usb2_remove, .driver = { .name = "chipidea-usb2", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ci_hdrc_usb2_of_match), }, }; -- cgit v1.2.3