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

Commit 82ef04fb authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

libata: make SCR access ops per-link



Logically, SCR access ops should take @link; however, there was no
compelling reason to convert all SCR access ops when adding @link
abstraction as there's one-to-one mapping between a port and a non-PMP
link.  However, that assumption won't hold anymore with the scheduled
addition of slave link.

Make SCR access ops per-link.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 6ef190cc
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -267,8 +267,8 @@ struct ahci_port_priv {
					 	 * per PM slot */
};

static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
@@ -820,10 +820,10 @@ static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
	return 0;
}

static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{
	void __iomem *port_mmio = ahci_port_base(ap);
	int offset = ahci_scr_offset(ap, sc_reg);
	void __iomem *port_mmio = ahci_port_base(link->ap);
	int offset = ahci_scr_offset(link->ap, sc_reg);

	if (offset) {
		*val = readl(port_mmio + offset);
@@ -832,10 +832,10 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
	return -EINVAL;
}

static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{
	void __iomem *port_mmio = ahci_port_base(ap);
	int offset = ahci_scr_offset(ap, sc_reg);
	void __iomem *port_mmio = ahci_port_base(link->ap);
	int offset = ahci_scr_offset(link->ap, sc_reg);

	if (offset) {
		writel(val, port_mmio + offset);
@@ -973,7 +973,7 @@ static void ahci_disable_alpm(struct ata_port *ap)
	writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);

	/* go ahead and clean out PhyRdy Change from Serror too */
	ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
	ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));

	/*
 	 * Clear flag to indicate that we should ignore all PhyRdy
@@ -1937,8 +1937,8 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
	ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat);

	/* AHCI needs SError cleared; otherwise, it might lock up */
	ahci_scr_read(ap, SCR_ERROR, &serror);
	ahci_scr_write(ap, SCR_ERROR, serror);
	ahci_scr_read(&ap->link, SCR_ERROR, &serror);
	ahci_scr_write(&ap->link, SCR_ERROR, serror);
	host_ehi->serror |= serror;

	/* some controllers set IRQ_IF_ERR on device errors, ignore it */
@@ -2027,7 +2027,7 @@ static void ahci_port_intr(struct ata_port *ap)
	if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
		(status & PORT_IRQ_PHYRDY)) {
		status &= ~PORT_IRQ_PHYRDY;
		ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
		ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
	}

	if (unlikely(status & PORT_IRQ_ERROR)) {
+11 −4
Original line number Diff line number Diff line
@@ -165,8 +165,10 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static int ich_pata_cable_detect(struct ata_port *ap);
static u8 piix_vmw_bmdma_status(struct ata_port *ap);
static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
static int piix_sidpr_scr_read(struct ata_link *link,
			       unsigned int reg, u32 *val);
static int piix_sidpr_scr_write(struct ata_link *link,
				unsigned int reg, u32 val);
#ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -971,8 +973,10 @@ static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
	return val;
}

static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val)
static int piix_sidpr_scr_read(struct ata_link *link,
			       unsigned int reg, u32 *val)
{
	struct ata_port *ap = link->ap;
	const int * const sstatus_merge_tbl[] = {
		/* DET */ (const int []){ 1, 3, 0, 4, 3, -1 },
		/* SPD */ (const int []){ 2, 1, 0, -1 },
@@ -1013,8 +1017,11 @@ static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val)
	return 0;
}

