diff options
Diffstat (limited to 'drivers/usb/phy/phy-rcar-gen2-usb.c')
-rw-r--r-- | drivers/usb/phy/phy-rcar-gen2-usb.c | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c b/drivers/usb/phy/phy-rcar-gen2-usb.c deleted file mode 100644 index f81800b6562a..000000000000 --- a/drivers/usb/phy/phy-rcar-gen2-usb.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Renesas R-Car Gen2 USB phy driver - * - * Copyright (C) 2013 Renesas Solutions Corp. - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/platform_data/usb-rcar-gen2-phy.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/usb/otg.h> - -struct rcar_gen2_usb_phy_priv { - struct usb_phy phy; - void __iomem *base; - struct clk *clk; - spinlock_t lock; - int usecount; - u32 ugctrl2; -}; - -#define usb_phy_to_priv(p) container_of(p, struct rcar_gen2_usb_phy_priv, phy) - -/* Low Power Status register */ -#define USBHS_LPSTS_REG 0x02 -#define USBHS_LPSTS_SUSPM (1 << 14) - -/* USB General control register */ -#define USBHS_UGCTRL_REG 0x80 -#define USBHS_UGCTRL_CONNECT (1 << 2) -#define USBHS_UGCTRL_PLLRESET (1 << 0) - -/* USB General control register 2 */ -#define USBHS_UGCTRL2_REG 0x84 -#define USBHS_UGCTRL2_USB0_PCI (1 << 4) -#define USBHS_UGCTRL2_USB0_HS (3 << 4) -#define USBHS_UGCTRL2_USB2_PCI (0 << 31) -#define USBHS_UGCTRL2_USB2_SS (1 << 31) - -/* USB General status register */ -#define USBHS_UGSTS_REG 0x88 -#define USBHS_UGSTS_LOCK (1 << 8) - -/* Enable USBHS internal phy */ -static int __rcar_gen2_usbhs_phy_enable(void __iomem *base) -{ - u32 val; - int i; - - /* USBHS PHY power on */ - val = ioread32(base + USBHS_UGCTRL_REG); - val &= ~USBHS_UGCTRL_PLLRESET; - iowrite32(val, base + USBHS_UGCTRL_REG); - - val = ioread16(base + USBHS_LPSTS_REG); - val |= USBHS_LPSTS_SUSPM; - iowrite16(val, base + USBHS_LPSTS_REG); - - for (i = 0; i < 20; i++) { - val = ioread32(base + USBHS_UGSTS_REG); - if ((val & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) { - val = ioread32(base + USBHS_UGCTRL_REG); - val |= USBHS_UGCTRL_CONNECT; - iowrite32(val, base + USBHS_UGCTRL_REG); - return 0; - } - udelay(1); - } - - /* Timed out waiting for the PLL lock */ - return -ETIMEDOUT; -} - -/* Disable USBHS internal phy */ -static int __rcar_gen2_usbhs_phy_disable(void __iomem *base) -{ - u32 val; - - /* USBHS PHY power off */ - val = ioread32(base + USBHS_UGCTRL_REG); - val &= ~USBHS_UGCTRL_CONNECT; - iowrite32(val, base + USBHS_UGCTRL_REG); - - val = ioread16(base + USBHS_LPSTS_REG); - val &= ~USBHS_LPSTS_SUSPM; - iowrite16(val, base + USBHS_LPSTS_REG); - - val = ioread32(base + USBHS_UGCTRL_REG); - val |= USBHS_UGCTRL_PLLRESET; - iowrite32(val, base + USBHS_UGCTRL_REG); - return 0; -} - -/* Setup USB channels */ -static void __rcar_gen2_usb_phy_init(struct rcar_gen2_usb_phy_priv *priv) -{ - u32 val; - - clk_prepare_enable(priv->clk); - - /* Set USB channels in the USBHS UGCTRL2 register */ - val = ioread32(priv->base + USBHS_UGCTRL2_REG); - val &= ~(USBHS_UGCTRL2_USB0_HS | USBHS_UGCTRL2_USB2_SS); - val |= priv->ugctrl2; - iowrite32(val, priv->base + USBHS_UGCTRL2_REG); -} - -/* Shutdown USB channels */ -static void __rcar_gen2_usb_phy_shutdown(struct rcar_gen2_usb_phy_priv *priv) -{ - __rcar_gen2_usbhs_phy_disable(priv->base); - clk_disable_unprepare(priv->clk); -} - -static int rcar_gen2_usb_phy_set_suspend(struct usb_phy *phy, int suspend) -{ - struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); - unsigned long flags; - int retval; - - spin_lock_irqsave(&priv->lock, flags); - retval = suspend ? __rcar_gen2_usbhs_phy_disable(priv->base) : - __rcar_gen2_usbhs_phy_enable(priv->base); - spin_unlock_irqrestore(&priv->lock, flags); - return retval; -} - -static int rcar_gen2_usb_phy_init(struct usb_phy *phy) -{ - struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - /* - * Enable the clock and setup USB channels - * if it's the first user - */ - if (!priv->usecount++) - __rcar_gen2_usb_phy_init(priv); - spin_unlock_irqrestore(&priv->lock, flags); - return 0; -} - -static void rcar_gen2_usb_phy_shutdown(struct usb_phy *phy) -{ - struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (!priv->usecount) { - dev_warn(phy->dev, "Trying to disable phy with 0 usecount\n"); - goto out; - } - - /* Disable everything if it's the last user */ - if (!--priv->usecount) - __rcar_gen2_usb_phy_shutdown(priv); -out: - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int rcar_gen2_usb_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct rcar_gen2_phy_platform_data *pdata; - struct rcar_gen2_usb_phy_priv *priv; - struct resource *res; - void __iomem *base; - struct clk *clk; - int retval; - - pdata = dev_get_platdata(dev); - if (!pdata) { - dev_err(dev, "No platform data\n"); - return -EINVAL; - } - - clk = devm_clk_get(dev, "usbhs"); - if (IS_ERR(clk)) { - dev_err(dev, "Can't get the clock\n"); - return PTR_ERR(clk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - spin_lock_init(&priv->lock); - priv->clk = clk; - priv->base = base; - priv->ugctrl2 = pdata->chan0_pci ? - USBHS_UGCTRL2_USB0_PCI : USBHS_UGCTRL2_USB0_HS; - priv->ugctrl2 |= pdata->chan2_pci ? - USBHS_UGCTRL2_USB2_PCI : USBHS_UGCTRL2_USB2_SS; - priv->phy.dev = dev; - priv->phy.label = dev_name(dev); - priv->phy.init = rcar_gen2_usb_phy_init; - priv->phy.shutdown = rcar_gen2_usb_phy_shutdown; - priv->phy.set_suspend = rcar_gen2_usb_phy_set_suspend; - - retval = usb_add_phy_dev(&priv->phy); - if (retval < 0) { - dev_err(dev, "Failed to add USB phy\n"); - return retval; - } - - platform_set_drvdata(pdev, priv); - - return retval; -} - -static int rcar_gen2_usb_phy_remove(struct platform_device *pdev) -{ - struct rcar_gen2_usb_phy_priv *priv = platform_get_drvdata(pdev); - - usb_remove_phy(&priv->phy); - - return 0; -} - -static struct platform_driver rcar_gen2_usb_phy_driver = { - .driver = { - .name = "usb_phy_rcar_gen2", - }, - .probe = rcar_gen2_usb_phy_probe, - .remove = rcar_gen2_usb_phy_remove, -}; - -module_platform_driver(rcar_gen2_usb_phy_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Renesas R-Car Gen2 USB phy"); -MODULE_AUTHOR("Valentine Barshak <valentine.barshak@cogentembedded.com>"); |