diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-19 14:04:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-19 14:04:29 -0500 |
commit | 70e66a5079b2b33f142303d31581cf03f7af98fe (patch) | |
tree | 3160fb22716de0407d87ec9de6135127ed7c1fed | |
parent | eca9dfcd0029c8a84b1094bb84a2fb53e4addf6c (diff) | |
parent | 0535f2bc170bc0779ac471faff39f633ca19ab59 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
sata_mv: remove pointless NULL test
pata_hpt3x2n: fix clock turnaround
libata: fix reporting of drained bytes when clearing DRQ
sata_mv: add power management support for the PCI controllers.
sata_mv: store the board_idx into the host private data
pata_octeon_cf: use resource_size(), to fix resource sizing bug
libata: use the WRITE_SAME_16 define
sata_mv: move the PCI bar description initialization code
sata_mv: add power management support for the platform driver
sata_mv: support clkdev framework
sata_mv: increase PIO IORDY timeout
Fixed crazy mode-change in merge.
-rw-r--r-- | drivers/ata/libata-scsi.c | 2 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 2 | ||||
-rw-r--r-- | drivers/ata/pata_hpt3x2n.c | 64 | ||||
-rw-r--r-- | drivers/ata/pata_octeon_cf.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 144 |
5 files changed, 163 insertions, 51 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1683ebda900b..f4ea5a8c325b 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) | |||
3022 | case WRITE_16: | 3022 | case WRITE_16: |
3023 | return ata_scsi_rw_xlat; | 3023 | return ata_scsi_rw_xlat; |
3024 | 3024 | ||
3025 | case 0x93 /*WRITE_SAME_16*/: | 3025 | case WRITE_SAME_16: |
3026 | return ata_scsi_write_same_xlat; | 3026 | return ata_scsi_write_same_xlat; |
3027 | 3027 | ||
3028 | case SYNCHRONIZE_CACHE: | 3028 | case SYNCHRONIZE_CACHE: |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index efa8773bef5a..741065c9da67 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc) | |||
2275 | ap = qc->ap; | 2275 | ap = qc->ap; |
2276 | /* Drain up to 64K of data before we give up this recovery method */ | 2276 | /* Drain up to 64K of data before we give up this recovery method */ |
2277 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) | 2277 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) |
2278 | && count < 32768; count++) | 2278 | && count < 65536; count += 2) |
2279 | ioread16(ap->ioaddr.data_addr); | 2279 | ioread16(ap->ioaddr.data_addr); |
2280 | 2280 | ||
2281 | /* Can become DEBUG later */ | 2281 | /* Can become DEBUG later */ |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 9a09a1b11ca5..dd26bc73bd9a 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
10 | * Portions Copyright (C) 2003 Red Hat Inc | 10 | * Portions Copyright (C) 2003 Red Hat Inc |
11 | * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. | 11 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * TODO | 14 | * TODO |
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_hpt3x2n" | 27 | #define DRV_NAME "pata_hpt3x2n" |
28 | #define DRV_VERSION "0.3.7" | 28 | #define DRV_VERSION "0.3.8" |
29 | 29 | ||
30 | enum { | 30 | enum { |
31 | HPT_PCI_FAST = (1 << 31), | 31 | HPT_PCI_FAST = (1 << 31), |
@@ -264,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) | |||
264 | 264 | ||
265 | static void hpt3x2n_set_clock(struct ata_port *ap, int source) | 265 | static void hpt3x2n_set_clock(struct ata_port *ap, int source) |
266 | { | 266 | { |
267 | void __iomem *bmdma = ap->ioaddr.bmdma_addr; | 267 | void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8; |
268 | 268 | ||
269 | /* Tristate the bus */ | 269 | /* Tristate the bus */ |
270 | iowrite8(0x80, bmdma+0x73); | 270 | iowrite8(0x80, bmdma+0x73); |
@@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source) | |||
274 | iowrite8(source, bmdma+0x7B); | 274 | iowrite8(source, bmdma+0x7B); |
275 | iowrite8(0xC0, bmdma+0x79); | 275 | iowrite8(0xC0, bmdma+0x79); |
276 | 276 | ||
277 | /* Reset state machines */ | 277 | /* Reset state machines, avoid enabling the disabled channels */ |
278 | iowrite8(0x37, bmdma+0x70); | 278 | iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70); |
279 | iowrite8(0x37, bmdma+0x74); | 279 | iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74); |
280 | 280 | ||
281 | /* Complete reset */ | 281 | /* Complete reset */ |
282 | iowrite8(0x00, bmdma+0x79); | 282 | iowrite8(0x00, bmdma+0x79); |
@@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source) | |||
286 | iowrite8(0x00, bmdma+0x77); | 286 | iowrite8(0x00, bmdma+0x77); |
287 | } | 287 | } |
288 | 288 | ||
289 | /* Check if our partner interface is busy */ | ||
290 | |||
291 | static int hpt3x2n_pair_idle(struct ata_port *ap) | ||
292 | { | ||
293 | struct ata_host *host = ap->host; | ||
294 | struct ata_port *pair = host->ports[ap->port_no ^ 1]; | ||
295 | |||
296 | if (pair->hsm_task_state == HSM_ST_IDLE) | ||
297 | return 1; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) | 289 | static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) |
302 | { | 290 | { |
303 | long flags = (long)ap->host->private_data; | 291 | long flags = (long)ap->host->private_data; |
292 | |||
304 | /* See if we should use the DPLL */ | 293 | /* See if we should use the DPLL */ |
305 | if (writing) | 294 | if (writing) |
306 | return USE_DPLL; /* Needed for write */ | 295 | return USE_DPLL; /* Needed for write */ |
@@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) | |||
309 | return 0; | 298 | return 0; |
310 | } | 299 | } |
311 | 300 | ||
301 | static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc) | ||
302 | { | ||
303 | struct ata_port *ap = qc->ap; | ||
304 | struct ata_port *alt = ap->host->ports[ap->port_no ^ 1]; | ||
305 | int rc, flags = (long)ap->host->private_data; | ||
306 | int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); | ||
307 | |||
308 | /* First apply the usual rules */ | ||
309 | rc = ata_std_qc_defer(qc); | ||
310 | if (rc != 0) | ||
311 | return rc; | ||
312 | |||
313 | if ((flags & USE_DPLL) != dpll && alt->qc_active) | ||
314 | return ATA_DEFER_PORT; | ||
315 | return 0; | ||
316 | } | ||
317 | |||
312 | static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) | 318 | static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) |
313 | { | 319 | { |
314 | struct ata_taskfile *tf = &qc->tf; | ||
315 | struct ata_port *ap = qc->ap; | 320 | struct ata_port *ap = qc->ap; |
316 | int flags = (long)ap->host->private_data; | 321 | int flags = (long)ap->host->private_data; |
322 | int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); | ||
317 | 323 | ||
318 | if (hpt3x2n_pair_idle(ap)) { | 324 | if ((flags & USE_DPLL) != dpll) { |
319 | int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); | 325 | flags &= ~USE_DPLL; |
320 | if ((flags & USE_DPLL) != dpll) { | 326 | flags |= dpll; |
321 | if (dpll == 1) | 327 | ap->host->private_data = (void *)(long)flags; |
322 | hpt3x2n_set_clock(ap, 0x21); | 328 | |
323 | else | 329 | hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23); |
324 | hpt3x2n_set_clock(ap, 0x23); | ||
325 | } | ||
326 | } | 330 | } |
327 | return ata_sff_qc_issue(qc); | 331 | return ata_sff_qc_issue(qc); |
328 | } | 332 | } |
@@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = { | |||
339 | .inherits = &ata_bmdma_port_ops, | 343 | .inherits = &ata_bmdma_port_ops, |
340 | 344 | ||
341 | .bmdma_stop = hpt3x2n_bmdma_stop, | 345 | .bmdma_stop = hpt3x2n_bmdma_stop, |
346 | |||
347 | .qc_defer = hpt3x2n_qc_defer, | ||
342 | .qc_issue = hpt3x2n_qc_issue, | 348 | .qc_issue = hpt3x2n_qc_issue, |
343 | 349 | ||
344 | .cable_detect = hpt3x2n_cable_detect, | 350 | .cable_detect = hpt3x2n_cable_detect, |
@@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
454 | unsigned int f_low, f_high; | 460 | unsigned int f_low, f_high; |
455 | int adjust; | 461 | int adjust; |
456 | unsigned long iobase = pci_resource_start(dev, 4); | 462 | unsigned long iobase = pci_resource_start(dev, 4); |
457 | void *hpriv = NULL; | 463 | void *hpriv = (void *)USE_DPLL; |
458 | int rc; | 464 | int rc; |
459 | 465 | ||
460 | rc = pcim_enable_device(dev); | 466 | rc = pcim_enable_device(dev); |
@@ -539,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
539 | /* Set our private data up. We only need a few flags so we use | 545 | /* Set our private data up. We only need a few flags so we use |
540 | it directly */ | 546 | it directly */ |
541 | if (pci_mhz > 60) { | 547 | if (pci_mhz > 60) { |
542 | hpriv = (void *)PCI66; | 548 | hpriv = (void *)(PCI66 | USE_DPLL); |
543 | /* | 549 | /* |
544 | * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in | 550 | * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in |
545 | * the MISC. register to stretch the UltraDMA Tss timing. | 551 | * the MISC. register to stretch the UltraDMA Tss timing. |
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index d6f69561dc86..37ef416c1242 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c | |||
@@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) | |||
853 | return -EINVAL; | 853 | return -EINVAL; |
854 | 854 | ||
855 | cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, | 855 | cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, |
856 | res_cs0->end - res_cs1->start + 1); | 856 | resource_size(res_cs1)); |
857 | 857 | ||
858 | if (!cs1) | 858 | if (!cs1) |
859 | return -ENOMEM; | 859 | return -ENOMEM; |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a8a7be0d06ff..df8ee325d3ca 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <linux/dmapool.h> | 59 | #include <linux/dmapool.h> |
60 | #include <linux/dma-mapping.h> | 60 | #include <linux/dma-mapping.h> |
61 | #include <linux/device.h> | 61 | #include <linux/device.h> |
62 | #include <linux/clk.h> | ||
62 | #include <linux/platform_device.h> | 63 | #include <linux/platform_device.h> |
63 | #include <linux/ata_platform.h> | 64 | #include <linux/ata_platform.h> |
64 | #include <linux/mbus.h> | 65 | #include <linux/mbus.h> |
@@ -538,6 +539,7 @@ struct mv_port_signal { | |||
538 | 539 | ||
539 | struct mv_host_priv { | 540 | struct mv_host_priv { |
540 | u32 hp_flags; | 541 | u32 hp_flags; |
542 | unsigned int board_idx; | ||
541 | u32 main_irq_mask; | 543 | u32 main_irq_mask; |
542 | struct mv_port_signal signal[8]; | 544 | struct mv_port_signal signal[8]; |
543 | const struct mv_hw_ops *ops; | 545 | const struct mv_hw_ops *ops; |
@@ -548,6 +550,10 @@ struct mv_host_priv { | |||
548 | u32 irq_cause_offset; | 550 | u32 irq_cause_offset; |
549 | u32 irq_mask_offset; | 551 | u32 irq_mask_offset; |
550 | u32 unmask_all_irqs; | 552 | u32 unmask_all_irqs; |
553 | |||
554 | #if defined(CONFIG_HAVE_CLK) | ||
555 | struct clk *clk; | ||
556 | #endif | ||
551 | /* | 557 | /* |
552 | * These consistent DMA memory pools give us guaranteed | 558 | * These consistent DMA memory pools give us guaranteed |
553 | * alignment for hardware-accessed data structures, | 559 | * alignment for hardware-accessed data structures, |
@@ -2775,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) | |||
2775 | struct mv_port_priv *pp; | 2781 | struct mv_port_priv *pp; |
2776 | int edma_was_enabled; | 2782 | int edma_was_enabled; |
2777 | 2783 | ||
2778 | if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { | 2784 | if (ap->flags & ATA_FLAG_DISABLED) { |
2779 | mv_unexpected_intr(ap, 0); | 2785 | mv_unexpected_intr(ap, 0); |
2780 | return; | 2786 | return; |
2781 | } | 2787 | } |
@@ -3393,7 +3399,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, | |||
3393 | ZERO(0x024); /* respq outp */ | 3399 | ZERO(0x024); /* respq outp */ |
3394 | ZERO(0x020); /* respq inp */ | 3400 | ZERO(0x020); /* respq inp */ |
3395 | ZERO(0x02c); /* test control */ | 3401 | ZERO(0x02c); /* test control */ |
3396 | writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); | 3402 | writel(0x800, port_mmio + EDMA_IORDY_TMOUT); |
3397 | } | 3403 | } |
3398 | 3404 | ||
3399 | #undef ZERO | 3405 | #undef ZERO |
@@ -3854,7 +3860,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
3854 | /** | 3860 | /** |
3855 | * mv_init_host - Perform some early initialization of the host. | 3861 | * mv_init_host - Perform some early initialization of the host. |
3856 | * @host: ATA host to initialize | 3862 | * @host: ATA host to initialize |
3857 | * @board_idx: controller index | ||
3858 | * | 3863 | * |
3859 | * If possible, do an early global reset of the host. Then do | 3864 | * If possible, do an early global reset of the host. Then do |
3860 | * our port init and clear/unmask all/relevant host interrupts. | 3865 | * our port init and clear/unmask all/relevant host interrupts. |
@@ -3862,13 +3867,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
3862 | * LOCKING: | 3867 | * LOCKING: |
3863 | * Inherited from caller. | 3868 | * Inherited from caller. |
3864 | */ | 3869 | */ |
3865 | static int mv_init_host(struct ata_host *host, unsigned int board_idx) | 3870 | static int mv_init_host(struct ata_host *host) |
3866 | { | 3871 | { |
3867 | int rc = 0, n_hc, port, hc; | 3872 | int rc = 0, n_hc, port, hc; |
3868 | struct mv_host_priv *hpriv = host->private_data; | 3873 | struct mv_host_priv *hpriv = host->private_data; |
3869 | void __iomem *mmio = hpriv->base; | 3874 | void __iomem *mmio = hpriv->base; |
3870 | 3875 | ||
3871 | rc = mv_chip_id(host, board_idx); | 3876 | rc = mv_chip_id(host, hpriv->board_idx); |
3872 | if (rc) | 3877 | if (rc) |
3873 | goto done; | 3878 | goto done; |
3874 | 3879 | ||
@@ -3905,14 +3910,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3905 | void __iomem *port_mmio = mv_port_base(mmio, port); | 3910 | void __iomem *port_mmio = mv_port_base(mmio, port); |
3906 | 3911 | ||
3907 | mv_port_init(&ap->ioaddr, port_mmio); | 3912 | mv_port_init(&ap->ioaddr, port_mmio); |
3908 | |||
3909 | #ifdef CONFIG_PCI | ||
3910 | if (!IS_SOC(hpriv)) { | ||
3911 | unsigned int offset = port_mmio - mmio; | ||
3912 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | ||
3913 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | ||
3914 | } | ||
3915 | #endif | ||
3916 | } | 3913 | } |
3917 | 3914 | ||
3918 | for (hc = 0; hc < n_hc; hc++) { | 3915 | for (hc = 0; hc < n_hc; hc++) { |
@@ -4035,12 +4032,21 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4035 | return -ENOMEM; | 4032 | return -ENOMEM; |
4036 | host->private_data = hpriv; | 4033 | host->private_data = hpriv; |
4037 | hpriv->n_ports = n_ports; | 4034 | hpriv->n_ports = n_ports; |
4035 | hpriv->board_idx = chip_soc; | ||
4038 | 4036 | ||
4039 | host->iomap = NULL; | 4037 | host->iomap = NULL; |
4040 | hpriv->base = devm_ioremap(&pdev->dev, res->start, | 4038 | hpriv->base = devm_ioremap(&pdev->dev, res->start, |
4041 | resource_size(res)); | 4039 | resource_size(res)); |
4042 | hpriv->base -= SATAHC0_REG_BASE; | 4040 | hpriv->base -= SATAHC0_REG_BASE; |
4043 | 4041 | ||
4042 | #if defined(CONFIG_HAVE_CLK) | ||
4043 | hpriv->clk = clk_get(&pdev->dev, NULL); | ||
4044 | if (IS_ERR(hpriv->clk)) | ||
4045 | dev_notice(&pdev->dev, "cannot get clkdev\n"); | ||
4046 | else | ||
4047 | clk_enable(hpriv->clk); | ||
4048 | #endif | ||
4049 | |||
4044 | /* | 4050 | /* |
4045 | * (Re-)program MBUS remapping windows if we are asked to. | 4051 | * (Re-)program MBUS remapping windows if we are asked to. |
4046 | */ | 4052 | */ |
@@ -4049,12 +4055,12 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4049 | 4055 | ||
4050 | rc = mv_create_dma_pools(hpriv, &pdev->dev); | 4056 | rc = mv_create_dma_pools(hpriv, &pdev->dev); |
4051 | if (rc) | 4057 | if (rc) |
4052 | return rc; | 4058 | goto err; |
4053 | 4059 | ||
4054 | /* initialize adapter */ | 4060 | /* initialize adapter */ |
4055 | rc = mv_init_host(host, chip_soc); | 4061 | rc = mv_init_host(host); |
4056 | if (rc) | 4062 | if (rc) |
4057 | return rc; | 4063 | goto err; |
4058 | 4064 | ||
4059 | dev_printk(KERN_INFO, &pdev->dev, | 4065 | dev_printk(KERN_INFO, &pdev->dev, |
4060 | "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, | 4066 | "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, |
@@ -4062,6 +4068,15 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4062 | 4068 | ||
4063 | return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, | 4069 | return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, |
4064 | IRQF_SHARED, &mv6_sht); | 4070 | IRQF_SHARED, &mv6_sht); |
4071 | err: | ||
4072 | #if defined(CONFIG_HAVE_CLK) | ||
4073 | if (!IS_ERR(hpriv->clk)) { | ||
4074 | clk_disable(hpriv->clk); | ||
4075 | clk_put(hpriv->clk); | ||
4076 | } | ||
4077 | #endif | ||
4078 | |||
4079 | return rc; | ||
4065 | } | 4080 | } |
4066 | 4081 | ||
4067 | /* | 4082 | /* |
@@ -4076,14 +4091,66 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) | |||
4076 | { | 4091 | { |
4077 | struct device *dev = &pdev->dev; | 4092 | struct device *dev = &pdev->dev; |
4078 | struct ata_host *host = dev_get_drvdata(dev); | 4093 | struct ata_host *host = dev_get_drvdata(dev); |
4079 | 4094 | #if defined(CONFIG_HAVE_CLK) | |
4095 | struct mv_host_priv *hpriv = host->private_data; | ||
4096 | #endif | ||
4080 | ata_host_detach(host); | 4097 | ata_host_detach(host); |
4098 | |||
4099 | #if defined(CONFIG_HAVE_CLK) | ||
4100 | if (!IS_ERR(hpriv->clk)) { | ||
4101 | clk_disable(hpriv->clk); | ||
4102 | clk_put(hpriv->clk); | ||
4103 | } | ||
4104 | #endif | ||
4081 | return 0; | 4105 | return 0; |
4082 | } | 4106 | } |
4083 | 4107 | ||
4108 | #ifdef CONFIG_PM | ||
4109 | static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) | ||
4110 | { | ||
4111 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
4112 | if (host) | ||
4113 | return ata_host_suspend(host, state); | ||
4114 | else | ||
4115 | return 0; | ||
4116 | } | ||
4117 | |||
4118 | static int mv_platform_resume(struct platform_device *pdev) | ||
4119 | { | ||
4120 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
4121 | int ret; | ||
4122 | |||
4123 | if (host) { | ||
4124 | struct mv_host_priv *hpriv = host->private_data; | ||
4125 | const struct mv_sata_platform_data *mv_platform_data = \ | ||
4126 | pdev->dev.platform_data; | ||
4127 | /* | ||
4128 | * (Re-)program MBUS remapping windows if we are asked to. | ||
4129 | */ | ||
4130 | if (mv_platform_data->dram != NULL) | ||
4131 | mv_conf_mbus_windows(hpriv, mv_platform_data->dram); | ||
4132 | |||
4133 | /* initialize adapter */ | ||
4134 | ret = mv_init_host(host); | ||
4135 | if (ret) { | ||
4136 | printk(KERN_ERR DRV_NAME ": Error during HW init\n"); | ||
4137 | return ret; | ||
4138 | } | ||
4139 | ata_host_resume(host); | ||
4140 | } | ||
4141 | |||
4142 | return 0; | ||
4143 | } | ||
4144 | #else | ||
4145 | #define mv_platform_suspend NULL | ||
4146 | #define mv_platform_resume NULL | ||
4147 | #endif | ||
4148 | |||
4084 | static struct platform_driver mv_platform_driver = { | 4149 | static struct platform_driver mv_platform_driver = { |
4085 | .probe = mv_platform_probe, | 4150 | .probe = mv_platform_probe, |
4086 | .remove = __devexit_p(mv_platform_remove), | 4151 | .remove = __devexit_p(mv_platform_remove), |
4152 | .suspend = mv_platform_suspend, | ||
4153 | .resume = mv_platform_resume, | ||
4087 | .driver = { | 4154 | .driver = { |
4088 | .name = DRV_NAME, | 4155 | .name = DRV_NAME, |
4089 | .owner = THIS_MODULE, | 4156 | .owner = THIS_MODULE, |
@@ -4094,6 +4161,9 @@ static struct platform_driver mv_platform_driver = { | |||
4094 | #ifdef CONFIG_PCI | 4161 | #ifdef CONFIG_PCI |
4095 | static int mv_pci_init_one(struct pci_dev *pdev, | 4162 | static int mv_pci_init_one(struct pci_dev *pdev, |
4096 | const struct pci_device_id *ent); | 4163 | const struct pci_device_id *ent); |
4164 | #ifdef CONFIG_PM | ||
4165 | static int mv_pci_device_resume(struct pci_dev *pdev); | ||
4166 | #endif | ||
4097 | 4167 | ||
4098 | 4168 | ||
4099 | static struct pci_driver mv_pci_driver = { | 4169 | static struct pci_driver mv_pci_driver = { |
@@ -4101,6 +4171,11 @@ static struct pci_driver mv_pci_driver = { | |||
4101 | .id_table = mv_pci_tbl, | 4171 | .id_table = mv_pci_tbl, |
4102 | .probe = mv_pci_init_one, | 4172 | .probe = mv_pci_init_one, |
4103 | .remove = ata_pci_remove_one, | 4173 | .remove = ata_pci_remove_one, |
4174 | #ifdef CONFIG_PM | ||
4175 | .suspend = ata_pci_device_suspend, | ||
4176 | .resume = mv_pci_device_resume, | ||
4177 | #endif | ||
4178 | |||
4104 | }; | 4179 | }; |
4105 | 4180 | ||
4106 | /* move to PCI layer or libata core? */ | 4181 | /* move to PCI layer or libata core? */ |
@@ -4194,7 +4269,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4194 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; | 4269 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; |
4195 | struct ata_host *host; | 4270 | struct ata_host *host; |
4196 | struct mv_host_priv *hpriv; | 4271 | struct mv_host_priv *hpriv; |
4197 | int n_ports, rc; | 4272 | int n_ports, port, rc; |
4198 | 4273 | ||
4199 | if (!printed_version++) | 4274 | if (!printed_version++) |
4200 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); | 4275 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); |
@@ -4208,6 +4283,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4208 | return -ENOMEM; | 4283 | return -ENOMEM; |
4209 | host->private_data = hpriv; | 4284 | host->private_data = hpriv; |
4210 | hpriv->n_ports = n_ports; | 4285 | hpriv->n_ports = n_ports; |
4286 | hpriv->board_idx = board_idx; | ||
4211 | 4287 | ||
4212 | /* acquire resources */ | 4288 | /* acquire resources */ |
4213 | rc = pcim_enable_device(pdev); | 4289 | rc = pcim_enable_device(pdev); |
@@ -4230,8 +4306,17 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4230 | if (rc) | 4306 | if (rc) |
4231 | return rc; | 4307 | return rc; |
4232 | 4308 | ||
4309 | for (port = 0; port < host->n_ports; port++) { | ||
4310 | struct ata_port *ap = host->ports[port]; | ||
4311 | void __iomem *port_mmio = mv_port_base(hpriv->base, port); | ||
4312 | unsigned int offset = port_mmio - hpriv->base; | ||
4313 | |||
4314 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | ||
4315 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | ||
4316 | } | ||
4317 | |||
4233 | /* initialize adapter */ | 4318 | /* initialize adapter */ |
4234 | rc = mv_init_host(host, board_idx); | 4319 | rc = mv_init_host(host); |
4235 | if (rc) | 4320 | if (rc) |
4236 | return rc; | 4321 | return rc; |
4237 | 4322 | ||
@@ -4247,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4247 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, | 4332 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, |
4248 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); | 4333 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); |
4249 | } | 4334 | } |
4335 | |||
4336 | #ifdef CONFIG_PM | ||
4337 | static int mv_pci_device_resume(struct pci_dev *pdev) | ||
4338 | { | ||
4339 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
4340 | int rc; | ||
4341 | |||
4342 | rc = ata_pci_device_do_resume(pdev); | ||
4343 | if (rc) | ||
4344 | return rc; | ||
4345 | |||
4346 | /* initialize adapter */ | ||
4347 | rc = mv_init_host(host); | ||
4348 | if (rc) | ||
4349 | return rc; | ||
4350 | |||
4351 | ata_host_resume(host); | ||
4352 | |||
4353 | return 0; | ||
4354 | } | ||
4355 | #endif | ||
4250 | #endif | 4356 | #endif |
4251 | 4357 | ||
4252 | static int mv_platform_probe(struct platform_device *pdev); | 4358 | static int mv_platform_probe(struct platform_device *pdev); |