diff mbox

[RFC] ARM: shmobile: R-Car Gen2: Add da9063/da9210 regulator quirk

Message ID 1425317323-5898-1-git-send-email-geert+renesas@glider.be (mailing list archive)
State Superseded
Headers show

Commit Message

Geert Uytterhoeven March 2, 2015, 5:28 p.m. UTC
The r8a7791/koelsch development board has da9063 and da9210 regulators.
Both regulators have their interrupt request lines tied to the same
interrupt pin (IRQ2) on the SoC.

After boot-up, both the da9063 and da9210 seem to assert their interrupt
request lines.  Hence as soon as one driver requests this irq, it gets
stuck in an interrupt storm, as it only manages to deassert its own
interrupt request line, and the other driver hasn't installed an
interrupt handler yet.

To handle this, install a quirk that masks the interrupts in both the
da9063 and da9210.  This quirk has to run after the i2c master driver
has been initialized, but before the i2c slave drivers are initialized.

On koelsch, the following happens:

  - Cold boot or reboot using the da9063 restart handler:

	IRQ2 is asserted, installing da9063/da9210 regulator quirk
	...
	i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
	i2c 6-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
	i2c 6-0058: Detected da9063
	i2c 6-0058: Masking da9063 interrupt sources
	i2c 6-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
	i2c 6-0068: Detected da9210
	i2c 6-0068: Masking da9210 interrupt sources
	i2c 6-0068: IRQ2 is not asserted, removing quirk

  - Warm boot (reset button):

	rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk

Not-yet-signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Based on the schematics, I believe r8a7790/lager is also affected.

I do not have schematics for r8a7793/gose, but according to the BSP, it
has both da9210 and da9063, so most probably it's also affected.

Other R-Car Gen2 boards (r8a7791/henninger, r8a7791/porter, r8a7794/alt,
r8a7794/silk) may only have the da9063. They are affected if the da9063
interrupt line is shared with another device.

This patch, against renesas-devel-20150301-v4.0-rc1, includes DTS
updates for koelsch and lager to allow testing.
To test on other boards, you'll have to add the nodes for the regulators
to the right i2c buses yourselves. These can be fairly minimal
("compatible" and "reg" should suffice).

Testing on other R-Car Gen2 platforms would be highly appreciated.
Thanks!

