From d980e0f8d858c6963d676013e976ff00ab7acb2b Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 09:42:11 +0000 Subject: ARM: omap: fix oops in arch/arm/mach-omap2/vp.c when pmic is not found When the PMIC is not found, voltdm->pmic will be NULL. vp.c's initialization function tries to dereferences this, which causes an oops: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT Modules linked in: CPU: 0 Not tainted (3.3.0-rc2+ #204) PC is at omap_vp_init+0x5c/0x15c LR is at omap_vp_init+0x58/0x15c pc : [] lr : [] psr: 60000013 sp : c181ff30 ip : c181ff68 fp : c181ff64 r10: c0407808 r9 : c040786c r8 : c0407814 r7 : c0026868 r6 : c00264fc r5 : c040ad6c r4 : 00000000 r3 : 00000040 r2 : 000032c8 r1 : 0000fa00 r0 : 000032c8 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 80004019 DAC: 00000015 Process swapper (pid: 1, stack limit = 0xc181e2e8) Stack: (0xc181ff30 to 0xc1820000) ff20: c0381d00 c02e9c6d c0383582 c040786c ff40: c040ad6c c00264fc c0026868 c0407814 00000000 c03d9de4 c181ff8c c181ff68 ff60: c03db448 c03db830 c02e982c c03fdfb8 c03fe004 c0039988 00000013 00000000 ff80: c181ff9c c181ff90 c03d9df8 c03db390 c181ffdc c181ffa0 c0008798 c03d9df0 ffa0: c181ffc4 c181ffb0 c0055a44 c0187050 c0039988 c03fdfb8 c03fe004 c0039988 ffc0: 00000013 00000000 00000000 00000000 c181fff4 c181ffe0 c03d1284 c0008708 ffe0: 00000000 c03d1208 00000000 c181fff8 c0039988 c03d1214 1077ce40 01f7ee08 Backtrace: [] (omap_vp_init+0x0/0x15c) from [] (omap_voltage_late_init+0xc4/0xfc) [] (omap_voltage_late_init+0x0/0xfc) from [] (omap2_common_pm_late_init+0x14/0x54) r8:00000000 r7:00000013 r6:c0039988 r5:c03fe004 r4:c03fdfb8 [] (omap2_common_pm_late_init+0x0/0x54) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x7c/0x120) [] (kernel_init+0x0/0x120) from [] (do_exit+0x0/0x2cc) r5:c03d1208 r4:00000000 Code: e5ca300b e5900034 ebf69027 e5994024 (e5941000) ---[ end trace aed617dddaf32c3d ]--- Kernel panic - not syncing: Attempted to kill init! Signed-off-by: Russell King --- arch/arm/mach-omap2/vp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 807391d84a9dcd..0df88820978d5d 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -41,6 +41,11 @@ void __init omap_vp_init(struct voltagedomain *voltdm) u32 val, sys_clk_rate, timeout, waittime; u32 vddmin, vddmax, vstepmin, vstepmax; + if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { + pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name); + return; + } + if (!voltdm->read || !voltdm->write) { pr_err("%s: No read/write API for accessing vdd_%s regs\n", __func__, voltdm->name); -- cgit 1.2.3-korg From 40410715715178ec196314dd0c19150c06901f80 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 09:44:55 +0000 Subject: ARM: omap: fix oops in drivers/video/omap2/dss/dpi.c When a PMIC is not found, this driver is unable to obtain its 'vdds_dsi_reg' regulator. Even through its initialization function fails, other code still calls its enable function, which fails to check whether it has this regulator before asking for it to be enabled. This fixes the oops, however a better fix would be to sort out the upper layers to prevent them calling into a module which failed to initialize. Unable to handle kernel NULL pointer dereference at virtual address 00000038 pgd = c0004000 [00000038] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT Modules linked in: CPU: 0 Not tainted (3.3.0-rc2+ #228) PC is at regulator_enable+0x10/0x70 LR is at omapdss_dpi_display_enable+0x54/0x15c pc : [] lr : [] psr: 60000013 sp : c181fd90 ip : c181fdb0 fp : c181fdac r10: c042eff0 r9 : 00000060 r8 : c044a164 r7 : c042c0e4 r6 : c042bd60 r5 : 00000000 r4 : c042bd60 r3 : c084de48 r2 : c181e000 r1 : c042bd60 r0 : 00000000 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 80004019 DAC: 00000015 Process swapper (pid: 1, stack limit = 0xc181e2e8) Stack: (0xc181fd90 to 0xc1820000) fd80: c001754c c042bd60 00000000 c042bd60 fda0: c181fdcc c181fdb0 c01af994 c01b9a04 c0016104 c042bd60 c042bd60 c044a338 fdc0: c181fdec c181fdd0 c01b5ed0 c01af94c c042bd60 c042bd60 c1aa8000 c1aa8a0c fde0: c181fe04 c181fdf0 c01b5f54 c01b5ea8 c02fc18c c042bd60 c181fe3c c181fe08 fe00: c01b2a18 c01b5f48 c01aed14 c02fc160 c01df8ec 00000002 c042bd60 00000003 fe20: c042bd60 c1aa8000 c1aa8a0c c042eff8 c181fe84 c181fe40 c01b3874 c01b29fc fe40: c042eff8 00000000 c042f000 c0449db8 c044ed78 00000000 c181fe74 c042eff8 fe60: c042eff8 c0449db8 c0449db8 c044ed78 00000000 00000000 c181fe94 c181fe88 fe80: c01e452c c01b35e8 c181feb4 c181fe98 c01e2fdc c01e4518 c042eff8 c0449db8 fea0: c0449db8 c181fef0 c181fecc c181feb8 c01e3104 c01e2f48 c042eff8 c042f02c fec0: c181feec c181fed0 c01e3190 c01e30c0 c01e311c 00000000 c01e311c c0449db8 fee0: c181ff14 c181fef0 c01e1998 c01e3128 c18330a8 c1892290 c04165e8 c0449db8 ff00: c0449db8 c1ab60c0 c181ff24 c181ff18 c01e2e28 c01e194c c181ff54 c181ff28 ff20: c01e2218 c01e2e14 c039afed c181ff38 c04165e8 c041660c c0449db8 00000013 ff40: 00000000 c03ffdb8 c181ff7c c181ff58 c01e384c c01e217c c181ff7c c04165e8 ff60: c041660c c003a37c 00000013 00000000 c181ff8c c181ff80 c01e488c c01e3790 ff80: c181ff9c c181ff90 c03ffdcc c01e484c c181ffdc c181ffa0 c0008798 c03ffdc4 ffa0: c181ffc4 c181ffb0 c0056440 c0187810 c003a37c c04165e8 c041660c c003a37c ffc0: 00000013 00000000 00000000 00000000 c181fff4 c181ffe0 c03ea284 c0008708 ffe0: 00000000 c03ea208 00000000 c181fff8 c003a37c c03ea214 1073cec0 01f7ee08 Backtrace: [] (regulator_enable+0x0/0x70) from [] (omapdss_dpi_display_enable+0x54/0x15c) r6:c042bd60 r5:00000000 r4:c042bd60 [] (omapdss_dpi_display_enable+0x0/0x15c) from [] (generic_dpi_panel_power_on+0x34/0x78) r6:c044a338 r5:c042bd60 r4:c042bd60 [] (generic_dpi_panel_power_on+0x0/0x78) from [] (generic_dpi_panel_enable+0x18/0x28) r7:c1aa8a0c r6:c1aa8000 r5:c042bd60 r4:c042bd60 [] (generic_dpi_panel_enable+0x0/0x28) from [] (omapfb_init_display+0x28/0x150) r4:c042bd60 [] (omapfb_init_display+0x0/0x150) from [] (omapfb_probe+0x298/0x318) r8:c042eff8 r7:c1aa8a0c r6:c1aa8000 r5:c042bd60 r4:00000003 [] (omapfb_probe+0x0/0x318) from [] (platform_drv_probe+0x20/0x24) [] (platform_drv_probe+0x0/0x24) from [] (really_probe+0xa0/0x178) [] (really_probe+0x0/0x178) from [] (driver_probe_device+0x50/0x68) r7:c181fef0 r6:c0449db8 r5:c0449db8 r4:c042eff8 [] (driver_probe_device+0x0/0x68) from [] (__driver_attach+0x74/0x98) r5:c042f02c r4:c042eff8 [] (__driver_attach+0x0/0x98) from [] (bus_for_each_dev+0x58/0x98) r6:c0449db8 r5:c01e311c r4:00000000 [] (bus_for_each_dev+0x0/0x98) from [] (driver_attach+0x20/0x28) r7:c1ab60c0 r6:c0449db8 r5:c0449db8 r4:c04165e8 [] (driver_attach+0x0/0x28) from [] (bus_add_driver+0xa8/0x22c) [] (bus_add_driver+0x0/0x22c) from [] (driver_register+0xc8/0x154) [] (driver_register+0x0/0x154) from [] (platform_driver_register+0x4c/0x60) r8:00000000 r7:00000013 r6:c003a37c r5:c041660c r4:c04165e8 [] (platform_driver_register+0x0/0x60) from [] (omapfb_init+0x14/0x34) [] (omapfb_init+0x0/0x34) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x7c/0x120) [] (kernel_init+0x0/0x120) from [] (do_exit+0x0/0x2d8) r5:c03ea208 r4:00000000 Code: e1a0c00d e92dd870 e24cb004 e24dd004 (e5906038) ---[ end trace 9e2474c2e193b223 ]--- Acked-by: Tony Lindgren Signed-off-by: Russell King --- drivers/video/omap2/dss/dpi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 395d658a94fcab..faaf305fda2796 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -180,6 +180,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) { int r; + if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) { + DSSERR("no VDSS_DSI regulator\n"); + return -ENODEV; + } + if (dssdev->manager == NULL) { DSSERR("failed to enable display: no manager\n"); return -ENODEV; -- cgit 1.2.3-korg From 6252547b8a7acced581b649af4ebf6d65f63a34b Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 09:47:21 +0000 Subject: ARM: omap: fix broken twl-core dependencies and ifdefs In commit aeb5032b3f, a dependency on IRQ_DOMAIN was added, which causes regressions on previously working setups: a previously working non-DT kernel configuration now loses its PMIC support. The lack of PMIC support in turn causes the loss of other functionality the kernel had. This dependency was added because the driver now registers its interrupts with the IRQ domain code, presumably to prevent a build error. The result is that OMAP3 oopses in the vp.c code (fixed by a previous commit) due to the lack of PMIC support. However, even with IRQ_DOMAIN enabled, the driver oopses: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP Modules linked in: CPU: 1 Not tainted (3.3.0-rc2+ #271) PC is at irq_domain_add+0x1c/0x134 LR is at twl_probe+0xd0/0x370 pc : [] lr : [] psr: 00000113 sp : df843c48 ip : df843c68 fp : df843c64 r10: c02b93e4 r9 : 00000000 r8 : c029b9dc r7 : df9d8a00 r6 : c03bef90 r5 : 00000000 r4 : c03f5240 r3 : 00000000 r2 : c03f5240 r1 : 00000015 r0 : c03f5240 Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 8000404a DAC: 00000015 Process swapper/0 (pid: 1, stack limit = 0xdf8422f0) Stack: (0xdf843c48 to 0xdf844000) 3c40: 00000014 00000170 00000014 c03bef90 df843c9c df843c68 3c60: c029baac c007bac0 00000000 df9d8a20 00000001 c03cd238 c02b93e4 df9d8a20 3c80: df9d8a04 df9d8a00 c029b9dc df8cae08 df843cc4 df843ca0 c01eee70 c029b9e8 ... Backtrace: [] (irq_domain_add+0x0/0x134) from [] (twl_probe+0xd0/0x370) r6:c03bef90 r5:00000014 r4:00000170 [] (twl_probe+0x0/0x370) from [] (i2c_device_probe+0xb0/0xe4) [] (i2c_device_probe+0x0/0xe4) from [] (really_probe+0xa0/0x178) r8:df8f0070 r7:c03cd238 r6:df9d8a20 r5:df9d8a20 r4:df9d8a20 [] (really_probe+0x0/0x178) from [] (driver_probe_device+0x50/0x68) r7:df843d18 r6:df9d8a20 r5:c03cd238 r4:df9d8a20 [] (driver_probe_device+0x0/0x68) from [] (__device_attach+0x44/0x48) r5:df9d8a20 r4:c03cd238 [] (__device_attach+0x0/0x48) from [] (bus_for_each_drv+0x58/0x98) r5:c01d2104 r4:00000000 [] (bus_for_each_drv+0x0/0x98) from [] (device_attach+0x80/0xac) r7:df9d8a28 r6:df9d8a54 r5:c03cd978 r4:df9d8a20 [] (device_attach+0x0/0xac) from [] (bus_probe_device+0x34/0xa4) r6:df9d8a20 r5:c03cd978 r4:df9d8a20 [] (bus_probe_device+0x0/0xa4) from [] (device_add+0x2a0/0x420) r6:00000000 r5:df9d8a20 r4:df9d8a20 [] (device_add+0x0/0x420) from [] (device_register+0x20/0x24) r8:df9d8a00 r7:df9d8a04 r6:df8f0048 r5:df9d8a00 r4:df9d8a20 [] (device_register+0x0/0x24) from [] (i2c_new_device+0x118/0x180) r4:df9d8a20 [] (i2c_new_device+0x0/0x180) from [] (i2c_register_adapter+0x140/0x204) r8:c03cd970 r7:00000000 r6:df8f0070 r5:df8a6300 r4:df8f0048 [] (i2c_register_adapter+0x0/0x204) from [] (i2c_add_numbered_adapter+0xb4/0xcc) r8:df8a4c54 r7:df8cae00 r6:df843e2c r5:df8f0048 r4:00000000 [] (i2c_add_numbered_adapter+0x0/0xcc) from [] (omap_i2c_probe+0x2f8/0x3b4) r6:00000000 r5:df8f0000 r4:df8f0070 [] (omap_i2c_probe+0x0/0x3b4) from [] (platform_drv_probe+0x20/0x24) [] (platform_drv_probe+0x0/0x24) from [] (really_probe+0xa0/0x178) [] (really_probe+0x0/0x178) from [] (driver_probe_device+0x50/0x68) r7:df843ef0 r6:c03cdb2c r5:c03cdb2c r4:df8cae08 [] (driver_probe_device+0x0/0x68) from [] (__driver_attach+0x6c/0x90) r5:df8cae3c r4:df8cae08 [] (__driver_attach+0x0/0x90) from [] (bus_for_each_dev+0x58/0x98) r6:c03cdb2c r5:c01d2074 r4:00000000 [] (bus_for_each_dev+0x0/0x98) from [] (driver_attach+0x20/0x28) r7:df880b80 r6:c03cdb2c r5:c03cdb2c r4:c0394f28 [] (driver_attach+0x0/0x28) from [] (bus_add_driver+0xb4/0x230) [] (bus_add_driver+0x0/0x230) from [] (driver_register+0xc8/0x154) [] (driver_register+0x0/0x154) from [] (platform_driver_register+0x4c/0x60) r8:00000000 r7:00000013 r6:c00384c8 r5:c0395180 r4:c0394f28 [] (platform_driver_register+0x0/0x60) from [] (omap_i2c_init_driver+0x14/0x1c) [] (omap_i2c_init_driver+0x0/0x1c) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x90/0x138) [] (kernel_init+0x0/0x138) from [] (do_exit+0x0/0x2ec) r5:c036c264 r4:00000000 <0>Code: e24dd004 e5903014 e1a04000 e5905010 (e5933000) <4>---[ end trace 1b75b31a2719ed1c ]--- This happens because we try to register an IRQ domain with a NULL ops structure, and the first thing irq_domain_add() does is try to dereference this ops structure. So, fix the problem by getting rid of the incorrect OF_IRQ ifdef and wrapping the IRQ domain bits of the driver with an IRQ_DOMAIN ifdef instead. Acked-by: Tony Lindgren Signed-off-by: Russell King --- drivers/mfd/Kconfig | 2 +- drivers/mfd/twl-core.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index cd13e9f2f5e668..f147395bac9a1e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -200,7 +200,7 @@ config MENELAUS config TWL4030_CORE bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" - depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN + depends on I2C=y && GENERIC_HARDIRQS help Say yes here if you have TWL4030 / TWL6030 family chip on your board. This core driver provides register access and IRQ handling diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index e04e04ddc15e41..8ce3959c691994 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -263,7 +263,9 @@ struct twl_client { static struct twl_client twl_modules[TWL_NUM_SLAVES]; +#ifdef CONFIG_IRQ_DOMAIN static struct irq_domain domain; +#endif /* mapping the module id to slave id and base address */ struct twl_mapping { @@ -1226,13 +1228,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) pdata->irq_base = status; pdata->irq_end = pdata->irq_base + nr_irqs; +#ifdef CONFIG_IRQ_DOMAIN domain.irq_base = pdata->irq_base; domain.nr_irq = nr_irqs; -#ifdef CONFIG_OF_IRQ domain.of_node = of_node_get(node); domain.ops = &irq_domain_simple_ops; -#endif irq_domain_add(&domain); +#endif if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { dev_dbg(&client->dev, "can't talk I2C?\n"); -- cgit 1.2.3-korg