X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=drivers%2Fata%2Fpata_bf54x.c;h=a32e3c44a606f2f78d5169f6d11103b47749d1f6;hp=b5e38426b815ec4ed64854d467ee0548f1a90c8b;hb=ef3f2de2b5496f721b12f21a157e19eac816394b;hpb=43cd73658d8077ee6899b0b5029aad0cba1e9f92 diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index b5e38426b815..a32e3c44a606 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -832,6 +832,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc) { unsigned short config = WDSIZE_16; struct scatterlist *sg; + unsigned int si; pr_debug("in atapi dma setup\n"); /* Program the ATA_CTRL register with dir */ @@ -839,7 +840,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc) /* fill the ATAPI DMA controller */ set_dma_config(CH_ATAPI_TX, config); set_dma_x_modify(CH_ATAPI_TX, 2); - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { set_dma_start_addr(CH_ATAPI_TX, sg_dma_address(sg)); set_dma_x_count(CH_ATAPI_TX, sg_dma_len(sg) >> 1); } @@ -848,7 +849,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc) /* fill the ATAPI DMA controller */ set_dma_config(CH_ATAPI_RX, config); set_dma_x_modify(CH_ATAPI_RX, 2); - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { set_dma_start_addr(CH_ATAPI_RX, sg_dma_address(sg)); set_dma_x_count(CH_ATAPI_RX, sg_dma_len(sg) >> 1); } @@ -867,6 +868,7 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; struct scatterlist *sg; + unsigned int si; pr_debug("in atapi dma start\n"); if (!(ap->udma_mask || ap->mwdma_mask)) @@ -881,7 +883,7 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) * data cache is enabled. Otherwise, this loop * is an empty loop and optimized out. */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { flush_dcache_range(sg_dma_address(sg), sg_dma_address(sg) + sg_dma_len(sg)); } @@ -910,7 +912,7 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST); /* Set transfer length to buffer len */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1)); } @@ -932,6 +934,7 @@ static void bfin_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg; + unsigned int si; pr_debug("in atapi dma stop\n"); if (!(ap->udma_mask || ap->mwdma_mask)) @@ -950,7 +953,7 @@ static void bfin_bmdma_stop(struct ata_queued_cmd *qc) * data cache is enabled. Otherwise, this loop * is an empty loop and optimized out. */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { invalidate_dcache_range( sg_dma_address(sg), sg_dma_address(sg) @@ -1145,13 +1148,13 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap) unsigned short int_status = ATAPI_GET_INT_STATUS(base); if (ATAPI_GET_STATUS(base) & (MULTI_XFER_ON|ULTRA_XFER_ON)) { - host_stat = ATA_DMA_ACTIVE; + host_stat |= ATA_DMA_ACTIVE; } if (int_status & (MULTI_DONE_INT|UDMAIN_DONE_INT|UDMAOUT_DONE_INT)) { - host_stat = ATA_DMA_INTR; + host_stat |= ATA_DMA_INTR; } if (int_status & (MULTI_TERM_INT|UDMAIN_TERM_INT|UDMAOUT_TERM_INT)) { - host_stat = ATA_DMA_ERR; + host_stat |= ATA_DMA_ERR; } return host_stat; @@ -1167,34 +1170,36 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap) * Note: Original code is ata_data_xfer(). */ -static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; - unsigned int words = buflen >> 1; - unsigned short *buf16 = (u16 *) buf; + struct ata_port *ap = dev->link->ap; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; + unsigned int words = buflen >> 1; + unsigned short *buf16 = (u16 *)buf; /* Transfer multiple of 2 bytes */ - if (write_data) { - write_atapi_data(base, words, buf16); - } else { + if (rw == READ) read_atapi_data(base, words, buf16); - } + else + write_atapi_data(base, words, buf16); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { unsigned short align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; - if (write_data) { - memcpy(align_buf, trailing_buf, 1); - write_atapi_data(base, 1, align_buf); - } else { + if (rw == READ) { read_atapi_data(base, 1, align_buf); memcpy(trailing_buf, align_buf, 1); + } else { + memcpy(align_buf, trailing_buf, 1); + write_atapi_data(base, 1, align_buf); } + words++; } + + return words << 1; } /** @@ -1489,6 +1494,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev) int board_idx = 0; struct resource *res; struct ata_host *host; + unsigned int fsclk = get_sclk(); + int udma_mode = 5; const struct ata_port_info *ppi[] = { &bfin_port_info[board_idx], NULL }; @@ -1507,6 +1514,12 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev) if (res == NULL) return -EINVAL; + while (bfin_port_info[board_idx].udma_mask > 0 && + udma_fsclk[udma_mode] > fsclk) { + udma_mode--; + bfin_port_info[board_idx].udma_mask >>= 1; + } + /* * Now that that's out of the way, wire up the port.. */