Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (278 commits) arm: remove machine_desc.io_pg_offst and .phys_io arm: use addruart macro to establish debug mappings arm: return both physical and virtual addresses from addruart arm/debug: consolidate addruart macros for CONFIG_DEBUG_ICEDCC ARM: make struct machine_desc definition coherent with its comment eukrea_mbimxsd-baseboard: Pass the correct GPIO to gpio_free cpuimx27: fix compile when ULPI is selected mach-pcm037_eet: fix compile errors Fixing ethernet driver compilation error for i.MX31 ADS board cpuimx51: update board support mx5: add cpuimx51sd module and its baseboard iomux-mx51: fix GPIO_1_xx 's IOMUX configuration imx-esdhc: update devices registration mx51: add resources for SD/MMC on i.MX51 iomux-mx51: fix SD1 and SD2's iomux configuration clock-mx51: rename CLOCK1 to CLOCK_CCGR for better readability clock-mx51: factorize clk_set_parent and clk_get_rate eukrea_mbimxsd: add support for DVI displays cpuimx25 & cpuimx35: fix OTG port registration in host mode i.MX31 and i.MX35 : fix errate TLSbo65953 and ENGcm09472 ...
This commit is contained in:
@@ -41,23 +41,35 @@ static unsigned int fmax = 515633;
|
||||
* @clkreg: default value for MCICLOCK register
|
||||
* @clkreg_enable: enable value for MMCICLOCK register
|
||||
* @datalength_bits: number of bits in the MMCIDATALENGTH register
|
||||
* @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
|
||||
* is asserted (likewise for RX)
|
||||
* @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
|
||||
* is asserted (likewise for RX)
|
||||
*/
|
||||
struct variant_data {
|
||||
unsigned int clkreg;
|
||||
unsigned int clkreg_enable;
|
||||
unsigned int datalength_bits;
|
||||
unsigned int fifosize;
|
||||
unsigned int fifohalfsize;
|
||||
};
|
||||
|
||||
static struct variant_data variant_arm = {
|
||||
.fifosize = 16 * 4,
|
||||
.fifohalfsize = 8 * 4,
|
||||
.datalength_bits = 16,
|
||||
};
|
||||
|
||||
static struct variant_data variant_u300 = {
|
||||
.fifosize = 16 * 4,
|
||||
.fifohalfsize = 8 * 4,
|
||||
.clkreg_enable = 1 << 13, /* HWFCEN */
|
||||
.datalength_bits = 16,
|
||||
};
|
||||
|
||||
static struct variant_data variant_ux500 = {
|
||||
.fifosize = 30 * 4,
|
||||
.fifohalfsize = 8 * 4,
|
||||
.clkreg = MCI_CLK_ENABLE,
|
||||
.clkreg_enable = 1 << 14, /* HWFCEN */
|
||||
.datalength_bits = 24,
|
||||
@@ -138,6 +150,7 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
|
||||
|
||||
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
||||
{
|
||||
struct variant_data *variant = host->variant;
|
||||
unsigned int datactrl, timeout, irqmask;
|
||||
unsigned long long clks;
|
||||
void __iomem *base;
|
||||
@@ -173,7 +186,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
||||
* If we have less than a FIFOSIZE of bytes to transfer,
|
||||
* trigger a PIO interrupt as soon as any data is available.
|
||||
*/
|
||||
if (host->size < MCI_FIFOSIZE)
|
||||
if (host->size < variant->fifosize)
|
||||
irqmask |= MCI_RXDATAAVLBLMASK;
|
||||
} else {
|
||||
/*
|
||||
@@ -332,13 +345,15 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
|
||||
|
||||
static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
|
||||
{
|
||||
struct variant_data *variant = host->variant;
|
||||
void __iomem *base = host->base;
|
||||
char *ptr = buffer;
|
||||
|
||||
do {
|
||||
unsigned int count, maxcnt;
|
||||
|
||||
maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : MCI_FIFOHALFSIZE;
|
||||
maxcnt = status & MCI_TXFIFOEMPTY ?
|
||||
variant->fifosize : variant->fifohalfsize;
|
||||
count = min(remain, maxcnt);
|
||||
|
||||
writesl(base + MMCIFIFO, ptr, count >> 2);
|
||||
@@ -362,6 +377,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct mmci_host *host = dev_id;
|
||||
struct sg_mapping_iter *sg_miter = &host->sg_miter;
|
||||
struct variant_data *variant = host->variant;
|
||||
void __iomem *base = host->base;
|
||||
unsigned long flags;
|
||||
u32 status;
|
||||
@@ -420,7 +436,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
|
||||
* If we're nearing the end of the read, switch to
|
||||
* "any data available" mode.
|
||||
*/
|
||||
if (status & MCI_RXACTIVE && host->size < MCI_FIFOSIZE)
|
||||
if (status & MCI_RXACTIVE && host->size < variant->fifosize)
|
||||
writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1);
|
||||
|
||||
/*
|
||||
@@ -564,18 +580,23 @@ static int mmci_get_ro(struct mmc_host *mmc)
|
||||
if (host->gpio_wp == -ENOSYS)
|
||||
return -ENOSYS;
|
||||
|
||||
return gpio_get_value(host->gpio_wp);
|
||||
return gpio_get_value_cansleep(host->gpio_wp);
|
||||
}
|
||||
|
||||
static int mmci_get_cd(struct mmc_host *mmc)
|
||||
{
|
||||
struct mmci_host *host = mmc_priv(mmc);
|
||||
struct mmci_platform_data *plat = host->plat;
|
||||
unsigned int status;
|
||||
|
||||
if (host->gpio_cd == -ENOSYS)
|
||||
status = host->plat->status(mmc_dev(host->mmc));
|
||||
else
|
||||
status = !gpio_get_value(host->gpio_cd);
|
||||
if (host->gpio_cd == -ENOSYS) {
|
||||
if (!plat->status)
|
||||
return 1; /* Assume always present */
|
||||
|
||||
status = plat->status(mmc_dev(host->mmc));
|
||||
} else
|
||||
status = !!gpio_get_value_cansleep(host->gpio_cd)
|
||||
^ plat->cd_invert;
|
||||
|
||||
/*
|
||||
* Use positive logic throughout - status is zero for no card,
|
||||
@@ -584,6 +605,15 @@ static int mmci_get_cd(struct mmc_host *mmc)
|
||||
return status;
|
||||
}
|
||||
|
||||
static irqreturn_t mmci_cd_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct mmci_host *host = dev_id;
|
||||
|
||||
mmc_detect_change(host->mmc, msecs_to_jiffies(500));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static const struct mmc_host_ops mmci_ops = {
|
||||
.request = mmci_request,
|
||||
.set_ios = mmci_set_ios,
|
||||
@@ -620,6 +650,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
||||
|
||||
host->gpio_wp = -ENOSYS;
|
||||
host->gpio_cd = -ENOSYS;
|
||||
host->gpio_cd_irq = -1;
|
||||
|
||||
host->hw_designer = amba_manf(dev);
|
||||
host->hw_revision = amba_rev(dev);
|
||||
@@ -699,7 +730,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
||||
if (host->vcc == NULL)
|
||||
mmc->ocr_avail = plat->ocr_mask;
|
||||
mmc->caps = plat->capabilities;
|
||||
mmc->caps |= MMC_CAP_NEEDS_POLL;
|
||||
|
||||
/*
|
||||
* We can do SGIO
|
||||
@@ -744,6 +774,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
||||
host->gpio_cd = plat->gpio_cd;
|
||||
else if (ret != -ENOSYS)
|
||||
goto err_gpio_cd;
|
||||
|
||||
ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd),
|
||||
mmci_cd_irq, 0,
|
||||
DRIVER_NAME " (cd)", host);
|
||||
if (ret >= 0)
|
||||
host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
|
||||
}
|
||||
if (gpio_is_valid(plat->gpio_wp)) {
|
||||
ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
|
||||
@@ -755,6 +791,10 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
||||
goto err_gpio_wp;
|
||||
}
|
||||
|
||||
if ((host->plat->status || host->gpio_cd != -ENOSYS)
|
||||
&& host->gpio_cd_irq < 0)
|
||||
mmc->caps |= MMC_CAP_NEEDS_POLL;
|
||||
|
||||
ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
|
||||
if (ret)
|
||||
goto unmap;
|
||||
@@ -781,6 +821,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
||||
if (host->gpio_wp != -ENOSYS)
|
||||
gpio_free(host->gpio_wp);
|
||||
err_gpio_wp:
|
||||
if (host->gpio_cd_irq >= 0)
|
||||
free_irq(host->gpio_cd_irq, host);
|
||||
if (host->gpio_cd != -ENOSYS)
|
||||
gpio_free(host->gpio_cd);
|
||||
err_gpio_cd:
|
||||
@@ -819,6 +861,8 @@ static int __devexit mmci_remove(struct amba_device *dev)
|
||||
|
||||
if (host->gpio_wp != -ENOSYS)
|
||||
gpio_free(host->gpio_wp);
|
||||
if (host->gpio_cd_irq >= 0)
|
||||
free_irq(host->gpio_cd_irq, host);
|
||||
if (host->gpio_cd != -ENOSYS)
|
||||
gpio_free(host->gpio_cd);
|
||||
|
||||
|
@@ -54,10 +54,16 @@
|
||||
#define MCI_DPSM_MODE (1 << 2)
|
||||
#define MCI_DPSM_DMAENABLE (1 << 3)
|
||||
#define MCI_DPSM_BLOCKSIZE (1 << 4)
|
||||
#define MCI_DPSM_RWSTART (1 << 8)
|
||||
#define MCI_DPSM_RWSTOP (1 << 9)
|
||||
#define MCI_DPSM_RWMOD (1 << 10)
|
||||
#define MCI_DPSM_SDIOEN (1 << 11)
|
||||
/* Control register extensions in the ST Micro U300 and Ux500 versions */
|
||||
#define MCI_ST_DPSM_RWSTART (1 << 8)
|
||||
#define MCI_ST_DPSM_RWSTOP (1 << 9)
|
||||
#define MCI_ST_DPSM_RWMOD (1 << 10)
|
||||
#define MCI_ST_DPSM_SDIOEN (1 << 11)
|
||||
/* Control register extensions in the ST Micro Ux500 versions */
|
||||
#define MCI_ST_DPSM_DMAREQCTL (1 << 12)
|
||||
#define MCI_ST_DPSM_DBOOTMODEEN (1 << 13)
|
||||
#define MCI_ST_DPSM_BUSYMODE (1 << 14)
|
||||
#define MCI_ST_DPSM_DDRMODE (1 << 15)
|
||||
|
||||
#define MMCIDATACNT 0x030
|
||||
#define MMCISTATUS 0x034
|
||||
@@ -133,13 +139,6 @@
|
||||
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
|
||||
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
|
||||
|
||||
/*
|
||||
* The size of the FIFO in bytes.
|
||||
*/
|
||||
#define MCI_FIFOSIZE (16*4)
|
||||
|
||||
#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
|
||||
|
||||
#define NR_SG 16
|
||||
|
||||
struct clk;
|
||||
@@ -154,6 +153,7 @@ struct mmci_host {
|
||||
struct clk *clk;
|
||||
int gpio_cd;
|
||||
int gpio_wp;
|
||||
int gpio_cd_irq;
|
||||
|
||||
unsigned int data_xfered;
|
||||
|
||||
|
Reference in New Issue
Block a user