Commit a1ca2c6b authored by Hans de Goede's avatar Hans de Goede Committed by Greg Kroah-Hartman

usb: musb: sunxi: Simplify dr_mode handling

phy-sun4i-usb now has proper dr_mode handling, it always registers an
extcon, and sends a notify with the mode (even when in peripheral- /
host-only mode) at least once.

So we can simply the sunxi musb glue by always registering its extcon
notifier and relying on sunxi_musb_work() to enable vbus when in
host-only mode.

This also enables host- and peripheral-only mode with vbus monitoring.
Tested-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarBin Liu <b-liu@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cd53bd68
...@@ -256,12 +256,10 @@ static int sunxi_musb_init(struct musb *musb) ...@@ -256,12 +256,10 @@ static int sunxi_musb_init(struct musb *musb)
writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0); writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0);
/* Register notifier before calling phy_init() */ /* Register notifier before calling phy_init() */
if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) {
ret = extcon_register_notifier(glue->extcon, EXTCON_USB_HOST, ret = extcon_register_notifier(glue->extcon, EXTCON_USB_HOST,
&glue->host_nb); &glue->host_nb);
if (ret) if (ret)
goto error_reset_assert; goto error_reset_assert;
}
ret = phy_init(glue->phy); ret = phy_init(glue->phy);
if (ret) if (ret)
...@@ -275,7 +273,6 @@ static int sunxi_musb_init(struct musb *musb) ...@@ -275,7 +273,6 @@ static int sunxi_musb_init(struct musb *musb)
return 0; return 0;
error_unregister_notifier: error_unregister_notifier:
if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST,
&glue->host_nb); &glue->host_nb);
error_reset_assert: error_reset_assert:
...@@ -301,7 +298,6 @@ static int sunxi_musb_exit(struct musb *musb) ...@@ -301,7 +298,6 @@ static int sunxi_musb_exit(struct musb *musb)
phy_exit(glue->phy); phy_exit(glue->phy);
if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST,
&glue->host_nb); &glue->host_nb);
...@@ -315,25 +311,6 @@ static int sunxi_musb_exit(struct musb *musb) ...@@ -315,25 +311,6 @@ static int sunxi_musb_exit(struct musb *musb)
return 0; return 0;
} }
static int sunxi_set_mode(struct musb *musb, u8 mode)
{
struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
int ret;
if (mode == MUSB_HOST) {
ret = phy_power_on(glue->phy);
if (ret)
return ret;
set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
/* Stop musb work from turning vbus off again */
set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
}
return 0;
}
static void sunxi_musb_enable(struct musb *musb) static void sunxi_musb_enable(struct musb *musb)
{ {
struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
...@@ -582,7 +559,6 @@ static const struct musb_platform_ops sunxi_musb_ops = { ...@@ -582,7 +559,6 @@ static const struct musb_platform_ops sunxi_musb_ops = {
.exit = sunxi_musb_exit, .exit = sunxi_musb_exit,
.enable = sunxi_musb_enable, .enable = sunxi_musb_enable,
.disable = sunxi_musb_disable, .disable = sunxi_musb_disable,
.set_mode = sunxi_set_mode,
.fifo_offset = sunxi_musb_fifo_offset, .fifo_offset = sunxi_musb_fifo_offset,
.ep_offset = sunxi_musb_ep_offset, .ep_offset = sunxi_musb_ep_offset,
.busctl_offset = sunxi_musb_busctl_offset, .busctl_offset = sunxi_musb_busctl_offset,
...@@ -638,10 +614,6 @@ static int sunxi_musb_probe(struct platform_device *pdev) ...@@ -638,10 +614,6 @@ static int sunxi_musb_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue)
return -ENOMEM;
memset(&pdata, 0, sizeof(pdata)); memset(&pdata, 0, sizeof(pdata));
switch (usb_get_dr_mode(&pdev->dev)) { switch (usb_get_dr_mode(&pdev->dev)) {
#if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST
...@@ -649,15 +621,13 @@ static int sunxi_musb_probe(struct platform_device *pdev) ...@@ -649,15 +621,13 @@ static int sunxi_musb_probe(struct platform_device *pdev)
pdata.mode = MUSB_PORT_MODE_HOST; pdata.mode = MUSB_PORT_MODE_HOST;
break; break;
#endif #endif
#if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET
case USB_DR_MODE_PERIPHERAL:
pdata.mode = MUSB_PORT_MODE_GADGET;
break;
#endif
#ifdef CONFIG_USB_MUSB_DUAL_ROLE #ifdef CONFIG_USB_MUSB_DUAL_ROLE
case USB_DR_MODE_OTG: case USB_DR_MODE_OTG:
glue->extcon = extcon_get_edev_by_phandle(&pdev->dev, 0);
if (IS_ERR(glue->extcon)) {
if (PTR_ERR(glue->extcon) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_err(&pdev->dev, "Invalid or missing extcon\n");
return PTR_ERR(glue->extcon);
}
pdata.mode = MUSB_PORT_MODE_DUAL_ROLE; pdata.mode = MUSB_PORT_MODE_DUAL_ROLE;
break; break;
#endif #endif
...@@ -668,6 +638,10 @@ static int sunxi_musb_probe(struct platform_device *pdev) ...@@ -668,6 +638,10 @@ static int sunxi_musb_probe(struct platform_device *pdev)
pdata.platform_ops = &sunxi_musb_ops; pdata.platform_ops = &sunxi_musb_ops;
pdata.config = &sunxi_musb_hdrc_config; pdata.config = &sunxi_musb_hdrc_config;
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue)
return -ENOMEM;
glue->dev = &pdev->dev; glue->dev = &pdev->dev;
INIT_WORK(&glue->work, sunxi_musb_work); INIT_WORK(&glue->work, sunxi_musb_work);
glue->host_nb.notifier_call = sunxi_musb_host_notifier; glue->host_nb.notifier_call = sunxi_musb_host_notifier;
...@@ -701,6 +675,14 @@ static int sunxi_musb_probe(struct platform_device *pdev) ...@@ -701,6 +675,14 @@ static int sunxi_musb_probe(struct platform_device *pdev)
} }
} }
glue->extcon = extcon_get_edev_by_phandle(&pdev->dev, 0);
if (IS_ERR(glue->extcon)) {
if (PTR_ERR(glue->extcon) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_err(&pdev->dev, "Invalid or missing extcon\n");
return PTR_ERR(glue->extcon);
}
glue->phy = devm_phy_get(&pdev->dev, "usb"); glue->phy = devm_phy_get(&pdev->dev, "usb");
if (IS_ERR(glue->phy)) { if (IS_ERR(glue->phy)) {
if (PTR_ERR(glue->phy) == -EPROBE_DEFER) if (PTR_ERR(glue->phy) == -EPROBE_DEFER)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment