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 resource *irq_res;
 593        struct device *dev = &pdev->dev;
 594        struct gpio_desc *gpiod;
 595        int ret;
 596        u32 tmp;
 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_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 612        if (!irq_res) {
 613                dev_err(dev, "Not enough Renesas USB platform resources.\n");
 614                return -ENODEV;
 615        }
 616
 617        /* usb private data */
 618        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 619        if (!priv)
 620                return -ENOMEM;
 621
 622        priv->base = devm_platform_ioremap_resource(pdev, 0);
 623        if (IS_ERR(priv->base))
 624                return PTR_ERR(priv->base);
 625
 626        if (of_property_read_bool(dev_of_node(dev), "extcon")) {
 627                priv->edev = extcon_get_edev_by_phandle(dev, 0);
 628                if (IS_ERR(priv->edev))
 629                        return PTR_ERR(priv->edev);
 630        }
 631
 632        priv->rsts = devm_reset_control_array_get_optional_shared(dev);
 633        if (IS_ERR(priv->rsts))
 634                return PTR_ERR(priv->rsts);
 635
 636        /*
 637         * care platform info
 638         */
 639
 640        priv->dparam = info->driver_param;
 641
 642        if (!info->platform_callback.get_id) {
 643                dev_err(dev, "no platform callbacks\n");
 644                return -EINVAL;
 645        }
 646        priv->pfunc = &info->platform_callback;
 647
 648        /* set default param if platform doesn't have */
 649        if (usbhs_get_dparam(priv, has_new_pipe_configs)) {
 650                priv->dparam.pipe_configs = usbhsc_new_pipe;
 651                priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
 652        } else if (!priv->dparam.pipe_configs) {
 653                priv->dparam.pipe_configs = usbhsc_default_pipe;
 654                priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe);
 655        }
 656        if (!priv->dparam.pio_dma_border)
 657                priv->dparam.pio_dma_border = 64; /* 64byte */
 658        if (!of_property_read_u32(dev_of_node(dev), "renesas,buswait", &tmp))
 659                priv->dparam.buswait_bwait = tmp;
 660        gpiod = devm_gpiod_get_optional(dev, "renesas,enable", GPIOD_IN);
 661        if (IS_ERR(gpiod))
 662                return PTR_ERR(gpiod);
 663
 664        /* FIXME */
 665        /* runtime power control ? */
 666        if (priv->pfunc->get_vbus)
 667                usbhs_get_dparam(priv, runtime_pwctrl) = 1;
 668
 669        /*
 670         * priv settings
 671         */
 672        priv->irq       = irq_res->start;
 673        if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE)
 674                priv->irqflags = IRQF_SHARED;
 675        priv->pdev      = pdev;
 676        INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
 677        spin_lock_init(usbhs_priv_to_lock(priv));
 678
 679        /* call pipe and module init */
 680        ret = usbhs_pipe_probe(priv);
 681        if (ret < 0)
 682                return ret;
 683
 684        ret = usbhs_fifo_probe(priv);
 685        if (ret < 0)
 686                goto probe_end_pipe_exit;
 687
 688        ret = usbhs_mod_probe(priv);
 689        if (ret < 0)
 690                goto probe_end_fifo_exit;
 691
 692        /* dev_set_drvdata should be called after usbhs_mod_init */
 693        platform_set_drvdata(pdev, priv);
 694
 695        ret = reset_control_deassert(priv->rsts);
 696        if (ret)
 697                goto probe_fail_rst;
 698
 699        ret = usbhsc_clk_get(dev, priv);
 700        if (ret)
 701                goto probe_fail_clks;
 702
 703        /*
 704         * deviece reset here because
 705         * USB device might be used in boot loader.
 706         */
 707        usbhs_sys_clock_ctrl(priv, 0);
 708
 709        /* check GPIO determining if USB function should be enabled */
 710        if (gpiod) {
 711                ret = !gpiod_get_value(gpiod);
 712                if (ret) {
 713                        dev_warn(dev, "USB function not selected (GPIO)\n");
 714                        ret = -ENOTSUPP;
 715                        goto probe_end_mod_exit;
 716                }
 717        }
 718
 719        /*
 720         * platform call
 721         *
 722         * USB phy setup might depend on CPU/Board.
 723         * If platform has its callback functions,
 724         * call it here.
 725         */
 726        ret = usbhs_platform_call(priv, hardware_init, pdev);
 727        if (ret < 0) {
 728                dev_err(dev, "platform init failed.\n");
 729                goto probe_end_mod_exit;
 730        }
 731
 732        /* reset phy for connection */
 733        usbhs_platform_call(priv, phy_reset, pdev);
 734
 735        /* power control */
 736        pm_runtime_enable(dev);
 737        if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
 738                usbhsc_power_ctrl(priv, 1);
 739                usbhs_mod_autonomy_mode(priv);
 740        } else {
 741                usbhs_mod_non_autonomy_mode(priv);
 742        }
 743
 744        /*
 745         * manual call notify_hotplug for cold plug
 746         */
 747        usbhsc_schedule_notify_hotplug(pdev);
 748
 749        dev_info(dev, "probed\n");
 750
 751        return ret;
 752
 753probe_end_mod_exit:
 754        usbhsc_clk_put(priv);
 755probe_fail_clks:
 756        reset_control_assert(priv->rsts);
 757probe_fail_rst:
 758        usbhs_mod_remove(priv);
 759probe_end_fifo_exit:
 760        usbhs_fifo_remove(priv);
 761probe_end_pipe_exit:
 762        usbhs_pipe_remove(priv);
 763
 764        dev_info(dev, "probe failed (%d)\n", ret);
 765
 766        return ret;
 767}
 768
 769static int usbhs_remove(struct platform_device *pdev)
 770{
 771        struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
 772
 773        dev_dbg(&pdev->dev, "usb remove\n");
 774
 775        /* power off */
 776        if (!usbhs_get_dparam(priv, runtime_pwctrl))
 777                usbhsc_power_ctrl(priv, 0);
 778
 779        pm_runtime_disable(&pdev->dev);
 780
 781        usbhs_platform_call(priv, hardware_exit, pdev);
 782        usbhsc_clk_put(priv);
 783        reset_control_assert(priv->rsts);
 784        usbhs_mod_remove(priv);
 785        usbhs_fifo_remove(priv);
 786        usbhs_pipe_remove(priv);
 787
 788        return 0;
 789}
 790
 791static __maybe_unused int usbhsc_suspend(struct device *dev)
 792{
 793        struct usbhs_priv *priv = dev_get_drvdata(dev);
 794        struct usbhs_mod *mod = usbhs_mod_get_current(priv);
 795
 796        if (mod) {
 797                usbhs_mod_call(priv, stop, priv);
 798                usbhs_mod_change(priv, -1);
 799        }
 800
 801        if (mod || !usbhs_get_dparam(priv, runtime_pwctrl))
 802                usbhsc_power_ctrl(priv, 0);
 803
 804        return 0;
 805}
 806
 807static __maybe_unused int usbhsc_resume(struct device *dev)
 808{
 809        struct usbhs_priv *priv = dev_get_drvdata(dev);
 810        struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 811
 812        if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
 813                usbhsc_power_ctrl(priv, 1);
 814                usbhs_mod_autonomy_mode(priv);
 815        }
 816
 817        usbhs_platform_call(priv, phy_reset, pdev);
 818
 819        usbhsc_schedule_notify_hotplug(pdev);
 820
 821        return 0;
 822}
 823
 824static SIMPLE_DEV_PM_OPS(usbhsc_pm_ops, usbhsc_suspend, usbhsc_resume);
 825
 826static struct platform_driver renesas_usbhs_driver = {
 827        .driver         = {
 828                .name   = "renesas_usbhs",
 829                .pm     = &usbhsc_pm_ops,
 830                .of_match_table = of_match_ptr(usbhs_of_match),
 831        },
 832        .probe          = usbhs_probe,
 833        .remove         = usbhs_remove,
 834};
 835
 836module_platform_driver(renesas_usbhs_driver);
 837
 838MODULE_LICENSE("GPL");
 839MODULE_DESCRIPTION("Renesas USB driver");
 840MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 841