Skip to content

Commit

Permalink
ARM: OMAP4: hsmmc: check for null pointer
Browse files Browse the repository at this point in the history
platform_device pdev can be NULL if CONFIG_MMC_OMAP_HS is not set.
Add check for NULL pointer. while at it move the duplicated functions
to omap4-common.c

Fixes the following boot crash seen with omap4sdp and omap4panda
when MMC is disabled.

Unable to handle kernel NULL pointer dereference at virtual address 0000008c
pgd = c0004000
[0000008c] *pgd=00000000
Internal error: Oops: 5 [#1] SMP ARM
Modules linked in:
CPU: 0    Not tainted  (3.4.0-rc1-05971-ga4dfa82 #4)
PC is at omap_4430sdp_init+0x184/0x410
LR is at device_add+0x1a0/0x664

Change-Id: I77d740a5e9b532e13b40b6640d815c512cbd48a8
Signed-off-by: Balaji T K <[email protected]>
Reported-by: Santosh Shilimkar <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
Signed-off-by: D. Andrei Măceș <[email protected]>
  • Loading branch information
balajitk authored and airend committed Aug 11, 2016
1 parent 9525cdd commit 0d4f24c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 93 deletions.
44 changes: 0 additions & 44 deletions arch/arm/mach-omap2/board-4430sdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,50 +595,6 @@ static struct platform_device omap_vwlan_device = {
},
};

static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
int irq = 0;
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;

/* Setting MMC1 Card detect Irq */
if (pdev->id == 0) {
irq = twl6030_mmc_card_detect_config();
if (irq < 0) {
pr_err("Failed configuring MMC1 card detect\n");
return irq;
}
pdata->slots[0].card_detect_irq = irq;
pdata->slots[0].card_detect = twl6030_mmc_card_detect;
}
return 0;
}

static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
struct omap_mmc_platform_data *pdata;

/* dev can be null if CONFIG_MMC_OMAP_HS is not set */
if (!dev) {
pr_err("Failed %s\n", __func__);
return;
}
pdata = dev->platform_data;
pdata->init = omap4_twl6030_hsmmc_late_init;
}

static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
struct omap2_hsmmc_info *c;

omap_hsmmc_init(controllers);
for (c = controllers; c->mmc; c++)
omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);

return 0;
}

static int tps6130x_enable(int on)
{
u8 mask;
Expand Down
49 changes: 0 additions & 49 deletions arch/arm/mach-omap2/board-omap4panda.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,55 +251,6 @@ static struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
.board_ref_clock = 2,
};

static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
int irq = 0;
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;

if (!pdata) {
dev_err(dev, "%s: NULL platform data\n", __func__);
return -EINVAL;
}
/* Setting MMC1 Card detect Irq */
if (pdev->id == 0) {
irq = twl6030_mmc_card_detect_config();
if (irq < 0) {
dev_err(dev, "%s: Error card detect config(%d)\n",
__func__, irq);
return irq;
}
pdata->slots[0].card_detect = twl6030_mmc_card_detect;
}
return 0;
}

static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
struct omap_mmc_platform_data *pdata;

/* dev can be null if CONFIG_MMC_OMAP_HS is not set */
if (!dev) {
pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
return;
}
pdata = dev->platform_data;

pdata->init = omap4_twl6030_hsmmc_late_init;
}

static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
struct omap2_hsmmc_info *c;

omap_hsmmc_init(controllers);
for (c = controllers; c->mmc; c++)
omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);

return 0;
}

static struct twl6040_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/mach-omap2/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#ifndef __ASSEMBLER__

#include <linux/delay.h>
#include <linux/i2c/twl.h>
#include <plat/common.h>
#include <asm/proc-fns.h>
#include <linux/platform_data/emif_plat.h>
Expand Down Expand Up @@ -290,6 +291,8 @@ static inline bool omap_wakeupgen_check_interrupts(char *report_string)
struct omap_sdrc_params;
extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1);
struct omap2_hsmmc_info;
extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers);

#if defined(CONFIG_TI_EMIF) || defined(CONFIG_TI_EMIF_MODULE)
void __init omap_emif_set_device_details(u32 emif_nr,
Expand Down
58 changes: 58 additions & 0 deletions arch/arm/mach-omap2/omap4-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
#include <plat/irqs.h>
#include <plat/sram.h>
#include <plat/omap-secure.h>
#include <plat/mmc.h>

#include <mach/hardware.h>
#include <mach/omap-wakeupgen.h>

#include "common.h"
#include "hsmmc.h"
#include "omap4-sar-layout.h"
#include <linux/export.h>

Expand Down Expand Up @@ -282,3 +284,59 @@ static int __init omap5_axi_err_init(void)
return ret;
}
postcore_initcall(omap5_axi_err_init);

#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
int irq = 0;
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;

/* Setting MMC1 Card detect Irq */
if (pdev->id == 0) {
irq = twl6030_mmc_card_detect_config();
if (irq < 0) {
dev_err(dev, "%s: Error card detect config(%d)\n",
__func__, irq);
return irq;
}
pdata->slots[0].card_detect_irq = irq;
pdata->slots[0].card_detect = twl6030_mmc_card_detect;
}
return 0;
}

static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
struct omap_mmc_platform_data *pdata;

/* dev can be null if CONFIG_MMC_OMAP_HS is not set */
if (!dev) {
pr_err("Failed %s\n", __func__);
return;
}
pdata = dev->platform_data;
pdata->init = omap4_twl6030_hsmmc_late_init;
}

int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
struct omap2_hsmmc_info *c;

omap_hsmmc_init(controllers);
for (c = controllers; c->mmc; c++) {
/* pdev can be null if CONFIG_MMC_OMAP_HS is not set */
if (!c->pdev)
continue;
omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
}

return 0;
}
#else
int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
return 0;
}
#endif

0 comments on commit 0d4f24c

Please sign in to comment.