- Add pinctrl support for dual-role switch at chipidea-core

- improve overcorrent handling for imx
 - some small code restructure (no function affect)
 -----BEGIN PGP SIGNATURE-----
 
 iQEwBAABCAAaBQJburdqExxwZXRlci5jaGVuQG54cC5jb20ACgkQSFkpgVDWcbsr
 ogf8C3QeuruN4+awCx4VQ7QPOhy0ewdr0OL3DCt1wjZkhvKilXcLHtKimbm7QQ7F
 9tHFpxya63MwZvnqjEGR/EgJpTPGVTx1KSBcBoEQn5qP+iYA/xVSYGpeLEHGZtQE
 FtsJGXg/dT1uzho43CibCksqiyHpScNAdUn9wl6go/LJKycVQ3nu+6R+kXbc+0ca
 gzPXUsApG4KTEJ8SH5eGZnx2uqZzhJnuYXDRr/8mw6S1GyM6wlobVHvSyhpj1uGy
 OsXluLgfu/+o+HYKwmKpqg2gZonk+1r2rE0qSmoAI7rYmX3irBC6VvASYqrok5jj
 lKQ/a/M8IeIsXo1a/Xv62SKU3w==
 =loIF
 -----END PGP SIGNATURE-----

Merge tag 'usb-ci-v4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb into usb-testing

Peter writes:

- Add pinctrl support for dual-role switch at chipidea-core
- improve overcorrent handling for imx
- some small code restructure (no function affect)

* tag 'usb-ci-v4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb:
  usb: chipidea: Fix otg event handler
  usb: chipidea: Prevent unbalanced IRQ disable
  doc: usb: ci-hdrc-usb2: Add pinctrl properties definition
  usb: chipidea: Add dynamic pinctrl selection
  usb: chipidea: imx: make MODULE_LICENCE and SPDX-identifier match
  usb: chipidea: imx: enable OTG overcurrent in case USB subsystem is already started
  usb: chipidea: imx: do not use preprocessor conditionals for PM
This commit is contained in:
Greg Kroah-Hartman 2018-10-08 16:27:14 +02:00
commit 6503016ea5
9 changed files with 63 additions and 17 deletions

View File

@ -80,6 +80,8 @@ Optional properties:
controller. It's expected that a mux state of 0 indicates device mode and a
mux state of 1 indicates host mode.
- mux-control-names: Shall be "usb_switch" if mux-controls is specified.
- pinctrl-names: Names for optional pin modes in "default", "host", "device"
- pinctrl-n: alternate pin modes
i.mx specific properties
- fsl,usbmisc: phandler of non-core register device, with one

View File

@ -364,8 +364,7 @@ static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
ci_hdrc_imx_remove(pdev);
}
#ifdef CONFIG_PM
static int imx_controller_suspend(struct device *dev)
static int __maybe_unused imx_controller_suspend(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
@ -377,7 +376,7 @@ static int imx_controller_suspend(struct device *dev)
return 0;
}
static int imx_controller_resume(struct device *dev)
static int __maybe_unused imx_controller_resume(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
int ret = 0;
@ -408,8 +407,7 @@ clk_disable:
return ret;
}
#ifdef CONFIG_PM_SLEEP
static int ci_hdrc_imx_suspend(struct device *dev)
static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
{
int ret;
@ -431,7 +429,7 @@ static int ci_hdrc_imx_suspend(struct device *dev)
return imx_controller_suspend(dev);
}
static int ci_hdrc_imx_resume(struct device *dev)
static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
int ret;
@ -445,9 +443,8 @@ static int ci_hdrc_imx_resume(struct device *dev)
return ret;
}
#endif /* CONFIG_PM_SLEEP */
static int ci_hdrc_imx_runtime_suspend(struct device *dev)
static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
int ret;
@ -466,13 +463,11 @@ static int ci_hdrc_imx_runtime_suspend(struct device *dev)
return imx_controller_suspend(dev);
}
static int ci_hdrc_imx_runtime_resume(struct device *dev)
static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev)
{
return imx_controller_resume(dev);
}
#endif /* CONFIG_PM */
static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
@ -492,7 +487,7 @@ static struct platform_driver ci_hdrc_imx_driver = {
module_platform_driver(ci_hdrc_imx_driver);
MODULE_ALIAS("platform:imx-usb");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");

View File

@ -53,6 +53,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/consumer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
@ -723,6 +724,24 @@ static int ci_get_platdata(struct device *dev,
else
cable->connected = false;
}
platdata->pctl = devm_pinctrl_get(dev);
if (!IS_ERR(platdata->pctl)) {
struct pinctrl_state *p;
p = pinctrl_lookup_state(platdata->pctl, "default");
if (!IS_ERR(p))
platdata->pins_default = p;
p = pinctrl_lookup_state(platdata->pctl, "host");
if (!IS_ERR(p))
platdata->pins_host = p;
p = pinctrl_lookup_state(platdata->pctl, "device");
if (!IS_ERR(p))
platdata->pins_device = p;
}
return 0;
}

