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.
This commit is contained in:
Linus Torvalds 2009-12-19 11:04:29 -08:00
commit 70e66a5079
5 changed files with 163 additions and 51 deletions

View File

@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case WRITE_16: case WRITE_16:
return ata_scsi_rw_xlat; return ata_scsi_rw_xlat;
case 0x93 /*WRITE_SAME_16*/: case WRITE_SAME_16:
return ata_scsi_write_same_xlat; return ata_scsi_write_same_xlat;
case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE:

View File

@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
ap = qc->ap; ap = qc->ap;
/* Drain up to 64K of data before we give up this recovery method */ /* Drain up to 64K of data before we give up this recovery method */
for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
&& count < 32768; count++) && count < 65536; count += 2)
ioread16(ap->ioaddr.data_addr); ioread16(ap->ioaddr.data_addr);
/* Can become DEBUG later */ /* Can become DEBUG later */

View File

@ -8,7 +8,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc * Portions Copyright (C) 2003 Red Hat Inc
* Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * Portions Copyright (C) 2005-2009 MontaVista Software, Inc.
* *
* *
* TODO * TODO
@ -25,7 +25,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n" #define DRV_NAME "pata_hpt3x2n"
#define DRV_VERSION "0.3.7" #define DRV_VERSION "0.3.8"
enum { enum {
HPT_PCI_FAST = (1 << 31), HPT_PCI_FAST = (1 << 31),
@ -264,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
static void hpt3x2n_set_clock(struct ata_port *ap, int source) static void hpt3x2n_set_clock(struct ata_port *ap, int source)
{ {
void __iomem *bmdma = ap->ioaddr.bmdma_addr; void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8;
/* Tristate the bus */ /* Tristate the bus */
iowrite8(0x80, bmdma+0x73); iowrite8(0x80, bmdma+0x73);
@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
iowrite8(source, bmdma+0x7B); iowrite8(source, bmdma+0x7B);
iowrite8(0xC0, bmdma+0x79); iowrite8(0xC0, bmdma+0x79);
/* Reset state machines */ /* Reset state machines, avoid enabling the disabled channels */
iowrite8(0x37, bmdma+0x70); iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70);
iowrite8(0x37, bmdma+0x74); iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74);
/* Complete reset */ /* Complete reset */
iowrite8(0x00, bmdma+0x79); iowrite8(0x00, bmdma+0x79);
@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
iowrite8(0x00, bmdma+0x77); iowrite8(0x00, bmdma+0x77);
} }
/* Check if our partner interface is busy */
static int hpt3x2n_pair_idle(struct ata_port *ap)
{
struct ata_host *host = ap->host;
struct ata_port *pair = host->ports[ap->port_no ^ 1];
if (pair->hsm_task_state == HSM_ST_IDLE)
return 1;
return 0;
}
static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
{ {
long flags = (long)ap->host->private_data; long flags = (long)ap->host->private_data;
/* See if we should use the DPLL */ /* See if we should use the DPLL */
if (writing) if (writing)
return USE_DPLL; /* Needed for write */ return USE_DPLL; /* Needed for write */
@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
return 0; return 0;
} }
static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_port *alt = ap->host->ports[ap->port_no ^ 1];
int rc, flags = (long)ap->host->private_data;
int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
/* First apply the usual rules */
rc = ata_std_qc_defer(qc);
if (rc != 0)
return rc;
if ((flags & USE_DPLL) != dpll && alt->qc_active)
return ATA_DEFER_PORT;
return 0;
}
static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
{ {
struct ata_taskfile *tf = &qc->tf;
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
int flags = (long)ap->host->private_data; int flags = (long)ap->host->private_data;
int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
if (hpt3x2n_pair_idle(ap)) { if ((flags & USE_DPLL) != dpll) {
int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); flags &= ~USE_DPLL;
if ((flags & USE_DPLL) != dpll) { flags |= dpll;
if (dpll == 1) ap->host->private_data = (void *)(long)flags;
hpt3x2n_set_clock(ap, 0x21);
else hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
hpt3x2n_set_clock(ap, 0x23);
}
} }
return ata_sff_qc_issue(qc); return ata_sff_qc_issue(qc);
} }
@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = {
.inherits = &ata_bmdma_port_ops, .inherits = &ata_bmdma_port_ops,
.bmdma_stop = hpt3x2n_bmdma_stop, .bmdma_stop = hpt3x2n_bmdma_stop,
.qc_defer = hpt3x2n_qc_defer,
.qc_issue = hpt3x2n_qc_issue, .qc_issue = hpt3x2n_qc_issue,
.cable_detect = hpt3x2n_cable_detect, .cable_detect = hpt3x2n_cable_detect,
@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
unsigned int f_low, f_high; unsigned int f_low, f_high;
int adjust; int adjust;
unsigned long iobase = pci_resource_start(dev, 4); unsigned long iobase = pci_resource_start(dev, 4);
void *hpriv = NULL; void *hpriv = (void *)USE_DPLL;
int rc; int rc;
rc = pcim_enable_device(dev); rc = pcim_enable_device(dev);
@ -539,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* Set our private data up. We only need a few flags so we use /* Set our private data up. We only need a few flags so we use
it directly */ it directly */
if (pci_mhz > 60) { if (pci_mhz > 60) {
hpriv = (void *)PCI66; hpriv = (void *)(PCI66 | USE_DPLL);
/* /*
* On HPT371N, if ATA clock is 66 MHz we must set bit 2 in * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
* the MISC. register to stretch the UltraDMA Tss timing. * the MISC. register to stretch the UltraDMA Tss timing.

View File

@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
res_cs0->end - res_cs1->start + 1); resource_size(res_cs1));
if (!cs1) if (!cs1)
return -ENOMEM; return -ENOMEM;

View File

@ -59,6 +59,7 @@
#include <linux/dmapool.h> #include <linux/dmapool.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/clk.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/ata_platform.h> #include <linux/ata_platform.h>
#include <linux/mbus.h> #include <linux/mbus.h>
@ -538,6 +539,7 @@ struct mv_port_signal {
struct mv_host_priv { struct mv_host_priv {
u32 hp_flags; u32 hp_flags;
unsigned int board_idx;
u32 main_irq_mask; u32 main_irq_mask;
struct mv_port_signal signal[8]; struct mv_port_signal signal[8];
const struct mv_hw_ops *ops; const struct mv_hw_ops *ops;
@ -548,6 +550,10 @@ struct mv_host_priv {
u32 irq_cause_offset; u32 irq_cause_offset;
u32 irq_mask_offset; u32 irq_mask_offset;
u32 unmask_all_irqs; u32 unmask_all_irqs;
#if defined(CONFIG_HAVE_CLK)
struct clk *clk;
#endif
/* /*
* These consistent DMA memory pools give us guaranteed * These consistent DMA memory pools give us guaranteed
* alignment for hardware-accessed data structures, * alignment for hardware-accessed data structures,
@ -2775,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
struct mv_port_priv *pp; struct mv_port_priv *pp;
int edma_was_enabled; int edma_was_enabled;
if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { if (ap->flags & ATA_FLAG_DISABLED) {
mv_unexpected_intr(ap, 0); mv_unexpected_intr(ap, 0);
return; return;
} }
@ -3393,7 +3399,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
ZERO(0x024); /* respq outp */ ZERO(0x024); /* respq outp */
ZERO(0x020); /* respq inp */ ZERO(0x020); /* respq inp */
ZERO(0x02c); /* test control */ ZERO(0x02c); /* test control */
writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); writel(0x800, port_mmio + EDMA_IORDY_TMOUT);
} }
#undef ZERO #undef ZERO
@ -3854,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. * mv_init_host - Perform some early initialization of the host.
* @host: ATA host to initialize * @host: ATA host to initialize
* @board_idx: controller index
* *
* If possible, do an early global reset of the host. Then do * If possible, do an early global reset of the host. Then do
* our port init and clear/unmask all/relevant host interrupts. * 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)
* LOCKING: * LOCKING:
* Inherited from caller. * 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; int rc = 0, n_hc, port, hc;
struct mv_host_priv *hpriv = host->private_data; struct mv_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->base; void __iomem *mmio = hpriv->base;
rc = mv_chip_id(host, board_idx); rc = mv_chip_id(host, hpriv->board_idx);
if (rc) if (rc)
goto done; goto done;
@ -3905,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); void __iomem *port_mmio = mv_port_base(mmio, port);
mv_port_init(&ap->ioaddr, port_mmio); 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++) { for (hc = 0; hc < n_hc; hc++) {
@ -4035,12 +4032,21 @@ static int mv_platform_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
host->private_data = hpriv; host->private_data = hpriv;
hpriv->n_ports = n_ports; hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc;
host->iomap = NULL; host->iomap = NULL;
hpriv->base = devm_ioremap(&pdev->dev, res->start, hpriv->base = devm_ioremap(&pdev->dev, res->start,
resource_size(res)); resource_size(res));
hpriv->base -= SATAHC0_REG_BASE; 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. * (Re-)program MBUS remapping windows if we are asked to.
*/ */
@ -4049,12 +4055,12 @@ static int mv_platform_probe(struct platform_device *pdev)
rc = mv_create_dma_pools(hpriv, &pdev->dev); rc = mv_create_dma_pools(hpriv, &pdev->dev);
if (rc) if (rc)
return rc; goto err;
/* initialize adapter */ /* initialize adapter */
rc = mv_init_host(host, chip_soc); rc = mv_init_host(host);
if (rc) if (rc)
return rc; goto err;
dev_printk(KERN_INFO, &pdev->dev, dev_printk(KERN_INFO, &pdev->dev,
"slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH,
@ -4062,6 +4068,15 @@ static int mv_platform_probe(struct platform_device *pdev)
return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
IRQF_SHARED, &mv6_sht); 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,14 +4091,66 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ata_host *host = dev_get_drvdata(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); 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; 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);
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 = { static struct platform_driver mv_platform_driver = {
.probe = mv_platform_probe, .probe = mv_platform_probe,
.remove = __devexit_p(mv_platform_remove), .remove = __devexit_p(mv_platform_remove),
.suspend = mv_platform_suspend,
.resume = mv_platform_resume,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
@ -4094,6 +4161,9 @@ static struct platform_driver mv_platform_driver = {
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
static int mv_pci_init_one(struct pci_dev *pdev, static int mv_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent); 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 = { static struct pci_driver mv_pci_driver = {
@ -4101,6 +4171,11 @@ static struct pci_driver mv_pci_driver = {
.id_table = mv_pci_tbl, .id_table = mv_pci_tbl,
.probe = mv_pci_init_one, .probe = mv_pci_init_one,
.remove = ata_pci_remove_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? */ /* move to PCI layer or libata core? */
@ -4194,7 +4269,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
struct ata_host *host; struct ata_host *host;
struct mv_host_priv *hpriv; struct mv_host_priv *hpriv;
int n_ports, rc; int n_ports, port, rc;
if (!printed_version++) if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@ -4208,6 +4283,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
return -ENOMEM; return -ENOMEM;
host->private_data = hpriv; host->private_data = hpriv;
hpriv->n_ports = n_ports; hpriv->n_ports = n_ports;
hpriv->board_idx = board_idx;
/* acquire resources */ /* acquire resources */
rc = pcim_enable_device(pdev); rc = pcim_enable_device(pdev);
@ -4230,8 +4306,17 @@ static int mv_pci_init_one(struct pci_dev *pdev,
if (rc) if (rc)
return 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 */ /* initialize adapter */
rc = mv_init_host(host, board_idx); rc = mv_init_host(host);
if (rc) if (rc)
return rc; return rc;
@ -4247,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev,
return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); 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 #endif
static int mv_platform_probe(struct platform_device *pdev); static int mv_platform_probe(struct platform_device *pdev);