Commit 1d6bebf2 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-mmc

parents 86166f98 3eee0d03
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/mmc/protocol.h> #include <linux/mmc/protocol.h>
#include <asm/div64.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
...@@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_host *host) ...@@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_host *host)
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{ {
unsigned int datactrl, timeout, irqmask; unsigned int datactrl, timeout, irqmask;
unsigned long long clks;
void __iomem *base; void __iomem *base;
DBG(host, "blksz %04x blks %04x flags %08x\n", DBG(host, "blksz %04x blks %04x flags %08x\n",
...@@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) ...@@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
mmci_init_sg(host, data); mmci_init_sg(host, data);
timeout = data->timeout_clks + clks = (unsigned long long)data->timeout_ns * host->cclk;
((unsigned long long)data->timeout_ns * host->cclk) / do_div(clks, 1000000000UL);
1000000000ULL;
timeout = data->timeout_clks + (unsigned int)clks;
base = host->base; base = host->base;
writel(timeout, base + MMCIDATATIMER); writel(timeout, base + MMCIDATATIMER);
......
...@@ -54,28 +54,6 @@ ...@@ -54,28 +54,6 @@
#define DBGF(x...) do { } while (0) #define DBGF(x...) do { } while (0)
#endif #endif
#ifdef CONFIG_MMC_DEBUG
void DBG_REG(int reg, u8 value)
{
int i;
printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ",
reg, (int)value, (int)value, (value < 0x20)?'.':value);
for (i = 7;i >= 0;i--)
{
if (value & (1 << i))
printk("x");
else
printk(".");
}
printk("\n");
}
#else
#define DBG_REG(r, v) do {} while (0)
#endif
/* /*
* Device resources * Device resources
*/ */
...@@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table); ...@@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
#endif /* CONFIG_PNP */ #endif /* CONFIG_PNP */
static const int config_ports[] = { 0x2E, 0x4E };
static const int unlock_codes[] = { 0x83, 0x87 };
static const int valid_ids[] = {
0x7112,
};
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static unsigned int nopnp = 0; static unsigned int nopnp = 0;
#else #else
...@@ -1050,6 +1035,20 @@ static struct mmc_host_ops wbsd_ops = { ...@@ -1050,6 +1035,20 @@ static struct mmc_host_ops wbsd_ops = {
* * * *
\*****************************************************************************/ \*****************************************************************************/
/*
* Helper function for card detection
*/
static void wbsd_detect_card(unsigned long data)
{
struct wbsd_host *host = (struct wbsd_host*)data;
BUG_ON(host == NULL);
DBG("Executing card detection\n");
mmc_detect_change(host->mmc);
}
/* /*
* Tasklets * Tasklets
*/ */
...@@ -1075,7 +1074,6 @@ static void wbsd_tasklet_card(unsigned long param) ...@@ -1075,7 +1074,6 @@ static void wbsd_tasklet_card(unsigned long param)
{ {
struct wbsd_host* host = (struct wbsd_host*)param; struct wbsd_host* host = (struct wbsd_host*)param;
u8 csr; u8 csr;
int change = 0;
spin_lock(&host->lock); spin_lock(&host->lock);
...@@ -1094,14 +1092,20 @@ static void wbsd_tasklet_card(unsigned long param) ...@@ -1094,14 +1092,20 @@ static void wbsd_tasklet_card(unsigned long param)
{ {
DBG("Card inserted\n"); DBG("Card inserted\n");
host->flags |= WBSD_FCARD_PRESENT; host->flags |= WBSD_FCARD_PRESENT;
change = 1;
/*
* Delay card detection to allow electrical connections
* to stabilise.
*/
mod_timer(&host->timer, jiffies + HZ/2);
} }
spin_unlock(&host->lock);
} }
else if (host->flags & WBSD_FCARD_PRESENT) else if (host->flags & WBSD_FCARD_PRESENT)
{ {
DBG("Card removed\n"); DBG("Card removed\n");
host->flags &= ~WBSD_FCARD_PRESENT; host->flags &= ~WBSD_FCARD_PRESENT;
change = 1;
if (host->mrq) if (host->mrq)
{ {
...@@ -1112,15 +1116,14 @@ static void wbsd_tasklet_card(unsigned long param) ...@@ -1112,15 +1116,14 @@ static void wbsd_tasklet_card(unsigned long param)
host->mrq->cmd->error = MMC_ERR_FAILED; host->mrq->cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet); tasklet_schedule(&host->finish_tasklet);
} }
}
/* /*
* Unlock first since we might get a call back. * Unlock first since we might get a call back.
*/ */
spin_unlock(&host->lock); spin_unlock(&host->lock);
if (change)
mmc_detect_change(host->mmc); mmc_detect_change(host->mmc);
}
} }
static void wbsd_tasklet_fifo(unsigned long param) static void wbsd_tasklet_fifo(unsigned long param)
...@@ -1324,6 +1327,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) ...@@ -1324,6 +1327,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
spin_lock_init(&host->lock); spin_lock_init(&host->lock);
/*
* Set up detection timer
*/
init_timer(&host->timer);
host->timer.data = (unsigned long)host;
host->timer.function = wbsd_detect_card;
/* /*
* Maximum number of segments. Worst case is one sector per segment * Maximum number of segments. Worst case is one sector per segment
* so this will be 64kB/512. * so this will be 64kB/512.
...@@ -1351,11 +1361,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) ...@@ -1351,11 +1361,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
static void __devexit wbsd_free_mmc(struct device* dev) static void __devexit wbsd_free_mmc(struct device* dev)
{ {
struct mmc_host* mmc; struct mmc_host* mmc;
struct wbsd_host* host;
mmc = dev_get_drvdata(dev); mmc = dev_get_drvdata(dev);
if (!mmc) if (!mmc)
return; return;
host = mmc_priv(mmc);
BUG_ON(host == NULL);
del_timer_sync(&host->timer);
mmc_free_host(mmc); mmc_free_host(mmc);
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
......
...@@ -8,13 +8,6 @@ ...@@ -8,13 +8,6 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
const int config_ports[] = { 0x2E, 0x4E };
const int unlock_codes[] = { 0x83, 0x87 };
const int valid_ids[] = {
0x7112,
};
#define LOCK_CODE 0xAA #define LOCK_CODE 0xAA
#define WBSD_CONF_SWRST 0x02 #define WBSD_CONF_SWRST 0x02
...@@ -187,4 +180,6 @@ struct wbsd_host ...@@ -187,4 +180,6 @@ struct wbsd_host
struct tasklet_struct timeout_tasklet; struct tasklet_struct timeout_tasklet;
struct tasklet_struct finish_tasklet; struct tasklet_struct finish_tasklet;
struct tasklet_struct block_tasklet; struct tasklet_struct block_tasklet;
struct timer_list timer; /* Card detection timer */
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment