1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Core MFD support for Cirrus Logic Madera codecs 4 * 5 * Copyright (C) 2015-2018 Cirrus Logic 6 */ 7 8 #include <linux/device.h> 9 #include <linux/delay.h> 10 #include <linux/err.h> 11 #include <linux/gpio.h> 12 #include <linux/mfd/core.h> 13 #include <linux/module.h> 14 #include <linux/mutex.h> 15 #include <linux/notifier.h> 16 #include <linux/of.h> 17 #include <linux/of_gpio.h> 18 #include <linux/platform_device.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/regmap.h> 21 #include <linux/regulator/consumer.h> 22 #include <linux/regulator/machine.h> 23 #include <linux/regulator/of_regulator.h> 24 25 #include <linux/mfd/madera/core.h> 26 #include <linux/mfd/madera/registers.h> 27 28 #include "madera.h" 29 30 #define CS47L15_SILICON_ID 0x6370 31 #define CS47L35_SILICON_ID 0x6360 32 #define CS47L85_SILICON_ID 0x6338 33 #define CS47L90_SILICON_ID 0x6364 34 #define CS47L92_SILICON_ID 0x6371 35 36 #define MADERA_32KZ_MCLK2 1 37 38 #define MADERA_RESET_MIN_US 2000 39 #define MADERA_RESET_MAX_US 3000 40 41 static const char * const madera_core_supplies[] = { 42 "AVDD", 43 "DBVDD1", 44 }; 45 46 static const struct mfd_cell madera_ldo1_devs[] = { 47 { .name = "madera-ldo1" }, 48 }; 49 50 static const char * const cs47l15_supplies[] = { 51 "MICVDD", 52 "CPVDD1", 53 "SPKVDD", 54 }; 55 56 static const struct mfd_cell cs47l15_devs[] = { 57 { .name = "madera-pinctrl", }, 58 { .name = "madera-irq" }, 59 { .name = "madera-gpio" }, 60 { 61 .name = "madera-extcon", 62 .parent_supplies = cs47l15_supplies, 63 .num_parent_supplies = 1, /* We only need MICVDD */ 64 }, 65 { 66 .name = "cs47l15-codec", 67 .parent_supplies = cs47l15_supplies, 68 .num_parent_supplies = ARRAY_SIZE(cs47l15_supplies), 69 }, 70 }; 71 72 static const char * const cs47l35_supplies[] = { 73 "MICVDD", 74 "DBVDD2", 75 "CPVDD1", 76 "CPVDD2", 77 "SPKVDD", 78 }; 79 80 static const struct mfd_cell cs47l35_devs[] = { 81 { .name = "madera-pinctrl", }, 82 { .name = "madera-irq", }, 83 { .name = "madera-micsupp", }, 84 { .name = "madera-gpio", }, 85 { 86 .name = "madera-extcon", 87 .parent_supplies = cs47l35_supplies, 88 .num_parent_supplies = 1, /* We only need MICVDD */ 89 }, 90 { 91 .name = "cs47l35-codec", 92 .parent_supplies = cs47l35_supplies, 93 .num_parent_supplies = ARRAY_SIZE(cs47l35_supplies), 94 }, 95 }; 96 97 static const char * const cs47l85_supplies[] = { 98 "MICVDD", 99 "DBVDD2", 100 "DBVDD3", 101 "DBVDD4", 102 "CPVDD1", 103 "CPVDD2", 104 "SPKVDDL", 105 "SPKVDDR", 106 }; 107 108 static const struct mfd_cell cs47l85_devs[] = { 109 { .name = "madera-pinctrl", }, 110 { .name = "madera-irq", }, 111 { .name = "madera-micsupp" }, 112 { .name = "madera-gpio", }, 113 { 114 .name = "madera-extcon", 115 .parent_supplies = cs47l85_supplies, 116 .num_parent_supplies = 1, /* We only need MICVDD */ 117 }, 118 { 119 .name = "cs47l85-codec", 120 .parent_supplies = cs47l85_supplies, 121 .num_parent_supplies = ARRAY_SIZE(cs47l85_supplies), 122 }, 123 }; 124 125 static const char * const cs47l90_supplies[] = { 126 "MICVDD", 127 "DBVDD2", 128 "DBVDD3", 129 "DBVDD4", 130 "CPVDD1", 131 "CPVDD2", 132 }; 133 134 static const struct mfd_cell cs47l90_devs[] = { 135 { .name = "madera-pinctrl", }, 136 { .name = "madera-irq", }, 137 { .name = "madera-micsupp", }, 138 { .name = "madera-gpio", }, 139 { 140 .name = "madera-extcon", 141 .parent_supplies = cs47l90_supplies, 142 .num_parent_supplies = 1, /* We only need MICVDD */ 143 }, 144 { 145 .name = "cs47l90-codec", 146 .parent_supplies = cs47l90_supplies, 147 .num_parent_supplies = ARRAY_SIZE(cs47l90_supplies), 148 }, 149 }; 150 151 static const char * const cs47l92_supplies[] = { 152 "MICVDD", 153 "CPVDD1", 154 "CPVDD2", 155 }; 156 157 static const struct mfd_cell cs47l92_devs[] = { 158 { .name = "madera-pinctrl" }, 159 { .name = "madera-irq", }, 160 { .name = "madera-micsupp", }, 161 { .name = "madera-gpio" }, 162 { 163 .name = "madera-extcon", 164 .parent_supplies = cs47l92_supplies, 165 .num_parent_supplies = 1, /* We only need MICVDD */ 166 }, 167 { 168 .name = "cs47l92-codec", 169 .parent_supplies = cs47l92_supplies, 170 .num_parent_supplies = ARRAY_SIZE(cs47l92_supplies), 171 }, 172 }; 173 174 /* Used by madera-i2c and madera-spi drivers */ 175 const char *madera_name_from_type(enum madera_type type) 176 { 177 switch (type) { 178 case CS47L15: 179 return "CS47L15"; 180 case CS47L35: 181 return "CS47L35"; 182 case CS47L85: 183 return "CS47L85"; 184 case CS47L90: 185 return "CS47L90"; 186 case CS47L91: 187 return "CS47L91"; 188 case CS42L92: 189 return "CS42L92"; 190 case CS47L92: 191 return "CS47L92"; 192 case CS47L93: 193 return "CS47L93"; 194 case WM1840: 195 return "WM1840"; 196 default: 197 return "Unknown"; 198 } 199 } 200 EXPORT_SYMBOL_GPL(madera_name_from_type); 201 202 #define MADERA_BOOT_POLL_INTERVAL_USEC 5000 203 #define MADERA_BOOT_POLL_TIMEOUT_USEC 25000 204 205 static int madera_wait_for_boot_noack(struct madera *madera) 206 { 207 ktime_t timeout; 208 unsigned int val = 0; 209 int ret = 0; 210 211 /* 212 * We can't use an interrupt as we need to runtime resume to do so, 213 * so we poll the status bit. This won't race with the interrupt 214 * handler because it will be blocked on runtime resume. 215 * The chip could NAK a read request while it is booting so ignore 216 * errors from regmap_read. 217 */ 218 timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC); 219 regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val); 220 while (!(val & MADERA_BOOT_DONE_STS1) && 221 !ktime_after(ktime_get(), timeout)) { 222 usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2, 223 MADERA_BOOT_POLL_INTERVAL_USEC); 224 regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val); 225 } 226 227 if (!(val & MADERA_BOOT_DONE_STS1)) { 228 dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n"); 229 ret = -ETIMEDOUT; 230 } 231 232 return ret; 233 } 234 235 static int madera_wait_for_boot(struct madera *madera) 236 { 237 int ret = madera_wait_for_boot_noack(madera); 238 239 /* 240 * BOOT_DONE defaults to unmasked on boot so we must ack it. 241 * Do this even after a timeout to avoid interrupt storms. 242 */ 243 regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1, 244 MADERA_BOOT_DONE_EINT1); 245 246 pm_runtime_mark_last_busy(madera->dev); 247 248 return ret; 249 } 250 251 static int madera_soft_reset(struct madera *madera) 252 { 253 int ret; 254 255 ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0); 256 if (ret != 0) { 257 dev_err(madera->dev, "Failed to soft reset device: %d\n", ret); 258 return ret; 259 } 260 261 /* Allow time for internal clocks to startup after reset */ 262 usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US); 263 264 return 0; 265 } 266 267 static void madera_enable_hard_reset(struct madera *madera) 268 { 269 /* 270 * There are many existing out-of-tree users of these codecs that we 271 * can't break so preserve the expected behaviour of setting the line 272 * low to assert reset. 273 */ 274 gpiod_set_raw_value_cansleep(madera->pdata.reset, 0); 275 } 276 277 static void madera_disable_hard_reset(struct madera *madera) 278 { 279 gpiod_set_raw_value_cansleep(madera->pdata.reset, 1); 280 281 usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US); 282 } 283 284 static int __maybe_unused madera_runtime_resume(struct device *dev) 285 { 286 struct madera *madera = dev_get_drvdata(dev); 287 int ret; 288 289 dev_dbg(dev, "Leaving sleep mode\n"); 290 291 ret = regulator_enable(madera->dcvdd); 292 if (ret) { 293 dev_err(dev, "Failed to enable DCVDD: %d\n", ret); 294 return ret; 295 } 296 297 regcache_cache_only(madera->regmap, false); 298 regcache_cache_only(madera->regmap_32bit, false); 299 300 usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US); 301 302 ret = madera_wait_for_boot(madera); 303 if (ret) 304 goto err; 305 306 ret = regcache_sync(madera->regmap); 307 if (ret) { 308 dev_err(dev, "Failed to restore 16-bit register cache\n"); 309 goto err; 310 } 311 312 ret = regcache_sync(madera->regmap_32bit); 313 if (ret) { 314 dev_err(dev, "Failed to restore 32-bit register cache\n"); 315 goto err; 316 } 317 318 return 0; 319 320 err: 321 regcache_cache_only(madera->regmap_32bit, true); 322 regcache_cache_only(madera->regmap, true); 323 regulator_disable(madera->dcvdd); 324 325 return ret; 326 } 327 328 static int __maybe_unused madera_runtime_suspend(struct device *dev) 329 { 330 struct madera *madera = dev_get_drvdata(dev); 331 332 dev_dbg(madera->dev, "Entering sleep mode\n"); 333 334 regcache_cache_only(madera->regmap, true); 335 regcache_mark_dirty(madera->regmap); 336 regcache_cache_only(madera->regmap_32bit, true); 337 regcache_mark_dirty(madera->regmap_32bit); 338 339 regulator_disable(madera->dcvdd); 340 341 return 0; 342 } 343 344 const struct dev_pm_ops madera_pm_ops = { 345 SET_RUNTIME_PM_OPS(madera_runtime_suspend, 346 madera_runtime_resume, 347 NULL) 348 }; 349 EXPORT_SYMBOL_GPL(madera_pm_ops); 350 351 const struct of_device_id madera_of_match[] = { 352 { .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 }, 353 { .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 }, 354 { .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 }, 355 { .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 }, 356 { .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 }, 357 { .compatible = "cirrus,cs42l92", .data = (void *)CS42L92 }, 358 { .compatible = "cirrus,cs47l92", .data = (void *)CS47L92 }, 359 { .compatible = "cirrus,cs47l93", .data = (void *)CS47L93 }, 360 { .compatible = "cirrus,wm1840", .data = (void *)WM1840 }, 361 {} 362 }; 363 MODULE_DEVICE_TABLE(of, madera_of_match); 364 EXPORT_SYMBOL_GPL(madera_of_match); 365 366 static int madera_get_reset_gpio(struct madera *madera) 367 { 368 struct gpio_desc *reset; 369 int ret; 370 371 if (madera->pdata.reset) 372 return 0; 373 374 reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW); 375 if (IS_ERR(reset)) { 376 ret = PTR_ERR(reset); 377 if (ret != -EPROBE_DEFER) 378 dev_err(madera->dev, "Failed to request /RESET: %d\n", 379 ret); 380 return ret; 381 } 382 383 /* 384 * A hard reset is needed for full reset of the chip. We allow running 385 * without hard reset only because it can be useful for early 386 * prototyping and some debugging, but we need to warn it's not ideal. 387 */ 388 if (!reset) 389 dev_warn(madera->dev, 390 "Running without reset GPIO is not recommended\n"); 391 392 madera->pdata.reset = reset; 393 394 return 0; 395 } 396 397 static void madera_set_micbias_info(struct madera *madera) 398 { 399 /* 400 * num_childbias is an array because future codecs can have different 401 * childbiases for each micbias. Unspecified values default to 0. 402 */ 403 switch (madera->type) { 404 case CS47L15: 405 madera->num_micbias = 1; 406 madera->num_childbias[0] = 3; 407 return; 408 case CS47L35: 409 madera->num_micbias = 2; 410 madera->num_childbias[0] = 2; 411 madera->num_childbias[1] = 2; 412 return; 413 case CS47L85: 414 case WM1840: 415 madera->num_micbias = 4; 416 /* no child biases */ 417 return; 418 case CS47L90: 419 case CS47L91: 420 madera->num_micbias = 2; 421 madera->num_childbias[0] = 4; 422 madera->num_childbias[1] = 4; 423 return; 424 case CS42L92: 425 case CS47L92: 426 case CS47L93: 427 madera->num_micbias = 2; 428 madera->num_childbias[0] = 4; 429 madera->num_childbias[1] = 2; 430 return; 431 default: 432 return; 433 } 434 } 435 436 int madera_dev_init(struct madera *madera) 437 { 438 struct device *dev = madera->dev; 439 unsigned int hwid; 440 int (*patch_fn)(struct madera *) = NULL; 441 const struct mfd_cell *mfd_devs; 442 int n_devs = 0; 443 int i, ret; 444 445 dev_set_drvdata(madera->dev, madera); 446 BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier); 447 mutex_init(&madera->dapm_ptr_lock); 448 449 madera_set_micbias_info(madera); 450 451 /* 452 * We need writable hw config info that all children can share. 453 * Simplest to take one shared copy of pdata struct. 454 */ 455 if (dev_get_platdata(madera->dev)) { 456 memcpy(&madera->pdata, dev_get_platdata(madera->dev), 457 sizeof(madera->pdata)); 458 } 459 460 madera->mclk[MADERA_MCLK1].id = "mclk1"; 461 madera->mclk[MADERA_MCLK2].id = "mclk2"; 462 madera->mclk[MADERA_MCLK3].id = "mclk3"; 463 464 ret = devm_clk_bulk_get_optional(madera->dev, ARRAY_SIZE(madera->mclk), 465 madera->mclk); 466 if (ret) { 467 dev_err(madera->dev, "Failed to get clocks: %d\n", ret); 468 return ret; 469 } 470 471 /* Not using devm_clk_get to prevent breakage of existing DTs */ 472 if (!madera->mclk[MADERA_MCLK2].clk) 473 dev_warn(madera->dev, "Missing MCLK2, requires 32kHz clock\n"); 474 475 ret = madera_get_reset_gpio(madera); 476 if (ret) 477 return ret; 478 479 regcache_cache_only(madera->regmap, true); 480 regcache_cache_only(madera->regmap_32bit, true); 481 482 for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++) 483 madera->core_supplies[i].supply = madera_core_supplies[i]; 484 485 madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies); 486 487 /* 488 * On some codecs DCVDD could be supplied by the internal LDO1. 489 * For those we must add the LDO1 driver before requesting DCVDD 490 * No devm_ because we need to control shutdown order of children. 491 */ 492 switch (madera->type) { 493 case CS47L15: 494 case CS47L35: 495 case CS47L90: 496 case CS47L91: 497 case CS42L92: 498 case CS47L92: 499 case CS47L93: 500 break; 501 case CS47L85: 502 case WM1840: 503 ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE, 504 madera_ldo1_devs, 505 ARRAY_SIZE(madera_ldo1_devs), 506 NULL, 0, NULL); 507 if (ret) { 508 dev_err(dev, "Failed to add LDO1 child: %d\n", ret); 509 return ret; 510 } 511 break; 512 default: 513 /* No point continuing if the type is unknown */ 514 dev_err(madera->dev, "Unknown device type %d\n", madera->type); 515 return -ENODEV; 516 } 517 518 ret = devm_regulator_bulk_get(dev, madera->num_core_supplies, 519 madera->core_supplies); 520 if (ret) { 521 dev_err(dev, "Failed to request core supplies: %d\n", ret); 522 goto err_devs; 523 } 524 525 /* 526 * Don't use devres here. If the regulator is one of our children it 527 * will already have been removed before devres cleanup on this mfd 528 * driver tries to call put() on it. We need control of shutdown order. 529 */ 530 madera->dcvdd = regulator_get(madera->dev, "DCVDD"); 531 if (IS_ERR(madera->dcvdd)) { 532 ret = PTR_ERR(madera->dcvdd); 533 dev_err(dev, "Failed to request DCVDD: %d\n", ret); 534 goto err_devs; 535 } 536 537 ret = regulator_bulk_enable(madera->num_core_supplies, 538 madera->core_supplies); 539 if (ret) { 540 dev_err(dev, "Failed to enable core supplies: %d\n", ret); 541 goto err_dcvdd; 542 } 543 544 ret = regulator_enable(madera->dcvdd); 545 if (ret) { 546 dev_err(dev, "Failed to enable DCVDD: %d\n", ret); 547 goto err_enable; 548 } 549 550 madera_disable_hard_reset(madera); 551 552 regcache_cache_only(madera->regmap, false); 553 regcache_cache_only(madera->regmap_32bit, false); 554 555 ret = madera_wait_for_boot_noack(madera); 556 if (ret) { 557 dev_err(madera->dev, "Device failed initial boot: %d\n", ret); 558 goto err_reset; 559 } 560 561 /* 562 * Now we can power up and verify that this is a chip we know about 563 * before we start doing any writes to its registers. 564 */ 565 ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid); 566 if (ret) { 567 dev_err(dev, "Failed to read ID register: %d\n", ret); 568 goto err_reset; 569 } 570 571 switch (hwid) { 572 case CS47L15_SILICON_ID: 573 if (IS_ENABLED(CONFIG_MFD_CS47L15)) { 574 switch (madera->type) { 575 case CS47L15: 576 patch_fn = &cs47l15_patch; 577 mfd_devs = cs47l15_devs; 578 n_devs = ARRAY_SIZE(cs47l15_devs); 579 break; 580 default: 581 break; 582 } 583 } 584 break; 585 case CS47L35_SILICON_ID: 586 if (IS_ENABLED(CONFIG_MFD_CS47L35)) { 587 switch (madera->type) { 588 case CS47L35: 589 patch_fn = cs47l35_patch; 590 mfd_devs = cs47l35_devs; 591 n_devs = ARRAY_SIZE(cs47l35_devs); 592 break; 593 default: 594 break; 595 } 596 } 597 break; 598 case CS47L85_SILICON_ID: 599 if (IS_ENABLED(CONFIG_MFD_CS47L85)) { 600 switch (madera->type) { 601 case CS47L85: 602 case WM1840: 603 patch_fn = cs47l85_patch; 604 mfd_devs = cs47l85_devs; 605 n_devs = ARRAY_SIZE(cs47l85_devs); 606 break; 607 default: 608 break; 609 } 610 } 611 break; 612 case CS47L90_SILICON_ID: 613 if (IS_ENABLED(CONFIG_MFD_CS47L90)) { 614 switch (madera->type) { 615 case CS47L90: 616 case CS47L91: 617 patch_fn = cs47l90_patch; 618 mfd_devs = cs47l90_devs; 619 n_devs = ARRAY_SIZE(cs47l90_devs); 620 break; 621 default: 622 break; 623 } 624 } 625 break; 626 case CS47L92_SILICON_ID: 627 if (IS_ENABLED(CONFIG_MFD_CS47L92)) { 628 switch (madera->type) { 629 case CS42L92: 630 case CS47L92: 631 case CS47L93: 632 patch_fn = cs47l92_patch; 633 mfd_devs = cs47l92_devs; 634 n_devs = ARRAY_SIZE(cs47l92_devs); 635 break; 636 default: 637 break; 638 } 639 } 640 break; 641 default: 642 dev_err(madera->dev, "Unknown device ID: %x\n", hwid); 643 ret = -EINVAL; 644 goto err_reset; 645 } 646 647 if (!n_devs) { 648 dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid, 649 madera->type_name); 650 ret = -ENODEV; 651 goto err_reset; 652 } 653 654 /* 655 * It looks like a device we support. If we don't have a hard reset 656 * we can now attempt a soft reset. 657 */ 658 if (!madera->pdata.reset) { 659 ret = madera_soft_reset(madera); 660 if (ret) 661 goto err_reset; 662 } 663 664 ret = madera_wait_for_boot(madera); 665 if (ret) { 666 dev_err(madera->dev, "Failed to clear boot done: %d\n", ret); 667 goto err_reset; 668 } 669 670 ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION, 671 &madera->rev); 672 if (ret) { 673 dev_err(dev, "Failed to read revision register: %d\n", ret); 674 goto err_reset; 675 } 676 madera->rev &= MADERA_HW_REVISION_MASK; 677 678 dev_info(dev, "%s silicon revision %d\n", madera->type_name, 679 madera->rev); 680 681 /* Apply hardware patch */ 682 if (patch_fn) { 683 ret = patch_fn(madera); 684 if (ret) { 685 dev_err(madera->dev, "Failed to apply patch %d\n", ret); 686 goto err_reset; 687 } 688 } 689 690 /* Init 32k clock sourced from MCLK2 */ 691 ret = clk_prepare_enable(madera->mclk[MADERA_MCLK2].clk); 692 if (ret) { 693 dev_err(madera->dev, "Failed to enable 32k clock: %d\n", ret); 694 goto err_reset; 695 } 696 697 ret = regmap_update_bits(madera->regmap, 698 MADERA_CLOCK_32K_1, 699 MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK, 700 MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2); 701 if (ret) { 702 dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret); 703 goto err_clock; 704 } 705 706 pm_runtime_set_active(madera->dev); 707 pm_runtime_enable(madera->dev); 708 pm_runtime_set_autosuspend_delay(madera->dev, 100); 709 pm_runtime_use_autosuspend(madera->dev); 710 711 /* No devm_ because we need to control shutdown order of children */ 712 ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE, 713 mfd_devs, n_devs, 714 NULL, 0, NULL); 715 if (ret) { 716 dev_err(madera->dev, "Failed to add subdevices: %d\n", ret); 717 goto err_pm_runtime; 718 } 719 720 return 0; 721 722 err_pm_runtime: 723 pm_runtime_disable(madera->dev); 724 err_clock: 725 clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk); 726 err_reset: 727 madera_enable_hard_reset(madera); 728 regulator_disable(madera->dcvdd); 729 err_enable: 730 regulator_bulk_disable(madera->num_core_supplies, 731 madera->core_supplies); 732 err_dcvdd: 733 regulator_put(madera->dcvdd); 734 err_devs: 735 mfd_remove_devices(dev); 736 737 return ret; 738 } 739 EXPORT_SYMBOL_GPL(madera_dev_init); 740 741 int madera_dev_exit(struct madera *madera) 742 { 743 /* Prevent any IRQs being serviced while we clean up */ 744 disable_irq(madera->irq); 745 746 /* 747 * DCVDD could be supplied by a child node, we must disable it before 748 * removing the children, and prevent PM runtime from turning it back on 749 */ 750 pm_runtime_disable(madera->dev); 751 752 clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk); 753 754 regulator_disable(madera->dcvdd); 755 regulator_put(madera->dcvdd); 756 757 mfd_remove_devices(madera->dev); 758 madera_enable_hard_reset(madera); 759 760 regulator_bulk_disable(madera->num_core_supplies, 761 madera->core_supplies); 762 return 0; 763 } 764 EXPORT_SYMBOL_GPL(madera_dev_exit); 765 766 MODULE_DESCRIPTION("Madera core MFD driver"); 767 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 768 MODULE_LICENSE("GPL v2"); 769