};
-static char* tifm_sd_kmap_atomic(struct mmc_data *data)
+static char* tifm_sd_data_buffer(struct mmc_data *data)
{
- return kmap_atomic(data->sg->page, KM_BIO_SRC_IRQ) + data->sg->offset;
-}
-
-static void tifm_sd_kunmap_atomic(char *buffer, struct mmc_data *data)
-{
- kunmap_atomic(buffer - data->sg->offset, KM_BIO_SRC_IRQ);
+ return page_address(data->sg->page) + data->sg->offset;
}
static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
if (host_status & TIFM_MMCSD_BRS) {
/* in non-dma rx mode BRS fires when fifo is still not empty */
if (no_dma && (cmd->data->flags & MMC_DATA_READ)) {
- buffer = tifm_sd_kmap_atomic(host->req->data);
+ buffer = tifm_sd_data_buffer(host->req->data);
while (host->buffer_size > host->buffer_pos) {
t_val = readl(sock->addr + SOCK_MMCSD_DATA);
buffer[host->buffer_pos++] = t_val & 0xff;
buffer[host->buffer_pos++] =
(t_val >> 8) & 0xff;
}
- tifm_sd_kunmap_atomic(buffer, host->req->data);
}
return 1;
} else if (no_dma) {
- buffer = tifm_sd_kmap_atomic(host->req->data);
+ buffer = tifm_sd_data_buffer(host->req->data);
if ((cmd->data->flags & MMC_DATA_READ) &&
(host_status & TIFM_MMCSD_AF)) {
for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
}
}
}
- tifm_sd_kunmap_atomic(buffer, host->req->data);
}
return 0;
}
mmc->f_max = 24000000;
mmc->max_hw_segs = 1;
mmc->max_phys_segs = 1;
- mmc->max_sectors = 127;
- mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length
+ // limited by DMA counter - it's safer to stick with
+ // block counter has 11 bits though
+ mmc->max_blk_count = 256;
+ // 2k maximum hw block length
+ mmc->max_blk_size = 2048;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
sock->signal_irq = tifm_sd_signal_irq;
rc = tifm_sd_initialize_host(host);
mmc_free_host(mmc);
}
+#ifdef CONFIG_PM
+
+static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state)
+{
+ struct mmc_host *mmc = tifm_get_drvdata(sock);
+ int rc;
+
+ rc = mmc_suspend_host(mmc, state);
+ /* The meaning of the bit majority in this constant is unknown. */
+ writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
+ sock->addr + SOCK_CONTROL);
+ return rc;
+}
+
+static int tifm_sd_resume(struct tifm_dev *sock)
+{
+ struct mmc_host *mmc = tifm_get_drvdata(sock);
+ struct tifm_sd *host = mmc_priv(mmc);
+
+ if (sock->media_id != FM_SD
+ || tifm_sd_initialize_host(host)) {
+ tifm_eject(sock);
+ return 0;
+ } else {
+ return mmc_resume_host(mmc);
+ }
+}
+
+#else
+
+#define tifm_sd_suspend NULL
+#define tifm_sd_resume NULL
+
+#endif /* CONFIG_PM */
+
static tifm_media_id tifm_sd_id_tbl[] = {
FM_SD, 0
};
},
.id_table = tifm_sd_id_tbl,
.probe = tifm_sd_probe,
- .remove = tifm_sd_remove
+ .remove = tifm_sd_remove,
+ .suspend = tifm_sd_suspend,
+ .resume = tifm_sd_resume
};
static int __init tifm_sd_init(void)