Skip to content

Commit

Permalink
ata: sata_dwc_460ex: get rid of global data
Browse files Browse the repository at this point in the history
This moves all global data into the driver private struct, thus
permitting multiple devices of this type to be used.

The core_scr_read/write() functions are replaced with equivalent
calls to the existing sata_dwc_scr_read/write().

Tested-by: Christian Lamparter <[email protected]>
Signed-off-by: Mans Rullgard <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
mansr authored and htejun committed May 10, 2016
1 parent 0f48deb commit 2d20da0
Showing 1 changed file with 29 additions and 50 deletions.
79 changes: 29 additions & 50 deletions drivers/ata/sata_dwc_460ex.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ struct sata_dwc_device {
struct ata_host *host;
u8 __iomem *reg_base;
struct sata_dwc_regs *sata_dwc_regs; /* DW Synopsys SATA specific */
u32 sactive_issued;
u32 sactive_queued;
struct phy *phy;
#ifdef CONFIG_SATA_DWC_OLD_DMA
struct dw_dma_chip *dma;
Expand Down Expand Up @@ -190,14 +192,6 @@ enum {
SATA_DWC_DMA_PENDING_RX = 2,
};

struct sata_dwc_host_priv {
void __iomem *scr_addr_sstatus;
u32 sata_dwc_sactive_issued ;
u32 sata_dwc_sactive_queued ;
};

static struct sata_dwc_host_priv host_pvt;

/*
* Prototypes
*/
Expand Down Expand Up @@ -457,21 +451,11 @@ static int sata_dwc_scr_write(struct ata_link *link, unsigned int scr, u32 val)
return 0;
}

static u32 core_scr_read(unsigned int scr)
{
return in_le32(host_pvt.scr_addr_sstatus + (scr * 4));
}

static void core_scr_write(unsigned int scr, u32 val)
{
out_le32(host_pvt.scr_addr_sstatus + (scr * 4), val);
}

static void clear_serror(void)
static void clear_serror(struct ata_port *ap)
{
u32 val;
val = core_scr_read(SCR_ERROR);
core_scr_write(SCR_ERROR, val);
sata_dwc_scr_read(&ap->link, SCR_ERROR, &val);
sata_dwc_scr_write(&ap->link, SCR_ERROR, val);
}

static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
Expand All @@ -498,7 +482,7 @@ static void sata_dwc_error_intr(struct ata_port *ap,

ata_ehi_clear_desc(ehi);

serror = core_scr_read(SCR_ERROR);
sata_dwc_scr_read(&ap->link, SCR_ERROR, &serror);
status = ap->ops->sff_check_status(ap);

tag = ap->link.active_tag;
Expand All @@ -509,7 +493,7 @@ static void sata_dwc_error_intr(struct ata_port *ap,
hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag]);

/* Clear error register and interrupt bit */
clear_serror();
clear_serror(ap);
clear_interrupt_bit(hsdev, SATA_DWC_INTPR_ERR);

/* This is the only error happening now. TODO check for exact error */
Expand Down Expand Up @@ -548,7 +532,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
int handled, num_processed, port = 0;
uint intpr, sactive, sactive2, tag_mask;
struct sata_dwc_device_port *hsdevp;
host_pvt.sata_dwc_sactive_issued = 0;
hsdev->sactive_issued = 0;

spin_lock_irqsave(&host->lock, flags);

Expand Down Expand Up @@ -577,7 +561,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
if (hsdevp->cmd_issued[tag] != SATA_DWC_CMD_ISSUED_PEND)
dev_warn(ap->dev, "CMD tag=%d not pending?\n", tag);

host_pvt.sata_dwc_sactive_issued |= qcmd_tag_to_mask(tag);
hsdev->sactive_issued |= qcmd_tag_to_mask(tag);

