mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
Merge remote branch 'rmk/for-linus' into for-linus
* rmk/for-linus: (1557 commits) ARM: 6806/1: irq: introduce entry and exit functions for chained handlers ARM: 6781/1: Thumb-2: Work around buggy Thumb-2 short branch relocations in gas ARM: 6747/1: P2V: Thumb2 support ARM: 6798/1: aout-core: zero thread debug registers in a.out core dump ARM: 6796/1: Footbridge: Fix I/O mappings for NOMMU mode ARM: 6784/1: errata: no automatic Store Buffer drain on Cortex-A9 ARM: 6772/1: errata: possible fault MMU translations following an ASID switch ARM: 6776/1: mach-ux500: activate fix for errata 753970 ARM: 6794/1: SPEAr: Append UL to device address macros. ARM: 6793/1: SPEAr: Remove unused *_SIZE macros from spear*.h files ARM: 6792/1: SPEAr: Replace SIZE macro's with SZ_4K macros ARM: 6791/1: SPEAr3xx: Declare device structures after shirq code ARM: 6790/1: SPEAr: Clock Framework: Rename usbd clock and align apb_clk entry ARM: 6789/1: SPEAr3xx: Rename sdio to sdhci ARM: 6788/1: SPEAr: Include mach/hardware.h instead of mach/spear.h ARM: 6787/1: SPEAr: Reorder #includes in .h & .c files. ARM: 6681/1: SPEAr: add debugfs support to clk API ARM: 6703/1: SPEAr: update clk API support ARM: 6679/1: SPEAr: make clk API functions more generic ARM: 6737/1: SPEAr: formalized timer support ... Conflicts: arch/arm/mach-msm/board-msm7x27.c arch/arm/mach-msm/board-msm7x30.c arch/arm/mach-msm/board-qsd8x50.c arch/arm/mach-msm/board-sapphire.c arch/arm/mach-msm/include/mach/memory.h
This commit is contained in:
commit
92c260f755
1728 changed files with 26170 additions and 14144 deletions
|
|
@ -792,7 +792,6 @@ int mmc_attach_sdio(struct mmc_host *host)
|
|||
*/
|
||||
mmc_release_host(host);
|
||||
err = mmc_add_card(host->card);
|
||||
mmc_claim_host(host);
|
||||
if (err)
|
||||
goto remove_added;
|
||||
|
||||
|
|
@ -805,12 +804,12 @@ int mmc_attach_sdio(struct mmc_host *host)
|
|||
goto remove_added;
|
||||
}
|
||||
|
||||
mmc_claim_host(host);
|
||||
return 0;
|
||||
|
||||
|
||||
remove_added:
|
||||
/* Remove without lock if the device has been added. */
|
||||
mmc_release_host(host);
|
||||
mmc_sdio_remove(host);
|
||||
mmc_claim_host(host);
|
||||
remove:
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ static int __devinit sdh_probe(struct platform_device *pdev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev);
|
||||
mmc = mmc_alloc_host(sizeof(struct sdh_host), &pdev->dev);
|
||||
if (!mmc) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
|
@ -827,8 +828,8 @@ static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
|
|||
}
|
||||
|
||||
host->clk = clk_get(&pdev->dev, "mmc");
|
||||
if (!host->clk) {
|
||||
ret = -ENOENT;
|
||||
if (IS_ERR(host->clk)) {
|
||||
ret = PTR_ERR(host->clk);
|
||||
dev_err(&pdev->dev, "Failed to get mmc clock\n");
|
||||
goto err_free_host;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/highmem.h>
|
||||
|
|
@ -46,10 +47,6 @@ static unsigned int fmax = 515633;
|
|||
* is asserted (likewise for RX)
|
||||
* @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
|
||||
* is asserted (likewise for RX)
|
||||
* @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
|
||||
* and will not work at all.
|
||||
* @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
|
||||
* using DMA.
|
||||
* @sdio: variant supports SDIO
|
||||
* @st_clkdiv: true if using a ST-specific clock divider algorithm
|
||||
*/
|
||||
|
|
@ -59,8 +56,6 @@ struct variant_data {
|
|||
unsigned int datalength_bits;
|
||||
unsigned int fifosize;
|
||||
unsigned int fifohalfsize;
|
||||
bool broken_blockend;
|
||||
bool broken_blockend_dma;
|
||||
bool sdio;
|
||||
bool st_clkdiv;
|
||||
};
|
||||
|
|
@ -76,7 +71,6 @@ static struct variant_data variant_u300 = {
|
|||
.fifohalfsize = 8 * 4,
|
||||
.clkreg_enable = 1 << 13, /* HWFCEN */
|
||||
.datalength_bits = 16,
|
||||
.broken_blockend_dma = true,
|
||||
.sdio = true,
|
||||
};
|
||||
|
||||
|
|
@ -86,7 +80,6 @@ static struct variant_data variant_ux500 = {
|
|||
.clkreg = MCI_CLK_ENABLE,
|
||||
.clkreg_enable = 1 << 14, /* HWFCEN */
|
||||
.datalength_bits = 24,
|
||||
.broken_blockend = true,
|
||||
.sdio = true,
|
||||
.st_clkdiv = true,
|
||||
};
|
||||
|
|
@ -210,8 +203,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
|||
host->data = data;
|
||||
host->size = data->blksz * data->blocks;
|
||||
host->data_xfered = 0;
|
||||
host->blockend = false;
|
||||
host->dataend = false;
|
||||
|
||||
mmci_init_sg(host, data);
|
||||
|
||||
|
|
@ -288,21 +279,26 @@ static void
|
|||
mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
|
||||
unsigned int status)
|
||||
{
|
||||
struct variant_data *variant = host->variant;
|
||||
|
||||
/* First check for errors */
|
||||
if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
|
||||
dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
|
||||
if (status & MCI_DATACRCFAIL)
|
||||
data->error = -EILSEQ;
|
||||
else if (status & MCI_DATATIMEOUT)
|
||||
data->error = -ETIMEDOUT;
|
||||
else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
|
||||
data->error = -EIO;
|
||||
u32 remain, success;
|
||||
|
||||
/* Force-complete the transaction */
|
||||
host->blockend = true;
|
||||
host->dataend = true;
|
||||
/* Calculate how far we are into the transfer */
|
||||
remain = readl(host->base + MMCIDATACNT);
|
||||
success = data->blksz * data->blocks - remain;
|
||||
|
||||
dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
|
||||
if (status & MCI_DATACRCFAIL) {
|
||||
/* Last block was not successful */
|
||||
host->data_xfered = round_down(success - 1, data->blksz);
|
||||
data->error = -EILSEQ;
|
||||
} else if (status & MCI_DATATIMEOUT) {
|
||||
host->data_xfered = round_down(success, data->blksz);
|
||||
data->error = -ETIMEDOUT;
|
||||
} else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
|
||||
host->data_xfered = round_down(success, data->blksz);
|
||||
data->error = -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* We hit an error condition. Ensure that any data
|
||||
|
|
@ -321,61 +317,14 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On ARM variants in PIO mode, MCI_DATABLOCKEND
|
||||
* is always sent first, and we increase the
|
||||
* transfered number of bytes for that IRQ. Then
|
||||
* MCI_DATAEND follows and we conclude the transaction.
|
||||
*
|
||||
* On the Ux500 single-IRQ variant MCI_DATABLOCKEND
|
||||
* doesn't seem to immediately clear from the status,
|
||||
* so we can't use it keep count when only one irq is
|
||||
* used because the irq will hit for other reasons, and
|
||||
* then the flag is still up. So we use the MCI_DATAEND
|
||||
* IRQ at the end of the entire transfer because
|
||||
* MCI_DATABLOCKEND is broken.
|
||||
*
|
||||
* In the U300, the IRQs can arrive out-of-order,
|
||||
* e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
|
||||
* so for this case we use the flags "blockend" and
|
||||
* "dataend" to make sure both IRQs have arrived before
|
||||
* concluding the transaction. (This does not apply
|
||||
* to the Ux500 which doesn't fire MCI_DATABLOCKEND
|
||||
* at all.) In DMA mode it suffers from the same problem
|
||||
* as the Ux500.
|
||||
*/
|
||||
if (status & MCI_DATABLOCKEND) {
|
||||
/*
|
||||
* Just being a little over-cautious, we do not
|
||||
* use this progressive update if the hardware blockend
|
||||
* flag is unreliable: since it can stay high between
|
||||
* IRQs it will corrupt the transfer counter.
|
||||
*/
|
||||
if (!variant->broken_blockend)
|
||||
host->data_xfered += data->blksz;
|
||||
host->blockend = true;
|
||||
}
|
||||
if (status & MCI_DATABLOCKEND)
|
||||
dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
|
||||
|
||||
if (status & MCI_DATAEND)
|
||||
host->dataend = true;
|
||||
|
||||
/*
|
||||
* On variants with broken blockend we shall only wait for dataend,
|
||||
* on others we must sync with the blockend signal since they can
|
||||
* appear out-of-order.
|
||||
*/
|
||||
if (host->dataend && (host->blockend || variant->broken_blockend)) {
|
||||
if (status & MCI_DATAEND || data->error) {
|
||||
mmci_stop_data(host);
|
||||
|
||||
/* Reset these flags */
|
||||
host->blockend = false;
|
||||
host->dataend = false;
|
||||
|
||||
/*
|
||||
* Variants with broken blockend flags need to handle the
|
||||
* end of the entire transfer here.
|
||||
*/
|
||||
if (variant->broken_blockend && !data->error)
|
||||
if (!data->error)
|
||||
/* The error clause is handled above, success! */
|
||||
host->data_xfered += data->blksz * data->blocks;
|
||||
|
||||
if (!data->stop) {
|
||||
|
|
@ -394,15 +343,15 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
|
|||
|
||||
host->cmd = NULL;
|
||||
|
||||
cmd->resp[0] = readl(base + MMCIRESPONSE0);
|
||||
cmd->resp[1] = readl(base + MMCIRESPONSE1);
|
||||
cmd->resp[2] = readl(base + MMCIRESPONSE2);
|
||||
cmd->resp[3] = readl(base + MMCIRESPONSE3);
|
||||
|
||||
if (status & MCI_CMDTIMEOUT) {
|
||||
cmd->error = -ETIMEDOUT;
|
||||
} else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
|
||||
cmd->error = -EILSEQ;
|
||||
} else {
|
||||
cmd->resp[0] = readl(base + MMCIRESPONSE0);
|
||||
cmd->resp[1] = readl(base + MMCIRESPONSE1);
|
||||
cmd->resp[2] = readl(base + MMCIRESPONSE2);
|
||||
cmd->resp[3] = readl(base + MMCIRESPONSE3);
|
||||
}
|
||||
|
||||
if (!cmd->data || cmd->error) {
|
||||
|
|
@ -770,7 +719,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
|||
struct variant_data *variant = id->data;
|
||||
struct mmci_host *host;
|
||||
struct mmc_host *mmc;
|
||||
unsigned int mask;
|
||||
int ret;
|
||||
|
||||
/* must have platform data */
|
||||
|
|
@ -951,12 +899,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
|||
goto irq0_free;
|
||||
}
|
||||
|
||||
mask = MCI_IRQENABLE;
|
||||
/* Don't use the datablockend flag if it's broken */
|
||||
if (variant->broken_blockend)
|
||||
mask &= ~MCI_DATABLOCKEND;
|
||||
|
||||
writel(mask, host->base + MMCIMASK0);
|
||||
writel(MCI_IRQENABLE, host->base + MMCIMASK0);
|
||||
|
||||
amba_set_drvdata(dev, mmc);
|
||||
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@
|
|||
#define MCI_IRQENABLE \
|
||||
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
|
||||
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
|
||||
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
|
||||
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
|
||||
|
||||
/* These interrupts are directed to IRQ1 when two IRQ lines are available */
|
||||
#define MCI_IRQ1MASK \
|
||||
|
|
@ -177,9 +177,6 @@ struct mmci_host {
|
|||
struct timer_list timer;
|
||||
unsigned int oldstat;
|
||||
|
||||
bool blockend;
|
||||
bool dataend;
|
||||
|
||||
/* pio stuff */
|
||||
struct sg_mapping_iter sg_miter;
|
||||
unsigned int size;
|
||||
|
|
|
|||
|
|
@ -277,10 +277,43 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
|
|||
host->clock = clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdhci_s3c_platform_8bit_width - support 8bit buswidth
|
||||
* @host: The SDHCI host being queried
|
||||
* @width: MMC_BUS_WIDTH_ macro for the bus width being requested
|
||||
*
|
||||
* We have 8-bit width support but is not a v3 controller.
|
||||
* So we add platform_8bit_width() and support 8bit width.
|
||||
*/
|
||||
static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width)
|
||||
{
|
||||
u8 ctrl;
|
||||
|
||||
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
|
||||
|
||||
switch (width) {
|
||||
case MMC_BUS_WIDTH_8:
|
||||
ctrl |= SDHCI_CTRL_8BITBUS;
|
||||
ctrl &= ~SDHCI_CTRL_4BITBUS;
|
||||
break;
|
||||
case MMC_BUS_WIDTH_4:
|
||||
ctrl |= SDHCI_CTRL_4BITBUS;
|
||||
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sdhci_ops sdhci_s3c_ops = {
|
||||
.get_max_clock = sdhci_s3c_get_max_clk,
|
||||
.set_clock = sdhci_s3c_set_clock,
|
||||
.get_min_clock = sdhci_s3c_get_min_clock,
|
||||
.platform_8bit_width = sdhci_s3c_platform_8bit_width,
|
||||
};
|
||||
|
||||
static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
|
||||
|
|
@ -473,6 +506,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
|
|||
if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
|
||||
host->mmc->caps = MMC_CAP_NONREMOVABLE;
|
||||
|
||||
if (pdata->host_caps)
|
||||
host->mmc->caps |= pdata->host_caps;
|
||||
|
||||
host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
|
||||
SDHCI_QUIRK_32BIT_DMA_SIZE);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/mmc/host.h>
|
||||
|
|
|
|||
Loading…
Reference in a new issue