static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
static int piix_sidpr_scr_write(struct ata_link *link,
				unsigned int reg, u32 val)
{
	struct ata_port *ap = link->ap;

	if (reg >= ARRAY_SIZE(piix_sidx_map))
		return -EINVAL;

+4 −9
Original line number Diff line number Diff line
@@ -4868,10 +4868,8 @@ int sata_scr_valid(struct ata_link *link)
int sata_scr_read(struct ata_link *link, int reg, u32 *val)
{
	if (ata_is_host_link(link)) {
		struct ata_port *ap = link->ap;

		if (sata_scr_valid(link))
			return ap->ops->scr_read(ap, reg, val);
			return link->ap->ops->scr_read(link, reg, val);
		return -EOPNOTSUPP;
	}

@@ -4897,10 +4895,8 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val)
int sata_scr_write(struct ata_link *link, int reg, u32 val)
{
	if (ata_is_host_link(link)) {
		struct ata_port *ap = link->ap;

		if (sata_scr_valid(link))
			return ap->ops->scr_write(ap, reg, val);
			return link->ap->ops->scr_write(link, reg, val);
		return -EOPNOTSUPP;
	}

@@ -4925,13 +4921,12 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val)
int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
{
	if (ata_is_host_link(link)) {
		struct ata_port *ap = link->ap;
		int rc;

		if (sata_scr_valid(link)) {
			rc = ap->ops->scr_write(ap, reg, val);
			rc = link->ap->ops->scr_write(link, reg, val);
			if (rc == 0)
				rc = ap->ops->scr_read(ap, reg, &val);
				rc = link->ap->ops->scr_read(link, reg, &val);
			return rc;
		}
		return -EOPNOTSUPP;
+13 −13
Original line number Diff line number Diff line
@@ -469,10 +469,10 @@ static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc)
	return true;
}

static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
			       u32 val)
static int sata_fsl_scr_write(struct ata_link *link,
			      unsigned int sc_reg_in, u32 val)
{
	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
	struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
	void __iomem *ssr_base = host_priv->ssr_base;
	unsigned int sc_reg;

@@ -493,10 +493,10 @@ static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
	return 0;
}

static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
			u32 *val)
static int sata_fsl_scr_read(struct ata_link *link,
			     unsigned int sc_reg_in, u32 *val)
{
	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
	struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
	void __iomem *ssr_base = host_priv->ssr_base;
	unsigned int sc_reg;

@@ -645,12 +645,12 @@ static int sata_fsl_port_start(struct ata_port *ap)
	 * Workaround for 8315DS board 3gbps link-up issue,
	 * currently limit SATA port to GEN1 speed
	 */
	sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
	sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
	temp &= ~(0xF << 4);
	temp |= (0x1 << 4);
	sata_fsl_scr_write(ap, SCR_CONTROL, temp);
	sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);

	sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
	sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
	dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n",
			temp);
#endif
@@ -868,7 +868,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
			ioread32(CQ + hcr_base),
			ioread32(CA + hcr_base), ioread32(CC + hcr_base));

		sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
		sata_fsl_scr_read(&ap->link, SCR_ERROR, &Serror);

		DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
		DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
@@ -972,9 +972,9 @@ static void sata_fsl_error_intr(struct ata_port *ap)
	 * Handle & Clear SError
	 */

	sata_fsl_scr_read(ap, SCR_ERROR, &SError);
	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
	if (unlikely(SError & 0xFFFF0000)) {
		sata_fsl_scr_write(ap, SCR_ERROR, SError);
		sata_fsl_scr_write(&ap->link, SCR_ERROR, SError);
	}

	DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
@@ -1091,7 +1091,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)

	hstatus = ioread32(hcr_base + HSTATUS);

	sata_fsl_scr_read(ap, SCR_ERROR, &SError);
	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);

	if (unlikely(SError & 0xFFFF0000)) {
		DPRINTK("serror @host_intr : 0x%x\n", SError);
+4 −4
Original line number Diff line number Diff line
@@ -269,9 +269,9 @@ static void inic_reset_port(void __iomem *port_base)
	writeb(0xff, port_base + PORT_IRQ_STAT);
}

static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
static int inic_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
{
	void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
	void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
	void __iomem *addr;

	if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -286,9 +286,9 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
	return 0;
}

static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
static int inic_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
{
	void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
	void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;

	if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
		return -EINVAL;
Loading