aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2017-03-29 14:54:37 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2017-04-18 13:18:07 -0400
commit5ef1ecf060f28ecef313b5723f1fd39bf5a35f56 (patch)
tree5548e6d502bbb2b22a9cac9c9b07da93da286fc8
parent4f7d029b9bf009fbee76bb10c0c4351a1870d2f3 (diff)
mmc: sdio: fix alignment issue in struct sdio_func
Certain 64-bit systems (e.g. Amlogic Meson GX) require buffers to be used for DMA to be 8-byte-aligned. struct sdio_func has an embedded small DMA buffer not meeting this requirement. When testing switching to descriptor chain mode in meson-gx driver SDIO is broken therefore. Fix this by allocating the small DMA buffer separately as kmalloc ensures that the returned memory area is properly aligned for every basic data type. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Tested-by: Helmut Klein <hgkr.klein@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/core/sdio_bus.c12
-rw-r--r--include/linux/mmc/sdio_func.h2
2 files changed, 12 insertions, 2 deletions
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index e992a7f8a16f..2b32b88949ba 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -267,7 +267,7 @@ static void sdio_release_func(struct device *dev)
267 sdio_free_func_cis(func); 267 sdio_free_func_cis(func);
268 268
269 kfree(func->info); 269 kfree(func->info);
270 270 kfree(func->tmpbuf);
271 kfree(func); 271 kfree(func);
272} 272}
273 273
@@ -282,6 +282,16 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card)
282 if (!func) 282 if (!func)
283 return ERR_PTR(-ENOMEM); 283 return ERR_PTR(-ENOMEM);
284 284
285 /*
286 * allocate buffer separately to make sure it's properly aligned for
287 * DMA usage (incl. 64 bit DMA)
288 */
289 func->tmpbuf = kmalloc(4, GFP_KERNEL);
290 if (!func->tmpbuf) {
291 kfree(func);
292 return ERR_PTR(-ENOMEM);
293 }
294
285 func->card = card; 295 func->card = card;
286 296
287 device_initialize(&func->dev); 297 device_initialize(&func->dev);
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index aab032a6ae61..97ca105347a6 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -53,7 +53,7 @@ struct sdio_func {
53 unsigned int state; /* function state */ 53 unsigned int state; /* function state */
54#define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ 54#define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */
55 55
56 u8 tmpbuf[4]; /* DMA:able scratch buffer */ 56 u8 *tmpbuf; /* DMA:able scratch buffer */
57 57
58 unsigned num_info; /* number of info strings */ 58 unsigned num_info; /* number of info strings */
59 const char **info; /* info strings */ 59 const char **info; /* info strings */