Date:2010-06-21 00:15:11 (13 years 9 months ago)
Author:Lars C.
Commit:002674ccdad60fb35481ea239df701449d236597
Message:use sg_mapping_iter to iterate over sg elements.

Files: drivers/mmc/host/jz4740_mmc.c (3 diffs)

Change Details

drivers/mmc/host/jz4740_mmc.c
218218static void jz4740_mmc_write_data(struct jz4740_mmc_host *host,
219219    struct mmc_data *data)
220220{
221    struct scatterlist *sg;
222    uint32_t *sg_pointer;
221    struct sg_mapping_iter miter;
222    uint32_t *buf;
223223    int status;
224224    unsigned int timeout;
225225    size_t i, j;
226226
227    for (sg = data->sg; sg; sg = sg_next(sg)) {
228        sg_pointer = sg_virt(sg);
229        i = sg->length / 4;
227    sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_FROM_SG);
228    while (sg_miter_next(&miter)) {
229        buf = miter.addr;
230        i = miter.length / 4;
230231        j = i >> 3;
231232        i = i & 0x7;
232233        while (j) {
233234            timeout = jz4740_mmc_wait_irq(host, JZ_MMC_IRQ_TXFIFO_WR_REQ);
234            if (unlikely(timeout == 0))
235            if (unlikely(timeout == 0)) {
236                sg_miter_stop(&miter);
235237                goto err_timeout;
238            }
236239
237            writel(sg_pointer[0], host->base + JZ_REG_MMC_TXFIFO);
238            writel(sg_pointer[1], host->base + JZ_REG_MMC_TXFIFO);
239            writel(sg_pointer[2], host->base + JZ_REG_MMC_TXFIFO);
240            writel(sg_pointer[3], host->base + JZ_REG_MMC_TXFIFO);
241            writel(sg_pointer[4], host->base + JZ_REG_MMC_TXFIFO);
242            writel(sg_pointer[5], host->base + JZ_REG_MMC_TXFIFO);
243            writel(sg_pointer[6], host->base + JZ_REG_MMC_TXFIFO);
244            writel(sg_pointer[7], host->base + JZ_REG_MMC_TXFIFO);
245            sg_pointer += 8;
240            writel(buf[0], host->base + JZ_REG_MMC_TXFIFO);
241            writel(buf[1], host->base + JZ_REG_MMC_TXFIFO);
242            writel(buf[2], host->base + JZ_REG_MMC_TXFIFO);
243            writel(buf[3], host->base + JZ_REG_MMC_TXFIFO);
244            writel(buf[4], host->base + JZ_REG_MMC_TXFIFO);
245            writel(buf[5], host->base + JZ_REG_MMC_TXFIFO);
246            writel(buf[6], host->base + JZ_REG_MMC_TXFIFO);
247            writel(buf[7], host->base + JZ_REG_MMC_TXFIFO);
248            buf += 8;
246249            --j;
247250        }
248        if (i) {
251        if (unlikely(i)) {
249252            timeout = jz4740_mmc_wait_irq(host, JZ_MMC_IRQ_TXFIFO_WR_REQ);
250            if (unlikely(timeout == 0))
253            if (unlikely(timeout == 0)) {
254                sg_miter_stop(&miter);
251255                goto err_timeout;
256            }
252257
253258            while (i) {
254                writel(*sg_pointer, host->base + JZ_REG_MMC_TXFIFO);
255                ++sg_pointer;
259                writel(*buf, host->base + JZ_REG_MMC_TXFIFO);
260                ++buf;
256261                --i;
257262            }
258263        }
259        data->bytes_xfered += sg->length;
264        data->bytes_xfered += miter.length;
260265    }
266    sg_miter_stop(&miter);
261267
262268    status = readl(host->base + JZ_REG_MMC_STATUS);
263269    if (status & JZ_MMC_STATUS_WRITE_ERROR_MASK)
...... 
287293    }
288294}
289295
290static void jz4740_mmc_timeout(unsigned long data)
291{
292    struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)data;
293    unsigned long flags;
294
295    spin_lock_irqsave(&host->lock, flags);
296    if (!host->waiting) {
297        spin_unlock_irqrestore(&host->lock, flags);
298        return;
299    }
300
301    host->waiting = 0;
302
303    spin_unlock_irqrestore(&host->lock, flags);
304
305    host->req->cmd->error = -ETIMEDOUT;
306    jz4740_mmc_request_done(host);
307}
308
309296static void jz4740_mmc_read_data(struct jz4740_mmc_host *host,
310297                struct mmc_data *data)
311298{
312    struct scatterlist *sg;
313    uint32_t *sg_pointer;
299    struct sg_mapping_iter miter;
300    uint32_t *buf;
314301    uint32_t d;
315302    uint16_t status = 0;
316303    size_t i, j;
317304    unsigned int timeout;
318305
319    for (sg = data->sg; sg; sg = sg_next(sg)) {
320        sg_pointer = sg_virt(sg);
321        i = sg->length;
306    sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_TO_SG);
307    while (sg_miter_next(&miter)) {
308        buf = miter.addr;
309        i = miter.length;
322310        j = i >> 5;
323311        i = i & 0x1f;
324312        while (j) {
325313            timeout = jz4740_mmc_wait_irq(host, JZ_MMC_IRQ_RXFIFO_RD_REQ);
326            if (unlikely(timeout == 0))
314            if (unlikely(timeout == 0)) {
315                sg_miter_stop(&miter);
327316                goto err_timeout;
317            }
328318
329            sg_pointer[0] = readl(host->base + JZ_REG_MMC_RXFIFO);
330            sg_pointer[1] = readl(host->base + JZ_REG_MMC_RXFIFO);
331            sg_pointer[2] = readl(host->base + JZ_REG_MMC_RXFIFO);
332            sg_pointer[3] = readl(host->base + JZ_REG_MMC_RXFIFO);
333            sg_pointer[4] = readl(host->base + JZ_REG_MMC_RXFIFO);
334            sg_pointer[5] = readl(host->base + JZ_REG_MMC_RXFIFO);
335            sg_pointer[6] = readl(host->base + JZ_REG_MMC_RXFIFO);
336            sg_pointer[7] = readl(host->base + JZ_REG_MMC_RXFIFO);
319            buf[0] = readl(host->base + JZ_REG_MMC_RXFIFO);
320            buf[1] = readl(host->base + JZ_REG_MMC_RXFIFO);
321            buf[2] = readl(host->base + JZ_REG_MMC_RXFIFO);
322            buf[3] = readl(host->base + JZ_REG_MMC_RXFIFO);
323            buf[4] = readl(host->base + JZ_REG_MMC_RXFIFO);
324            buf[5] = readl(host->base + JZ_REG_MMC_RXFIFO);
325            buf[6] = readl(host->base + JZ_REG_MMC_RXFIFO);
326            buf[7] = readl(host->base + JZ_REG_MMC_RXFIFO);
337327
338            sg_pointer += 8;
328            buf += 8;
339329            --j;
340330        }
341331
342332        while (i >= 4) {
343333            timeout = jz4740_mmc_wait_irq(host, JZ_MMC_IRQ_RXFIFO_RD_REQ);
344            if (unlikely(timeout == 0))
334            if (unlikely(timeout == 0)) {
335                sg_miter_stop(&miter);
345336                goto err_timeout;
337            }
346338
347            *sg_pointer = readl(host->base + JZ_REG_MMC_RXFIFO);
348            ++sg_pointer;
339            *buf++ = readl(host->base + JZ_REG_MMC_RXFIFO);
349340            i -= 4;
350341        }
351        if (i > 0) {
342        if (unlikely(i > 0)) {
352343            d = readl(host->base + JZ_REG_MMC_RXFIFO);
353            memcpy(sg_pointer, &d, i);
344            memcpy(buf, &d, i);
354345        }
355        data->bytes_xfered += sg->length;
346        data->bytes_xfered += miter.length;
356347
357        flush_dcache_page(sg_page(sg));
348        /* This can go away once MIPS implements flush_kernel_dcache_page */
349        flush_dcache_page(miter.page);
358350    }
351    sg_miter_stop(&miter);
359352
360353    status = readl(host->base + JZ_REG_MMC_STATUS);
361354    if (status & JZ_MMC_STATUS_READ_ERROR_MASK)
...... 
382375    }
383376}
384377
378static void jz4740_mmc_timeout(unsigned long data)
379{
380    struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)data;
381    unsigned long flags;
382
383    spin_lock_irqsave(&host->lock, flags);
384    if (!host->waiting) {
385        spin_unlock_irqrestore(&host->lock, flags);
386        return;
387    }
388
389    host->waiting = 0;
390
391    spin_unlock_irqrestore(&host->lock, flags);
392
393    host->req->cmd->error = -ETIMEDOUT;
394    jz4740_mmc_request_done(host);
395}
396
385397static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
386398{
387399    struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)devid;

Archive Download the corresponding diff file



interactive