Message ID | 1425317323-5898-1-git-send-email-geert+renesas@glider.be (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
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
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
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
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
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?
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 --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, ®ulator_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, ®ulator_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 */