References:
  - "ARM: shmobile: koelsch: da9210/da9063 interrupt storm (was: Re:
    [PATCH 3/4] ARM: shmobile: koelsch: Add DA9063 PMIC device node for
    system restart") (https://lkml.org/lkml/2015/2/17/254),
  - "[PATCH/RFC 1/2] regulator: da9210: Mask all interrupt sources to
    deassert interrupt line" (https://lkml.org/lkml/2015/2/17/274)
  - "[PATCH/RFC 2/2] regulator: da9210: Add optional interrupt support"
    (https://lkml.org/lkml/2015/2/17/275)
---
 arch/arm/boot/dts/r8a7790-lager.dts      |  18 ++++
 arch/arm/boot/dts/r8a7791-koelsch.dts    |  18 ++++
 arch/arm/mach-shmobile/setup-rcar-gen2.c | 152 +++++++++++++++++++++++++++++++
 3 files changed, 188 insertions(+)

Comments

Wolfram Sang March 2, 2015, 6:32 p.m. UTC | #1
Hi Geert,

On Mon, Mar 02, 2015 at 06:28:43PM +0100, Geert Uytterhoeven wrote:
> The r8a7791/koelsch development board has da9063 and da9210 regulators.
> Both regulators have their interrupt request lines tied to the same
> interrupt pin (IRQ2) on the SoC.
> 
> After boot-up, both the da9063 and da9210 seem to assert their interrupt
> request lines.  Hence as soon as one driver requests this irq, it gets
> stuck in an interrupt storm, as it only manages to deassert its own
> interrupt request line, and the other driver hasn't installed an
> interrupt handler yet.
> 
> To handle this, install a quirk that masks the interrupts in both the
> da9063 and da9210.  This quirk has to run after the i2c master driver
> has been initialized, but before the i2c slave drivers are initialized.
> 
> On koelsch, the following happens:
> 
>   - Cold boot or reboot using the da9063 restart handler:
> 
> 	IRQ2 is asserted, installing da9063/da9210 regulator quirk
> 	...
> 	i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
> 	i2c 6-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
> 	i2c 6-0058: Detected da9063
> 	i2c 6-0058: Masking da9063 interrupt sources
> 	i2c 6-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
> 	i2c 6-0068: Detected da9210
> 	i2c 6-0068: Masking da9210 interrupt sources
> 	i2c 6-0068: IRQ2 is not asserted, removing quirk
> 
>   - Warm boot (reset button):
> 
> 	rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk
> 
> Not-yet-signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> Based on the schematics, I believe r8a7790/lager is also affected.

Boot log from Lager (cold boot & watchdog reboot):

[    0.117037] IRQ2 is asserted, installing da9063/da9210 regulator quirk
[    0.162803] i2c i2c-4: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.163050] i2c-sh_mobile e6500000.i2c: I2C adapter 4, bus speed 100000 Hz
[    0.164283] i2c i2c-5: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.164481] i2c-sh_mobile e6510000.i2c: I2C adapter 5, bus speed 100000 Hz
[    0.165836] i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.166352] i2c 6-0012: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.166425] i2c 6-0012: Detected ak4643
[    0.166891] i2c 6-0020: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.166963] i2c 6-0020: Detected adv7180
[    0.167421] i2c 6-0039: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.167494] i2c 6-0039: Detected adv7511w
[    0.167630] i2c-sh_mobile e6520000.i2c: I2C adapter 6, bus speed 100000 Hz
[    0.168805] i2c i2c-7: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.169343] i2c 7-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.169415] i2c 7-0058: Detected da9063
[    0.169479] i2c 7-0058: Masking da9063 interrupt sources
[    0.175641] i2c 7-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
[    0.175715] i2c 7-0068: Detected da9210
[    0.175778] i2c 7-0068: Masking da9210 interrupt sources
[    0.176757] i2c 7-0068: IRQ2 is not asserted, removing quirk

Reboot using reset:

[    0.117819] rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk

So, not surprisingly, no difference to Koelsch. For completeness, I disabled
installing the notifier and got the interrupt storm again. So:

Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

> +#ifdef CONFIG_I2C

Is it a realistic scenario that I2C and slave drivers are modules?

> +static int regulator_quirk_notify(struct notifier_block *nb,
> +				  unsigned long action, void *data);

This forward declaration can be skipped...

> +
> +static struct notifier_block regulator_quirk_nb = {
> +	.notifier_call = regulator_quirk_notify
> +};

... if you move this after the notfier function.

Other than that the code looks okay to me (given that this is a quirk
workaround).

Regards,

   Wolfram
Geert Uytterhoeven March 2, 2015, 8:49 p.m. UTC | #2
Hi Wolfram,

