linux/drivers/usb/renesas_usbhs/common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-1.0+
   2/*
   3 * Renesas USB driver
   4 *
   5 * Copyright (C) 2011 Renesas Solutions Corp.
   6 * Copyright (C) 2019 Renesas Electronics Corporation
   7 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
   8 */
   9#include <linux/clk.h>
  10#include <linux/err.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/io.h>
  13#include <linux/module.h>
  14#include <linux/of_device.h>
  15#include <linux/pm_runtime.h>
  16#include <linux/reset.h>
  17#include <linux/slab.h>
  18#include <linux/sysfs.h>
  19#include "common.h"
  20#include "rcar2.h"
  21#include "rcar3.h"
  22#include "rza.h"
  23
  24/*
  25 *              image of renesas_usbhs
  26 *
  27 * ex) gadget case
  28
  29 * mod.c
  30 * mod_gadget.c
  31 * mod_host.c           pipe.c          fifo.c
  32 *
  33 *                      +-------+       +-----------+
  34 *                      | pipe0 |------>| fifo pio  |
  35 * +------------+       +-------+       +-----------+
  36 * | mod_gadget |=====> | pipe1 |--+
  37 * +------------+       +-------+  |    +-----------+
  38 *                      | pipe2 |  |  +-| fifo dma0 |
  39 * +------------+       +-------+  |  | +-----------+
  40 * | mod_host   |       | pipe3 |<-|--+
  41 * +------------+       +-------+  |    +-----------+
  42 *                      | ....  |  +--->| fifo dma1 |
  43 *                      | ....  |       +-----------+
  44 */
  45
  46/*
  47 * platform call back
  48 *
  49 * renesas usb support platform callback function.
  50 * Below macro call it.
  51 * if platform doesn't have callback, it return 0 (no error)
  52 */
  53#define usbhs_platform_call(priv, func, args...)\
  54        (!(priv) ? -ENODEV :                    \
  55         !((priv)->pfunc->func) ? 0 :           \
  56         (priv)->pfunc->func(args))
  57
  58/*
  59 *              common functions
  60 */
  61u16 usbhs_read(struct usbhs_priv *priv, u32 reg)
  62{
  63        return ioread16(priv->base + reg);
  64}
  65
  66void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data)
  67{
  68        iowrite16(data, priv->base + reg);
  69}
  70
  71void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data)
  72{
  73        u16 val = usbhs_read(priv, reg);
  74
  75        val &= ~mask;
  76        val |= data & mask;
  77
  78        usbhs_write(priv, reg, val);
  79}
  80
  81struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev)
  82{
  83        return dev_get_drvdata(&pdev->dev);
  84}
  85
  86int usbhs_get_id_as_gadget(struct platform_device *pdev)
  87{
  88        return USBHS_GADGET;
  89}
  90
  91/*
  92 *              syscfg functions
  93 */
  94static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
  95{
  96        usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0);
  97}
  98
  99void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
 100{
 101        u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
 102        u16 val  = DCFM | DRPD | HSE | USBE;
 103
 104        /*
 105         * if enable
 106         *
 107         * - select Host mode
 108         * - D+ Line/D- Line Pull-down
 109         */
 110        usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
 111}
 112
 113void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
 114{
 115        u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
 116        u16 val  = HSE | USBE;
 117
 118        /* CNEN bit is required for function operation */
 119        if (usbhs_get_dparam(priv, has_cnen)) {
 120                mask |= CNEN;
 121                val  |= CNEN;
 122        }
 123
 124        /*
 125         * if enable
 126         *
 127         * - select Function mode
 128         * - D+ Line Pull-up is disabled
 129         *      When D+ Line Pull-up is enabled,
 130         *      calling usbhs_sys_function_pullup(,1)
 131         */
 132        usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
 133}
 134
 135void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable)
 136{
 137        usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0);
 138}
 139
 140void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode)
 141{
 142        usbhs_write(priv, TESTMODE, mode);
 143}
 144
 145/*
 146 *              frame functions
 147 */
 148int usbhs_frame_get_num(struct usbhs_priv *priv)
 149{
 150        return usbhs_read(priv, FRMNUM) & FRNM_MASK;
 151}
 152
 153/*
 154 *              usb request functions
 155 */
 156void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
 157{
 158        u16 val;
 159
 160        val = usbhs_read(priv, USBREQ);
 161        req->bRequest           = (val >> 8) & 0xFF;
 162        req->bRequestType       = (val >> 0) & 0xFF;
 163
 164        req->wValue     = cpu_to_le16(usbhs_read(priv, USBVAL));
 165        req->wIndex     = cpu_to_le16(usbhs_read(priv, USBINDX));
 166        req->wLength    = cpu_to_le16(usbhs_read(priv, USBLENG));
 167}
 168
 169void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
 170{
 171        usbhs_write(priv, USBREQ,  (req->bRequest << 8) | req->bRequestType);
 172        usbhs_write(priv, USBVAL,  le16_to_cpu(req->wValue));
 173        usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex));
 174        usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength));
 175
 176        usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
 177}
 178
 179/*
 180 *              bus/vbus functions
 181 */
 182void usbhs_bus_send_sof_enable(struct usbhs_priv *priv)
 183{
 184        u16 status = usbhs_read(priv, DVSTCTR) & (USBRST | UACT);
 185
 186        if (status != USBRST) {
 187                struct device *dev = usbhs_priv_to_dev(priv);
 188                dev_err(dev, "usbhs should be reset\n");
 189        }
 190
 191        usbhs_bset(priv, DVSTCTR, (USBRST | UACT), UACT);
 192}
 193
 194void usbhs_bus_send_reset(struct usbhs_priv *priv)
 195{
 196        usbhs_bset(priv, DVSTCTR, (USBRST | UACT), USBRST);
 197}
 198
 199int usbhs_bus_get_speed(struct usbhs_priv *priv)
 200{
 201        u16 dvstctr = usbhs_read(priv, DVSTCTR);
 202
 203        switch (RHST & dvstctr) {
 204        case RHST_LOW_SPEED:
 205                return USB_SPEED_LOW;
 206        case RHST_FULL_SPEED:
 207                return USB_SPEED_FULL;
 208        case RHST_HIGH_SPEED:
 209                return USB_SPEED_HIGH;
 210        }
 211
 212        return USB_SPEED_UNKNOWN;
 213}
 214
 215int usbhs_vbus_ctrl(struct usbhs_priv *priv, int enable)
 216{
 217        struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 218
 219        return usbhs_platform_call(priv, set_vbus, pdev, enable);
 220}
 221
 222static void usbhsc_bus_init(struct usbhs_priv *priv)
 223{
 224        usbhs_write(priv, DVSTCTR, 0);
 225
 226        usbhs_vbus_ctrl(priv, 0);
 227}
 228
 229/*
 230 *              device configuration
 231 */
 232int usbhs_set_device_config(struct usbhs_priv *priv, int devnum,
 233                           u16 upphub, u16 hubport, u16 speed)
 234{
 235        struct device *dev = usbhs_priv_to_dev(priv);
 236        u16 usbspd = 0;
 237        u32 reg = DEVADD0 + (2 * devnum);
 238
 239        if (devnum > 10) {
 240                dev_err(dev, "cannot set speed to unknown device %d\n", devnum);
 241                return -EIO;
 242        }
 243
 244        if (upphub > 0xA) {
 245                dev_err(dev, "unsupported hub number %d\n", upphub);
 246                return -EIO;
 247        }
 248
 249        switch (speed) {
 250        case USB_SPEED_LOW:
 251                usbspd = USBSPD_SPEED_LOW;
 252                break;
 253        case USB_SPEED_FULL:
 254                usbspd = USBSPD_SPEED_FULL;
 255                break;
 256        case USB_SPEED_HIGH:
 257                usbspd = USBSPD_SPEED_HIGH;
 258                break;
 259        default:
 260                dev_err(dev, "unsupported speed %d\n", speed);
 261                return -EIO;
 262        }
 263
 264        usbhs_write(priv, reg,  UPPHUB(upphub)  |
 265                                HUBPORT(hubport)|
 266                                USBSPD(usbspd));
 267
 268        return 0;
 269}
 270
 271/*
 272 *              interrupt functions
 273 */
 274void usbhs_xxxsts_clear(struct usbhs_priv *priv, u16 sts_reg, u16 bit)
 275{
 276        u16 pipe_mask = (u16)GENMASK(usbhs_get_dparam(priv, pipe_size), 0);
 277
 278        usbhs_write(priv, sts_reg, ~(1 << bit) & pipe_mask);
 279}
 280
 281/*
 282 *              local functions
 283 */
 284static void usbhsc_set_buswait(struct usbhs_priv *priv)
 285{
 286        int wait = usbhs_get_dparam(priv, buswait_bwait);
 287
 288        /* set bus wait if platform have */
 289        if (wait)
 290                usbhs_bset(priv, BUSWAIT, 0x000F, wait);
 291}
 292
 293static bool usbhsc_is_multi_clks(struct usbhs_priv *priv)
 294{
 295        return priv->dparam.multi_clks;
 296}
 297
 298static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv)
 299{
 300        if (!usbhsc_is_multi_clks(priv))
 301                return 0;
 302
 303        /* The first clock should exist */
 304        priv->clks[0] = of_clk_get(dev_of_node(dev), 0);
 305        if (IS_ERR(priv->clks[0]))
 306                return PTR_ERR(priv->clks[0]);
 307
 308        /*
 309         * To backward compatibility with old DT, this driver checks the return
 310         * value if it's -ENOENT or not.
 311         */
 312        priv->clks[1] = of_clk_get(dev_of_node(dev), 1);
 313        if (PTR_ERR(priv->clks[1]) == -ENOENT)
 314                priv->clks[1] = NULL;
 315        else if (IS_ERR(priv->clks[1]))
 316                return PTR_ERR(priv->clks[1]);
 317
 318        return 0;
 319}
 320
 321static void usbhsc_clk_put(struct usbhs_priv *priv)
 322{
 323        int i;
 324
 325        if (!usbhsc_is_multi_clks(priv))
 326                return;
 327
 328        for (i = 0; i < ARRAY_SIZE(priv->clks); i++)
 329                clk_put(priv->clks[i]);
 330}
 331
 332static int usbhsc_clk_prepare_enable(struct usbhs_priv *priv)
 333{
 334        int i, ret;
 335
 336        if (!usbhsc_is_multi_clks(priv))
 337                return 0;
 338
 339        for (i = 0; i < ARRAY_SIZE(priv->clks); i++) {
 340                ret = clk_prepare_enable(priv->clks[i]);
 341                if (ret) {
 342                        while (--i >= 0)
 343                                clk_disable_unprepare(priv->clks[i]);
 344                        return ret;
 345                }
 346        }
 347
 348        return ret;
 349}
 350
 351static void usbhsc_clk_disable_unprepare(struct usbhs_priv *priv)
 352{
 353        int i;
 354
 355        if (!usbhsc_is_multi_clks(priv))
 356                return;
 357
 358        for (i = 0; i < ARRAY_SIZE(priv->clks); i++)
 359                clk_disable_unprepare(priv->clks[i]);
 360}
 361
 362/*
 363 *              platform default param
 364 */
 365
 366/* commonly used on old SH-Mobile SoCs */
 367static struct renesas_usbhs_driver_pipe_config usbhsc_default_pipe[] = {
 368        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false),
 369        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, false),
 370        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x18, false),
 371        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x28, true),
 372        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x38, true),
 373        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true),
 374        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false),
 375        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false),
 376        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false),
 377        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x07, false),
 378};
 379
 380/* commonly used on newer SH-Mobile and R-Car SoCs */
 381static struct renesas_usbhs_driver_pipe_config usbhsc_new_pipe[] = {
 382        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false),
 383        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, true),
 384        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x28, true),
 385        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true),
 386        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x58, true),
 387        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x68, true),
 388        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false),
 389        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false),
 390        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false),
 391        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x78, true),
 392        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x88, true),
 393        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x98, true),
 394        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xa8, true),
 395        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xb8, true),
 396        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xc8, true),
 397        RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xd8, true),
 398};
 399
 400/*
 401 *              power control
 402 */
 403static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable)
 404{
 405        struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 406        struct device *dev = usbhs_priv_to_dev(priv);
 407
 408        if (enable) {
 409                /* enable PM */
 410                pm_runtime_get_sync(dev);
 411
 412                /* enable clks */
 413                if (usbhsc_clk_prepare_enable(priv))
 414                        return;
 415
 416                /* enable platform power */
 417                usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
 418
 419                /* USB on */
 420                usbhs_sys_clock_ctrl(priv, enable);
 421        } else {
 422                /* USB off */
 423                usbhs_sys_clock_ctrl(priv, enable);
 424
 425                /* disable platform power */
 426                usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
 427
 428                /* disable clks */
 429                usbhsc_clk_disable_unprepare(priv);
 430
 431                /* disable PM */
 432                pm_runtime_put_sync(dev);
 433        }
 434}
 435
 436/*
 437 *              hotplug
 438 */
 439static void usbhsc_hotplug(struct usbhs_priv *priv)
 440{
 441        struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 442        struct usbhs_mod *mod = usbhs_mod_get_current(priv);
 443        int id;
 444        int enable;
 445        int cable;
 446        int ret;
 447
 448        /*
 449         * get vbus status from platform
 450         */
 451        enable = usbhs_mod_info_call(priv, get_vbus, pdev);
 452
 453        /*
 454         * get id from platform
 455         */
 456        id = usbhs_platform_call(priv, get_id, pdev);
 457
 458        if (enable && !mod) {
 459                if (priv->edev) {
 460                        cable = extcon_get_state(priv->edev, EXTCON_USB_HOST);
 461                        if ((cable > 0 && id != USBHS_HOST) ||
 462                            (!cable && id != USBHS_GADGET)) {
 463                                dev_info(&pdev->dev,
 464                                         "USB cable plugged in doesn't match the selected role!\n");
 465                                return;
 466                        }
 467                }
 468
 469                ret = usbhs_mod_change(priv, id);
 470                if (ret < 0)
 471                        return;
 472
 473                dev_dbg(&pdev->dev, "%s enable\n", __func__);
 474
 475                /* power on */
 476                if (usbhs_get_dparam(priv, runtime_pwctrl))
 477                        usbhsc_power_ctrl(priv, enable);
 478
 479                /* bus init */
 480                usbhsc_set_buswait(priv);
 481                usbhsc_bus_init(priv);
 482
 483                /* module start */
 484                usbhs_mod_call(priv, start, priv);
 485
 486        } else if (!enable && mod) {
 487                dev_dbg(&pdev->dev, "%s disable\n", __func__);
 488
 489                /* module stop */
 490                usbhs_mod_call(priv, stop, priv);
 491
 492                /* bus init */
 493                usbhsc_bus_init(priv);
 494
 495                /* power off */
 496                if (usbhs_get_dparam(priv, runtime_pwctrl))
 497                        usbhsc_power_ctrl(priv, enable);
 498
 499                usbhs_mod_change(priv, -1);
 500
 501                /* reset phy for next connection */
 502                usbhs_platform_call(priv, phy_reset, pdev);
 503        }
 504}
 505
 506/*
 507 *              notify hotplug
 508 */
 509static void usbhsc_notify_hotplug(struct work_struct *work)
 510{
 511        struct usbhs_priv *priv = container_of(work,
 512                                               struct usbhs_priv,
 513                                               notify_hotplug_work.work);
 514        usbhsc_hotplug(priv);
 515}
 516
 517int usbhsc_schedule_notify_hotplug(struct platform_device *pdev)
 518{
 519        struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
 520        int delay = usbhs_get_dparam(priv, detection_delay);
 521
 522        /*
 523         * This functions will be called in interrupt.
 524         * To make sure safety context,
 525         * use workqueue for usbhs_notify_hotplug
 526         */
 527        schedule_delayed_work(&priv->notify_hotplug_work,
 528                              msecs_to_jiffies(delay));
 529        return 0;
 530}
 531
 532/*
 533 *              platform functions
 534 */
 535static const struct of_device_id usbhs_of_match[] = {
 536        {
 537                .compatible = "renesas,usbhs-r8a774c0",
 538                .data = &usbhs_rcar_gen3_with_pll_plat_info,
 539        },
 540        {
 541                .compatible = "renesas,usbhs-r8a7790",
 542                .data = &usbhs_rcar_gen2_plat_info,
 543        },
 544        {
 545                .compatible = "renesas,usbhs-r8a7791",
 546                .data = &usbhs_rcar_gen2_plat_info,
 547        },
 548        {
 549                .compatible = "renesas,usbhs-r8a7794",
 550                .data = &usbhs_rcar_gen2_plat_info,
 551        },
 552        {
 553                .compatible = "renesas,usbhs-r8a7795",
 554                .data = &usbhs_rcar_gen3_plat_info,
 555        },
 556        {
 557                .compatible = "renesas,usbhs-r8a7796",
 558                .data = &usbhs_rcar_gen3_plat_info,
 559        },
 560        {
 561                .compatible = "renesas,usbhs-r8a77990",
 562                .data = &usbhs_rcar_gen3_with_pll_plat_info,
 563        },
 564        {
 565                .compatible = "renesas,usbhs-r8a77995",
 566                .data = &usbhs_rcar_gen3_with_pll_plat_info,
 567        },
 568        {
 569                .compatible = "renesas,rcar-gen2-usbhs",
 570                .data = &usbhs_rcar_gen2_plat_info,
 571        },
 572        {
 573                .compatible = "renesas,rcar-gen3-usbhs",
 574                .data = &usbhs_rcar_gen3_plat_info,
 575        },
 576        {
 577                .compatible = "renesas,rza1-usbhs",
 578                .data = &usbhs_rza1_plat_info,
 579        },
 580        {
 581                .compatible = "renesas,rza2-usbhs",
 582                .data = &usbhs_rza2_plat_info,
 583        },
 584        { },
 585};
 586MODULE_DEVICE_TABLE(of, usbhs_of_match);
 587
 588static int usbhs_probe(struct platform_device *pdev)
 589{
 590        const struct renesas_usbhs_platform_info *info;
 591        struct usbhs_priv *priv;
 592        struct device *dev = &pdev->dev;
 593        struct gpio_desc *gpiod;
 594        int ret;
 595        u32 tmp;
 596        int irq;
 597
 598        /* check device node */
 599        if (dev_of_node(dev))
 600                info = of_device_get_match_data(dev);
 601        else
 602                info = renesas_usbhs_get_info(pdev);
 603
 604        /* check platform information */
 605        if (!info) {
 606                dev_err(dev, "no platform information\n");
 607                return -EINVAL;
 608        }
 609
 610        /* platform data */
 611        irq = platform_get_irq(pdev, 0);
 612        if (irq < 0)
 613                return irq;
 614
 615        /* usb private data */
 616        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 617        if (!priv)
 618                return -ENOMEM;
 619
 620        priv->base = devm_platform_ioremap_resource(pdev, 0);
 621        if (IS_ERR(priv->base))
 622                return PTR_ERR(priv->base);
 623
 624        if (of_property_read_bool(dev_of_node(dev), "extcon")) {
 625                priv->edev = extcon_get_edev_by_phandle(dev, 0);
 626                if (IS_ERR(priv->edev))
 627                        return PTR_ERR(priv->edev);
 628        }
 629
 630        priv->rsts = devm_reset_control_array_get_optional_shared(dev);
 631        if (IS_ERR(priv->rsts))
 632                return PTR_ERR(priv->rsts);
 633
 634        /*
 635         * care platform info
 636         */
 637
 638        priv->dparam = info->driver_param;
 639
 640        if (!info->platform_callback.get_id) {
 641                dev_err(dev, "no platform callbacks\n");
 642                return -EINVAL;
 643        }
 644        priv->pfunc = &info->platform_callback;
 645
 646        /* set default param if platform doesn't have */
 647        if (usbhs_get_dparam(priv, has_new_pipe_configs)) {
 648                priv->dparam.pipe_configs = usbhsc_new_pipe;
 649                priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
 650        } else if (!priv->dparam.pipe_configs) {
 651                priv->dparam.pipe_configs = usbhsc_default_pipe;
 652                priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe);
 653        }
 654        if (!priv->dparam.pio_dma_border)
 655                priv->dparam.pio_dma_border = 64; /* 64byte */
 656        if (!of_property_read_u32(dev_of_node(dev), "renesas,buswait", &tmp))
 657                priv->dparam.buswait_bwait = tmp;
 658        gpiod = devm_gpiod_get_optional(dev, "renesas,enable", GPIOD_IN);
 659        if (IS_ERR(gpiod))
 660                return PTR_ERR(gpiod);
 661
 662        /* FIXME */
 663        /* runtime power control ? */
 664        if (priv->pfunc->get_vbus)
 665                usbhs_get_dparam(priv, runtime_pwctrl) = 1;
 666
 667        /*
 668         * priv settings
 669         */
 670        priv->irq = irq;
 671        priv->pdev      = pdev;
 672        INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
 673        spin_lock_init(usbhs_priv_to_lock(priv));
 674
 675        /* call pipe and module init */
 676        ret = usbhs_pipe_probe(priv);
 677        if (ret < 0)
 678                return ret;
 679
 680        ret = usbhs_fifo_probe(priv);
 681        if (ret < 0)
 682                goto probe_end_pipe_exit;
 683
 684        ret = usbhs_mod_probe(priv);
 685        if (ret < 0)
 686                goto probe_end_fifo_exit;
 687
 688        /* dev_set_drvdata should be called after usbhs_mod_init */
 689        platform_set_drvdata(pdev, priv);
 690
 691        ret = reset_control_deassert(priv->rsts);
 692        if (ret)
 693                goto probe_fail_rst;
 694
 695        ret = usbhsc_clk_get(dev, priv);
 696        if (ret)
 697                goto probe_fail_clks;
 698
 699        /*
 700         * deviece reset here because
 701         * USB device might be used in boot loader.
 702         */
 703        usbhs_sys_clock_ctrl(priv, 0);
 704
 705        /* check GPIO determining if USB function should be enabled */
 706        if (gpiod) {
 707                ret = !gpiod_get_value(gpiod);
 708                if (ret) {
 709                        dev_warn(dev, "USB function not selected (GPIO)\n");
 710                        ret = -ENOTSUPP;
 711                        goto probe_end_mod_exit;
 712                }
 713        }
 714
 715        /*
 716         * platform call
 717         *
 718         * USB phy setup might depend on CPU/Board.
 719         * If platform has its callback functions,
 720         * call it here.
 721         */
 722        ret = usbhs_platform_call(priv, hardware_init, pdev);
 723        if (ret < 0) {
 724                dev_err(dev, "platform init failed.\n");
 725                goto probe_end_mod_exit;
 726        }
 727
 728        /* reset phy for connection */
 729        usbhs_platform_call(priv, phy_reset, pdev);
 730
 731        /* power control */
 732        pm_runtime_enable(dev);
 733        if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
 734                usbhsc_power_ctrl(priv, 1);
 735                usbhs_mod_autonomy_mode(priv);
 736        } else {
 737                usbhs_mod_non_autonomy_mode(priv);
 738        }
 739
 740        /*
 741         * manual call notify_hotplug for cold plug
 742         */
 743        usbhsc_schedule_notify_hotplug(pdev);
 744
 745        dev_info(dev, "probed\n");
 746
 747        return ret;
 748
 749probe_end_mod_exit:
 750        usbhsc_clk_put(priv);
 751probe_fail_clks:
 752        reset_control_assert(priv->rsts);
 753probe_fail_rst:
 754        usbhs_mod_remove(priv);
 755probe_end_fifo_exit:
 756        usbhs_fifo_remove(priv);
 757probe_end_pipe_exit:
 758        usbhs_pipe_remove(priv);
 759
 760        dev_info(dev, "probe failed (%d)\n", ret);
 761
 762        return ret;
 763}
 764
 765static int usbhs_remove(struct platform_device *pdev)
 766{
 767        struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
 768
 769        dev_dbg(&pdev->dev, "usb remove\n");
 770
 771        /* power off */
 772        if (!usbhs_get_dparam(priv, runtime_pwctrl))
 773                usbhsc_power_ctrl(priv, 0);
 774
 775        pm_runtime_disable(&pdev->dev);
 776
 777        usbhs_platform_call(priv, hardware_exit, pdev);
 778        usbhsc_clk_put(priv);
 779        reset_control_assert(priv->rsts);
 780        usbhs_mod_remove(priv);
 781        usbhs_fifo_remove(priv);
 782        usbhs_pipe_remove(priv);
 783
 784        return 0;
 785}
 786
 787static __maybe_unused int usbhsc_suspend(struct device *dev)
 788{
 789        struct usbhs_priv *priv = dev_get_drvdata(dev);
 790        struct usbhs_mod *mod = usbhs_mod_get_current(priv);
 791
 792        if (mod) {
 793                usbhs_mod_call(priv, stop, priv);
 794                usbhs_mod_change(priv, -1);
 795        }
 796
 797        if (mod || !usbhs_get_dparam(priv, runtime_pwctrl))
 798                usbhsc_power_ctrl(priv, 0);
 799
 800        return 0;
 801}
 802
 803static __maybe_unused int usbhsc_resume(struct device *dev)
 804{
 805        struct usbhs_priv *priv = dev_get_drvdata(dev);
 806        struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 807
 808        if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
 809                usbhsc_power_ctrl(priv, 1);
 810                usbhs_mod_autonomy_mode(priv);
 811        }
 812
 813        usbhs_platform_call(priv, phy_reset, pdev);
 814
 815        usbhsc_schedule_notify_hotplug(pdev);
 816
 817        return 0;
 818}
 819
 820static SIMPLE_DEV_PM_OPS(usbhsc_pm_ops, usbhsc_suspend, usbhsc_resume);
 821
 822static struct platform_driver renesas_usbhs_driver = {
 823        .driver         = {
 824                .name   = "renesas_usbhs",
 825                .pm     = &usbhsc_pm_ops,
 826                .of_match_table = of_match_ptr(usbhs_of_match),
 827        },
 828        .probe          = usbhs_probe,
 829        .remove         = usbhs_remove,
 830};
 831
 832module_platform_driver(renesas_usbhs_driver);
 833
 834MODULE_LICENSE("GPL");
 835MODULE_DESCRIPTION("Renesas USB driver");
 836MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 837