Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70e66a50 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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.
parents eca9dfcd 0535f2bc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
	case WRITE_16:
		return ata_scsi_rw_xlat;

	case 0x93 /*WRITE_SAME_16*/:
	case WRITE_SAME_16:
		return ata_scsi_write_same_xlat;

	case SYNCHRONIZE_CACHE:
+1 −1
Original line number Diff line number Diff line
@@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
	ap = qc->ap;
	/* Drain up to 64K of data before we give up this recovery method */
	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
						&& count < 32768; count++)
						&& count < 65536; count += 2)
		ioread16(ap->ioaddr.data_addr);

	/* Can become DEBUG later */
+35 −29
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
 * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
 * Portions Copyright (C) 2001	        Sun Microsystems, 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
@@ -25,7 +25,7 @@
#include <linux/libata.h>

#define DRV_NAME	"pata_hpt3x2n"
#define DRV_VERSION	"0.3.7"
#define DRV_VERSION	"0.3.8"

enum {
	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)
{
	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
	void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8;

	/* Tristate the bus */
	iowrite8(0x80, bmdma+0x73);
@@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
	iowrite8(source, bmdma+0x7B);
	iowrite8(0xC0, bmdma+0x79);

	/* Reset state machines */
	iowrite8(0x37, bmdma+0x70);
	iowrite8(0x37, bmdma+0x74);
	/* Reset state machines, avoid enabling the disabled channels */
	iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70);
	iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74);

	/* Complete reset */
	iowrite8(0x00, bmdma+0x79);
@@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
	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)
{
	long flags = (long)ap->host->private_data;

	/* See if we should use the DPLL */
	if (writing)
		return USE_DPLL;	/* Needed for write */
@@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
	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)
{
	struct ata_taskfile *tf = &qc->tf;
	struct ata_port *ap = qc->ap;
	int flags = (long)ap->host->private_data;
	int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);

	if (hpt3x2n_pair_idle(ap)) {
		int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE));
	if ((flags & USE_DPLL) != dpll) {
			if (dpll == 1)
				hpt3x2n_set_clock(ap, 0x21);
			else
				hpt3x2n_set_clock(ap, 0x23);
		}
		flags &= ~USE_DPLL;
		flags |= dpll;
		ap->host->private_data = (void *)(long)flags;

		hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
	}
	return ata_sff_qc_issue(qc);
}
@@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = {
	.inherits	= &ata_bmdma_port_ops,

	.bmdma_stop	= hpt3x2n_bmdma_stop,

	.qc_defer	= hpt3x2n_qc_defer,
	.qc_issue	= hpt3x2n_qc_issue,

	.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;
	int adjust;
	unsigned long iobase = pci_resource_start(dev, 4);
	void *hpriv = NULL;
	void *hpriv = (void *)USE_DPLL;
	int rc;

	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
	   it directly */
	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
		 * the MISC. register to stretch the UltraDMA Tss timing.
+1 −1
Original line number Diff line number Diff line
@@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev)
			return -EINVAL;

		cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
					   res_cs0->end - res_cs1->start + 1);
					   resource_size(res_cs1));

		if (!cs1)
			return -ENOMEM;
+125 −19
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mbus.h>
@@ -538,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;
@@ -548,6 +550,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,
@@ -2775,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;
	}
@@ -3393,7 +3399,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
@@ -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.
 *	@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.
@@ -3862,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;

@@ -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);

		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++) {
@@ -4035,12 +4032,21 @@ 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,
				   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 +4055,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);
	rc = mv_init_host(host);
	if (rc)
		return rc;
		goto err;

	dev_printk(KERN_INFO, &pdev->dev,
		   "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,
				 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 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;
}

#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 = {
	.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,
@@ -4094,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 = {
@@ -4101,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? */
@@ -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 };
	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");
@@ -4208,6 +4283,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);
@@ -4230,8 +4306,17 @@ 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);
	rc = mv_init_host(host);
	if (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,
				 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);