linux/drivers/usb/host/ehci-st.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * ST EHCI driver
   4 *
   5 * Copyright (C) 2014 STMicroelectronics – All Rights Reserved
   6 *
   7 * Author: Peter Griffin <peter.griffin@linaro.org>
   8 *
   9 * Derived from ehci-platform.c
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/dma-mapping.h>
  14#include <linux/err.h>
  15#include <linux/kernel.h>
  16#include <linux/hrtimer.h>
  17#include <linux/io.h>
  18#include <linux/module.h>
  19#include <linux/of.h>
  20#include <linux/phy/phy.h>
  21#include <linux/platform_device.h>
  22#include <linux/reset.h>
  23#include <linux/usb.h>
  24#include <linux/usb/hcd.h>
  25#include <linux/usb/ehci_pdriver.h>
  26#include <linux/pinctrl/consumer.h>
  27
  28#include "ehci.h"
  29
  30#define USB_MAX_CLKS 3
  31
  32struct st_ehci_platform_priv {
  33        struct clk *clks[USB_MAX_CLKS];
  34        struct clk *clk48;
  35        struct reset_control *rst;
  36        struct reset_control *pwr;
  37        struct phy *phy;
  38};
  39
  40#define DRIVER_DESC "EHCI STMicroelectronics driver"
  41
  42#define hcd_to_ehci_priv(h) \
  43        ((struct st_ehci_platform_priv *)hcd_to_ehci(h)->priv)
  44
  45static const char hcd_name[] = "ehci-st";
  46
  47#define EHCI_CAPS_SIZE 0x10
  48#define AHB2STBUS_INSREG01 (EHCI_CAPS_SIZE + 0x84)
  49
  50static int st_ehci_platform_reset(struct usb_hcd *hcd)
  51{
  52        struct platform_device *pdev = to_platform_device(hcd->self.controller);
  53        struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
  54        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  55        u32 threshold;
  56
  57        /* Set EHCI packet buffer IN/OUT threshold to 128 bytes */
  58        threshold = 128 | (128 << 16);
  59        writel(threshold, hcd->regs + AHB2STBUS_INSREG01);
  60
  61        ehci->caps = hcd->regs + pdata->caps_offset;
  62        return ehci_setup(hcd);
  63}
  64
  65static int st_ehci_platform_power_on(struct platform_device *dev)
  66{
  67        struct usb_hcd *hcd = platform_get_drvdata(dev);
  68        struct st_ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
  69        int clk, ret;
  70
  71        ret = reset_control_deassert(priv->pwr);
  72        if (ret)
  73                return ret;
  74
  75        ret = reset_control_deassert(priv->rst);
  76        if (ret)
  77                goto err_assert_power;
  78
  79        /* some SoCs don't have a dedicated 48Mhz clock, but those that do
  80           need the rate to be explicitly set */
  81        if (priv->clk48) {
  82                ret = clk_set_rate(priv->clk48, 48000000);
  83                if (ret)
  84                        goto err_assert_reset;
  85        }
  86
  87        for (clk = 0; clk < USB_MAX_CLKS && priv->clks[clk]; clk++) {
  88                ret = clk_prepare_enable(priv->clks[clk]);
  89                if (ret)
  90                        goto err_disable_clks;
  91        }
  92
  93        ret = phy_init(priv->phy);
  94        if (ret)
  95                goto err_disable_clks;
  96
  97        ret = phy_power_on(priv->phy);
  98        if (ret)
  99                goto err_exit_phy;
 100
 101        return 0;
 102
 103err_exit_phy:
 104        phy_exit(priv->phy);
 105err_disable_clks:
 106        while (--clk >= 0)
 107                clk_disable_unprepare(priv->clks[clk]);
 108err_assert_reset:
 109        reset_control_assert(priv->rst);
 110err_assert_power:
 111        reset_control_assert(priv->pwr);
 112
 113        return ret;
 114}
 115
 116static void st_ehci_platform_power_off(struct platform_device *dev)
 117{
 118        struct usb_hcd *hcd = platform_get_drvdata(dev);
 119        struct st_ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
 120        int clk;
 121
 122        reset_control_assert(priv->pwr);
 123
 124        reset_control_assert(priv->rst);
 125
 126        phy_power_off(priv->phy);
 127
 128        phy_exit(priv->phy);
 129
 130        for (clk = USB_MAX_CLKS - 1; clk >= 0; clk--)
 131                if (priv->clks[clk])
 132                        clk_disable_unprepare(priv->clks[clk]);
 133
 134}
 135
 136static struct hc_driver __read_mostly ehci_platform_hc_driver;
 137
 138static const struct ehci_driver_overrides platform_overrides __initconst = {
 139        .reset =                st_ehci_platform_reset,
 140        .extra_priv_size =      sizeof(struct st_ehci_platform_priv),
 141};
 142
 143static struct usb_ehci_pdata ehci_platform_defaults = {
 144        .power_on =             st_ehci_platform_power_on,
 145        .power_suspend =        st_ehci_platform_power_off,
 146        .power_off =            st_ehci_platform_power_off,
 147};
 148
 149static int st_ehci_platform_probe(struct platform_device *dev)
 150{
 151        struct usb_hcd *hcd;
 152        struct resource *res_mem;
 153        struct usb_ehci_pdata *pdata = &ehci_platform_defaults;
 154        struct st_ehci_platform_priv *priv;
 155        int err, irq, clk = 0;
 156
 157        if (usb_disabled())
 158                return -ENODEV;
 159
 160        irq = platform_get_irq(dev, 0);
 161        if (irq < 0)
 162                return irq;
 163        res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
 164        if (!res_mem) {
 165                dev_err(&dev->dev, "no memory resource provided");
 166                return -ENXIO;
 167        }
 168
 169        hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
 170                             dev_name(&dev->dev));
 171        if (!hcd)
 172                return -ENOMEM;
 173
 174        platform_set_drvdata(dev, hcd);
 175        dev->dev.platform_data = pdata;
 176        priv = hcd_to_ehci_priv(hcd);
 177
 178        priv->phy = devm_phy_get(&dev->dev, "usb");
 179        if (IS_ERR(priv->phy)) {
 180                err = PTR_ERR(priv->phy);
 181                goto err_put_hcd;
 182        }
 183
 184        for (clk = 0; clk < USB_MAX_CLKS; clk++) {
 185                priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
 186                if (IS_ERR(priv->clks[clk])) {
 187                        err = PTR_ERR(priv->clks[clk]);
 188                        if (err == -EPROBE_DEFER)
 189                                goto err_put_clks;
 190                        priv->clks[clk] = NULL;
 191                        break;
 192                }
 193        }
 194
 195        /* some SoCs don't have a dedicated 48Mhz clock, but those that
 196           do need the rate to be explicitly set */
 197        priv->clk48 = devm_clk_get(&dev->dev, "clk48");
 198        if (IS_ERR(priv->clk48)) {
 199                dev_info(&dev->dev, "48MHz clk not found\n");
 200                priv->clk48 = NULL;
 201        }
 202
 203        priv->pwr =
 204                devm_reset_control_get_optional_shared(&dev->dev, "power");
 205        if (IS_ERR(priv->pwr)) {
 206                err = PTR_ERR(priv->pwr);
 207                if (err == -EPROBE_DEFER)
 208                        goto err_put_clks;
 209                priv->pwr = NULL;
 210        }
 211
 212        priv->rst =
 213                devm_reset_control_get_optional_shared(&dev->dev, "softreset");
 214        if (IS_ERR(priv->rst)) {
 215                err = PTR_ERR(priv->rst);
 216                if (err == -EPROBE_DEFER)
 217                        goto err_put_clks;
 218                priv->rst = NULL;
 219        }
 220
 221        if (pdata->power_on) {
 222                err = pdata->power_on(dev);
 223                if (err < 0)
 224                        goto err_put_clks;
 225        }
 226
 227        hcd->rsrc_start = res_mem->start;
 228        hcd->rsrc_len = resource_size(res_mem);
 229
 230        hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
 231        if (IS_ERR(hcd->regs)) {
 232                err = PTR_ERR(hcd->regs);
 233                goto err_put_clks;
 234        }
 235
 236        err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 237        if (err)
 238                goto err_put_clks;
 239
 240        device_wakeup_enable(hcd->self.controller);
 241        platform_set_drvdata(dev, hcd);
 242
 243        return err;
 244
 245err_put_clks:
 246        while (--clk >= 0)
 247                clk_put(priv->clks[clk]);
 248err_put_hcd:
 249        if (pdata == &ehci_platform_defaults)
 250                dev->dev.platform_data = NULL;
 251
 252        usb_put_hcd(hcd);
 253
 254        return err;
 255}
 256
 257static int st_ehci_platform_remove(struct platform_device *dev)
 258{
 259        struct usb_hcd *hcd = platform_get_drvdata(dev);
 260        struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
 261        struct st_ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
 262        int clk;
 263
 264        usb_remove_hcd(hcd);
 265
 266        if (pdata->power_off)
 267                pdata->power_off(dev);
 268
 269        for (clk = 0; clk < USB_MAX_CLKS && priv->clks[clk]; clk++)
 270                clk_put(priv->clks[clk]);
 271
 272        usb_put_hcd(hcd);
 273
 274        if (pdata == &ehci_platform_defaults)
 275                dev->dev.platform_data = NULL;
 276
 277        return 0;
 278}
 279
 280#ifdef CONFIG_PM_SLEEP
 281
 282static int st_ehci_suspend(struct device *dev)
 283{
 284        struct usb_hcd *hcd = dev_get_drvdata(dev);
 285        struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
 286        struct platform_device *pdev = to_platform_device(dev);
 287        bool do_wakeup = device_may_wakeup(dev);
 288        int ret;
 289
 290        ret = ehci_suspend(hcd, do_wakeup);
 291        if (ret)
 292                return ret;
 293
 294        if (pdata->power_suspend)
 295                pdata->power_suspend(pdev);
 296
 297        pinctrl_pm_select_sleep_state(dev);
 298
 299        return ret;
 300}
 301
 302static int st_ehci_resume(struct device *dev)
 303{
 304        struct usb_hcd *hcd = dev_get_drvdata(dev);
 305        struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
 306        struct platform_device *pdev = to_platform_device(dev);
 307        int err;
 308
 309        pinctrl_pm_select_default_state(dev);
 310
 311        if (pdata->power_on) {
 312                err = pdata->power_on(pdev);
 313                if (err < 0)
 314                        return err;
 315        }
 316
 317        ehci_resume(hcd, false);
 318        return 0;
 319}
 320
 321static SIMPLE_DEV_PM_OPS(st_ehci_pm_ops, st_ehci_suspend, st_ehci_resume);
 322
 323#endif /* CONFIG_PM_SLEEP */
 324
 325static const struct of_device_id st_ehci_ids[] = {
 326        { .compatible = "st,st-ehci-300x", },
 327        { /* sentinel */ }
 328};
 329MODULE_DEVICE_TABLE(of, st_ehci_ids);
 330
 331static struct platform_driver ehci_platform_driver = {
 332        .probe          = st_ehci_platform_probe,
 333        .remove         = st_ehci_platform_remove,
 334        .shutdown       = usb_hcd_platform_shutdown,
 335        .driver         = {
 336                .name   = "st-ehci",
 337#ifdef CONFIG_PM_SLEEP
 338                .pm     = &st_ehci_pm_ops,
 339#endif
 340                .of_match_table = st_ehci_ids,
 341        }
 342};
 343
 344static int __init ehci_platform_init(void)
 345{
 346        if (usb_disabled())
 347                return -ENODEV;
 348
 349        pr_info("%s: " DRIVER_DESC "\n", hcd_name);
 350
 351        ehci_init_driver(&ehci_platform_hc_driver, &platform_overrides);
 352        return platform_driver_register(&ehci_platform_driver);
 353}
 354module_init(ehci_platform_init);
 355
 356static void __exit ehci_platform_cleanup(void)
 357{
 358        platform_driver_unregister(&ehci_platform_driver);
 359}
 360module_exit(ehci_platform_cleanup);
 361
 362MODULE_DESCRIPTION(DRIVER_DESC);
 363MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
 364MODULE_LICENSE("GPL");
 365