1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ 3 4 #include <linux/err.h> 5 #include <linux/init.h> 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/mutex.h> 9 #include <linux/pm_domain.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_opp.h> 13 #include <linux/soc/qcom/smd-rpm.h> 14 15 #include <dt-bindings/power/qcom-rpmpd.h> 16 17 #define domain_to_rpmpd(domain) container_of(domain, struct rpmpd, pd) 18 19 static struct qcom_smd_rpm *rpmpd_smd_rpm; 20 21 /* Resource types: 22 * RPMPD_X is X encoded as a little-endian, lower-case, ASCII string */ 23 #define RPMPD_SMPA 0x61706d73 24 #define RPMPD_LDOA 0x616f646c 25 #define RPMPD_SMPB 0x62706d73 26 #define RPMPD_LDOB 0x626f646c 27 #define RPMPD_RWCX 0x78637772 28 #define RPMPD_RWMX 0x786d7772 29 #define RPMPD_RWLC 0x636c7772 30 #define RPMPD_RWLM 0x6d6c7772 31 #define RPMPD_RWSC 0x63737772 32 #define RPMPD_RWSM 0x6d737772 33 #define RPMPD_RWGX 0x78677772 34 35 /* Operation Keys */ 36 #define KEY_CORNER 0x6e726f63 /* corn */ 37 #define KEY_ENABLE 0x6e657773 /* swen */ 38 #define KEY_FLOOR_CORNER 0x636676 /* vfc */ 39 #define KEY_FLOOR_LEVEL 0x6c6676 /* vfl */ 40 #define KEY_LEVEL 0x6c766c76 /* vlvl */ 41 42 #define MAX_CORNER_RPMPD_STATE 6 43 44 struct rpmpd_req { 45 __le32 key; 46 __le32 nbytes; 47 __le32 value; 48 }; 49 50 struct rpmpd { 51 struct generic_pm_domain pd; 52 struct generic_pm_domain *parent; 53 struct rpmpd *peer; 54 const bool active_only; 55 unsigned int corner; 56 bool enabled; 57 const int res_type; 58 const int res_id; 59 unsigned int max_state; 60 __le32 key; 61 bool state_synced; 62 }; 63 64 struct rpmpd_desc { 65 struct rpmpd **rpmpds; 66 size_t num_pds; 67 unsigned int max_state; 68 }; 69 70 static DEFINE_MUTEX(rpmpd_lock); 71 72 /* CX */ 73 static struct rpmpd cx_rwcx0_lvl_ao; 74 static struct rpmpd cx_rwcx0_lvl = { 75 .pd = { .name = "cx", }, 76 .peer = &cx_rwcx0_lvl_ao, 77 .res_type = RPMPD_RWCX, 78 .res_id = 0, 79 .key = KEY_LEVEL, 80 }; 81 82 static struct rpmpd cx_rwcx0_lvl_ao = { 83 .pd = { .name = "cx_ao", }, 84 .peer = &cx_rwcx0_lvl, 85 .active_only = true, 86 .res_type = RPMPD_RWCX, 87 .res_id = 0, 88 .key = KEY_LEVEL, 89 }; 90 91 static struct rpmpd cx_s1a_corner_ao; 92 static struct rpmpd cx_s1a_corner = { 93 .pd = { .name = "cx", }, 94 .peer = &cx_s1a_corner_ao, 95 .res_type = RPMPD_SMPA, 96 .res_id = 1, 97 .key = KEY_CORNER, 98 }; 99 100 static struct rpmpd cx_s1a_corner_ao = { 101 .pd = { .name = "cx_ao", }, 102 .peer = &cx_s1a_corner, 103 .active_only = true, 104 .res_type = RPMPD_SMPA, 105 .res_id = 1, 106 .key = KEY_CORNER, 107 }; 108 109 static struct rpmpd cx_s1a_lvl_ao; 110 static struct rpmpd cx_s1a_lvl = { 111 .pd = { .name = "cx", }, 112 .peer = &cx_s1a_lvl_ao, 113 .res_type = RPMPD_SMPA, 114 .res_id = 1, 115 .key = KEY_LEVEL, 116 }; 117 118 static struct rpmpd cx_s1a_lvl_ao = { 119 .pd = { .name = "cx_ao", }, 120 .peer = &cx_s1a_lvl, 121 .active_only = true, 122 .res_type = RPMPD_SMPA, 123 .res_id = 1, 124 .key = KEY_LEVEL, 125 }; 126 127 static struct rpmpd cx_s2a_corner_ao; 128 static struct rpmpd cx_s2a_corner = { 129 .pd = { .name = "cx", }, 130 .peer = &cx_s2a_corner_ao, 131 .res_type = RPMPD_SMPA, 132 .res_id = 2, 133 .key = KEY_CORNER, 134 }; 135 136 static struct rpmpd cx_s2a_corner_ao = { 137 .pd = { .name = "cx_ao", }, 138 .peer = &cx_s2a_corner, 139 .active_only = true, 140 .res_type = RPMPD_SMPA, 141 .res_id = 2, 142 .key = KEY_CORNER, 143 }; 144 145 static struct rpmpd cx_s2a_lvl_ao; 146 static struct rpmpd cx_s2a_lvl = { 147 .pd = { .name = "cx", }, 148 .peer = &cx_s2a_lvl_ao, 149 .res_type = RPMPD_SMPA, 150 .res_id = 2, 151 .key = KEY_LEVEL, 152 }; 153 154 static struct rpmpd cx_s2a_lvl_ao = { 155 .pd = { .name = "cx_ao", }, 156 .peer = &cx_s2a_lvl, 157 .active_only = true, 158 .res_type = RPMPD_SMPA, 159 .res_id = 2, 160 .key = KEY_LEVEL, 161 }; 162 163 static struct rpmpd cx_s3a_lvl_ao; 164 static struct rpmpd cx_s3a_lvl = { 165 .pd = { .name = "cx", }, 166 .peer = &cx_s3a_lvl_ao, 167 .res_type = RPMPD_SMPA, 168 .res_id = 3, 169 .key = KEY_LEVEL, 170 }; 171 172 static struct rpmpd cx_s3a_lvl_ao = { 173 .pd = { .name = "cx_ao", }, 174 .peer = &cx_s3a_lvl, 175 .active_only = true, 176 .res_type = RPMPD_SMPA, 177 .res_id = 3, 178 .key = KEY_LEVEL, 179 }; 180 181 static struct rpmpd cx_rwcx0_vfl = { 182 .pd = { .name = "cx_vfl", }, 183 .res_type = RPMPD_RWCX, 184 .res_id = 0, 185 .key = KEY_FLOOR_LEVEL, 186 }; 187 188 static struct rpmpd cx_rwsc2_vfl = { 189 .pd = { .name = "cx_vfl", }, 190 .res_type = RPMPD_RWSC, 191 .res_id = 2, 192 .key = KEY_FLOOR_LEVEL, 193 }; 194 195 static struct rpmpd cx_s1a_vfc = { 196 .pd = { .name = "cx_vfc", }, 197 .res_type = RPMPD_SMPA, 198 .res_id = 1, 199 .key = KEY_FLOOR_CORNER, 200 }; 201 202 static struct rpmpd cx_s1a_vfl = { 203 .pd = { .name = "cx_vfl", }, 204 .res_type = RPMPD_SMPA, 205 .res_id = 1, 206 .key = KEY_FLOOR_LEVEL, 207 }; 208 209 static struct rpmpd cx_s2a_vfc = { 210 .pd = { .name = "cx_vfc", }, 211 .res_type = RPMPD_SMPA, 212 .res_id = 2, 213 .key = KEY_FLOOR_CORNER, 214 }; 215 216 static struct rpmpd cx_s2a_vfl = { 217 .pd = { .name = "cx_vfl", }, 218 .res_type = RPMPD_SMPA, 219 .res_id = 2, 220 .key = KEY_FLOOR_LEVEL, 221 }; 222 223 static struct rpmpd cx_s3a_vfl = { 224 .pd = { .name = "cx_vfl", }, 225 .res_type = RPMPD_SMPA, 226 .res_id = 3, 227 .key = KEY_FLOOR_LEVEL, 228 }; 229 230 static struct rpmpd cx_s2b_corner_ao; 231 static struct rpmpd cx_s2b_corner = { 232 .pd = { .name = "cx", }, 233 .peer = &cx_s2b_corner_ao, 234 .res_type = RPMPD_SMPB, 235 .res_id = 2, 236 .key = KEY_CORNER, 237 }; 238 239 static struct rpmpd cx_s2b_corner_ao = { 240 .pd = { .name = "cx_ao", }, 241 .peer = &cx_s2b_corner, 242 .active_only = true, 243 .res_type = RPMPD_SMPB, 244 .res_id = 2, 245 .key = KEY_CORNER, 246 }; 247 248 static struct rpmpd cx_s2b_vfc = { 249 .pd = { .name = "cx_vfc", }, 250 .res_type = RPMPD_SMPB, 251 .res_id = 2, 252 .key = KEY_FLOOR_CORNER, 253 }; 254 255 /* G(F)X */ 256 static struct rpmpd gfx_s7a_corner = { 257 .pd = { .name = "gfx", }, 258 .res_type = RPMPD_SMPA, 259 .res_id = 7, 260 .key = KEY_CORNER, 261 }; 262 263 static struct rpmpd gfx_s7a_vfc = { 264 .pd = { .name = "gfx_vfc", }, 265 .res_type = RPMPD_SMPA, 266 .res_id = 7, 267 .key = KEY_FLOOR_CORNER, 268 }; 269 270 static struct rpmpd gfx_s2b_corner = { 271 .pd = { .name = "gfx", }, 272 .res_type = RPMPD_SMPB, 273 .res_id = 2, 274 .key = KEY_CORNER, 275 }; 276 277 static struct rpmpd gfx_s2b_vfc = { 278 .pd = { .name = "gfx_vfc", }, 279 .res_type = RPMPD_SMPB, 280 .res_id = 2, 281 .key = KEY_FLOOR_CORNER, 282 }; 283 284 static struct rpmpd gfx_s4b_corner = { 285 .pd = { .name = "gfx", }, 286 .res_type = RPMPD_SMPB, 287 .res_id = 4, 288 .key = KEY_CORNER, 289 }; 290 291 static struct rpmpd gfx_s4b_vfc = { 292 .pd = { .name = "gfx_vfc", }, 293 .res_type = RPMPD_SMPB, 294 .res_id = 4, 295 .key = KEY_FLOOR_CORNER, 296 }; 297 298 static struct rpmpd mx_rwmx0_lvl; 299 static struct rpmpd gx_rwgx0_lvl_ao; 300 static struct rpmpd gx_rwgx0_lvl = { 301 .pd = { .name = "gx", }, 302 .peer = &gx_rwgx0_lvl_ao, 303 .res_type = RPMPD_RWGX, 304 .parent = &mx_rwmx0_lvl.pd, 305 .res_id = 0, 306 .key = KEY_LEVEL, 307 }; 308 309 static struct rpmpd mx_rwmx0_lvl_ao; 310 static struct rpmpd gx_rwgx0_lvl_ao = { 311 .pd = { .name = "gx_ao", }, 312 .peer = &gx_rwgx0_lvl, 313 .parent = &mx_rwmx0_lvl_ao.pd, 314 .active_only = true, 315 .res_type = RPMPD_RWGX, 316 .res_id = 0, 317 .key = KEY_LEVEL, 318 }; 319 320 /* MX */ 321 static struct rpmpd mx_l2a_lvl_ao; 322 static struct rpmpd mx_l2a_lvl = { 323 .pd = { .name = "mx", }, 324 .peer = &mx_l2a_lvl_ao, 325 .res_type = RPMPD_LDOA, 326 .res_id = 2, 327 .key = KEY_LEVEL, 328 }; 329 330 static struct rpmpd mx_l2a_lvl_ao = { 331 .pd = { .name = "mx_ao", }, 332 .peer = &mx_l2a_lvl, 333 .active_only = true, 334 .res_type = RPMPD_LDOA, 335 .res_id = 2, 336 .key = KEY_LEVEL, 337 }; 338 339 static struct rpmpd mx_l3a_corner_ao; 340 static struct rpmpd mx_l3a_corner = { 341 .pd = { .name = "mx", }, 342 .peer = &mx_l3a_corner_ao, 343 .res_type = RPMPD_LDOA, 344 .res_id = 3, 345 .key = KEY_CORNER, 346 }; 347 348 static struct rpmpd mx_l3a_corner_ao = { 349 .pd = { .name = "mx_ao", }, 350 .peer = &mx_l3a_corner, 351 .active_only = true, 352 .res_type = RPMPD_LDOA, 353 .res_id = 3, 354 .key = KEY_CORNER, 355 }; 356 357 static struct rpmpd mx_l3a_lvl_ao; 358 static struct rpmpd mx_l3a_lvl = { 359 .pd = { .name = "mx", }, 360 .peer = &mx_l3a_lvl_ao, 361 .res_type = RPMPD_LDOA, 362 .res_id = 3, 363 .key = KEY_LEVEL, 364 }; 365 366 static struct rpmpd mx_l3a_lvl_ao = { 367 .pd = { .name = "mx_ao", }, 368 .peer = &mx_l3a_lvl, 369 .active_only = true, 370 .res_type = RPMPD_LDOA, 371 .res_id = 3, 372 .key = KEY_LEVEL, 373 }; 374 375 static struct rpmpd mx_l12a_lvl_ao; 376 static struct rpmpd mx_l12a_lvl = { 377 .pd = { .name = "mx", }, 378 .peer = &mx_l12a_lvl_ao, 379 .res_type = RPMPD_LDOA, 380 .res_id = 12, 381 .key = KEY_LEVEL, 382 }; 383 384 static struct rpmpd mx_l12a_lvl_ao = { 385 .pd = { .name = "mx_ao", }, 386 .peer = &mx_l12a_lvl, 387 .active_only = true, 388 .res_type = RPMPD_LDOA, 389 .res_id = 12, 390 .key = KEY_LEVEL, 391 }; 392 393 static struct rpmpd mx_s2a_corner_ao; 394 static struct rpmpd mx_s2a_corner = { 395 .pd = { .name = "mx", }, 396 .peer = &mx_s2a_corner_ao, 397 .res_type = RPMPD_SMPA, 398 .res_id = 2, 399 .key = KEY_CORNER, 400 }; 401 402 static struct rpmpd mx_s2a_corner_ao = { 403 .pd = { .name = "mx_ao", }, 404 .peer = &mx_s2a_corner, 405 .active_only = true, 406 .res_type = RPMPD_SMPA, 407 .res_id = 2, 408 .key = KEY_CORNER, 409 }; 410 411 static struct rpmpd mx_rwmx0_lvl_ao; 412 static struct rpmpd mx_rwmx0_lvl = { 413 .pd = { .name = "mx", }, 414 .peer = &mx_rwmx0_lvl_ao, 415 .res_type = RPMPD_RWMX, 416 .res_id = 0, 417 .key = KEY_LEVEL, 418 }; 419 420 static struct rpmpd mx_rwmx0_lvl_ao = { 421 .pd = { .name = "mx_ao", }, 422 .peer = &mx_rwmx0_lvl, 423 .active_only = true, 424 .res_type = RPMPD_RWMX, 425 .res_id = 0, 426 .key = KEY_LEVEL, 427 }; 428 429 static struct rpmpd mx_s6a_lvl_ao; 430 static struct rpmpd mx_s6a_lvl = { 431 .pd = { .name = "mx", }, 432 .peer = &mx_s6a_lvl_ao, 433 .res_type = RPMPD_SMPA, 434 .res_id = 6, 435 .key = KEY_LEVEL, 436 }; 437 438 static struct rpmpd mx_s6a_lvl_ao = { 439 .pd = { .name = "mx_ao", }, 440 .peer = &mx_s6a_lvl, 441 .active_only = true, 442 .res_type = RPMPD_SMPA, 443 .res_id = 6, 444 .key = KEY_LEVEL, 445 }; 446 447 static struct rpmpd mx_s7a_lvl_ao; 448 static struct rpmpd mx_s7a_lvl = { 449 .pd = { .name = "mx", }, 450 .peer = &mx_s7a_lvl_ao, 451 .res_type = RPMPD_SMPA, 452 .res_id = 7, 453 .key = KEY_LEVEL, 454 }; 455 456 static struct rpmpd mx_s7a_lvl_ao = { 457 .pd = { .name = "mx_ao", }, 458 .peer = &mx_s7a_lvl, 459 .active_only = true, 460 .res_type = RPMPD_SMPA, 461 .res_id = 7, 462 .key = KEY_LEVEL, 463 }; 464 465 static struct rpmpd mx_l12a_vfl = { 466 .pd = { .name = "mx_vfl", }, 467 .res_type = RPMPD_LDOA, 468 .res_id = 12, 469 .key = KEY_FLOOR_LEVEL, 470 }; 471 472 static struct rpmpd mx_rwmx0_vfl = { 473 .pd = { .name = "mx_vfl", }, 474 .res_type = RPMPD_RWMX, 475 .res_id = 0, 476 .key = KEY_FLOOR_LEVEL, 477 }; 478 479 static struct rpmpd mx_rwsm6_vfl = { 480 .pd = { .name = "mx_vfl", }, 481 .res_type = RPMPD_RWSM, 482 .res_id = 6, 483 .key = KEY_FLOOR_LEVEL, 484 }; 485 486 /* MD */ 487 static struct rpmpd md_s1a_corner_ao; 488 static struct rpmpd md_s1a_corner = { 489 .pd = { .name = "md", }, 490 .peer = &md_s1a_corner_ao, 491 .res_type = RPMPD_SMPA, 492 .res_id = 1, 493 .key = KEY_CORNER, 494 }; 495 496 static struct rpmpd md_s1a_corner_ao = { 497 .pd = { .name = "md_ao", }, 498 .peer = &md_s1a_corner, 499 .active_only = true, 500 .res_type = RPMPD_SMPA, 501 .res_id = 1, 502 .key = KEY_CORNER, 503 }; 504 505 static struct rpmpd md_s1a_lvl_ao; 506 static struct rpmpd md_s1a_lvl = { 507 .pd = { .name = "md", }, 508 .peer = &md_s1a_lvl_ao, 509 .res_type = RPMPD_SMPA, 510 .res_id = 1, 511 .key = KEY_LEVEL, 512 }; 513 514 static struct rpmpd md_s1a_lvl_ao = { 515 .pd = { .name = "md_ao", }, 516 .peer = &md_s1a_lvl, 517 .active_only = true, 518 .res_type = RPMPD_SMPA, 519 .res_id = 1, 520 .key = KEY_LEVEL, 521 }; 522 523 static struct rpmpd md_s1a_vfc = { 524 .pd = { .name = "md_vfc", }, 525 .res_type = RPMPD_SMPA, 526 .res_id = 1, 527 .key = KEY_FLOOR_CORNER, 528 }; 529 530 /* LPI_CX */ 531 static struct rpmpd lpi_cx_rwlc0_lvl = { 532 .pd = { .name = "lpi_cx", }, 533 .res_type = RPMPD_RWLC, 534 .res_id = 0, 535 .key = KEY_LEVEL, 536 }; 537 538 static struct rpmpd lpi_cx_rwlc0_vfl = { 539 .pd = { .name = "lpi_cx_vfl", }, 540 .res_type = RPMPD_RWLC, 541 .res_id = 0, 542 .key = KEY_FLOOR_LEVEL, 543 }; 544 545 /* LPI_MX */ 546 static struct rpmpd lpi_mx_rwlm0_lvl = { 547 .pd = { .name = "lpi_mx", }, 548 .res_type = RPMPD_RWLM, 549 .res_id = 0, 550 .key = KEY_LEVEL, 551 }; 552 553 static struct rpmpd lpi_mx_rwlm0_vfl = { 554 .pd = { .name = "lpi_mx_vfl", }, 555 .res_type = RPMPD_RWLM, 556 .res_id = 0, 557 .key = KEY_FLOOR_LEVEL, 558 }; 559 560 /* SSC_CX */ 561 static struct rpmpd ssc_cx_l26a_corner = { 562 .pd = { .name = "ssc_cx", }, 563 .res_type = RPMPD_LDOA, 564 .res_id = 26, 565 .key = KEY_CORNER, 566 }; 567 568 static struct rpmpd ssc_cx_rwlc0_lvl = { 569 .pd = { .name = "ssc_cx", }, 570 .res_type = RPMPD_RWLC, 571 .res_id = 0, 572 .key = KEY_LEVEL, 573 }; 574 575 static struct rpmpd ssc_cx_rwsc0_lvl = { 576 .pd = { .name = "ssc_cx", }, 577 .res_type = RPMPD_RWSC, 578 .res_id = 0, 579 .key = KEY_LEVEL, 580 }; 581 582 static struct rpmpd ssc_cx_l26a_vfc = { 583 .pd = { .name = "ssc_cx_vfc", }, 584 .res_type = RPMPD_LDOA, 585 .res_id = 26, 586 .key = KEY_FLOOR_CORNER, 587 }; 588 589 static struct rpmpd ssc_cx_rwlc0_vfl = { 590 .pd = { .name = "ssc_cx_vfl", }, 591 .res_type = RPMPD_RWLC, 592 .res_id = 0, 593 .key = KEY_FLOOR_LEVEL, 594 }; 595 596 static struct rpmpd ssc_cx_rwsc0_vfl = { 597 .pd = { .name = "ssc_cx_vfl", }, 598 .res_type = RPMPD_RWSC, 599 .res_id = 0, 600 .key = KEY_FLOOR_LEVEL, 601 }; 602 603 /* SSC_MX */ 604 static struct rpmpd ssc_mx_rwlm0_lvl = { 605 .pd = { .name = "ssc_mx", }, 606 .res_type = RPMPD_RWLM, 607 .res_id = 0, 608 .key = KEY_LEVEL, 609 }; 610 611 static struct rpmpd ssc_mx_rwsm0_lvl = { 612 .pd = { .name = "ssc_mx", }, 613 .res_type = RPMPD_RWSM, 614 .res_id = 0, 615 .key = KEY_LEVEL, 616 }; 617 618 static struct rpmpd ssc_mx_rwlm0_vfl = { 619 .pd = { .name = "ssc_mx_vfl", }, 620 .res_type = RPMPD_RWLM, 621 .res_id = 0, 622 .key = KEY_FLOOR_LEVEL, 623 }; 624 625 static struct rpmpd ssc_mx_rwsm0_vfl = { 626 .pd = { .name = "ssc_mx_vfl", }, 627 .res_type = RPMPD_RWSM, 628 .res_id = 0, 629 .key = KEY_FLOOR_LEVEL, 630 }; 631 632 static struct rpmpd *mdm9607_rpmpds[] = { 633 [MDM9607_VDDCX] = &cx_s3a_lvl, 634 [MDM9607_VDDCX_AO] = &cx_s3a_lvl_ao, 635 [MDM9607_VDDCX_VFL] = &cx_s3a_vfl, 636 [MDM9607_VDDMX] = &mx_l12a_lvl, 637 [MDM9607_VDDMX_AO] = &mx_l12a_lvl_ao, 638 [MDM9607_VDDMX_VFL] = &mx_l12a_vfl, 639 }; 640 641 static const struct rpmpd_desc mdm9607_desc = { 642 .rpmpds = mdm9607_rpmpds, 643 .num_pds = ARRAY_SIZE(mdm9607_rpmpds), 644 .max_state = RPM_SMD_LEVEL_TURBO, 645 }; 646 647 static struct rpmpd *msm8226_rpmpds[] = { 648 [MSM8226_VDDCX] = &cx_s1a_corner, 649 [MSM8226_VDDCX_AO] = &cx_s1a_corner_ao, 650 [MSM8226_VDDCX_VFC] = &cx_s1a_vfc, 651 }; 652 653 static const struct rpmpd_desc msm8226_desc = { 654 .rpmpds = msm8226_rpmpds, 655 .num_pds = ARRAY_SIZE(msm8226_rpmpds), 656 .max_state = MAX_CORNER_RPMPD_STATE, 657 }; 658 659 static struct rpmpd *msm8939_rpmpds[] = { 660 [MSM8939_VDDMDCX] = &md_s1a_corner, 661 [MSM8939_VDDMDCX_AO] = &md_s1a_corner_ao, 662 [MSM8939_VDDMDCX_VFC] = &md_s1a_vfc, 663 [MSM8939_VDDCX] = &cx_s2a_corner, 664 [MSM8939_VDDCX_AO] = &cx_s2a_corner_ao, 665 [MSM8939_VDDCX_VFC] = &cx_s2a_vfc, 666 [MSM8939_VDDMX] = &mx_l3a_corner, 667 [MSM8939_VDDMX_AO] = &mx_l3a_corner_ao, 668 }; 669 670 static const struct rpmpd_desc msm8939_desc = { 671 .rpmpds = msm8939_rpmpds, 672 .num_pds = ARRAY_SIZE(msm8939_rpmpds), 673 .max_state = MAX_CORNER_RPMPD_STATE, 674 }; 675 676 static struct rpmpd *msm8916_rpmpds[] = { 677 [MSM8916_VDDCX] = &cx_s1a_corner, 678 [MSM8916_VDDCX_AO] = &cx_s1a_corner_ao, 679 [MSM8916_VDDCX_VFC] = &cx_s1a_vfc, 680 [MSM8916_VDDMX] = &mx_l3a_corner, 681 [MSM8916_VDDMX_AO] = &mx_l3a_corner_ao, 682 }; 683 684 static const struct rpmpd_desc msm8916_desc = { 685 .rpmpds = msm8916_rpmpds, 686 .num_pds = ARRAY_SIZE(msm8916_rpmpds), 687 .max_state = MAX_CORNER_RPMPD_STATE, 688 }; 689 690 static struct rpmpd *msm8917_rpmpds[] = { 691 [MSM8917_VDDCX] = &cx_s2a_lvl, 692 [MSM8917_VDDCX_AO] = &cx_s2a_lvl_ao, 693 [MSM8917_VDDCX_VFL] = &cx_s2a_vfl, 694 [MSM8917_VDDMX] = &mx_l3a_lvl, 695 [MSM8917_VDDMX_AO] = &mx_l3a_lvl_ao, 696 }; 697 698 static const struct rpmpd_desc msm8917_desc = { 699 .rpmpds = msm8917_rpmpds, 700 .num_pds = ARRAY_SIZE(msm8917_rpmpds), 701 .max_state = RPM_SMD_LEVEL_TURBO, 702 }; 703 704 static struct rpmpd *msm8953_rpmpds[] = { 705 [MSM8953_VDDMD] = &md_s1a_lvl, 706 [MSM8953_VDDMD_AO] = &md_s1a_lvl_ao, 707 [MSM8953_VDDCX] = &cx_s2a_lvl, 708 [MSM8953_VDDCX_AO] = &cx_s2a_lvl_ao, 709 [MSM8953_VDDCX_VFL] = &cx_s2a_vfl, 710 [MSM8953_VDDMX] = &mx_s7a_lvl, 711 [MSM8953_VDDMX_AO] = &mx_s7a_lvl_ao, 712 }; 713 714 static const struct rpmpd_desc msm8953_desc = { 715 .rpmpds = msm8953_rpmpds, 716 .num_pds = ARRAY_SIZE(msm8953_rpmpds), 717 .max_state = RPM_SMD_LEVEL_TURBO, 718 }; 719 720 static struct rpmpd *msm8974_rpmpds[] = { 721 [MSM8974_VDDCX] = &cx_s2b_corner, 722 [MSM8974_VDDCX_AO] = &cx_s2b_corner_ao, 723 [MSM8974_VDDCX_VFC] = &cx_s2b_vfc, 724 [MSM8974_VDDGFX] = &gfx_s4b_corner, 725 [MSM8974_VDDGFX_VFC] = &gfx_s4b_vfc, 726 }; 727 728 static const struct rpmpd_desc msm8974_desc = { 729 .rpmpds = msm8974_rpmpds, 730 .num_pds = ARRAY_SIZE(msm8974_rpmpds), 731 .max_state = MAX_CORNER_RPMPD_STATE, 732 }; 733 734 static struct rpmpd *msm8974pro_pma8084_rpmpds[] = { 735 [MSM8974_VDDCX] = &cx_s2a_corner, 736 [MSM8974_VDDCX_AO] = &cx_s2a_corner_ao, 737 [MSM8974_VDDCX_VFC] = &cx_s2a_vfc, 738 [MSM8974_VDDGFX] = &gfx_s7a_corner, 739 [MSM8974_VDDGFX_VFC] = &gfx_s7a_vfc, 740 }; 741 742 static const struct rpmpd_desc msm8974pro_pma8084_desc = { 743 .rpmpds = msm8974pro_pma8084_rpmpds, 744 .num_pds = ARRAY_SIZE(msm8974pro_pma8084_rpmpds), 745 .max_state = MAX_CORNER_RPMPD_STATE, 746 }; 747 748 static struct rpmpd *msm8976_rpmpds[] = { 749 [MSM8976_VDDCX] = &cx_s2a_lvl, 750 [MSM8976_VDDCX_AO] = &cx_s2a_lvl_ao, 751 [MSM8976_VDDCX_VFL] = &cx_rwsc2_vfl, 752 [MSM8976_VDDMX] = &mx_s6a_lvl, 753 [MSM8976_VDDMX_AO] = &mx_s6a_lvl_ao, 754 [MSM8976_VDDMX_VFL] = &mx_rwsm6_vfl, 755 }; 756 757 static const struct rpmpd_desc msm8976_desc = { 758 .rpmpds = msm8976_rpmpds, 759 .num_pds = ARRAY_SIZE(msm8976_rpmpds), 760 .max_state = RPM_SMD_LEVEL_TURBO_HIGH, 761 }; 762 763 static struct rpmpd *msm8994_rpmpds[] = { 764 [MSM8994_VDDCX] = &cx_s1a_corner, 765 [MSM8994_VDDCX_AO] = &cx_s1a_corner_ao, 766 [MSM8994_VDDCX_VFC] = &cx_s1a_vfc, 767 [MSM8994_VDDMX] = &mx_s2a_corner, 768 [MSM8994_VDDMX_AO] = &mx_s2a_corner_ao, 769 770 /* Attention! *Some* 8994 boards with pm8004 may use SMPC here! */ 771 [MSM8994_VDDGFX] = &gfx_s2b_corner, 772 [MSM8994_VDDGFX_VFC] = &gfx_s2b_vfc, 773 }; 774 775 static const struct rpmpd_desc msm8994_desc = { 776 .rpmpds = msm8994_rpmpds, 777 .num_pds = ARRAY_SIZE(msm8994_rpmpds), 778 .max_state = MAX_CORNER_RPMPD_STATE, 779 }; 780 781 static struct rpmpd *msm8996_rpmpds[] = { 782 [MSM8996_VDDCX] = &cx_s1a_corner, 783 [MSM8996_VDDCX_AO] = &cx_s1a_corner_ao, 784 [MSM8996_VDDCX_VFC] = &cx_s1a_vfc, 785 [MSM8996_VDDMX] = &mx_s2a_corner, 786 [MSM8996_VDDMX_AO] = &mx_s2a_corner_ao, 787 [MSM8996_VDDSSCX] = &ssc_cx_l26a_corner, 788 [MSM8996_VDDSSCX_VFC] = &ssc_cx_l26a_vfc, 789 }; 790 791 static const struct rpmpd_desc msm8996_desc = { 792 .rpmpds = msm8996_rpmpds, 793 .num_pds = ARRAY_SIZE(msm8996_rpmpds), 794 .max_state = MAX_CORNER_RPMPD_STATE, 795 }; 796 797 static struct rpmpd *msm8998_rpmpds[] = { 798 [MSM8998_VDDCX] = &cx_rwcx0_lvl, 799 [MSM8998_VDDCX_AO] = &cx_rwcx0_lvl_ao, 800 [MSM8998_VDDCX_VFL] = &cx_rwcx0_vfl, 801 [MSM8998_VDDMX] = &mx_rwmx0_lvl, 802 [MSM8998_VDDMX_AO] = &mx_rwmx0_lvl_ao, 803 [MSM8998_VDDMX_VFL] = &mx_rwmx0_vfl, 804 [MSM8998_SSCCX] = &ssc_cx_rwsc0_lvl, 805 [MSM8998_SSCCX_VFL] = &ssc_cx_rwsc0_vfl, 806 [MSM8998_SSCMX] = &ssc_mx_rwsm0_lvl, 807 [MSM8998_SSCMX_VFL] = &ssc_mx_rwsm0_vfl, 808 }; 809 810 static const struct rpmpd_desc msm8998_desc = { 811 .rpmpds = msm8998_rpmpds, 812 .num_pds = ARRAY_SIZE(msm8998_rpmpds), 813 .max_state = RPM_SMD_LEVEL_BINNING, 814 }; 815 816 static struct rpmpd *qcs404_rpmpds[] = { 817 [QCS404_VDDMX] = &mx_rwmx0_lvl, 818 [QCS404_VDDMX_AO] = &mx_rwmx0_lvl_ao, 819 [QCS404_VDDMX_VFL] = &mx_rwmx0_vfl, 820 [QCS404_LPICX] = &lpi_cx_rwlc0_lvl, 821 [QCS404_LPICX_VFL] = &lpi_cx_rwlc0_vfl, 822 [QCS404_LPIMX] = &lpi_mx_rwlm0_lvl, 823 [QCS404_LPIMX_VFL] = &lpi_mx_rwlm0_vfl, 824 }; 825 826 static const struct rpmpd_desc qcs404_desc = { 827 .rpmpds = qcs404_rpmpds, 828 .num_pds = ARRAY_SIZE(qcs404_rpmpds), 829 .max_state = RPM_SMD_LEVEL_BINNING, 830 }; 831 832 static struct rpmpd *qm215_rpmpds[] = { 833 [QM215_VDDCX] = &cx_s1a_lvl, 834 [QM215_VDDCX_AO] = &cx_s1a_lvl_ao, 835 [QM215_VDDCX_VFL] = &cx_s1a_vfl, 836 [QM215_VDDMX] = &mx_l2a_lvl, 837 [QM215_VDDMX_AO] = &mx_l2a_lvl_ao, 838 }; 839 840 static const struct rpmpd_desc qm215_desc = { 841 .rpmpds = qm215_rpmpds, 842 .num_pds = ARRAY_SIZE(qm215_rpmpds), 843 .max_state = RPM_SMD_LEVEL_TURBO, 844 }; 845 846 static struct rpmpd *sdm660_rpmpds[] = { 847 [SDM660_VDDCX] = &cx_rwcx0_lvl, 848 [SDM660_VDDCX_AO] = &cx_rwcx0_lvl_ao, 849 [SDM660_VDDCX_VFL] = &cx_rwcx0_vfl, 850 [SDM660_VDDMX] = &mx_rwmx0_lvl, 851 [SDM660_VDDMX_AO] = &mx_rwmx0_lvl_ao, 852 [SDM660_VDDMX_VFL] = &mx_rwmx0_vfl, 853 [SDM660_SSCCX] = &ssc_cx_rwlc0_lvl, 854 [SDM660_SSCCX_VFL] = &ssc_cx_rwlc0_vfl, 855 [SDM660_SSCMX] = &ssc_mx_rwlm0_lvl, 856 [SDM660_SSCMX_VFL] = &ssc_mx_rwlm0_vfl, 857 }; 858 859 static const struct rpmpd_desc sdm660_desc = { 860 .rpmpds = sdm660_rpmpds, 861 .num_pds = ARRAY_SIZE(sdm660_rpmpds), 862 .max_state = RPM_SMD_LEVEL_TURBO, 863 }; 864 865 static struct rpmpd *sm6115_rpmpds[] = { 866 [SM6115_VDDCX] = &cx_rwcx0_lvl, 867 [SM6115_VDDCX_AO] = &cx_rwcx0_lvl_ao, 868 [SM6115_VDDCX_VFL] = &cx_rwcx0_vfl, 869 [SM6115_VDDMX] = &mx_rwmx0_lvl, 870 [SM6115_VDDMX_AO] = &mx_rwmx0_lvl_ao, 871 [SM6115_VDDMX_VFL] = &mx_rwmx0_vfl, 872 [SM6115_VDD_LPI_CX] = &lpi_cx_rwlc0_lvl, 873 [SM6115_VDD_LPI_MX] = &lpi_mx_rwlm0_lvl, 874 }; 875 876 static const struct rpmpd_desc sm6115_desc = { 877 .rpmpds = sm6115_rpmpds, 878 .num_pds = ARRAY_SIZE(sm6115_rpmpds), 879 .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, 880 }; 881 882 static struct rpmpd *sm6125_rpmpds[] = { 883 [SM6125_VDDCX] = &cx_rwcx0_lvl, 884 [SM6125_VDDCX_AO] = &cx_rwcx0_lvl_ao, 885 [SM6125_VDDCX_VFL] = &cx_rwcx0_vfl, 886 [SM6125_VDDMX] = &mx_rwmx0_lvl, 887 [SM6125_VDDMX_AO] = &mx_rwmx0_lvl_ao, 888 [SM6125_VDDMX_VFL] = &mx_rwmx0_vfl, 889 }; 890 891 static const struct rpmpd_desc sm6125_desc = { 892 .rpmpds = sm6125_rpmpds, 893 .num_pds = ARRAY_SIZE(sm6125_rpmpds), 894 .max_state = RPM_SMD_LEVEL_BINNING, 895 }; 896 897 static struct rpmpd *sm6375_rpmpds[] = { 898 [SM6375_VDDCX] = &cx_rwcx0_lvl, 899 [SM6375_VDDCX_AO] = &cx_rwcx0_lvl_ao, 900 [SM6375_VDDCX_VFL] = &cx_rwcx0_vfl, 901 [SM6375_VDDMX] = &mx_rwmx0_lvl, 902 [SM6375_VDDMX_AO] = &mx_rwmx0_lvl_ao, 903 [SM6375_VDDMX_VFL] = &mx_rwmx0_vfl, 904 [SM6375_VDDGX] = &gx_rwgx0_lvl, 905 [SM6375_VDDGX_AO] = &gx_rwgx0_lvl_ao, 906 [SM6375_VDD_LPI_CX] = &lpi_cx_rwlc0_lvl, 907 [SM6375_VDD_LPI_MX] = &lpi_mx_rwlm0_lvl, 908 }; 909 910 static const struct rpmpd_desc sm6375_desc = { 911 .rpmpds = sm6375_rpmpds, 912 .num_pds = ARRAY_SIZE(sm6375_rpmpds), 913 .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, 914 }; 915 916 static struct rpmpd *qcm2290_rpmpds[] = { 917 [QCM2290_VDDCX] = &cx_rwcx0_lvl, 918 [QCM2290_VDDCX_AO] = &cx_rwcx0_lvl_ao, 919 [QCM2290_VDDCX_VFL] = &cx_rwcx0_vfl, 920 [QCM2290_VDDMX] = &mx_rwmx0_lvl, 921 [QCM2290_VDDMX_AO] = &mx_rwmx0_lvl_ao, 922 [QCM2290_VDDMX_VFL] = &mx_rwmx0_vfl, 923 [QCM2290_VDD_LPI_CX] = &lpi_cx_rwlc0_lvl, 924 [QCM2290_VDD_LPI_MX] = &lpi_mx_rwlm0_lvl, 925 }; 926 927 static const struct rpmpd_desc qcm2290_desc = { 928 .rpmpds = qcm2290_rpmpds, 929 .num_pds = ARRAY_SIZE(qcm2290_rpmpds), 930 .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, 931 }; 932 933 static const struct of_device_id rpmpd_match_table[] = { 934 { .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc }, 935 { .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc }, 936 { .compatible = "qcom,msm8909-rpmpd", .data = &msm8916_desc }, 937 { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, 938 { .compatible = "qcom,msm8917-rpmpd", .data = &msm8917_desc }, 939 { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc }, 940 { .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc }, 941 { .compatible = "qcom,msm8974-rpmpd", .data = &msm8974_desc }, 942 { .compatible = "qcom,msm8974pro-pma8084-rpmpd", .data = &msm8974pro_pma8084_desc }, 943 { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, 944 { .compatible = "qcom,msm8994-rpmpd", .data = &msm8994_desc }, 945 { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, 946 { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, 947 { .compatible = "qcom,qcm2290-rpmpd", .data = &qcm2290_desc }, 948 { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, 949 { .compatible = "qcom,qm215-rpmpd", .data = &qm215_desc }, 950 { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, 951 { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, 952 { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, 953 { .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc }, 954 { } 955 }; 956 MODULE_DEVICE_TABLE(of, rpmpd_match_table); 957 958 static int rpmpd_send_enable(struct rpmpd *pd, bool enable) 959 { 960 struct rpmpd_req req = { 961 .key = KEY_ENABLE, 962 .nbytes = cpu_to_le32(sizeof(u32)), 963 .value = cpu_to_le32(enable), 964 }; 965 966 return qcom_rpm_smd_write(rpmpd_smd_rpm, QCOM_SMD_RPM_ACTIVE_STATE, 967 pd->res_type, pd->res_id, &req, sizeof(req)); 968 } 969 970 static int rpmpd_send_corner(struct rpmpd *pd, int state, unsigned int corner) 971 { 972 struct rpmpd_req req = { 973 .key = pd->key, 974 .nbytes = cpu_to_le32(sizeof(u32)), 975 .value = cpu_to_le32(corner), 976 }; 977 978 return qcom_rpm_smd_write(rpmpd_smd_rpm, state, pd->res_type, pd->res_id, 979 &req, sizeof(req)); 980 }; 981 982 static void to_active_sleep(struct rpmpd *pd, unsigned int corner, 983 unsigned int *active, unsigned int *sleep) 984 { 985 *active = corner; 986 987 if (pd->active_only) 988 *sleep = 0; 989 else 990 *sleep = *active; 991 } 992 993 static int rpmpd_aggregate_corner(struct rpmpd *pd) 994 { 995 int ret; 996 struct rpmpd *peer = pd->peer; 997 unsigned int active_corner, sleep_corner; 998 unsigned int this_active_corner = 0, this_sleep_corner = 0; 999 unsigned int peer_active_corner = 0, peer_sleep_corner = 0; 1000 1001 /* Clamp to the highest corner/level if sync_state isn't done yet */ 1002 if (!pd->state_synced) 1003 this_active_corner = this_sleep_corner = pd->max_state - 1; 1004 else 1005 to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); 1006 1007 if (peer && peer->enabled) 1008 to_active_sleep(peer, peer->corner, &peer_active_corner, 1009 &peer_sleep_corner); 1010 1011 active_corner = max(this_active_corner, peer_active_corner); 1012 1013 ret = rpmpd_send_corner(pd, QCOM_SMD_RPM_ACTIVE_STATE, active_corner); 1014 if (ret) 1015 return ret; 1016 1017 sleep_corner = max(this_sleep_corner, peer_sleep_corner); 1018 1019 return rpmpd_send_corner(pd, QCOM_SMD_RPM_SLEEP_STATE, sleep_corner); 1020 } 1021 1022 static int rpmpd_power_on(struct generic_pm_domain *domain) 1023 { 1024 int ret; 1025 struct rpmpd *pd = domain_to_rpmpd(domain); 1026 1027 mutex_lock(&rpmpd_lock); 1028 1029 ret = rpmpd_send_enable(pd, true); 1030 if (ret) 1031 goto out; 1032 1033 pd->enabled = true; 1034 1035 if (pd->corner) 1036 ret = rpmpd_aggregate_corner(pd); 1037 1038 out: 1039 mutex_unlock(&rpmpd_lock); 1040 1041 return ret; 1042 } 1043 1044 static int rpmpd_power_off(struct generic_pm_domain *domain) 1045 { 1046 int ret; 1047 struct rpmpd *pd = domain_to_rpmpd(domain); 1048 1049 mutex_lock(&rpmpd_lock); 1050 1051 ret = rpmpd_send_enable(pd, false); 1052 if (!ret) 1053 pd->enabled = false; 1054 1055 mutex_unlock(&rpmpd_lock); 1056 1057 return ret; 1058 } 1059 1060 static int rpmpd_set_performance(struct generic_pm_domain *domain, 1061 unsigned int state) 1062 { 1063 int ret = 0; 1064 struct rpmpd *pd = domain_to_rpmpd(domain); 1065 1066 if (state > pd->max_state) 1067 state = pd->max_state; 1068 1069 mutex_lock(&rpmpd_lock); 1070 1071 pd->corner = state; 1072 1073 /* Always send updates for vfc and vfl */ 1074 if (!pd->enabled && pd->key != cpu_to_le32(KEY_FLOOR_CORNER) && 1075 pd->key != cpu_to_le32(KEY_FLOOR_LEVEL)) 1076 goto out; 1077 1078 ret = rpmpd_aggregate_corner(pd); 1079 1080 out: 1081 mutex_unlock(&rpmpd_lock); 1082 1083 return ret; 1084 } 1085 1086 static int rpmpd_probe(struct platform_device *pdev) 1087 { 1088 int i; 1089 size_t num; 1090 struct genpd_onecell_data *data; 1091 struct rpmpd **rpmpds; 1092 const struct rpmpd_desc *desc; 1093 1094 rpmpd_smd_rpm = dev_get_drvdata(pdev->dev.parent); 1095 if (!rpmpd_smd_rpm) { 1096 dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n"); 1097 return -ENODEV; 1098 } 1099 1100 desc = of_device_get_match_data(&pdev->dev); 1101 if (!desc) 1102 return -EINVAL; 1103 1104 rpmpds = desc->rpmpds; 1105 num = desc->num_pds; 1106 1107 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 1108 if (!data) 1109 return -ENOMEM; 1110 1111 data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains), 1112 GFP_KERNEL); 1113 if (!data->domains) 1114 return -ENOMEM; 1115 1116 data->num_domains = num; 1117 1118 for (i = 0; i < num; i++) { 1119 if (!rpmpds[i]) { 1120 dev_warn(&pdev->dev, "rpmpds[] with empty entry at index=%d\n", 1121 i); 1122 continue; 1123 } 1124 1125 rpmpds[i]->max_state = desc->max_state; 1126 rpmpds[i]->pd.power_off = rpmpd_power_off; 1127 rpmpds[i]->pd.power_on = rpmpd_power_on; 1128 rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; 1129 rpmpds[i]->pd.flags = GENPD_FLAG_ACTIVE_WAKEUP; 1130 pm_genpd_init(&rpmpds[i]->pd, NULL, true); 1131 1132 data->domains[i] = &rpmpds[i]->pd; 1133 } 1134 1135 /* Add subdomains */ 1136 for (i = 0; i < num; i++) { 1137 if (!rpmpds[i]) 1138 continue; 1139 1140 if (rpmpds[i]->parent) 1141 pm_genpd_add_subdomain(rpmpds[i]->parent, &rpmpds[i]->pd); 1142 } 1143 1144 return of_genpd_add_provider_onecell(pdev->dev.of_node, data); 1145 } 1146 1147 static void rpmpd_sync_state(struct device *dev) 1148 { 1149 const struct rpmpd_desc *desc = of_device_get_match_data(dev); 1150 struct rpmpd **rpmpds = desc->rpmpds; 1151 struct rpmpd *pd; 1152 unsigned int i; 1153 int ret; 1154 1155 mutex_lock(&rpmpd_lock); 1156 for (i = 0; i < desc->num_pds; i++) { 1157 pd = rpmpds[i]; 1158 if (!pd) 1159 continue; 1160 1161 pd->state_synced = true; 1162 1163 if (!pd->enabled) 1164 pd->corner = 0; 1165 1166 ret = rpmpd_aggregate_corner(pd); 1167 if (ret) 1168 dev_err(dev, "failed to sync %s: %d\n", pd->pd.name, ret); 1169 } 1170 mutex_unlock(&rpmpd_lock); 1171 } 1172 1173 static struct platform_driver rpmpd_driver = { 1174 .driver = { 1175 .name = "qcom-rpmpd", 1176 .of_match_table = rpmpd_match_table, 1177 .suppress_bind_attrs = true, 1178 .sync_state = rpmpd_sync_state, 1179 }, 1180 .probe = rpmpd_probe, 1181 }; 1182 1183 static int __init rpmpd_init(void) 1184 { 1185 return platform_driver_register(&rpmpd_driver); 1186 } 1187 core_initcall(rpmpd_init); 1188 1189 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPM Power Domain Driver"); 1190 MODULE_LICENSE("GPL v2"); 1191