linux/drivers/usb/dwc2/platform.c
<<
>>
Prefs
   1/*
   2 * platform.c - DesignWare HS OTG Controller platform driver
   3 *
   4 * Copyright (C) Matthijs Kooijman <matthijs@stdin.nl>
   5 *
   6 * Redistribution and use in source and binary forms, with or without
   7 * modification, are permitted provided that the following conditions
   8 * are met:
   9 * 1. Redistributions of source code must retain the above copyright
  10 *    notice, this list of conditions, and the following disclaimer,
  11 *    without modification.
  12 * 2. Redistributions in binary form must reproduce the above copyright
  13 *    notice, this list of conditions and the following disclaimer in the
  14 *    documentation and/or other materials provided with the distribution.
  15 * 3. The names of the above-listed copyright holders may not be used
  16 *    to endorse or promote products derived from this software without
  17 *    specific prior written permission.
  18 *
  19 * ALTERNATIVELY, this software may be distributed under the terms of the
  20 * GNU General Public License ("GPL") as published by the Free Software
  21 * Foundation; either version 2 of the License, or (at your option) any
  22 * later version.
  23 *
  24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  26 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35 */
  36
  37#include <linux/kernel.h>
  38#include <linux/module.h>
  39#include <linux/slab.h>
  40#include <linux/clk.h>
  41#include <linux/device.h>
  42#include <linux/dma-mapping.h>
  43#include <linux/of_device.h>
  44#include <linux/mutex.h>
  45#include <linux/platform_device.h>
  46#include <linux/phy/phy.h>
  47#include <linux/platform_data/s3c-hsotg.h>
  48#include <linux/reset.h>
  49
  50#include <linux/usb/of.h>
  51
  52#include "core.h"
  53#include "hcd.h"
  54#include "debug.h"
  55
  56static const char dwc2_driver_name[] = "dwc2";
  57
  58static const struct dwc2_core_params params_hi6220 = {
  59        .otg_cap                        = 2,    /* No HNP/SRP capable */
  60        .otg_ver                        = 0,    /* 1.3 */
  61        .dma_enable                     = 1,
  62        .dma_desc_enable                = 0,
  63        .dma_desc_fs_enable             = 0,
  64        .speed                          = 0,    /* High Speed */
  65        .enable_dynamic_fifo            = 1,
  66        .en_multiple_tx_fifo            = 1,
  67        .host_rx_fifo_size              = 512,
  68        .host_nperio_tx_fifo_size       = 512,
  69        .host_perio_tx_fifo_size        = 512,
  70        .max_transfer_size              = 65535,
  71        .max_packet_count               = 511,
  72        .host_channels                  = 16,
  73        .phy_type                       = 1,    /* UTMI */
  74        .phy_utmi_width                 = 8,
  75        .phy_ulpi_ddr                   = 0,    /* Single */
  76        .phy_ulpi_ext_vbus              = 0,
  77        .i2c_enable                     = 0,
  78        .ulpi_fs_ls                     = 0,
  79        .host_support_fs_ls_low_power   = 0,
  80        .host_ls_low_power_phy_clk      = 0,    /* 48 MHz */
  81        .ts_dline                       = 0,
  82        .reload_ctl                     = 0,
  83        .ahbcfg                         = GAHBCFG_HBSTLEN_INCR16 <<
  84                                          GAHBCFG_HBSTLEN_SHIFT,
  85        .uframe_sched                   = 0,
  86        .external_id_pin_ctl            = -1,
  87        .hibernation                    = -1,
  88};
  89
  90static const struct dwc2_core_params params_bcm2835 = {
  91        .otg_cap                        = 0,    /* HNP/SRP capable */
  92        .otg_ver                        = 0,    /* 1.3 */
  93        .dma_enable                     = 1,
  94        .dma_desc_enable                = 0,
  95        .dma_desc_fs_enable             = 0,
  96        .speed                          = 0,    /* High Speed */
  97        .enable_dynamic_fifo            = 1,
  98        .en_multiple_tx_fifo            = 1,
  99        .host_rx_fifo_size              = 774,  /* 774 DWORDs */
 100        .host_nperio_tx_fifo_size       = 256,  /* 256 DWORDs */
 101        .host_perio_tx_fifo_size        = 512,  /* 512 DWORDs */
 102        .max_transfer_size              = 65535,
 103        .max_packet_count               = 511,
 104        .host_channels                  = 8,
 105        .phy_type                       = 1,    /* UTMI */
 106        .phy_utmi_width                 = 8,    /* 8 bits */
 107        .phy_ulpi_ddr                   = 0,    /* Single */
 108        .phy_ulpi_ext_vbus              = 0,
 109        .i2c_enable                     = 0,
 110        .ulpi_fs_ls                     = 0,
 111        .host_support_fs_ls_low_power   = 0,
 112        .host_ls_low_power_phy_clk      = 0,    /* 48 MHz */
 113        .ts_dline                       = 0,
 114        .reload_ctl                     = 0,
 115        .ahbcfg                         = 0x10,
 116        .uframe_sched                   = 0,
 117        .external_id_pin_ctl            = -1,
 118        .hibernation                    = -1,
 119};
 120
 121static const struct dwc2_core_params params_rk3066 = {
 122        .otg_cap                        = 2,    /* non-HNP/non-SRP */
 123        .otg_ver                        = -1,
 124        .dma_enable                     = -1,
 125        .dma_desc_enable                = 0,
 126        .dma_desc_fs_enable             = 0,
 127        .speed                          = -1,
 128        .enable_dynamic_fifo            = 1,
 129        .en_multiple_tx_fifo            = -1,
 130        .host_rx_fifo_size              = 525,  /* 525 DWORDs */
 131        .host_nperio_tx_fifo_size       = 128,  /* 128 DWORDs */
 132        .host_perio_tx_fifo_size        = 256,  /* 256 DWORDs */
 133        .max_transfer_size              = -1,
 134        .max_packet_count               = -1,
 135        .host_channels                  = -1,
 136        .phy_type                       = -1,
 137        .phy_utmi_width                 = -1,
 138        .phy_ulpi_ddr                   = -1,
 139        .phy_ulpi_ext_vbus              = -1,
 140        .i2c_enable                     = -1,
 141        .ulpi_fs_ls                     = -1,
 142        .host_support_fs_ls_low_power   = -1,
 143        .host_ls_low_power_phy_clk      = -1,
 144        .ts_dline                       = -1,
 145        .reload_ctl                     = -1,
 146        .ahbcfg                         = GAHBCFG_HBSTLEN_INCR16 <<
 147                                          GAHBCFG_HBSTLEN_SHIFT,
 148        .uframe_sched                   = -1,
 149        .external_id_pin_ctl            = -1,
 150        .hibernation                    = -1,
 151};
 152
 153static const struct dwc2_core_params params_ltq = {
 154        .otg_cap                        = 2,    /* non-HNP/non-SRP */
 155        .otg_ver                        = -1,
 156        .dma_enable                     = -1,
 157        .dma_desc_enable                = -1,
 158        .dma_desc_fs_enable             = -1,
 159        .speed                          = -1,
 160        .enable_dynamic_fifo            = -1,
 161        .en_multiple_tx_fifo            = -1,
 162        .host_rx_fifo_size              = 288,  /* 288 DWORDs */
 163        .host_nperio_tx_fifo_size       = 128,  /* 128 DWORDs */
 164        .host_perio_tx_fifo_size        = 96,   /* 96 DWORDs */
 165        .max_transfer_size              = 65535,
 166        .max_packet_count               = 511,
 167        .host_channels                  = -1,
 168        .phy_type                       = -1,
 169        .phy_utmi_width                 = -1,
 170        .phy_ulpi_ddr                   = -1,
 171        .phy_ulpi_ext_vbus              = -1,
 172        .i2c_enable                     = -1,
 173        .ulpi_fs_ls                     = -1,
 174        .host_support_fs_ls_low_power   = -1,
 175        .host_ls_low_power_phy_clk      = -1,
 176        .ts_dline                       = -1,
 177        .reload_ctl                     = -1,
 178        .ahbcfg                         = GAHBCFG_HBSTLEN_INCR16 <<
 179                                          GAHBCFG_HBSTLEN_SHIFT,
 180        .uframe_sched                   = -1,
 181        .external_id_pin_ctl            = -1,
 182        .hibernation                    = -1,
 183};
 184
 185static const struct dwc2_core_params params_amlogic = {
 186        .otg_cap                        = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE,
 187        .otg_ver                        = -1,
 188        .dma_enable                     = 1,
 189        .dma_desc_enable                = 0,
 190        .dma_desc_fs_enable             = 0,
 191        .speed                          = DWC2_SPEED_PARAM_HIGH,
 192        .enable_dynamic_fifo            = 1,
 193        .en_multiple_tx_fifo            = -1,
 194        .host_rx_fifo_size              = 512,
 195        .host_nperio_tx_fifo_size       = 500,
 196        .host_perio_tx_fifo_size        = 500,
 197        .max_transfer_size              = -1,
 198        .max_packet_count               = -1,
 199        .host_channels                  = 16,
 200        .phy_type                       = DWC2_PHY_TYPE_PARAM_UTMI,
 201        .phy_utmi_width                 = -1,
 202        .phy_ulpi_ddr                   = -1,
 203        .phy_ulpi_ext_vbus              = -1,
 204        .i2c_enable                     = -1,
 205        .ulpi_fs_ls                     = -1,
 206        .host_support_fs_ls_low_power   = -1,
 207        .host_ls_low_power_phy_clk      = -1,
 208        .ts_dline                       = -1,
 209        .reload_ctl                     = 1,
 210        .ahbcfg                         = GAHBCFG_HBSTLEN_INCR8 <<
 211                                          GAHBCFG_HBSTLEN_SHIFT,
 212        .uframe_sched                   = 0,
 213        .external_id_pin_ctl            = -1,
 214        .hibernation                    = -1,
 215};
 216
 217/*
 218 * Check the dr_mode against the module configuration and hardware
 219 * capabilities.
 220 *
 221 * The hardware, module, and dr_mode, can each be set to host, device,
 222 * or otg. Check that all these values are compatible and adjust the
 223 * value of dr_mode if possible.
 224 *
 225 *                      actual
 226 *    HW  MOD dr_mode   dr_mode
 227 *  ------------------------------
 228 *   HST  HST  any    :  HST
 229 *   HST  DEV  any    :  ---
 230 *   HST  OTG  any    :  HST
 231 *
 232 *   DEV  HST  any    :  ---
 233 *   DEV  DEV  any    :  DEV
 234 *   DEV  OTG  any    :  DEV
 235 *
 236 *   OTG  HST  any    :  HST
 237 *   OTG  DEV  any    :  DEV
 238 *   OTG  OTG  any    :  dr_mode
 239 */
 240static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
 241{
 242        enum usb_dr_mode mode;
 243
 244        hsotg->dr_mode = usb_get_dr_mode(hsotg->dev);
 245        if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN)
 246                hsotg->dr_mode = USB_DR_MODE_OTG;
 247
 248        mode = hsotg->dr_mode;
 249
 250        if (dwc2_hw_is_device(hsotg)) {
 251                if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) {
 252                        dev_err(hsotg->dev,
 253                                "Controller does not support host mode.\n");
 254                        return -EINVAL;
 255                }
 256                mode = USB_DR_MODE_PERIPHERAL;
 257        } else if (dwc2_hw_is_host(hsotg)) {
 258                if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) {
 259                        dev_err(hsotg->dev,
 260                                "Controller does not support device mode.\n");
 261                        return -EINVAL;
 262                }
 263                mode = USB_DR_MODE_HOST;
 264        } else {
 265                if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
 266                        mode = USB_DR_MODE_HOST;
 267                else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL))
 268                        mode = USB_DR_MODE_PERIPHERAL;
 269        }
 270
 271        if (mode != hsotg->dr_mode) {
 272                dev_warn(hsotg->dev,
 273                        "Configuration mismatch. dr_mode forced to %s\n",
 274                        mode == USB_DR_MODE_HOST ? "host" : "device");
 275
 276                hsotg->dr_mode = mode;
 277        }
 278
 279        return 0;
 280}
 281
 282static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 283{
 284        struct platform_device *pdev = to_platform_device(hsotg->dev);
 285        int ret;
 286
 287        ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
 288                                    hsotg->supplies);
 289        if (ret)
 290                return ret;
 291
 292        if (hsotg->clk) {
 293                ret = clk_prepare_enable(hsotg->clk);
 294                if (ret)
 295                        return ret;
 296        }
 297
 298        if (hsotg->uphy)
 299                ret = usb_phy_init(hsotg->uphy);
 300        else if (hsotg->plat && hsotg->plat->phy_init)
 301                ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
 302        else {
 303                ret = phy_power_on(hsotg->phy);
 304                if (ret == 0)
 305                        ret = phy_init(hsotg->phy);
 306        }
 307
 308        return ret;
 309}
 310
 311/**
 312 * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources
 313 * @hsotg: The driver state
 314 *
 315 * A wrapper for platform code responsible for controlling
 316 * low-level USB platform resources (phy, clock, regulators)
 317 */
 318int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 319{
 320        int ret = __dwc2_lowlevel_hw_enable(hsotg);
 321
 322        if (ret == 0)
 323                hsotg->ll_hw_enabled = true;
 324        return ret;
 325}
 326
 327static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 328{
 329        struct platform_device *pdev = to_platform_device(hsotg->dev);
 330        int ret = 0;
 331
 332        if (hsotg->uphy)
 333                usb_phy_shutdown(hsotg->uphy);
 334        else if (hsotg->plat && hsotg->plat->phy_exit)
 335                ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
 336        else {
 337                ret = phy_exit(hsotg->phy);
 338                if (ret == 0)
 339                        ret = phy_power_off(hsotg->phy);
 340        }
 341        if (ret)
 342                return ret;
 343
 344        if (hsotg->clk)
 345                clk_disable_unprepare(hsotg->clk);
 346
 347        ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
 348                                     hsotg->supplies);
 349
 350        return ret;
 351}
 352
 353/**
 354 * dwc2_lowlevel_hw_disable - disable platform lowlevel hw resources
 355 * @hsotg: The driver state
 356 *
 357 * A wrapper for platform code responsible for controlling
 358 * low-level USB platform resources (phy, clock, regulators)
 359 */
 360int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 361{
 362        int ret = __dwc2_lowlevel_hw_disable(hsotg);
 363
 364        if (ret == 0)
 365                hsotg->ll_hw_enabled = false;
 366        return ret;
 367}
 368
 369static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 370{
 371        int i, ret;
 372
 373        hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2");
 374        if (IS_ERR(hsotg->reset)) {
 375                ret = PTR_ERR(hsotg->reset);
 376                switch (ret) {
 377                case -ENOENT:
 378                case -ENOTSUPP:
 379                        hsotg->reset = NULL;
 380                        break;
 381                default:
 382                        dev_err(hsotg->dev, "error getting reset control %d\n",
 383                                ret);
 384                        return ret;
 385                }
 386        }
 387
 388        if (hsotg->reset)
 389                reset_control_deassert(hsotg->reset);
 390
 391        /* Set default UTMI width */
 392        hsotg->phyif = GUSBCFG_PHYIF16;
 393
 394        /*
 395         * Attempt to find a generic PHY, then look for an old style
 396         * USB PHY and then fall back to pdata
 397         */
 398        hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
 399        if (IS_ERR(hsotg->phy)) {
 400                ret = PTR_ERR(hsotg->phy);
 401                switch (ret) {
 402                case -ENODEV:
 403                case -ENOSYS:
 404                        hsotg->phy = NULL;
 405                        break;
 406                case -EPROBE_DEFER:
 407                        return ret;
 408                default:
 409                        dev_err(hsotg->dev, "error getting phy %d\n", ret);
 410                        return ret;
 411                }
 412        }
 413
 414        if (!hsotg->phy) {
 415                hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
 416                if (IS_ERR(hsotg->uphy)) {
 417                        ret = PTR_ERR(hsotg->uphy);
 418                        switch (ret) {
 419                        case -ENODEV:
 420                        case -ENXIO:
 421                                hsotg->uphy = NULL;
 422                                break;
 423                        case -EPROBE_DEFER:
 424                                return ret;
 425                        default:
 426                                dev_err(hsotg->dev, "error getting usb phy %d\n",
 427                                        ret);
 428                                return ret;
 429                        }
 430                }
 431        }
 432
 433        hsotg->plat = dev_get_platdata(hsotg->dev);
 434
 435        if (hsotg->phy) {
 436                /*
 437                 * If using the generic PHY framework, check if the PHY bus
 438                 * width is 8-bit and set the phyif appropriately.
 439                 */
 440                if (phy_get_bus_width(hsotg->phy) == 8)
 441                        hsotg->phyif = GUSBCFG_PHYIF8;
 442        }
 443
 444        /* Clock */
 445        hsotg->clk = devm_clk_get(hsotg->dev, "otg");
 446        if (IS_ERR(hsotg->clk)) {
 447                hsotg->clk = NULL;
 448                dev_dbg(hsotg->dev, "cannot get otg clock\n");
 449        }
 450
 451        /* Regulators */
 452        for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
 453                hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
 454
 455        ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies),
 456                                      hsotg->supplies);
 457        if (ret) {
 458                dev_err(hsotg->dev, "failed to request supplies: %d\n", ret);
 459                return ret;
 460        }
 461        return 0;
 462}
 463
 464/**
 465 * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
 466 * DWC_otg driver
 467 *
 468 * @dev: Platform device
 469 *
 470 * This routine is called, for example, when the rmmod command is executed. The
 471 * device may or may not be electrically present. If it is present, the driver
 472 * stops device processing. Any resources used on behalf of this device are
 473 * freed.
 474 */
 475static int dwc2_driver_remove(struct platform_device *dev)
 476{
 477        struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
 478
 479        dwc2_debugfs_exit(hsotg);
 480        if (hsotg->hcd_enabled)
 481                dwc2_hcd_remove(hsotg);
 482        if (hsotg->gadget_enabled)
 483                dwc2_hsotg_remove(hsotg);
 484
 485        if (hsotg->ll_hw_enabled)
 486                dwc2_lowlevel_hw_disable(hsotg);
 487
 488        if (hsotg->reset)
 489                reset_control_assert(hsotg->reset);
 490
 491        return 0;
 492}
 493
 494/**
 495 * dwc2_driver_shutdown() - Called on device shutdown
 496 *
 497 * @dev: Platform device
 498 *
 499 * In specific conditions (involving usb hubs) dwc2 devices can create a
 500 * lot of interrupts, even to the point of overwhelming devices running
 501 * at low frequencies. Some devices need to do special clock handling
 502 * at shutdown-time which may bring the system clock below the threshold
 503 * of being able to handle the dwc2 interrupts. Disabling dwc2-irqs
 504 * prevents reboots/poweroffs from getting stuck in such cases.
 505 */
 506static void dwc2_driver_shutdown(struct platform_device *dev)
 507{
 508        struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
 509
 510        disable_irq(hsotg->irq);
 511}
 512
 513static const struct of_device_id dwc2_of_match_table[] = {
 514        { .compatible = "brcm,bcm2835-usb", .data = &params_bcm2835 },
 515        { .compatible = "hisilicon,hi6220-usb", .data = &params_hi6220 },
 516        { .compatible = "rockchip,rk3066-usb", .data = &params_rk3066 },
 517        { .compatible = "lantiq,arx100-usb", .data = &params_ltq },
 518        { .compatible = "lantiq,xrx200-usb", .data = &params_ltq },
 519        { .compatible = "snps,dwc2", .data = NULL },
 520        { .compatible = "samsung,s3c6400-hsotg", .data = NULL},
 521        { .compatible = "amlogic,meson8b-usb", .data = &params_amlogic },
 522        { .compatible = "amlogic,meson-gxbb-usb", .data = &params_amlogic },
 523        {},
 524};
 525MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
 526
 527/**
 528 * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg
 529 * driver
 530 *
 531 * @dev: Platform device
 532 *
 533 * This routine creates the driver components required to control the device
 534 * (core, HCD, and PCD) and initializes the device. The driver components are
 535 * stored in a dwc2_hsotg structure. A reference to the dwc2_hsotg is saved
 536 * in the device private data. This allows the driver to access the dwc2_hsotg
 537 * structure on subsequent calls to driver methods for this device.
 538 */
 539static int dwc2_driver_probe(struct platform_device *dev)
 540{
 541        const struct of_device_id *match;
 542        const struct dwc2_core_params *params;
 543        struct dwc2_core_params defparams;
 544        struct dwc2_hsotg *hsotg;
 545        struct resource *res;
 546        int retval;
 547
 548        match = of_match_device(dwc2_of_match_table, &dev->dev);
 549        if (match && match->data) {
 550                params = match->data;
 551        } else {
 552                /* Default all params to autodetect */
 553                dwc2_set_all_params(&defparams, -1);
 554                params = &defparams;
 555
 556                /*
 557                 * Disable descriptor dma mode by default as the HW can support
 558                 * it, but does not support it for SPLIT transactions.
 559                 * Disable it for FS devices as well.
 560                 */
 561                defparams.dma_desc_enable = 0;
 562                defparams.dma_desc_fs_enable = 0;
 563        }
 564
 565        hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
 566        if (!hsotg)
 567                return -ENOMEM;
 568
 569        hsotg->dev = &dev->dev;
 570
 571        /*
 572         * Use reasonable defaults so platforms don't have to provide these.
 573         */
 574        if (!dev->dev.dma_mask)
 575                dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
 576        retval = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
 577        if (retval)
 578                return retval;
 579
 580        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 581        hsotg->regs = devm_ioremap_resource(&dev->dev, res);
 582        if (IS_ERR(hsotg->regs))
 583                return PTR_ERR(hsotg->regs);
 584
 585        dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
 586                (unsigned long)res->start, hsotg->regs);
 587
 588        retval = dwc2_lowlevel_hw_init(hsotg);
 589        if (retval)
 590                return retval;
 591
 592        spin_lock_init(&hsotg->lock);
 593
 594        hsotg->core_params = devm_kzalloc(&dev->dev,
 595                                sizeof(*hsotg->core_params), GFP_KERNEL);
 596        if (!hsotg->core_params)
 597                return -ENOMEM;
 598
 599        dwc2_set_all_params(hsotg->core_params, -1);
 600
 601        hsotg->irq = platform_get_irq(dev, 0);
 602        if (hsotg->irq < 0) {
 603                dev_err(&dev->dev, "missing IRQ resource\n");
 604                return hsotg->irq;
 605        }
 606
 607        dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
 608                hsotg->irq);
 609        retval = devm_request_irq(hsotg->dev, hsotg->irq,
 610                                  dwc2_handle_common_intr, IRQF_SHARED,
 611                                  dev_name(hsotg->dev), hsotg);
 612        if (retval)
 613                return retval;
 614
 615        retval = dwc2_lowlevel_hw_enable(hsotg);
 616        if (retval)
 617                return retval;
 618
 619        retval = dwc2_get_dr_mode(hsotg);
 620        if (retval)
 621                goto error;
 622
 623        /*
 624         * Reset before dwc2_get_hwparams() then it could get power-on real
 625         * reset value form registers.
 626         */
 627        dwc2_core_reset_and_force_dr_mode(hsotg);
 628
 629        /* Detect config values from hardware */
 630        retval = dwc2_get_hwparams(hsotg);
 631        if (retval)
 632                goto error;
 633
 634        /* Validate parameter values */
 635        dwc2_set_parameters(hsotg, params);
 636
 637        dwc2_force_dr_mode(hsotg);
 638
 639        if (hsotg->dr_mode != USB_DR_MODE_HOST) {
 640                retval = dwc2_gadget_init(hsotg, hsotg->irq);
 641                if (retval)
 642                        goto error;
 643                hsotg->gadget_enabled = 1;
 644        }
 645
 646        if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
 647                retval = dwc2_hcd_init(hsotg, hsotg->irq);
 648                if (retval) {
 649                        if (hsotg->gadget_enabled)
 650                                dwc2_hsotg_remove(hsotg);
 651                        goto error;
 652                }
 653                hsotg->hcd_enabled = 1;
 654        }
 655
 656        platform_set_drvdata(dev, hsotg);
 657
 658        dwc2_debugfs_init(hsotg);
 659
 660        /* Gadget code manages lowlevel hw on its own */
 661        if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
 662                dwc2_lowlevel_hw_disable(hsotg);
 663
 664        return 0;
 665
 666error:
 667        dwc2_lowlevel_hw_disable(hsotg);
 668        return retval;
 669}
 670
 671static int __maybe_unused dwc2_suspend(struct device *dev)
 672{
 673        struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 674        int ret = 0;
 675
 676        if (dwc2_is_device_mode(dwc2))
 677                dwc2_hsotg_suspend(dwc2);
 678
 679        if (dwc2->ll_hw_enabled)
 680                ret = __dwc2_lowlevel_hw_disable(dwc2);
 681
 682        return ret;
 683}
 684
 685static int __maybe_unused dwc2_resume(struct device *dev)
 686{
 687        struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 688        int ret = 0;
 689
 690        if (dwc2->ll_hw_enabled) {
 691                ret = __dwc2_lowlevel_hw_enable(dwc2);
 692                if (ret)
 693                        return ret;
 694        }
 695
 696        if (dwc2_is_device_mode(dwc2))
 697                ret = dwc2_hsotg_resume(dwc2);
 698
 699        return ret;
 700}
 701
 702static const struct dev_pm_ops dwc2_dev_pm_ops = {
 703        SET_SYSTEM_SLEEP_PM_OPS(dwc2_suspend, dwc2_resume)
 704};
 705
 706static struct platform_driver dwc2_platform_driver = {
 707        .driver = {
 708                .name = dwc2_driver_name,
 709                .of_match_table = dwc2_of_match_table,
 710                .pm = &dwc2_dev_pm_ops,
 711        },
 712        .probe = dwc2_driver_probe,
 713        .remove = dwc2_driver_remove,
 714        .shutdown = dwc2_driver_shutdown,
 715};
 716
 717module_platform_driver(dwc2_platform_driver);
 718
 719MODULE_DESCRIPTION("DESIGNWARE HS OTG Platform Glue");
 720MODULE_AUTHOR("Matthijs Kooijman <matthijs@stdin.nl>");
 721MODULE_LICENSE("Dual BSD/GPL");
 722