On Mon, Mar 2, 2015 at 7:32 PM, Wolfram Sang <wsa@the-dreams.de> wrote:
> On Mon, Mar 02, 2015 at 06:28:43PM +0100, Geert Uytterhoeven wrote:
>> The r8a7791/koelsch development board has da9063 and da9210 regulators.
>> Both regulators have their interrupt request lines tied to the same
>> interrupt pin (IRQ2) on the SoC.
>>
>> After boot-up, both the da9063 and da9210 seem to assert their interrupt
>> request lines.  Hence as soon as one driver requests this irq, it gets
>> stuck in an interrupt storm, as it only manages to deassert its own
>> interrupt request line, and the other driver hasn't installed an
>> interrupt handler yet.
>>
>> To handle this, install a quirk that masks the interrupts in both the
>> da9063 and da9210.  This quirk has to run after the i2c master driver
>> has been initialized, but before the i2c slave drivers are initialized.
>>
>> On koelsch, the following happens:
>>
>>   - Cold boot or reboot using the da9063 restart handler:
>>
>>       IRQ2 is asserted, installing da9063/da9210 regulator quirk
>>       ...
>>       i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
>>       i2c 6-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
>>       i2c 6-0058: Detected da9063
>>       i2c 6-0058: Masking da9063 interrupt sources
>>       i2c 6-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
>>       i2c 6-0068: Detected da9210
>>       i2c 6-0068: Masking da9210 interrupt sources
>>       i2c 6-0068: IRQ2 is not asserted, removing quirk
>>
>>   - Warm boot (reset button):
>>
>>       rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk
>>
>> Not-yet-signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>> ---
>> Based on the schematics, I believe r8a7790/lager is also affected.
>
> Boot log from Lager (cold boot & watchdog reboot):
>
> [    0.117037] IRQ2 is asserted, installing da9063/da9210 regulator quirk
> [    0.162803] i2c i2c-4: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.163050] i2c-sh_mobile e6500000.i2c: I2C adapter 4, bus speed 100000 Hz
> [    0.164283] i2c i2c-5: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.164481] i2c-sh_mobile e6510000.i2c: I2C adapter 5, bus speed 100000 Hz
> [    0.165836] i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.166352] i2c 6-0012: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.166425] i2c 6-0012: Detected ak4643
> [    0.166891] i2c 6-0020: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.166963] i2c 6-0020: Detected adv7180
> [    0.167421] i2c 6-0039: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.167494] i2c 6-0039: Detected adv7511w
> [    0.167630] i2c-sh_mobile e6520000.i2c: I2C adapter 6, bus speed 100000 Hz
> [    0.168805] i2c i2c-7: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.169343] i2c 7-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.169415] i2c 7-0058: Detected da9063
> [    0.169479] i2c 7-0058: Masking da9063 interrupt sources
> [    0.175641] i2c 7-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> [    0.175715] i2c 7-0068: Detected da9210
> [    0.175778] i2c 7-0068: Masking da9210 interrupt sources
> [    0.176757] i2c 7-0068: IRQ2 is not asserted, removing quirk
>
> Reboot using reset:
>
> [    0.117819] rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk
>
> So, not surprisingly, no difference to Koelsch. For completeness, I disabled
> installing the notifier and got the interrupt storm again. So:
>
> Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thanks for testing!

>> +#ifdef CONFIG_I2C
>
> Is it a realistic scenario that I2C and slave drivers are modules?

Yes.

Unfortunately that's more difficult to support, as the code references
i2c_bus_type and i2c_adapter_type.

i2c_bus_type is needed to register the notifier.
i2c_adapter_type is needed to distinguish between i2c adapters and clients,
as the notifier is called for both with action BUS_NOTIFY_ADD_DEVICE.

>> +static int regulator_quirk_notify(struct notifier_block *nb,
>> +                               unsigned long action, void *data);
>
> This forward declaration can be skipped...
>
>> +
>> +static struct notifier_block regulator_quirk_nb = {
>> +     .notifier_call = regulator_quirk_notify
>> +};
>
> ... if you move this after the notfier function.

regulator_quirk_nb and regulator_quirk_notify reference each other.
But regulator_quirk_notify() can probably just use the passed
struct notifier_block pointer. Will fix.

