aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sata_sil.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index bfcece18a7cb..aa63044eed2e 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -96,6 +96,8 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
96static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); 96static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
97static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); 97static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
98static void sil_post_set_mode (struct ata_port *ap); 98static void sil_post_set_mode (struct ata_port *ap);
99static void sil_freeze(struct ata_port *ap);
100static void sil_thaw(struct ata_port *ap);
99 101
100 102
101static const struct pci_device_id sil_pci_tbl[] = { 103static const struct pci_device_id sil_pci_tbl[] = {
@@ -174,7 +176,10 @@ static const struct ata_port_operations sil_ops = {
174 .bmdma_status = ata_bmdma_status, 176 .bmdma_status = ata_bmdma_status,
175 .qc_prep = ata_qc_prep, 177 .qc_prep = ata_qc_prep,
176 .qc_issue = ata_qc_issue_prot, 178 .qc_issue = ata_qc_issue_prot,
177 .eng_timeout = ata_eng_timeout, 179 .freeze = sil_freeze,
180 .thaw = sil_thaw,
181 .error_handler = ata_bmdma_error_handler,
182 .post_internal_cmd = ata_bmdma_post_internal_cmd,
178 .irq_handler = ata_interrupt, 183 .irq_handler = ata_interrupt,
179 .irq_clear = ata_bmdma_irq_clear, 184 .irq_clear = ata_bmdma_irq_clear,
180 .scr_read = sil_scr_read, 185 .scr_read = sil_scr_read,
@@ -314,6 +319,33 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
314 writel(val, mmio); 319 writel(val, mmio);
315} 320}
316 321
322static void sil_freeze(struct ata_port *ap)
323{
324 void __iomem *mmio_base = ap->host_set->mmio_base;
325 u32 tmp;
326
327 /* plug IRQ */
328 tmp = readl(mmio_base + SIL_SYSCFG);
329 tmp |= SIL_MASK_IDE0_INT << ap->port_no;
330 writel(tmp, mmio_base + SIL_SYSCFG);
331 readl(mmio_base + SIL_SYSCFG); /* flush */
332}
333
334static void sil_thaw(struct ata_port *ap)
335{
336 void __iomem *mmio_base = ap->host_set->mmio_base;
337 u32 tmp;
338
339 /* clear IRQ */
340 ata_chk_status(ap);
341 ata_bmdma_irq_clear(ap);
342
343 /* turn on IRQ */
344 tmp = readl(mmio_base + SIL_SYSCFG);
345 tmp &= ~(SIL_MASK_IDE0_INT << ap->port_no);
346 writel(tmp, mmio_base + SIL_SYSCFG);
347}
348
317/** 349/**
318 * sil_dev_config - Apply device/host-specific errata fixups 350 * sil_dev_config - Apply device/host-specific errata fixups
319 * @ap: Port containing device to be examined 351 * @ap: Port containing device to be examined
@@ -384,7 +416,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
384 int rc; 416 int rc;
385 unsigned int i; 417 unsigned int i;
386 int pci_dev_busy = 0; 418 int pci_dev_busy = 0;
387 u32 tmp, irq_mask; 419 u32 tmp;
388 u8 cls; 420 u8 cls;
389 421
390 if (!printed_version++) 422 if (!printed_version++)
@@ -474,24 +506,11 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
474 } 506 }
475 507
476 if (ent->driver_data == sil_3114) { 508 if (ent->driver_data == sil_3114) {
477 irq_mask = SIL_MASK_4PORT;
478
479 /* flip the magic "make 4 ports work" bit */ 509 /* flip the magic "make 4 ports work" bit */
480 tmp = readl(mmio_base + sil_port[2].bmdma); 510 tmp = readl(mmio_base + sil_port[2].bmdma);
481 if ((tmp & SIL_INTR_STEERING) == 0) 511 if ((tmp & SIL_INTR_STEERING) == 0)
482 writel(tmp | SIL_INTR_STEERING, 512 writel(tmp | SIL_INTR_STEERING,
483 mmio_base + sil_port[2].bmdma); 513 mmio_base + sil_port[2].bmdma);
484
485 } else {
486 irq_mask = SIL_MASK_2PORT;
487 }
488
489 /* make sure IDE0/1/2/3 interrupts are not masked */
490 tmp = readl(mmio_base + SIL_SYSCFG);
491 if (tmp & irq_mask) {
492 tmp &= ~irq_mask;
493 writel(tmp, mmio_base + SIL_SYSCFG);
494 readl(mmio_base + SIL_SYSCFG); /* flush */
495 } 514 }
496 515
497 /* mask all SATA phy-related interrupts */ 516 /* mask all SATA phy-related interrupts */