summaryrefslogtreecommitdiff
path: root/drivers/usb/musb/jz4740.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/jz4740.c')
-rw-r--r--drivers/usb/musb/jz4740.c72
1 files changed, 56 insertions, 16 deletions
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c
index 417c30bff9ca..df56c972986f 100644
--- a/drivers/usb/musb/jz4740.c
+++ b/drivers/usb/musb/jz4740.c
@@ -10,7 +10,8 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb/role.h>
#include <linux/usb/usb_phy_generic.h>
@@ -58,7 +59,7 @@ static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci)
return IRQ_NONE;
}
-static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = {
+static const struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, },
@@ -81,6 +82,9 @@ static int jz4740_musb_role_switch_set(struct usb_role_switch *sw,
struct jz4740_glue *glue = usb_role_switch_get_drvdata(sw);
struct usb_phy *phy = glue->musb->xceiv;
+ if (!phy)
+ return 0;
+
switch (role) {
case USB_ROLE_NONE:
atomic_notifier_call_chain(&phy->notifier, USB_EVENT_NONE, phy);
@@ -109,21 +113,47 @@ static int jz4740_musb_init(struct musb *musb)
glue->musb = musb;
- if (dev->of_node)
- musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0);
- else
- musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
- if (IS_ERR(musb->xceiv)) {
- err = PTR_ERR(musb->xceiv);
- if (err != -EPROBE_DEFER)
- dev_err(dev, "No transceiver configured: %d\n", err);
- return err;
+ if (IS_ENABLED(CONFIG_GENERIC_PHY)) {
+ musb->phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
+ if (IS_ERR(musb->phy)) {
+ err = PTR_ERR(musb->phy);
+ if (err != -ENODEV) {
+ dev_err(dev, "Unable to get PHY\n");
+ return err;
+ }
+
+ musb->phy = NULL;
+ }
+ }
+
+ if (musb->phy) {
+ err = phy_init(musb->phy);
+ if (err) {
+ dev_err(dev, "Failed to init PHY\n");
+ return err;
+ }
+
+ err = phy_power_on(musb->phy);
+ if (err) {
+ dev_err(dev, "Unable to power on PHY\n");
+ goto err_phy_shutdown;
+ }
+ } else {
+ if (dev->of_node)
+ musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0);
+ else
+ musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+ if (IS_ERR(musb->xceiv)) {
+ dev_err(dev, "No transceiver configured\n");
+ return PTR_ERR(musb->xceiv);
+ }
}
glue->role_sw = usb_role_switch_register(dev, &role_sw_desc);
if (IS_ERR(glue->role_sw)) {
dev_err(dev, "Failed to register USB role switch\n");
- return PTR_ERR(glue->role_sw);
+ err = PTR_ERR(glue->role_sw);
+ goto err_phy_power_down;
}
/*
@@ -135,6 +165,14 @@ static int jz4740_musb_init(struct musb *musb)
musb->isr = jz4740_musb_interrupt;
return 0;
+
+err_phy_power_down:
+ if (musb->phy)
+ phy_power_off(musb->phy);
+err_phy_shutdown:
+ if (musb->phy)
+ phy_exit(musb->phy);
+ return err;
}
static int jz4740_musb_exit(struct musb *musb)
@@ -142,6 +180,10 @@ static int jz4740_musb_exit(struct musb *musb)
struct jz4740_glue *glue = dev_get_drvdata(musb->controller->parent);
usb_role_switch_unregister(glue->role_sw);
+ if (musb->phy) {
+ phy_power_off(musb->phy);
+ phy_exit(musb->phy);
+ }
return 0;
}
@@ -163,7 +205,7 @@ static const struct musb_hdrc_platform_data jz4740_musb_pdata = {
.platform_ops = &jz4740_musb_ops,
};
-static struct musb_fifo_cfg jz4770_musb_fifo_cfg[] = {
+static const struct musb_fifo_cfg jz4770_musb_fifo_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -266,14 +308,12 @@ err_platform_device_put:
return ret;
}
-static int jz4740_remove(struct platform_device *pdev)
+static void jz4740_remove(struct platform_device *pdev)
{
struct jz4740_glue *glue = platform_get_drvdata(pdev);
platform_device_unregister(glue->pdev);
clk_disable_unprepare(glue->clk);
-
- return 0;
}
static const struct of_device_id jz4740_musb_of_match[] = {