Add 2.6.22.10 and 2.6.23 support

This commit is contained in:
Ulf Samuelsson 2007-10-12 15:10:27 +00:00
parent 103832204d
commit 022b104152
8 changed files with 20125 additions and 17 deletions

View File

@ -0,0 +1,130 @@
>From 9c5fa914202d20756c56e0c4fd76035ed8f8ced8 Mon Sep 17 00:00:00 2001
From: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
Date: Mon, 6 Aug 2007 08:31:14 +0200
Subject: [PATCH 1/1] Add gpio_mouse board setup to atstk1000 board
This patch adds a gpio_mouse_platform_data to the atstk1000 board code and
registers a gpio_mouse platform_device. This will enable a GPIO mouse on header
J1 on GPIO of the ATSTK1000 development kit. The board code is enabled/disabled
in menuconfig.
By connecting J1 (GPIO) to J25 (SWITCH) you can use the following keys to
simulate a mouse:
SW0: right
SW1: down
SW2: up
SW3: left
SW5: right button
SW6: middle button
SW7: left button
Signed-off-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
---
arch/avr32/boards/atstk1000/Kconfig | 16 ++++++++++
arch/avr32/boards/atstk1000/atstk1002.c | 48 +++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig
index 718578f..d99d4bd 100644
--- a/arch/avr32/boards/atstk1000/Kconfig
+++ b/arch/avr32/boards/atstk1000/Kconfig
@@ -50,6 +50,22 @@ config BOARD_ATSTK1002_SPI1
GPIO lines and accessed through the J1 jumper block. Say "y"
here to configure that SPI controller.
+config BOARD_ATSTK1002_GPIO_MOUSE
+ bool "Configure gpio_mouse on GPIO J1 header"
+ depends on !BOARD_ATSTK1002_SW4_CUSTOM
+ help
+ Enable gpio_mouse board configuration on GPIO 0 to 7. Connecting a
+ 10-pin flat cable from J1 (GPIO) to J25 (SWITCH) will let a user give
+ mouse inputs using the the switches SW0 to SW7.
+
+ SW0: right
+ SW1: down
+ SW2: up
+ SW3: left
+ SW5: right button
+ SW6: middle button
+ SW7: left button
+
config BOARD_ATSTK1002_J2_LED
bool
default BOARD_ATSTK1002_J2_LED8 || BOARD_ATSTK1002_J2_RGB
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index c958fd4..c7560e5 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/spi/spi.h>
#include <linux/spi/at73c213.h>
+#include <linux/gpio_mouse.h>
#include <video/atmel_lcdc.h>
@@ -91,6 +92,49 @@ static struct mci_platform_data __initdata mci0_data = {
.wp_pin = GPIO_PIN_NONE,
};
+#ifdef CONFIG_BOARD_ATSTK1002_GPIO_MOUSE
+static struct gpio_mouse_platform_data gpio_mouse0_data = {
+ .polarity = GPIO_MOUSE_POLARITY_ACT_LOW,
+ {
+ {
+ .up = GPIO_PIN_PB(2),
+ .down = GPIO_PIN_PB(1),
+ .left = GPIO_PIN_PB(3),
+ .right = GPIO_PIN_PB(0),
+ .bleft = GPIO_PIN_PB(7),
+ .bmiddle = GPIO_PIN_PB(6),
+ .bright = GPIO_PIN_PB(5),
+ },
+ },
+ .scan_ms = 10,
+};
+
+static struct platform_device gpio_mouse0_device = {
+ .name = "gpio_mouse",
+ .id = 0,
+ .dev = {
+ .platform_data = &gpio_mouse0_data,
+ },
+};
+
+static void __init add_device_gpio_mouse0(void)
+{
+ struct platform_device *pdev = &gpio_mouse0_device;
+ struct gpio_mouse_platform_data *data = pdev->dev.platform_data;
+
+ at32_select_gpio(data->up, 0);
+ at32_select_gpio(data->down, 0);
+ at32_select_gpio(data->left, 0);
+ at32_select_gpio(data->right, 0);
+
+ at32_select_gpio(data->bleft, 0);
+ at32_select_gpio(data->bmiddle, 0);
+ at32_select_gpio(data->bright, 0);
+
+ platform_device_register(pdev);
+}
+#endif
+
/*
* The next two functions should go away as the boot loader is
* supposed to initialize the macb address registers with a valid
@@ -321,6 +365,10 @@ static int __init atstk1002_init(void)
#endif
#endif
+#ifdef CONFIG_BOARD_ATSTK1002_GPIO_MOUSE
+ add_device_gpio_mouse0();
+#endif
+
return 0;
}
postcore_initcall(atstk1002_init);
--
1.5.2.3

View File

@ -0,0 +1,290 @@
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Subject: [PATCH 1/2] atmel_mci: Minor fixes and cleanups
* Use ios->clock to define when to enable the controller instead of
ios->power_mode.
* Send initialization command (74 idle clock cycles) when power_mode
is set to MMC_POWER_ON.
* Use dev_dbg() and friends instead of pr_debug() and printk().
* Don't print data- or probe errors when debugging is not enabled.
* Adjust ocr_avail range to 3.2V-3.4V using proper constants.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mmc/host/atmel-mci.c | 120 ++++++++++++++++++++++-------------------
1 files changed, 64 insertions(+), 56 deletions(-)
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 74d343f..1dc91b4 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -464,9 +464,8 @@ static void atmci_set_timeout(struct atmel_mci *host,
dtocyc = 15;
}
- pr_debug("%s: setting timeout to %u cycles\n",
- mmc_hostname(host->mmc),
- dtocyc << dtomul_to_shift[dtomul]);
+ dev_dbg(&host->mmc->class_dev, "setting timeout to %u cycles\n",
+ dtocyc << dtomul_to_shift[dtomul]);
mci_writel(host, DTOR, (MCI_BF(DTOMUL, dtomul)
| MCI_BF(DTOCYC, dtocyc)));
}
@@ -508,9 +507,9 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
if (!(cmd->flags & MMC_RSP_CRC))
iflags &= ~MCI_BIT(RCRCE);
- pr_debug("%s: cmd: op %02x arg %08x flags %08x, cmdflags %08lx\n",
- mmc_hostname(mmc), cmd->opcode, cmd->arg, cmd->flags,
- (unsigned long)cmdr);
+ dev_dbg(&mmc->class_dev,
+ "cmd: op %02x arg %08x flags %08x, cmdflags %08lx\n",
+ cmd->opcode, cmd->arg, cmd->flags, (unsigned long)cmdr);
*cmd_flags = cmdr;
return iflags;
@@ -589,7 +588,8 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
iflags = mci_readl(host, IMR);
if (iflags)
- printk("WARNING: IMR=0x%08x\n", mci_readl(host, IMR));
+ dev_warn(&mmc->class_dev, "WARNING: IMR=0x%08x\n",
+ mci_readl(host, IMR));
WARN_ON(host->mrq != NULL);
host->mrq = mrq;
@@ -623,16 +623,30 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct atmel_mci *host = mmc_priv(mmc);
+ u32 mr;
if (ios->clock) {
u32 clkdiv;
+ /* Set clock rate */
clkdiv = host->bus_hz / (2 * ios->clock) - 1;
- if (clkdiv > 255)
+ if (clkdiv > 255) {
+ dev_warn(&mmc->class_dev,
+ "clock %u too slow; using %lu\n",
+ ios->clock, host->bus_hz / (2 * 256));
clkdiv = 255;
- mci_writel(host, MR, (clkdiv
- | MCI_BIT(WRPROOF)
- | MCI_BIT(RDPROOF)));
+ }
+
+ mr = mci_readl(host, MR);
+ mr = MCI_BFINS(CLKDIV, clkdiv, mr)
+ | MCI_BIT(WRPROOF) | MCI_BIT(RDPROOF);
+ mci_writel(host, MR, mr);
+
+ /* Enable the MCI controller */
+ mci_writel(host, CR, MCI_BIT(MCIEN));
+ } else {
+ /* Disable the MCI controller */
+ mci_writel(host, CR, MCI_BIT(MCIDIS));
}
switch (ios->bus_width) {
@@ -645,14 +659,19 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
}
switch (ios->power_mode) {
- case MMC_POWER_OFF:
- mci_writel(host, CR, MCI_BIT(MCIDIS));
- break;
- case MMC_POWER_UP:
- mci_writel(host, CR, MCI_BIT(SWRST));
- break;
case MMC_POWER_ON:
- mci_writel(host, CR, MCI_BIT(MCIEN));
+ /* Send init sequence (74 clock cycles) */
+ mci_writel(host, IDR, ~0UL);
+ mci_writel(host, CMDR, MCI_BF(SPCMD, MCI_SPCMD_INIT_CMD));
+ while (!(mci_readl(host, SR) & MCI_BIT(CMDRDY)))
+ cpu_relax();
+ break;
+ default:
+ /*
+ * TODO: None of the currently available AVR32-based
+ * boards allow MMC power to be turned off. Implement
+ * power control when this can be tested properly.
+ */
break;
}
}
@@ -664,11 +683,12 @@ static int atmci_get_ro(struct mmc_host *mmc)
if (host->wp_pin >= 0) {
read_only = gpio_get_value(host->wp_pin);
- pr_debug("%s: card is %s\n", mmc_hostname(mmc),
- read_only ? "read-only" : "read-write");
+ dev_dbg(&mmc->class_dev, "card is %s\n",
+ read_only ? "read-only" : "read-write");
} else {
- pr_debug("%s: no pin for checking read-only switch."
- " Assuming write-enable.\n", mmc_hostname(mmc));
+ dev_dbg(&mmc->class_dev,
+ "no pin for checking read-only switch."
+ " Assuming write-enable.\n");
}
return read_only;
@@ -719,8 +739,7 @@ static void atmci_command_error(struct mmc_host *mmc,
struct mmc_command *cmd,
u32 status)
{
- pr_debug("%s: command error: status=0x%08x\n",
- mmc_hostname(mmc), status);
+ dev_dbg(&mmc->class_dev, "command error: status=0x%08x\n", status);
if (status & MCI_BIT(RTOE))
cmd->error = MMC_ERR_TIMEOUT;
@@ -737,7 +756,8 @@ static void atmci_tasklet_func(unsigned long priv)
struct mmc_request *mrq = host->mrq;
struct mmc_data *data = host->data;
- pr_debug("atmci_tasklet: pending/completed/mask %lx/%lx/%x\n",
+ dev_dbg(&mmc->class_dev,
+ "tasklet: pending/completed/mask %lx/%lx/%x\n",
host->pending_events, host->completed_events,
mci_readl(host, IMR));
@@ -784,8 +804,8 @@ static void atmci_tasklet_func(unsigned long priv)
/* DMA controller got bus error => invalid address */
data->error = MMC_ERR_INVALID;
- printk(KERN_DEBUG "%s: dma error after %u bytes xfered\n",
- mmc_hostname(mmc), host->data->bytes_xfered);
+ dev_dbg(&mmc->class_dev, "dma error after %u bytes xfered\n",
+ host->data->bytes_xfered);
if (data->stop
&& !mci_set_stop_sent_is_completed(host))
@@ -803,24 +823,18 @@ static void atmci_tasklet_func(unsigned long priv)
dma_stop_request(host->dma.req.req.dmac,
host->dma.req.req.channel);
- printk(KERN_DEBUG "%s: data error: status=0x%08x\n",
- mmc_hostname(host->mmc), status);
-
if (status & MCI_BIT(DCRCE)) {
- printk(KERN_DEBUG "%s: Data CRC error\n",
- mmc_hostname(host->mmc));
+ dev_dbg(&mmc->class_dev, "data CRC error\n");
data->error = MMC_ERR_BADCRC;
} else if (status & MCI_BIT(DTOE)) {
- printk(KERN_DEBUG "%s: Data Timeout error\n",
- mmc_hostname(host->mmc));
+ dev_dbg(&mmc->class_dev, "data timeout error\n");
data->error = MMC_ERR_TIMEOUT;
} else {
- printk(KERN_DEBUG "%s: Data FIFO error\n",
- mmc_hostname(host->mmc));
+ dev_dbg(&mmc->class_dev, "data FIFO error\n");
data->error = MMC_ERR_FIFO;
}
- printk(KERN_DEBUG "%s: Bytes xfered: %u\n",
- mmc_hostname(host->mmc), data->bytes_xfered);
+ dev_dbg(&mmc->class_dev, "bytes xfered: %u\n",
+ data->bytes_xfered);
if (data->stop
&& !mci_set_stop_sent_is_completed(host))
@@ -998,8 +1012,8 @@ static irqreturn_t atmci_detect_change(int irq, void *dev_id)
int present = !gpio_get_value(irq_to_gpio(irq));
if (present != host->present) {
- pr_debug("%s: card %s\n", mmc_hostname(host->mmc),
- present ? "inserted" : "removed");
+ dev_dbg(&mmc->class_dev, "card %s\n",
+ present ? "inserted" : "removed");
host->present = present;
mci_set_card_detect_pending(host);
tasklet_schedule(&host->tasklet);
@@ -1058,7 +1072,7 @@ static int __devinit atmci_probe(struct platform_device *pdev)
mmc->ops = &atmci_ops;
mmc->f_min = (host->bus_hz + 511) / 512;
mmc->f_max = min((unsigned int)(host->bus_hz / 2), fmax);
- mmc->ocr_avail = 0x00100000;
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
mmc->caps |= MMC_CAP_4_BIT_DATA;
tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)mmc);
@@ -1071,8 +1085,7 @@ static int __devinit atmci_probe(struct platform_device *pdev)
host->present = 1;
if (host->detect_pin >= 0) {
if (gpio_request(host->detect_pin, "mmc_detect")) {
- printk(KERN_WARNING "%s: no detect pin available\n",
- mmc_hostname(host->mmc));
+ dev_dbg(&mmc->class_dev, "no detect pin available\n");
host->detect_pin = -1;
} else {
host->present = !gpio_get_value(host->detect_pin);
@@ -1080,8 +1093,7 @@ static int __devinit atmci_probe(struct platform_device *pdev)
}
if (host->wp_pin >= 0) {
if (gpio_request(host->wp_pin, "mmc_wp")) {
- printk(KERN_WARNING "%s: no WP pin available\n",
- mmc_hostname(host->mmc));
+ dev_dbg(&mmc->class_dev, "no WP pin available\n");
host->wp_pin = -1;
}
}
@@ -1090,14 +1102,12 @@ static int __devinit atmci_probe(struct platform_device *pdev)
ret = -ENOMEM;
host->dma.req.req.dmac = find_dma_controller(0);
if (!host->dma.req.req.dmac) {
- printk(KERN_ERR
- "mmci: No DMA controller available, aborting\n");
+ dev_dbg(&mmc->class_dev, "no DMA controller available\n");
goto out_free_irq;
}
ret = dma_alloc_channel(host->dma.req.req.dmac);
if (ret < 0) {
- printk(KERN_ERR
- "mmci: Unable to allocate DMA channel, aborting\n");
+ dev_dbg(&mmc->class_dev, "unable to allocate DMA channel\n");
goto out_free_irq;
}
host->dma.req.req.channel = ret;
@@ -1110,7 +1120,6 @@ static int __devinit atmci_probe(struct platform_device *pdev)
mci_writel(host, CR, MCI_BIT(SWRST));
mci_writel(host, IDR, ~0UL);
- mci_writel(host, CR, MCI_BIT(MCIEN));
platform_set_drvdata(pdev, host);
@@ -1122,17 +1131,16 @@ static int __devinit atmci_probe(struct platform_device *pdev)
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
DRIVER_NAME, mmc);
if (ret) {
- printk(KERN_ERR
- "%s: could not request IRQ %d for detect pin\n",
- mmc_hostname(mmc),
- gpio_to_irq(host->detect_pin));
+ dev_dbg(&mmc->class_dev,
+ "could not request IRQ %d for detect pin\n",
+ gpio_to_irq(host->detect_pin));
gpio_free(host->detect_pin);
host->detect_pin = -1;
}
}
- printk(KERN_INFO "%s: Atmel MCI controller at 0x%08lx irq %d\n",
- mmc_hostname(mmc), host->mapbase, irq);
+ dev_info(&mmc->class_dev, "Atmel MCI controller at 0x%08lx irq %d\n",
+ host->mapbase, irq);
atmci_init_debugfs(host);
--
1.5.3.2
_______________________________________________
Kernel mailing list
Kernel@avr32linux.org
http://duppen.flaskehals.net/cgi-bin/mailman/listinfo/kernel

