aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyungsik Lee <kyungsik.lee@lge.com>2012-08-02 20:58:03 -0400
committerChris Ball <cjb@laptop.org>2012-09-19 04:29:42 -0400
commit1a41313e7f8c5b724a2e3ff66558dbe811844423 (patch)
treec6a536fc3288f76049b6301c7c7a4e8ce553e067
parent8f63795c60ef5bc3dbfcbf19c1ac64ed79d23c62 (diff)
mmc: core: Remove bounce buffer in mmc_send_cxd_data()
It is expected that Extended CSD register (the size of this register is larger than CID/CSD) will be referenced more frequently as more fields have been added to Extended CSD and it seems that it is not a good option to double the memory used. This patch is intended to avoid the use of bounce buffer for reading Extended CSD register in mmc_send_cxd_data(). It will provide a better performance gain by removing memcpy() overhead for a half KiB and a redundant bounce buffer allocated repeatedly at the cost of providing DMA-capable buffer from upper caller (but on-stack buffer is allowed with no performance gain). Signed-off-by: Kyungsik Lee <kyungsik.lee@lge.com> Reviewed-by: Venkatraman S <svenkatr@ti.com> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/core/mmc_ops.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0ed2cc5f35b6..225371a28861 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -230,6 +230,10 @@ mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
230 return 0; 230 return 0;
231} 231}
232 232
233/*
234 * NOTE: void *buf, caller for the buf is required to use DMA-capable
235 * buffer or on-stack buffer (with some overhead in callee).
236 */
233static int 237static int
234mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, 238mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
235 u32 opcode, void *buf, unsigned len) 239 u32 opcode, void *buf, unsigned len)
@@ -239,13 +243,19 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
239 struct mmc_data data = {0}; 243 struct mmc_data data = {0};
240 struct scatterlist sg; 244 struct scatterlist sg;
241 void *data_buf; 245 void *data_buf;
246 int is_on_stack;
242 247
243 /* dma onto stack is unsafe/nonportable, but callers to this 248 is_on_stack = object_is_on_stack(buf);
244 * routine normally provide temporary on-stack buffers ... 249 if (is_on_stack) {
245 */ 250 /*
246 data_buf = kmalloc(len, GFP_KERNEL); 251 * dma onto stack is unsafe/nonportable, but callers to this
247 if (data_buf == NULL) 252 * routine normally provide temporary on-stack buffers ...
248 return -ENOMEM; 253 */
254 data_buf = kmalloc(len, GFP_KERNEL);
255 if (!data_buf)
256 return -ENOMEM;
257 } else
258 data_buf = buf;
249 259
250 mrq.cmd = &cmd; 260 mrq.cmd = &cmd;
251 mrq.data = &data; 261 mrq.data = &data;
@@ -280,8 +290,10 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
280 290
281 mmc_wait_for_req(host, &mrq); 291 mmc_wait_for_req(host, &mrq);
282 292
283 memcpy(buf, data_buf, len); 293 if (is_on_stack) {
284 kfree(data_buf); 294 memcpy(buf, data_buf, len);
295 kfree(data_buf);
296 }
285 297
286 if (cmd.error) 298 if (cmd.error)
287 return cmd.error; 299 return cmd.error;
@@ -294,24 +306,32 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
294int mmc_send_csd(struct mmc_card *card, u32 *csd) 306int mmc_send_csd(struct mmc_card *card, u32 *csd)
295{ 307{
296 int ret, i; 308 int ret, i;
309 u32 *csd_tmp;
297 310
298 if (!mmc_host_is_spi(card->host)) 311 if (!mmc_host_is_spi(card->host))
299 return mmc_send_cxd_native(card->host, card->rca << 16, 312 return mmc_send_cxd_native(card->host, card->rca << 16,
300 csd, MMC_SEND_CSD); 313 csd, MMC_SEND_CSD);
301 314
302 ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); 315 csd_tmp = kmalloc(16, GFP_KERNEL);
316 if (!csd_tmp)
317 return -ENOMEM;
318
319 ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16);
303 if (ret) 320 if (ret)
304 return ret; 321 goto err;
305 322
306 for (i = 0;i < 4;i++) 323 for (i = 0;i < 4;i++)
307 csd[i] = be32_to_cpu(csd[i]); 324 csd[i] = be32_to_cpu(csd_tmp[i]);
308 325
309 return 0; 326err:
327 kfree(csd_tmp);
328 return ret;
310} 329}
311 330
312int mmc_send_cid(struct mmc_host *host, u32 *cid) 331int mmc_send_cid(struct mmc_host *host, u32 *cid)
313{ 332{
314 int ret, i; 333 int ret, i;
334 u32 *cid_tmp;
315 335
316 if (!mmc_host_is_spi(host)) { 336 if (!mmc_host_is_spi(host)) {
317 if (!host->card) 337 if (!host->card)
@@ -320,14 +340,20 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid)
320 cid, MMC_SEND_CID); 340 cid, MMC_SEND_CID);
321 } 341 }
322 342
323 ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); 343 cid_tmp = kmalloc(16, GFP_KERNEL);
344 if (!cid_tmp)
345 return -ENOMEM;
346
347 ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16);
324 if (ret) 348 if (ret)
325 return ret; 349 goto err;
326 350
327 for (i = 0;i < 4;i++) 351 for (i = 0;i < 4;i++)
328 cid[i] = be32_to_cpu(cid[i]); 352 cid[i] = be32_to_cpu(cid_tmp[i]);
329 353
330 return 0; 354err:
355 kfree(cid_tmp);
356 return ret;
331} 357}
332 358
333int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) 359int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)