linux-sh.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/08] clocksource: sh_cmt: CMT driver update
@ 2012-12-14  5:53 Magnus Damm
  2012-12-14  5:53 ` [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Magnus Damm
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:53 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
	tglx

clocksource: sh_cmt: CMT driver update

[PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
[PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
[PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
[PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
[PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
[PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
[PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
[PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment

This patch series contains a couple of driver updates from Kuribayashi-san
together with some register access changes from me. The register access
changes work towards adding support for 32-bit only CMT hardware, but
the final bits are not yet included in this series due to lack of hardware.

Patches 1-3:
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>

Patches 4-8:
Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |  257 ++++++++++++++++++++++++------------------
 1 file changed, 152 insertions(+), 105 deletions(-)



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

* [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
@ 2012-12-14  5:53 ` Magnus Damm
  2012-12-14  5:53 ` [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup() Magnus Damm
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:53 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
	Magnus Damm

From: Magnus Damm <damm@opensource.se>

Make sure clk_put() is called in case of failure in sh_cmt_setup().

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- 0001/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 12:50:02.000000000 +0900
@@ -708,17 +708,19 @@ static int sh_cmt_setup(struct sh_cmt_pr
 			      cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&p->pdev->dev, "registration failed\n");
-		goto err1;
+		goto err2;
 	}
 	p->cs_enabled = false;
 
 	ret = setup_irq(irq, &p->irqaction);
 	if (ret) {
 		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
-		goto err1;
+		goto err2;
 	}
 
 	return 0;
+err2:
+	clk_put(p->clk);
 
 err1:
 	iounmap(p->mapbase);

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

* [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
  2012-12-14  5:53 ` [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Magnus Damm
@ 2012-12-14  5:53 ` Magnus Damm
  2012-12-14  5:53 ` [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call Magnus Damm
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:53 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
	tglx

From: Magnus Damm <damm@opensource.se>

Move the setup of spinlock and max_match_value to sh_cmt_setup().
There's no need to defer those steps until sh_cmt_register().

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

--- 0002/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 12:52:35.000000000 +0900
@@ -625,14 +625,6 @@ static int sh_cmt_register(struct sh_cmt
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
-	if (p->width = (sizeof(p->max_match_value) * 8))
-		p->max_match_value = ~0;
-	else
-		p->max_match_value = (1 << p->width) - 1;
-
-	p->match_value = p->max_match_value;
-	raw_spin_lock_init(&p->lock);
-
 	if (clockevent_rating)
 		sh_cmt_register_clockevent(p, name, clockevent_rating);
 
@@ -703,6 +695,14 @@ static int sh_cmt_setup(struct sh_cmt_pr
 		p->clear_bits = ~0xc000;
 	}
 
+	if (p->width = (sizeof(p->max_match_value) * 8))
+		p->max_match_value = ~0;
+	else
+		p->max_match_value = (1 << p->width) - 1;
+
+	p->match_value = p->max_match_value;
+	raw_spin_lock_init(&p->lock);
+
 	ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);

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

* [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
  2012-12-14  5:53 ` [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Magnus Damm
  2012-12-14  5:53 ` [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup() Magnus Damm
@ 2012-12-14  5:53 ` Magnus Damm
  2012-12-14  5:54 ` [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions Magnus Damm
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:53 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
	Magnus Damm

From: Magnus Damm <damm@opensource.se>

Cleanup the use of platform_set_drvdata() to reduce code size

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

--- 0003/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 12:54:59.000000000 +0900
@@ -649,8 +649,6 @@ static int sh_cmt_setup(struct sh_cmt_pr
 		goto err0;
 	}
 
-	platform_set_drvdata(pdev, p);
-
 	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
@@ -718,6 +716,8 @@ static int sh_cmt_setup(struct sh_cmt_pr
 		goto err2;
 	}
 
+	platform_set_drvdata(pdev, p);
+
 	return 0;
 err2:
 	clk_put(p->clk);
@@ -753,7 +753,6 @@ static int __devinit sh_cmt_probe(struct
 	ret = sh_cmt_setup(p, pdev);
 	if (ret) {
 		kfree(p);
-		platform_set_drvdata(pdev, NULL);
 		pm_runtime_idle(&pdev->dev);
 		return ret;
 	}

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

* [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (2 preceding siblings ...)
  2012-12-14  5:53 ` [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call Magnus Damm
@ 2012-12-14  5:54 ` Magnus Damm
  2012-12-14  5:54 ` [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update Magnus Damm
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
	tglx

From: Magnus Damm <damm@opensource.se>

Introduce sh_cmt_read_cmstr/cmcsr/cmcnt() and
sh_cmt_write_cmstr/cmcsr/cmcnt/cmcor() to in the
future allow us to split counter registers from
control registers and reduce code complexity by
removing sh_cmt_read() and sh_cmt_write(). 

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |   71 ++++++++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 16 deletions(-)

--- 0001/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 10:50:15.000000000 +0900
@@ -86,6 +86,21 @@ static inline unsigned long sh_cmt_read(
 	return ioread16(base + offs);
 }
 
+static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
+{
+	return sh_cmt_read(p, CMSTR);
+}
+
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
+{
+	return sh_cmt_read(p, CMCSR);
+}
+
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
+{
+	return sh_cmt_read(p, CMCNT);
+}
+
 static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
 				unsigned long value)
 {
@@ -112,21 +127,45 @@ static inline void sh_cmt_write(struct s
 	iowrite16(value, base + offs);
 }
 
+static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
+				      unsigned long value)
+{
+	sh_cmt_write(p, CMSTR, value);
+}
+
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
+				      unsigned long value)
+{
+	sh_cmt_write(p, CMCSR, value);
+}
+
+static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
+				      unsigned long value)
+{
+	sh_cmt_write(p, CMCNT, value);
+}
+
+static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
+				      unsigned long value)
+{
+	sh_cmt_write(p, CMCOR, value);
+}
+
 static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
 					int *has_wrapped)
 {
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
 		o2 = o1;
-		v1 = sh_cmt_read(p, CMCNT);
-		v2 = sh_cmt_read(p, CMCNT);
-		v3 = sh_cmt_read(p, CMCNT);
-		o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+		v1 = sh_cmt_read_cmcnt(p);
+		v2 = sh_cmt_read_cmcnt(p);
+		v3 = sh_cmt_read_cmcnt(p);
+		o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -142,14 +181,14 @@ static void sh_cmt_start_stop_ch(struct
 
 	/* start stop register shared by multiple timer channels */
 	raw_spin_lock_irqsave(&sh_cmt_lock, flags);
-	value = sh_cmt_read(p, CMSTR);
+	value = sh_cmt_read_cmstr(p);
 
 	if (start)
 		value |= 1 << cfg->timer_bit;
 	else
 		value &= ~(1 << cfg->timer_bit);
 
-	sh_cmt_write(p, CMSTR, value);
+	sh_cmt_write_cmstr(p, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
 }
 
@@ -173,14 +212,14 @@ static int sh_cmt_enable(struct sh_cmt_p
 	/* configure channel, periodic mode and maximum timeout */
 	if (p->width = 16) {
 		*rate = clk_get_rate(p->clk) / 512;
-		sh_cmt_write(p, CMCSR, 0x43);
+		sh_cmt_write_cmcsr(p, 0x43);
 	} else {
 		*rate = clk_get_rate(p->clk) / 8;
-		sh_cmt_write(p, CMCSR, 0x01a4);
+		sh_cmt_write_cmcsr(p, 0x01a4);
 	}
 
-	sh_cmt_write(p, CMCOR, 0xffffffff);
-	sh_cmt_write(p, CMCNT, 0);
+	sh_cmt_write_cmcor(p, 0xffffffff);
+	sh_cmt_write_cmcnt(p, 0);
 
 	/*
 	 * According to the sh73a0 user's manual, as CMCNT can be operated
@@ -194,12 +233,12 @@ static int sh_cmt_enable(struct sh_cmt_p
 	 * take RCLKx2 at maximum.
 	 */
 	for (k = 0; k < 100; k++) {
-		if (!sh_cmt_read(p, CMCNT))
+		if (!sh_cmt_read_cmcnt(p))
 			break;
 		udelay(1);
 	}
 
-	if (sh_cmt_read(p, CMCNT)) {
+	if (sh_cmt_read_cmcnt(p)) {
 		dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
 		ret = -ETIMEDOUT;
 		goto err1;
@@ -222,7 +261,7 @@ static void sh_cmt_disable(struct sh_cmt
 	sh_cmt_start_stop_ch(p, 0);
 
 	/* disable interrupts in CMT block */
-	sh_cmt_write(p, CMCSR, 0);
+	sh_cmt_write_cmcsr(p, 0);
 
 	/* stop clock */
 	clk_disable(p->clk);
@@ -270,7 +309,7 @@ static void sh_cmt_clock_event_program_v
 		if (new_match > p->max_match_value)
 			new_match = p->max_match_value;
 
-		sh_cmt_write(p, CMCOR, new_match);
+		sh_cmt_write_cmcor(p, new_match);
 
 		now = sh_cmt_get_counter(p, &has_wrapped);
 		if (has_wrapped && (new_match > p->match_value)) {
@@ -346,7 +385,7 @@ static irqreturn_t sh_cmt_interrupt(int
 	struct sh_cmt_priv *p = dev_id;
 
 	/* clear flags */
-	sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
+	sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific

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

* [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (3 preceding siblings ...)
  2012-12-14  5:54 ` [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions Magnus Damm
@ 2012-12-14  5:54 ` Magnus Damm
  2012-12-14  5:54 ` [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR " Magnus Damm
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
	Magnus Damm

From: Magnus Damm <damm@opensource.se>

Update hardware register access code for CMSTR and CMCSR
from using sh_cmt_read() and sh_cmt_write() to make use
of 16-bit register access functions such as sh_cmt_read16()
and sh_cmt_write16(). Also update sh_cmt_read() and
sh_cmt_write() now when the special cases are gone.

This patch moves us one step closer to the goal of separating
counter register access functions from control control register
functions.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |   66 +++++++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 36 deletions(-)

--- 0005/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 12:58:01.000000000 +0900
@@ -56,44 +56,46 @@ struct sh_cmt_priv {
 	bool cs_enabled;
 };
 
-static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
+static inline unsigned long sh_cmt_read16(void __iomem *base,
+					  unsigned long offs)
+{
+	return ioread16(base + (offs << 1));
+}
+
+static inline void sh_cmt_write16(void __iomem *base, unsigned long offs,
+				  unsigned long value)
+{
+	iowrite16(value, base + (offs << 1));
+}
 
-#define CMSTR -1 /* shared register */
 #define CMCSR 0 /* channel register */
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
 static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
 {
-	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
 	void __iomem *base = p->mapbase;
-	unsigned long offs;
+	unsigned long offs = reg_nr;
 
-	if (reg_nr = CMSTR) {
-		offs = 0;
-		base -= cfg->channel_offset;
-	} else
-		offs = reg_nr;
-
-	if (p->width = 16)
+	if (p->width = 16) {
 		offs <<= 1;
-	else {
+		return ioread16(base + offs);
+	} else {
 		offs <<= 2;
-		if ((reg_nr = CMCNT) || (reg_nr = CMCOR))
-			return ioread32(base + offs);
+		return ioread32(base + offs);
 	}
-
-	return ioread16(base + offs);
 }
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
 {
-	return sh_cmt_read(p, CMSTR);
+	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+
+	return sh_cmt_read16(p->mapbase - cfg->channel_offset, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
 {
-	return sh_cmt_read(p, CMCSR);
+	return sh_cmt_read16(p->mapbase, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
@@ -104,39 +106,30 @@ static inline unsigned long sh_cmt_read_
 static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
 				unsigned long value)
 {
-	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
 	void __iomem *base = p->mapbase;
-	unsigned long offs;
-
-	if (reg_nr = CMSTR) {
-		offs = 0;
-		base -= cfg->channel_offset;
-	} else
-		offs = reg_nr;
+	unsigned long offs = reg_nr;
 
-	if (p->width = 16)
+	if (p->width = 16) {
 		offs <<= 1;
-	else {
+		iowrite16(value, base + offs);
+	} else {
 		offs <<= 2;
-		if ((reg_nr = CMCNT) || (reg_nr = CMCOR)) {
-			iowrite32(value, base + offs);
-			return;
-		}
+		iowrite32(value, base + offs);
 	}
-
-	iowrite16(value, base + offs);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
 				      unsigned long value)
 {
-	sh_cmt_write(p, CMSTR, value);
+	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+
+	sh_cmt_write16(p->mapbase - cfg->channel_offset, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
 				      unsigned long value)
 {
-	sh_cmt_write(p, CMCSR, value);
+	sh_cmt_write16(p->mapbase, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
@@ -173,6 +166,7 @@ static unsigned long sh_cmt_get_counter(
 	return v2;
 }
 
+static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
 static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
 {

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

* [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (4 preceding siblings ...)
  2012-12-14  5:54 ` [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update Magnus Damm
@ 2012-12-14  5:54 ` Magnus Damm
  2012-12-14  5:54 ` [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks Magnus Damm
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
	tglx

From: Magnus Damm <damm@opensource.se>

Break out the CMCNT and CMCOR register access code
into separate 16-bit and 32-bit functions that are
hooked into callbacks at init time. This reduces
the amount of software calculations happening at
runtime.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |   62 +++++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 36 deletions(-)

--- 0006/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 13:00:20.000000000 +0900
@@ -54,38 +54,39 @@ struct sh_cmt_priv {
 	struct clocksource cs;
 	unsigned long total_cycles;
 	bool cs_enabled;
+
+	/* callbacks for CMCNT and CMCOR access */
+	unsigned long (*read_count)(void __iomem *base, unsigned long offs);
+	void (*write_count)(void __iomem *base, unsigned long offs,
+			    unsigned long value);
 };
 
-static inline unsigned long sh_cmt_read16(void __iomem *base,
-					  unsigned long offs)
+static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
 }
 
-static inline void sh_cmt_write16(void __iomem *base, unsigned long offs,
-				  unsigned long value)
+static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs)
+{
+	return ioread32(base + (offs << 2));
+}
+
+static void sh_cmt_write16(void __iomem *base, unsigned long offs,
+			   unsigned long value)
 {
 	iowrite16(value, base + (offs << 1));
 }
 
+static void sh_cmt_write32(void __iomem *base, unsigned long offs,
+			   unsigned long value)
+{
+	iowrite32(value, base + (offs << 2));
+}
+
 #define CMCSR 0 /* channel register */
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
-static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
-{
-	void __iomem *base = p->mapbase;
-	unsigned long offs = reg_nr;
-
-	if (p->width = 16) {
-		offs <<= 1;
-		return ioread16(base + offs);
-	} else {
-		offs <<= 2;
-		return ioread32(base + offs);
-	}
-}
-
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
 {
 	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
@@ -100,22 +101,7 @@ static inline unsigned long sh_cmt_read_
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
 {
-	return sh_cmt_read(p, CMCNT);
-}
-
-static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
-				unsigned long value)
-{
-	void __iomem *base = p->mapbase;
-	unsigned long offs = reg_nr;
-
-	if (p->width = 16) {
-		offs <<= 1;
-		iowrite16(value, base + offs);
-	} else {
-		offs <<= 2;
-		iowrite32(value, base + offs);
-	}
+	return p->read_count(p->mapbase, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
@@ -135,13 +121,13 @@ static inline void sh_cmt_write_cmcsr(st
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
 				      unsigned long value)
 {
-	sh_cmt_write(p, CMCNT, value);
+	p->write_count(p->mapbase, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
 				      unsigned long value)
 {
-	sh_cmt_write(p, CMCOR, value);
+	p->write_count(p->mapbase, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
@@ -718,10 +704,14 @@ static int sh_cmt_setup(struct sh_cmt_pr
 
 	if (resource_size(res) = 6) {
 		p->width = 16;
+		p->read_count = sh_cmt_read16;
+		p->write_count = sh_cmt_write16;
 		p->overflow_bit = 0x80;
 		p->clear_bits = ~0x80;
 	} else {
 		p->width = 32;
+		p->read_count = sh_cmt_read32;
+		p->write_count = sh_cmt_write32;
 		p->overflow_bit = 0x8000;
 		p->clear_bits = ~0xc000;
 	}

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

* [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (5 preceding siblings ...)
  2012-12-14  5:54 ` [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR " Magnus Damm
@ 2012-12-14  5:54 ` Magnus Damm
  2012-12-14  5:54 ` [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment Magnus Damm
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
	Magnus Damm

From: Magnus Damm <damm@opensource.se>

This patch adds control register callbacks for the CMT
driver. At this point only 16-bit access is supported
but in the future this will be updated to allow 32-bit
access as well.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

--- 0004/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 11:28:57.000000000 +0900
@@ -55,6 +55,11 @@ struct sh_cmt_priv {
 	unsigned long total_cycles;
 	bool cs_enabled;
 
+	/* callbacks for CMSTR and CMCSR access */
+	unsigned long (*read_control)(void __iomem *base, unsigned long offs);
+	void (*write_control)(void __iomem *base, unsigned long offs,
+			      unsigned long value);
+
 	/* callbacks for CMCNT and CMCOR access */
 	unsigned long (*read_count)(void __iomem *base, unsigned long offs);
 	void (*write_count)(void __iomem *base, unsigned long offs,
@@ -94,12 +99,12 @@ static inline unsigned long sh_cmt_read_
 {
 	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
 
-	return sh_cmt_read16(p->mapbase - cfg->channel_offset, 0);
+	return p->read_control(p->mapbase - cfg->channel_offset, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
 {
-	return sh_cmt_read16(p->mapbase, CMCSR);
+	return p->read_control(p->mapbase, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
@@ -112,13 +117,13 @@ static inline void sh_cmt_write_cmstr(st
 {
 	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
 
-	sh_cmt_write16(p->mapbase - cfg->channel_offset, 0, value);
+	p->write_control(p->mapbase - cfg->channel_offset, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
 				      unsigned long value)
 {
-	sh_cmt_write16(p->mapbase, CMCSR, value);
+	p->write_control(p->mapbase, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
@@ -714,6 +719,9 @@ static int sh_cmt_setup(struct sh_cmt_pr
 		goto err1;
 	}
 
+	p->read_control = sh_cmt_read16;
+	p->write_control = sh_cmt_write16;
+
 	if (resource_size(res) = 6) {
 		p->width = 16;
 		p->read_count = sh_cmt_read16;

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

* [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (6 preceding siblings ...)
  2012-12-14  5:54 ` [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks Magnus Damm
@ 2012-12-14  5:54 ` Magnus Damm
  2012-12-19 17:57 ` [PATCH 00/08] clocksource: sh_cmt: CMT driver update John Stultz
  2013-02-13  9:45 ` Guennadi Liakhovetski
  9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14  5:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
	tglx

From: Magnus Damm <damm@opensource.se>

Add a comment about different register layouts
supported by the CMT driver.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/clocksource/sh_cmt.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

--- 0005/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2012-12-14 11:43:10.000000000 +0900
@@ -66,6 +66,21 @@ struct sh_cmt_priv {
 			    unsigned long value);
 };
 
+/* Examples of supported CMT timer register layouts and I/O access widths:
+ *
+ * "16-bit counter and 16-bit control" as found on sh7263:
+ * CMSTR 0xfffec000 16-bit
+ * CMCSR 0xfffec002 16-bit
+ * CMCNT 0xfffec004 16-bit
+ * CMCOR 0xfffec006 16-bit
+ *
+ * "32-bit counter and 16-bit control" as found on sh7372, sh73a0, r8a7740:
+ * CMSTR 0xffca0000 16-bit
+ * CMCSR 0xffca0060 16-bit
+ * CMCNT 0xffca0064 32-bit
+ * CMCOR 0xffca0068 32-bit
+ */
+
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));

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

* Re: [PATCH 00/08] clocksource: sh_cmt: CMT driver update
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (7 preceding siblings ...)
  2012-12-14  5:54 ` [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment Magnus Damm
@ 2012-12-19 17:57 ` John Stultz
  2013-02-13  9:45 ` Guennadi Liakhovetski
  9 siblings, 0 replies; 12+ messages in thread
From: John Stultz @ 2012-12-19 17:57 UTC (permalink / raw)
  To: Magnus Damm; +Cc: linux-kernel, linux-sh, horms, shinya.kuribayashi.px, tglx

On 12/13/2012 09:53 PM, Magnus Damm wrote:
> clocksource: sh_cmt: CMT driver update
>
> [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
> [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
> [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
> [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
> [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
> [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
> [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
> [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
>
> This patch series contains a couple of driver updates from Kuribayashi-san
> together with some register access changes from me. The register access
> changes work towards adding support for 32-bit only CMT hardware, but
> the final bits are not yet included in this series due to lack of hardware.
>
> Patches 1-3:
> Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
> Signed-off-by: Magnus Damm <damm@opensource.se>
>
> Patches 4-8:
> Signed-off-by: Magnus Damm <damm@opensource.se>
Due to unfamiliarity with the hardware, I can't really review these 
changes, so I'd prefer they be merged through the arch tree, where it 
can get proper review/testing.

Acked-by: John Stultz <john.stultz@linaro.org>

thanks
-john


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

* Re: [PATCH 00/08] clocksource: sh_cmt: CMT driver update
  2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
                   ` (8 preceding siblings ...)
  2012-12-19 17:57 ` [PATCH 00/08] clocksource: sh_cmt: CMT driver update John Stultz
@ 2013-02-13  9:45 ` Guennadi Liakhovetski
  2013-02-13 10:54   ` Simon Horman
  9 siblings, 1 reply; 12+ messages in thread
From: Guennadi Liakhovetski @ 2013-02-13  9:45 UTC (permalink / raw)
  To: Magnus Damm
  Cc: linux-kernel, linux-sh, johnstul, horms, shinya.kuribayashi.px,
	tglx

Hi Magnus

On Fri, 14 Dec 2012, Magnus Damm wrote:

> clocksource: sh_cmt: CMT driver update
> 
> [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
> [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
> [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
> [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
> [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
> [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
> [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
> [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment

On a kzm9g board with -reference DT configuration and on armadillo800eva:

Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Thanks
Guennadi

> This patch series contains a couple of driver updates from Kuribayashi-san
> together with some register access changes from me. The register access
> changes work towards adding support for 32-bit only CMT hardware, but
> the final bits are not yet included in this series due to lack of hardware.
> 
> Patches 1-3:
> Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
> Signed-off-by: Magnus Damm <damm@opensource.se>
> 
> Patches 4-8:
> Signed-off-by: Magnus Damm <damm@opensource.se>
> ---
> 
>  drivers/clocksource/sh_cmt.c |  257 ++++++++++++++++++++++++------------------
>  1 file changed, 152 insertions(+), 105 deletions(-)
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

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

* Re: [PATCH 00/08] clocksource: sh_cmt: CMT driver update
  2013-02-13  9:45 ` Guennadi Liakhovetski
@ 2013-02-13 10:54   ` Simon Horman
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2013-02-13 10:54 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Magnus Damm, linux-kernel, linux-sh, johnstul,
	shinya.kuribayashi.px, tglx

On Wed, Feb 13, 2013 at 10:45:13AM +0100, Guennadi Liakhovetski wrote:
> Hi Magnus
> 
> On Fri, 14 Dec 2012, Magnus Damm wrote:
> 
> > clocksource: sh_cmt: CMT driver update
> > 
> > [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
> > [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
> > [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
> > [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
> > [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
> > [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
> > [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
> > [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
> 
> On a kzm9g board with -reference DT configuration and on armadillo800eva:
> 
> Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Thanks, I have applied these to the clocksource branch.

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

end of thread, other threads:[~2013-02-13 10:54 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-14  5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
2012-12-14  5:53 ` [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Magnus Damm
2012-12-14  5:53 ` [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup() Magnus Damm
2012-12-14  5:53 ` [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call Magnus Damm
2012-12-14  5:54 ` [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions Magnus Damm
2012-12-14  5:54 ` [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update Magnus Damm
2012-12-14  5:54 ` [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR " Magnus Damm
2012-12-14  5:54 ` [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks Magnus Damm
2012-12-14  5:54 ` [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment Magnus Damm
2012-12-19 17:57 ` [PATCH 00/08] clocksource: sh_cmt: CMT driver update John Stultz
2013-02-13  9:45 ` Guennadi Liakhovetski
2013-02-13 10:54   ` Simon Horman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).