View File

@ -0,0 +1,438 @@
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Subject: [PATCH 2/2] atmel_mci: Fix two subtle but deadly races
This patch fixes two possible races in the atmel_mci driver, at least
one of which may cause card probing to fail.
The first one may happen if a command fails and the next command is
queued before the controller is ready to accept a new one. Fix this by
not enabling error interrupts for commands and instead do any error
handling when the CMDRDY bit has been set.
The second one may happen after a successful read data transfer where
then next command is queued after the DMA transfer is complete, but
before the whole data transfer from the card is complete (i.e. the
card is still sending CRC, for example.) Fix this by waiting for the
NOTBUSY bit to be set before considering the request to be done. This
will also ensure that we actually see any CRC failures before
completing the request.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mmc/host/atmel-mci.c | 172 +++++++++++++-----------------------------
1 files changed, 54 insertions(+), 118 deletions(-)
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 1dc91b4..45323c9 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -28,20 +28,15 @@
#define DRIVER_NAME "atmel_mci"
-#define MCI_CMD_ERROR_FLAGS (MCI_BIT(RINDE) | MCI_BIT(RDIRE) | \
- MCI_BIT(RCRCE) | MCI_BIT(RENDE) | \
- MCI_BIT(RTOE))
#define MCI_DATA_ERROR_FLAGS (MCI_BIT(DCRCE) | MCI_BIT(DTOE) | \
MCI_BIT(OVRE) | MCI_BIT(UNRE))
enum {
EVENT_CMD_COMPLETE = 0,
- EVENT_CMD_ERROR,
EVENT_DATA_COMPLETE,
EVENT_DATA_ERROR,
EVENT_STOP_SENT,
EVENT_STOP_COMPLETE,
- EVENT_STOP_ERROR,
EVENT_DMA_ERROR,
EVENT_CARD_DETECT,
};
@@ -61,13 +56,14 @@ struct atmel_mci {
struct mmc_command *cmd;
struct mmc_data *data;
+ u32 cmd_status;
+ u32 data_status;
+ u32 stop_status;
u32 stop_cmdr;
- u32 stop_iflags;
struct tasklet_struct tasklet;
unsigned long pending_events;
unsigned long completed_events;
- u32 error_status;
int present;
int detect_pin;
@@ -99,8 +95,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
/* Test bit macros for completed events */
#define mci_cmd_is_complete(host) \
test_bit(EVENT_CMD_COMPLETE, &host->completed_events)
-#define mci_cmd_error_is_complete(host) \
- test_bit(EVENT_CMD_ERROR, &host->completed_events)
#define mci_data_is_complete(host) \
test_bit(EVENT_DATA_COMPLETE, &host->completed_events)
#define mci_data_error_is_complete(host) \
@@ -109,8 +103,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
test_bit(EVENT_STOP_SENT, &host->completed_events)
#define mci_stop_is_complete(host) \
test_bit(EVENT_STOP_COMPLETE, &host->completed_events)
-#define mci_stop_error_is_complete(host) \
- test_bit(EVENT_STOP_ERROR, &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) \
@@ -119,8 +111,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
/* Test and clear bit macros for pending events */
#define mci_clear_cmd_is_pending(host) \
test_and_clear_bit(EVENT_CMD_COMPLETE, &host->pending_events)
-#define mci_clear_cmd_error_is_pending(host) \
- test_and_clear_bit(EVENT_CMD_ERROR, &host->pending_events)
#define mci_clear_data_is_pending(host) \
test_and_clear_bit(EVENT_DATA_COMPLETE, &host->pending_events)
#define mci_clear_data_error_is_pending(host) \
@@ -129,8 +119,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
test_and_clear_bit(EVENT_STOP_SENT, &host->pending_events)
#define mci_clear_stop_is_pending(host) \
test_and_clear_bit(EVENT_STOP_COMPLETE, &host->pending_events)
-#define mci_clear_stop_error_is_pending(host) \
- test_and_clear_bit(EVENT_STOP_ERROR, &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) \
@@ -139,8 +127,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
/* Test and set bit macros for completed events */
#define mci_set_cmd_is_completed(host) \
test_and_set_bit(EVENT_CMD_COMPLETE, &host->completed_events)
-#define mci_set_cmd_error_is_completed(host) \
- test_and_set_bit(EVENT_CMD_ERROR, &host->completed_events)
#define mci_set_data_is_completed(host) \
test_and_set_bit(EVENT_DATA_COMPLETE, &host->completed_events)
#define mci_set_data_error_is_completed(host) \
@@ -149,8 +135,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
test_and_set_bit(EVENT_STOP_SENT, &host->completed_events)
#define mci_set_stop_is_completed(host) \
test_and_set_bit(EVENT_STOP_COMPLETE, &host->completed_events)
-#define mci_set_stop_error_is_completed(host) \
- test_and_set_bit(EVENT_STOP_ERROR, &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) \
@@ -159,8 +143,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
/* Set bit macros for completed events */
#define mci_set_cmd_complete(host) \
set_bit(EVENT_CMD_COMPLETE, &host->completed_events)
-#define mci_set_cmd_error_complete(host) \
- set_bit(EVENT_CMD_ERROR, &host->completed_events)
#define mci_set_data_complete(host) \
set_bit(EVENT_DATA_COMPLETE, &host->completed_events)
#define mci_set_data_error_complete(host) \
@@ -169,8 +151,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
set_bit(EVENT_STOP_SENT, &host->completed_events)
#define mci_set_stop_complete(host) \
set_bit(EVENT_STOP_COMPLETE, &host->completed_events)
-#define mci_set_stop_error_complete(host) \
- set_bit(EVENT_STOP_ERROR, &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) \
@@ -179,8 +159,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
/* Set bit macros for pending events */
#define mci_set_cmd_pending(host) \
set_bit(EVENT_CMD_COMPLETE, &host->pending_events)
-#define mci_set_cmd_error_pending(host) \
- set_bit(EVENT_CMD_ERROR, &host->pending_events)
#define mci_set_data_pending(host) \
set_bit(EVENT_DATA_COMPLETE, &host->pending_events)
#define mci_set_data_error_pending(host) \
@@ -189,8 +167,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
set_bit(EVENT_STOP_SENT, &host->pending_events)
#define mci_set_stop_pending(host) \
set_bit(EVENT_STOP_COMPLETE, &host->pending_events)
-#define mci_set_stop_error_pending(host) \
- set_bit(EVENT_STOP_ERROR, &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) \
@@ -199,8 +175,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
/* Clear bit macros for pending events */
#define mci_clear_cmd_pending(host) \
clear_bit(EVENT_CMD_COMPLETE, &host->pending_events)
-#define mci_clear_cmd_error_pending(host) \
- clear_bit(EVENT_CMD_ERROR, &host->pending_events)
#define mci_clear_data_pending(host) \
clear_bit(EVENT_DATA_COMPLETE, &host->pending_events)
#define mci_clear_data_error_pending(host) \
@@ -209,8 +183,6 @@ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
clear_bit(EVENT_STOP_SENT, &host->pending_events)
#define mci_clear_stop_pending(host) \
clear_bit(EVENT_STOP_COMPLETE, &host->pending_events)
-#define mci_clear_stop_error_pending(host) \
- clear_bit(EVENT_STOP_ERROR, &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) \
@@ -471,20 +443,16 @@ static void atmci_set_timeout(struct atmel_mci *host,
}
/*
- * Return mask with interrupt flags to be handled for this command.
+ * Return mask with command flags to be enabled for this command.
*/
static u32 atmci_prepare_command(struct mmc_host *mmc,
- struct mmc_command *cmd,
- u32 *cmd_flags)
+ struct mmc_command *cmd)
{
u32 cmdr;
- u32 iflags;
cmd->error = MMC_ERR_NONE;
- cmdr = 0;
- BUG_ON(MCI_BFEXT(CMDNB, cmdr) != 0);
- cmdr = MCI_BFINS(CMDNB, cmd->opcode, cmdr);
+ cmdr = MCI_BF(CMDNB, cmd->opcode);
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136)
@@ -503,16 +471,11 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN)
cmdr |= MCI_BIT(OPDCMD);
- iflags = MCI_BIT(CMDRDY) | MCI_CMD_ERROR_FLAGS;
- if (!(cmd->flags & MMC_RSP_CRC))
- iflags &= ~MCI_BIT(RCRCE);
-
dev_dbg(&mmc->class_dev,
"cmd: op %02x arg %08x flags %08x, cmdflags %08lx\n",
cmd->opcode, cmd->arg, cmd->flags, (unsigned long)cmdr);
- *cmd_flags = cmdr;
- return iflags;
+ return cmdr;
}
static void atmci_start_command(struct atmel_mci *host,
@@ -596,13 +559,13 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->pending_events = 0;
host->completed_events = 0;
- iflags = atmci_prepare_command(mmc, mrq->cmd, &cmdflags);
+ iflags = MCI_BIT(CMDRDY);
+ cmdflags = atmci_prepare_command(mmc, mrq->cmd);
if (mrq->stop) {
- BUG_ON(!data);
+ WARN_ON(!data);
- host->stop_iflags = atmci_prepare_command(mmc, mrq->stop,
- &host->stop_cmdr);
+ host->stop_cmdr = atmci_prepare_command(mmc, mrq->stop);
host->stop_cmdr |= MCI_BF(TRCMD, MCI_TRCMD_STOP_TRANS);
if (!(data->flags & MMC_DATA_WRITE))
host->stop_cmdr |= MCI_BIT(TRDIR);
@@ -716,7 +679,7 @@ static void send_stop_cmd(struct mmc_host *mmc, struct mmc_data *data,
struct atmel_mci *host = mmc_priv(mmc);
atmci_start_command(host, data->stop, host->stop_cmdr | flags);
- mci_writel(host, IER, host->stop_iflags);
+ mci_writel(host, IER, MCI_BIT(CMDRDY));
}
static void atmci_data_complete(struct atmel_mci *host, struct mmc_data *data)
@@ -735,18 +698,30 @@ static void atmci_data_complete(struct atmel_mci *host, struct mmc_data *data)
atmci_request_end(host->mmc, data->mrq);
}
-static void atmci_command_error(struct mmc_host *mmc,
- struct mmc_command *cmd,
- u32 status)
+static void atmci_command_complete(struct atmel_mci *host,
+ struct mmc_command *cmd, u32 status)
{
- dev_dbg(&mmc->class_dev, "command error: status=0x%08x\n", status);
-
if (status & MCI_BIT(RTOE))
cmd->error = MMC_ERR_TIMEOUT;
- else if (status & MCI_BIT(RCRCE))
+ else if ((cmd->flags & MMC_RSP_CRC)
+ && (status & MCI_BIT(RCRCE)))
cmd->error = MMC_ERR_BADCRC;
- else
+ else if (status & (MCI_BIT(RINDE) | MCI_BIT(RDIRE) | MCI_BIT(RENDE)))
cmd->error = MMC_ERR_FAILED;
+
+ if (cmd->error != MMC_ERR_NONE) {
+ dev_dbg(&host->mmc->class_dev,
+ "command error: op=0x%x status=0x%08x\n",
+ cmd->opcode, status);
+
+ if (cmd->data) {
+ dma_stop_request(host->dma.req.req.dmac,
+ host->dma.req.req.channel);
+ mci_writel(host, IDR, MCI_BIT(NOTBUSY)
+ | MCI_DATA_ERROR_FLAGS);
+ host->data = NULL;
+ }
+ }
}
static void atmci_tasklet_func(unsigned long priv)
@@ -761,38 +736,16 @@ static void atmci_tasklet_func(unsigned long priv)
host->pending_events, host->completed_events,
mci_readl(host, IMR));
- if (mci_clear_cmd_error_is_pending(host)) {
- struct mmc_command *cmd;
-
- mci_set_cmd_error_complete(host);
- mci_clear_cmd_pending(host);
- cmd = host->mrq->cmd;
-
- if (cmd->data) {
- dma_stop_request(host->dma.req.req.dmac,
- host->dma.req.req.channel);
- host->data = NULL;
- }
-
- atmci_command_error(mmc, cmd, host->error_status);
- atmci_request_end(mmc, cmd->mrq);
- }
- if (mci_clear_stop_error_is_pending(host)) {
- mci_set_stop_error_complete(host);
- mci_clear_stop_pending(host);
- atmci_command_error(mmc, host->mrq->stop,
- host->error_status);
- if (!host->data)
- atmci_request_end(mmc, host->mrq);
- }
if (mci_clear_cmd_is_pending(host)) {
mci_set_cmd_complete(host);
- if (!mrq->data || mci_data_is_complete(host)
+ atmci_command_complete(host, mrq->cmd, host->cmd_status);
+ if (!host->data || mci_data_is_complete(host)
|| mci_data_error_is_complete(host))
atmci_request_end(mmc, mrq);
}
if (mci_clear_stop_is_pending(host)) {
mci_set_stop_complete(host);
+ atmci_command_complete(host, mrq->stop, host->stop_status);
if (mci_data_is_complete(host)
|| mci_data_error_is_complete(host))
atmci_request_end(mmc, mrq);
@@ -815,7 +768,7 @@ static void atmci_tasklet_func(unsigned long priv)
atmci_data_complete(host, data);
}
if (mci_clear_data_error_is_pending(host)) {
- u32 status = host->error_status;
+ u32 status = host->data_status;
mci_set_data_error_complete(host);
mci_clear_data_pending(host);
@@ -858,10 +811,8 @@ static void atmci_tasklet_func(unsigned long priv)
/* Clean up queue if present */
if (mrq) {
- if (!mci_cmd_is_complete(host)
- && !mci_cmd_error_is_complete(host)) {
+ if (!mci_cmd_is_complete(host))
mrq->cmd->error = MMC_ERR_TIMEOUT;
- }
if (mrq->data && !mci_data_is_complete(host)
&& !mci_data_error_is_complete(host)) {
dma_stop_request(host->dma.req.req.dmac,
@@ -869,10 +820,8 @@ static void atmci_tasklet_func(unsigned long priv)
host->data->error = MMC_ERR_TIMEOUT;
atmci_data_complete(host, data);
}
- if (mrq->stop && !mci_stop_is_complete(host)
- && !mci_stop_error_is_complete(host)) {
+ if (mrq->stop && !mci_stop_is_complete(host))
mrq->stop->error = MMC_ERR_TIMEOUT;
- }
host->cmd = NULL;
atmci_request_end(mmc, mrq);
@@ -895,13 +844,16 @@ static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status)
cmd->resp[2] = mci_readl(host, RSPR);
cmd->resp[3] = mci_readl(host, RSPR);
- mci_writel(host, IDR, MCI_BIT(CMDRDY) | MCI_CMD_ERROR_FLAGS);
+ mci_writel(host, IDR, MCI_BIT(CMDRDY));
host->cmd = NULL;
- if (mci_stop_sent_is_complete(host))
+ if (mci_stop_sent_is_complete(host)) {
+ host->stop_status = status;
mci_set_stop_pending(host);
- else
+ } else {
+ host->cmd_status = status;
mci_set_cmd_pending(host);
+ }
tasklet_schedule(&host->tasklet);
}
@@ -920,18 +872,16 @@ static void atmci_xfer_complete(struct dma_request *_req)
if (data->stop && !mci_set_stop_sent_is_completed(host))
send_stop_cmd(host->mmc, data, 0);
- if (data->flags & MMC_DATA_READ) {
- mci_writel(host, IDR, MCI_DATA_ERROR_FLAGS);
- mci_set_data_pending(host);
- tasklet_schedule(&host->tasklet);
- } else {
- /*
- * For the WRITE case, wait for NOTBUSY. This function
- * is called when everything has been written to the
- * controller, not when the card is done programming.
- */
- mci_writel(host, IER, MCI_BIT(NOTBUSY));
- }
+ /*
+ * Regardless of what the documentation says, we have to wait
+ * for NOTBUSY even after block read operations.
+ *
+ * When the DMA transfer is complete, the controller may still
+ * be reading the CRC from the card, i.e. the data transfer is
+ * still in progress and we haven't seen all the potential
+ * error bits yet.
+ */
+ mci_writel(host, IER, MCI_BIT(NOTBUSY));
}
static void atmci_dma_error(struct dma_request *_req)
@@ -963,24 +913,10 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
pending = status & mask;
do {
- if (pending & MCI_CMD_ERROR_FLAGS) {
- mci_writel(host, IDR, (MCI_BIT(CMDRDY)
- | MCI_BIT(NOTBUSY)
- | MCI_CMD_ERROR_FLAGS
- | MCI_DATA_ERROR_FLAGS));
- host->error_status = status;
- host->cmd = NULL;
- if (mci_stop_sent_is_complete(host))
- mci_set_stop_error_pending(host);
- else
- mci_set_cmd_error_pending(host);
- tasklet_schedule(&host->tasklet);
- break;
- }
if (pending & MCI_DATA_ERROR_FLAGS) {
mci_writel(host, IDR, (MCI_BIT(NOTBUSY)
| MCI_DATA_ERROR_FLAGS));
- host->error_status = status;
+ host->data_status = status;
mci_set_data_error_pending(host);
tasklet_schedule(&host->tasklet);
break;
--
1.5.3.2
_______________________________________________
Kernel mailing list
Kernel@avr32linux.org
http://duppen.flaskehals.net/cgi-bin/mailman/listinfo/kernel

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -81,11 +81,17 @@ config BR2_LINUX_2_6_STABLE
help
Linux 2.6.22.1
config BR2_LINUX_2_6_22_10
bool "Linux 2.6.22.10"
depends BR2_PACKAGE_LINUX
help
Linux 2.6.22.10
config BR2_LINUX_2_6_22_1
bool "Linux 2.6.22.1"
depends BR2_PACKAGE_LINUX
help
Linux 2.6.22-rc1
Linux 2.6.22.1
config BR2_LINUX_2_6_22
bool "Linux 2.6.22"
@ -212,13 +218,14 @@ config BR2_DOWNLOAD_LINUX26_VERSION
default "2.6.21.6" if BR2_LINUX_2_6_21_6
default "2.6.22" if BR2_LINUX_2_6_22
default "2.6.22.1" if BR2_LINUX_2_6_22_1
default "2.6.22.10" if BR2_LINUX_2_6_22_10
default "2.6.22" if BR2_LINUX_2_6_23_RC1
default "2.6.22" if BR2_LINUX_2_6_SNAP
default "2.6.22" if BR2_LINUX_2_6_MM
default $(BR2_CUSTOM_DOWNLOAD_LINUX26_VERSION) if BR2_LINUX_CUSTOM
config BR2_LINUX26_VERSION
string "Selected Version:"
string #"Selected Version:"
default "2.6.15" if BR2_LINUX_2_6_15
default "2.6.16" if BR2_LINUX_2_6_16
default "2.6.17" if BR2_LINUX_2_6_17
@ -232,6 +239,7 @@ config BR2_LINUX26_VERSION
default "2.6.21.6" if BR2_LINUX_2_6_21_6
default "2.6.22" if BR2_LINUX_2_6_22
default "2.6.22.1" if BR2_LINUX_2_6_22_1
default "2.6.22.10" if BR2_LINUX_2_6_22_10
default "2.6.22" if BR2_LINUX_2_6_23_RC1
default "2.6.22" if BR2_LINUX_2_6_SNAP
default "2.6.22" if BR2_LINUX_2_6_MM
@ -252,6 +260,7 @@ config BR2_LINUX26_RC_PATCH
default "" if BR2_LINUX_2_6_21_6
default "" if BR2_LINUX_2_6_22
default "" if BR2_LINUX_2_6_22_1
default "" if BR2_LINUX_2_6_22_10
default "patch-2.6.23-rc1.bz2" if BR2_LINUX_2_6_23_RC1
default $(BR2_CUSTOM_LINUX26_RC_PATCH) if BR2_LINUX_CUSTOM

View File

@ -6,7 +6,9 @@ comment "Kernel Header Options"
choice
prompt "Kernel Headers"
default BR2_KERNEL_HEADERS_2_6_22_10 if BR2_avr32
default BR2_KERNEL_HEADERS_2_6_22
help
Select the version of kernel header files you wish to use.
You must select the correct set of header files to match
@ -63,10 +65,18 @@ choice
depends !BR2_nios2
bool "Linux 2.6.22.1 kernel headers"
config BR2_KERNEL_HEADERS_2_6_22_10
depends !BR2_nios2
bool "Linux 2.6.22.10 kernel headers"
config BR2_KERNEL_HEADERS_2_6_22
depends !BR2_avr32 && !BR2_nios2
bool "Latest Linux 2.6.22.x kernel headers"
config BR2_KERNEL_HEADERS_2_6_23
depends !BR2_avr32 && !BR2_nios2
bool "Latest Linux 2.6.23.x kernel headers"
config BR2_KERNEL_HEADERS_SNAP
bool "Linux 2.6 snapshot"
@ -98,25 +108,27 @@ config BR2_KERNEL_HEADERS_RT
config BR2_KERNEL_HEADERS_PATCH_DIR
bool "Add additional headers from $(KERNEL_HEADERS_PATCH_DIR)"
default n
depends BR2_KERNEL_HEADERS_2_6_20_4 || BR2_KERNEL_HEADERS_2_6_21_5 || BR2_KERNEL_HEADERS_2_6_22_1
depends BR2_KERNEL_HEADERS_2_6_20_4 || BR2_KERNEL_HEADERS_2_6_21_5 || BR2_KERNEL_HEADERS_2_6_22_1 || BR2_KERNEL_HEADERS_2_6_22_10
help
Apply additional kernel patches defined by KERNEL_HEADERS_PATCH_DIR
in your board directory.
config BR2_DEFAULT_KERNEL_HEADERS
string
default "2.4.25" if BR2_KERNEL_HEADERS_2_4_25
default "2.4.27" if BR2_KERNEL_HEADERS_2_4_27
default "2.4.29" if BR2_KERNEL_HEADERS_2_4_29
default "2.4.31" if BR2_KERNEL_HEADERS_2_4_31
default "2.6.9" if BR2_KERNEL_HEADERS_2_6_9
default "2.6.11" if BR2_KERNEL_HEADERS_2_6_11
default "2.6.12" if BR2_KERNEL_HEADERS_2_6_12
default "2.6.20.4" if BR2_KERNEL_HEADERS_2_6_20_4
default "2.6.20.20" if BR2_KERNEL_HEADERS_2_6_20
default "2.6.21.5" if BR2_KERNEL_HEADERS_2_6_21_5
default "2.6.21.7" if BR2_KERNEL_HEADERS_2_6_21
default "2.6.22.1" if BR2_KERNEL_HEADERS_2_6_22_1
default "2.6.22.9" if BR2_KERNEL_HEADERS_2_6_22
default "2.6" if BR2_KERNEL_HEADERS_SNAP
default "2.4.25" if BR2_KERNEL_HEADERS_2_4_25
default "2.4.27" if BR2_KERNEL_HEADERS_2_4_27
default "2.4.29" if BR2_KERNEL_HEADERS_2_4_29
default "2.4.31" if BR2_KERNEL_HEADERS_2_4_31
default "2.6.9" if BR2_KERNEL_HEADERS_2_6_9
default "2.6.11" if BR2_KERNEL_HEADERS_2_6_11
default "2.6.12" if BR2_KERNEL_HEADERS_2_6_12
default "2.6.20.4" if BR2_KERNEL_HEADERS_2_6_20_4
default "2.6.20.20" if BR2_KERNEL_HEADERS_2_6_20
default "2.6.21.5" if BR2_KERNEL_HEADERS_2_6_21_5
default "2.6.21.7" if BR2_KERNEL_HEADERS_2_6_21
default "2.6.22.1" if BR2_KERNEL_HEADERS_2_6_22_1
default "2.6.22.10" if BR2_KERNEL_HEADERS_2_6_22_10
default "2.6.22.10" if BR2_KERNEL_HEADERS_2_6_22
default "2.6.23" if BR2_KERNEL_HEADERS_2_6_22
default "2.6" if BR2_KERNEL_HEADERS_SNAP