msm: acpuclock-krait: Add support for HFPLL lock detect bit polling

Some recent devices have a lock detect bit that can be used to
determine when the HFPLL frequency has stabilized. Add optional
support for polling this bit instead of delaying pessimistically
for 60us.

Change-Id: I38bb0c98e36f66fc5efadf9189dbe817f648a972
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index a6f4423..e3a3f54 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -22,6 +22,7 @@
 #include <linux/cpufreq.h>
 #include <linux/cpu.h>
 #include <linux/regulator/consumer.h>
+#include <linux/iopoll.h>
 
 #include <asm/mach-types.h>
 #include <asm/cpu.h>
@@ -131,8 +132,14 @@
 	writel_relaxed(0x6, sc->hfpll_base + drv.hfpll_data->mode_offset);
 
 	/* Wait for PLL to lock. */
-	mb();
-	udelay(60);
+	if (drv.hfpll_data->has_lock_status) {
+		u32 regval;
+		readl_tight_poll(sc->hfpll_base + drv.hfpll_data->status_offset,
+			   regval, regval & BIT(16));
+	} else {
+		mb();
+		udelay(60);
+	}
 
 	/* Enable PLL output. */
 	writel_relaxed(0x7, sc->hfpll_base + drv.hfpll_data->mode_offset);
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index 11d58dd..f02af98 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -171,8 +171,10 @@
  * @user_val: Value to initialize the @user_offset register to.
  * @user_vco_mask: Bit in the @user_offset to enable high-frequency VCO mode.
  * @has_droop_ctl: Indicates the presence of a voltage droop controller.
+ * @has_lock_status: Indicates the presence of a lock status bit.
  * @droop_offset: Droop controller register offset from base address.
  * @droop_val: Value to initialize the @config_offset register to.
+ * @status_offset: PLL status register offset.
  * @low_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_LOW.
  * @nom_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_NOM.
  * @low_vco_l_max: Maximum "L" value supported in low-frequency VCO mode.
@@ -190,8 +192,10 @@
 	const u32 user_val;
 	const u32 user_vco_mask;
 	const bool has_droop_ctl;
+	const bool has_lock_status;
 	const u32 droop_offset;
 	const u32 droop_val;
+	const u32 status_offset;
 	u32 low_vdd_l_max;
 	u32 nom_vdd_l_max;
 	const u32 low_vco_l_max;