1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2012 Freescale Semiconductor, Inc. 4 * Copyright (C) 2012 Marek Vasut <marex@denx.de> 5 * on behalf of DENX Software Engineering GmbH 6 */ 7 8#include <linux/module.h> 9#include <linux/of_platform.h> 10#include <linux/platform_device.h> 11#include <linux/pm_runtime.h> 12#include <linux/usb/chipidea.h> 13#include <linux/usb/of.h> 14#include <linux/clk.h> 15#include <linux/pinctrl/consumer.h> 16#include <linux/pm_qos.h> 17 18#include "ci.h" 19#include "ci_hdrc_imx.h" 20 21struct ci_hdrc_imx_platform_flag { 22 unsigned int flags; 23}; 24 25static const struct ci_hdrc_imx_platform_flag imx23_usb_data = { 26 .flags = CI_HDRC_TURN_VBUS_EARLY_ON | 27 CI_HDRC_DISABLE_STREAMING, 28}; 29 30static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { 31 .flags = CI_HDRC_DISABLE_STREAMING, 32}; 33 34static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { 35 .flags = CI_HDRC_IMX28_WRITE_FIX | 36 CI_HDRC_TURN_VBUS_EARLY_ON | 37 CI_HDRC_DISABLE_STREAMING, 38}; 39 40static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = { 41 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 42 CI_HDRC_TURN_VBUS_EARLY_ON | 43 CI_HDRC_DISABLE_STREAMING, 44}; 45 46static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = { 47 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 48 CI_HDRC_TURN_VBUS_EARLY_ON | 49 CI_HDRC_DISABLE_HOST_STREAMING, 50}; 51 52static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = { 53 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 54 CI_HDRC_TURN_VBUS_EARLY_ON | 55 CI_HDRC_DISABLE_HOST_STREAMING, 56}; 57 58static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = { 59 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 60 CI_HDRC_TURN_VBUS_EARLY_ON | 61 CI_HDRC_DISABLE_DEVICE_STREAMING, 62}; 63 64static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = { 65 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, 66}; 67 68static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = { 69 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | 70 CI_HDRC_PMQOS, 71}; 72 73static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { 74 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, 75}; 76 77static const struct of_device_id ci_hdrc_imx_dt_ids[] = { 78 { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, 79 { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, 80 { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data}, 81 { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data}, 82 { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data}, 83 { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data}, 84 { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data}, 85 { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, 86 { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data}, 87 { .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data}, 88 { /* sentinel */ } 89}; 90MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); 91 92struct ci_hdrc_imx_data { 93 struct usb_phy *phy; 94 struct platform_device *ci_pdev; 95 struct clk *clk; 96 struct imx_usbmisc_data *usbmisc_data; 97 bool supports_runtime_pm; 98 bool override_phy_control; 99 bool in_lpm; 100 struct pinctrl *pinctrl; 101 struct pinctrl_state *pinctrl_hsic_active; 102 struct regulator *hsic_pad_regulator; 103 /* SoC before i.mx6 (except imx23/imx28) needs three clks */ 104 bool need_three_clks; 105 struct clk *clk_ipg; 106 struct clk *clk_ahb; 107 struct clk *clk_per; 108 /* --------------------------------- */ 109 struct pm_qos_request pm_qos_req; 110 const struct ci_hdrc_imx_platform_flag *plat_data; 111}; 112 113/* Common functions shared by usbmisc drivers */ 114 115static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) 116{ 117 struct platform_device *misc_pdev; 118 struct device_node *np = dev->of_node; 119 struct of_phandle_args args; 120 struct imx_usbmisc_data *data; 121 int ret; 122 123 /* 124 * In case the fsl,usbmisc property is not present this device doesn't 125 * need usbmisc. Return NULL (which is no error here) 126 */ 127 if (!of_get_property(np, "fsl,usbmisc", NULL)) 128 return NULL; 129 130 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 131 if (!data) 132 return ERR_PTR(-ENOMEM); 133 134 ret = of_parse_phandle_with_args(np, "fsl,usbmisc", "#index-cells", 135 0, &args); 136 if (ret) { 137 dev_err(dev, "Failed to parse property fsl,usbmisc, errno %d\n", 138 ret); 139 return ERR_PTR(ret); 140 } 141 142 data->index = args.args[0]; 143 144 misc_pdev = of_find_device_by_node(args.np); 145 of_node_put(args.np); 146 147 if (!misc_pdev) 148 return ERR_PTR(-EPROBE_DEFER); 149 150 if (!platform_get_drvdata(misc_pdev)) { 151 put_device(&misc_pdev->dev); 152 return ERR_PTR(-EPROBE_DEFER); 153 } 154 data->dev = &misc_pdev->dev; 155 156 /* 157 * Check the various over current related properties. If over current 158 * detection is disabled we're not interested in the polarity. 159 */ 160 if (of_find_property(np, "disable-over-current", NULL)) { 161 data->disable_oc = 1; 162 } else if (of_find_property(np, "over-current-active-high", NULL)) { 163 data->oc_pol_active_low = 0; 164 data->oc_pol_configured = 1; 165 } else if (of_find_property(np, "over-current-active-low", NULL)) { 166 data->oc_pol_active_low = 1; 167 data->oc_pol_configured = 1; 168 } else { 169 dev_warn(dev, "No over current polarity defined\n"); 170 } 171 172 data->pwr_pol = of_property_read_bool(np, "power-active-high"); 173 data->evdo = of_property_read_bool(np, "external-vbus-divider"); 174 175 if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) 176 data->ulpi = 1; 177 178 if (of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control", 179 &data->emp_curr_control)) 180 data->emp_curr_control = -1; 181 if (of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust", 182 &data->dc_vol_level_adjust)) 183 data->dc_vol_level_adjust = -1; 184 185 return data; 186} 187 188/* End of common functions shared by usbmisc drivers*/ 189static int imx_get_clks(struct device *dev) 190{ 191 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 192 int ret = 0; 193 194 data->clk_ipg = devm_clk_get(dev, "ipg"); 195 if (IS_ERR(data->clk_ipg)) { 196 /* If the platform only needs one clocks */ 197 data->clk = devm_clk_get(dev, NULL); 198 if (IS_ERR(data->clk)) { 199 ret = PTR_ERR(data->clk); 200 dev_err(dev, 201 "Failed to get clks, err=%ld,%ld\n", 202 PTR_ERR(data->clk), PTR_ERR(data->clk_ipg)); 203 return ret; 204 } 205 return ret; 206 } 207 208 data->clk_ahb = devm_clk_get(dev, "ahb"); 209 if (IS_ERR(data->clk_ahb)) { 210 ret = PTR_ERR(data->clk_ahb); 211 dev_err(dev, 212 "Failed to get ahb clock, err=%d\n", ret); 213 return ret; 214 } 215 216 data->clk_per = devm_clk_get(dev, "per"); 217 if (IS_ERR(data->clk_per)) { 218 ret = PTR_ERR(data->clk_per); 219 dev_err(dev, 220 "Failed to get per clock, err=%d\n", ret); 221 return ret; 222 } 223 224 data->need_three_clks = true; 225 return ret; 226} 227 228static int imx_prepare_enable_clks(struct device *dev) 229{ 230 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 231 int ret = 0; 232 233 if (data->need_three_clks) { 234 ret = clk_prepare_enable(data->clk_ipg); 235 if (ret) { 236 dev_err(dev, 237 "Failed to prepare/enable ipg clk, err=%d\n", 238 ret); 239 return ret; 240 } 241 242 ret = clk_prepare_enable(data->clk_ahb); 243 if (ret) { 244 dev_err(dev, 245 "Failed to prepare/enable ahb clk, err=%d\n", 246 ret); 247 clk_disable_unprepare(data->clk_ipg); 248 return ret; 249 } 250 251 ret = clk_prepare_enable(data->clk_per); 252 if (ret) { 253 dev_err(dev, 254 "Failed to prepare/enable per clk, err=%d\n", 255 ret); 256 clk_disable_unprepare(data->clk_ahb); 257 clk_disable_unprepare(data->clk_ipg); 258 return ret; 259 } 260 } else { 261 ret = clk_prepare_enable(data->clk); 262 if (ret) { 263 dev_err(dev, 264 "Failed to prepare/enable clk, err=%d\n", 265 ret); 266 return ret; 267 } 268 } 269 270 return ret; 271} 272 273static void imx_disable_unprepare_clks(struct device *dev) 274{ 275 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 276 277 if (data->need_three_clks) { 278 clk_disable_unprepare(data->clk_per); 279 clk_disable_unprepare(data->clk_ahb); 280 clk_disable_unprepare(data->clk_ipg); 281 } else { 282 clk_disable_unprepare(data->clk); 283 } 284} 285 286static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event) 287{ 288 struct device *dev = ci->dev->parent; 289 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 290 int ret = 0; 291 struct imx_usbmisc_data *mdata = data->usbmisc_data; 292 293 switch (event) { 294 case CI_HDRC_IMX_HSIC_ACTIVE_EVENT: 295 if (data->pinctrl) { 296 ret = pinctrl_select_state(data->pinctrl, 297 data->pinctrl_hsic_active); 298 if (ret) 299 dev_err(dev, 300 "hsic_active select failed, err=%d\n", 301 ret); 302 } 303 break; 304 case CI_HDRC_IMX_HSIC_SUSPEND_EVENT: 305 ret = imx_usbmisc_hsic_set_connect(mdata); 306 if (ret) 307 dev_err(dev, 308 "hsic_set_connect failed, err=%d\n", ret); 309 break; 310 case CI_HDRC_CONTROLLER_VBUS_EVENT: 311 if (ci->vbus_active) 312 ret = imx_usbmisc_charger_detection(mdata, true); 313 else 314 ret = imx_usbmisc_charger_detection(mdata, false); 315 if (ci->usb_phy) 316 schedule_work(&ci->usb_phy->chg_work); 317 break; 318 default: 319 break; 320 } 321 322 return ret; 323} 324 325static int ci_hdrc_imx_probe(struct platform_device *pdev) 326{ 327 struct ci_hdrc_imx_data *data; 328 struct ci_hdrc_platform_data pdata = { 329 .name = dev_name(&pdev->dev), 330 .capoffset = DEF_CAPOFFSET, 331 .notify_event = ci_hdrc_imx_notify_event, 332 }; 333 int ret; 334 const struct of_device_id *of_id; 335 const struct ci_hdrc_imx_platform_flag *imx_platform_flag; 336 struct device_node *np = pdev->dev.of_node; 337 struct device *dev = &pdev->dev; 338 339 of_id = of_match_device(ci_hdrc_imx_dt_ids, dev); 340 if (!of_id) 341 return -ENODEV; 342 343 imx_platform_flag = of_id->data; 344 345 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 346 if (!data) 347 return -ENOMEM; 348 349 data->plat_data = imx_platform_flag; 350 pdata.flags |= imx_platform_flag->flags; 351 platform_set_drvdata(pdev, data); 352 data->usbmisc_data = usbmisc_get_init_data(dev); 353 if (IS_ERR(data->usbmisc_data)) 354 return PTR_ERR(data->usbmisc_data); 355 356 if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC) 357 && data->usbmisc_data) { 358 pdata.flags |= CI_HDRC_IMX_IS_HSIC; 359 data->usbmisc_data->hsic = 1; 360 data->pinctrl = devm_pinctrl_get(dev); 361 if (PTR_ERR(data->pinctrl) == -ENODEV) 362 data->pinctrl = NULL; 363 else if (IS_ERR(data->pinctrl)) { 364 if (PTR_ERR(data->pinctrl) != -EPROBE_DEFER) 365 dev_err(dev, "pinctrl get failed, err=%ld\n", 366 PTR_ERR(data->pinctrl)); 367 return PTR_ERR(data->pinctrl); 368 } 369 370 data->hsic_pad_regulator = 371 devm_regulator_get_optional(dev, "hsic"); 372 if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { 373 /* no pad regualator is needed */ 374 data->hsic_pad_regulator = NULL; 375 } else if (IS_ERR(data->hsic_pad_regulator)) { 376 if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER) 377 dev_err(dev, 378 "Get HSIC pad regulator error: %ld\n", 379 PTR_ERR(data->hsic_pad_regulator)); 380 return PTR_ERR(data->hsic_pad_regulator); 381 } 382 383 if (data->hsic_pad_regulator) { 384 ret = regulator_enable(data->hsic_pad_regulator); 385 if (ret) { 386 dev_err(dev, 387 "Failed to enable HSIC pad regulator\n"); 388 return ret; 389 } 390 } 391 } 392 393 /* HSIC pinctrl handling */ 394 if (data->pinctrl) { 395 struct pinctrl_state *pinctrl_hsic_idle; 396 397 pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle"); 398 if (IS_ERR(pinctrl_hsic_idle)) { 399 dev_err(dev, 400 "pinctrl_hsic_idle lookup failed, err=%ld\n", 401 PTR_ERR(pinctrl_hsic_idle)); 402 return PTR_ERR(pinctrl_hsic_idle); 403 } 404 405 ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle); 406 if (ret) { 407 dev_err(dev, "hsic_idle select failed, err=%d\n", ret); 408 return ret; 409 } 410 411 data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl, 412 "active"); 413 if (IS_ERR(data->pinctrl_hsic_active)) { 414 dev_err(dev, 415 "pinctrl_hsic_active lookup failed, err=%ld\n", 416 PTR_ERR(data->pinctrl_hsic_active)); 417 return PTR_ERR(data->pinctrl_hsic_active); 418 } 419 } 420 421 if (pdata.flags & CI_HDRC_PMQOS) 422 cpu_latency_qos_add_request(&data->pm_qos_req, 0); 423 424 ret = imx_get_clks(dev); 425 if (ret) 426 goto disable_hsic_regulator; 427 428 ret = imx_prepare_enable_clks(dev); 429 if (ret) 430 goto disable_hsic_regulator; 431 432 data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0); 433 if (IS_ERR(data->phy)) { 434 ret = PTR_ERR(data->phy); 435 if (ret != -ENODEV) 436 goto err_clk; 437 data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0); 438 if (IS_ERR(data->phy)) { 439 ret = PTR_ERR(data->phy); 440 if (ret == -ENODEV) 441 data->phy = NULL; 442 else 443 goto err_clk; 444 } 445 } 446 447 pdata.usb_phy = data->phy; 448 if (data->usbmisc_data) 449 data->usbmisc_data->usb_phy = data->phy; 450 451 if ((of_device_is_compatible(np, "fsl,imx53-usb") || 452 of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy && 453 of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) { 454 pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL; 455 data->override_phy_control = true; 456 usb_phy_init(pdata.usb_phy); 457 } 458 459 if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM) 460 data->supports_runtime_pm = true; 461 462 ret = imx_usbmisc_init(data->usbmisc_data); 463 if (ret) { 464 dev_err(dev, "usbmisc init failed, ret=%d\n", ret); 465 goto err_clk; 466 } 467 468 data->ci_pdev = ci_hdrc_add_device(dev, 469 pdev->resource, pdev->num_resources, 470 &pdata); 471 if (IS_ERR(data->ci_pdev)) { 472 ret = PTR_ERR(data->ci_pdev); 473 if (ret != -EPROBE_DEFER) 474 dev_err(dev, "ci_hdrc_add_device failed, err=%d\n", 475 ret); 476 goto err_clk; 477 } 478 479 if (data->usbmisc_data) { 480 if (!IS_ERR(pdata.id_extcon.edev) || 481 of_property_read_bool(np, "usb-role-switch")) 482 data->usbmisc_data->ext_id = 1; 483 484 if (!IS_ERR(pdata.vbus_extcon.edev) || 485 of_property_read_bool(np, "usb-role-switch")) 486 data->usbmisc_data->ext_vbus = 1; 487 488 /* usbmisc needs to know dr mode to choose wakeup setting */ 489 data->usbmisc_data->available_role = 490 ci_hdrc_query_available_role(data->ci_pdev); 491 } 492 493 ret = imx_usbmisc_init_post(data->usbmisc_data); 494 if (ret) { 495 dev_err(dev, "usbmisc post failed, ret=%d\n", ret); 496 goto disable_device; 497 } 498 499 if (data->supports_runtime_pm) { 500 pm_runtime_set_active(dev); 501 pm_runtime_enable(dev); 502 } 503 504 device_set_wakeup_capable(dev, true); 505 506 return 0; 507 508disable_device: 509 ci_hdrc_remove_device(data->ci_pdev); 510err_clk: 511 imx_disable_unprepare_clks(dev); 512disable_hsic_regulator: 513 if (data->hsic_pad_regulator) 514 /* don't overwrite original ret (cf. EPROBE_DEFER) */ 515 regulator_disable(data->hsic_pad_regulator); 516 if (pdata.flags & CI_HDRC_PMQOS) 517 cpu_latency_qos_remove_request(&data->pm_qos_req); 518 data->ci_pdev = NULL; 519 return ret; 520} 521 522static int ci_hdrc_imx_remove(struct platform_device *pdev) 523{ 524 struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev); 525 526 if (data->supports_runtime_pm) { 527 pm_runtime_get_sync(&pdev->dev); 528 pm_runtime_disable(&pdev->dev); 529 pm_runtime_put_noidle(&pdev->dev); 530 } 531 if (data->ci_pdev) 532 ci_hdrc_remove_device(data->ci_pdev); 533 if (data->override_phy_control) 534 usb_phy_shutdown(data->phy); 535 if (data->ci_pdev) { 536 imx_disable_unprepare_clks(&pdev->dev); 537 if (data->plat_data->flags & CI_HDRC_PMQOS) 538 cpu_latency_qos_remove_request(&data->pm_qos_req); 539 if (data->hsic_pad_regulator) 540 regulator_disable(data->hsic_pad_regulator); 541 } 542 543 return 0; 544} 545 546static void ci_hdrc_imx_shutdown(struct platform_device *pdev) 547{ 548 ci_hdrc_imx_remove(pdev); 549} 550 551static int __maybe_unused imx_controller_suspend(struct device *dev) 552{ 553 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 554 int ret = 0; 555 556 dev_dbg(dev, "at %s\n", __func__); 557 558 ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false); 559 if (ret) { 560 dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret); 561 return ret; 562 } 563 564 imx_disable_unprepare_clks(dev); 565 if (data->plat_data->flags & CI_HDRC_PMQOS) 566 cpu_latency_qos_remove_request(&data->pm_qos_req); 567 568 data->in_lpm = true; 569 570 return 0; 571} 572 573static int __maybe_unused imx_controller_resume(struct device *dev) 574{ 575 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 576 int ret = 0; 577 578 dev_dbg(dev, "at %s\n", __func__); 579 580 if (!data->in_lpm) { 581 WARN_ON(1); 582 return 0; 583 } 584 585 if (data->plat_data->flags & CI_HDRC_PMQOS) 586 cpu_latency_qos_add_request(&data->pm_qos_req, 0); 587 588 ret = imx_prepare_enable_clks(dev); 589 if (ret) 590 return ret; 591 592 data->in_lpm = false; 593 594 ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false); 595 if (ret) { 596 dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret); 597 goto clk_disable; 598 } 599 600 ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true); 601 if (ret) { 602 dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret); 603 goto hsic_set_clk_fail; 604 } 605 606 return 0; 607 608hsic_set_clk_fail: 609 imx_usbmisc_set_wakeup(data->usbmisc_data, true); 610clk_disable: 611 imx_disable_unprepare_clks(dev); 612 return ret; 613} 614 615static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev) 616{ 617 int ret; 618 619 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 620 621 if (data->in_lpm) 622 /* The core's suspend doesn't run */ 623 return 0; 624 625 if (device_may_wakeup(dev)) { 626 ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true); 627 if (ret) { 628 dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", 629 ret); 630 return ret; 631 } 632 } 633 634 ret = imx_controller_suspend(dev); 635 if (ret) 636 return ret; 637 638 pinctrl_pm_select_sleep_state(dev); 639 return ret; 640} 641 642static int __maybe_unused ci_hdrc_imx_resume(struct device *dev) 643{ 644 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 645 int ret; 646 647 pinctrl_pm_select_default_state(dev); 648 ret = imx_controller_resume(dev); 649 if (!ret && data->supports_runtime_pm) { 650 pm_runtime_disable(dev); 651 pm_runtime_set_active(dev); 652 pm_runtime_enable(dev); 653 } 654 655 return ret; 656} 657 658static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev) 659{ 660 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 661 int ret; 662 663 if (data->in_lpm) { 664 WARN_ON(1); 665 return 0; 666 } 667 668 ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true); 669 if (ret) { 670 dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret); 671 return ret; 672 } 673 674 return imx_controller_suspend(dev); 675} 676 677static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev) 678{ 679 return imx_controller_resume(dev); 680} 681 682static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { 683 SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume) 684 SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend, 685 ci_hdrc_imx_runtime_resume, NULL) 686}; 687static struct platform_driver ci_hdrc_imx_driver = { 688 .probe = ci_hdrc_imx_probe, 689 .remove = ci_hdrc_imx_remove, 690 .shutdown = ci_hdrc_imx_shutdown, 691 .driver = { 692 .name = "imx_usb", 693 .of_match_table = ci_hdrc_imx_dt_ids, 694 .pm = &ci_hdrc_imx_pm_ops, 695 }, 696}; 697 698module_platform_driver(ci_hdrc_imx_driver); 699 700MODULE_ALIAS("platform:imx-usb"); 701MODULE_LICENSE("GPL"); 702MODULE_DESCRIPTION("CI HDRC i.MX USB binding"); 703MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); 704MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>"); 705