| 286 | } |
| 287 | |
| 288 | static int sdhci_send_command(struct sd_mmc_ctrlr *ctrlr, |
| 289 | struct mmc_command *cmd, struct mmc_data *data) |
| 290 | { |
| 291 | void *buf; |
| 292 | unsigned int bbflags; |
| 293 | size_t len; |
| 294 | struct bounce_buffer *bbstate = NULL; |
| 295 | struct bounce_buffer bbstate_val; |
| 296 | int ret; |
| 297 | |
| 298 | sdhc_log_command(cmd); |
| 299 | |
| 300 | if (CONFIG(SDHCI_BOUNCE_BUFFER) && data) { |
| 301 | if (data->flags & DATA_FLAG_READ) { |
| 302 | buf = data->dest; |
| 303 | bbflags = GEN_BB_WRITE; |
| 304 | } else { |
| 305 | buf = (void *)data->src; |
| 306 | bbflags = GEN_BB_READ; |
| 307 | } |
| 308 | len = data->blocks * data->blocksize; |
| 309 | |
| 310 | /* |
| 311 | * on some platform(like rk3399 etc) need to worry about |
| 312 | * cache coherency, so check the buffer, if not dma |
| 313 | * coherent, use bounce_buffer to do DMA management. |
| 314 | */ |
| 315 | if (!dma_coherent(buf)) { |
| 316 | bbstate = &bbstate_val; |
| 317 | if (bounce_buffer_start(bbstate, buf, len, bbflags)) { |
| 318 | sdhc_error("Failed to get bounce buffer.\n"); |
| 319 | return -1; |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | sdhci_led_control(ctrlr, 1); |
| 325 | ret = sdhci_send_command_bounced(ctrlr, cmd, data, bbstate); |
| 326 | sdhci_led_control(ctrlr, 0); |
| 327 | sdhc_log_ret(ret); |
| 328 | |
| 329 | if (CONFIG(SDHCI_BOUNCE_BUFFER) && bbstate) |
| 330 | bounce_buffer_stop(bbstate); |
| 331 | |
| 332 | return ret; |
| 333 | } |
| 334 | |
| 335 | static int sdhci_set_clock(struct sdhci_ctrlr *sdhci_ctrlr, unsigned int clock) |
| 336 | { |
nothing calls this directly
no test coverage detected