View File

@ -13,6 +13,7 @@
#include <linux/usb/hcd.h>
#include <linux/usb/chipidea.h>
#include <linux/regulator/consumer.h>
#include <linux/pinctrl/consumer.h>
#include "../host/ehci.h"
@ -153,6 +154,10 @@ static int host_start(struct ci_hdrc *ci)
}
}
if (ci->platdata->pins_host)
pinctrl_select_state(ci->platdata->pctl,
ci->platdata->pins_host);
ret = usb_add_hcd(hcd, 0, 0);
if (ret) {
goto disable_reg;
@ -197,6 +202,10 @@ static void host_stop(struct ci_hdrc *ci)
}
ci->hcd = NULL;
ci->otg.host = NULL;
if (ci->platdata->pins_host && ci->platdata->pins_default)
pinctrl_select_state(ci->platdata->pctl,
ci->platdata->pins_default);
}

View File

@ -203,14 +203,17 @@ static void ci_otg_work(struct work_struct *work)
}
pm_runtime_get_sync(ci->dev);
if (ci->id_event) {
ci->id_event = false;
ci_handle_id_switch(ci);
} else if (ci->b_sess_valid_event) {
}
if (ci->b_sess_valid_event) {
ci->b_sess_valid_event = false;
ci_handle_vbus_change(ci);
} else
dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
}
pm_runtime_put_sync(ci->dev);
enable_irq(ci->irq);

View File

@ -17,7 +17,8 @@ void ci_handle_vbus_change(struct ci_hdrc *ci);
static inline void ci_otg_queue_work(struct ci_hdrc *ci)
{
disable_irq_nosync(ci->irq);
queue_work(ci->wq, &ci->work);
if (queue_work(ci->wq, &ci->work) == false)
enable_irq(ci->irq);
}
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */

View File

@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/consumer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg-fsm.h>
@ -1965,6 +1966,10 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
static int udc_id_switch_for_device(struct ci_hdrc *ci)
{
if (ci->platdata->pins_device)
pinctrl_select_state(ci->platdata->pctl,
ci->platdata->pins_device);
if (ci->is_otg)
/* Clear and enable BSV irq */
hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
@ -1983,6 +1988,10 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)
hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS);
ci->vbus_active = 0;
if (ci->platdata->pins_device && ci->platdata->pins_default)
pinctrl_select_state(ci->platdata->pctl,
ci->platdata->pins_default);
}
/**

View File

@ -343,6 +343,8 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
} else if (data->oc_polarity == 1) {
/* High active */
reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
} else {
reg &= ~(MX6_BM_OVER_CUR_DIS);
}
writel(reg, usbmisc->base + data->index * 4);
@ -633,6 +635,6 @@ static struct platform_driver usbmisc_imx_driver = {
module_platform_driver(usbmisc_imx_driver);
MODULE_ALIAS("platform:usbmisc-imx");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("driver for imx usb non-core registers");
MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");

View File

@ -77,6 +77,12 @@ struct ci_hdrc_platform_data {
struct ci_hdrc_cable vbus_extcon;
struct ci_hdrc_cable id_extcon;
u32 phy_clkgate_delay_us;
/* pins */
struct pinctrl *pctl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_host;
struct pinctrl_state *pins_device;
};
/* Default offset of capability registers */