diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/1251-My-GTA01-2.6.26-kernel-was-crashing-within-mmc_power.patch')
-rwxr-xr-x | target/linux/s3c24xx/patches-2.6.26/1251-My-GTA01-2.6.26-kernel-was-crashing-within-mmc_power.patch | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/1251-My-GTA01-2.6.26-kernel-was-crashing-within-mmc_power.patch b/target/linux/s3c24xx/patches-2.6.26/1251-My-GTA01-2.6.26-kernel-was-crashing-within-mmc_power.patch new file mode 100755 index 000000000..e312075b2 --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.26/1251-My-GTA01-2.6.26-kernel-was-crashing-within-mmc_power.patch @@ -0,0 +1,108 @@ +From 0733a2e1b598dec898fef5066b737764170aaf62 Mon Sep 17 00:00:00 2001 +From: Andy Green <agreen@pads.home.warmcat.com> +Date: Sun, 10 Aug 2008 09:27:16 +0100 +Subject: [PATCH] My GTA01 2.6.26 kernel was crashing within mmc_power_up(), at the first + call to mmc_set_ios(host), due to host->ops being NULL. mmc_power_up() + was being called by mmc_rescan(). + +The only possible call path I can imagine for that is s3cmci_irq_cd +getting called before host->ops is set, thus calling mmc_detect_change() +which will schedule host->detect which is mmc_rescan. + +This patch avoids the problem by moving the enable of the gpio_detect +interrupt to just before calling mmc_add_host(), where everything else +is already set up. + +Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net> +--- + drivers/mmc/host/s3cmci.c | 34 +++++++++++++++++----------------- + 1 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c +index 9ef4d5b..107847a 100644 +--- a/drivers/mmc/host/s3cmci.c ++++ b/drivers/mmc/host/s3cmci.c +@@ -1226,17 +1226,6 @@ static int s3cmci_probe(struct platform_device *pdev, int is2440) + + disable_irq(host->irq); + +- s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); +- set_irq_type(host->irq_cd, IRQT_BOTHEDGE); +- +- if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { +- dev_err(&pdev->dev, +- "failed to request card detect interrupt.\n"); +- +- ret = -ENOENT; +- goto probe_free_irq; +- } +- + if (host->pdata->gpio_wprotect) + s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect, + S3C2410_GPIO_INPUT); +@@ -1244,7 +1233,7 @@ static int s3cmci_probe(struct platform_device *pdev, int is2440) + if (s3c2410_dma_request(host->dma, &s3cmci_dma_client, NULL)) { + dev_err(&pdev->dev, "unable to get DMA channel.\n"); + ret = -EBUSY; +- goto probe_free_irq_cd; ++ goto probe_free_irq; + } + + host->clk = clk_get(&pdev->dev, "sdi"); +@@ -1281,10 +1270,21 @@ static int s3cmci_probe(struct platform_device *pdev, int is2440) + "irq_cd:%u dma:%u.\n", (host->is2440?"2440":""), + host->base, host->irq, host->irq_cd, host->dma); + ++ s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); ++ set_irq_type(host->irq_cd, IRQT_BOTHEDGE); ++ ++ if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { ++ dev_err(&pdev->dev, ++ "failed to request card detect interrupt.\n"); ++ ++ ret = -ENOENT; ++ goto probe_disable_clk; ++ } ++ + ret = mmc_add_host(mmc); + if (ret) { + dev_err(&pdev->dev, "failed to add mmc host.\n"); +- goto probe_disable_clk; ++ goto probe_free_irq_cd; + } + + platform_set_drvdata(pdev, mmc); +@@ -1292,15 +1292,15 @@ static int s3cmci_probe(struct platform_device *pdev, int is2440) + dev_info(&pdev->dev, "initialisation done.\n"); + return 0; + ++ probe_free_irq_cd: ++ free_irq(host->irq_cd, host); ++ + probe_disable_clk: + clk_disable(host->clk); + + probe_free_clk: + clk_put(host->clk); + +- probe_free_irq_cd: +- free_irq(host->irq_cd, host); +- + probe_free_dma: + s3c2410_dma_free(host->dma, &s3cmci_dma_client); + +@@ -1325,10 +1325,10 @@ static int s3cmci_remove(struct platform_device *pdev) + struct s3cmci_host *host = mmc_priv(mmc); + + mmc_remove_host(mmc); ++ free_irq(host->irq_cd, host); + clk_disable(host->clk); + clk_put(host->clk); + s3c2410_dma_free(host->dma, &s3cmci_dma_client); +- free_irq(host->irq_cd, host); + free_irq(host->irq, host); + iounmap(host->base); + release_mem_region(host->mem->start, RESSIZE(host->mem)); +-- +1.5.6.3 + |