summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-10-11 10:47:50 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2010-10-11 13:22:13 +0200
commitbe2be409c04a0aee2b4d04decd132a046582dff9 (patch)
tree65106fa03c49744d79711cb78fad0d32878258a4 /drivers
parentf78e8f84fec3dcaada1a8334c896a99b677bf24f (diff)
downloadbarebox-be2be409c04a0aee2b4d04decd132a046582dff9.tar.gz
barebox-be2be409c04a0aee2b4d04decd132a046582dff9.tar.xz
mci: align write buffer if necessary
Most SD controllers need some kind of alignment for writing blocks. Instead of coding this in every driver, align write blocks to a 4 byte alignment in the mci layer. For DMA accesses we may need bigger alignment, but let's solve this problem when we have it. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mci/mci-core.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 57b82bfb0c..6a35d54654 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -94,6 +94,8 @@ static int mci_set_blocklen(struct device_d *mci_dev, unsigned len)
return mci_send_cmd(mci_dev, &cmd, NULL);
}
+static void *sector_buf;
+
/**
* Write one block of data to the card
* @param mci_dev MCI instance
@@ -106,13 +108,21 @@ static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned b
struct mci *mci = GET_MCI_DATA(mci_dev);
struct mci_cmd cmd;
struct mci_data data;
+ const void *buf;
+
+ if ((unsigned long)src & 0x3) {
+ memcpy(sector_buf, src, 512);
+ buf = sector_buf;
+ } else {
+ buf = src;
+ }
mci_setup_cmd(&cmd,
MMC_CMD_WRITE_SINGLE_BLOCK,
mci->high_capacity != 0 ? blocknum : blocknum * mci->write_bl_len,
MMC_RSP_R1);
- data.src = src;
+ data.src = buf;
data.blocks = 1;
data.blocksize = mci->write_bl_len;
data.flags = MMC_DATA_WRITE;
@@ -1299,6 +1309,10 @@ static struct driver_d mci_driver = {
static int mci_init(void)
{
+ sector_buf = memalign(32, 512);
+ if (!sector_buf)
+ return -ENOMEM;
+
return register_driver(&mci_driver);
}