All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <htejun@gmail.com>
To: jgarzik@pobox.com, linux-ide@vger.kernel.org
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 3/5] libata: implement ata_wait_register()
Date: Fri, 7 Apr 2006 17:02:47 +0900	[thread overview]
Message-ID: <11443969673301-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <11443969673485-git-send-email-htejun@gmail.com>

As waiting for some register bits to change seems to be a common
operation shared by some controllers, implement helper function
ata_wait_register().  This function also takes care of register write
flushing.

Note that the condition is inverted, the wait is over when the masked
value does NOT match @val.  As we're waiting for bits to change, this
test is more powerful and allows the function to be used in more
places.

Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-core.c |   47 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/libata.h     |    3 +++
 2 files changed, 50 insertions(+), 0 deletions(-)

9a5b48cf585e6fdfdabc64efd8c4de58db2facec
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index ed089a0..56e1cc6 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5029,6 +5029,52 @@ int ata_ratelimit(void)
 	return rc;
 }
 
+/**
+ *	ata_wait_register - wait until register value changes
+ *	@reg: IO-mapped register
+ *	@mask: Mask to apply to read register value
+ *	@val: Wait condition
+ *	@interval_msec: polling interval in milliseconds
+ *	@timeout_msec: timeout in milliseconds
+ *
+ *	Waiting for some bits of register to change is a common
+ *	operation for ATA controllers.  This function reads 32bit LE
+ *	IO-mapped register @reg and tests for the following condition.
+ *
+ *	(*@reg & mask) != val
+ *
+ *	If the condition is met, it returns; otherwise, the process is
+ *	repeated after @interval_msec until timeout.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	The final register value.
+ */
+u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
+		      unsigned long interval_msec,
+		      unsigned long timeout_msec)
+{
+	unsigned long timeout;
+	u32 tmp;
+
+	tmp = ioread32(reg);
+
+	/* Calculate timeout _after_ the first read to make sure
+	 * preceding writes reach the controller before starting to
+	 * eat away the timeout.
+	 */
+	timeout = jiffies + (timeout_msec * HZ) / 1000;
+
+	while ((tmp & mask) == val && time_before(jiffies, timeout)) {
+		msleep(interval_msec);
+		tmp = ioread32(reg);
+	}
+
+	return tmp;
+}
+
 /*
  * libata is essentially a library of internal helper functions for
  * low-level ATA host controller drivers.  As such, the API/ABI is
@@ -5079,6 +5125,7 @@ EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);
 EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_ratelimit);
+EXPORT_SYMBOL_GPL(ata_wait_register);
 EXPORT_SYMBOL_GPL(ata_busy_sleep);
 EXPORT_SYMBOL_GPL(ata_port_queue_task);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6954852..bf2f334 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -540,6 +540,9 @@ extern unsigned int ata_busy_sleep(struc
 				   unsigned long timeout);
 extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
 				void *data, unsigned long delay);
+extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
+			     unsigned long interval_msec,
+			     unsigned long timeout_msec);
 
 /*
  * Default driver ops implementations
-- 
1.2.4



  parent reply	other threads:[~2006-04-07  8:02 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-07  8:02 [PATCHSET] libata: implement and use ata_wait_register() Tejun Heo
2006-04-07  8:02 ` [PATCH 2/5] sata_sil24: better error message from softreset Tejun Heo
2006-04-07  8:02 ` [PATCH 5/5] sata_sil24: use ata_wait_register() Tejun Heo
2006-04-07  8:02 ` Tejun Heo [this message]
2006-04-07  8:02 ` [PATCH 1/5] sata_sil24: fix timeout calculation in sil24_softreset Tejun Heo
2006-04-07  8:02 ` [PATCH 4/5] ahci: use ata_wait_register() Tejun Heo
  -- strict thread matches above, loose matches on Subject: below --
2006-04-11 13:22 [PATCHSET 2/9] implement and use ata_wait_register (repost) Tejun Heo
2006-04-11 13:22 ` [PATCH 3/5] libata: implement ata_wait_register() Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11443969673301-git-send-email-htejun@gmail.com \
    --to=htejun@gmail.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.