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