From ce647a69fe2179582e07a0b4f9eb6bb534d07edb Mon Sep 17 00:00:00 2001 From: Ulf Samuelsson Date: Tue, 18 Mar 2008 12:02:16 +0000 Subject: Use same name for same patch --- .../linux-2.6.24-600-avr32-mmc.patch | 255 +++++++++++++++++++++ .../kernel-patches/linux-2.6.24-avr32-mmc.patch | 255 --------------------- 2 files changed, 255 insertions(+), 255 deletions(-) create mode 100644 target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-600-avr32-mmc.patch delete mode 100644 target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-avr32-mmc.patch (limited to 'target/device/Atmel') diff --git a/target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-600-avr32-mmc.patch b/target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-600-avr32-mmc.patch new file mode 100644 index 000000000..a7654b5c6 --- /dev/null +++ b/target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-600-avr32-mmc.patch @@ -0,0 +1,255 @@ +diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c +index eeac479..7913cd8 100644 +--- a/drivers/mmc/host/atmel-mci.c ++++ b/drivers/mmc/host/atmel-mci.c +@@ -39,7 +39,6 @@ enum { + EVENT_STOP_COMPLETE, + EVENT_DMA_COMPLETE, + EVENT_DMA_ERROR, +- EVENT_CARD_DETECT, + }; + + struct atmel_mci_dma { +@@ -70,6 +69,9 @@ struct atmel_mci { + int detect_pin; + int wp_pin; + ++ /* For detect pin debouncing */ ++ struct timer_list detect_timer; ++ + unsigned long bus_hz; + unsigned long mapbase; + struct clk *mck; +@@ -108,8 +110,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); + test_bit(EVENT_DMA_COMPLETE, &host->completed_events) + #define mci_dma_error_is_complete(host) \ + test_bit(EVENT_DMA_ERROR, &host->completed_events) +-#define mci_card_detect_is_complete(host) \ +- test_bit(EVENT_CARD_DETECT, &host->completed_events) + + /* Test and clear bit macros for pending events */ + #define mci_clear_cmd_is_pending(host) \ +@@ -124,8 +124,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); + test_and_clear_bit(EVENT_STOP_COMPLETE, &host->pending_events) + #define mci_clear_dma_error_is_pending(host) \ + test_and_clear_bit(EVENT_DMA_ERROR, &host->pending_events) +-#define mci_clear_card_detect_is_pending(host) \ +- test_and_clear_bit(EVENT_CARD_DETECT, &host->pending_events) + + /* Test and set bit macros for completed events */ + #define mci_set_cmd_is_completed(host) \ +@@ -140,8 +138,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); + test_and_set_bit(EVENT_STOP_COMPLETE, &host->completed_events) + #define mci_set_dma_error_is_completed(host) \ + test_and_set_bit(EVENT_DMA_ERROR, &host->completed_events) +-#define mci_set_card_detect_is_completed(host) \ +- test_and_set_bit(EVENT_CARD_DETECT, &host->completed_events) + + /* Set bit macros for completed events */ + #define mci_set_cmd_complete(host) \ +@@ -158,8 +154,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); + set_bit(EVENT_DMA_COMPLETE, &host->completed_events) + #define mci_set_dma_error_complete(host) \ + set_bit(EVENT_DMA_ERROR, &host->completed_events) +-#define mci_set_card_detect_complete(host) \ +- set_bit(EVENT_CARD_DETECT, &host->completed_events) + + /* Set bit macros for pending events */ + #define mci_set_cmd_pending(host) \ +@@ -174,8 +168,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); + set_bit(EVENT_STOP_COMPLETE, &host->pending_events) + #define mci_set_dma_error_pending(host) \ + set_bit(EVENT_DMA_ERROR, &host->pending_events) +-#define mci_set_card_detect_pending(host) \ +- set_bit(EVENT_CARD_DETECT, &host->pending_events) + + /* Clear bit macros for pending events */ + #define mci_clear_cmd_pending(host) \ +@@ -190,8 +182,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); + clear_bit(EVENT_STOP_COMPLETE, &host->pending_events) + #define mci_clear_dma_error_pending(host) \ + clear_bit(EVENT_DMA_ERROR, &host->pending_events) +-#define mci_clear_card_detect_pending(host) \ +- clear_bit(EVENT_CARD_DETECT, &host->pending_events) + + + #ifdef CONFIG_DEBUG_FS +@@ -560,6 +550,21 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) + mci_readl(host, IMR)); + + WARN_ON(host->mrq != NULL); ++ ++ /* ++ * We may "know" the card is gone even though there's still an ++ * electrical connection. If so, we really need to communicate ++ * this to the MMC core since there won't be any more ++ * interrupts as the card is completely removed. Otherwise, ++ * the MMC core might believe the card is still there even ++ * though the card was just removed very slowly. ++ */ ++ if (!host->present) { ++ mrq->cmd->error = -ENOMEDIUM; ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ + host->mrq = mrq; + host->pending_events = 0; + host->completed_events = 0; +@@ -729,6 +734,61 @@ static void atmci_command_complete(struct atmel_mci *host, + } + } + ++static void atmci_detect_change(unsigned long data) ++{ ++ struct atmel_mci *host = (struct atmel_mci *)data; ++ struct mmc_request *mrq = host->mrq; ++ int present; ++ ++ /* ++ * atmci_remove() sets detect_pin to -1 before freeing the ++ * interrupt. We must not re-enable the interrupt if it has ++ * been freed. ++ */ ++ smp_rmb(); ++ if (host->detect_pin < 0) ++ return; ++ ++ enable_irq(gpio_to_irq(host->detect_pin)); ++ present = !gpio_get_value(host->detect_pin); ++ ++ dev_vdbg(&host->pdev->dev, "detect change: %d (was %d)\n", ++ present, host->present); ++ ++ if (present != host->present) { ++ dev_dbg(&host->mmc->class_dev, "card %s\n", ++ present ? "inserted" : "removed"); ++ host->present = present; ++ ++ /* Reset controller if card is gone */ ++ if (!present) { ++ mci_writel(host, CR, MCI_BIT(SWRST)); ++ mci_writel(host, IDR, ~0UL); ++ mci_writel(host, CR, MCI_BIT(MCIEN)); ++ } ++ ++ /* Clean up queue if present */ ++ if (mrq) { ++ if (!mci_cmd_is_complete(host)) ++ mrq->cmd->error = -ENOMEDIUM; ++ if (mrq->data && !mci_data_is_complete(host) ++ && !mci_data_error_is_complete(host)) { ++ dma_stop_request(host->dma.req.req.dmac, ++ host->dma.req.req.channel); ++ host->data->error = -ENOMEDIUM; ++ atmci_data_complete(host, host->data); ++ } ++ if (mrq->stop && !mci_stop_is_complete(host)) ++ mrq->stop->error = -ENOMEDIUM; ++ ++ host->cmd = NULL; ++ atmci_request_end(host->mmc, mrq); ++ } ++ ++ mmc_detect_change(host->mmc, 0); ++ } ++} ++ + static void atmci_tasklet_func(unsigned long priv) + { + struct mmc_host *mmc = (struct mmc_host *)priv; +@@ -806,33 +866,6 @@ static void atmci_tasklet_func(unsigned long priv) + data->bytes_xfered = data->blocks * data->blksz; + atmci_data_complete(host, data); + } +- if (mci_clear_card_detect_is_pending(host)) { +- /* Reset controller if card is gone */ +- if (!host->present) { +- mci_writel(host, CR, MCI_BIT(SWRST)); +- mci_writel(host, IDR, ~0UL); +- mci_writel(host, CR, MCI_BIT(MCIEN)); +- } +- +- /* Clean up queue if present */ +- if (mrq) { +- if (!mci_cmd_is_complete(host)) +- mrq->cmd->error = -ETIMEDOUT; +- if (mrq->data && !mci_data_is_complete(host) +- && !mci_data_error_is_complete(host)) { +- dma_stop_request(host->dma.req.req.dmac, +- host->dma.req.req.channel); +- host->data->error = -ETIMEDOUT; +- atmci_data_complete(host, data); +- } +- if (mrq->stop && !mci_stop_is_complete(host)) +- mrq->stop->error = -ETIMEDOUT; +- +- host->cmd = NULL; +- atmci_request_end(mmc, mrq); +- } +- mmc_detect_change(host->mmc, msecs_to_jiffies(100)); +- } + } + + static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status) +@@ -957,20 +990,19 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) + return IRQ_HANDLED; + } + +-static irqreturn_t atmci_detect_change(int irq, void *dev_id) ++static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) + { + struct mmc_host *mmc = dev_id; + struct atmel_mci *host = mmc_priv(mmc); + +- int present = !gpio_get_value(irq_to_gpio(irq)); ++ /* ++ * Disable interrupts until the pin has stabilized and check ++ * the state then. Use mod_timer() since we may be in the ++ * middle of the timer routine when this interrupt triggers. ++ */ ++ disable_irq_nosync(irq); ++ mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(20)); + +- if (present != host->present) { +- dev_dbg(&mmc->class_dev, "card %s\n", +- present ? "inserted" : "removed"); +- host->present = present; +- mci_set_card_detect_pending(host); +- tasklet_schedule(&host->tasklet); +- } + return IRQ_HANDLED; + } + +@@ -1079,8 +1111,11 @@ static int __devinit atmci_probe(struct platform_device *pdev) + mmc_add_host(mmc); + + if (host->detect_pin >= 0) { ++ setup_timer(&host->detect_timer, atmci_detect_change, ++ (unsigned long)host); ++ + ret = request_irq(gpio_to_irq(host->detect_pin), +- atmci_detect_change, ++ atmci_detect_interrupt, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + DRIVER_NAME, mmc); + if (ret) { +@@ -1125,9 +1160,16 @@ static int __devexit atmci_remove(struct platform_device *pdev) + atmci_cleanup_debugfs(host); + + if (host->detect_pin >= 0) { +- free_irq(gpio_to_irq(host->detect_pin), host->mmc); ++ int pin = host->detect_pin; ++ ++ /* Make sure our timer doesn't enable the interrupt */ ++ host->detect_pin = -1; ++ smp_wmb(); ++ ++ free_irq(gpio_to_irq(pin), host->mmc); ++ del_timer_sync(&host->detect_timer); + cancel_delayed_work(&host->mmc->detect); +- gpio_free(host->detect_pin); ++ gpio_free(pin); + } + + mmc_remove_host(host->mmc); diff --git a/target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-avr32-mmc.patch b/target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-avr32-mmc.patch deleted file mode 100644 index a7654b5c6..000000000 --- a/target/device/Atmel/atstk1002/kernel-patches/linux-2.6.24-avr32-mmc.patch +++ /dev/null @@ -1,255 +0,0 @@ -diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c -index eeac479..7913cd8 100644 ---- a/drivers/mmc/host/atmel-mci.c -+++ b/drivers/mmc/host/atmel-mci.c -@@ -39,7 +39,6 @@ enum { - EVENT_STOP_COMPLETE, - EVENT_DMA_COMPLETE, - EVENT_DMA_ERROR, -- EVENT_CARD_DETECT, - }; - - struct atmel_mci_dma { -@@ -70,6 +69,9 @@ struct atmel_mci { - int detect_pin; - int wp_pin; - -+ /* For detect pin debouncing */ -+ struct timer_list detect_timer; -+ - unsigned long bus_hz; - unsigned long mapbase; - struct clk *mck; -@@ -108,8 +110,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); - test_bit(EVENT_DMA_COMPLETE, &host->completed_events) - #define mci_dma_error_is_complete(host) \ - test_bit(EVENT_DMA_ERROR, &host->completed_events) --#define mci_card_detect_is_complete(host) \ -- test_bit(EVENT_CARD_DETECT, &host->completed_events) - - /* Test and clear bit macros for pending events */ - #define mci_clear_cmd_is_pending(host) \ -@@ -124,8 +124,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); - test_and_clear_bit(EVENT_STOP_COMPLETE, &host->pending_events) - #define mci_clear_dma_error_is_pending(host) \ - test_and_clear_bit(EVENT_DMA_ERROR, &host->pending_events) --#define mci_clear_card_detect_is_pending(host) \ -- test_and_clear_bit(EVENT_CARD_DETECT, &host->pending_events) - - /* Test and set bit macros for completed events */ - #define mci_set_cmd_is_completed(host) \ -@@ -140,8 +138,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); - test_and_set_bit(EVENT_STOP_COMPLETE, &host->completed_events) - #define mci_set_dma_error_is_completed(host) \ - test_and_set_bit(EVENT_DMA_ERROR, &host->completed_events) --#define mci_set_card_detect_is_completed(host) \ -- test_and_set_bit(EVENT_CARD_DETECT, &host->completed_events) - - /* Set bit macros for completed events */ - #define mci_set_cmd_complete(host) \ -@@ -158,8 +154,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); - set_bit(EVENT_DMA_COMPLETE, &host->completed_events) - #define mci_set_dma_error_complete(host) \ - set_bit(EVENT_DMA_ERROR, &host->completed_events) --#define mci_set_card_detect_complete(host) \ -- set_bit(EVENT_CARD_DETECT, &host->completed_events) - - /* Set bit macros for pending events */ - #define mci_set_cmd_pending(host) \ -@@ -174,8 +168,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); - set_bit(EVENT_STOP_COMPLETE, &host->pending_events) - #define mci_set_dma_error_pending(host) \ - set_bit(EVENT_DMA_ERROR, &host->pending_events) --#define mci_set_card_detect_pending(host) \ -- set_bit(EVENT_CARD_DETECT, &host->pending_events) - - /* Clear bit macros for pending events */ - #define mci_clear_cmd_pending(host) \ -@@ -190,8 +182,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); - clear_bit(EVENT_STOP_COMPLETE, &host->pending_events) - #define mci_clear_dma_error_pending(host) \ - clear_bit(EVENT_DMA_ERROR, &host->pending_events) --#define mci_clear_card_detect_pending(host) \ -- clear_bit(EVENT_CARD_DETECT, &host->pending_events) - - - #ifdef CONFIG_DEBUG_FS -@@ -560,6 +550,21 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) - mci_readl(host, IMR)); - - WARN_ON(host->mrq != NULL); -+ -+ /* -+ * We may "know" the card is gone even though there's still an -+ * electrical connection. If so, we really need to communicate -+ * this to the MMC core since there won't be any more -+ * interrupts as the card is completely removed. Otherwise, -+ * the MMC core might believe the card is still there even -+ * though the card was just removed very slowly. -+ */ -+ if (!host->present) { -+ mrq->cmd->error = -ENOMEDIUM; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ - host->mrq = mrq; - host->pending_events = 0; - host->completed_events = 0; -@@ -729,6 +734,61 @@ static void atmci_command_complete(struct atmel_mci *host, - } - } - -+static void atmci_detect_change(unsigned long data) -+{ -+ struct atmel_mci *host = (struct atmel_mci *)data; -+ struct mmc_request *mrq = host->mrq; -+ int present; -+ -+ /* -+ * atmci_remove() sets detect_pin to -1 before freeing the -+ * interrupt. We must not re-enable the interrupt if it has -+ * been freed. -+ */ -+ smp_rmb(); -+ if (host->detect_pin < 0) -+ return; -+ -+ enable_irq(gpio_to_irq(host->detect_pin)); -+ present = !gpio_get_value(host->detect_pin); -+ -+ dev_vdbg(&host->pdev->dev, "detect change: %d (was %d)\n", -+ present, host->present); -+ -+ if (present != host->present) { -+ dev_dbg(&host->mmc->class_dev, "card %s\n", -+ present ? "inserted" : "removed"); -+ host->present = present; -+ -+ /* Reset controller if card is gone */ -+ if (!present) { -+ mci_writel(host, CR, MCI_BIT(SWRST)); -+ mci_writel(host, IDR, ~0UL); -+ mci_writel(host, CR, MCI_BIT(MCIEN)); -+ } -+ -+ /* Clean up queue if present */ -+ if (mrq) { -+ if (!mci_cmd_is_complete(host)) -+ mrq->cmd->error = -ENOMEDIUM; -+ if (mrq->data && !mci_data_is_complete(host) -+ && !mci_data_error_is_complete(host)) { -+ dma_stop_request(host->dma.req.req.dmac, -+ host->dma.req.req.channel); -+ host->data->error = -ENOMEDIUM; -+ atmci_data_complete(host, host->data); -+ } -+ if (mrq->stop && !mci_stop_is_complete(host)) -+ mrq->stop->error = -ENOMEDIUM; -+ -+ host->cmd = NULL; -+ atmci_request_end(host->mmc, mrq); -+ } -+ -+ mmc_detect_change(host->mmc, 0); -+ } -+} -+ - static void atmci_tasklet_func(unsigned long priv) - { - struct mmc_host *mmc = (struct mmc_host *)priv; -@@ -806,33 +866,6 @@ static void atmci_tasklet_func(unsigned long priv) - data->bytes_xfered = data->blocks * data->blksz; - atmci_data_complete(host, data); - } -- if (mci_clear_card_detect_is_pending(host)) { -- /* Reset controller if card is gone */ -- if (!host->present) { -- mci_writel(host, CR, MCI_BIT(SWRST)); -- mci_writel(host, IDR, ~0UL); -- mci_writel(host, CR, MCI_BIT(MCIEN)); -- } -- -- /* Clean up queue if present */ -- if (mrq) { -- if (!mci_cmd_is_complete(host)) -- mrq->cmd->error = -ETIMEDOUT; -- if (mrq->data && !mci_data_is_complete(host) -- && !mci_data_error_is_complete(host)) { -- dma_stop_request(host->dma.req.req.dmac, -- host->dma.req.req.channel); -- host->data->error = -ETIMEDOUT; -- atmci_data_complete(host, data); -- } -- if (mrq->stop && !mci_stop_is_complete(host)) -- mrq->stop->error = -ETIMEDOUT; -- -- host->cmd = NULL; -- atmci_request_end(mmc, mrq); -- } -- mmc_detect_change(host->mmc, msecs_to_jiffies(100)); -- } - } - - static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status) -@@ -957,20 +990,19 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) - return IRQ_HANDLED; - } - --static irqreturn_t atmci_detect_change(int irq, void *dev_id) -+static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) - { - struct mmc_host *mmc = dev_id; - struct atmel_mci *host = mmc_priv(mmc); - -- int present = !gpio_get_value(irq_to_gpio(irq)); -+ /* -+ * Disable interrupts until the pin has stabilized and check -+ * the state then. Use mod_timer() since we may be in the -+ * middle of the timer routine when this interrupt triggers. -+ */ -+ disable_irq_nosync(irq); -+ mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(20)); - -- if (present != host->present) { -- dev_dbg(&mmc->class_dev, "card %s\n", -- present ? "inserted" : "removed"); -- host->present = present; -- mci_set_card_detect_pending(host); -- tasklet_schedule(&host->tasklet); -- } - return IRQ_HANDLED; - } - -@@ -1079,8 +1111,11 @@ static int __devinit atmci_probe(struct platform_device *pdev) - mmc_add_host(mmc); - - if (host->detect_pin >= 0) { -+ setup_timer(&host->detect_timer, atmci_detect_change, -+ (unsigned long)host); -+ - ret = request_irq(gpio_to_irq(host->detect_pin), -- atmci_detect_change, -+ atmci_detect_interrupt, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - DRIVER_NAME, mmc); - if (ret) { -@@ -1125,9 +1160,16 @@ static int __devexit atmci_remove(struct platform_device *pdev) - atmci_cleanup_debugfs(host); - - if (host->detect_pin >= 0) { -- free_irq(gpio_to_irq(host->detect_pin), host->mmc); -+ int pin = host->detect_pin; -+ -+ /* Make sure our timer doesn't enable the interrupt */ -+ host->detect_pin = -1; -+ smp_wmb(); -+ -+ free_irq(gpio_to_irq(pin), host->mmc); -+ del_timer_sync(&host->detect_timer); - cancel_delayed_work(&host->mmc->detect); -- gpio_free(host->detect_pin); -+ gpio_free(pin); - } - - mmc_remove_host(host->mmc); -- cgit v1.2.3