This is needed to let the omap3 otg controller make use of a generic
usb-nop-xceiv phy.
---
drivers/usb/phy/phy-generic.c | 50 ++++++++++++++++++++++++++++++++++++++++---
drivers/usb/phy/phy-generic.h | 1 +
2 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index deee68eafb72..dfff5c2ca604 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -157,6 +157,16 @@ int usb_gen_phy_init(struct usb_phy *phy)
}
EXPORT_SYMBOL_GPL(usb_gen_phy_init);
+static int usb_gen_phy_phy_init(struct phy *phy)
+{
+ struct platform_device *pdev = container_of(phy->dev.parent,
+ struct platform_device,
+ dev);
+ struct usb_phy_generic *nop = platform_get_drvdata(pdev);
+
+ return usb_gen_phy_init(&nop->phy);
+}
+
void usb_gen_phy_shutdown(struct usb_phy *phy)
{
struct usb_phy_generic *nop = dev_get_drvdata(phy->dev);
@@ -173,6 +183,23 @@ void usb_gen_phy_shutdown(struct usb_phy *phy)
}
EXPORT_SYMBOL_GPL(usb_gen_phy_shutdown);
+static int usb_gen_phy_phy_exit(struct phy *phy)
+{
+ struct platform_device *pdev = container_of(phy->dev.parent,
+ struct platform_device,
+ dev);
+ struct usb_phy_generic *nop = platform_get_drvdata(pdev);
+
+ usb_gen_phy_shutdown(&nop->phy);
+ return 0;
+}
+
+static struct phy_ops usb_gen_phy_phy_ops = {
+ .init = usb_gen_phy_phy_init,
+ .exit = usb_gen_phy_phy_exit,
+ .owner = THIS_MODULE,
+};
+
static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
{
if (!otg)
@@ -293,13 +320,17 @@ EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy);
static int usb_phy_generic_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct usb_phy_generic *nop;
+ struct usb_phy_generic *nop;
+ struct phy *phy;
+ struct phy_provider *phy_provider;
int err;
nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL);
if (!nop)
return -ENOMEM;
+ platform_set_drvdata(pdev, nop);
+
err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev));
if (err)
return err;
@@ -319,6 +350,21 @@ static int usb_phy_generic_probe(struct platform_device
*pdev)
nop->phy.init = usb_gen_phy_init;
nop->phy.shutdown = usb_gen_phy_shutdown;
+ phy = devm_phy_create(dev, NULL, &usb_gen_phy_phy_ops);
+ if (IS_ERR(phy)) {
+ err = PTR_ERR(phy);
+ dev_err(&pdev->dev, "can't create phy device, err: %d\n", err);
+ return err;
+ }
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider)) {
+ err = PTR_ERR(phy_provider);
+ dev_err(&pdev->dev,
+ "can't create phy provider, err: %d\n", err);
+ return err;
+ }
+
err = usb_add_phy_dev(&nop->phy);
if (err) {
dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
@@ -326,8 +372,6 @@ static int usb_phy_generic_probe(struct platform_device
*pdev)
return err;
}
- platform_set_drvdata(pdev, nop);
-
return 0;
}
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h
index 0d0eadd54ed9..a71314df1c6a 100644
--- a/drivers/usb/phy/phy-generic.h
+++ b/drivers/usb/phy/phy-generic.h
@@ -4,6 +4,7 @@
#include <linux/usb/usb_phy_generic.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
+#include <linux/phy/phy.h>
struct usb_phy_generic {
struct usb_phy phy;
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html