> Other than that the code looks okay to me (given that this is a quirk
> workaround).

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Simon Horman March 2, 2015, 10:44 p.m. UTC | #3
On Mon, Mar 02, 2015 at 09:49:11PM +0100, Geert Uytterhoeven wrote:
> Hi Wolfram,
> 
> On Mon, Mar 2, 2015 at 7:32 PM, Wolfram Sang <wsa@the-dreams.de> wrote:
> > On Mon, Mar 02, 2015 at 06:28:43PM +0100, Geert Uytterhoeven wrote:
> >> The r8a7791/koelsch development board has da9063 and da9210 regulators.
> >> Both regulators have their interrupt request lines tied to the same
> >> interrupt pin (IRQ2) on the SoC.
> >>
> >> After boot-up, both the da9063 and da9210 seem to assert their interrupt
> >> request lines.  Hence as soon as one driver requests this irq, it gets
> >> stuck in an interrupt storm, as it only manages to deassert its own
> >> interrupt request line, and the other driver hasn't installed an
> >> interrupt handler yet.
> >>
> >> To handle this, install a quirk that masks the interrupts in both the
> >> da9063 and da9210.  This quirk has to run after the i2c master driver
> >> has been initialized, but before the i2c slave drivers are initialized.
> >>
> >> On koelsch, the following happens:
> >>
> >>   - Cold boot or reboot using the da9063 restart handler:
> >>
> >>       IRQ2 is asserted, installing da9063/da9210 regulator quirk
> >>       ...
> >>       i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
> >>       i2c 6-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
> >>       i2c 6-0058: Detected da9063
> >>       i2c 6-0058: Masking da9063 interrupt sources
> >>       i2c 6-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb
> >>       i2c 6-0068: Detected da9210
> >>       i2c 6-0068: Masking da9210 interrupt sources
> >>       i2c 6-0068: IRQ2 is not asserted, removing quirk
> >>
> >>   - Warm boot (reset button):
> >>
> >>       rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk
> >>
> >> Not-yet-signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> >> ---
> >> Based on the schematics, I believe r8a7790/lager is also affected.
> >
> > Boot log from Lager (cold boot & watchdog reboot):
> >
> > [    0.117037] IRQ2 is asserted, installing da9063/da9210 regulator quirk
> > [    0.162803] i2c i2c-4: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.163050] i2c-sh_mobile e6500000.i2c: I2C adapter 4, bus speed 100000 Hz
> > [    0.164283] i2c i2c-5: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.164481] i2c-sh_mobile e6510000.i2c: I2C adapter 5, bus speed 100000 Hz
> > [    0.165836] i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.166352] i2c 6-0012: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.166425] i2c 6-0012: Detected ak4643
> > [    0.166891] i2c 6-0020: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.166963] i2c 6-0020: Detected adv7180
> > [    0.167421] i2c 6-0039: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.167494] i2c 6-0039: Detected adv7511w
> > [    0.167630] i2c-sh_mobile e6520000.i2c: I2C adapter 6, bus speed 100000 Hz
> > [    0.168805] i2c i2c-7: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.169343] i2c 7-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.169415] i2c 7-0058: Detected da9063
> > [    0.169479] i2c 7-0058: Masking da9063 interrupt sources
> > [    0.175641] i2c 7-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0xb
> > [    0.175715] i2c 7-0068: Detected da9210
> > [    0.175778] i2c 7-0068: Masking da9210 interrupt sources
> > [    0.176757] i2c 7-0068: IRQ2 is not asserted, removing quirk
> >
> > Reboot using reset:
> >
> > [    0.117819] rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk
> >
> > So, not surprisingly, no difference to Koelsch. For completeness, I disabled
> > installing the notifier and got the interrupt storm again. So:
> >
> > Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> 
> Thanks for testing!
> 
> >> +#ifdef CONFIG_I2C
> >
> > Is it a realistic scenario that I2C and slave drivers are modules?
> 
> Yes.
> 
> Unfortunately that's more difficult to support, as the code references
> i2c_bus_type and i2c_adapter_type.
> 
> i2c_bus_type is needed to register the notifier.
> i2c_adapter_type is needed to distinguish between i2c adapters and clients,
> as the notifier is called for both with action BUS_NOTIFY_ADD_DEVICE.
> 
> >> +static int regulator_quirk_notify(struct notifier_block *nb,
> >> +                               unsigned long action, void *data);
> >
> > This forward declaration can be skipped...
> >
> >> +
> >> +static struct notifier_block regulator_quirk_nb = {
> >> +     .notifier_call = regulator_quirk_notify
> >> +};
> >
> > ... if you move this after the notfier function.
> 
> regulator_quirk_nb and regulator_quirk_notify reference each other.
> But regulator_quirk_notify() can probably just use the passed
> struct notifier_block pointer. Will fix.
> 
> > Other than that the code looks okay to me (given that this is a quirk
> > workaround).

