[libata] pata_sil680: Add MMIO support
This patch adds MMIO support to the pata_sil680 for taskfile IOs, based on what the old siimage does. I haven't bothered changing the chip setup stuff from PCI config cycles to MMIO though (siimage does it), I don't think it matters, I've only adapted it to use MMIO for taskfile accesses. I've tested it on a Cell blade and it seems to work fine. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
f4921aff5b
commit
2b9e68f728
|
@ -279,7 +279,7 @@ static struct ata_port_operations sil680_port_ops = {
|
|||
* Returns the final clock settings.
|
||||
*/
|
||||
|
||||
static u8 sil680_init_chip(struct pci_dev *pdev)
|
||||
static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
|
||||
{
|
||||
u32 class_rev = 0;
|
||||
u8 tmpbyte = 0;
|
||||
|
@ -297,6 +297,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
|
|||
dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
|
||||
tmpbyte & 1, tmpbyte & 0x30);
|
||||
|
||||
*try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
|
||||
|
||||
switch(tmpbyte & 0x30) {
|
||||
case 0x00:
|
||||
/* 133 clock attempt to force it on */
|
||||
|
@ -361,25 +363,76 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
|
|||
};
|
||||
const struct ata_port_info *ppi[] = { &info, NULL };
|
||||
static int printed_version;
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
int rc, try_mmio;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
switch(sil680_init_chip(pdev))
|
||||
{
|
||||
switch (sil680_init_chip(pdev, &try_mmio)) {
|
||||
case 0:
|
||||
ppi[0] = &info_slow;
|
||||
break;
|
||||
case 0x30:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!try_mmio)
|
||||
goto use_ioports;
|
||||
|
||||
/* Try to acquire MMIO resources and fallback to PIO if
|
||||
* that fails
|
||||
*/
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME);
|
||||
if (rc)
|
||||
goto use_ioports;
|
||||
|
||||
/* Allocate host and set it up */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
/* Setup DMA masks */
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* Get MMIO base and initialize port addresses */
|
||||
mmio_base = host->iomap[SIL680_MMIO_BAR];
|
||||
host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x00;
|
||||
host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80;
|
||||
host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a;
|
||||
host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a;
|
||||
ata_std_ports(&host->ports[0]->ioaddr);
|
||||
host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08;
|
||||
host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0;
|
||||
host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca;
|
||||
host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca;
|
||||
ata_std_ports(&host->ports[1]->ioaddr);
|
||||
|
||||
/* Register & activate */
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&sil680_sht);
|
||||
|
||||
use_ioports:
|
||||
return ata_pci_init_one(pdev, ppi);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int sil680_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
sil680_init_chip(pdev);
|
||||
int try_mmio;
|
||||
|
||||
sil680_init_chip(pdev, &try_mmio);
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue