aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-19 14:04:29 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-19 14:04:29 -0500
commit70e66a5079b2b33f142303d31581cf03f7af98fe (patch)
tree3160fb22716de0407d87ec9de6135127ed7c1fed /drivers/ata/sata_mv.c
parenteca9dfcd0029c8a84b1094bb84a2fb53e4addf6c (diff)
parent0535f2bc170bc0779ac471faff39f633ca19ab59 (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.
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c144
1 files changed, 125 insertions, 19 deletions
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
539struct mv_host_priv { 540struct 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 */
3865static int mv_init_host(struct ata_host *host, unsigned int board_idx) 3870static 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);
4071err:
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
4109static 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
4118static 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
4084static struct platform_driver mv_platform_driver = { 4149static 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
4095static int mv_pci_init_one(struct pci_dev *pdev, 4162static 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
4165static int mv_pci_device_resume(struct pci_dev *pdev);
4166#endif
4097 4167
4098 4168
4099static struct pci_driver mv_pci_driver = { 4169static 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
4337static 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
4252static int mv_platform_probe(struct platform_device *pdev); 4358static int mv_platform_probe(struct platform_device *pdev);