From f977caea50381e9ca38319037a2b23fe3209d647 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 10 Mar 2023 08:47:28 -0600 Subject: usb: Use of_property_read_bool() for boolean properties It is preferred to use typed property access functions (i.e. of_property_read_ functions) rather than low-level of_get_property/of_find_property functions for reading properties. Convert reading boolean properties to to of_property_read_bool(). Signed-off-by: Rob Herring Reviewed-by: Richard Leitner Link: https://lore.kernel.org/r/20230310144729.1545857-1-robh@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/chipidea/core.c') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 27c601296130..7ccb223ed53c 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -753,7 +753,7 @@ static int ci_get_platdata(struct device *dev, return ret; } - if (of_find_property(dev->of_node, "non-zero-ttctrl-ttha", NULL)) + if (of_property_read_bool(dev->of_node, "non-zero-ttctrl-ttha")) platdata->flags |= CI_HDRC_SET_NON_ZERO_TTHA; ext_id = ERR_PTR(-ENODEV); -- cgit v1.2.3 From 3670de80678961eda7fa2220883fc77c16868951 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Fri, 17 Mar 2023 14:15:15 +0800 Subject: usb: chipdea: core: fix return -EINVAL if request role is the same with current role It should not return -EINVAL if the request role is the same with current role, return non-error and without do anything instead. Fixes: a932a8041ff9 ("usb: chipidea: core: add sysfs group") cc: Acked-by: Peter Chen Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20230317061516.2451728-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/usb/chipidea/core.c') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 27c601296130..b6f2a41de20e 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -984,9 +984,12 @@ static ssize_t role_store(struct device *dev, strlen(ci->roles[role]->name))) break; - if (role == CI_ROLE_END || role == ci->role) + if (role == CI_ROLE_END) return -EINVAL; + if (role == ci->role) + return n; + pm_runtime_get_sync(dev); disable_irq(ci->irq); ci_role_stop(ci); -- cgit v1.2.3 From 451b15ed138ec15bffbebb58a00ebdd884c3e659 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Fri, 17 Mar 2023 14:15:16 +0800 Subject: usb: chipidea: core: fix possible concurrent when switch role The user may call role_store() when driver is handling ci_handle_id_switch() which is triggerred by otg event or power lost event. Unfortunately, the controller may go into chaos in this case. Fix this by protecting it with mutex lock. Fixes: a932a8041ff9 ("usb: chipidea: core: add sysfs group") cc: Acked-by: Peter Chen Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20230317061516.2451728-2-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci.h | 2 ++ drivers/usb/chipidea/core.c | 8 +++++++- drivers/usb/chipidea/otg.c | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/usb/chipidea/core.c') diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 005c67cb3afb..f210b7489fd5 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -208,6 +208,7 @@ struct hw_bank { * @in_lpm: if the core in low power mode * @wakeup_int: if wakeup interrupt occur * @rev: The revision number for controller + * @mutex: protect code from concorrent running when doing role switch */ struct ci_hdrc { struct device *dev; @@ -260,6 +261,7 @@ struct ci_hdrc { bool in_lpm; bool wakeup_int; enum ci_revision rev; + struct mutex mutex; }; static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index b6f2a41de20e..281fc51720ce 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -987,8 +987,12 @@ static ssize_t role_store(struct device *dev, if (role == CI_ROLE_END) return -EINVAL; - if (role == ci->role) + mutex_lock(&ci->mutex); + + if (role == ci->role) { + mutex_unlock(&ci->mutex); return n; + } pm_runtime_get_sync(dev); disable_irq(ci->irq); @@ -998,6 +1002,7 @@ static ssize_t role_store(struct device *dev, ci_handle_vbus_change(ci); enable_irq(ci->irq); pm_runtime_put_sync(dev); + mutex_unlock(&ci->mutex); return (ret == 0) ? n : ret; } @@ -1033,6 +1038,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENOMEM; spin_lock_init(&ci->lock); + mutex_init(&ci->mutex); ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index 622c3b68aa1e..f5490f2a5b6b 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -167,8 +167,10 @@ static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci) void ci_handle_id_switch(struct ci_hdrc *ci) { - enum ci_role role = ci_otg_role(ci); + enum ci_role role; + mutex_lock(&ci->mutex); + role = ci_otg_role(ci); if (role != ci->role) { dev_dbg(ci->dev, "switching from %s to %s\n", ci_role(ci)->name, ci->roles[role]->name); @@ -198,6 +200,7 @@ void ci_handle_id_switch(struct ci_hdrc *ci) if (role == CI_ROLE_GADGET) ci_handle_vbus_change(ci); } + mutex_unlock(&ci->mutex); } /** * ci_otg_work - perform otg (vbus/id) event handle -- cgit v1.2.3 From d6f712f53b79f5017cdcefafb7a5aea9ec52da5d Mon Sep 17 00:00:00 2001 From: Yinhao Hu Date: Wed, 12 Apr 2023 13:58:52 +0800 Subject: usb: chipidea: fix missing goto in `ci_hdrc_probe` From the comment of ci_usb_phy_init, it returns an error code if usb_phy_init has failed, and it should do some clean up, not just return directly. Fix this by goto the error handling. Fixes: 74475ede784d ("usb: chipidea: move PHY operation to core") Reviewed-by: Dongliang Mu Acked-by: Peter Chen Signed-off-by: Yinhao Hu Link: https://lore.kernel.org/r/20230412055852.971991-1-dddddd@hust.edu.cn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/chipidea/core.c') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index d1d252c87e4f..798cb077867a 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -1108,7 +1108,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) ret = ci_usb_phy_init(ci); if (ret) { dev_err(dev, "unable to init phy: %d\n", ret); - return ret; + goto ulpi_exit; } ci->hw_bank.phys = res->start; -- cgit v1.2.3