qc = ata_qc_from_tag(ap, tag);
/*
Expand All @@ -591,11 +575,11 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
handled = 1;
goto DONE;
}
sactive = core_scr_read(SCR_ACTIVE);
tag_mask = (host_pvt.sata_dwc_sactive_issued | sactive) ^ sactive;
sata_dwc_scr_read(&ap->link, SCR_ACTIVE, &sactive);
tag_mask = (hsdev->sactive_issued | sactive) ^ sactive;

/* If no sactive issued and tag_mask is zero then this is not NCQ */
if (host_pvt.sata_dwc_sactive_issued == 0 && tag_mask == 0) {
if (hsdev->sactive_issued == 0 && tag_mask == 0) {
if (ap->link.active_tag == ATA_TAG_POISON)
tag = 0;
else
Expand Down Expand Up @@ -665,22 +649,19 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
*/

/* process completed commands */
sactive = core_scr_read(SCR_ACTIVE);
tag_mask = (host_pvt.sata_dwc_sactive_issued | sactive) ^ sactive;
sata_dwc_scr_read(&ap->link, SCR_ACTIVE, &sactive);
tag_mask = (hsdev->sactive_issued | sactive) ^ sactive;

if (sactive != 0 || (host_pvt.sata_dwc_sactive_issued) > 1 || \
tag_mask > 1) {
if (sactive != 0 || hsdev->sactive_issued > 1 || tag_mask > 1) {
dev_dbg(ap->dev,
"%s NCQ:sactive=0x%08x sactive_issued=0x%08x tag_mask=0x%08x\n",
__func__, sactive, host_pvt.sata_dwc_sactive_issued,
tag_mask);
__func__, sactive, hsdev->sactive_issued, tag_mask);
}

if ((tag_mask | (host_pvt.sata_dwc_sactive_issued)) != \
(host_pvt.sata_dwc_sactive_issued)) {
if ((tag_mask | hsdev->sactive_issued) != hsdev->sactive_issued) {
dev_warn(ap->dev,
"Bad tag mask? sactive=0x%08x (host_pvt.sata_dwc_sactive_issued)=0x%08x tag_mask=0x%08x\n",
sactive, host_pvt.sata_dwc_sactive_issued, tag_mask);
"Bad tag mask? sactive=0x%08x sactive_issued=0x%08x tag_mask=0x%08x\n",
sactive, hsdev->sactive_issued, tag_mask);
}

/* read just to clear ... not bad if currently still busy */
Expand Down Expand Up @@ -742,7 +723,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
* we were processing --we read status as part of processing a completed
* command).
*/
sactive2 = core_scr_read(SCR_ACTIVE);
sata_dwc_scr_read(&ap->link, SCR_ACTIVE, &sactive2);
if (sactive2 != sactive) {
dev_dbg(ap->dev,
"More completed - sactive=0x%x sactive2=0x%x\n",
Expand Down Expand Up @@ -828,8 +809,9 @@ static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc,
u8 status = 0;
u32 mask = 0x0;
u8 tag = qc->tag;
struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
host_pvt.sata_dwc_sactive_queued = 0;
hsdev->sactive_queued = 0;
dev_dbg(ap->dev, "%s checkstatus? %x\n", __func__, check_status);

if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_TX)
Expand All @@ -842,10 +824,8 @@ static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc,

/* clear active bit */
mask = (~(qcmd_tag_to_mask(tag)));
host_pvt.sata_dwc_sactive_queued = (host_pvt.sata_dwc_sactive_queued) \
& mask;
host_pvt.sata_dwc_sactive_issued = (host_pvt.sata_dwc_sactive_issued) \
& mask;
hsdev->sactive_queued = hsdev->sactive_queued & mask;
hsdev->sactive_issued = hsdev->sactive_issued & mask;
ata_qc_complete(qc);
return 0;
}
Expand Down Expand Up @@ -974,7 +954,7 @@ static int sata_dwc_port_start(struct ata_port *ap)
}

/* Clear any error bits before libata starts issuing commands */
clear_serror();
clear_serror(ap);
ap->private_data = hsdevp;
dev_dbg(ap->dev, "%s: done\n", __func__);
return 0;
Expand Down Expand Up @@ -1025,7 +1005,7 @@ static void sata_dwc_exec_command_by_tag(struct ata_port *ap,
* managed SError register for the disk needs to be done before the
* task file is loaded.
*/
clear_serror();
clear_serror(ap);
ata_sff_exec_command(ap, tf);
}

Expand Down Expand Up @@ -1078,7 +1058,7 @@ static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag)
sata_dwc_tf_dump(ap, &qc->tf);

if (start_dma) {
reg = core_scr_read(SCR_ERROR);
sata_dwc_scr_read(&ap->link, SCR_ERROR, &reg);
if (reg & SATA_DWC_SERROR_ERR_BITS) {
dev_err(ap->dev, "%s: ****** SError=0x%08x ******\n",
__func__, reg);
Expand Down Expand Up @@ -1140,9 +1120,9 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
}

if (ata_is_ncq(qc->tf.protocol)) {
sactive = core_scr_read(SCR_ACTIVE);
sata_dwc_scr_read(&ap->link, SCR_ACTIVE, &sactive);
sactive |= (0x00000001 << tag);
core_scr_write(SCR_ACTIVE, sactive);
sata_dwc_scr_write(&ap->link, SCR_ACTIVE, sactive);

dev_dbg(qc->ap->dev,
"%s: tag=%d ap->link.sactive = 0x%08x sactive=0x%08x\n",
Expand Down Expand Up @@ -1298,7 +1278,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
/* Setup port */
host->ports[0]->ioaddr.cmd_addr = base;
host->ports[0]->ioaddr.scr_addr = base + SATA_DWC_SCR_OFFSET;
host_pvt.scr_addr_sstatus = base + SATA_DWC_SCR_OFFSET;
sata_dwc_setup_port(&host->ports[0]->ioaddr, (unsigned long)base);

/* Read the ID and Version Registers */
Expand Down

0 comments on commit 2d20da0

Please sign in to comment.