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