From d7b0c143693bcbf391d2be235e150b97bfd8f9ba Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:17 +0200 Subject: sata_mv: increase PIO IORDY timeout The old value (0xbc) in cycles of the IORDY timeout is suitable for devices with core clock of 166 MHz, but some SoC controllers have faster core clocks. The new value will make the IORDY timeout large enough also for all SoC devices. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a8a7be0d06ff..bbeaf3a776c9 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3393,7 +3393,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, ZERO(0x024); /* respq outp */ ZERO(0x020); /* respq inp */ ZERO(0x02c); /* test control */ - writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); + writel(0x800, port_mmio + EDMA_IORDY_TMOUT); } #undef ZERO -- cgit v1.2.3 From c77a2f4e6b76c9094182dfa653ece4243f6df80c Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:18 +0200 Subject: sata_mv: support clkdev framework Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index bbeaf3a776c9..b625b3614989 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -548,6 +549,10 @@ struct mv_host_priv { u32 irq_cause_offset; u32 irq_mask_offset; u32 unmask_all_irqs; + +#if defined(CONFIG_HAVE_CLK) + struct clk *clk; +#endif /* * These consistent DMA memory pools give us guaranteed * alignment for hardware-accessed data structures, @@ -4041,6 +4046,14 @@ static int mv_platform_probe(struct platform_device *pdev) resource_size(res)); hpriv->base -= SATAHC0_REG_BASE; +#if defined(CONFIG_HAVE_CLK) + hpriv->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(hpriv->clk)) + dev_notice(&pdev->dev, "cannot get clkdev\n"); + else + clk_enable(hpriv->clk); +#endif + /* * (Re-)program MBUS remapping windows if we are asked to. */ @@ -4049,12 +4062,12 @@ static int mv_platform_probe(struct platform_device *pdev) rc = mv_create_dma_pools(hpriv, &pdev->dev); if (rc) - return rc; + goto err; /* initialize adapter */ rc = mv_init_host(host, chip_soc); if (rc) - return rc; + goto err; dev_printk(KERN_INFO, &pdev->dev, "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, @@ -4062,6 +4075,15 @@ static int mv_platform_probe(struct platform_device *pdev) return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, IRQF_SHARED, &mv6_sht); +err: +#if defined(CONFIG_HAVE_CLK) + if (!IS_ERR(hpriv->clk)) { + clk_disable(hpriv->clk); + clk_put(hpriv->clk); + } +#endif + + return rc; } /* @@ -4076,8 +4098,17 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ata_host *host = dev_get_drvdata(dev); - +#if defined(CONFIG_HAVE_CLK) + struct mv_host_priv *hpriv = host->private_data; +#endif ata_host_detach(host); + +#if defined(CONFIG_HAVE_CLK) + if (!IS_ERR(hpriv->clk)) { + clk_disable(hpriv->clk); + clk_put(hpriv->clk); + } +#endif return 0; } -- cgit v1.2.3 From 6481f2b52cd5411ea6342b749daf0e4f3b390d7b Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:19 +0200 Subject: sata_mv: add power management support for the platform driver Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) mode change 100644 => 100755 drivers/ata/sata_mv.c (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c old mode 100644 new mode 100755 index b625b3614989..0f7704c0b4cc --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4112,9 +4112,52 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + if (host) + return ata_host_suspend(host, state); + else + return 0; +} + +static int mv_platform_resume(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int ret; + + if (host) { + struct mv_host_priv *hpriv = host->private_data; + const struct mv_sata_platform_data *mv_platform_data = \ + pdev->dev.platform_data; + /* + * (Re-)program MBUS remapping windows if we are asked to. + */ + if (mv_platform_data->dram != NULL) + mv_conf_mbus_windows(hpriv, mv_platform_data->dram); + + /* initialize adapter */ + ret = mv_init_host(host, chip_soc); + if (ret) { + printk(KERN_ERR DRV_NAME ": Error during HW init\n"); + return ret; + } + ata_host_resume(host); + } + + return 0; +} +#else +#define mv_platform_suspend NULL +#define mv_platform_resume NULL +#endif + static struct platform_driver mv_platform_driver = { .probe = mv_platform_probe, .remove = __devexit_p(mv_platform_remove), + .suspend = mv_platform_suspend, + .resume = mv_platform_resume, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, -- cgit v1.2.3 From c4bc7d7310a40c8c0b917e88983dc4a8e6b59e38 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:20 +0200 Subject: sata_mv: move the PCI bar description initialization code The mv_init_host will be used to initialize the host hw on resume. The PCI bar description need to be initialized only once when the device probed. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 0f7704c0b4cc..e1b9568538f3 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3910,14 +3910,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) void __iomem *port_mmio = mv_port_base(mmio, port); mv_port_init(&ap->ioaddr, port_mmio); - -#ifdef CONFIG_PCI - if (!IS_SOC(hpriv)) { - unsigned int offset = port_mmio - mmio; - ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); - ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); - } -#endif } for (hc = 0; hc < n_hc; hc++) { @@ -4268,7 +4260,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; struct ata_host *host; struct mv_host_priv *hpriv; - int n_ports, rc; + int n_ports, port, rc; if (!printed_version++) dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); @@ -4304,6 +4296,15 @@ static int mv_pci_init_one(struct pci_dev *pdev, if (rc) return rc; + for (port = 0; port < host->n_ports; port++) { + struct ata_port *ap = host->ports[port]; + void __iomem *port_mmio = mv_port_base(hpriv->base, port); + unsigned int offset = port_mmio - hpriv->base; + + ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); + ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); + } + /* initialize adapter */ rc = mv_init_host(host, board_idx); if (rc) -- cgit v1.2.3 From 1bfeff03f8a52eb896e5aad33d52e2451437bb0b Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Thu, 17 Dec 2009 01:05:00 -0500 Subject: sata_mv: store the board_idx into the host private data This information will be used in the resume function. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index e1b9568538f3..53a1d97cd9a6 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -539,6 +539,7 @@ struct mv_port_signal { struct mv_host_priv { u32 hp_flags; + unsigned int board_idx; u32 main_irq_mask; struct mv_port_signal signal[8]; const struct mv_hw_ops *ops; @@ -3859,7 +3860,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) /** * mv_init_host - Perform some early initialization of the host. * @host: ATA host to initialize - * @board_idx: controller index * * If possible, do an early global reset of the host. Then do * our port init and clear/unmask all/relevant host interrupts. @@ -3867,13 +3867,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) * LOCKING: * Inherited from caller. */ -static int mv_init_host(struct ata_host *host, unsigned int board_idx) +static int mv_init_host(struct ata_host *host) { int rc = 0, n_hc, port, hc; struct mv_host_priv *hpriv = host->private_data; void __iomem *mmio = hpriv->base; - rc = mv_chip_id(host, board_idx); + rc = mv_chip_id(host, hpriv->board_idx); if (rc) goto done; @@ -4032,6 +4032,7 @@ static int mv_platform_probe(struct platform_device *pdev) return -ENOMEM; host->private_data = hpriv; hpriv->n_ports = n_ports; + hpriv->board_idx = chip_soc; host->iomap = NULL; hpriv->base = devm_ioremap(&pdev->dev, res->start, @@ -4057,7 +4058,7 @@ static int mv_platform_probe(struct platform_device *pdev) goto err; /* initialize adapter */ - rc = mv_init_host(host, chip_soc); + rc = mv_init_host(host); if (rc) goto err; @@ -4130,7 +4131,7 @@ static int mv_platform_resume(struct platform_device *pdev) mv_conf_mbus_windows(hpriv, mv_platform_data->dram); /* initialize adapter */ - ret = mv_init_host(host, chip_soc); + ret = mv_init_host(host); if (ret) { printk(KERN_ERR DRV_NAME ": Error during HW init\n"); return ret; @@ -4274,6 +4275,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, return -ENOMEM; host->private_data = hpriv; hpriv->n_ports = n_ports; + hpriv->board_idx = board_idx; /* acquire resources */ rc = pcim_enable_device(pdev); @@ -4306,7 +4308,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, } /* initialize adapter */ - rc = mv_init_host(host, board_idx); + rc = mv_init_host(host); if (rc) return rc; -- cgit v1.2.3 From b2dec48ccaad004fc706352f82725d43369d9bd7 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:22 +0200 Subject: sata_mv: add power management support for the PCI controllers. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 53a1d97cd9a6..73768195ccc2 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4161,6 +4161,9 @@ static struct platform_driver mv_platform_driver = { #ifdef CONFIG_PCI static int mv_pci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +#ifdef CONFIG_PM +static int mv_pci_device_resume(struct pci_dev *pdev); +#endif static struct pci_driver mv_pci_driver = { @@ -4168,6 +4171,11 @@ static struct pci_driver mv_pci_driver = { .id_table = mv_pci_tbl, .probe = mv_pci_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = mv_pci_device_resume, +#endif + }; /* move to PCI layer or libata core? */ @@ -4324,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev, return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); } + +#ifdef CONFIG_PM +static int mv_pci_device_resume(struct pci_dev *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc; + + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; + + /* initialize adapter */ + rc = mv_init_host(host); + if (rc) + return rc; + + ata_host_resume(host); + + return 0; +} +#endif #endif static int mv_platform_probe(struct platform_device *pdev); -- cgit v1.2.3 From 0535f2bc170bc0779ac471faff39f633ca19ab59 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 17 Dec 2009 01:23:16 -0500 Subject: sata_mv: remove pointless NULL test Remove !ap test, where ap is guaranteed not-NULL. Found by way of automated bug report from Alexander Strakh via "Linux Device Drivers Verification Project (Svace Detector)" Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/sata_mv.c') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 73768195ccc2..df8ee325d3ca 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2781,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) struct mv_port_priv *pp; int edma_was_enabled; - if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { + if (ap->flags & ATA_FLAG_DISABLED) { mv_unexpected_intr(ap, 0); return; } -- cgit v1.2.3