root/drivers/usb/host/ohci-st.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st_ohci_platform_power_on
  2. st_ohci_platform_power_off
  3. st_ohci_platform_probe
  4. st_ohci_platform_remove
  5. st_ohci_suspend
  6. st_ohci_resume
  7. ohci_platform_init
  8. ohci_platform_cleanup

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

/* [<][>][^][v][top][bottom][index][help] */