aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_sil24.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-04-17 10:44:08 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:16:06 -0400
commit4447d35156169cf136e829eb6b5cac2d6370f2d9 (patch)
tree20be4c582ea4ce1cce1b0f8dbea949a410a72e3c /drivers/ata/sata_sil24.c
parent9a829ccfc833269bdb85751f5048288ab93678ac (diff)
libata: convert the remaining SATA drivers to new init model
Convert ahci, sata_sil, sata_sil24, sata_svw, sata_qstor, sata_mv, sata_sx4, sata_vsc and sata_inic162x to new init model. Now that host and ap are available during intialization, functions are converted to take either host or ap instead of low level parameters which were inevitable for functions shared between init and other paths. This simplifies code quite a bit. * init_one()'s now follow more consistent init order * ahci_setup_port() and ahci_host_init() collapsed into ahci_init_one() for init order consistency * sata_vsc uses port_info instead of setting fields manually * in sata_svw, k2_board_info converted to port_info (info is now in port flags). port number is honored now. Tested on ICH7/8 AHCI, jmb360, sil3112, 3114, 3124 and 3132. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_sil24.c')
-rw-r--r--drivers/ata/sata_sil24.c111
1 files changed, 40 insertions, 71 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 4f522ec04049..e6223ba667da 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
331static void sil24_qc_prep(struct ata_queued_cmd *qc); 331static void sil24_qc_prep(struct ata_queued_cmd *qc);
332static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); 332static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
333static void sil24_irq_clear(struct ata_port *ap); 333static void sil24_irq_clear(struct ata_port *ap);
334static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
335static void sil24_freeze(struct ata_port *ap); 334static void sil24_freeze(struct ata_port *ap);
336static void sil24_thaw(struct ata_port *ap); 335static void sil24_thaw(struct ata_port *ap);
337static void sil24_error_handler(struct ata_port *ap); 336static void sil24_error_handler(struct ata_port *ap);
@@ -401,7 +400,6 @@ static const struct ata_port_operations sil24_ops = {
401 .qc_prep = sil24_qc_prep, 400 .qc_prep = sil24_qc_prep,
402 .qc_issue = sil24_qc_issue, 401 .qc_issue = sil24_qc_issue,
403 402
404 .irq_handler = sil24_interrupt,
405 .irq_clear = sil24_irq_clear, 403 .irq_clear = sil24_irq_clear,
406 .irq_on = ata_dummy_irq_on, 404 .irq_on = ata_dummy_irq_on,
407 .irq_ack = ata_dummy_irq_ack, 405 .irq_ack = ata_dummy_irq_ack,
@@ -424,10 +422,9 @@ static const struct ata_port_operations sil24_ops = {
424#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30) 422#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
425#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1) 423#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
426 424
427static struct ata_port_info sil24_port_info[] = { 425static const struct ata_port_info sil24_port_info[] = {
428 /* sil_3124 */ 426 /* sil_3124 */
429 { 427 {
430 .sht = &sil24_sht,
431 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | 428 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
432 SIL24_FLAG_PCIX_IRQ_WOC, 429 SIL24_FLAG_PCIX_IRQ_WOC,
433 .pio_mask = 0x1f, /* pio0-4 */ 430 .pio_mask = 0x1f, /* pio0-4 */
@@ -437,7 +434,6 @@ static struct ata_port_info sil24_port_info[] = {
437 }, 434 },
438 /* sil_3132 */ 435 /* sil_3132 */
439 { 436 {
440 .sht = &sil24_sht,
441 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), 437 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
442 .pio_mask = 0x1f, /* pio0-4 */ 438 .pio_mask = 0x1f, /* pio0-4 */
443 .mwdma_mask = 0x07, /* mwdma0-2 */ 439 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -446,7 +442,6 @@ static struct ata_port_info sil24_port_info[] = {
446 }, 442 },
447 /* sil_3131/sil_3531 */ 443 /* sil_3131/sil_3531 */
448 { 444 {
449 .sht = &sil24_sht,
450 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), 445 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
451 .pio_mask = 0x1f, /* pio0-4 */ 446 .pio_mask = 0x1f, /* pio0-4 */
452 .mwdma_mask = 0x07, /* mwdma0-2 */ 447 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -961,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap)
961 return 0; 956 return 0;
962} 957}
963 958
964static void sil24_init_controller(struct pci_dev *pdev, int n_ports, 959static void sil24_init_controller(struct ata_host *host)
965 unsigned long port_flags,
966 void __iomem *host_base,
967 void __iomem *port_base)
968{ 960{
961 void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
962 void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
969 u32 tmp; 963 u32 tmp;
970 int i; 964 int i;
971 965
@@ -976,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
976 writel(0, host_base + HOST_CTRL); 970 writel(0, host_base + HOST_CTRL);
977 971
978 /* init ports */ 972 /* init ports */
979 for (i = 0; i < n_ports; i++) { 973 for (i = 0; i < host->n_ports; i++) {
980 void __iomem *port = port_base + i * PORT_REGS_SIZE; 974 void __iomem *port = port_base + i * PORT_REGS_SIZE;
981 975
982 /* Initial PHY setting */ 976 /* Initial PHY setting */
@@ -990,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
990 PORT_CS_PORT_RST, 984 PORT_CS_PORT_RST,
991 PORT_CS_PORT_RST, 10, 100); 985 PORT_CS_PORT_RST, 10, 100);
992 if (tmp & PORT_CS_PORT_RST) 986 if (tmp & PORT_CS_PORT_RST)
993 dev_printk(KERN_ERR, &pdev->dev, 987 dev_printk(KERN_ERR, host->dev,
994 "failed to clear port RST\n"); 988 "failed to clear port RST\n");
995 } 989 }
996 990
997 /* Configure IRQ WoC */ 991 /* Configure IRQ WoC */
998 if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC) 992 if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
999 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); 993 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
1000 else 994 else
1001 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); 995 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
@@ -1023,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
1023static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 1017static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1024{ 1018{
1025 static int printed_version = 0; 1019 static int printed_version = 0;
1026 struct device *dev = &pdev->dev; 1020 struct ata_port_info pi = sil24_port_info[ent->driver_data];
1027 unsigned int board_id = (unsigned int)ent->driver_data; 1021 const struct ata_port_info *ppi[] = { &pi, NULL };
1028 struct ata_port_info *pinfo = &sil24_port_info[board_id]; 1022 void __iomem * const *iomap;
1029 struct ata_probe_ent *probe_ent; 1023 struct ata_host *host;
1030 void __iomem *host_base;
1031 void __iomem *port_base;
1032 int i, rc; 1024 int i, rc;
1033 u32 tmp; 1025 u32 tmp;
1034 1026
1035 if (!printed_version++) 1027 if (!printed_version++)
1036 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); 1028 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
1037 1029
1030 /* acquire resources */
1038 rc = pcim_enable_device(pdev); 1031 rc = pcim_enable_device(pdev);
1039 if (rc) 1032 if (rc)
1040 return rc; 1033 return rc;
@@ -1044,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1044 DRV_NAME); 1037 DRV_NAME);
1045 if (rc) 1038 if (rc)
1046 return rc; 1039 return rc;
1040 iomap = pcim_iomap_table(pdev);
1047 1041
1048 /* allocate & init probe_ent */ 1042 /* apply workaround for completion IRQ loss on PCI-X errata */
1049 probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); 1043 if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
1050 if (!probe_ent) 1044 tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
1051 return -ENOMEM; 1045 if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
1046 dev_printk(KERN_INFO, &pdev->dev,
1047 "Applying completion IRQ loss on PCI-X "
1048 "errata fix\n");
1049 else
1050 pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
1051 }
1052 1052
1053 probe_ent->dev = pci_dev_to_dev(pdev); 1053 /* allocate and fill host */
1054 INIT_LIST_HEAD(&probe_ent->node); 1054 host = ata_host_alloc_pinfo(&pdev->dev, ppi,
1055 SIL24_FLAG2NPORTS(ppi[0]->flags));
1056 if (!host)
1057 return -ENOMEM;
1058 host->iomap = iomap;
1055 1059
1056 probe_ent->sht = pinfo->sht; 1060 for (i = 0; i < host->n_ports; i++) {
1057 probe_ent->port_flags = pinfo->flags; 1061 void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
1058 probe_ent->pio_mask = pinfo->pio_mask;
1059 probe_ent->mwdma_mask = pinfo->mwdma_mask;
1060 probe_ent->udma_mask = pinfo->udma_mask;
1061 probe_ent->port_ops = pinfo->port_ops;
1062 probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->flags);
1063 1062
1064 probe_ent->irq = pdev->irq; 1063 host->ports[i]->ioaddr.cmd_addr = port;
1065 probe_ent->irq_flags = IRQF_SHARED; 1064 host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
1066 probe_ent->iomap = pcim_iomap_table(pdev);
1067 1065
1068 host_base = probe_ent->iomap[SIL24_HOST_BAR]; 1066 ata_std_ports(&host->ports[i]->ioaddr);
1069 port_base = probe_ent->iomap[SIL24_PORT_BAR]; 1067 }
1070 1068
1071 /* 1069 /* configure and activate the device */
1072 * Configure the device
1073 */
1074 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { 1070 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1075 rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); 1071 rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
1076 if (rc) { 1072 if (rc) {
@@ -1096,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1096 } 1092 }
1097 } 1093 }
1098 1094
1099 /* Apply workaround for completion IRQ loss on PCI-X errata */ 1095 sil24_init_controller(host);
1100 if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
1101 tmp = readl(host_base + HOST_CTRL);
1102 if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
1103 dev_printk(KERN_INFO, &pdev->dev,
1104 "Applying completion IRQ loss on PCI-X "
1105 "errata fix\n");
1106 else
1107 probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
1108 }
1109
1110 for (i = 0; i < probe_ent->n_ports; i++) {
1111 void __iomem *port = port_base + i * PORT_REGS_SIZE;
1112
1113 probe_ent->port[i].cmd_addr = port;
1114 probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
1115
1116 ata_std_ports(&probe_ent->port[i]);
1117 }
1118
1119 sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
1120 host_base, port_base);
1121 1096
1122 pci_set_master(pdev); 1097 pci_set_master(pdev);
1123 1098 return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
1124 if (!ata_device_add(probe_ent)) 1099 &sil24_sht);
1125 return -ENODEV;
1126
1127 devm_kfree(dev, probe_ent);
1128 return 0;
1129} 1100}
1130 1101
1131#ifdef CONFIG_PM 1102#ifdef CONFIG_PM
@@ -1133,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
1133{ 1104{
1134 struct ata_host *host = dev_get_drvdata(&pdev->dev); 1105 struct ata_host *host = dev_get_drvdata(&pdev->dev);
1135 void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; 1106 void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
1136 void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
1137 int rc; 1107 int rc;
1138 1108
1139 rc = ata_pci_device_do_resume(pdev); 1109 rc = ata_pci_device_do_resume(pdev);
@@ -1143,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
1143 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) 1113 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
1144 writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL); 1114 writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
1145 1115
1146 sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags, 1116 sil24_init_controller(host);
1147 host_base, port_base);
1148 1117
1149 ata_host_resume(host); 1118 ata_host_resume(host);
1150 1119