All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove
@ 2012-07-02  6:50 Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume Shiraz Hashim
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-02  6:50 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, Vipul Kumar Samar

From: Vipul Kumar Samar <vipulkumar.samar@st.com>

This patch is to disable device wakeup while removing keyboard.

Signed-off-by: Vipul Kumar Samar <vipulkumar.samar@st.com>
---
 drivers/input/keyboard/spear-keyboard.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 605d3d2..67d9afb 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -303,7 +303,7 @@ static int __devexit spear_kbd_remove(struct platform_device *pdev)
 	release_mem_region(kbd->res->start, resource_size(kbd->res));
 	kfree(kbd);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, 0);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume
  2012-07-02  6:50 [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove Shiraz Hashim
@ 2012-07-02  6:50 ` Shiraz Hashim
  2012-07-08  1:11   ` Dmitry Torokhov
  2012-07-09  6:35   ` [PATCH V2 " Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 3/6] input/spear_keyboard: use correct io accessors Shiraz Hashim
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-02  6:50 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, Shiraz Hashim

SPEAr keyboard should normally disable clock during suspend and enable it
during resume.

For cases where it is expected to act as a wakeup source the clock can
remain in the same state i.e. kept enabled if it is being used.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 drivers/input/keyboard/spear-keyboard.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 67d9afb..ef147f3 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -318,12 +318,12 @@ static int spear_kbd_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
-		clk_enable(kbd->clk);
-
 	if (device_may_wakeup(&pdev->dev)) {
 		if (!enable_irq_wake(kbd->irq))
 			kbd->irq_wake = 1;
+	} else {
+		if (input_dev->users)
+			clk_disable(kbd->clk);
 	}
 
 	mutex_unlock(&input_dev->mutex);
@@ -344,11 +344,11 @@ static int spear_kbd_resume(struct device *dev)
 			kbd->irq_wake = 0;
 			disable_irq_wake(kbd->irq);
 		}
+	} else {
+		if (input_dev->users)
+			clk_enable(kbd->clk);
 	}
 
-	if (input_dev->users)
-		clk_enable(kbd->clk);
-
 	mutex_unlock(&input_dev->mutex);
 
 	return 0;
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/6] input/spear_keyboard: use correct io accessors
  2012-07-02  6:50 [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume Shiraz Hashim
@ 2012-07-02  6:50 ` Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 4/6] input/spear_keyboard: rename bit definitions to reflect register Shiraz Hashim
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-02  6:50 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, Shiraz Hashim

All SPEAr keyboard registers are 32 bit wide and are word aligned. This
patch aligns all io access to be word size using relaxed version of
readl/writel.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 drivers/input/keyboard/spear-keyboard.c |   30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index ef147f3..36c145a 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -27,9 +27,9 @@
 #include <plat/keyboard.h>
 
 /* Keyboard Registers */
-#define MODE_REG	0x00	/* 16 bit reg */
-#define STATUS_REG	0x0C	/* 2 bit reg */
-#define DATA_REG	0x10	/* 8 bit reg */
+#define MODE_REG	0x00
+#define STATUS_REG	0x0C
+#define DATA_REG	0x10
 #define INTR_MASK	0x54
 
 /* Register Values */
@@ -73,9 +73,9 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
 	struct spear_kbd *kbd = dev_id;
 	struct input_dev *input = kbd->input;
 	unsigned int key;
-	u8 sts, val;
+	u32 sts, val;
 
-	sts = readb(kbd->io_base + STATUS_REG);
+	sts = readl_relaxed(kbd->io_base + STATUS_REG);
 	if (!(sts & DATA_AVAIL))
 		return IRQ_NONE;
 
@@ -85,7 +85,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
 	}
 
 	/* following reads active (row, col) pair */
-	val = readb(kbd->io_base + DATA_REG);
+	val = readl_relaxed(kbd->io_base + DATA_REG);
 	key = kbd->keycodes[val];
 
 	input_event(input, EV_MSC, MSC_SCAN, val);
@@ -95,7 +95,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
 	kbd->last_key = key;
 
 	/* clear interrupt */
-	writeb(0, kbd->io_base + STATUS_REG);
+	writel_relaxed(0, kbd->io_base + STATUS_REG);
 
 	return IRQ_HANDLED;
 }
@@ -104,7 +104,7 @@ static int spear_kbd_open(struct input_dev *dev)
 {
 	struct spear_kbd *kbd = input_get_drvdata(dev);
 	int error;
-	u16 val;
+	u32 val;
 
 	kbd->last_key = KEY_RESERVED;
 
@@ -115,13 +115,13 @@ static int spear_kbd_open(struct input_dev *dev)
 	/* program keyboard */
 	val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK |
 		(kbd->mode << KEY_MATRIX_SHIFT);
-	writew(val, kbd->io_base + MODE_REG);
-	writeb(1, kbd->io_base + STATUS_REG);
+	writel_relaxed(val, kbd->io_base + MODE_REG);
+	writel_relaxed(1, kbd->io_base + STATUS_REG);
 
 	/* start key scan */
-	val = readw(kbd->io_base + MODE_REG);
+	val = readl_relaxed(kbd->io_base + MODE_REG);
 	val |= START_SCAN;
-	writew(val, kbd->io_base + MODE_REG);
+	writel_relaxed(val, kbd->io_base + MODE_REG);
 
 	return 0;
 }
@@ -129,12 +129,12 @@ static int spear_kbd_open(struct input_dev *dev)
 static void spear_kbd_close(struct input_dev *dev)
 {
 	struct spear_kbd *kbd = input_get_drvdata(dev);
-	u16 val;
+	u32 val;
 
 	/* stop key scan */
-	val = readw(kbd->io_base + MODE_REG);
+	val = readl_relaxed(kbd->io_base + MODE_REG);
 	val &= ~START_SCAN;
-	writew(val, kbd->io_base + MODE_REG);
+	writel_relaxed(val, kbd->io_base + MODE_REG);
 
 	clk_disable(kbd->clk);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/6] input/spear_keyboard: rename bit definitions to reflect register
  2012-07-02  6:50 [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 3/6] input/spear_keyboard: use correct io accessors Shiraz Hashim
@ 2012-07-02  6:50 ` Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 5/6] input/spear_keyboard: generalize keyboard frequency configuration Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 6/6] input/spear_keyboard: reconfigure operating frequency on suspend Shiraz Hashim
  4 siblings, 0 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-02  6:50 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, Shiraz Hashim

Rename bit definition macros to reflect keyboard registers clearly thus
being more readable.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 drivers/input/keyboard/spear-keyboard.c |   52 ++++++++++++++++---------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 36c145a..70f43c2 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -27,7 +27,7 @@
 #include <plat/keyboard.h>
 
 /* Keyboard Registers */
-#define MODE_REG	0x00
+#define MODE_CTL_REG	0x00
 #define STATUS_REG	0x0C
 #define DATA_REG	0x10
 #define INTR_MASK	0x54
@@ -38,22 +38,23 @@
  * control register as 1010010(82MHZ)
  */
 #define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
-#define START_SCAN	0x0100
-#define SCAN_RATE_10	0x0000
-#define SCAN_RATE_20	0x0004
-#define SCAN_RATE_40	0x0008
-#define SCAN_RATE_80	0x000C
-#define MODE_KEYBOARD	0x0002
-#define DATA_AVAIL	0x2
-
-#define KEY_MASK	0xFF000000
-#define KEY_VALUE	0x00FFFFFF
-#define ROW_MASK	0xF0
-#define COLUMN_MASK	0x0F
 #define NUM_ROWS	16
 #define NUM_COLS	16
 
-#define KEY_MATRIX_SHIFT	6
+#define MODE_CTL_KEYBOARD	(0x2 << 0)
+#define MODE_CTL_SCAN_RATE_10	(0x0 << 2)
+#define MODE_CTL_SCAN_RATE_20	(0x1 << 2)
+#define MODE_CTL_SCAN_RATE_40	(0x2 << 2)
+#define MODE_CTL_SCAN_RATE_80	(0x3 << 2)
+#define MODE_CTL_KEYNUM_SHIFT	6
+#define MODE_CTL_START_SCAN	(0x1 << 8)
+
+#define STATUS_DATA_AVAIL	(0x1 << 1)
+
+#define DATA_ROW_MASK		0xF0
+#define DATA_COLUMN_MASK	0x0F
+
+#define ROW_SHIFT		4
 
 struct spear_kbd {
 	struct input_dev *input;
@@ -76,7 +77,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
 	u32 sts, val;
 
 	sts = readl_relaxed(kbd->io_base + STATUS_REG);
-	if (!(sts & DATA_AVAIL))
+	if (!(sts & STATUS_DATA_AVAIL))
 		return IRQ_NONE;
 
 	if (kbd->last_key != KEY_RESERVED) {
@@ -85,7 +86,8 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
 	}
 
 	/* following reads active (row, col) pair */
-	val = readl_relaxed(kbd->io_base + DATA_REG);
+	val = readl_relaxed(kbd->io_base + DATA_REG) &
+		(DATA_ROW_MASK | DATA_COLUMN_MASK);
 	key = kbd->keycodes[val];
 
 	input_event(input, EV_MSC, MSC_SCAN, val);
@@ -113,15 +115,15 @@ static int spear_kbd_open(struct input_dev *dev)
 		return error;
 
 	/* program keyboard */
-	val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK |
-		(kbd->mode << KEY_MATRIX_SHIFT);
-	writel_relaxed(val, kbd->io_base + MODE_REG);
+	val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | PCLK_FREQ_MSK |
+		(kbd->mode << MODE_CTL_KEYNUM_SHIFT);
+	writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
 	writel_relaxed(1, kbd->io_base + STATUS_REG);
 
 	/* start key scan */
-	val = readl_relaxed(kbd->io_base + MODE_REG);
-	val |= START_SCAN;
-	writel_relaxed(val, kbd->io_base + MODE_REG);
+	val = readl_relaxed(kbd->io_base + MODE_CTL_REG);
+	val |= MODE_CTL_START_SCAN;
+	writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
 
 	return 0;
 }
@@ -132,9 +134,9 @@ static void spear_kbd_close(struct input_dev *dev)
 	u32 val;
 
 	/* stop key scan */
-	val = readl_relaxed(kbd->io_base + MODE_REG);
-	val &= ~START_SCAN;
-	writel_relaxed(val, kbd->io_base + MODE_REG);
+	val = readl_relaxed(kbd->io_base + MODE_CTL_REG);
+	val &= ~MODE_CTL_START_SCAN;
+	writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
 
 	clk_disable(kbd->clk);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/6] input/spear_keyboard: generalize keyboard frequency configuration
  2012-07-02  6:50 [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove Shiraz Hashim
                   ` (2 preceding siblings ...)
  2012-07-02  6:50 ` [PATCH 4/6] input/spear_keyboard: rename bit definitions to reflect register Shiraz Hashim
@ 2012-07-02  6:50 ` Shiraz Hashim
  2012-07-02  6:50 ` [PATCH 6/6] input/spear_keyboard: reconfigure operating frequency on suspend Shiraz Hashim
  4 siblings, 0 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-02  6:50 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, Shiraz Hashim

Current implementation hard coded keyboard frequency configuration
assuming input clock as fixed APB (83 MHz). Generalize the configuration
using clock framework APIs.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 drivers/input/keyboard/spear-keyboard.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 70f43c2..ae1132e 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -33,13 +33,10 @@
 #define INTR_MASK	0x54
 
 /* Register Values */
-/*
- * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
- * control register as 1010010(82MHZ)
- */
-#define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
 #define NUM_ROWS	16
 #define NUM_COLS	16
+#define MODE_CTL_PCLK_FREQ_SHIFT	9
+#define MODE_CTL_PCLK_FREQ_MSK		0x7F
 
 #define MODE_CTL_KEYBOARD	(0x2 << 0)
 #define MODE_CTL_SCAN_RATE_10	(0x0 << 2)
@@ -114,8 +111,12 @@ static int spear_kbd_open(struct input_dev *dev)
 	if (error)
 		return error;
 
+	/* keyboard rate to be programmed is input clock (in MHz) - 1 */
+	val = clk_get_rate(kbd->clk) / 1000000 - 1;
+	val = (val & MODE_CTL_PCLK_FREQ_MSK) << MODE_CTL_PCLK_FREQ_SHIFT;
+
 	/* program keyboard */
-	val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | PCLK_FREQ_MSK |
+	val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | val |
 		(kbd->mode << MODE_CTL_KEYNUM_SHIFT);
 	writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
 	writel_relaxed(1, kbd->io_base + STATUS_REG);
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/6] input/spear_keyboard: reconfigure operating frequency on suspend
  2012-07-02  6:50 [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove Shiraz Hashim
                   ` (3 preceding siblings ...)
  2012-07-02  6:50 ` [PATCH 5/6] input/spear_keyboard: generalize keyboard frequency configuration Shiraz Hashim
@ 2012-07-02  6:50 ` Shiraz Hashim
  2012-07-09  6:36   ` [PATCH V2 " Shiraz Hashim
  4 siblings, 1 reply; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-02  6:50 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, Shiraz Hashim

On some platform it may happen that the input clock to keyboard may
change thus impacting its wakeup capability.

There is no means for keyboard driver to know this frequency before
hand. Hence introduce a platform data 'suspended_rate' which indicates
the frequency during suspend at which keyboard operates.

Accordingly reprogram keyboard while going into suspend and restore
original configuration at the time of resume.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 arch/arm/plat-spear/include/plat/keyboard.h |    2 ++
 drivers/input/keyboard/spear-keyboard.c     |   44 +++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
index 0562f13..9248e3a 100644
--- a/arch/arm/plat-spear/include/plat/keyboard.h
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -149,6 +149,7 @@ int _name[] = { \
  * keymap: pointer to keymap data (table and size)
  * rep: enables key autorepeat
  * mode: choose keyboard support(9x9, 6x6, 2x2)
+ * suspended_rate: rate at which keyboard would operate in suspended mode
  *
  * This structure is supposed to be used by platform code to supply
  * keymaps to drivers that implement keyboards.
@@ -157,6 +158,7 @@ struct kbd_platform_data {
 	const struct matrix_keymap_data *keymap;
 	bool rep;
 	unsigned int mode;
+	unsigned int suspended_rate;
 };
 
 #endif /* __PLAT_KEYBOARD_H */
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index ae1132e..9333a35 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -64,6 +64,8 @@ struct spear_kbd {
 	unsigned short last_key;
 	unsigned short keycodes[NUM_ROWS * NUM_COLS];
 	bool rep;
+	unsigned int suspended_rate;
+	u32 mode_ctl_reg;
 };
 
 static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
@@ -150,7 +152,7 @@ static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
 {
 	struct device_node *np = pdev->dev.of_node;
 	int error;
-	u32 val;
+	u32 val, suspended_rate;
 
 	if (!np) {
 		dev_err(&pdev->dev, "Missing DT data\n");
@@ -160,6 +162,9 @@ static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
 	if (of_property_read_bool(np, "autorepeat"))
 		kbd->rep = true;
 
+	if (of_property_read_u32(np, "suspended_rate", &suspended_rate))
+		kbd->suspended_rate = suspended_rate;
+
 	error = of_property_read_u32(np, "st,mode", &val);
 	if (error) {
 		dev_err(&pdev->dev, "DT: Invalid or missing mode\n");
@@ -217,6 +222,7 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev)
 	} else {
 		kbd->mode = pdata->mode;
 		kbd->rep = pdata->rep;
+		kbd->suspended_rate = pdata->suspended_rate;
 	}
 
 	kbd->res = request_mem_region(res->start, resource_size(res),
@@ -318,17 +324,47 @@ static int spear_kbd_suspend(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct spear_kbd *kbd = platform_get_drvdata(pdev);
 	struct input_dev *input_dev = kbd->input;
+	unsigned int rate = 0, mode_ctl_reg, val;
 
 	mutex_lock(&input_dev->mutex);
 
+	/* explicitly enable clock as we may program device */
+	clk_enable(kbd->clk);
+
+	mode_ctl_reg = readl_relaxed(kbd->io_base + MODE_CTL_REG);
+
 	if (device_may_wakeup(&pdev->dev)) {
 		if (!enable_irq_wake(kbd->irq))
 			kbd->irq_wake = 1;
+
+		/*
+		 * reprogram the keyboard operating frequency as on some
+		 * platform it may change during system suspended
+		 */
+		if (kbd->suspended_rate)
+			rate = kbd->suspended_rate / 1000000 - 1;
+
+		val = mode_ctl_reg &
+			~(MODE_CTL_PCLK_FREQ_MSK << MODE_CTL_PCLK_FREQ_SHIFT);
+		val |= (rate & MODE_CTL_PCLK_FREQ_MSK)
+			<< MODE_CTL_PCLK_FREQ_SHIFT;
+		writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
+
 	} else {
-		if (input_dev->users)
+		if (input_dev->users) {
+			writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN,
+					kbd->io_base + MODE_CTL_REG);
 			clk_disable(kbd->clk);
+		}
 	}
 
+	/* store current configuration */
+	if (input_dev->users)
+		kbd->mode_ctl_reg = mode_ctl_reg;
+
+	/* restore previous clk state */
+	clk_disable(kbd->clk);
+
 	mutex_unlock(&input_dev->mutex);
 
 	return 0;
@@ -352,6 +388,10 @@ static int spear_kbd_resume(struct device *dev)
 			clk_enable(kbd->clk);
 	}
 
+	/* restore current configuration */
+	if (input_dev->users)
+		writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG);
+
 	mutex_unlock(&input_dev->mutex);
 
 	return 0;
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume
  2012-07-02  6:50 ` [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume Shiraz Hashim
@ 2012-07-08  1:11   ` Dmitry Torokhov
  2012-07-09  4:03     ` Shiraz Hashim
  2012-07-09  6:35   ` [PATCH V2 " Shiraz Hashim
  1 sibling, 1 reply; 10+ messages in thread
From: Dmitry Torokhov @ 2012-07-08  1:11 UTC (permalink / raw)
  To: Shiraz Hashim; +Cc: spear-devel, linux-input

Hi Shiraz,

On Mon, Jul 02, 2012 at 12:20:10PM +0530, Shiraz Hashim wrote:
> SPEAr keyboard should normally disable clock during suspend and enable it
> during resume.
> 
> For cases where it is expected to act as a wakeup source the clock can
> remain in the same state i.e. kept enabled if it is being used.
> 
> Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
> ---
>  drivers/input/keyboard/spear-keyboard.c |   12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
> index 67d9afb..ef147f3 100644
> --- a/drivers/input/keyboard/spear-keyboard.c
> +++ b/drivers/input/keyboard/spear-keyboard.c
> @@ -318,12 +318,12 @@ static int spear_kbd_suspend(struct device *dev)
>  
>  	mutex_lock(&input_dev->mutex);
>  
> -	if (input_dev->users)
> -		clk_enable(kbd->clk);
> -
>  	if (device_may_wakeup(&pdev->dev)) {
>  		if (!enable_irq_wake(kbd->irq))
>  			kbd->irq_wake = 1;
> +	} else {
> +		if (input_dev->users)
> +			clk_disable(kbd->clk);
>  	}

This patch does not apply to mainline version of the driver because the
change introducing handling for enable_irq_wake() failures was rejected
from mainline. I also have not appplied the 6th patch in the series
because it depends on this one.

Also, don't you need to enable clock if device is marked as wakeup
source but happens to have no active users?

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume
  2012-07-08  1:11   ` Dmitry Torokhov
@ 2012-07-09  4:03     ` Shiraz Hashim
  0 siblings, 0 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-09  4:03 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: spear-devel, linux-input

Hi Dmitry,

On Sat, Jul 07, 2012 at 06:11:55PM -0700, Dmitry Torokhov wrote:
> Hi Shiraz,
> 
> On Mon, Jul 02, 2012 at 12:20:10PM +0530, Shiraz Hashim wrote:
> > SPEAr keyboard should normally disable clock during suspend and enable it
> > during resume.
> > 
> > For cases where it is expected to act as a wakeup source the clock can
> > remain in the same state i.e. kept enabled if it is being used.
> > 
> > Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
> > ---
> >  drivers/input/keyboard/spear-keyboard.c |   12 ++++++------
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
> > index 67d9afb..ef147f3 100644
> > --- a/drivers/input/keyboard/spear-keyboard.c
> > +++ b/drivers/input/keyboard/spear-keyboard.c
> > @@ -318,12 +318,12 @@ static int spear_kbd_suspend(struct device *dev)
> >  
> >  	mutex_lock(&input_dev->mutex);
> >  
> > -	if (input_dev->users)
> > -		clk_enable(kbd->clk);
> > -
> >  	if (device_may_wakeup(&pdev->dev)) {
> >  		if (!enable_irq_wake(kbd->irq))
> >  			kbd->irq_wake = 1;
> > +	} else {
> > +		if (input_dev->users)
> > +			clk_disable(kbd->clk);
> >  	}
> 
> This patch does not apply to mainline version of the driver because the
> change introducing handling for enable_irq_wake() failures was rejected
> from mainline. I also have not appplied the 6th patch in the series
> because it depends on this one.

Oh. Sorry, I should have been careful. I would clean up and send V2
for this.

> Also, don't you need to enable clock if device is marked as wakeup
> source but happens to have no active users?

The keyboard is initialized and programmed in open and disabled in
close, so I thought even if I just enable the clock in suspend
(without open being called) it would not be able to generate the
wakeup interrupt.

--
regards
Shiraz

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH V2 2/6] input/spear_keyboard: fix clock handling during suspend/resume
  2012-07-02  6:50 ` [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume Shiraz Hashim
  2012-07-08  1:11   ` Dmitry Torokhov
@ 2012-07-09  6:35   ` Shiraz Hashim
  1 sibling, 0 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-09  6:35 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, vipulkumar.samar, Shiraz Hashim

SPEAr keyboard should normally disable clock during suspend and enable it
during resume.

For cases where it is expected to act as a wakeup source the clock can
remain in the same state i.e. kept enabled if it is being used.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
Changes since V1:
 * remove discarded irq balancing patch dependency

 drivers/input/keyboard/spear-keyboard.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 45dd02c..aa1259a 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -317,11 +317,12 @@ static int spear_kbd_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
-		clk_enable(kbd->clk);
-
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(&pdev->dev)) {
 		enable_irq_wake(kbd->irq);
+	} else {
+		if (input_dev->users)
+			clk_disable(kbd->clk);
+	}
 
 	mutex_unlock(&input_dev->mutex);
 
@@ -336,11 +337,12 @@ static int spear_kbd_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(&pdev->dev)) {
 		disable_irq_wake(kbd->irq);
-
-	if (input_dev->users)
-		clk_enable(kbd->clk);
+	} else {
+		if (input_dev->users)
+			clk_enable(kbd->clk);
+	}
 
 	mutex_unlock(&input_dev->mutex);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH V2 6/6] input/spear_keyboard: reconfigure operating frequency on suspend
  2012-07-02  6:50 ` [PATCH 6/6] input/spear_keyboard: reconfigure operating frequency on suspend Shiraz Hashim
@ 2012-07-09  6:36   ` Shiraz Hashim
  0 siblings, 0 replies; 10+ messages in thread
From: Shiraz Hashim @ 2012-07-09  6:36 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: spear-devel, linux-input, vipulkumar.samar, Shiraz Hashim

On some platform it may happen that the input clock to keyboard may
change during suspend, thus impacting its wakeup capability.

There is no means for keyboard driver to know this frequency before
hand. Hence introduce a platform data 'suspended_rate' which indicates
the frequency during suspend at which keyboard operates.

Accordingly reprogram keyboard while going into suspend and restore
original configuration at the time of resume.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
Changes since V1:
 * remove discarded irq balancing patch dependency
 * consifer kbd rate from clock APIs, if suspended_rate is not available

 arch/arm/plat-spear/include/plat/keyboard.h |    2 ++
 drivers/input/keyboard/spear-keyboard.c     |   46 +++++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
index 0562f13..9248e3a 100644
--- a/arch/arm/plat-spear/include/plat/keyboard.h
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -149,6 +149,7 @@ int _name[] = { \
  * keymap: pointer to keymap data (table and size)
  * rep: enables key autorepeat
  * mode: choose keyboard support(9x9, 6x6, 2x2)
+ * suspended_rate: rate at which keyboard would operate in suspended mode
  *
  * This structure is supposed to be used by platform code to supply
  * keymaps to drivers that implement keyboards.
@@ -157,6 +158,7 @@ struct kbd_platform_data {
 	const struct matrix_keymap_data *keymap;
 	bool rep;
 	unsigned int mode;
+	unsigned int suspended_rate;
 };
 
 #endif /* __PLAT_KEYBOARD_H */
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 617a33d..72ef01b 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -63,6 +63,8 @@ struct spear_kbd {
 	unsigned short last_key;
 	unsigned short keycodes[NUM_ROWS * NUM_COLS];
 	bool rep;
+	unsigned int suspended_rate;
+	u32 mode_ctl_reg;
 };
 
 static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
@@ -149,7 +151,7 @@ static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
 {
 	struct device_node *np = pdev->dev.of_node;
 	int error;
-	u32 val;
+	u32 val, suspended_rate;
 
 	if (!np) {
 		dev_err(&pdev->dev, "Missing DT data\n");
@@ -159,6 +161,9 @@ static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
 	if (of_property_read_bool(np, "autorepeat"))
 		kbd->rep = true;
 
+	if (of_property_read_u32(np, "suspended_rate", &suspended_rate))
+		kbd->suspended_rate = suspended_rate;
+
 	error = of_property_read_u32(np, "st,mode", &val);
 	if (error) {
 		dev_err(&pdev->dev, "DT: Invalid or missing mode\n");
@@ -216,6 +221,7 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev)
 	} else {
 		kbd->mode = pdata->mode;
 		kbd->rep = pdata->rep;
+		kbd->suspended_rate = pdata->suspended_rate;
 	}
 
 	kbd->res = request_mem_region(res->start, resource_size(res),
@@ -317,16 +323,48 @@ static int spear_kbd_suspend(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct spear_kbd *kbd = platform_get_drvdata(pdev);
 	struct input_dev *input_dev = kbd->input;
+	unsigned int rate = 0, mode_ctl_reg, val;
 
 	mutex_lock(&input_dev->mutex);
 
+	/* explicitly enable clock as we may program device */
+	clk_enable(kbd->clk);
+
+	mode_ctl_reg = readl_relaxed(kbd->io_base + MODE_CTL_REG);
+
 	if (device_may_wakeup(&pdev->dev)) {
 		enable_irq_wake(kbd->irq);
+
+		/*
+		 * reprogram the keyboard operating frequency as on some
+		 * platform it may change during system suspended
+		 */
+		if (kbd->suspended_rate)
+			rate = kbd->suspended_rate / 1000000 - 1;
+		else
+			rate = clk_get_rate(kbd->clk) / 1000000 - 1;
+
+		val = mode_ctl_reg &
+			~(MODE_CTL_PCLK_FREQ_MSK << MODE_CTL_PCLK_FREQ_SHIFT);
+		val |= (rate & MODE_CTL_PCLK_FREQ_MSK)
+			<< MODE_CTL_PCLK_FREQ_SHIFT;
+		writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
+
 	} else {
-		if (input_dev->users)
+		if (input_dev->users) {
+			writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN,
+					kbd->io_base + MODE_CTL_REG);
 			clk_disable(kbd->clk);
+		}
 	}
 
+	/* store current configuration */
+	if (input_dev->users)
+		kbd->mode_ctl_reg = mode_ctl_reg;
+
+	/* restore previous clk state */
+	clk_disable(kbd->clk);
+
 	mutex_unlock(&input_dev->mutex);
 
 	return 0;
@@ -347,6 +385,10 @@ static int spear_kbd_resume(struct device *dev)
 			clk_enable(kbd->clk);
 	}
 
+	/* restore current configuration */
+	if (input_dev->users)
+		writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG);
+
 	mutex_unlock(&input_dev->mutex);
 
 	return 0;
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-07-09  6:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-02  6:50 [PATCH 1/6] input/spear-keyboard: fix disable device_init_wakeup in remove Shiraz Hashim
2012-07-02  6:50 ` [PATCH 2/6] input/spear_keyboard: fix clock handling during suspend/resume Shiraz Hashim
2012-07-08  1:11   ` Dmitry Torokhov
2012-07-09  4:03     ` Shiraz Hashim
2012-07-09  6:35   ` [PATCH V2 " Shiraz Hashim
2012-07-02  6:50 ` [PATCH 3/6] input/spear_keyboard: use correct io accessors Shiraz Hashim
2012-07-02  6:50 ` [PATCH 4/6] input/spear_keyboard: rename bit definitions to reflect register Shiraz Hashim
2012-07-02  6:50 ` [PATCH 5/6] input/spear_keyboard: generalize keyboard frequency configuration Shiraz Hashim
2012-07-02  6:50 ` [PATCH 6/6] input/spear_keyboard: reconfigure operating frequency on suspend Shiraz Hashim
2012-07-09  6:36   ` [PATCH V2 " Shiraz Hashim

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.