[PATCH v5 2/3] input: syscon support in bcm_iproc_tsc driver

2016-03-23 Thread Raveendra Padasalagi
In Cygnus SOC touch screen controller registers are shared
with ADC and flex timer. Using readl/writel could lead to
race condition. So touch screen driver is enhanced to support
register access using syscon framework API's to take care of
mutually exclusive access.

Signed-off-by: Raveendra Padasalagi 
Reviewed-by: Ray Jui 
Reviewed-by: Scott Branden 
Reviewed-by: Arnd Bergmann 
---
 drivers/input/touchscreen/bcm_iproc_tsc.c | 79 +--
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/drivers/input/touchscreen/bcm_iproc_tsc.c 
b/drivers/input/touchscreen/bcm_iproc_tsc.c
index ae460a5c..0fd5f35 100644
--- a/drivers/input/touchscreen/bcm_iproc_tsc.c
+++ b/drivers/input/touchscreen/bcm_iproc_tsc.c
@@ -23,6 +23,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define IPROC_TS_NAME "iproc-ts"
 
@@ -88,7 +90,11 @@
 #define TS_WIRE_MODE_BITBIT(1)
 
 #define dbg_reg(dev, priv, reg) \
-   dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg))
+do { \
+   u32 val; \
+   regmap_read(priv->regmap, reg, ); \
+   dev_dbg(dev, "%20s= 0x%08x\n", #reg, val); \
+} while (0)
 
 struct tsc_param {
/* Each step is 1024 us.  Valid 1-256 */
@@ -141,7 +147,7 @@ struct iproc_ts_priv {
struct platform_device *pdev;
struct input_dev *idev;
 
-   void __iomem *regs;
+   struct regmap *regmap;
struct clk *tsc_clk;
 
int  pen_status;
@@ -196,22 +202,22 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
int i;
bool needs_sync = false;
 
-   intr_status = readl(priv->regs + INTERRUPT_STATUS);
-   intr_status &= TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
+   regmap_read(priv->regmap, INTERRUPT_STATUS, _status);
+   intr_status &= (TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK);
if (intr_status == 0)
return IRQ_NONE;
 
/* Clear all interrupt status bits, write-1-clear */
-   writel(intr_status, priv->regs + INTERRUPT_STATUS);
-
+   regmap_write(priv->regmap, INTERRUPT_STATUS, intr_status);
/* Pen up/down */
if (intr_status & TS_PEN_INTR_MASK) {
-   if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN)
+   regmap_read(priv->regmap, CONTROLLER_STATUS, >pen_status);
+   if (priv->pen_status & TS_PEN_DOWN)
priv->pen_status = PEN_DOWN_STATUS;
else
priv->pen_status = PEN_UP_STATUS;
 
-   input_report_key(priv->idev, BTN_TOUCH, priv->pen_status);
+   input_report_key(priv->idev, BTN_TOUCH, priv->pen_status);
needs_sync = true;
 
dev_dbg(>pdev->dev,
@@ -221,7 +227,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
/* coordinates in FIFO exceed the theshold */
if (intr_status & TS_FIFO_INTR_MASK) {
for (i = 0; i < priv->cfg_params.fifo_threshold; i++) {
-   raw_coordinate = readl(priv->regs + FIFO_DATA);
+   regmap_read(priv->regmap, FIFO_DATA, _coordinate);
if (raw_coordinate == INVALID_COORD)
continue;
 
@@ -239,7 +245,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
x = (x >> 4) & 0x0FFF;
y = (y >> 4) & 0x0FFF;
 
-   /* adjust x y according to lcd tsc mount angle */
+   /* Adjust x y according to LCD tsc mount angle. */
if (priv->cfg_params.invert_x)
x = priv->cfg_params.max_x - x;
 
@@ -262,9 +268,10 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
 
 static int iproc_ts_start(struct input_dev *idev)
 {
-   struct iproc_ts_priv *priv = input_get_drvdata(idev);
u32 val;
+   u32 mask;
int error;
+   struct iproc_ts_priv *priv = input_get_drvdata(idev);
 
/* Enable clock */
error = clk_prepare_enable(priv->tsc_clk);
@@ -279,9 +286,10 @@ static int iproc_ts_start(struct input_dev *idev)
 *  FIFO reaches the int_th value, and pen event(up/down)
 */
val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
-   writel(val, priv->regs + INTERRUPT_MASK);
+   regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, val);
 
-   writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES);
+   val = priv->cfg_params.fifo_threshold;
+   regmap_write(priv->regmap, INTERRUPT_THRES, val);
 
/* Initialize control reg1 */
val = 0;
@@ -289,26 +297,23 @@ static int iproc_ts_start(struct input_dev *idev)
val |= priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT;
val |= priv->cfg_params.settling_timeout << 

[PATCH v5 2/3] input: syscon support in bcm_iproc_tsc driver

2016-03-23 Thread Raveendra Padasalagi
In Cygnus SOC touch screen controller registers are shared
with ADC and flex timer. Using readl/writel could lead to
race condition. So touch screen driver is enhanced to support
register access using syscon framework API's to take care of
mutually exclusive access.

Signed-off-by: Raveendra Padasalagi 
Reviewed-by: Ray Jui 
Reviewed-by: Scott Branden 
Reviewed-by: Arnd Bergmann 
---
 drivers/input/touchscreen/bcm_iproc_tsc.c | 79 +--
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/drivers/input/touchscreen/bcm_iproc_tsc.c 
b/drivers/input/touchscreen/bcm_iproc_tsc.c
index ae460a5c..0fd5f35 100644
--- a/drivers/input/touchscreen/bcm_iproc_tsc.c
+++ b/drivers/input/touchscreen/bcm_iproc_tsc.c
@@ -23,6 +23,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define IPROC_TS_NAME "iproc-ts"
 
@@ -88,7 +90,11 @@
 #define TS_WIRE_MODE_BITBIT(1)
 
 #define dbg_reg(dev, priv, reg) \
-   dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg))
+do { \
+   u32 val; \
+   regmap_read(priv->regmap, reg, ); \
+   dev_dbg(dev, "%20s= 0x%08x\n", #reg, val); \
+} while (0)
 
 struct tsc_param {
/* Each step is 1024 us.  Valid 1-256 */
@@ -141,7 +147,7 @@ struct iproc_ts_priv {
struct platform_device *pdev;
struct input_dev *idev;
 
-   void __iomem *regs;
+   struct regmap *regmap;
struct clk *tsc_clk;
 
int  pen_status;
@@ -196,22 +202,22 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
int i;
bool needs_sync = false;
 
-   intr_status = readl(priv->regs + INTERRUPT_STATUS);
-   intr_status &= TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
+   regmap_read(priv->regmap, INTERRUPT_STATUS, _status);
+   intr_status &= (TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK);
if (intr_status == 0)
return IRQ_NONE;
 
/* Clear all interrupt status bits, write-1-clear */
-   writel(intr_status, priv->regs + INTERRUPT_STATUS);
-
+   regmap_write(priv->regmap, INTERRUPT_STATUS, intr_status);
/* Pen up/down */
if (intr_status & TS_PEN_INTR_MASK) {
-   if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN)
+   regmap_read(priv->regmap, CONTROLLER_STATUS, >pen_status);
+   if (priv->pen_status & TS_PEN_DOWN)
priv->pen_status = PEN_DOWN_STATUS;
else
priv->pen_status = PEN_UP_STATUS;
 
-   input_report_key(priv->idev, BTN_TOUCH, priv->pen_status);
+   input_report_key(priv->idev, BTN_TOUCH, priv->pen_status);
needs_sync = true;
 
dev_dbg(>pdev->dev,
@@ -221,7 +227,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
/* coordinates in FIFO exceed the theshold */
if (intr_status & TS_FIFO_INTR_MASK) {
for (i = 0; i < priv->cfg_params.fifo_threshold; i++) {
-   raw_coordinate = readl(priv->regs + FIFO_DATA);
+   regmap_read(priv->regmap, FIFO_DATA, _coordinate);
if (raw_coordinate == INVALID_COORD)
continue;
 
@@ -239,7 +245,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
x = (x >> 4) & 0x0FFF;
y = (y >> 4) & 0x0FFF;
 
-   /* adjust x y according to lcd tsc mount angle */
+   /* Adjust x y according to LCD tsc mount angle. */
if (priv->cfg_params.invert_x)
x = priv->cfg_params.max_x - x;
 
@@ -262,9 +268,10 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, 
void *data)
 
 static int iproc_ts_start(struct input_dev *idev)
 {
-   struct iproc_ts_priv *priv = input_get_drvdata(idev);
u32 val;
+   u32 mask;
int error;
+   struct iproc_ts_priv *priv = input_get_drvdata(idev);
 
/* Enable clock */
error = clk_prepare_enable(priv->tsc_clk);
@@ -279,9 +286,10 @@ static int iproc_ts_start(struct input_dev *idev)
 *  FIFO reaches the int_th value, and pen event(up/down)
 */
val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
-   writel(val, priv->regs + INTERRUPT_MASK);
+   regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, val);
 
-   writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES);
+   val = priv->cfg_params.fifo_threshold;
+   regmap_write(priv->regmap, INTERRUPT_THRES, val);
 
/* Initialize control reg1 */
val = 0;
@@ -289,26 +297,23 @@ static int iproc_ts_start(struct input_dev *idev)
val |= priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT;
val |= priv->cfg_params.settling_timeout << SETTLING_TIMEOUT_SHIFT;
val |= priv->cfg_params.touch_timeout << TOUCH_TIMEOUT_SHIFT;
-   writel(val,