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