diff options
Diffstat (limited to 'drivers/ata/sata_sil.c')
-rw-r--r-- | drivers/ata/sata_sil.c | 89 |
1 files changed, 37 insertions, 52 deletions
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 466b05b67115..0a1e417f309c 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -118,7 +118,6 @@ static void sil_dev_config(struct ata_device *dev); | |||
118 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); | 118 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); |
119 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 119 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
120 | static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); | 120 | static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); |
121 | static irqreturn_t sil_interrupt(int irq, void *dev_instance); | ||
122 | static void sil_freeze(struct ata_port *ap); | 121 | static void sil_freeze(struct ata_port *ap); |
123 | static void sil_thaw(struct ata_port *ap); | 122 | static void sil_thaw(struct ata_port *ap); |
124 | 123 | ||
@@ -209,7 +208,6 @@ static const struct ata_port_operations sil_ops = { | |||
209 | .thaw = sil_thaw, | 208 | .thaw = sil_thaw, |
210 | .error_handler = ata_bmdma_error_handler, | 209 | .error_handler = ata_bmdma_error_handler, |
211 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 210 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
212 | .irq_handler = sil_interrupt, | ||
213 | .irq_clear = ata_bmdma_irq_clear, | 211 | .irq_clear = ata_bmdma_irq_clear, |
214 | .irq_on = ata_irq_on, | 212 | .irq_on = ata_irq_on, |
215 | .irq_ack = ata_irq_ack, | 213 | .irq_ack = ata_irq_ack, |
@@ -221,7 +219,6 @@ static const struct ata_port_operations sil_ops = { | |||
221 | static const struct ata_port_info sil_port_info[] = { | 219 | static const struct ata_port_info sil_port_info[] = { |
222 | /* sil_3112 */ | 220 | /* sil_3112 */ |
223 | { | 221 | { |
224 | .sht = &sil_sht, | ||
225 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, | 222 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, |
226 | .pio_mask = 0x1f, /* pio0-4 */ | 223 | .pio_mask = 0x1f, /* pio0-4 */ |
227 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 224 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -230,7 +227,6 @@ static const struct ata_port_info sil_port_info[] = { | |||
230 | }, | 227 | }, |
231 | /* sil_3112_no_sata_irq */ | 228 | /* sil_3112_no_sata_irq */ |
232 | { | 229 | { |
233 | .sht = &sil_sht, | ||
234 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | | 230 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | |
235 | SIL_FLAG_NO_SATA_IRQ, | 231 | SIL_FLAG_NO_SATA_IRQ, |
236 | .pio_mask = 0x1f, /* pio0-4 */ | 232 | .pio_mask = 0x1f, /* pio0-4 */ |
@@ -240,7 +236,6 @@ static const struct ata_port_info sil_port_info[] = { | |||
240 | }, | 236 | }, |
241 | /* sil_3512 */ | 237 | /* sil_3512 */ |
242 | { | 238 | { |
243 | .sht = &sil_sht, | ||
244 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, | 239 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, |
245 | .pio_mask = 0x1f, /* pio0-4 */ | 240 | .pio_mask = 0x1f, /* pio0-4 */ |
246 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 241 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -249,7 +244,6 @@ static const struct ata_port_info sil_port_info[] = { | |||
249 | }, | 244 | }, |
250 | /* sil_3114 */ | 245 | /* sil_3114 */ |
251 | { | 246 | { |
252 | .sht = &sil_sht, | ||
253 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, | 247 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, |
254 | .pio_mask = 0x1f, /* pio0-4 */ | 248 | .pio_mask = 0x1f, /* pio0-4 */ |
255 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 249 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -598,10 +592,10 @@ static void sil_dev_config(struct ata_device *dev) | |||
598 | } | 592 | } |
599 | } | 593 | } |
600 | 594 | ||
601 | static void sil_init_controller(struct pci_dev *pdev, | 595 | static void sil_init_controller(struct ata_host *host) |
602 | int n_ports, unsigned long port_flags, | ||
603 | void __iomem *mmio_base) | ||
604 | { | 596 | { |
597 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
598 | void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR]; | ||
605 | u8 cls; | 599 | u8 cls; |
606 | u32 tmp; | 600 | u32 tmp; |
607 | int i; | 601 | int i; |
@@ -611,7 +605,7 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
611 | if (cls) { | 605 | if (cls) { |
612 | cls >>= 3; | 606 | cls >>= 3; |
613 | cls++; /* cls = (line_size/8)+1 */ | 607 | cls++; /* cls = (line_size/8)+1 */ |
614 | for (i = 0; i < n_ports; i++) | 608 | for (i = 0; i < host->n_ports; i++) |
615 | writew(cls << 8 | cls, | 609 | writew(cls << 8 | cls, |
616 | mmio_base + sil_port[i].fifo_cfg); | 610 | mmio_base + sil_port[i].fifo_cfg); |
617 | } else | 611 | } else |
@@ -619,10 +613,10 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
619 | "cache line size not set. Driver may not function\n"); | 613 | "cache line size not set. Driver may not function\n"); |
620 | 614 | ||
621 | /* Apply R_ERR on DMA activate FIS errata workaround */ | 615 | /* Apply R_ERR on DMA activate FIS errata workaround */ |
622 | if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | 616 | if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) { |
623 | int cnt; | 617 | int cnt; |
624 | 618 | ||
625 | for (i = 0, cnt = 0; i < n_ports; i++) { | 619 | for (i = 0, cnt = 0; i < host->n_ports; i++) { |
626 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | 620 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); |
627 | if ((tmp & 0x3) != 0x01) | 621 | if ((tmp & 0x3) != 0x01) |
628 | continue; | 622 | continue; |
@@ -635,7 +629,7 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
635 | } | 629 | } |
636 | } | 630 | } |
637 | 631 | ||
638 | if (n_ports == 4) { | 632 | if (host->n_ports == 4) { |
639 | /* flip the magic "make 4 ports work" bit */ | 633 | /* flip the magic "make 4 ports work" bit */ |
640 | tmp = readl(mmio_base + sil_port[2].bmdma); | 634 | tmp = readl(mmio_base + sil_port[2].bmdma); |
641 | if ((tmp & SIL_INTR_STEERING) == 0) | 635 | if ((tmp & SIL_INTR_STEERING) == 0) |
@@ -647,15 +641,26 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
647 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 641 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
648 | { | 642 | { |
649 | static int printed_version; | 643 | static int printed_version; |
650 | struct device *dev = &pdev->dev; | 644 | int board_id = ent->driver_data; |
651 | struct ata_probe_ent *probe_ent; | 645 | const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL }; |
646 | struct ata_host *host; | ||
652 | void __iomem *mmio_base; | 647 | void __iomem *mmio_base; |
653 | int rc; | 648 | int n_ports, rc; |
654 | unsigned int i; | 649 | unsigned int i; |
655 | 650 | ||
656 | if (!printed_version++) | 651 | if (!printed_version++) |
657 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 652 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
658 | 653 | ||
654 | /* allocate host */ | ||
655 | n_ports = 2; | ||
656 | if (board_id == sil_3114) | ||
657 | n_ports = 4; | ||
658 | |||
659 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | ||
660 | if (!host) | ||
661 | return -ENOMEM; | ||
662 | |||
663 | /* acquire resources and fill host */ | ||
659 | rc = pcim_enable_device(pdev); | 664 | rc = pcim_enable_device(pdev); |
660 | if (rc) | 665 | if (rc) |
661 | return rc; | 666 | return rc; |
@@ -665,6 +670,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
665 | pcim_pin_device(pdev); | 670 | pcim_pin_device(pdev); |
666 | if (rc) | 671 | if (rc) |
667 | return rc; | 672 | return rc; |
673 | host->iomap = pcim_iomap_table(pdev); | ||
668 | 674 | ||
669 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 675 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); |
670 | if (rc) | 676 | if (rc) |
@@ -673,45 +679,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
673 | if (rc) | 679 | if (rc) |
674 | return rc; | 680 | return rc; |
675 | 681 | ||
676 | probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); | 682 | mmio_base = host->iomap[SIL_MMIO_BAR]; |
677 | if (probe_ent == NULL) | ||
678 | return -ENOMEM; | ||
679 | 683 | ||
680 | INIT_LIST_HEAD(&probe_ent->node); | 684 | for (i = 0; i < host->n_ports; i++) { |
681 | probe_ent->dev = pci_dev_to_dev(pdev); | 685 | struct ata_ioports *ioaddr = &host->ports[i]->ioaddr; |
682 | probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops; | 686 | |
683 | probe_ent->sht = sil_port_info[ent->driver_data].sht; | 687 | ioaddr->cmd_addr = mmio_base + sil_port[i].tf; |
684 | probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2; | 688 | ioaddr->altstatus_addr = |
685 | probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask; | 689 | ioaddr->ctl_addr = mmio_base + sil_port[i].ctl; |
686 | probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask; | 690 | ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma; |
687 | probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask; | 691 | ioaddr->scr_addr = mmio_base + sil_port[i].scr; |
688 | probe_ent->irq = pdev->irq; | 692 | ata_std_ports(ioaddr); |
689 | probe_ent->irq_flags = IRQF_SHARED; | ||
690 | probe_ent->port_flags = sil_port_info[ent->driver_data].flags; | ||
691 | |||
692 | probe_ent->iomap = pcim_iomap_table(pdev); | ||
693 | |||
694 | mmio_base = probe_ent->iomap[SIL_MMIO_BAR]; | ||
695 | |||
696 | for (i = 0; i < probe_ent->n_ports; i++) { | ||
697 | probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf; | ||
698 | probe_ent->port[i].altstatus_addr = | ||
699 | probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl; | ||
700 | probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma; | ||
701 | probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr; | ||
702 | ata_std_ports(&probe_ent->port[i]); | ||
703 | } | 693 | } |
704 | 694 | ||
705 | sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags, | 695 | /* initialize and activate */ |
706 | mmio_base); | 696 | sil_init_controller(host); |
707 | 697 | ||
708 | pci_set_master(pdev); | 698 | pci_set_master(pdev); |
709 | 699 | return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED, | |
710 | if (!ata_device_add(probe_ent)) | 700 | &sil_sht); |
711 | return -ENODEV; | ||
712 | |||
713 | devm_kfree(dev, probe_ent); | ||
714 | return 0; | ||
715 | } | 701 | } |
716 | 702 | ||
717 | #ifdef CONFIG_PM | 703 | #ifdef CONFIG_PM |
@@ -724,8 +710,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev) | |||
724 | if (rc) | 710 | if (rc) |
725 | return rc; | 711 | return rc; |
726 | 712 | ||
727 | sil_init_controller(pdev, host->n_ports, host->ports[0]->flags, | 713 | sil_init_controller(host); |
728 | host->iomap[SIL_MMIO_BAR]); | ||
729 | ata_host_resume(host); | 714 | ata_host_resume(host); |
730 | 715 | ||
731 | return 0; | 716 | return 0; |