Hi Geert,

this seems reasonable enough to me, however, I'd like to let it hang out
for a bit longer to see if there is any further review. To that end could
you consider posting a non-RFC version for review if you wish to pursue
this approach further?
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Geert Uytterhoeven March 3, 2015, 9:37 a.m. UTC | #4
Hi Simon,

On Mon, Mar 2, 2015 at 11:44 PM, Simon Horman <horms@verge.net.au> wrote:
> On Mon, Mar 02, 2015 at 09:49:11PM +0100, Geert Uytterhoeven wrote:
>> On Mon, Mar 2, 2015 at 7:32 PM, Wolfram Sang <wsa@the-dreams.de> wrote:
>> > On Mon, Mar 02, 2015 at 06:28:43PM +0100, Geert Uytterhoeven wrote:
>> >> The r8a7791/koelsch development board has da9063 and da9210 regulators.
>> >> Both regulators have their interrupt request lines tied to the same
>> >> interrupt pin (IRQ2) on the SoC.
>> >>
>> >> After boot-up, both the da9063 and da9210 seem to assert their interrupt
>> >> request lines.  Hence as soon as one driver requests this irq, it gets
>> >> stuck in an interrupt storm, as it only manages to deassert its own
>> >> interrupt request line, and the other driver hasn't installed an
>> >> interrupt handler yet.
>> >>
>> >> To handle this, install a quirk that masks the interrupts in both the
>> >> da9063 and da9210.  This quirk has to run after the i2c master driver
>> >> has been initialized, but before the i2c slave drivers are initialized.

>> >> +#ifdef CONFIG_I2C
>> >
>> > Is it a realistic scenario that I2C and slave drivers are modules?
>>
>> Yes.
>>
>> Unfortunately that's more difficult to support, as the code references
>> i2c_bus_type and i2c_adapter_type.
>>
>> i2c_bus_type is needed to register the notifier.
>> i2c_adapter_type is needed to distinguish between i2c adapters and clients,
>> as the notifier is called for both with action BUS_NOTIFY_ADD_DEVICE.

Given we already have a few "select I2C" under arch/arm, I guess it won't
hurt much to let ARCH_R8A7790 and ARCH_R8A7791 select I2C, too.

> this seems reasonable enough to me, however, I'd like to let it hang out
> for a bit longer to see if there is any further review. To that end could
> you consider posting a non-RFC version for review if you wish to pursue
> this approach further?

Sure, will do after a bit of more cooking, and updating with the findings of
more test results, if needed.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Brown March 3, 2015, 9:44 a.m. UTC | #5
On Mon, Mar 02, 2015 at 06:28:43PM +0100, Geert Uytterhoeven wrote:
> The r8a7791/koelsch development board has da9063 and da9210 regulators.
> Both regulators have their interrupt request lines tied to the same
> interrupt pin (IRQ2) on the SoC.

Reviewed-by: Mark Brown <broonie@kernel.org>

This is all rather fun isn't it?
Simon Horman March 7, 2015, 1:05 a.m. UTC | #6
On Tue, Mar 03, 2015 at 09:44:06AM +0000, Mark Brown wrote:
> On Mon, Mar 02, 2015 at 06:28:43PM +0100, Geert Uytterhoeven wrote:
> > The r8a7791/koelsch development board has da9063 and da9210 regulators.
> > Both regulators have their interrupt request lines tied to the same
> > interrupt pin (IRQ2) on the SoC.
> 
> Reviewed-by: Mark Brown <broonie@kernel.org>
> 
> This is all rather fun isn't it?

Hi Geert,

please repost this with Mark's Ack as a non-RFC if you would like me
to pick it up.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 329bb994aac04084..aaa4f258e279ccfa 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -582,9 +582,27 @@ 
 	pinctrl-0 = <&iic3_pins>;
 	status = "okay";
 
+	pmic@58 {
+		compatible = "dlg,da9063";
+		reg = <0x58>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+
+		rtc {
+			compatible = "dlg,da9063-rtc";
+		};
+
+		wdt {
+			compatible = "dlg,da9063-watchdog";
+		};
+	};
+
 	vdd_dvfs: regulator@68 {
 		compatible = "dlg,da9210";
 		reg = <0x68>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 
 		regulator-min-microvolt = <1000000>;
 		regulator-max-microvolt = <1000000>;
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 75fa9852e235455c..74c3212f1f11e47e 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -584,9 +584,27 @@ 
 	status = "okay";
 	clock-frequency = <100000>;
 
+	pmic@58 {
+		compatible = "dlg,da9063";
+		reg = <0x58>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+
+		rtc {
+			compatible = "dlg,da9063-rtc";
+		};
+
+		wdt {
+			compatible = "dlg,da9063-watchdog";
+		};
+	};
+
 	vdd_dvfs: regulator@68 {
 		compatible = "dlg,da9210";
 		reg = <0x68>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 
 		regulator-min-microvolt = <1000000>;
 		regulator-max-microvolt = <1000000>;
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index 5d13595aa027447d..71700ad7e2d24b74 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -1,3 +1,4 @@ 
+#define DEBUG
 /*
  * R-Car Generation 2 support
  *
@@ -19,9 +20,12 @@ 
 #include <linux/clocksource.h>
 #include <linux/device.h>
 #include <linux/dma-contiguous.h>
+#include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/memblock.h>
+#include <linux/mfd/da9063/registers.h>
+#include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <asm/mach/arch.h>
@@ -201,3 +205,151 @@  void __init rcar_gen2_reserve(void)
 					    &rcar_gen2_dma_contiguous, true);
 #endif
 }
+
+
+#ifdef CONFIG_I2C
+
+/*
+ *  The r8a7791/koelsch (and FIXME) development boards have da9210 and da9063
+ *  regulators.  Both regulators have their interrupt request lines tied to the
+ *  same interrupt pin (IRQ2) on the SoC.
+ *
+ *  After boot-up, both the da9210 and da9063 seem to assert their interrupt
+ *  request lines.  Hence as soon as one driver requests this irq, it gets
+ *  stuck in an interrupt storm, as it only manages to deassert its own
+ *  interrupt request line, and the other driver hasn't installed an interrupt
+ *  handler yet.
+ *
+ *  To handle this, install a quirk that masks the interrupts in both the
+ *  da9210 and da9063.  This quirk has to run after the i2c master driver has
+ *  been initialized, but before the i2c slave drivers are initialized.
+ */
+
+#define IRQC_BASE		0xe61c0000
+#define IRQC_MONITOR		0x104	/* IRQn Signal Level Monitor Register */
+
+#define REGULATOR_IRQ_MASK	BIT(2)	/* IRQ2, active low */
+
+static void __iomem *irqc;
+
+
+/* DA9210 System Control and Event Registers */
+#define DA9210_REG_MASK_A		0x54
+#define DA9210_REG_MASK_B		0x55
+
+static const u8 da9063_mask_regs[] = {
+	DA9063_REG_IRQ_MASK_A,
+	DA9063_REG_IRQ_MASK_B,
+	DA9063_REG_IRQ_MASK_C,
+	DA9063_REG_IRQ_MASK_D,
+};
+
+static const u8 da9210_mask_regs[] = {
+	DA9210_REG_MASK_A,
+	DA9210_REG_MASK_B,
+};
+
+static void da9xxx_mask_irqs(struct i2c_client *client, const u8 regs[],
+			     unsigned int nregs)
+{
+	unsigned int i;
+
+	dev_info(&client->dev, "Masking %s interrupt sources\n", client->name);
+
+	for (i = 0; i < nregs; i++) {
+		int error = i2c_smbus_write_byte_data(client, regs[i], ~0);
+		if (error) {
+			dev_err(&client->dev, "i2c error %d\n", error);
+			return;
+		}
+	}
+}
+
+static int regulator_quirk_notify(struct notifier_block *nb,
+				  unsigned long action, void *data);
+
+static struct notifier_block regulator_quirk_nb = {
+	.notifier_call = regulator_quirk_notify
+};
+
+static int regulator_quirk_notify(struct notifier_block *nb,
+				  unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct i2c_client *client;
+	int error;
+	u32 mon;
+
+	mon = ioread32(irqc + IRQC_MONITOR);
+	dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon);
+	if (mon & REGULATOR_IRQ_MASK)
+		goto remove;
+
+	if (action != BUS_NOTIFY_ADD_DEVICE || dev->type == &i2c_adapter_type)
+		return 0;
+
+	client = to_i2c_client(dev);
+	dev_dbg(dev, "Detected %s\n", client->name);
+
+	if ((client->addr == 0x58 && !strcmp(client->name, "da9063")))
+		da9xxx_mask_irqs(client, da9063_mask_regs,
+				 ARRAY_SIZE(da9063_mask_regs));
+	else if (client->addr == 0x68 && !strcmp(client->name, "da9210"))
+		da9xxx_mask_irqs(client, da9210_mask_regs,
+				 ARRAY_SIZE(da9210_mask_regs));
+
+	mon = ioread32(irqc + IRQC_MONITOR);
+	if (mon & REGULATOR_IRQ_MASK)
+		goto remove;
+
+	return 0;
+
+remove:
+	dev_info(dev, "IRQ2 is not asserted, removing quirk\n");
+	iounmap(irqc);
+
+	error = bus_unregister_notifier(&i2c_bus_type, &regulator_quirk_nb);
+	if (error)
+		pr_err("%s: Failed to unregister bus notifier: %d\n", __func__,
+		       error);
+	return 0;
+}
+
+static int __init rcar_gen2_regulator_quirk(void)
+{
+	u32 mon;
+	int error;
+
+	// FIXME Use list of affected boards
+	if (!of_machine_is_compatible("renesas,koelsch") &&
+	    !of_machine_is_compatible("renesas,r8a7790") &&
+	    !of_machine_is_compatible("renesas,r8a7791") &&
+	    !of_machine_is_compatible("renesas,r8a7792") &&
+	    !of_machine_is_compatible("renesas,r8a7793") &&
+	    !of_machine_is_compatible("renesas,r8a7794"))
+		return -ENODEV;
+
+	irqc = ioremap(IRQC_BASE, PAGE_SIZE);
+	if (!irqc)
+		return -ENOMEM;
+
+	mon = ioread32(irqc + IRQC_MONITOR);
+	if (mon & REGULATOR_IRQ_MASK) {
+		pr_debug("%s: IRQ2 is not asserted, not installing quirk\n",
+			 __func__);
+		iounmap(irqc);
+		return 0;
+	}
+
+	pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n");
+
+	error = bus_register_notifier(&i2c_bus_type, &regulator_quirk_nb);
+	if (error)
+		pr_err("%s: Failed to register bus notifier: %d\n", __func__,
+		       error);
+
+	return error;
+}
+
+arch_initcall(rcar_gen2_regulator_quirk);
+#endif /* CONFIG_I2C */