All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/27] Renesas CMT (Compare Match Timer) DT bindings
@ 2014-02-14  0:59 ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch set adds DT support to the Renesas CMT driver.

The first 14 patches are a bunch of necessary cleanups that reorganize the
driver, its platform data, and the memory, interrupt and clock resources it
expects. As a result the driver accepts a new platform data model close to the
hardware with supports for all the timer channels using a single device.

The next 7 patches (15 to 21) move all platforms from the old to the new
platform data model. Patch 22 then drops support for the old model, and patch
23 finally adds DT support.

Patches 24 to 27 then add the CMT devices to the r8a7790 and r8a7791 device
trees, and enable them for the lager-reference and koelsch-reference boards.

The patches are based on top of Simon's latest devel branch with the
"[PATCH v4 0/2] [RESEND] Lager and Koelsch reference serial port support"
series applied.

Laurent Pinchart (27):
  clocksource: sh_cmt: Split channel fields from sh_cmt_priv
  clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device
  clocksource: sh_cmt: Split channel setup to separate function
  clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase
  clocksource: sh_cmt: Add memory base to sh_cmt_channel structure
  clocksource: sh_cmt: Add index to struct sh_cmt_channel
  clocksource: sh_cmt: Replace kmalloc + memset with kzalloc
  clocksource: sh_cmt: Allocate channels dynamically
  clocksource: sh_cmt: Split static information from sh_cmt_device
  clocksource: sh_cmt: Replace hardcoded register values with macros
  clocksource: sh_cmt: Add support for multiple channels per device
  clocksource: sh_cmt: Acquire default clock in the non-legacy case
  clocksource: sh_cmt: Remove FSF mail address from GPL notice
  clocksource: sh_cmt: Sort headers alphabetically
  sh: Switch to new style CMT device
  ARM: shmobile: sh7372: Switch to new style CMT device
  ARM: shmobile: sh73a0: Switch to new style CMT device
  ARM: shmobile: r8a73a4: Switch to new style CMT device
  ARM: shmobile: r8a7740: Switch to new style CMT device
  ARM: shmobile: r8a7790: Switch to new style CMT device
  ARM: shmobile: r8a7791: Switch to new style CMT device
  clocksource: sh_cmt: Drop support for legacy platform data
  clocksource: sh_cmt: Add DT support
  ARM: shmobile: r8a7790: Add CMT devices to DT
  ARM: shmobile: r8a7791: Add CMT devices to DT
  ARM: shmobile: lager-reference: Enable CMT0 in device tree
  ARM: shmobile: koelsch-reference: Enable CMT0 in device tree

 .../devicetree/bindings/timer/renesas,cmt.txt      |  75 ++
 arch/arm/boot/dts/r8a7790-lager.dts                |   9 +
 arch/arm/boot/dts/r8a7790.dtsi                     |  38 +
 arch/arm/boot/dts/r8a7791-koelsch.dts              |   9 +
 arch/arm/boot/dts/r8a7791.dtsi                     |  38 +
 arch/arm/mach-shmobile/board-koelsch-reference.c   |  15 +-
 arch/arm/mach-shmobile/board-lager-reference.c     |  15 +-
 arch/arm/mach-shmobile/clock-r8a73a4.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7740.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7790.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7791.c             |   2 +-
 arch/arm/mach-shmobile/clock-sh7372.c              |   6 +-
 arch/arm/mach-shmobile/clock-sh73a0.c              |   2 +-
 arch/arm/mach-shmobile/include/mach/r8a7790.h      |   1 -
 arch/arm/mach-shmobile/include/mach/r8a7791.h      |   1 -
 arch/arm/mach-shmobile/setup-r8a73a4.c             |  25 +-
 arch/arm/mach-shmobile/setup-r8a7740.c             |  45 +-
 arch/arm/mach-shmobile/setup-r8a7790.c             |  31 +-
 arch/arm/mach-shmobile/setup-r8a7791.c             |  31 +-
 arch/arm/mach-shmobile/setup-sh7372.c              |  30 +-
 arch/arm/mach-shmobile/setup-sh73a0.c              |  45 +-
 arch/sh/kernel/cpu/clock-cpg.c                     |   3 +-
 arch/sh/kernel/cpu/sh2/setup-sh7619.c              |  73 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7264.c             |   2 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7269.c             |   2 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7203.c             |  73 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7206.c             |  73 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7264.c             |  76 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7269.c             |  73 +-
 arch/sh/kernel/cpu/sh3/setup-sh7720.c              | 155 +---
 arch/sh/kernel/cpu/sh4a/clock-sh7343.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7366.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7723.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7343.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7366.c             |  27 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7722.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7723.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7724.c             |  28 +-
 drivers/clocksource/sh_cmt.c                       | 903 +++++++++++++--------
 include/linux/sh_timer.h                           |   9 +
 42 files changed, 1078 insertions(+), 937 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt

-- 
Regards,

Laurent Pinchart


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

* [PATCH 00/27] Renesas CMT (Compare Match Timer) DT bindings
@ 2014-02-14  0:59 ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Hello,

This patch set adds DT support to the Renesas CMT driver.

The first 14 patches are a bunch of necessary cleanups that reorganize the
driver, its platform data, and the memory, interrupt and clock resources it
expects. As a result the driver accepts a new platform data model close to the
hardware with supports for all the timer channels using a single device.

The next 7 patches (15 to 21) move all platforms from the old to the new
platform data model. Patch 22 then drops support for the old model, and patch
23 finally adds DT support.

Patches 24 to 27 then add the CMT devices to the r8a7790 and r8a7791 device
trees, and enable them for the lager-reference and koelsch-reference boards.

The patches are based on top of Simon's latest devel branch with the
"[PATCH v4 0/2] [RESEND] Lager and Koelsch reference serial port support"
series applied.

Laurent Pinchart (27):
  clocksource: sh_cmt: Split channel fields from sh_cmt_priv
  clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device
  clocksource: sh_cmt: Split channel setup to separate function
  clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase
  clocksource: sh_cmt: Add memory base to sh_cmt_channel structure
  clocksource: sh_cmt: Add index to struct sh_cmt_channel
  clocksource: sh_cmt: Replace kmalloc + memset with kzalloc
  clocksource: sh_cmt: Allocate channels dynamically
  clocksource: sh_cmt: Split static information from sh_cmt_device
  clocksource: sh_cmt: Replace hardcoded register values with macros
  clocksource: sh_cmt: Add support for multiple channels per device
  clocksource: sh_cmt: Acquire default clock in the non-legacy case
  clocksource: sh_cmt: Remove FSF mail address from GPL notice
  clocksource: sh_cmt: Sort headers alphabetically
  sh: Switch to new style CMT device
  ARM: shmobile: sh7372: Switch to new style CMT device
  ARM: shmobile: sh73a0: Switch to new style CMT device
  ARM: shmobile: r8a73a4: Switch to new style CMT device
  ARM: shmobile: r8a7740: Switch to new style CMT device
  ARM: shmobile: r8a7790: Switch to new style CMT device
  ARM: shmobile: r8a7791: Switch to new style CMT device
  clocksource: sh_cmt: Drop support for legacy platform data
  clocksource: sh_cmt: Add DT support
  ARM: shmobile: r8a7790: Add CMT devices to DT
  ARM: shmobile: r8a7791: Add CMT devices to DT
  ARM: shmobile: lager-reference: Enable CMT0 in device tree
  ARM: shmobile: koelsch-reference: Enable CMT0 in device tree

 .../devicetree/bindings/timer/renesas,cmt.txt      |  75 ++
 arch/arm/boot/dts/r8a7790-lager.dts                |   9 +
 arch/arm/boot/dts/r8a7790.dtsi                     |  38 +
 arch/arm/boot/dts/r8a7791-koelsch.dts              |   9 +
 arch/arm/boot/dts/r8a7791.dtsi                     |  38 +
 arch/arm/mach-shmobile/board-koelsch-reference.c   |  15 +-
 arch/arm/mach-shmobile/board-lager-reference.c     |  15 +-
 arch/arm/mach-shmobile/clock-r8a73a4.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7740.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7790.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7791.c             |   2 +-
 arch/arm/mach-shmobile/clock-sh7372.c              |   6 +-
 arch/arm/mach-shmobile/clock-sh73a0.c              |   2 +-
 arch/arm/mach-shmobile/include/mach/r8a7790.h      |   1 -
 arch/arm/mach-shmobile/include/mach/r8a7791.h      |   1 -
 arch/arm/mach-shmobile/setup-r8a73a4.c             |  25 +-
 arch/arm/mach-shmobile/setup-r8a7740.c             |  45 +-
 arch/arm/mach-shmobile/setup-r8a7790.c             |  31 +-
 arch/arm/mach-shmobile/setup-r8a7791.c             |  31 +-
 arch/arm/mach-shmobile/setup-sh7372.c              |  30 +-
 arch/arm/mach-shmobile/setup-sh73a0.c              |  45 +-
 arch/sh/kernel/cpu/clock-cpg.c                     |   3 +-
 arch/sh/kernel/cpu/sh2/setup-sh7619.c              |  73 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7264.c             |   2 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7269.c             |   2 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7203.c             |  73 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7206.c             |  73 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7264.c             |  76 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7269.c             |  73 +-
 arch/sh/kernel/cpu/sh3/setup-sh7720.c              | 155 +---
 arch/sh/kernel/cpu/sh4a/clock-sh7343.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7366.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7723.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7343.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7366.c             |  27 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7722.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7723.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7724.c             |  28 +-
 drivers/clocksource/sh_cmt.c                       | 903 +++++++++++++--------
 include/linux/sh_timer.h                           |   9 +
 42 files changed, 1078 insertions(+), 937 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt

-- 
Regards,

Laurent Pinchart


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

* [PATCH 00/27] Renesas CMT (Compare Match Timer) DT bindings
@ 2014-02-14  0:59 ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch set adds DT support to the Renesas CMT driver.

The first 14 patches are a bunch of necessary cleanups that reorganize the
driver, its platform data, and the memory, interrupt and clock resources it
expects. As a result the driver accepts a new platform data model close to the
hardware with supports for all the timer channels using a single device.

The next 7 patches (15 to 21) move all platforms from the old to the new
platform data model. Patch 22 then drops support for the old model, and patch
23 finally adds DT support.

Patches 24 to 27 then add the CMT devices to the r8a7790 and r8a7791 device
trees, and enable them for the lager-reference and koelsch-reference boards.

The patches are based on top of Simon's latest devel branch with the
"[PATCH v4 0/2] [RESEND] Lager and Koelsch reference serial port support"
series applied.

Laurent Pinchart (27):
  clocksource: sh_cmt: Split channel fields from sh_cmt_priv
  clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device
  clocksource: sh_cmt: Split channel setup to separate function
  clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase
  clocksource: sh_cmt: Add memory base to sh_cmt_channel structure
  clocksource: sh_cmt: Add index to struct sh_cmt_channel
  clocksource: sh_cmt: Replace kmalloc + memset with kzalloc
  clocksource: sh_cmt: Allocate channels dynamically
  clocksource: sh_cmt: Split static information from sh_cmt_device
  clocksource: sh_cmt: Replace hardcoded register values with macros
  clocksource: sh_cmt: Add support for multiple channels per device
  clocksource: sh_cmt: Acquire default clock in the non-legacy case
  clocksource: sh_cmt: Remove FSF mail address from GPL notice
  clocksource: sh_cmt: Sort headers alphabetically
  sh: Switch to new style CMT device
  ARM: shmobile: sh7372: Switch to new style CMT device
  ARM: shmobile: sh73a0: Switch to new style CMT device
  ARM: shmobile: r8a73a4: Switch to new style CMT device
  ARM: shmobile: r8a7740: Switch to new style CMT device
  ARM: shmobile: r8a7790: Switch to new style CMT device
  ARM: shmobile: r8a7791: Switch to new style CMT device
  clocksource: sh_cmt: Drop support for legacy platform data
  clocksource: sh_cmt: Add DT support
  ARM: shmobile: r8a7790: Add CMT devices to DT
  ARM: shmobile: r8a7791: Add CMT devices to DT
  ARM: shmobile: lager-reference: Enable CMT0 in device tree
  ARM: shmobile: koelsch-reference: Enable CMT0 in device tree

 .../devicetree/bindings/timer/renesas,cmt.txt      |  75 ++
 arch/arm/boot/dts/r8a7790-lager.dts                |   9 +
 arch/arm/boot/dts/r8a7790.dtsi                     |  38 +
 arch/arm/boot/dts/r8a7791-koelsch.dts              |   9 +
 arch/arm/boot/dts/r8a7791.dtsi                     |  38 +
 arch/arm/mach-shmobile/board-koelsch-reference.c   |  15 +-
 arch/arm/mach-shmobile/board-lager-reference.c     |  15 +-
 arch/arm/mach-shmobile/clock-r8a73a4.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7740.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7790.c             |   2 +-
 arch/arm/mach-shmobile/clock-r8a7791.c             |   2 +-
 arch/arm/mach-shmobile/clock-sh7372.c              |   6 +-
 arch/arm/mach-shmobile/clock-sh73a0.c              |   2 +-
 arch/arm/mach-shmobile/include/mach/r8a7790.h      |   1 -
 arch/arm/mach-shmobile/include/mach/r8a7791.h      |   1 -
 arch/arm/mach-shmobile/setup-r8a73a4.c             |  25 +-
 arch/arm/mach-shmobile/setup-r8a7740.c             |  45 +-
 arch/arm/mach-shmobile/setup-r8a7790.c             |  31 +-
 arch/arm/mach-shmobile/setup-r8a7791.c             |  31 +-
 arch/arm/mach-shmobile/setup-sh7372.c              |  30 +-
 arch/arm/mach-shmobile/setup-sh73a0.c              |  45 +-
 arch/sh/kernel/cpu/clock-cpg.c                     |   3 +-
 arch/sh/kernel/cpu/sh2/setup-sh7619.c              |  73 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7264.c             |   2 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7269.c             |   2 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7203.c             |  73 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7206.c             |  73 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7264.c             |  76 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7269.c             |  73 +-
 arch/sh/kernel/cpu/sh3/setup-sh7720.c              | 155 +---
 arch/sh/kernel/cpu/sh4a/clock-sh7343.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7366.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7723.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c             |   2 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7343.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7366.c             |  27 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7722.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7723.c             |  28 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7724.c             |  28 +-
 drivers/clocksource/sh_cmt.c                       | 903 +++++++++++++--------
 include/linux/sh_timer.h                           |   9 +
 42 files changed, 1078 insertions(+), 937 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt

-- 
Regards,

Laurent Pinchart

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

* [PATCH 01/27] clocksource: sh_cmt: Split channel fields from sh_cmt_priv
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Create a new sh_cmt_channel structure to hold the channel-specific
field in preparation for multiple channels per device support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 393 ++++++++++++++++++++++---------------------
 1 file changed, 204 insertions(+), 189 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 0b1836a..12ccd11 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -35,15 +35,12 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
-struct sh_cmt_priv {
-	void __iomem *mapbase;
-	void __iomem *mapbase_str;
-	struct clk *clk;
-	unsigned long width; /* 16 or 32 bit version of hardware block */
-	unsigned long overflow_bit;
-	unsigned long clear_bits;
+struct sh_cmt_priv;
+
+struct sh_cmt_channel {
+	struct sh_cmt_priv *cmt;
+
 	struct irqaction irqaction;
-	struct platform_device *pdev;
 
 	unsigned long flags;
 	unsigned long match_value;
@@ -55,6 +52,20 @@ struct sh_cmt_priv {
 	struct clocksource cs;
 	unsigned long total_cycles;
 	bool cs_enabled;
+};
+
+struct sh_cmt_priv {
+	struct platform_device *pdev;
+
+	void __iomem *mapbase;
+	void __iomem *mapbase_str;
+	struct clk *clk;
+
+	struct sh_cmt_channel channel;
+
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
 
 	/* callbacks for CMSTR and CMCSR access */
 	unsigned long (*read_control)(void __iomem *base, unsigned long offs);
@@ -114,60 +125,60 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
-static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return p->read_control(p->mapbase_str, 0);
+	return ch->cmt->read_control(ch->cmt->mapbase_str, 0);
 }
 
-static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return p->read_control(p->mapbase, CMCSR);
+	return ch->cmt->read_control(ch->cmt->mapbase, CMCSR);
 }
 
-static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return p->read_count(p->mapbase, CMCNT);
+	return ch->cmt->read_count(ch->cmt->mapbase, CMCNT);
 }
 
-static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_control(p->mapbase_str, 0, value);
+	ch->cmt->write_control(ch->cmt->mapbase_str, 0, value);
 }
 
-static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_control(p->mapbase, CMCSR, value);
+	ch->cmt->write_control(ch->cmt->mapbase, CMCSR, value);
 }
 
-static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_count(p->mapbase, CMCNT, value);
+	ch->cmt->write_count(ch->cmt->mapbase, CMCNT, value);
 }
 
-static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_count(p->mapbase, CMCOR, value);
+	ch->cmt->write_count(ch->cmt->mapbase, CMCOR, value);
 }
 
-static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 					int *has_wrapped)
 {
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
 		o2 = o1;
-		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;
+		v1 = sh_cmt_read_cmcnt(ch);
+		v2 = sh_cmt_read_cmcnt(ch);
+		v3 = sh_cmt_read_cmcnt(ch);
+		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -177,52 +188,52 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
 
 static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
-static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 {
-	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+	struct sh_timer_config *cfg = ch->cmt->pdev->dev.platform_data;
 	unsigned long flags, value;
 
 	/* start stop register shared by multiple timer channels */
 	raw_spin_lock_irqsave(&sh_cmt_lock, flags);
-	value = sh_cmt_read_cmstr(p);
+	value = sh_cmt_read_cmstr(ch);
 
 	if (start)
 		value |= 1 << cfg->timer_bit;
 	else
 		value &= ~(1 << cfg->timer_bit);
 
-	sh_cmt_write_cmstr(p, value);
+	sh_cmt_write_cmstr(ch, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
 }
 
-static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 {
 	int k, ret;
 
-	pm_runtime_get_sync(&p->pdev->dev);
-	dev_pm_syscore_device(&p->pdev->dev, true);
+	pm_runtime_get_sync(&ch->cmt->pdev->dev);
+	dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
 
 	/* enable clock */
-	ret = clk_enable(p->clk);
+	ret = clk_enable(ch->cmt->clk);
 	if (ret) {
-		dev_err(&p->pdev->dev, "cannot enable clock\n");
+		dev_err(&ch->cmt->pdev->dev, "cannot enable clock\n");
 		goto err0;
 	}
 
 	/* make sure channel is disabled */
-	sh_cmt_start_stop_ch(p, 0);
+	sh_cmt_start_stop_ch(ch, 0);
 
 	/* configure channel, periodic mode and maximum timeout */
-	if (p->width = 16) {
-		*rate = clk_get_rate(p->clk) / 512;
-		sh_cmt_write_cmcsr(p, 0x43);
+	if (ch->cmt->width = 16) {
+		*rate = clk_get_rate(ch->cmt->clk) / 512;
+		sh_cmt_write_cmcsr(ch, 0x43);
 	} else {
-		*rate = clk_get_rate(p->clk) / 8;
-		sh_cmt_write_cmcsr(p, 0x01a4);
+		*rate = clk_get_rate(ch->cmt->clk) / 8;
+		sh_cmt_write_cmcsr(ch, 0x01a4);
 	}
 
-	sh_cmt_write_cmcor(p, 0xffffffff);
-	sh_cmt_write_cmcnt(p, 0);
+	sh_cmt_write_cmcor(ch, 0xffffffff);
+	sh_cmt_write_cmcnt(ch, 0);
 
 	/*
 	 * According to the sh73a0 user's manual, as CMCNT can be operated
@@ -236,41 +247,41 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
 	 * take RCLKx2 at maximum.
 	 */
 	for (k = 0; k < 100; k++) {
-		if (!sh_cmt_read_cmcnt(p))
+		if (!sh_cmt_read_cmcnt(ch))
 			break;
 		udelay(1);
 	}
 
-	if (sh_cmt_read_cmcnt(p)) {
-		dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
+	if (sh_cmt_read_cmcnt(ch)) {
+		dev_err(&ch->cmt->pdev->dev, "cannot clear CMCNT\n");
 		ret = -ETIMEDOUT;
 		goto err1;
 	}
 
 	/* enable channel */
-	sh_cmt_start_stop_ch(p, 1);
+	sh_cmt_start_stop_ch(ch, 1);
 	return 0;
  err1:
 	/* stop clock */
-	clk_disable(p->clk);
+	clk_disable(ch->cmt->clk);
 
  err0:
 	return ret;
 }
 
-static void sh_cmt_disable(struct sh_cmt_priv *p)
+static void sh_cmt_disable(struct sh_cmt_channel *ch)
 {
 	/* disable channel */
-	sh_cmt_start_stop_ch(p, 0);
+	sh_cmt_start_stop_ch(ch, 0);
 
 	/* disable interrupts in CMT block */
-	sh_cmt_write_cmcsr(p, 0);
+	sh_cmt_write_cmcsr(ch, 0);
 
 	/* stop clock */
-	clk_disable(p->clk);
+	clk_disable(ch->cmt->clk);
 
-	dev_pm_syscore_device(&p->pdev->dev, false);
-	pm_runtime_put(&p->pdev->dev);
+	dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
+	pm_runtime_put(&ch->cmt->pdev->dev);
 }
 
 /* private flags */
@@ -280,24 +291,24 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
 #define FLAG_SKIPEVENT (1 << 3)
 #define FLAG_IRQCONTEXT (1 << 4)
 
-static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 					      int absolute)
 {
 	unsigned long new_match;
-	unsigned long value = p->next_match_value;
+	unsigned long value = ch->next_match_value;
 	unsigned long delay = 0;
 	unsigned long now = 0;
 	int has_wrapped;
 
-	now = sh_cmt_get_counter(p, &has_wrapped);
-	p->flags |= FLAG_REPROGRAM; /* force reprogram */
+	now = sh_cmt_get_counter(ch, &has_wrapped);
+	ch->flags |= FLAG_REPROGRAM; /* force reprogram */
 
 	if (has_wrapped) {
 		/* we're competing with the interrupt handler.
 		 *  -> let the interrupt handler reprogram the timer.
 		 *  -> interrupt number two handles the event.
 		 */
-		p->flags |= FLAG_SKIPEVENT;
+		ch->flags |= FLAG_SKIPEVENT;
 		return;
 	}
 
@@ -309,20 +320,20 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 		 * but don't save the new match value yet.
 		 */
 		new_match = now + value + delay;
-		if (new_match > p->max_match_value)
-			new_match = p->max_match_value;
+		if (new_match > ch->max_match_value)
+			new_match = ch->max_match_value;
 
-		sh_cmt_write_cmcor(p, new_match);
+		sh_cmt_write_cmcor(ch, new_match);
 
-		now = sh_cmt_get_counter(p, &has_wrapped);
-		if (has_wrapped && (new_match > p->match_value)) {
+		now = sh_cmt_get_counter(ch, &has_wrapped);
+		if (has_wrapped && (new_match > ch->match_value)) {
 			/* we are changing to a greater match value,
 			 * so this wrap must be caused by the counter
 			 * matching the old value.
 			 * -> first interrupt reprograms the timer.
 			 * -> interrupt number two handles the event.
 			 */
-			p->flags |= FLAG_SKIPEVENT;
+			ch->flags |= FLAG_SKIPEVENT;
 			break;
 		}
 
@@ -333,7 +344,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			 * -> save programmed match value.
 			 * -> let isr handle the event.
 			 */
-			p->match_value = new_match;
+			ch->match_value = new_match;
 			break;
 		}
 
@@ -344,7 +355,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			 * -> save programmed match value.
 			 * -> let isr handle the event.
 			 */
-			p->match_value = new_match;
+			ch->match_value = new_match;
 			break;
 		}
 
@@ -360,138 +371,138 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			delay = 1;
 
 		if (!delay)
-			dev_warn(&p->pdev->dev, "too long delay\n");
+			dev_warn(&ch->cmt->pdev->dev, "too long delay\n");
 
 	} while (delay);
 }
 
-static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
-	if (delta > p->max_match_value)
-		dev_warn(&p->pdev->dev, "delta out of range\n");
+	if (delta > ch->max_match_value)
+		dev_warn(&ch->cmt->pdev->dev, "delta out of range\n");
 
-	p->next_match_value = delta;
-	sh_cmt_clock_event_program_verify(p, 0);
+	ch->next_match_value = delta;
+	sh_cmt_clock_event_program_verify(ch, 0);
 }
 
-static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
-	__sh_cmt_set_next(p, delta);
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
+	__sh_cmt_set_next(ch, delta);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 }
 
 static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 {
-	struct sh_cmt_priv *p = dev_id;
+	struct sh_cmt_channel *ch = dev_id;
 
 	/* clear flags */
-	sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits);
+	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific
 	 * isr before we end up here.
 	 */
-	if (p->flags & FLAG_CLOCKSOURCE)
-		p->total_cycles += p->match_value + 1;
+	if (ch->flags & FLAG_CLOCKSOURCE)
+		ch->total_cycles += ch->match_value + 1;
 
-	if (!(p->flags & FLAG_REPROGRAM))
-		p->next_match_value = p->max_match_value;
+	if (!(ch->flags & FLAG_REPROGRAM))
+		ch->next_match_value = ch->max_match_value;
 
-	p->flags |= FLAG_IRQCONTEXT;
+	ch->flags |= FLAG_IRQCONTEXT;
 
-	if (p->flags & FLAG_CLOCKEVENT) {
-		if (!(p->flags & FLAG_SKIPEVENT)) {
-			if (p->ced.mode = CLOCK_EVT_MODE_ONESHOT) {
-				p->next_match_value = p->max_match_value;
-				p->flags |= FLAG_REPROGRAM;
+	if (ch->flags & FLAG_CLOCKEVENT) {
+		if (!(ch->flags & FLAG_SKIPEVENT)) {
+			if (ch->ced.mode = CLOCK_EVT_MODE_ONESHOT) {
+				ch->next_match_value = ch->max_match_value;
+				ch->flags |= FLAG_REPROGRAM;
 			}
 
-			p->ced.event_handler(&p->ced);
+			ch->ced.event_handler(&ch->ced);
 		}
 	}
 
-	p->flags &= ~FLAG_SKIPEVENT;
+	ch->flags &= ~FLAG_SKIPEVENT;
 
-	if (p->flags & FLAG_REPROGRAM) {
-		p->flags &= ~FLAG_REPROGRAM;
-		sh_cmt_clock_event_program_verify(p, 1);
+	if (ch->flags & FLAG_REPROGRAM) {
+		ch->flags &= ~FLAG_REPROGRAM;
+		sh_cmt_clock_event_program_verify(ch, 1);
 
-		if (p->flags & FLAG_CLOCKEVENT)
-			if ((p->ced.mode = CLOCK_EVT_MODE_SHUTDOWN)
-			    || (p->match_value = p->next_match_value))
-				p->flags &= ~FLAG_REPROGRAM;
+		if (ch->flags & FLAG_CLOCKEVENT)
+			if ((ch->ced.mode = CLOCK_EVT_MODE_SHUTDOWN)
+			    || (ch->match_value = ch->next_match_value))
+				ch->flags &= ~FLAG_REPROGRAM;
 	}
 
-	p->flags &= ~FLAG_IRQCONTEXT;
+	ch->flags &= ~FLAG_IRQCONTEXT;
 
 	return IRQ_HANDLED;
 }
 
-static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
 {
 	int ret = 0;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
 
-	if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
-		ret = sh_cmt_enable(p, &p->rate);
+	if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		ret = sh_cmt_enable(ch, &ch->rate);
 
 	if (ret)
 		goto out;
-	p->flags |= flag;
+	ch->flags |= flag;
 
 	/* setup timeout if no clockevent */
-	if ((flag = FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
-		__sh_cmt_set_next(p, p->max_match_value);
+	if ((flag = FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT)))
+		__sh_cmt_set_next(ch, ch->max_match_value);
  out:
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return ret;
 }
 
-static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag)
 {
 	unsigned long flags;
 	unsigned long f;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
 
-	f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
-	p->flags &= ~flag;
+	f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+	ch->flags &= ~flag;
 
-	if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
-		sh_cmt_disable(p);
+	if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		sh_cmt_disable(ch);
 
 	/* adjust the timeout to maximum if only clocksource left */
-	if ((flag = FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
-		__sh_cmt_set_next(p, p->max_match_value);
+	if ((flag = FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE))
+		__sh_cmt_set_next(ch, ch->max_match_value);
 
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 }
 
-static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs)
+static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
 {
-	return container_of(cs, struct sh_cmt_priv, cs);
+	return container_of(cs, struct sh_cmt_channel, cs);
 }
 
 static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 	unsigned long flags, raw;
 	unsigned long value;
 	int has_wrapped;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
-	value = p->total_cycles;
-	raw = sh_cmt_get_counter(p, &has_wrapped);
+	raw_spin_lock_irqsave(&ch->lock, flags);
+	value = ch->total_cycles;
+	raw = sh_cmt_get_counter(ch, &has_wrapped);
 
 	if (unlikely(has_wrapped))
-		raw += p->match_value + 1;
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+		raw += ch->match_value + 1;
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return value + raw;
 }
@@ -499,50 +510,50 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
 static int sh_cmt_clocksource_enable(struct clocksource *cs)
 {
 	int ret;
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	WARN_ON(p->cs_enabled);
+	WARN_ON(ch->cs_enabled);
 
-	p->total_cycles = 0;
+	ch->total_cycles = 0;
 
-	ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 	if (!ret) {
-		__clocksource_updatefreq_hz(cs, p->rate);
-		p->cs_enabled = true;
+		__clocksource_updatefreq_hz(cs, ch->rate);
+		ch->cs_enabled = true;
 	}
 	return ret;
 }
 
 static void sh_cmt_clocksource_disable(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	WARN_ON(!p->cs_enabled);
+	WARN_ON(!ch->cs_enabled);
 
-	sh_cmt_stop(p, FLAG_CLOCKSOURCE);
-	p->cs_enabled = false;
+	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
+	ch->cs_enabled = false;
 }
 
 static void sh_cmt_clocksource_suspend(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	sh_cmt_stop(p, FLAG_CLOCKSOURCE);
-	pm_genpd_syscore_poweroff(&p->pdev->dev);
+	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
+	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
 }
 
 static void sh_cmt_clocksource_resume(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	pm_genpd_syscore_poweron(&p->pdev->dev);
-	sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
+	sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 }
 
-static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
+static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
 				       char *name, unsigned long rating)
 {
-	struct clocksource *cs = &p->cs;
+	struct clocksource *cs = &ch->cs;
 
 	cs->name = name;
 	cs->rating = rating;
@@ -554,47 +565,47 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	dev_info(&p->pdev->dev, "used as clock source\n");
+	dev_info(&ch->cmt->pdev->dev, "used as clock source\n");
 
 	/* Register with dummy 1 Hz value, gets updated in ->enable() */
 	clocksource_register_hz(cs, 1);
 	return 0;
 }
 
-static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
 {
-	return container_of(ced, struct sh_cmt_priv, ced);
+	return container_of(ced, struct sh_cmt_channel, ced);
 }
 
-static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
 {
-	struct clock_event_device *ced = &p->ced;
+	struct clock_event_device *ced = &ch->ced;
 
-	sh_cmt_start(p, FLAG_CLOCKEVENT);
+	sh_cmt_start(ch, FLAG_CLOCKEVENT);
 
 	/* TODO: calculate good shift from rate and counter bit width */
 
 	ced->shift = 32;
-	ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
-	ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+	ced->mult = div_sc(ch->rate, NSEC_PER_SEC, ced->shift);
+	ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
 	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
 
 	if (periodic)
-		sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1);
+		sh_cmt_set_next(ch, ((ch->rate + HZ/2) / HZ) - 1);
 	else
-		sh_cmt_set_next(p, p->max_match_value);
+		sh_cmt_set_next(ch, ch->max_match_value);
 }
 
 static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 				    struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
 	/* deal with old setting first */
 	switch (ced->mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 	case CLOCK_EVT_MODE_ONESHOT:
-		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
 		break;
 	default:
 		break;
@@ -602,16 +613,18 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		dev_info(&p->pdev->dev, "used for periodic clock events\n");
-		sh_cmt_clock_event_start(p, 1);
+		dev_info(&ch->cmt->pdev->dev,
+			 "used for periodic clock events\n");
+		sh_cmt_clock_event_start(ch, 1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
-		dev_info(&p->pdev->dev, "used for oneshot clock events\n");
-		sh_cmt_clock_event_start(p, 0);
+		dev_info(&ch->cmt->pdev->dev,
+			 "used for oneshot clock events\n");
+		sh_cmt_clock_event_start(ch, 0);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
-		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
 		break;
 	default:
 		break;
@@ -621,37 +634,37 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 static int sh_cmt_clock_event_next(unsigned long delta,
 				   struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
 	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
-	if (likely(p->flags & FLAG_IRQCONTEXT))
-		p->next_match_value = delta - 1;
+	if (likely(ch->flags & FLAG_IRQCONTEXT))
+		ch->next_match_value = delta - 1;
 	else
-		sh_cmt_set_next(p, delta - 1);
+		sh_cmt_set_next(ch, delta - 1);
 
 	return 0;
 }
 
 static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
-	pm_genpd_syscore_poweroff(&p->pdev->dev);
-	clk_unprepare(p->clk);
+	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
+	clk_unprepare(ch->cmt->clk);
 }
 
 static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
-	clk_prepare(p->clk);
-	pm_genpd_syscore_poweron(&p->pdev->dev);
+	clk_prepare(ch->cmt->clk);
+	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
 }
 
-static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 				       char *name, unsigned long rating)
 {
-	struct clock_event_device *ced = &p->ced;
+	struct clock_event_device *ced = &ch->ced;
 
 	memset(ced, 0, sizeof(*ced));
 
@@ -665,19 +678,19 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
 	ced->suspend = sh_cmt_clock_event_suspend;
 	ced->resume = sh_cmt_clock_event_resume;
 
-	dev_info(&p->pdev->dev, "used for clock events\n");
+	dev_info(&ch->cmt->pdev->dev, "used for clock events\n");
 	clockevents_register_device(ced);
 }
 
-static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
 	if (clockevent_rating)
-		sh_cmt_register_clockevent(p, name, clockevent_rating);
+		sh_cmt_register_clockevent(ch, name, clockevent_rating);
 
 	if (clocksource_rating)
-		sh_cmt_register_clocksource(p, name, clocksource_rating);
+		sh_cmt_register_clocksource(ch, name, clocksource_rating);
 
 	return 0;
 }
@@ -685,6 +698,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
 static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
+	struct sh_cmt_channel *ch = &p->channel;
 	struct resource *res, *res2;
 	int irq, ret;
 	ret = -ENXIO;
@@ -729,10 +743,10 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 	}
 
 	/* request irq using setup_irq() (too early for request_irq()) */
-	p->irqaction.name = dev_name(&p->pdev->dev);
-	p->irqaction.handler = sh_cmt_interrupt;
-	p->irqaction.dev_id = p;
-	p->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
+	ch->irqaction.name = dev_name(&p->pdev->dev);
+	ch->irqaction.handler = sh_cmt_interrupt;
+	ch->irqaction.dev_id = ch;
+	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
 	/* get hold of clock */
 	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
@@ -769,24 +783,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 		p->clear_bits = ~0xc000;
 	}
 
-	if (p->width = (sizeof(p->max_match_value) * 8))
-		p->max_match_value = ~0;
+	if (p->width = (sizeof(ch->max_match_value) * 8))
+		ch->max_match_value = ~0;
 	else
-		p->max_match_value = (1 << p->width) - 1;
+		ch->max_match_value = (1 << p->width) - 1;
 
-	p->match_value = p->max_match_value;
-	raw_spin_lock_init(&p->lock);
+	ch->cmt = p;
+	ch->match_value = ch->max_match_value;
+	raw_spin_lock_init(&ch->lock);
 
-	ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
+	ret = sh_cmt_register(ch, (char *)dev_name(&p->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&p->pdev->dev, "registration failed\n");
 		goto err4;
 	}
-	p->cs_enabled = false;
+	ch->cs_enabled = false;
 
-	ret = setup_irq(irq, &p->irqaction);
+	ret = setup_irq(irq, &ch->irqaction);
 	if (ret) {
 		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
 		goto err4;
-- 
1.8.3.2


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

* [PATCH 01/27] clocksource: sh_cmt: Split channel fields from sh_cmt_priv
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Create a new sh_cmt_channel structure to hold the channel-specific
field in preparation for multiple channels per device support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 393 ++++++++++++++++++++++---------------------
 1 file changed, 204 insertions(+), 189 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 0b1836a..12ccd11 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -35,15 +35,12 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
-struct sh_cmt_priv {
-	void __iomem *mapbase;
-	void __iomem *mapbase_str;
-	struct clk *clk;
-	unsigned long width; /* 16 or 32 bit version of hardware block */
-	unsigned long overflow_bit;
-	unsigned long clear_bits;
+struct sh_cmt_priv;
+
+struct sh_cmt_channel {
+	struct sh_cmt_priv *cmt;
+
 	struct irqaction irqaction;
-	struct platform_device *pdev;
 
 	unsigned long flags;
 	unsigned long match_value;
@@ -55,6 +52,20 @@ struct sh_cmt_priv {
 	struct clocksource cs;
 	unsigned long total_cycles;
 	bool cs_enabled;
+};
+
+struct sh_cmt_priv {
+	struct platform_device *pdev;
+
+	void __iomem *mapbase;
+	void __iomem *mapbase_str;
+	struct clk *clk;
+
+	struct sh_cmt_channel channel;
+
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
 
 	/* callbacks for CMSTR and CMCSR access */
 	unsigned long (*read_control)(void __iomem *base, unsigned long offs);
@@ -114,60 +125,60 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
-static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return p->read_control(p->mapbase_str, 0);
+	return ch->cmt->read_control(ch->cmt->mapbase_str, 0);
 }
 
-static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return p->read_control(p->mapbase, CMCSR);
+	return ch->cmt->read_control(ch->cmt->mapbase, CMCSR);
 }
 
-static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return p->read_count(p->mapbase, CMCNT);
+	return ch->cmt->read_count(ch->cmt->mapbase, CMCNT);
 }
 
-static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_control(p->mapbase_str, 0, value);
+	ch->cmt->write_control(ch->cmt->mapbase_str, 0, value);
 }
 
-static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_control(p->mapbase, CMCSR, value);
+	ch->cmt->write_control(ch->cmt->mapbase, CMCSR, value);
 }
 
-static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_count(p->mapbase, CMCNT, value);
+	ch->cmt->write_count(ch->cmt->mapbase, CMCNT, value);
 }
 
-static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_count(p->mapbase, CMCOR, value);
+	ch->cmt->write_count(ch->cmt->mapbase, CMCOR, value);
 }
 
-static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 					int *has_wrapped)
 {
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
 		o2 = o1;
-		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;
+		v1 = sh_cmt_read_cmcnt(ch);
+		v2 = sh_cmt_read_cmcnt(ch);
+		v3 = sh_cmt_read_cmcnt(ch);
+		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -177,52 +188,52 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
 
 static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
-static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 {
-	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+	struct sh_timer_config *cfg = ch->cmt->pdev->dev.platform_data;
 	unsigned long flags, value;
 
 	/* start stop register shared by multiple timer channels */
 	raw_spin_lock_irqsave(&sh_cmt_lock, flags);
-	value = sh_cmt_read_cmstr(p);
+	value = sh_cmt_read_cmstr(ch);
 
 	if (start)
 		value |= 1 << cfg->timer_bit;
 	else
 		value &= ~(1 << cfg->timer_bit);
 
-	sh_cmt_write_cmstr(p, value);
+	sh_cmt_write_cmstr(ch, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
 }
 
-static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 {
 	int k, ret;
 
-	pm_runtime_get_sync(&p->pdev->dev);
-	dev_pm_syscore_device(&p->pdev->dev, true);
+	pm_runtime_get_sync(&ch->cmt->pdev->dev);
+	dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
 
 	/* enable clock */
-	ret = clk_enable(p->clk);
+	ret = clk_enable(ch->cmt->clk);
 	if (ret) {
-		dev_err(&p->pdev->dev, "cannot enable clock\n");
+		dev_err(&ch->cmt->pdev->dev, "cannot enable clock\n");
 		goto err0;
 	}
 
 	/* make sure channel is disabled */
-	sh_cmt_start_stop_ch(p, 0);
+	sh_cmt_start_stop_ch(ch, 0);
 
 	/* configure channel, periodic mode and maximum timeout */
-	if (p->width == 16) {
-		*rate = clk_get_rate(p->clk) / 512;
-		sh_cmt_write_cmcsr(p, 0x43);
+	if (ch->cmt->width == 16) {
+		*rate = clk_get_rate(ch->cmt->clk) / 512;
+		sh_cmt_write_cmcsr(ch, 0x43);
 	} else {
-		*rate = clk_get_rate(p->clk) / 8;
-		sh_cmt_write_cmcsr(p, 0x01a4);
+		*rate = clk_get_rate(ch->cmt->clk) / 8;
+		sh_cmt_write_cmcsr(ch, 0x01a4);
 	}
 
-	sh_cmt_write_cmcor(p, 0xffffffff);
-	sh_cmt_write_cmcnt(p, 0);
+	sh_cmt_write_cmcor(ch, 0xffffffff);
+	sh_cmt_write_cmcnt(ch, 0);
 
 	/*
 	 * According to the sh73a0 user's manual, as CMCNT can be operated
@@ -236,41 +247,41 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
 	 * take RCLKx2 at maximum.
 	 */
 	for (k = 0; k < 100; k++) {
-		if (!sh_cmt_read_cmcnt(p))
+		if (!sh_cmt_read_cmcnt(ch))
 			break;
 		udelay(1);
 	}
 
-	if (sh_cmt_read_cmcnt(p)) {
-		dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
+	if (sh_cmt_read_cmcnt(ch)) {
+		dev_err(&ch->cmt->pdev->dev, "cannot clear CMCNT\n");
 		ret = -ETIMEDOUT;
 		goto err1;
 	}
 
 	/* enable channel */
-	sh_cmt_start_stop_ch(p, 1);
+	sh_cmt_start_stop_ch(ch, 1);
 	return 0;
  err1:
 	/* stop clock */
-	clk_disable(p->clk);
+	clk_disable(ch->cmt->clk);
 
  err0:
 	return ret;
 }
 
-static void sh_cmt_disable(struct sh_cmt_priv *p)
+static void sh_cmt_disable(struct sh_cmt_channel *ch)
 {
 	/* disable channel */
-	sh_cmt_start_stop_ch(p, 0);
+	sh_cmt_start_stop_ch(ch, 0);
 
 	/* disable interrupts in CMT block */
-	sh_cmt_write_cmcsr(p, 0);
+	sh_cmt_write_cmcsr(ch, 0);
 
 	/* stop clock */
-	clk_disable(p->clk);
+	clk_disable(ch->cmt->clk);
 
-	dev_pm_syscore_device(&p->pdev->dev, false);
-	pm_runtime_put(&p->pdev->dev);
+	dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
+	pm_runtime_put(&ch->cmt->pdev->dev);
 }
 
 /* private flags */
@@ -280,24 +291,24 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
 #define FLAG_SKIPEVENT (1 << 3)
 #define FLAG_IRQCONTEXT (1 << 4)
 
-static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 					      int absolute)
 {
 	unsigned long new_match;
-	unsigned long value = p->next_match_value;
+	unsigned long value = ch->next_match_value;
 	unsigned long delay = 0;
 	unsigned long now = 0;
 	int has_wrapped;
 
-	now = sh_cmt_get_counter(p, &has_wrapped);
-	p->flags |= FLAG_REPROGRAM; /* force reprogram */
+	now = sh_cmt_get_counter(ch, &has_wrapped);
+	ch->flags |= FLAG_REPROGRAM; /* force reprogram */
 
 	if (has_wrapped) {
 		/* we're competing with the interrupt handler.
 		 *  -> let the interrupt handler reprogram the timer.
 		 *  -> interrupt number two handles the event.
 		 */
-		p->flags |= FLAG_SKIPEVENT;
+		ch->flags |= FLAG_SKIPEVENT;
 		return;
 	}
 
@@ -309,20 +320,20 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 		 * but don't save the new match value yet.
 		 */
 		new_match = now + value + delay;
-		if (new_match > p->max_match_value)
-			new_match = p->max_match_value;
+		if (new_match > ch->max_match_value)
+			new_match = ch->max_match_value;
 
-		sh_cmt_write_cmcor(p, new_match);
+		sh_cmt_write_cmcor(ch, new_match);
 
-		now = sh_cmt_get_counter(p, &has_wrapped);
-		if (has_wrapped && (new_match > p->match_value)) {
+		now = sh_cmt_get_counter(ch, &has_wrapped);
+		if (has_wrapped && (new_match > ch->match_value)) {
 			/* we are changing to a greater match value,
 			 * so this wrap must be caused by the counter
 			 * matching the old value.
 			 * -> first interrupt reprograms the timer.
 			 * -> interrupt number two handles the event.
 			 */
-			p->flags |= FLAG_SKIPEVENT;
+			ch->flags |= FLAG_SKIPEVENT;
 			break;
 		}
 
@@ -333,7 +344,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			 * -> save programmed match value.
 			 * -> let isr handle the event.
 			 */
-			p->match_value = new_match;
+			ch->match_value = new_match;
 			break;
 		}
 
@@ -344,7 +355,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			 * -> save programmed match value.
 			 * -> let isr handle the event.
 			 */
-			p->match_value = new_match;
+			ch->match_value = new_match;
 			break;
 		}
 
@@ -360,138 +371,138 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			delay = 1;
 
 		if (!delay)
-			dev_warn(&p->pdev->dev, "too long delay\n");
+			dev_warn(&ch->cmt->pdev->dev, "too long delay\n");
 
 	} while (delay);
 }
 
-static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
-	if (delta > p->max_match_value)
-		dev_warn(&p->pdev->dev, "delta out of range\n");
+	if (delta > ch->max_match_value)
+		dev_warn(&ch->cmt->pdev->dev, "delta out of range\n");
 
-	p->next_match_value = delta;
-	sh_cmt_clock_event_program_verify(p, 0);
+	ch->next_match_value = delta;
+	sh_cmt_clock_event_program_verify(ch, 0);
 }
 
-static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
-	__sh_cmt_set_next(p, delta);
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
+	__sh_cmt_set_next(ch, delta);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 }
 
 static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 {
-	struct sh_cmt_priv *p = dev_id;
+	struct sh_cmt_channel *ch = dev_id;
 
 	/* clear flags */
-	sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits);
+	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific
 	 * isr before we end up here.
 	 */
-	if (p->flags & FLAG_CLOCKSOURCE)
-		p->total_cycles += p->match_value + 1;
+	if (ch->flags & FLAG_CLOCKSOURCE)
+		ch->total_cycles += ch->match_value + 1;
 
-	if (!(p->flags & FLAG_REPROGRAM))
-		p->next_match_value = p->max_match_value;
+	if (!(ch->flags & FLAG_REPROGRAM))
+		ch->next_match_value = ch->max_match_value;
 
-	p->flags |= FLAG_IRQCONTEXT;
+	ch->flags |= FLAG_IRQCONTEXT;
 
-	if (p->flags & FLAG_CLOCKEVENT) {
-		if (!(p->flags & FLAG_SKIPEVENT)) {
-			if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
-				p->next_match_value = p->max_match_value;
-				p->flags |= FLAG_REPROGRAM;
+	if (ch->flags & FLAG_CLOCKEVENT) {
+		if (!(ch->flags & FLAG_SKIPEVENT)) {
+			if (ch->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+				ch->next_match_value = ch->max_match_value;
+				ch->flags |= FLAG_REPROGRAM;
 			}
 
-			p->ced.event_handler(&p->ced);
+			ch->ced.event_handler(&ch->ced);
 		}
 	}
 
-	p->flags &= ~FLAG_SKIPEVENT;
+	ch->flags &= ~FLAG_SKIPEVENT;
 
-	if (p->flags & FLAG_REPROGRAM) {
-		p->flags &= ~FLAG_REPROGRAM;
-		sh_cmt_clock_event_program_verify(p, 1);
+	if (ch->flags & FLAG_REPROGRAM) {
+		ch->flags &= ~FLAG_REPROGRAM;
+		sh_cmt_clock_event_program_verify(ch, 1);
 
-		if (p->flags & FLAG_CLOCKEVENT)
-			if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
-			    || (p->match_value == p->next_match_value))
-				p->flags &= ~FLAG_REPROGRAM;
+		if (ch->flags & FLAG_CLOCKEVENT)
+			if ((ch->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
+			    || (ch->match_value == ch->next_match_value))
+				ch->flags &= ~FLAG_REPROGRAM;
 	}
 
-	p->flags &= ~FLAG_IRQCONTEXT;
+	ch->flags &= ~FLAG_IRQCONTEXT;
 
 	return IRQ_HANDLED;
 }
 
-static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
 {
 	int ret = 0;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
 
-	if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
-		ret = sh_cmt_enable(p, &p->rate);
+	if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		ret = sh_cmt_enable(ch, &ch->rate);
 
 	if (ret)
 		goto out;
-	p->flags |= flag;
+	ch->flags |= flag;
 
 	/* setup timeout if no clockevent */
-	if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
-		__sh_cmt_set_next(p, p->max_match_value);
+	if ((flag == FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT)))
+		__sh_cmt_set_next(ch, ch->max_match_value);
  out:
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return ret;
 }
 
-static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag)
 {
 	unsigned long flags;
 	unsigned long f;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
 
-	f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
-	p->flags &= ~flag;
+	f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+	ch->flags &= ~flag;
 
-	if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
-		sh_cmt_disable(p);
+	if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		sh_cmt_disable(ch);
 
 	/* adjust the timeout to maximum if only clocksource left */
-	if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
-		__sh_cmt_set_next(p, p->max_match_value);
+	if ((flag == FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE))
+		__sh_cmt_set_next(ch, ch->max_match_value);
 
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 }
 
-static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs)
+static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
 {
-	return container_of(cs, struct sh_cmt_priv, cs);
+	return container_of(cs, struct sh_cmt_channel, cs);
 }
 
 static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 	unsigned long flags, raw;
 	unsigned long value;
 	int has_wrapped;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
-	value = p->total_cycles;
-	raw = sh_cmt_get_counter(p, &has_wrapped);
+	raw_spin_lock_irqsave(&ch->lock, flags);
+	value = ch->total_cycles;
+	raw = sh_cmt_get_counter(ch, &has_wrapped);
 
 	if (unlikely(has_wrapped))
-		raw += p->match_value + 1;
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+		raw += ch->match_value + 1;
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return value + raw;
 }
@@ -499,50 +510,50 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
 static int sh_cmt_clocksource_enable(struct clocksource *cs)
 {
 	int ret;
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	WARN_ON(p->cs_enabled);
+	WARN_ON(ch->cs_enabled);
 
-	p->total_cycles = 0;
+	ch->total_cycles = 0;
 
-	ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 	if (!ret) {
-		__clocksource_updatefreq_hz(cs, p->rate);
-		p->cs_enabled = true;
+		__clocksource_updatefreq_hz(cs, ch->rate);
+		ch->cs_enabled = true;
 	}
 	return ret;
 }
 
 static void sh_cmt_clocksource_disable(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	WARN_ON(!p->cs_enabled);
+	WARN_ON(!ch->cs_enabled);
 
-	sh_cmt_stop(p, FLAG_CLOCKSOURCE);
-	p->cs_enabled = false;
+	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
+	ch->cs_enabled = false;
 }
 
 static void sh_cmt_clocksource_suspend(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	sh_cmt_stop(p, FLAG_CLOCKSOURCE);
-	pm_genpd_syscore_poweroff(&p->pdev->dev);
+	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
+	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
 }
 
 static void sh_cmt_clocksource_resume(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	pm_genpd_syscore_poweron(&p->pdev->dev);
-	sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
+	sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 }
 
-static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
+static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
 				       char *name, unsigned long rating)
 {
-	struct clocksource *cs = &p->cs;
+	struct clocksource *cs = &ch->cs;
 
 	cs->name = name;
 	cs->rating = rating;
@@ -554,47 +565,47 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	dev_info(&p->pdev->dev, "used as clock source\n");
+	dev_info(&ch->cmt->pdev->dev, "used as clock source\n");
 
 	/* Register with dummy 1 Hz value, gets updated in ->enable() */
 	clocksource_register_hz(cs, 1);
 	return 0;
 }
 
-static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
 {
-	return container_of(ced, struct sh_cmt_priv, ced);
+	return container_of(ced, struct sh_cmt_channel, ced);
 }
 
-static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
 {
-	struct clock_event_device *ced = &p->ced;
+	struct clock_event_device *ced = &ch->ced;
 
-	sh_cmt_start(p, FLAG_CLOCKEVENT);
+	sh_cmt_start(ch, FLAG_CLOCKEVENT);
 
 	/* TODO: calculate good shift from rate and counter bit width */
 
 	ced->shift = 32;
-	ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
-	ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+	ced->mult = div_sc(ch->rate, NSEC_PER_SEC, ced->shift);
+	ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
 	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
 
 	if (periodic)
-		sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1);
+		sh_cmt_set_next(ch, ((ch->rate + HZ/2) / HZ) - 1);
 	else
-		sh_cmt_set_next(p, p->max_match_value);
+		sh_cmt_set_next(ch, ch->max_match_value);
 }
 
 static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 				    struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
 	/* deal with old setting first */
 	switch (ced->mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 	case CLOCK_EVT_MODE_ONESHOT:
-		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
 		break;
 	default:
 		break;
@@ -602,16 +613,18 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		dev_info(&p->pdev->dev, "used for periodic clock events\n");
-		sh_cmt_clock_event_start(p, 1);
+		dev_info(&ch->cmt->pdev->dev,
+			 "used for periodic clock events\n");
+		sh_cmt_clock_event_start(ch, 1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
-		dev_info(&p->pdev->dev, "used for oneshot clock events\n");
-		sh_cmt_clock_event_start(p, 0);
+		dev_info(&ch->cmt->pdev->dev,
+			 "used for oneshot clock events\n");
+		sh_cmt_clock_event_start(ch, 0);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
-		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
 		break;
 	default:
 		break;
@@ -621,37 +634,37 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 static int sh_cmt_clock_event_next(unsigned long delta,
 				   struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
 	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
-	if (likely(p->flags & FLAG_IRQCONTEXT))
-		p->next_match_value = delta - 1;
+	if (likely(ch->flags & FLAG_IRQCONTEXT))
+		ch->next_match_value = delta - 1;
 	else
-		sh_cmt_set_next(p, delta - 1);
+		sh_cmt_set_next(ch, delta - 1);
 
 	return 0;
 }
 
 static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
-	pm_genpd_syscore_poweroff(&p->pdev->dev);
-	clk_unprepare(p->clk);
+	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
+	clk_unprepare(ch->cmt->clk);
 }
 
 static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
-	clk_prepare(p->clk);
-	pm_genpd_syscore_poweron(&p->pdev->dev);
+	clk_prepare(ch->cmt->clk);
+	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
 }
 
-static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 				       char *name, unsigned long rating)
 {
-	struct clock_event_device *ced = &p->ced;
+	struct clock_event_device *ced = &ch->ced;
 
 	memset(ced, 0, sizeof(*ced));
 
@@ -665,19 +678,19 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
 	ced->suspend = sh_cmt_clock_event_suspend;
 	ced->resume = sh_cmt_clock_event_resume;
 
-	dev_info(&p->pdev->dev, "used for clock events\n");
+	dev_info(&ch->cmt->pdev->dev, "used for clock events\n");
 	clockevents_register_device(ced);
 }
 
-static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
 	if (clockevent_rating)
-		sh_cmt_register_clockevent(p, name, clockevent_rating);
+		sh_cmt_register_clockevent(ch, name, clockevent_rating);
 
 	if (clocksource_rating)
-		sh_cmt_register_clocksource(p, name, clocksource_rating);
+		sh_cmt_register_clocksource(ch, name, clocksource_rating);
 
 	return 0;
 }
@@ -685,6 +698,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
 static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
+	struct sh_cmt_channel *ch = &p->channel;
 	struct resource *res, *res2;
 	int irq, ret;
 	ret = -ENXIO;
@@ -729,10 +743,10 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 	}
 
 	/* request irq using setup_irq() (too early for request_irq()) */
-	p->irqaction.name = dev_name(&p->pdev->dev);
-	p->irqaction.handler = sh_cmt_interrupt;
-	p->irqaction.dev_id = p;
-	p->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
+	ch->irqaction.name = dev_name(&p->pdev->dev);
+	ch->irqaction.handler = sh_cmt_interrupt;
+	ch->irqaction.dev_id = ch;
+	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
 	/* get hold of clock */
 	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
@@ -769,24 +783,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 		p->clear_bits = ~0xc000;
 	}
 
-	if (p->width == (sizeof(p->max_match_value) * 8))
-		p->max_match_value = ~0;
+	if (p->width == (sizeof(ch->max_match_value) * 8))
+		ch->max_match_value = ~0;
 	else
-		p->max_match_value = (1 << p->width) - 1;
+		ch->max_match_value = (1 << p->width) - 1;
 
-	p->match_value = p->max_match_value;
-	raw_spin_lock_init(&p->lock);
+	ch->cmt = p;
+	ch->match_value = ch->max_match_value;
+	raw_spin_lock_init(&ch->lock);
 
-	ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
+	ret = sh_cmt_register(ch, (char *)dev_name(&p->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&p->pdev->dev, "registration failed\n");
 		goto err4;
 	}
-	p->cs_enabled = false;
+	ch->cs_enabled = false;
 
-	ret = setup_irq(irq, &p->irqaction);
+	ret = setup_irq(irq, &ch->irqaction);
 	if (ret) {
 		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
 		goto err4;
-- 
1.8.3.2


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

* [PATCH 01/27] clocksource: sh_cmt: Split channel fields from sh_cmt_priv
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Create a new sh_cmt_channel structure to hold the channel-specific
field in preparation for multiple channels per device support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 393 ++++++++++++++++++++++---------------------
 1 file changed, 204 insertions(+), 189 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 0b1836a..12ccd11 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -35,15 +35,12 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
-struct sh_cmt_priv {
-	void __iomem *mapbase;
-	void __iomem *mapbase_str;
-	struct clk *clk;
-	unsigned long width; /* 16 or 32 bit version of hardware block */
-	unsigned long overflow_bit;
-	unsigned long clear_bits;
+struct sh_cmt_priv;
+
+struct sh_cmt_channel {
+	struct sh_cmt_priv *cmt;
+
 	struct irqaction irqaction;
-	struct platform_device *pdev;
 
 	unsigned long flags;
 	unsigned long match_value;
@@ -55,6 +52,20 @@ struct sh_cmt_priv {
 	struct clocksource cs;
 	unsigned long total_cycles;
 	bool cs_enabled;
+};
+
+struct sh_cmt_priv {
+	struct platform_device *pdev;
+
+	void __iomem *mapbase;
+	void __iomem *mapbase_str;
+	struct clk *clk;
+
+	struct sh_cmt_channel channel;
+
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
 
 	/* callbacks for CMSTR and CMCSR access */
 	unsigned long (*read_control)(void __iomem *base, unsigned long offs);
@@ -114,60 +125,60 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
-static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return p->read_control(p->mapbase_str, 0);
+	return ch->cmt->read_control(ch->cmt->mapbase_str, 0);
 }
 
-static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return p->read_control(p->mapbase, CMCSR);
+	return ch->cmt->read_control(ch->cmt->mapbase, CMCSR);
 }
 
-static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return p->read_count(p->mapbase, CMCNT);
+	return ch->cmt->read_count(ch->cmt->mapbase, CMCNT);
 }
 
-static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_control(p->mapbase_str, 0, value);
+	ch->cmt->write_control(ch->cmt->mapbase_str, 0, value);
 }
 
-static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_control(p->mapbase, CMCSR, value);
+	ch->cmt->write_control(ch->cmt->mapbase, CMCSR, value);
 }
 
-static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_count(p->mapbase, CMCNT, value);
+	ch->cmt->write_count(ch->cmt->mapbase, CMCNT, value);
 }
 
-static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
+static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	p->write_count(p->mapbase, CMCOR, value);
+	ch->cmt->write_count(ch->cmt->mapbase, CMCOR, value);
 }
 
-static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 					int *has_wrapped)
 {
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
 		o2 = o1;
-		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;
+		v1 = sh_cmt_read_cmcnt(ch);
+		v2 = sh_cmt_read_cmcnt(ch);
+		v3 = sh_cmt_read_cmcnt(ch);
+		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -177,52 +188,52 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
 
 static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
-static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 {
-	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+	struct sh_timer_config *cfg = ch->cmt->pdev->dev.platform_data;
 	unsigned long flags, value;
 
 	/* start stop register shared by multiple timer channels */
 	raw_spin_lock_irqsave(&sh_cmt_lock, flags);
-	value = sh_cmt_read_cmstr(p);
+	value = sh_cmt_read_cmstr(ch);
 
 	if (start)
 		value |= 1 << cfg->timer_bit;
 	else
 		value &= ~(1 << cfg->timer_bit);
 
-	sh_cmt_write_cmstr(p, value);
+	sh_cmt_write_cmstr(ch, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
 }
 
-static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 {
 	int k, ret;
 
-	pm_runtime_get_sync(&p->pdev->dev);
-	dev_pm_syscore_device(&p->pdev->dev, true);
+	pm_runtime_get_sync(&ch->cmt->pdev->dev);
+	dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
 
 	/* enable clock */
-	ret = clk_enable(p->clk);
+	ret = clk_enable(ch->cmt->clk);
 	if (ret) {
-		dev_err(&p->pdev->dev, "cannot enable clock\n");
+		dev_err(&ch->cmt->pdev->dev, "cannot enable clock\n");
 		goto err0;
 	}
 
 	/* make sure channel is disabled */
-	sh_cmt_start_stop_ch(p, 0);
+	sh_cmt_start_stop_ch(ch, 0);
 
 	/* configure channel, periodic mode and maximum timeout */
-	if (p->width == 16) {
-		*rate = clk_get_rate(p->clk) / 512;
-		sh_cmt_write_cmcsr(p, 0x43);
+	if (ch->cmt->width == 16) {
+		*rate = clk_get_rate(ch->cmt->clk) / 512;
+		sh_cmt_write_cmcsr(ch, 0x43);
 	} else {
-		*rate = clk_get_rate(p->clk) / 8;
-		sh_cmt_write_cmcsr(p, 0x01a4);
+		*rate = clk_get_rate(ch->cmt->clk) / 8;
+		sh_cmt_write_cmcsr(ch, 0x01a4);
 	}
 
-	sh_cmt_write_cmcor(p, 0xffffffff);
-	sh_cmt_write_cmcnt(p, 0);
+	sh_cmt_write_cmcor(ch, 0xffffffff);
+	sh_cmt_write_cmcnt(ch, 0);
 
 	/*
 	 * According to the sh73a0 user's manual, as CMCNT can be operated
@@ -236,41 +247,41 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
 	 * take RCLKx2 at maximum.
 	 */
 	for (k = 0; k < 100; k++) {
-		if (!sh_cmt_read_cmcnt(p))
+		if (!sh_cmt_read_cmcnt(ch))
 			break;
 		udelay(1);
 	}
 
-	if (sh_cmt_read_cmcnt(p)) {
-		dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
+	if (sh_cmt_read_cmcnt(ch)) {
+		dev_err(&ch->cmt->pdev->dev, "cannot clear CMCNT\n");
 		ret = -ETIMEDOUT;
 		goto err1;
 	}
 
 	/* enable channel */
-	sh_cmt_start_stop_ch(p, 1);
+	sh_cmt_start_stop_ch(ch, 1);
 	return 0;
  err1:
 	/* stop clock */
-	clk_disable(p->clk);
+	clk_disable(ch->cmt->clk);
 
  err0:
 	return ret;
 }
 
-static void sh_cmt_disable(struct sh_cmt_priv *p)
+static void sh_cmt_disable(struct sh_cmt_channel *ch)
 {
 	/* disable channel */
-	sh_cmt_start_stop_ch(p, 0);
+	sh_cmt_start_stop_ch(ch, 0);
 
 	/* disable interrupts in CMT block */
-	sh_cmt_write_cmcsr(p, 0);
+	sh_cmt_write_cmcsr(ch, 0);
 
 	/* stop clock */
-	clk_disable(p->clk);
+	clk_disable(ch->cmt->clk);
 
-	dev_pm_syscore_device(&p->pdev->dev, false);
-	pm_runtime_put(&p->pdev->dev);
+	dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
+	pm_runtime_put(&ch->cmt->pdev->dev);
 }
 
 /* private flags */
@@ -280,24 +291,24 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
 #define FLAG_SKIPEVENT (1 << 3)
 #define FLAG_IRQCONTEXT (1 << 4)
 
-static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 					      int absolute)
 {
 	unsigned long new_match;
-	unsigned long value = p->next_match_value;
+	unsigned long value = ch->next_match_value;
 	unsigned long delay = 0;
 	unsigned long now = 0;
 	int has_wrapped;
 
-	now = sh_cmt_get_counter(p, &has_wrapped);
-	p->flags |= FLAG_REPROGRAM; /* force reprogram */
+	now = sh_cmt_get_counter(ch, &has_wrapped);
+	ch->flags |= FLAG_REPROGRAM; /* force reprogram */
 
 	if (has_wrapped) {
 		/* we're competing with the interrupt handler.
 		 *  -> let the interrupt handler reprogram the timer.
 		 *  -> interrupt number two handles the event.
 		 */
-		p->flags |= FLAG_SKIPEVENT;
+		ch->flags |= FLAG_SKIPEVENT;
 		return;
 	}
 
@@ -309,20 +320,20 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 		 * but don't save the new match value yet.
 		 */
 		new_match = now + value + delay;
-		if (new_match > p->max_match_value)
-			new_match = p->max_match_value;
+		if (new_match > ch->max_match_value)
+			new_match = ch->max_match_value;
 
-		sh_cmt_write_cmcor(p, new_match);
+		sh_cmt_write_cmcor(ch, new_match);
 
-		now = sh_cmt_get_counter(p, &has_wrapped);
-		if (has_wrapped && (new_match > p->match_value)) {
+		now = sh_cmt_get_counter(ch, &has_wrapped);
+		if (has_wrapped && (new_match > ch->match_value)) {
 			/* we are changing to a greater match value,
 			 * so this wrap must be caused by the counter
 			 * matching the old value.
 			 * -> first interrupt reprograms the timer.
 			 * -> interrupt number two handles the event.
 			 */
-			p->flags |= FLAG_SKIPEVENT;
+			ch->flags |= FLAG_SKIPEVENT;
 			break;
 		}
 
@@ -333,7 +344,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			 * -> save programmed match value.
 			 * -> let isr handle the event.
 			 */
-			p->match_value = new_match;
+			ch->match_value = new_match;
 			break;
 		}
 
@@ -344,7 +355,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			 * -> save programmed match value.
 			 * -> let isr handle the event.
 			 */
-			p->match_value = new_match;
+			ch->match_value = new_match;
 			break;
 		}
 
@@ -360,138 +371,138 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
 			delay = 1;
 
 		if (!delay)
-			dev_warn(&p->pdev->dev, "too long delay\n");
+			dev_warn(&ch->cmt->pdev->dev, "too long delay\n");
 
 	} while (delay);
 }
 
-static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
-	if (delta > p->max_match_value)
-		dev_warn(&p->pdev->dev, "delta out of range\n");
+	if (delta > ch->max_match_value)
+		dev_warn(&ch->cmt->pdev->dev, "delta out of range\n");
 
-	p->next_match_value = delta;
-	sh_cmt_clock_event_program_verify(p, 0);
+	ch->next_match_value = delta;
+	sh_cmt_clock_event_program_verify(ch, 0);
 }
 
-static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
-	__sh_cmt_set_next(p, delta);
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
+	__sh_cmt_set_next(ch, delta);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 }
 
 static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 {
-	struct sh_cmt_priv *p = dev_id;
+	struct sh_cmt_channel *ch = dev_id;
 
 	/* clear flags */
-	sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits);
+	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific
 	 * isr before we end up here.
 	 */
-	if (p->flags & FLAG_CLOCKSOURCE)
-		p->total_cycles += p->match_value + 1;
+	if (ch->flags & FLAG_CLOCKSOURCE)
+		ch->total_cycles += ch->match_value + 1;
 
-	if (!(p->flags & FLAG_REPROGRAM))
-		p->next_match_value = p->max_match_value;
+	if (!(ch->flags & FLAG_REPROGRAM))
+		ch->next_match_value = ch->max_match_value;
 
-	p->flags |= FLAG_IRQCONTEXT;
+	ch->flags |= FLAG_IRQCONTEXT;
 
-	if (p->flags & FLAG_CLOCKEVENT) {
-		if (!(p->flags & FLAG_SKIPEVENT)) {
-			if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
-				p->next_match_value = p->max_match_value;
-				p->flags |= FLAG_REPROGRAM;
+	if (ch->flags & FLAG_CLOCKEVENT) {
+		if (!(ch->flags & FLAG_SKIPEVENT)) {
+			if (ch->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+				ch->next_match_value = ch->max_match_value;
+				ch->flags |= FLAG_REPROGRAM;
 			}
 
-			p->ced.event_handler(&p->ced);
+			ch->ced.event_handler(&ch->ced);
 		}
 	}
 
-	p->flags &= ~FLAG_SKIPEVENT;
+	ch->flags &= ~FLAG_SKIPEVENT;
 
-	if (p->flags & FLAG_REPROGRAM) {
-		p->flags &= ~FLAG_REPROGRAM;
-		sh_cmt_clock_event_program_verify(p, 1);
+	if (ch->flags & FLAG_REPROGRAM) {
+		ch->flags &= ~FLAG_REPROGRAM;
+		sh_cmt_clock_event_program_verify(ch, 1);
 
-		if (p->flags & FLAG_CLOCKEVENT)
-			if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
-			    || (p->match_value == p->next_match_value))
-				p->flags &= ~FLAG_REPROGRAM;
+		if (ch->flags & FLAG_CLOCKEVENT)
+			if ((ch->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
+			    || (ch->match_value == ch->next_match_value))
+				ch->flags &= ~FLAG_REPROGRAM;
 	}
 
-	p->flags &= ~FLAG_IRQCONTEXT;
+	ch->flags &= ~FLAG_IRQCONTEXT;
 
 	return IRQ_HANDLED;
 }
 
-static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
 {
 	int ret = 0;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
 
-	if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
-		ret = sh_cmt_enable(p, &p->rate);
+	if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		ret = sh_cmt_enable(ch, &ch->rate);
 
 	if (ret)
 		goto out;
-	p->flags |= flag;
+	ch->flags |= flag;
 
 	/* setup timeout if no clockevent */
-	if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
-		__sh_cmt_set_next(p, p->max_match_value);
+	if ((flag == FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT)))
+		__sh_cmt_set_next(ch, ch->max_match_value);
  out:
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return ret;
 }
 
-static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag)
 {
 	unsigned long flags;
 	unsigned long f;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
+	raw_spin_lock_irqsave(&ch->lock, flags);
 
-	f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
-	p->flags &= ~flag;
+	f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+	ch->flags &= ~flag;
 
-	if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
-		sh_cmt_disable(p);
+	if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		sh_cmt_disable(ch);
 
 	/* adjust the timeout to maximum if only clocksource left */
-	if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
-		__sh_cmt_set_next(p, p->max_match_value);
+	if ((flag == FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE))
+		__sh_cmt_set_next(ch, ch->max_match_value);
 
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 }
 
-static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs)
+static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
 {
-	return container_of(cs, struct sh_cmt_priv, cs);
+	return container_of(cs, struct sh_cmt_channel, cs);
 }
 
 static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 	unsigned long flags, raw;
 	unsigned long value;
 	int has_wrapped;
 
-	raw_spin_lock_irqsave(&p->lock, flags);
-	value = p->total_cycles;
-	raw = sh_cmt_get_counter(p, &has_wrapped);
+	raw_spin_lock_irqsave(&ch->lock, flags);
+	value = ch->total_cycles;
+	raw = sh_cmt_get_counter(ch, &has_wrapped);
 
 	if (unlikely(has_wrapped))
-		raw += p->match_value + 1;
-	raw_spin_unlock_irqrestore(&p->lock, flags);
+		raw += ch->match_value + 1;
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return value + raw;
 }
@@ -499,50 +510,50 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
 static int sh_cmt_clocksource_enable(struct clocksource *cs)
 {
 	int ret;
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	WARN_ON(p->cs_enabled);
+	WARN_ON(ch->cs_enabled);
 
-	p->total_cycles = 0;
+	ch->total_cycles = 0;
 
-	ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 	if (!ret) {
-		__clocksource_updatefreq_hz(cs, p->rate);
-		p->cs_enabled = true;
+		__clocksource_updatefreq_hz(cs, ch->rate);
+		ch->cs_enabled = true;
 	}
 	return ret;
 }
 
 static void sh_cmt_clocksource_disable(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	WARN_ON(!p->cs_enabled);
+	WARN_ON(!ch->cs_enabled);
 
-	sh_cmt_stop(p, FLAG_CLOCKSOURCE);
-	p->cs_enabled = false;
+	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
+	ch->cs_enabled = false;
 }
 
 static void sh_cmt_clocksource_suspend(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	sh_cmt_stop(p, FLAG_CLOCKSOURCE);
-	pm_genpd_syscore_poweroff(&p->pdev->dev);
+	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
+	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
 }
 
 static void sh_cmt_clocksource_resume(struct clocksource *cs)
 {
-	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
-	pm_genpd_syscore_poweron(&p->pdev->dev);
-	sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
+	sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 }
 
-static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
+static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
 				       char *name, unsigned long rating)
 {
-	struct clocksource *cs = &p->cs;
+	struct clocksource *cs = &ch->cs;
 
 	cs->name = name;
 	cs->rating = rating;
@@ -554,47 +565,47 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	dev_info(&p->pdev->dev, "used as clock source\n");
+	dev_info(&ch->cmt->pdev->dev, "used as clock source\n");
 
 	/* Register with dummy 1 Hz value, gets updated in ->enable() */
 	clocksource_register_hz(cs, 1);
 	return 0;
 }
 
-static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
 {
-	return container_of(ced, struct sh_cmt_priv, ced);
+	return container_of(ced, struct sh_cmt_channel, ced);
 }
 
-static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
 {
-	struct clock_event_device *ced = &p->ced;
+	struct clock_event_device *ced = &ch->ced;
 
-	sh_cmt_start(p, FLAG_CLOCKEVENT);
+	sh_cmt_start(ch, FLAG_CLOCKEVENT);
 
 	/* TODO: calculate good shift from rate and counter bit width */
 
 	ced->shift = 32;
-	ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
-	ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+	ced->mult = div_sc(ch->rate, NSEC_PER_SEC, ced->shift);
+	ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
 	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
 
 	if (periodic)
-		sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1);
+		sh_cmt_set_next(ch, ((ch->rate + HZ/2) / HZ) - 1);
 	else
-		sh_cmt_set_next(p, p->max_match_value);
+		sh_cmt_set_next(ch, ch->max_match_value);
 }
 
 static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 				    struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
 	/* deal with old setting first */
 	switch (ced->mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 	case CLOCK_EVT_MODE_ONESHOT:
-		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
 		break;
 	default:
 		break;
@@ -602,16 +613,18 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		dev_info(&p->pdev->dev, "used for periodic clock events\n");
-		sh_cmt_clock_event_start(p, 1);
+		dev_info(&ch->cmt->pdev->dev,
+			 "used for periodic clock events\n");
+		sh_cmt_clock_event_start(ch, 1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
-		dev_info(&p->pdev->dev, "used for oneshot clock events\n");
-		sh_cmt_clock_event_start(p, 0);
+		dev_info(&ch->cmt->pdev->dev,
+			 "used for oneshot clock events\n");
+		sh_cmt_clock_event_start(ch, 0);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
-		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
 		break;
 	default:
 		break;
@@ -621,37 +634,37 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 static int sh_cmt_clock_event_next(unsigned long delta,
 				   struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
 	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
-	if (likely(p->flags & FLAG_IRQCONTEXT))
-		p->next_match_value = delta - 1;
+	if (likely(ch->flags & FLAG_IRQCONTEXT))
+		ch->next_match_value = delta - 1;
 	else
-		sh_cmt_set_next(p, delta - 1);
+		sh_cmt_set_next(ch, delta - 1);
 
 	return 0;
 }
 
 static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
-	pm_genpd_syscore_poweroff(&p->pdev->dev);
-	clk_unprepare(p->clk);
+	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
+	clk_unprepare(ch->cmt->clk);
 }
 
 static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
 {
-	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
 
-	clk_prepare(p->clk);
-	pm_genpd_syscore_poweron(&p->pdev->dev);
+	clk_prepare(ch->cmt->clk);
+	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
 }
 
-static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 				       char *name, unsigned long rating)
 {
-	struct clock_event_device *ced = &p->ced;
+	struct clock_event_device *ced = &ch->ced;
 
 	memset(ced, 0, sizeof(*ced));
 
@@ -665,19 +678,19 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
 	ced->suspend = sh_cmt_clock_event_suspend;
 	ced->resume = sh_cmt_clock_event_resume;
 
-	dev_info(&p->pdev->dev, "used for clock events\n");
+	dev_info(&ch->cmt->pdev->dev, "used for clock events\n");
 	clockevents_register_device(ced);
 }
 
-static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
 	if (clockevent_rating)
-		sh_cmt_register_clockevent(p, name, clockevent_rating);
+		sh_cmt_register_clockevent(ch, name, clockevent_rating);
 
 	if (clocksource_rating)
-		sh_cmt_register_clocksource(p, name, clocksource_rating);
+		sh_cmt_register_clocksource(ch, name, clocksource_rating);
 
 	return 0;
 }
@@ -685,6 +698,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
 static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
+	struct sh_cmt_channel *ch = &p->channel;
 	struct resource *res, *res2;
 	int irq, ret;
 	ret = -ENXIO;
@@ -729,10 +743,10 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 	}
 
 	/* request irq using setup_irq() (too early for request_irq()) */
-	p->irqaction.name = dev_name(&p->pdev->dev);
-	p->irqaction.handler = sh_cmt_interrupt;
-	p->irqaction.dev_id = p;
-	p->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
+	ch->irqaction.name = dev_name(&p->pdev->dev);
+	ch->irqaction.handler = sh_cmt_interrupt;
+	ch->irqaction.dev_id = ch;
+	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
 	/* get hold of clock */
 	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
@@ -769,24 +783,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
 		p->clear_bits = ~0xc000;
 	}
 
-	if (p->width == (sizeof(p->max_match_value) * 8))
-		p->max_match_value = ~0;
+	if (p->width == (sizeof(ch->max_match_value) * 8))
+		ch->max_match_value = ~0;
 	else
-		p->max_match_value = (1 << p->width) - 1;
+		ch->max_match_value = (1 << p->width) - 1;
 
-	p->match_value = p->max_match_value;
-	raw_spin_lock_init(&p->lock);
+	ch->cmt = p;
+	ch->match_value = ch->max_match_value;
+	raw_spin_lock_init(&ch->lock);
 
-	ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
+	ret = sh_cmt_register(ch, (char *)dev_name(&p->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&p->pdev->dev, "registration failed\n");
 		goto err4;
 	}
-	p->cs_enabled = false;
+	ch->cs_enabled = false;
 
-	ret = setup_irq(irq, &p->irqaction);
+	ret = setup_irq(irq, &ch->irqaction);
 	if (ret) {
 		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
 		goto err4;
-- 
1.8.3.2

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

* [PATCH 02/27] clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Channel data is private as well, rename priv to device to make the
distrinction between the core device and the channels clearer.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 116 +++++++++++++++++++++----------------------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 12ccd11..68cca0a 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -35,10 +35,10 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
-struct sh_cmt_priv;
+struct sh_cmt_device;
 
 struct sh_cmt_channel {
-	struct sh_cmt_priv *cmt;
+	struct sh_cmt_device *cmt;
 
 	struct irqaction irqaction;
 
@@ -54,7 +54,7 @@ struct sh_cmt_channel {
 	bool cs_enabled;
 };
 
-struct sh_cmt_priv {
+struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	void __iomem *mapbase;
@@ -695,136 +695,136 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct sh_cmt_channel *ch = &p->channel;
+	struct sh_cmt_channel *ch = &cmt->channel;
 	struct resource *res, *res2;
 	int irq, ret;
 	ret = -ENXIO;
 
-	memset(p, 0, sizeof(*p));
-	p->pdev = pdev;
+	memset(cmt, 0, sizeof(*cmt));
+	cmt->pdev = pdev;
 
 	if (!cfg) {
-		dev_err(&p->pdev->dev, "missing platform data\n");
+		dev_err(&cmt->pdev->dev, "missing platform data\n");
 		goto err0;
 	}
 
-	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
 		goto err0;
 	}
 
 	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(p->pdev, IORESOURCE_MEM, 1);
+	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	irq = platform_get_irq(p->pdev, 0);
+	irq = platform_get_irq(cmt->pdev, 0);
 	if (irq < 0) {
-		dev_err(&p->pdev->dev, "failed to get irq\n");
+		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		goto err0;
 	}
 
 	/* map memory, let mapbase point to our channel */
-	p->mapbase = ioremap_nocache(res->start, resource_size(res));
-	if (p->mapbase = NULL) {
-		dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
+	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
+	if (cmt->mapbase = NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
 		goto err0;
 	}
 
 	/* map second resource for CMSTR */
-	p->mapbase_str = ioremap_nocache(res2 ? res2->start :
-					 res->start - cfg->channel_offset,
-					 res2 ? resource_size(res2) : 2);
-	if (p->mapbase_str = NULL) {
-		dev_err(&p->pdev->dev, "failed to remap I/O second memory\n");
+	cmt->mapbase_str = ioremap_nocache(res2 ? res2->start :
+					   res->start - cfg->channel_offset,
+					   res2 ? resource_size(res2) : 2);
+	if (cmt->mapbase_str = NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
 		goto err1;
 	}
 
 	/* request irq using setup_irq() (too early for request_irq()) */
-	ch->irqaction.name = dev_name(&p->pdev->dev);
+	ch->irqaction.name = dev_name(&cmt->pdev->dev);
 	ch->irqaction.handler = sh_cmt_interrupt;
 	ch->irqaction.dev_id = ch;
 	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
 	/* get hold of clock */
-	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
-	if (IS_ERR(p->clk)) {
-		dev_err(&p->pdev->dev, "cannot get clock\n");
-		ret = PTR_ERR(p->clk);
+	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
+	if (IS_ERR(cmt->clk)) {
+		dev_err(&cmt->pdev->dev, "cannot get clock\n");
+		ret = PTR_ERR(cmt->clk);
 		goto err2;
 	}
 
-	ret = clk_prepare(p->clk);
+	ret = clk_prepare(cmt->clk);
 	if (ret < 0)
 		goto err3;
 
 	if (res2 && (resource_size(res2) = 4)) {
 		/* assume both CMSTR and CMCSR to be 32-bit */
-		p->read_control = sh_cmt_read32;
-		p->write_control = sh_cmt_write32;
+		cmt->read_control = sh_cmt_read32;
+		cmt->write_control = sh_cmt_write32;
 	} else {
-		p->read_control = sh_cmt_read16;
-		p->write_control = sh_cmt_write16;
+		cmt->read_control = sh_cmt_read16;
+		cmt->write_control = sh_cmt_write16;
 	}
 
 	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;
+		cmt->width = 16;
+		cmt->read_count = sh_cmt_read16;
+		cmt->write_count = sh_cmt_write16;
+		cmt->overflow_bit = 0x80;
+		cmt->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;
+		cmt->width = 32;
+		cmt->read_count = sh_cmt_read32;
+		cmt->write_count = sh_cmt_write32;
+		cmt->overflow_bit = 0x8000;
+		cmt->clear_bits = ~0xc000;
 	}
 
-	if (p->width = (sizeof(ch->max_match_value) * 8))
+	if (cmt->width = (sizeof(ch->max_match_value) * 8))
 		ch->max_match_value = ~0;
 	else
-		ch->max_match_value = (1 << p->width) - 1;
+		ch->max_match_value = (1 << cmt->width) - 1;
 
-	ch->cmt = p;
+	ch->cmt = cmt;
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
-	ret = sh_cmt_register(ch, (char *)dev_name(&p->pdev->dev),
+	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);
 	if (ret) {
-		dev_err(&p->pdev->dev, "registration failed\n");
+		dev_err(&cmt->pdev->dev, "registration failed\n");
 		goto err4;
 	}
 	ch->cs_enabled = false;
 
 	ret = setup_irq(irq, &ch->irqaction);
 	if (ret) {
-		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
+		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
 		goto err4;
 	}
 
-	platform_set_drvdata(pdev, p);
+	platform_set_drvdata(pdev, cmt);
 
 	return 0;
 err4:
-	clk_unprepare(p->clk);
+	clk_unprepare(cmt->clk);
 err3:
-	clk_put(p->clk);
+	clk_put(cmt->clk);
 err2:
-	iounmap(p->mapbase_str);
+	iounmap(cmt->mapbase_str);
 err1:
-	iounmap(p->mapbase);
+	iounmap(cmt->mapbase);
 err0:
 	return ret;
 }
 
 static int sh_cmt_probe(struct platform_device *pdev)
 {
-	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	int ret;
 
@@ -833,20 +833,20 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		pm_runtime_enable(&pdev->dev);
 	}
 
-	if (p) {
+	if (cmt) {
 		dev_info(&pdev->dev, "kept as earlytimer\n");
 		goto out;
 	}
 
-	p = kmalloc(sizeof(*p), GFP_KERNEL);
-	if (p = NULL) {
+	cmt = kmalloc(sizeof(*cmt), GFP_KERNEL);
+	if (cmt = NULL) {
 		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
 	}
 
-	ret = sh_cmt_setup(p, pdev);
+	ret = sh_cmt_setup(cmt, pdev);
 	if (ret) {
-		kfree(p);
+		kfree(cmt);
 		pm_runtime_idle(&pdev->dev);
 		return ret;
 	}
-- 
1.8.3.2


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

* [PATCH 02/27] clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Channel data is private as well, rename priv to device to make the
distrinction between the core device and the channels clearer.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 116 +++++++++++++++++++++----------------------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 12ccd11..68cca0a 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -35,10 +35,10 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
-struct sh_cmt_priv;
+struct sh_cmt_device;
 
 struct sh_cmt_channel {
-	struct sh_cmt_priv *cmt;
+	struct sh_cmt_device *cmt;
 
 	struct irqaction irqaction;
 
@@ -54,7 +54,7 @@ struct sh_cmt_channel {
 	bool cs_enabled;
 };
 
-struct sh_cmt_priv {
+struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	void __iomem *mapbase;
@@ -695,136 +695,136 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct sh_cmt_channel *ch = &p->channel;
+	struct sh_cmt_channel *ch = &cmt->channel;
 	struct resource *res, *res2;
 	int irq, ret;
 	ret = -ENXIO;
 
-	memset(p, 0, sizeof(*p));
-	p->pdev = pdev;
+	memset(cmt, 0, sizeof(*cmt));
+	cmt->pdev = pdev;
 
 	if (!cfg) {
-		dev_err(&p->pdev->dev, "missing platform data\n");
+		dev_err(&cmt->pdev->dev, "missing platform data\n");
 		goto err0;
 	}
 
-	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
 		goto err0;
 	}
 
 	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(p->pdev, IORESOURCE_MEM, 1);
+	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	irq = platform_get_irq(p->pdev, 0);
+	irq = platform_get_irq(cmt->pdev, 0);
 	if (irq < 0) {
-		dev_err(&p->pdev->dev, "failed to get irq\n");
+		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		goto err0;
 	}
 
 	/* map memory, let mapbase point to our channel */
-	p->mapbase = ioremap_nocache(res->start, resource_size(res));
-	if (p->mapbase == NULL) {
-		dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
+	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
+	if (cmt->mapbase == NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
 		goto err0;
 	}
 
 	/* map second resource for CMSTR */
-	p->mapbase_str = ioremap_nocache(res2 ? res2->start :
-					 res->start - cfg->channel_offset,
-					 res2 ? resource_size(res2) : 2);
-	if (p->mapbase_str == NULL) {
-		dev_err(&p->pdev->dev, "failed to remap I/O second memory\n");
+	cmt->mapbase_str = ioremap_nocache(res2 ? res2->start :
+					   res->start - cfg->channel_offset,
+					   res2 ? resource_size(res2) : 2);
+	if (cmt->mapbase_str == NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
 		goto err1;
 	}
 
 	/* request irq using setup_irq() (too early for request_irq()) */
-	ch->irqaction.name = dev_name(&p->pdev->dev);
+	ch->irqaction.name = dev_name(&cmt->pdev->dev);
 	ch->irqaction.handler = sh_cmt_interrupt;
 	ch->irqaction.dev_id = ch;
 	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
 	/* get hold of clock */
-	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
-	if (IS_ERR(p->clk)) {
-		dev_err(&p->pdev->dev, "cannot get clock\n");
-		ret = PTR_ERR(p->clk);
+	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
+	if (IS_ERR(cmt->clk)) {
+		dev_err(&cmt->pdev->dev, "cannot get clock\n");
+		ret = PTR_ERR(cmt->clk);
 		goto err2;
 	}
 
-	ret = clk_prepare(p->clk);
+	ret = clk_prepare(cmt->clk);
 	if (ret < 0)
 		goto err3;
 
 	if (res2 && (resource_size(res2) == 4)) {
 		/* assume both CMSTR and CMCSR to be 32-bit */
-		p->read_control = sh_cmt_read32;
-		p->write_control = sh_cmt_write32;
+		cmt->read_control = sh_cmt_read32;
+		cmt->write_control = sh_cmt_write32;
 	} else {
-		p->read_control = sh_cmt_read16;
-		p->write_control = sh_cmt_write16;
+		cmt->read_control = sh_cmt_read16;
+		cmt->write_control = sh_cmt_write16;
 	}
 
 	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;
+		cmt->width = 16;
+		cmt->read_count = sh_cmt_read16;
+		cmt->write_count = sh_cmt_write16;
+		cmt->overflow_bit = 0x80;
+		cmt->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;
+		cmt->width = 32;
+		cmt->read_count = sh_cmt_read32;
+		cmt->write_count = sh_cmt_write32;
+		cmt->overflow_bit = 0x8000;
+		cmt->clear_bits = ~0xc000;
 	}
 
-	if (p->width == (sizeof(ch->max_match_value) * 8))
+	if (cmt->width == (sizeof(ch->max_match_value) * 8))
 		ch->max_match_value = ~0;
 	else
-		ch->max_match_value = (1 << p->width) - 1;
+		ch->max_match_value = (1 << cmt->width) - 1;
 
-	ch->cmt = p;
+	ch->cmt = cmt;
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
-	ret = sh_cmt_register(ch, (char *)dev_name(&p->pdev->dev),
+	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);
 	if (ret) {
-		dev_err(&p->pdev->dev, "registration failed\n");
+		dev_err(&cmt->pdev->dev, "registration failed\n");
 		goto err4;
 	}
 	ch->cs_enabled = false;
 
 	ret = setup_irq(irq, &ch->irqaction);
 	if (ret) {
-		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
+		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
 		goto err4;
 	}
 
-	platform_set_drvdata(pdev, p);
+	platform_set_drvdata(pdev, cmt);
 
 	return 0;
 err4:
-	clk_unprepare(p->clk);
+	clk_unprepare(cmt->clk);
 err3:
-	clk_put(p->clk);
+	clk_put(cmt->clk);
 err2:
-	iounmap(p->mapbase_str);
+	iounmap(cmt->mapbase_str);
 err1:
-	iounmap(p->mapbase);
+	iounmap(cmt->mapbase);
 err0:
 	return ret;
 }
 
 static int sh_cmt_probe(struct platform_device *pdev)
 {
-	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	int ret;
 
@@ -833,20 +833,20 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		pm_runtime_enable(&pdev->dev);
 	}
 
-	if (p) {
+	if (cmt) {
 		dev_info(&pdev->dev, "kept as earlytimer\n");
 		goto out;
 	}
 
-	p = kmalloc(sizeof(*p), GFP_KERNEL);
-	if (p == NULL) {
+	cmt = kmalloc(sizeof(*cmt), GFP_KERNEL);
+	if (cmt == NULL) {
 		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
 	}
 
-	ret = sh_cmt_setup(p, pdev);
+	ret = sh_cmt_setup(cmt, pdev);
 	if (ret) {
-		kfree(p);
+		kfree(cmt);
 		pm_runtime_idle(&pdev->dev);
 		return ret;
 	}
-- 
1.8.3.2


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

* [PATCH 02/27] clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Channel data is private as well, rename priv to device to make the
distrinction between the core device and the channels clearer.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 116 +++++++++++++++++++++----------------------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 12ccd11..68cca0a 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -35,10 +35,10 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
-struct sh_cmt_priv;
+struct sh_cmt_device;
 
 struct sh_cmt_channel {
-	struct sh_cmt_priv *cmt;
+	struct sh_cmt_device *cmt;
 
 	struct irqaction irqaction;
 
@@ -54,7 +54,7 @@ struct sh_cmt_channel {
 	bool cs_enabled;
 };
 
-struct sh_cmt_priv {
+struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	void __iomem *mapbase;
@@ -695,136 +695,136 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct sh_cmt_channel *ch = &p->channel;
+	struct sh_cmt_channel *ch = &cmt->channel;
 	struct resource *res, *res2;
 	int irq, ret;
 	ret = -ENXIO;
 
-	memset(p, 0, sizeof(*p));
-	p->pdev = pdev;
+	memset(cmt, 0, sizeof(*cmt));
+	cmt->pdev = pdev;
 
 	if (!cfg) {
-		dev_err(&p->pdev->dev, "missing platform data\n");
+		dev_err(&cmt->pdev->dev, "missing platform data\n");
 		goto err0;
 	}
 
-	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
 		goto err0;
 	}
 
 	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(p->pdev, IORESOURCE_MEM, 1);
+	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	irq = platform_get_irq(p->pdev, 0);
+	irq = platform_get_irq(cmt->pdev, 0);
 	if (irq < 0) {
-		dev_err(&p->pdev->dev, "failed to get irq\n");
+		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		goto err0;
 	}
 
 	/* map memory, let mapbase point to our channel */
-	p->mapbase = ioremap_nocache(res->start, resource_size(res));
-	if (p->mapbase == NULL) {
-		dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
+	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
+	if (cmt->mapbase == NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
 		goto err0;
 	}
 
 	/* map second resource for CMSTR */
-	p->mapbase_str = ioremap_nocache(res2 ? res2->start :
-					 res->start - cfg->channel_offset,
-					 res2 ? resource_size(res2) : 2);
-	if (p->mapbase_str == NULL) {
-		dev_err(&p->pdev->dev, "failed to remap I/O second memory\n");
+	cmt->mapbase_str = ioremap_nocache(res2 ? res2->start :
+					   res->start - cfg->channel_offset,
+					   res2 ? resource_size(res2) : 2);
+	if (cmt->mapbase_str == NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
 		goto err1;
 	}
 
 	/* request irq using setup_irq() (too early for request_irq()) */
-	ch->irqaction.name = dev_name(&p->pdev->dev);
+	ch->irqaction.name = dev_name(&cmt->pdev->dev);
 	ch->irqaction.handler = sh_cmt_interrupt;
 	ch->irqaction.dev_id = ch;
 	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
 	/* get hold of clock */
-	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
-	if (IS_ERR(p->clk)) {
-		dev_err(&p->pdev->dev, "cannot get clock\n");
-		ret = PTR_ERR(p->clk);
+	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
+	if (IS_ERR(cmt->clk)) {
+		dev_err(&cmt->pdev->dev, "cannot get clock\n");
+		ret = PTR_ERR(cmt->clk);
 		goto err2;
 	}
 
-	ret = clk_prepare(p->clk);
+	ret = clk_prepare(cmt->clk);
 	if (ret < 0)
 		goto err3;
 
 	if (res2 && (resource_size(res2) == 4)) {
 		/* assume both CMSTR and CMCSR to be 32-bit */
-		p->read_control = sh_cmt_read32;
-		p->write_control = sh_cmt_write32;
+		cmt->read_control = sh_cmt_read32;
+		cmt->write_control = sh_cmt_write32;
 	} else {
-		p->read_control = sh_cmt_read16;
-		p->write_control = sh_cmt_write16;
+		cmt->read_control = sh_cmt_read16;
+		cmt->write_control = sh_cmt_write16;
 	}
 
 	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;
+		cmt->width = 16;
+		cmt->read_count = sh_cmt_read16;
+		cmt->write_count = sh_cmt_write16;
+		cmt->overflow_bit = 0x80;
+		cmt->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;
+		cmt->width = 32;
+		cmt->read_count = sh_cmt_read32;
+		cmt->write_count = sh_cmt_write32;
+		cmt->overflow_bit = 0x8000;
+		cmt->clear_bits = ~0xc000;
 	}
 
-	if (p->width == (sizeof(ch->max_match_value) * 8))
+	if (cmt->width == (sizeof(ch->max_match_value) * 8))
 		ch->max_match_value = ~0;
 	else
-		ch->max_match_value = (1 << p->width) - 1;
+		ch->max_match_value = (1 << cmt->width) - 1;
 
-	ch->cmt = p;
+	ch->cmt = cmt;
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
-	ret = sh_cmt_register(ch, (char *)dev_name(&p->pdev->dev),
+	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
 			      cfg->clockevent_rating,
 			      cfg->clocksource_rating);
 	if (ret) {
-		dev_err(&p->pdev->dev, "registration failed\n");
+		dev_err(&cmt->pdev->dev, "registration failed\n");
 		goto err4;
 	}
 	ch->cs_enabled = false;
 
 	ret = setup_irq(irq, &ch->irqaction);
 	if (ret) {
-		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
+		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
 		goto err4;
 	}
 
-	platform_set_drvdata(pdev, p);
+	platform_set_drvdata(pdev, cmt);
 
 	return 0;
 err4:
-	clk_unprepare(p->clk);
+	clk_unprepare(cmt->clk);
 err3:
-	clk_put(p->clk);
+	clk_put(cmt->clk);
 err2:
-	iounmap(p->mapbase_str);
+	iounmap(cmt->mapbase_str);
 err1:
-	iounmap(p->mapbase);
+	iounmap(cmt->mapbase);
 err0:
 	return ret;
 }
 
 static int sh_cmt_probe(struct platform_device *pdev)
 {
-	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	int ret;
 
@@ -833,20 +833,20 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		pm_runtime_enable(&pdev->dev);
 	}
 
-	if (p) {
+	if (cmt) {
 		dev_info(&pdev->dev, "kept as earlytimer\n");
 		goto out;
 	}
 
-	p = kmalloc(sizeof(*p), GFP_KERNEL);
-	if (p == NULL) {
+	cmt = kmalloc(sizeof(*cmt), GFP_KERNEL);
+	if (cmt == NULL) {
 		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
 	}
 
-	ret = sh_cmt_setup(p, pdev);
+	ret = sh_cmt_setup(cmt, pdev);
 	if (ret) {
-		kfree(p);
+		kfree(cmt);
 		pm_runtime_idle(&pdev->dev);
 		return ret;
 	}
-- 
1.8.3.2

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

* [PATCH 03/27] clocksource: sh_cmt: Split channel setup to separate function
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Move the channel setup code from sh_cmt_setup to a new
sh_cmt_setup_channel function and call it from sh_cmt_setup.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 87 ++++++++++++++++++++++++++------------------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 68cca0a..3a3cc83 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -695,12 +695,59 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
+				struct sh_cmt_device *cmt)
+{
+	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	int irq;
+	int ret;
+
+	memset(ch, 0, sizeof(*ch));
+	ch->cmt = cmt;
+
+	/* Request irq using setup_irq() (too early for request_irq()). */
+	irq = platform_get_irq(cmt->pdev, 0);
+	if (irq < 0) {
+		dev_err(&cmt->pdev->dev, "failed to get irq\n");
+		return irq;
+	}
+
+	ch->irqaction.name = dev_name(&cmt->pdev->dev);
+	ch->irqaction.handler = sh_cmt_interrupt;
+	ch->irqaction.dev_id = ch;
+	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
+
+	if (cmt->width = (sizeof(ch->max_match_value) * 8))
+		ch->max_match_value = ~0;
+	else
+		ch->max_match_value = (1 << cmt->width) - 1;
+
+	ch->match_value = ch->max_match_value;
+	raw_spin_lock_init(&ch->lock);
+
+	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
+			      cfg->clockevent_rating,
+			      cfg->clocksource_rating);
+	if (ret) {
+		dev_err(&cmt->pdev->dev, "registration failed\n");
+		return ret;
+	}
+	ch->cs_enabled = false;
+
+	ret = setup_irq(irq, &ch->irqaction);
+	if (ret) {
+		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct sh_cmt_channel *ch = &cmt->channel;
 	struct resource *res, *res2;
-	int irq, ret;
+	int ret;
 	ret = -ENXIO;
 
 	memset(cmt, 0, sizeof(*cmt));
@@ -720,12 +767,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	/* optional resource for the shared timer start/stop register */
 	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	irq = platform_get_irq(cmt->pdev, 0);
-	if (irq < 0) {
-		dev_err(&cmt->pdev->dev, "failed to get irq\n");
-		goto err0;
-	}
-
 	/* map memory, let mapbase point to our channel */
 	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
 	if (cmt->mapbase = NULL) {
@@ -742,12 +783,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err1;
 	}
 
-	/* request irq using setup_irq() (too early for request_irq()) */
-	ch->irqaction.name = dev_name(&cmt->pdev->dev);
-	ch->irqaction.handler = sh_cmt_interrupt;
-	ch->irqaction.dev_id = ch;
-	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
-
 	/* get hold of clock */
 	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
 	if (IS_ERR(cmt->clk)) {
@@ -783,29 +818,9 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	if (cmt->width = (sizeof(ch->max_match_value) * 8))
-		ch->max_match_value = ~0;
-	else
-		ch->max_match_value = (1 << cmt->width) - 1;
-
-	ch->cmt = cmt;
-	ch->match_value = ch->max_match_value;
-	raw_spin_lock_init(&ch->lock);
-
-	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      cfg->clockevent_rating,
-			      cfg->clocksource_rating);
-	if (ret) {
-		dev_err(&cmt->pdev->dev, "registration failed\n");
-		goto err4;
-	}
-	ch->cs_enabled = false;
-
-	ret = setup_irq(irq, &ch->irqaction);
-	if (ret) {
-		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
+	ret = sh_cmt_setup_channel(&cmt->channel, cmt);
+	if (ret < 0)
 		goto err4;
-	}
 
 	platform_set_drvdata(pdev, cmt);
 
-- 
1.8.3.2


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

* [PATCH 03/27] clocksource: sh_cmt: Split channel setup to separate function
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Move the channel setup code from sh_cmt_setup to a new
sh_cmt_setup_channel function and call it from sh_cmt_setup.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 87 ++++++++++++++++++++++++++------------------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 68cca0a..3a3cc83 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -695,12 +695,59 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
+				struct sh_cmt_device *cmt)
+{
+	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	int irq;
+	int ret;
+
+	memset(ch, 0, sizeof(*ch));
+	ch->cmt = cmt;
+
+	/* Request irq using setup_irq() (too early for request_irq()). */
+	irq = platform_get_irq(cmt->pdev, 0);
+	if (irq < 0) {
+		dev_err(&cmt->pdev->dev, "failed to get irq\n");
+		return irq;
+	}
+
+	ch->irqaction.name = dev_name(&cmt->pdev->dev);
+	ch->irqaction.handler = sh_cmt_interrupt;
+	ch->irqaction.dev_id = ch;
+	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
+
+	if (cmt->width == (sizeof(ch->max_match_value) * 8))
+		ch->max_match_value = ~0;
+	else
+		ch->max_match_value = (1 << cmt->width) - 1;
+
+	ch->match_value = ch->max_match_value;
+	raw_spin_lock_init(&ch->lock);
+
+	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
+			      cfg->clockevent_rating,
+			      cfg->clocksource_rating);
+	if (ret) {
+		dev_err(&cmt->pdev->dev, "registration failed\n");
+		return ret;
+	}
+	ch->cs_enabled = false;
+
+	ret = setup_irq(irq, &ch->irqaction);
+	if (ret) {
+		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct sh_cmt_channel *ch = &cmt->channel;
 	struct resource *res, *res2;
-	int irq, ret;
+	int ret;
 	ret = -ENXIO;
 
 	memset(cmt, 0, sizeof(*cmt));
@@ -720,12 +767,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	/* optional resource for the shared timer start/stop register */
 	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	irq = platform_get_irq(cmt->pdev, 0);
-	if (irq < 0) {
-		dev_err(&cmt->pdev->dev, "failed to get irq\n");
-		goto err0;
-	}
-
 	/* map memory, let mapbase point to our channel */
 	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
 	if (cmt->mapbase == NULL) {
@@ -742,12 +783,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err1;
 	}
 
-	/* request irq using setup_irq() (too early for request_irq()) */
-	ch->irqaction.name = dev_name(&cmt->pdev->dev);
-	ch->irqaction.handler = sh_cmt_interrupt;
-	ch->irqaction.dev_id = ch;
-	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
-
 	/* get hold of clock */
 	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
 	if (IS_ERR(cmt->clk)) {
@@ -783,29 +818,9 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	if (cmt->width == (sizeof(ch->max_match_value) * 8))
-		ch->max_match_value = ~0;
-	else
-		ch->max_match_value = (1 << cmt->width) - 1;
-
-	ch->cmt = cmt;
-	ch->match_value = ch->max_match_value;
-	raw_spin_lock_init(&ch->lock);
-
-	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      cfg->clockevent_rating,
-			      cfg->clocksource_rating);
-	if (ret) {
-		dev_err(&cmt->pdev->dev, "registration failed\n");
-		goto err4;
-	}
-	ch->cs_enabled = false;
-
-	ret = setup_irq(irq, &ch->irqaction);
-	if (ret) {
-		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
+	ret = sh_cmt_setup_channel(&cmt->channel, cmt);
+	if (ret < 0)
 		goto err4;
-	}
 
 	platform_set_drvdata(pdev, cmt);
 
-- 
1.8.3.2


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

* [PATCH 03/27] clocksource: sh_cmt: Split channel setup to separate function
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Move the channel setup code from sh_cmt_setup to a new
sh_cmt_setup_channel function and call it from sh_cmt_setup.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 87 ++++++++++++++++++++++++++------------------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 68cca0a..3a3cc83 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -695,12 +695,59 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
+				struct sh_cmt_device *cmt)
+{
+	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	int irq;
+	int ret;
+
+	memset(ch, 0, sizeof(*ch));
+	ch->cmt = cmt;
+
+	/* Request irq using setup_irq() (too early for request_irq()). */
+	irq = platform_get_irq(cmt->pdev, 0);
+	if (irq < 0) {
+		dev_err(&cmt->pdev->dev, "failed to get irq\n");
+		return irq;
+	}
+
+	ch->irqaction.name = dev_name(&cmt->pdev->dev);
+	ch->irqaction.handler = sh_cmt_interrupt;
+	ch->irqaction.dev_id = ch;
+	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
+
+	if (cmt->width == (sizeof(ch->max_match_value) * 8))
+		ch->max_match_value = ~0;
+	else
+		ch->max_match_value = (1 << cmt->width) - 1;
+
+	ch->match_value = ch->max_match_value;
+	raw_spin_lock_init(&ch->lock);
+
+	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
+			      cfg->clockevent_rating,
+			      cfg->clocksource_rating);
+	if (ret) {
+		dev_err(&cmt->pdev->dev, "registration failed\n");
+		return ret;
+	}
+	ch->cs_enabled = false;
+
+	ret = setup_irq(irq, &ch->irqaction);
+	if (ret) {
+		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct sh_cmt_channel *ch = &cmt->channel;
 	struct resource *res, *res2;
-	int irq, ret;
+	int ret;
 	ret = -ENXIO;
 
 	memset(cmt, 0, sizeof(*cmt));
@@ -720,12 +767,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	/* optional resource for the shared timer start/stop register */
 	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	irq = platform_get_irq(cmt->pdev, 0);
-	if (irq < 0) {
-		dev_err(&cmt->pdev->dev, "failed to get irq\n");
-		goto err0;
-	}
-
 	/* map memory, let mapbase point to our channel */
 	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
 	if (cmt->mapbase == NULL) {
@@ -742,12 +783,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err1;
 	}
 
-	/* request irq using setup_irq() (too early for request_irq()) */
-	ch->irqaction.name = dev_name(&cmt->pdev->dev);
-	ch->irqaction.handler = sh_cmt_interrupt;
-	ch->irqaction.dev_id = ch;
-	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
-
 	/* get hold of clock */
 	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
 	if (IS_ERR(cmt->clk)) {
@@ -783,29 +818,9 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	if (cmt->width == (sizeof(ch->max_match_value) * 8))
-		ch->max_match_value = ~0;
-	else
-		ch->max_match_value = (1 << cmt->width) - 1;
-
-	ch->cmt = cmt;
-	ch->match_value = ch->max_match_value;
-	raw_spin_lock_init(&ch->lock);
-
-	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      cfg->clockevent_rating,
-			      cfg->clocksource_rating);
-	if (ret) {
-		dev_err(&cmt->pdev->dev, "registration failed\n");
-		goto err4;
-	}
-	ch->cs_enabled = false;
-
-	ret = setup_irq(irq, &ch->irqaction);
-	if (ret) {
-		dev_err(&cmt->pdev->dev, "failed to request irq %d\n", irq);
+	ret = sh_cmt_setup_channel(&cmt->channel, cmt);
+	if (ret < 0)
 		goto err4;
-	}
 
 	platform_set_drvdata(pdev, cmt);
 
-- 
1.8.3.2

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

* [PATCH 04/27] clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The mapbase variable points to the mapped base address of the channel,
rename it to mapbase_sh. mapbase_str points to the mapped base address
of the CMT device, rename it to mapbase.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3a3cc83..1ac84ff 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -57,8 +57,8 @@ struct sh_cmt_channel {
 struct sh_cmt_device {
 	struct platform_device *pdev;
 
+	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
-	void __iomem *mapbase_str;
 	struct clk *clk;
 
 	struct sh_cmt_channel channel;
@@ -127,41 +127,41 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase_str, 0);
+	return ch->cmt->read_control(ch->cmt->mapbase, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase, CMCSR);
+	return ch->cmt->read_control(ch->cmt->mapbase_ch, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->cmt->mapbase, CMCNT);
+	return ch->cmt->read_count(ch->cmt->mapbase_ch, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase_str, 0, value);
+	ch->cmt->write_control(ch->cmt->mapbase, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase, CMCSR, value);
+	ch->cmt->write_control(ch->cmt->mapbase_ch, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase, CMCNT, value);
+	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase, CMCOR, value);
+	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -767,18 +767,18 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	/* optional resource for the shared timer start/stop register */
 	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	/* map memory, let mapbase point to our channel */
-	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
-	if (cmt->mapbase = NULL) {
+	/* map memory, let mapbase_ch point to our channel */
+	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
+	if (cmt->mapbase_ch = NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
 		goto err0;
 	}
 
 	/* map second resource for CMSTR */
-	cmt->mapbase_str = ioremap_nocache(res2 ? res2->start :
-					   res->start - cfg->channel_offset,
-					   res2 ? resource_size(res2) : 2);
-	if (cmt->mapbase_str = NULL) {
+	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
+				       res->start - cfg->channel_offset,
+				       res2 ? resource_size(res2) : 2);
+	if (cmt->mapbase = NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
 		goto err1;
 	}
@@ -830,9 +830,9 @@ err4:
 err3:
 	clk_put(cmt->clk);
 err2:
-	iounmap(cmt->mapbase_str);
-err1:
 	iounmap(cmt->mapbase);
+err1:
+	iounmap(cmt->mapbase_ch);
 err0:
 	return ret;
 }
-- 
1.8.3.2


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

* [PATCH 04/27] clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The mapbase variable points to the mapped base address of the channel,
rename it to mapbase_sh. mapbase_str points to the mapped base address
of the CMT device, rename it to mapbase.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3a3cc83..1ac84ff 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -57,8 +57,8 @@ struct sh_cmt_channel {
 struct sh_cmt_device {
 	struct platform_device *pdev;
 
+	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
-	void __iomem *mapbase_str;
 	struct clk *clk;
 
 	struct sh_cmt_channel channel;
@@ -127,41 +127,41 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase_str, 0);
+	return ch->cmt->read_control(ch->cmt->mapbase, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase, CMCSR);
+	return ch->cmt->read_control(ch->cmt->mapbase_ch, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->cmt->mapbase, CMCNT);
+	return ch->cmt->read_count(ch->cmt->mapbase_ch, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase_str, 0, value);
+	ch->cmt->write_control(ch->cmt->mapbase, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase, CMCSR, value);
+	ch->cmt->write_control(ch->cmt->mapbase_ch, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase, CMCNT, value);
+	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase, CMCOR, value);
+	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -767,18 +767,18 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	/* optional resource for the shared timer start/stop register */
 	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	/* map memory, let mapbase point to our channel */
-	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
-	if (cmt->mapbase == NULL) {
+	/* map memory, let mapbase_ch point to our channel */
+	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
+	if (cmt->mapbase_ch == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
 		goto err0;
 	}
 
 	/* map second resource for CMSTR */
-	cmt->mapbase_str = ioremap_nocache(res2 ? res2->start :
-					   res->start - cfg->channel_offset,
-					   res2 ? resource_size(res2) : 2);
-	if (cmt->mapbase_str == NULL) {
+	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
+				       res->start - cfg->channel_offset,
+				       res2 ? resource_size(res2) : 2);
+	if (cmt->mapbase == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
 		goto err1;
 	}
@@ -830,9 +830,9 @@ err4:
 err3:
 	clk_put(cmt->clk);
 err2:
-	iounmap(cmt->mapbase_str);
-err1:
 	iounmap(cmt->mapbase);
+err1:
+	iounmap(cmt->mapbase_ch);
 err0:
 	return ret;
 }
-- 
1.8.3.2


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

* [PATCH 04/27] clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The mapbase variable points to the mapped base address of the channel,
rename it to mapbase_sh. mapbase_str points to the mapped base address
of the CMT device, rename it to mapbase.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3a3cc83..1ac84ff 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -57,8 +57,8 @@ struct sh_cmt_channel {
 struct sh_cmt_device {
 	struct platform_device *pdev;
 
+	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
-	void __iomem *mapbase_str;
 	struct clk *clk;
 
 	struct sh_cmt_channel channel;
@@ -127,41 +127,41 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase_str, 0);
+	return ch->cmt->read_control(ch->cmt->mapbase, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase, CMCSR);
+	return ch->cmt->read_control(ch->cmt->mapbase_ch, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->cmt->mapbase, CMCNT);
+	return ch->cmt->read_count(ch->cmt->mapbase_ch, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase_str, 0, value);
+	ch->cmt->write_control(ch->cmt->mapbase, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase, CMCSR, value);
+	ch->cmt->write_control(ch->cmt->mapbase_ch, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase, CMCNT, value);
+	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase, CMCOR, value);
+	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -767,18 +767,18 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	/* optional resource for the shared timer start/stop register */
 	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
 
-	/* map memory, let mapbase point to our channel */
-	cmt->mapbase = ioremap_nocache(res->start, resource_size(res));
-	if (cmt->mapbase == NULL) {
+	/* map memory, let mapbase_ch point to our channel */
+	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
+	if (cmt->mapbase_ch == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
 		goto err0;
 	}
 
 	/* map second resource for CMSTR */
-	cmt->mapbase_str = ioremap_nocache(res2 ? res2->start :
-					   res->start - cfg->channel_offset,
-					   res2 ? resource_size(res2) : 2);
-	if (cmt->mapbase_str == NULL) {
+	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
+				       res->start - cfg->channel_offset,
+				       res2 ? resource_size(res2) : 2);
+	if (cmt->mapbase == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
 		goto err1;
 	}
@@ -830,9 +830,9 @@ err4:
 err3:
 	clk_put(cmt->clk);
 err2:
-	iounmap(cmt->mapbase_str);
-err1:
 	iounmap(cmt->mapbase);
+err1:
+	iounmap(cmt->mapbase_ch);
 err0:
 	return ret;
 }
-- 
1.8.3.2

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

* [PATCH 05/27] clocksource: sh_cmt: Add memory base to sh_cmt_channel structure
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The channel memory base is channel-specific, add it to the channel
structure in preparation for support of multiple channels per device.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 1ac84ff..ec10cf4 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -40,6 +40,7 @@ struct sh_cmt_device;
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
 
+	void __iomem *base;
 	struct irqaction irqaction;
 
 	unsigned long flags;
@@ -132,12 +133,12 @@ static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase_ch, CMCSR);
+	return ch->cmt->read_control(ch->base, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->cmt->mapbase_ch, CMCNT);
+	return ch->cmt->read_count(ch->base, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
@@ -149,19 +150,19 @@ static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase_ch, CMCSR, value);
+	ch->cmt->write_control(ch->base, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCNT, value);
+	ch->cmt->write_count(ch->base, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCOR, value);
+	ch->cmt->write_count(ch->base, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -704,6 +705,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 
 	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
+	ch->base = cmt->mapbase_ch;
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
 	irq = platform_get_irq(cmt->pdev, 0);
-- 
1.8.3.2


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

* [PATCH 05/27] clocksource: sh_cmt: Add memory base to sh_cmt_channel structure
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The channel memory base is channel-specific, add it to the channel
structure in preparation for support of multiple channels per device.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 1ac84ff..ec10cf4 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -40,6 +40,7 @@ struct sh_cmt_device;
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
 
+	void __iomem *base;
 	struct irqaction irqaction;
 
 	unsigned long flags;
@@ -132,12 +133,12 @@ static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase_ch, CMCSR);
+	return ch->cmt->read_control(ch->base, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->cmt->mapbase_ch, CMCNT);
+	return ch->cmt->read_count(ch->base, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
@@ -149,19 +150,19 @@ static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase_ch, CMCSR, value);
+	ch->cmt->write_control(ch->base, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCNT, value);
+	ch->cmt->write_count(ch->base, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCOR, value);
+	ch->cmt->write_count(ch->base, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -704,6 +705,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 
 	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
+	ch->base = cmt->mapbase_ch;
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
 	irq = platform_get_irq(cmt->pdev, 0);
-- 
1.8.3.2


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

* [PATCH 05/27] clocksource: sh_cmt: Add memory base to sh_cmt_channel structure
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The channel memory base is channel-specific, add it to the channel
structure in preparation for support of multiple channels per device.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 1ac84ff..ec10cf4 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -40,6 +40,7 @@ struct sh_cmt_device;
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
 
+	void __iomem *base;
 	struct irqaction irqaction;
 
 	unsigned long flags;
@@ -132,12 +133,12 @@ static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase_ch, CMCSR);
+	return ch->cmt->read_control(ch->base, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->cmt->mapbase_ch, CMCNT);
+	return ch->cmt->read_count(ch->base, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
@@ -149,19 +150,19 @@ static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase_ch, CMCSR, value);
+	ch->cmt->write_control(ch->base, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCNT, value);
+	ch->cmt->write_count(ch->base, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->cmt->mapbase_ch, CMCOR, value);
+	ch->cmt->write_count(ch->base, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -704,6 +705,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 
 	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
+	ch->base = cmt->mapbase_ch;
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
 	irq = platform_get_irq(cmt->pdev, 0);
-- 
1.8.3.2

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

* [PATCH 06/27] clocksource: sh_cmt: Add index to struct sh_cmt_channel
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Use the index when printing messages to identify the channel.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index ec10cf4..0796460 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -39,6 +39,7 @@ struct sh_cmt_device;
 
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
+	unsigned int index;
 
 	void __iomem *base;
 	struct irqaction irqaction;
@@ -217,7 +218,8 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	/* enable clock */
 	ret = clk_enable(ch->cmt->clk);
 	if (ret) {
-		dev_err(&ch->cmt->pdev->dev, "cannot enable clock\n");
+		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot enable clock\n",
+			ch->index);
 		goto err0;
 	}
 
@@ -254,7 +256,8 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	}
 
 	if (sh_cmt_read_cmcnt(ch)) {
-		dev_err(&ch->cmt->pdev->dev, "cannot clear CMCNT\n");
+		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
+			ch->index);
 		ret = -ETIMEDOUT;
 		goto err1;
 	}
@@ -372,7 +375,8 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 			delay = 1;
 
 		if (!delay)
-			dev_warn(&ch->cmt->pdev->dev, "too long delay\n");
+			dev_warn(&ch->cmt->pdev->dev, "ch%u: too long delay\n",
+				 ch->index);
 
 	} while (delay);
 }
@@ -380,7 +384,8 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
 	if (delta > ch->max_match_value)
-		dev_warn(&ch->cmt->pdev->dev, "delta out of range\n");
+		dev_warn(&ch->cmt->pdev->dev, "ch%u: delta out of range\n",
+			 ch->index);
 
 	ch->next_match_value = delta;
 	sh_cmt_clock_event_program_verify(ch, 0);
@@ -566,7 +571,8 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	dev_info(&ch->cmt->pdev->dev, "used as clock source\n");
+	dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
+		 ch->index);
 
 	/* Register with dummy 1 Hz value, gets updated in ->enable() */
 	clocksource_register_hz(cs, 1);
@@ -615,12 +621,12 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		dev_info(&ch->cmt->pdev->dev,
-			 "used for periodic clock events\n");
+			 "ch%u: used for periodic clock events\n", ch->index);
 		sh_cmt_clock_event_start(ch, 1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		dev_info(&ch->cmt->pdev->dev,
-			 "used for oneshot clock events\n");
+			 "ch%u: used for oneshot clock events\n", ch->index);
 		sh_cmt_clock_event_start(ch, 0);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
@@ -679,7 +685,8 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 	ced->suspend = sh_cmt_clock_event_suspend;
 	ced->resume = sh_cmt_clock_event_resume;
 
-	dev_info(&ch->cmt->pdev->dev, "used for clock events\n");
+	dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
+		 ch->index);
 	clockevents_register_device(ced);
 }
 
@@ -696,7 +703,7 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 				struct sh_cmt_device *cmt)
 {
 	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
@@ -706,6 +713,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
 	ch->base = cmt->mapbase_ch;
+	ch->index = index;
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
 	irq = platform_get_irq(cmt->pdev, 0);
@@ -820,7 +828,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	ret = sh_cmt_setup_channel(&cmt->channel, cmt);
+	ret = sh_cmt_setup_channel(&cmt->channel, cfg->timer_bit, cmt);
 	if (ret < 0)
 		goto err4;
 
-- 
1.8.3.2


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

* [PATCH 06/27] clocksource: sh_cmt: Add index to struct sh_cmt_channel
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Use the index when printing messages to identify the channel.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index ec10cf4..0796460 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -39,6 +39,7 @@ struct sh_cmt_device;
 
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
+	unsigned int index;
 
 	void __iomem *base;
 	struct irqaction irqaction;
@@ -217,7 +218,8 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	/* enable clock */
 	ret = clk_enable(ch->cmt->clk);
 	if (ret) {
-		dev_err(&ch->cmt->pdev->dev, "cannot enable clock\n");
+		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot enable clock\n",
+			ch->index);
 		goto err0;
 	}
 
@@ -254,7 +256,8 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	}
 
 	if (sh_cmt_read_cmcnt(ch)) {
-		dev_err(&ch->cmt->pdev->dev, "cannot clear CMCNT\n");
+		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
+			ch->index);
 		ret = -ETIMEDOUT;
 		goto err1;
 	}
@@ -372,7 +375,8 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 			delay = 1;
 
 		if (!delay)
-			dev_warn(&ch->cmt->pdev->dev, "too long delay\n");
+			dev_warn(&ch->cmt->pdev->dev, "ch%u: too long delay\n",
+				 ch->index);
 
 	} while (delay);
 }
@@ -380,7 +384,8 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
 	if (delta > ch->max_match_value)
-		dev_warn(&ch->cmt->pdev->dev, "delta out of range\n");
+		dev_warn(&ch->cmt->pdev->dev, "ch%u: delta out of range\n",
+			 ch->index);
 
 	ch->next_match_value = delta;
 	sh_cmt_clock_event_program_verify(ch, 0);
@@ -566,7 +571,8 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	dev_info(&ch->cmt->pdev->dev, "used as clock source\n");
+	dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
+		 ch->index);
 
 	/* Register with dummy 1 Hz value, gets updated in ->enable() */
 	clocksource_register_hz(cs, 1);
@@ -615,12 +621,12 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		dev_info(&ch->cmt->pdev->dev,
-			 "used for periodic clock events\n");
+			 "ch%u: used for periodic clock events\n", ch->index);
 		sh_cmt_clock_event_start(ch, 1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		dev_info(&ch->cmt->pdev->dev,
-			 "used for oneshot clock events\n");
+			 "ch%u: used for oneshot clock events\n", ch->index);
 		sh_cmt_clock_event_start(ch, 0);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
@@ -679,7 +685,8 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 	ced->suspend = sh_cmt_clock_event_suspend;
 	ced->resume = sh_cmt_clock_event_resume;
 
-	dev_info(&ch->cmt->pdev->dev, "used for clock events\n");
+	dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
+		 ch->index);
 	clockevents_register_device(ced);
 }
 
@@ -696,7 +703,7 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 				struct sh_cmt_device *cmt)
 {
 	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
@@ -706,6 +713,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
 	ch->base = cmt->mapbase_ch;
+	ch->index = index;
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
 	irq = platform_get_irq(cmt->pdev, 0);
@@ -820,7 +828,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	ret = sh_cmt_setup_channel(&cmt->channel, cmt);
+	ret = sh_cmt_setup_channel(&cmt->channel, cfg->timer_bit, cmt);
 	if (ret < 0)
 		goto err4;
 
-- 
1.8.3.2


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

* [PATCH 06/27] clocksource: sh_cmt: Add index to struct sh_cmt_channel
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Use the index when printing messages to identify the channel.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index ec10cf4..0796460 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -39,6 +39,7 @@ struct sh_cmt_device;
 
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
+	unsigned int index;
 
 	void __iomem *base;
 	struct irqaction irqaction;
@@ -217,7 +218,8 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	/* enable clock */
 	ret = clk_enable(ch->cmt->clk);
 	if (ret) {
-		dev_err(&ch->cmt->pdev->dev, "cannot enable clock\n");
+		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot enable clock\n",
+			ch->index);
 		goto err0;
 	}
 
@@ -254,7 +256,8 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	}
 
 	if (sh_cmt_read_cmcnt(ch)) {
-		dev_err(&ch->cmt->pdev->dev, "cannot clear CMCNT\n");
+		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
+			ch->index);
 		ret = -ETIMEDOUT;
 		goto err1;
 	}
@@ -372,7 +375,8 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 			delay = 1;
 
 		if (!delay)
-			dev_warn(&ch->cmt->pdev->dev, "too long delay\n");
+			dev_warn(&ch->cmt->pdev->dev, "ch%u: too long delay\n",
+				 ch->index);
 
 	} while (delay);
 }
@@ -380,7 +384,8 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
 static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
 {
 	if (delta > ch->max_match_value)
-		dev_warn(&ch->cmt->pdev->dev, "delta out of range\n");
+		dev_warn(&ch->cmt->pdev->dev, "ch%u: delta out of range\n",
+			 ch->index);
 
 	ch->next_match_value = delta;
 	sh_cmt_clock_event_program_verify(ch, 0);
@@ -566,7 +571,8 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	dev_info(&ch->cmt->pdev->dev, "used as clock source\n");
+	dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
+		 ch->index);
 
 	/* Register with dummy 1 Hz value, gets updated in ->enable() */
 	clocksource_register_hz(cs, 1);
@@ -615,12 +621,12 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		dev_info(&ch->cmt->pdev->dev,
-			 "used for periodic clock events\n");
+			 "ch%u: used for periodic clock events\n", ch->index);
 		sh_cmt_clock_event_start(ch, 1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		dev_info(&ch->cmt->pdev->dev,
-			 "used for oneshot clock events\n");
+			 "ch%u: used for oneshot clock events\n", ch->index);
 		sh_cmt_clock_event_start(ch, 0);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
@@ -679,7 +685,8 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 	ced->suspend = sh_cmt_clock_event_suspend;
 	ced->resume = sh_cmt_clock_event_resume;
 
-	dev_info(&ch->cmt->pdev->dev, "used for clock events\n");
+	dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
+		 ch->index);
 	clockevents_register_device(ced);
 }
 
@@ -696,7 +703,7 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 				struct sh_cmt_device *cmt)
 {
 	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
@@ -706,6 +713,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
 	ch->base = cmt->mapbase_ch;
+	ch->index = index;
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
 	irq = platform_get_irq(cmt->pdev, 0);
@@ -820,7 +828,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	ret = sh_cmt_setup_channel(&cmt->channel, cmt);
+	ret = sh_cmt_setup_channel(&cmt->channel, cfg->timer_bit, cmt);
 	if (ret < 0)
 		goto err4;
 
-- 
1.8.3.2

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

* [PATCH 07/27] clocksource: sh_cmt: Replace kmalloc + memset with kzalloc
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

One kzalloc a day keeps the bugs away.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 0796460..cd3121d 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -673,8 +673,6 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 {
 	struct clock_event_device *ced = &ch->ced;
 
-	memset(ced, 0, sizeof(*ced));
-
 	ced->name = name;
 	ced->features = CLOCK_EVT_FEAT_PERIODIC;
 	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
@@ -710,7 +708,6 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	int irq;
 	int ret;
 
-	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
 	ch->base = cmt->mapbase_ch;
 	ch->index = index;
@@ -760,7 +757,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	int ret;
 	ret = -ENXIO;
 
-	memset(cmt, 0, sizeof(*cmt));
 	cmt->pdev = pdev;
 
 	if (!cfg) {
@@ -863,7 +859,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	cmt = kmalloc(sizeof(*cmt), GFP_KERNEL);
+	cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
 	if (cmt = NULL) {
 		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
-- 
1.8.3.2


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

* [PATCH 07/27] clocksource: sh_cmt: Replace kmalloc + memset with kzalloc
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

One kzalloc a day keeps the bugs away.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 0796460..cd3121d 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -673,8 +673,6 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 {
 	struct clock_event_device *ced = &ch->ced;
 
-	memset(ced, 0, sizeof(*ced));
-
 	ced->name = name;
 	ced->features = CLOCK_EVT_FEAT_PERIODIC;
 	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
@@ -710,7 +708,6 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	int irq;
 	int ret;
 
-	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
 	ch->base = cmt->mapbase_ch;
 	ch->index = index;
@@ -760,7 +757,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	int ret;
 	ret = -ENXIO;
 
-	memset(cmt, 0, sizeof(*cmt));
 	cmt->pdev = pdev;
 
 	if (!cfg) {
@@ -863,7 +859,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	cmt = kmalloc(sizeof(*cmt), GFP_KERNEL);
+	cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
 	if (cmt == NULL) {
 		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
-- 
1.8.3.2


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

* [PATCH 07/27] clocksource: sh_cmt: Replace kmalloc + memset with kzalloc
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

One kzalloc a day keeps the bugs away.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 0796460..cd3121d 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -673,8 +673,6 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
 {
 	struct clock_event_device *ced = &ch->ced;
 
-	memset(ced, 0, sizeof(*ced));
-
 	ced->name = name;
 	ced->features = CLOCK_EVT_FEAT_PERIODIC;
 	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
@@ -710,7 +708,6 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	int irq;
 	int ret;
 
-	memset(ch, 0, sizeof(*ch));
 	ch->cmt = cmt;
 	ch->base = cmt->mapbase_ch;
 	ch->index = index;
@@ -760,7 +757,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	int ret;
 	ret = -ENXIO;
 
-	memset(cmt, 0, sizeof(*cmt));
 	cmt->pdev = pdev;
 
 	if (!cfg) {
@@ -863,7 +859,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	cmt = kmalloc(sizeof(*cmt), GFP_KERNEL);
+	cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
 	if (cmt == NULL) {
 		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
-- 
1.8.3.2

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

* [PATCH 08/27] clocksource: sh_cmt: Allocate channels dynamically
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

This prepares the driver for multi-channel support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index cd3121d..7a65d64 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -63,7 +63,8 @@ struct sh_cmt_device {
 	void __iomem *mapbase;
 	struct clk *clk;
 
-	struct sh_cmt_channel channel;
+	struct sh_cmt_channel *channels;
+	unsigned int num_channels;
 
 	unsigned long width; /* 16 or 32 bit version of hardware block */
 	unsigned long overflow_bit;
@@ -824,7 +825,15 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	ret = sh_cmt_setup_channel(&cmt->channel, cfg->timer_bit, cmt);
+	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
+	if (cmt->channels = NULL) {
+		ret = -ENOMEM;
+		goto err4;
+	}
+
+	cmt->num_channels = 1;
+
+	ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit, cmt);
 	if (ret < 0)
 		goto err4;
 
@@ -832,6 +841,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 
 	return 0;
 err4:
+	kfree(cmt->channels);
 	clk_unprepare(cmt->clk);
 err3:
 	clk_put(cmt->clk);
-- 
1.8.3.2


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

* [PATCH 08/27] clocksource: sh_cmt: Allocate channels dynamically
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

This prepares the driver for multi-channel support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index cd3121d..7a65d64 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -63,7 +63,8 @@ struct sh_cmt_device {
 	void __iomem *mapbase;
 	struct clk *clk;
 
-	struct sh_cmt_channel channel;
+	struct sh_cmt_channel *channels;
+	unsigned int num_channels;
 
 	unsigned long width; /* 16 or 32 bit version of hardware block */
 	unsigned long overflow_bit;
@@ -824,7 +825,15 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	ret = sh_cmt_setup_channel(&cmt->channel, cfg->timer_bit, cmt);
+	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
+	if (cmt->channels == NULL) {
+		ret = -ENOMEM;
+		goto err4;
+	}
+
+	cmt->num_channels = 1;
+
+	ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit, cmt);
 	if (ret < 0)
 		goto err4;
 
@@ -832,6 +841,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 
 	return 0;
 err4:
+	kfree(cmt->channels);
 	clk_unprepare(cmt->clk);
 err3:
 	clk_put(cmt->clk);
-- 
1.8.3.2


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

* [PATCH 08/27] clocksource: sh_cmt: Allocate channels dynamically
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

This prepares the driver for multi-channel support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index cd3121d..7a65d64 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -63,7 +63,8 @@ struct sh_cmt_device {
 	void __iomem *mapbase;
 	struct clk *clk;
 
-	struct sh_cmt_channel channel;
+	struct sh_cmt_channel *channels;
+	unsigned int num_channels;
 
 	unsigned long width; /* 16 or 32 bit version of hardware block */
 	unsigned long overflow_bit;
@@ -824,7 +825,15 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		cmt->clear_bits = ~0xc000;
 	}
 
-	ret = sh_cmt_setup_channel(&cmt->channel, cfg->timer_bit, cmt);
+	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
+	if (cmt->channels == NULL) {
+		ret = -ENOMEM;
+		goto err4;
+	}
+
+	cmt->num_channels = 1;
+
+	ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit, cmt);
 	if (ret < 0)
 		goto err4;
 
@@ -832,6 +841,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 
 	return 0;
 err4:
+	kfree(cmt->channels);
 	clk_unprepare(cmt->clk);
 err3:
 	clk_put(cmt->clk);
-- 
1.8.3.2

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

* [PATCH 09/27] clocksource: sh_cmt: Split static information from sh_cmt_device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Create a new sh_cmt_info structure to hold static information about the
device model and reference that structure from the sh_cmt_device
structure.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 192 +++++++++++++++++++++++++++----------------
 1 file changed, 122 insertions(+), 70 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7a65d64..3946c14 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -37,6 +37,52 @@
 
 struct sh_cmt_device;
 
+/*
+ * The CMT comes in 5 different identified flavours, depending not only on the
+ * SoC but also on the particular instance. The following table lists the main
+ * characteristics of those flavours.
+ *
+ *			16B	32B	32B-F	48B	48B-2
+ * -----------------------------------------------------------------------------
+ * Channels		2	1/4	1	6	2/8
+ * Control Width	16	16	16	16	32
+ * Counter Width	16	32	32	32/48	32/48
+ * Shared Start/Stop	Y	Y	Y	Y	N
+ *
+ * The 48-bit gen2 version has a per-channel start/stop register located in the
+ * channel registers block. All other versions have a shared start/stop register
+ * located in the global space.
+ *
+ * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
+ * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
+ */
+
+enum sh_cmt_model {
+	SH_CMT_16BIT,
+	SH_CMT_32BIT,
+	SH_CMT_32BIT_FAST,
+	SH_CMT_48BIT,
+	SH_CMT_48BIT_GEN2,
+};
+
+struct sh_cmt_info {
+	enum sh_cmt_model model;
+
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
+
+	/* 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,
+			    unsigned long value);
+};
+
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
 	unsigned int index;
@@ -59,49 +105,16 @@ struct sh_cmt_channel {
 struct sh_cmt_device {
 	struct platform_device *pdev;
 
+	const struct sh_cmt_info *info;
+
 	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
 	struct clk *clk;
 
 	struct sh_cmt_channel *channels;
 	unsigned int num_channels;
-
-	unsigned long width; /* 16 or 32 bit version of hardware block */
-	unsigned long overflow_bit;
-	unsigned long clear_bits;
-
-	/* 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,
-			    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
- *
- * "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790:
- * CMSTR 0xffca0500 32-bit
- * CMCSR 0xffca0510 32-bit
- * CMCNT 0xffca0514 32-bit
- * CMCOR 0xffca0518 32-bit
- */
-
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
@@ -124,47 +137,100 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 	iowrite32(value, base + (offs << 2));
 }
 
+static const struct sh_cmt_info sh_cmt_info[] = {
+	[SH_CMT_16BIT] = {
+		.model = SH_CMT_16BIT,
+		.width = 16,
+		.overflow_bit = 0x80,
+		.clear_bits = ~0x80,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read16,
+		.write_count = sh_cmt_write16,
+	},
+	[SH_CMT_32BIT] = {
+		.model = SH_CMT_32BIT,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_32BIT_FAST] = {
+		.model = SH_CMT_32BIT_FAST,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_48BIT] = {
+		.model = SH_CMT_48BIT,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read32,
+		.write_control = sh_cmt_write32,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_48BIT_GEN2] = {
+		.model = SH_CMT_48BIT_GEN2,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read32,
+		.write_control = sh_cmt_write32,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+};
+
 #define CMCSR 0 /* channel register */
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase, 0);
+	return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->base, CMCSR);
+	return ch->cmt->info->read_control(ch->base, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->base, CMCNT);
+	return ch->cmt->info->read_count(ch->base, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase, 0, value);
+	ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->base, CMCSR, value);
+	ch->cmt->info->write_control(ch->base, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->base, CMCNT, value);
+	ch->cmt->info->write_count(ch->base, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->base, CMCOR, value);
+	ch->cmt->info->write_count(ch->base, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -173,7 +239,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
@@ -181,7 +247,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 		v1 = sh_cmt_read_cmcnt(ch);
 		v2 = sh_cmt_read_cmcnt(ch);
 		v3 = sh_cmt_read_cmcnt(ch);
-		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
+		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -228,7 +294,7 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	sh_cmt_start_stop_ch(ch, 0);
 
 	/* configure channel, periodic mode and maximum timeout */
-	if (ch->cmt->width = 16) {
+	if (ch->cmt->info->width = 16) {
 		*rate = clk_get_rate(ch->cmt->clk) / 512;
 		sh_cmt_write_cmcsr(ch, 0x43);
 	} else {
@@ -406,7 +472,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 	struct sh_cmt_channel *ch = dev_id;
 
 	/* clear flags */
-	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits);
+	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
+			   ch->cmt->info->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific
@@ -725,10 +792,10 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->irqaction.dev_id = ch;
 	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
-	if (cmt->width = (sizeof(ch->max_match_value) * 8))
+	if (cmt->info->width = (sizeof(ch->max_match_value) * 8))
 		ch->max_match_value = ~0;
 	else
-		ch->max_match_value = (1 << cmt->width) - 1;
+		ch->max_match_value = (1 << cmt->info->width) - 1;
 
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
@@ -802,28 +869,13 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	if (ret < 0)
 		goto err3;
 
-	if (res2 && (resource_size(res2) = 4)) {
-		/* assume both CMSTR and CMCSR to be 32-bit */
-		cmt->read_control = sh_cmt_read32;
-		cmt->write_control = sh_cmt_write32;
-	} else {
-		cmt->read_control = sh_cmt_read16;
-		cmt->write_control = sh_cmt_write16;
-	}
-
-	if (resource_size(res) = 6) {
-		cmt->width = 16;
-		cmt->read_count = sh_cmt_read16;
-		cmt->write_count = sh_cmt_write16;
-		cmt->overflow_bit = 0x80;
-		cmt->clear_bits = ~0x80;
-	} else {
-		cmt->width = 32;
-		cmt->read_count = sh_cmt_read32;
-		cmt->write_count = sh_cmt_write32;
-		cmt->overflow_bit = 0x8000;
-		cmt->clear_bits = ~0xc000;
-	}
+	/* identify the model based on the resources */
+	if (resource_size(res) = 6)
+		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
+	else if (res2 && (resource_size(res2) = 4))
+		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	else
+		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
 
 	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
 	if (cmt->channels = NULL) {
-- 
1.8.3.2


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

* [PATCH 09/27] clocksource: sh_cmt: Split static information from sh_cmt_device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Create a new sh_cmt_info structure to hold static information about the
device model and reference that structure from the sh_cmt_device
structure.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 192 +++++++++++++++++++++++++++----------------
 1 file changed, 122 insertions(+), 70 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7a65d64..3946c14 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -37,6 +37,52 @@
 
 struct sh_cmt_device;
 
+/*
+ * The CMT comes in 5 different identified flavours, depending not only on the
+ * SoC but also on the particular instance. The following table lists the main
+ * characteristics of those flavours.
+ *
+ *			16B	32B	32B-F	48B	48B-2
+ * -----------------------------------------------------------------------------
+ * Channels		2	1/4	1	6	2/8
+ * Control Width	16	16	16	16	32
+ * Counter Width	16	32	32	32/48	32/48
+ * Shared Start/Stop	Y	Y	Y	Y	N
+ *
+ * The 48-bit gen2 version has a per-channel start/stop register located in the
+ * channel registers block. All other versions have a shared start/stop register
+ * located in the global space.
+ *
+ * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
+ * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
+ */
+
+enum sh_cmt_model {
+	SH_CMT_16BIT,
+	SH_CMT_32BIT,
+	SH_CMT_32BIT_FAST,
+	SH_CMT_48BIT,
+	SH_CMT_48BIT_GEN2,
+};
+
+struct sh_cmt_info {
+	enum sh_cmt_model model;
+
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
+
+	/* 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,
+			    unsigned long value);
+};
+
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
 	unsigned int index;
@@ -59,49 +105,16 @@ struct sh_cmt_channel {
 struct sh_cmt_device {
 	struct platform_device *pdev;
 
+	const struct sh_cmt_info *info;
+
 	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
 	struct clk *clk;
 
 	struct sh_cmt_channel *channels;
 	unsigned int num_channels;
-
-	unsigned long width; /* 16 or 32 bit version of hardware block */
-	unsigned long overflow_bit;
-	unsigned long clear_bits;
-
-	/* 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,
-			    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
- *
- * "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790:
- * CMSTR 0xffca0500 32-bit
- * CMCSR 0xffca0510 32-bit
- * CMCNT 0xffca0514 32-bit
- * CMCOR 0xffca0518 32-bit
- */
-
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
@@ -124,47 +137,100 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 	iowrite32(value, base + (offs << 2));
 }
 
+static const struct sh_cmt_info sh_cmt_info[] = {
+	[SH_CMT_16BIT] = {
+		.model = SH_CMT_16BIT,
+		.width = 16,
+		.overflow_bit = 0x80,
+		.clear_bits = ~0x80,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read16,
+		.write_count = sh_cmt_write16,
+	},
+	[SH_CMT_32BIT] = {
+		.model = SH_CMT_32BIT,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_32BIT_FAST] = {
+		.model = SH_CMT_32BIT_FAST,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_48BIT] = {
+		.model = SH_CMT_48BIT,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read32,
+		.write_control = sh_cmt_write32,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_48BIT_GEN2] = {
+		.model = SH_CMT_48BIT_GEN2,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read32,
+		.write_control = sh_cmt_write32,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+};
+
 #define CMCSR 0 /* channel register */
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase, 0);
+	return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->base, CMCSR);
+	return ch->cmt->info->read_control(ch->base, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->base, CMCNT);
+	return ch->cmt->info->read_count(ch->base, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase, 0, value);
+	ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->base, CMCSR, value);
+	ch->cmt->info->write_control(ch->base, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->base, CMCNT, value);
+	ch->cmt->info->write_count(ch->base, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->base, CMCOR, value);
+	ch->cmt->info->write_count(ch->base, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -173,7 +239,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
@@ -181,7 +247,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 		v1 = sh_cmt_read_cmcnt(ch);
 		v2 = sh_cmt_read_cmcnt(ch);
 		v3 = sh_cmt_read_cmcnt(ch);
-		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
+		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -228,7 +294,7 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	sh_cmt_start_stop_ch(ch, 0);
 
 	/* configure channel, periodic mode and maximum timeout */
-	if (ch->cmt->width == 16) {
+	if (ch->cmt->info->width == 16) {
 		*rate = clk_get_rate(ch->cmt->clk) / 512;
 		sh_cmt_write_cmcsr(ch, 0x43);
 	} else {
@@ -406,7 +472,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 	struct sh_cmt_channel *ch = dev_id;
 
 	/* clear flags */
-	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits);
+	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
+			   ch->cmt->info->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific
@@ -725,10 +792,10 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->irqaction.dev_id = ch;
 	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
-	if (cmt->width == (sizeof(ch->max_match_value) * 8))
+	if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
 		ch->max_match_value = ~0;
 	else
-		ch->max_match_value = (1 << cmt->width) - 1;
+		ch->max_match_value = (1 << cmt->info->width) - 1;
 
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
@@ -802,28 +869,13 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	if (ret < 0)
 		goto err3;
 
-	if (res2 && (resource_size(res2) == 4)) {
-		/* assume both CMSTR and CMCSR to be 32-bit */
-		cmt->read_control = sh_cmt_read32;
-		cmt->write_control = sh_cmt_write32;
-	} else {
-		cmt->read_control = sh_cmt_read16;
-		cmt->write_control = sh_cmt_write16;
-	}
-
-	if (resource_size(res) == 6) {
-		cmt->width = 16;
-		cmt->read_count = sh_cmt_read16;
-		cmt->write_count = sh_cmt_write16;
-		cmt->overflow_bit = 0x80;
-		cmt->clear_bits = ~0x80;
-	} else {
-		cmt->width = 32;
-		cmt->read_count = sh_cmt_read32;
-		cmt->write_count = sh_cmt_write32;
-		cmt->overflow_bit = 0x8000;
-		cmt->clear_bits = ~0xc000;
-	}
+	/* identify the model based on the resources */
+	if (resource_size(res) == 6)
+		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
+	else if (res2 && (resource_size(res2) == 4))
+		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	else
+		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
 
 	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
 	if (cmt->channels == NULL) {
-- 
1.8.3.2


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

* [PATCH 09/27] clocksource: sh_cmt: Split static information from sh_cmt_device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Create a new sh_cmt_info structure to hold static information about the
device model and reference that structure from the sh_cmt_device
structure.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 192 +++++++++++++++++++++++++++----------------
 1 file changed, 122 insertions(+), 70 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7a65d64..3946c14 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -37,6 +37,52 @@
 
 struct sh_cmt_device;
 
+/*
+ * The CMT comes in 5 different identified flavours, depending not only on the
+ * SoC but also on the particular instance. The following table lists the main
+ * characteristics of those flavours.
+ *
+ *			16B	32B	32B-F	48B	48B-2
+ * -----------------------------------------------------------------------------
+ * Channels		2	1/4	1	6	2/8
+ * Control Width	16	16	16	16	32
+ * Counter Width	16	32	32	32/48	32/48
+ * Shared Start/Stop	Y	Y	Y	Y	N
+ *
+ * The 48-bit gen2 version has a per-channel start/stop register located in the
+ * channel registers block. All other versions have a shared start/stop register
+ * located in the global space.
+ *
+ * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
+ * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
+ */
+
+enum sh_cmt_model {
+	SH_CMT_16BIT,
+	SH_CMT_32BIT,
+	SH_CMT_32BIT_FAST,
+	SH_CMT_48BIT,
+	SH_CMT_48BIT_GEN2,
+};
+
+struct sh_cmt_info {
+	enum sh_cmt_model model;
+
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
+
+	/* 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,
+			    unsigned long value);
+};
+
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
 	unsigned int index;
@@ -59,49 +105,16 @@ struct sh_cmt_channel {
 struct sh_cmt_device {
 	struct platform_device *pdev;
 
+	const struct sh_cmt_info *info;
+
 	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
 	struct clk *clk;
 
 	struct sh_cmt_channel *channels;
 	unsigned int num_channels;
-
-	unsigned long width; /* 16 or 32 bit version of hardware block */
-	unsigned long overflow_bit;
-	unsigned long clear_bits;
-
-	/* 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,
-			    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
- *
- * "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790:
- * CMSTR 0xffca0500 32-bit
- * CMCSR 0xffca0510 32-bit
- * CMCNT 0xffca0514 32-bit
- * CMCOR 0xffca0518 32-bit
- */
-
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
@@ -124,47 +137,100 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
 	iowrite32(value, base + (offs << 2));
 }
 
+static const struct sh_cmt_info sh_cmt_info[] = {
+	[SH_CMT_16BIT] = {
+		.model = SH_CMT_16BIT,
+		.width = 16,
+		.overflow_bit = 0x80,
+		.clear_bits = ~0x80,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read16,
+		.write_count = sh_cmt_write16,
+	},
+	[SH_CMT_32BIT] = {
+		.model = SH_CMT_32BIT,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_32BIT_FAST] = {
+		.model = SH_CMT_32BIT_FAST,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read16,
+		.write_control = sh_cmt_write16,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_48BIT] = {
+		.model = SH_CMT_48BIT,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read32,
+		.write_control = sh_cmt_write32,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+	[SH_CMT_48BIT_GEN2] = {
+		.model = SH_CMT_48BIT_GEN2,
+		.width = 32,
+		.overflow_bit = 0x8000,
+		.clear_bits = ~0xc000,
+		.read_control = sh_cmt_read32,
+		.write_control = sh_cmt_write32,
+		.read_count = sh_cmt_read32,
+		.write_count = sh_cmt_write32,
+	},
+};
+
 #define CMCSR 0 /* channel register */
 #define CMCNT 1 /* channel register */
 #define CMCOR 2 /* channel register */
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->cmt->mapbase, 0);
+	return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
 }
 
 static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_control(ch->base, CMCSR);
+	return ch->cmt->info->read_control(ch->base, CMCSR);
 }
 
 static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->read_count(ch->base, CMCNT);
+	return ch->cmt->info->read_count(ch->base, CMCNT);
 }
 
 static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->cmt->mapbase, 0, value);
+	ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
 }
 
 static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_control(ch->base, CMCSR, value);
+	ch->cmt->info->write_control(ch->base, CMCSR, value);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->base, CMCNT, value);
+	ch->cmt->info->write_count(ch->base, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->write_count(ch->base, CMCOR, value);
+	ch->cmt->info->write_count(ch->base, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -173,7 +239,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 	unsigned long v1, v2, v3;
 	int o1, o2;
 
-	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
+	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
@@ -181,7 +247,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
 		v1 = sh_cmt_read_cmcnt(ch);
 		v2 = sh_cmt_read_cmcnt(ch);
 		v3 = sh_cmt_read_cmcnt(ch);
-		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit;
+		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
 	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
 			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
@@ -228,7 +294,7 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	sh_cmt_start_stop_ch(ch, 0);
 
 	/* configure channel, periodic mode and maximum timeout */
-	if (ch->cmt->width == 16) {
+	if (ch->cmt->info->width == 16) {
 		*rate = clk_get_rate(ch->cmt->clk) / 512;
 		sh_cmt_write_cmcsr(ch, 0x43);
 	} else {
@@ -406,7 +472,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 	struct sh_cmt_channel *ch = dev_id;
 
 	/* clear flags */
-	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits);
+	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
+			   ch->cmt->info->clear_bits);
 
 	/* update clock source counter to begin with if enabled
 	 * the wrap flag should be cleared by the timer specific
@@ -725,10 +792,10 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->irqaction.dev_id = ch;
 	ch->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING;
 
-	if (cmt->width == (sizeof(ch->max_match_value) * 8))
+	if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
 		ch->max_match_value = ~0;
 	else
-		ch->max_match_value = (1 << cmt->width) - 1;
+		ch->max_match_value = (1 << cmt->info->width) - 1;
 
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
@@ -802,28 +869,13 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	if (ret < 0)
 		goto err3;
 
-	if (res2 && (resource_size(res2) == 4)) {
-		/* assume both CMSTR and CMCSR to be 32-bit */
-		cmt->read_control = sh_cmt_read32;
-		cmt->write_control = sh_cmt_write32;
-	} else {
-		cmt->read_control = sh_cmt_read16;
-		cmt->write_control = sh_cmt_write16;
-	}
-
-	if (resource_size(res) == 6) {
-		cmt->width = 16;
-		cmt->read_count = sh_cmt_read16;
-		cmt->write_count = sh_cmt_write16;
-		cmt->overflow_bit = 0x80;
-		cmt->clear_bits = ~0x80;
-	} else {
-		cmt->width = 32;
-		cmt->read_count = sh_cmt_read32;
-		cmt->write_count = sh_cmt_write32;
-		cmt->overflow_bit = 0x8000;
-		cmt->clear_bits = ~0xc000;
-	}
+	/* identify the model based on the resources */
+	if (resource_size(res) == 6)
+		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
+	else if (res2 && (resource_size(res2) == 4))
+		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	else
+		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
 
 	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
 	if (cmt->channels == NULL) {
-- 
1.8.3.2

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

* [PATCH 10/27] clocksource: sh_cmt: Replace hardcoded register values with macros
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Define symbolic macros for all used registers bits.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 56 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3946c14..5280231 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -115,6 +115,34 @@ struct sh_cmt_device {
 	unsigned int num_channels;
 };
 
+#define SH_CMT16_CMCSR_CMF		(1 << 7)
+#define SH_CMT16_CMCSR_CMIE		(1 << 6)
+#define SH_CMT16_CMCSR_CKS8		(0 << 0)
+#define SH_CMT16_CMCSR_CKS32		(1 << 0)
+#define SH_CMT16_CMCSR_CKS128		(2 << 0)
+#define SH_CMT16_CMCSR_CKS512		(3 << 0)
+#define SH_CMT16_CMCSR_CKS_MASK		(3 << 0)
+
+#define SH_CMT32_CMCSR_CMF		(1 << 15)
+#define SH_CMT32_CMCSR_OVF		(1 << 14)
+#define SH_CMT32_CMCSR_WRFLG		(1 << 13)
+#define SH_CMT32_CMCSR_STTF		(1 << 12)
+#define SH_CMT32_CMCSR_STPF		(1 << 11)
+#define SH_CMT32_CMCSR_SSIE		(1 << 10)
+#define SH_CMT32_CMCSR_CMS		(1 << 9)
+#define SH_CMT32_CMCSR_CMM		(1 << 8)
+#define SH_CMT32_CMCSR_CMTOUT_IE	(1 << 7)
+#define SH_CMT32_CMCSR_CMR_NONE		(0 << 4)
+#define SH_CMT32_CMCSR_CMR_DMA		(1 << 4)
+#define SH_CMT32_CMCSR_CMR_IRQ		(2 << 4)
+#define SH_CMT32_CMCSR_CMR_MASK		(3 << 4)
+#define SH_CMT32_CMCSR_DBGIVD		(1 << 3)
+#define SH_CMT32_CMCSR_CKS_RCLK8	(4 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK32	(5 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK128	(6 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK1	(7 << 0)
+#define SH_CMT32_CMCSR_CKS_MASK		(7 << 0)
+
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
@@ -141,8 +169,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_16BIT] = {
 		.model = SH_CMT_16BIT,
 		.width = 16,
-		.overflow_bit = 0x80,
-		.clear_bits = ~0x80,
+		.overflow_bit = SH_CMT16_CMCSR_CMF,
+		.clear_bits = ~SH_CMT16_CMCSR_CMF,
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read16,
@@ -151,8 +179,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_32BIT] = {
 		.model = SH_CMT_32BIT,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read32,
@@ -161,8 +189,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_32BIT_FAST] = {
 		.model = SH_CMT_32BIT_FAST,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read32,
@@ -171,8 +199,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_48BIT] = {
 		.model = SH_CMT_48BIT,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read32,
 		.write_control = sh_cmt_write32,
 		.read_count = sh_cmt_read32,
@@ -181,8 +209,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_48BIT_GEN2] = {
 		.model = SH_CMT_48BIT_GEN2,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read32,
 		.write_control = sh_cmt_write32,
 		.read_count = sh_cmt_read32,
@@ -296,10 +324,14 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	/* configure channel, periodic mode and maximum timeout */
 	if (ch->cmt->info->width = 16) {
 		*rate = clk_get_rate(ch->cmt->clk) / 512;
-		sh_cmt_write_cmcsr(ch, 0x43);
+		sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
+				   SH_CMT16_CMCSR_CKS512);
 	} else {
 		*rate = clk_get_rate(ch->cmt->clk) / 8;
-		sh_cmt_write_cmcsr(ch, 0x01a4);
+		sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM |
+				   SH_CMT32_CMCSR_CMTOUT_IE |
+				   SH_CMT32_CMCSR_CMR_IRQ |
+				   SH_CMT32_CMCSR_CKS_RCLK8);
 	}
 
 	sh_cmt_write_cmcor(ch, 0xffffffff);
-- 
1.8.3.2


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

* [PATCH 10/27] clocksource: sh_cmt: Replace hardcoded register values with macros
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Define symbolic macros for all used registers bits.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 56 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3946c14..5280231 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -115,6 +115,34 @@ struct sh_cmt_device {
 	unsigned int num_channels;
 };
 
+#define SH_CMT16_CMCSR_CMF		(1 << 7)
+#define SH_CMT16_CMCSR_CMIE		(1 << 6)
+#define SH_CMT16_CMCSR_CKS8		(0 << 0)
+#define SH_CMT16_CMCSR_CKS32		(1 << 0)
+#define SH_CMT16_CMCSR_CKS128		(2 << 0)
+#define SH_CMT16_CMCSR_CKS512		(3 << 0)
+#define SH_CMT16_CMCSR_CKS_MASK		(3 << 0)
+
+#define SH_CMT32_CMCSR_CMF		(1 << 15)
+#define SH_CMT32_CMCSR_OVF		(1 << 14)
+#define SH_CMT32_CMCSR_WRFLG		(1 << 13)
+#define SH_CMT32_CMCSR_STTF		(1 << 12)
+#define SH_CMT32_CMCSR_STPF		(1 << 11)
+#define SH_CMT32_CMCSR_SSIE		(1 << 10)
+#define SH_CMT32_CMCSR_CMS		(1 << 9)
+#define SH_CMT32_CMCSR_CMM		(1 << 8)
+#define SH_CMT32_CMCSR_CMTOUT_IE	(1 << 7)
+#define SH_CMT32_CMCSR_CMR_NONE		(0 << 4)
+#define SH_CMT32_CMCSR_CMR_DMA		(1 << 4)
+#define SH_CMT32_CMCSR_CMR_IRQ		(2 << 4)
+#define SH_CMT32_CMCSR_CMR_MASK		(3 << 4)
+#define SH_CMT32_CMCSR_DBGIVD		(1 << 3)
+#define SH_CMT32_CMCSR_CKS_RCLK8	(4 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK32	(5 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK128	(6 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK1	(7 << 0)
+#define SH_CMT32_CMCSR_CKS_MASK		(7 << 0)
+
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
@@ -141,8 +169,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_16BIT] = {
 		.model = SH_CMT_16BIT,
 		.width = 16,
-		.overflow_bit = 0x80,
-		.clear_bits = ~0x80,
+		.overflow_bit = SH_CMT16_CMCSR_CMF,
+		.clear_bits = ~SH_CMT16_CMCSR_CMF,
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read16,
@@ -151,8 +179,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_32BIT] = {
 		.model = SH_CMT_32BIT,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read32,
@@ -161,8 +189,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_32BIT_FAST] = {
 		.model = SH_CMT_32BIT_FAST,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read32,
@@ -171,8 +199,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_48BIT] = {
 		.model = SH_CMT_48BIT,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read32,
 		.write_control = sh_cmt_write32,
 		.read_count = sh_cmt_read32,
@@ -181,8 +209,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_48BIT_GEN2] = {
 		.model = SH_CMT_48BIT_GEN2,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read32,
 		.write_control = sh_cmt_write32,
 		.read_count = sh_cmt_read32,
@@ -296,10 +324,14 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	/* configure channel, periodic mode and maximum timeout */
 	if (ch->cmt->info->width == 16) {
 		*rate = clk_get_rate(ch->cmt->clk) / 512;
-		sh_cmt_write_cmcsr(ch, 0x43);
+		sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
+				   SH_CMT16_CMCSR_CKS512);
 	} else {
 		*rate = clk_get_rate(ch->cmt->clk) / 8;
-		sh_cmt_write_cmcsr(ch, 0x01a4);
+		sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM |
+				   SH_CMT32_CMCSR_CMTOUT_IE |
+				   SH_CMT32_CMCSR_CMR_IRQ |
+				   SH_CMT32_CMCSR_CKS_RCLK8);
 	}
 
 	sh_cmt_write_cmcor(ch, 0xffffffff);
-- 
1.8.3.2


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

* [PATCH 10/27] clocksource: sh_cmt: Replace hardcoded register values with macros
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Define symbolic macros for all used registers bits.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 56 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3946c14..5280231 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -115,6 +115,34 @@ struct sh_cmt_device {
 	unsigned int num_channels;
 };
 
+#define SH_CMT16_CMCSR_CMF		(1 << 7)
+#define SH_CMT16_CMCSR_CMIE		(1 << 6)
+#define SH_CMT16_CMCSR_CKS8		(0 << 0)
+#define SH_CMT16_CMCSR_CKS32		(1 << 0)
+#define SH_CMT16_CMCSR_CKS128		(2 << 0)
+#define SH_CMT16_CMCSR_CKS512		(3 << 0)
+#define SH_CMT16_CMCSR_CKS_MASK		(3 << 0)
+
+#define SH_CMT32_CMCSR_CMF		(1 << 15)
+#define SH_CMT32_CMCSR_OVF		(1 << 14)
+#define SH_CMT32_CMCSR_WRFLG		(1 << 13)
+#define SH_CMT32_CMCSR_STTF		(1 << 12)
+#define SH_CMT32_CMCSR_STPF		(1 << 11)
+#define SH_CMT32_CMCSR_SSIE		(1 << 10)
+#define SH_CMT32_CMCSR_CMS		(1 << 9)
+#define SH_CMT32_CMCSR_CMM		(1 << 8)
+#define SH_CMT32_CMCSR_CMTOUT_IE	(1 << 7)
+#define SH_CMT32_CMCSR_CMR_NONE		(0 << 4)
+#define SH_CMT32_CMCSR_CMR_DMA		(1 << 4)
+#define SH_CMT32_CMCSR_CMR_IRQ		(2 << 4)
+#define SH_CMT32_CMCSR_CMR_MASK		(3 << 4)
+#define SH_CMT32_CMCSR_DBGIVD		(1 << 3)
+#define SH_CMT32_CMCSR_CKS_RCLK8	(4 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK32	(5 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK128	(6 << 0)
+#define SH_CMT32_CMCSR_CKS_RCLK1	(7 << 0)
+#define SH_CMT32_CMCSR_CKS_MASK		(7 << 0)
+
 static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
 {
 	return ioread16(base + (offs << 1));
@@ -141,8 +169,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_16BIT] = {
 		.model = SH_CMT_16BIT,
 		.width = 16,
-		.overflow_bit = 0x80,
-		.clear_bits = ~0x80,
+		.overflow_bit = SH_CMT16_CMCSR_CMF,
+		.clear_bits = ~SH_CMT16_CMCSR_CMF,
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read16,
@@ -151,8 +179,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_32BIT] = {
 		.model = SH_CMT_32BIT,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read32,
@@ -161,8 +189,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_32BIT_FAST] = {
 		.model = SH_CMT_32BIT_FAST,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read16,
 		.write_control = sh_cmt_write16,
 		.read_count = sh_cmt_read32,
@@ -171,8 +199,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_48BIT] = {
 		.model = SH_CMT_48BIT,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read32,
 		.write_control = sh_cmt_write32,
 		.read_count = sh_cmt_read32,
@@ -181,8 +209,8 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 	[SH_CMT_48BIT_GEN2] = {
 		.model = SH_CMT_48BIT_GEN2,
 		.width = 32,
-		.overflow_bit = 0x8000,
-		.clear_bits = ~0xc000,
+		.overflow_bit = SH_CMT32_CMCSR_CMF,
+		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
 		.read_control = sh_cmt_read32,
 		.write_control = sh_cmt_write32,
 		.read_count = sh_cmt_read32,
@@ -296,10 +324,14 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
 	/* configure channel, periodic mode and maximum timeout */
 	if (ch->cmt->info->width == 16) {
 		*rate = clk_get_rate(ch->cmt->clk) / 512;
-		sh_cmt_write_cmcsr(ch, 0x43);
+		sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
+				   SH_CMT16_CMCSR_CKS512);
 	} else {
 		*rate = clk_get_rate(ch->cmt->clk) / 8;
-		sh_cmt_write_cmcsr(ch, 0x01a4);
+		sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM |
+				   SH_CMT32_CMCSR_CMTOUT_IE |
+				   SH_CMT32_CMCSR_CMR_IRQ |
+				   SH_CMT32_CMCSR_CKS_RCLK8);
 	}
 
 	sh_cmt_write_cmcor(ch, 0xffffffff);
-- 
1.8.3.2

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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

CMT hardware devices can support multiple channels, with global
registers and per-channel registers. The sh_cmt driver currently models
the hardware with one Linux device per channel. This model makes it
difficult to handle global registers in a clean way.

Add support for a new model that uses one Linux device per timer with
multiple channels per device. This requires changes to platform data,
add new channel configuration fields.

Support for the legacy model is kept and will be removed after all
platforms switch to the new model.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++++++----------
 include/linux/sh_timer.h     |   9 ++
 2 files changed, 239 insertions(+), 69 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 5280231..8390f0f 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -53,7 +53,16 @@ struct sh_cmt_device;
  * channel registers block. All other versions have a shared start/stop register
  * located in the global space.
  *
- * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
+ * Channels are indexed from 0 to N-1 in the documentation. The channel index
+ * infers the start/stop bit position in the control register and the channel
+ * registers block address. Some CMT instances have a subset of channels
+ * available, in which case the index in the documentation doesn't match the
+ * "real" index as implemented in hardware. This is for instance the case with
+ * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
+ * in the documentation but using start/stop bit 5 and having its registers
+ * block at 0x60.
+ *
+ * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
  * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
  */
 
@@ -85,11 +94,15 @@ struct sh_cmt_info {
 
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
-	unsigned int index;
 
-	void __iomem *base;
+	unsigned int index;	/* Index in the documentation */
+	unsigned int hwidx;	/* Real hardware index */
+
+	void __iomem *iostart;
+	void __iomem *ioctrl;
 	struct irqaction irqaction;
 
+	unsigned int timer_bit;
 	unsigned long flags;
 	unsigned long match_value;
 	unsigned long next_match_value;
@@ -106,6 +119,7 @@ struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	const struct sh_cmt_info *info;
+	bool legacy;
 
 	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
@@ -113,6 +127,10 @@ struct sh_cmt_device {
 
 	struct sh_cmt_channel *channels;
 	unsigned int num_channels;
+	unsigned int hw_channels;
+
+	bool has_clockevent;
+	bool has_clocksource;
 };
 
 #define SH_CMT16_CMCSR_CMF		(1 << 7)
@@ -224,41 +242,47 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
+	if (ch->iostart)
+		return ch->cmt->info->read_control(ch->iostart, 0);
+	else
+		return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
 }
 
-static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
+				      unsigned long value)
 {
-	return ch->cmt->info->read_control(ch->base, CMCSR);
+	if (ch->iostart)
+		ch->cmt->info->write_control(ch->iostart, 0, value);
+	else
+		ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
 }
 
-static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->info->read_count(ch->base, CMCNT);
+	return ch->cmt->info->read_control(ch->ioctrl, CMCSR);
 }
 
-static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
+	ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
 }
 
-static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
-				      unsigned long value)
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	ch->cmt->info->write_control(ch->base, CMCSR, value);
+	return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_count(ch->base, CMCNT, value);
+	ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_count(ch->base, CMCOR, value);
+	ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -287,7 +311,6 @@ static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
 static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 {
-	struct sh_timer_config *cfg = ch->cmt->pdev->dev.platform_data;
 	unsigned long flags, value;
 
 	/* start stop register shared by multiple timer channels */
@@ -295,9 +318,9 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 	value = sh_cmt_read_cmstr(ch);
 
 	if (start)
-		value |= 1 << cfg->timer_bit;
+		value |= 1 << ch->timer_bit;
 	else
-		value &= ~(1 << cfg->timer_bit);
+		value &= ~(1 << ch->timer_bit);
 
 	sh_cmt_write_cmstr(ch, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
@@ -792,28 +815,71 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
-	if (clockevent_rating)
+	if (clockevent_rating) {
+		ch->cmt->has_clockevent = true;
 		sh_cmt_register_clockevent(ch, name, clockevent_rating);
+	}
 
-	if (clocksource_rating)
+	if (clocksource_rating) {
+		ch->cmt->has_clocksource = true;
 		sh_cmt_register_clocksource(ch, name, clocksource_rating);
+	}
 
 	return 0;
 }
 
 static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
-				struct sh_cmt_device *cmt)
+				const struct sh_timer_channel_config *ch_cfg,
+				unsigned int hwidx, struct sh_cmt_device *cmt)
 {
-	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	unsigned long clockevent_rating;
+	unsigned long clocksource_rating;
 	int irq;
 	int ret;
 
 	ch->cmt = cmt;
-	ch->base = cmt->mapbase_ch;
-	ch->index = index;
+	ch->index = ch_cfg ? ch_cfg->index : index;
+	ch->hwidx = hwidx;
+
+	/*
+	 * Compute the address of the channel control register block. For the
+	 * timers with a per-channel start/stop register, compute its address
+	 * as well.
+	 *
+	 * For legacy configuration the address has been mapped explicitly.
+	 */
+	if (cmt->legacy) {
+		ch->ioctrl = cmt->mapbase_ch;
+	} else {
+		switch (cmt->info->model) {
+		case SH_CMT_16BIT:
+			ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+			break;
+		case SH_CMT_32BIT:
+		case SH_CMT_48BIT:
+			ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+			break;
+		case SH_CMT_32BIT_FAST:
+			/*
+			 * The 32-bit "fast" timer has a single channel at hwidx
+			 * 5 but is located at offset 0x40 instead of 0x60 for
+			 * some reason.
+			 */
+			ch->ioctrl = cmt->mapbase + 0x40;
+			break;
+		case SH_CMT_48BIT_GEN2:
+			ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+			ch->ioctrl = ch->iostart + 0x10;
+			break;
+		}
+	}
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
-	irq = platform_get_irq(cmt->pdev, 0);
+	if (cmt->legacy)
+		irq = platform_get_irq(cmt->pdev, 0);
+	else
+		irq = platform_get_irq(cmt->pdev, ch->index);
+
 	if (irq < 0) {
 		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		return irq;
@@ -832,9 +898,20 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
+	if (ch_cfg) {
+		ch->timer_bit = cmt->info->model = SH_CMT_48BIT_GEN2
+			      ? 0 : ch->hwidx;
+		clockevent_rating = ch_cfg->clockevent_rating;
+		clocksource_rating = ch_cfg->clocksource_rating;
+	} else {
+		struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+		ch->timer_bit = cfg->timer_bit;
+		clockevent_rating = cfg->clockevent_rating;
+		clocksource_rating = cfg->clocksource_rating;
+	}
+
 	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      cfg->clockevent_rating,
-			      cfg->clocksource_rating);
+			      clockevent_rating, clocksource_rating);
 	if (ret) {
 		dev_err(&cmt->pdev->dev, "registration failed\n");
 		return ret;
@@ -850,97 +927,169 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	return 0;
 }
 
-static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 {
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct resource *res, *res2;
-	int ret;
-	ret = -ENXIO;
+	struct resource *mem;
 
-	cmt->pdev = pdev;
+	mem = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
+		return -ENXIO;
+	}
 
-	if (!cfg) {
-		dev_err(&cmt->pdev->dev, "missing platform data\n");
-		goto err0;
+	cmt->mapbase = ioremap_nocache(mem->start, resource_size(mem));
+	if (cmt->mapbase = NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
+		return -ENXIO;
 	}
 
+	return 0;
+}
+
+static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
+{
+	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	struct resource *res, *res2;
+
+	/* map memory, let mapbase_ch point to our channel */
 	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
-		goto err0;
+		return -ENXIO;
 	}
 
-	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
-	/* map memory, let mapbase_ch point to our channel */
 	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
 	if (cmt->mapbase_ch = NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
-		goto err0;
+		return -ENXIO;
 	}
 
+	/* optional resource for the shared timer start/stop register */
+	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
+
 	/* map second resource for CMSTR */
 	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
 				       res->start - cfg->channel_offset,
 				       res2 ? resource_size(res2) : 2);
 	if (cmt->mapbase = NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
-		goto err1;
+		iounmap(cmt->mapbase_ch);
+		return -ENXIO;
 	}
 
-	/* get hold of clock */
+	/* identify the model based on the resources */
+	if (resource_size(res) = 6)
+		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
+	else if (res2 && (resource_size(res2) = 4))
+		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	else
+		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+
+	return 0;
+}
+
+static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
+{
+	iounmap(cmt->mapbase);
+	if (cmt->mapbase_ch)
+		iounmap(cmt->mapbase_ch);
+}
+
+static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+{
+	struct sh_timer_config *cfg = pdev->dev.platform_data;
+	const struct platform_device_id *id = pdev->id_entry;
+	int ret;
+
+	memset(cmt, 0, sizeof(*cmt));
+	cmt->pdev = pdev;
+
+	if (!cfg) {
+		dev_err(&cmt->pdev->dev, "missing platform data\n");
+		return -ENXIO;
+	}
+
+	cmt->info = (const struct sh_cmt_info *)id->driver_data;
+	cmt->legacy = cmt->info ? false : true;
+
+	/* Get hold of clock. */
 	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
-		ret = PTR_ERR(cmt->clk);
-		goto err2;
+		return PTR_ERR(cmt->clk);
 	}
 
 	ret = clk_prepare(cmt->clk);
 	if (ret < 0)
-		goto err3;
+		goto err_clk_put;
 
-	/* identify the model based on the resources */
-	if (resource_size(res) = 6)
-		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
-	else if (res2 && (resource_size(res2) = 4))
-		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	/*
+	 * Map the memory resource(s). We need to support both the legacy
+	 * platform device configuration (with one device per channel) and the
+	 * new version (with multiple channels per device).
+	 */
+	if (cmt->legacy)
+		ret = sh_cmt_map_memory_legacy(cmt);
 	else
-		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+		ret = sh_cmt_map_memory(cmt);
 
-	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
+	if (ret < 0)
+		goto err_clk_unprepare;
+
+	/* Allocate and setup the channels. */
+	if (cmt->legacy) {
+		cmt->num_channels = 1;
+	} else {
+		cmt->num_channels = cfg->num_channels;
+		cmt->hw_channels = ~cfg->channels_mask;
+	}
+
+	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
+				GFP_KERNEL);
 	if (cmt->channels = NULL) {
 		ret = -ENOMEM;
-		goto err4;
+		goto err_unmap;
 	}
 
-	cmt->num_channels = 1;
+	if (cmt->legacy) {
+		ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit,
+					   NULL, cfg->timer_bit, cmt);
+		if (ret < 0)
+			goto err_unmap;
+	} else {
+		const struct sh_timer_channel_config *ch_cfg = cfg->channels;
+		unsigned int mask = cmt->hw_channels;
+		unsigned int i;
+
+		for (i = 0; i < cmt->num_channels; ++i) {
+			unsigned int hwidx = ffs(mask) - 1;
 
-	ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit, cmt);
-	if (ret < 0)
-		goto err4;
+			ret = sh_cmt_setup_channel(&cmt->channels[i], 0, ch_cfg,
+						   hwidx, cmt);
+			if (ret < 0)
+				goto err_unmap;
+
+			mask &= ~(1 << hwidx);
+		}
+	}
 
 	platform_set_drvdata(pdev, cmt);
 
 	return 0;
-err4:
+
+err_unmap:
 	kfree(cmt->channels);
+	sh_cmt_unmap_memory(cmt);
+err_clk_unprepare:
 	clk_unprepare(cmt->clk);
-err3:
+err_clk_put:
 	clk_put(cmt->clk);
-err2:
-	iounmap(cmt->mapbase);
-err1:
-	iounmap(cmt->mapbase_ch);
-err0:
 	return ret;
 }
 
 static int sh_cmt_probe(struct platform_device *pdev)
 {
 	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	int ret;
 
 	if (!is_early_platform_device(pdev)) {
@@ -969,7 +1118,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		return 0;
 
  out:
-	if (cfg->clockevent_rating || cfg->clocksource_rating)
+	if (cmt->has_clockevent || cmt->has_clocksource)
 		pm_runtime_irq_safe(&pdev->dev);
 	else
 		pm_runtime_idle(&pdev->dev);
@@ -982,12 +1131,24 @@ static int sh_cmt_remove(struct platform_device *pdev)
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
+static const struct platform_device_id sh_cmt_id_table[] = {
+	{ "sh_cmt", 0 },
+	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
+
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= sh_cmt_remove,
 	.driver		= {
 		.name	= "sh_cmt",
-	}
+	},
+	.id_table	= sh_cmt_id_table,
 };
 
 static int __init sh_cmt_init(void)
diff --git a/include/linux/sh_timer.h b/include/linux/sh_timer.h
index 4d9dcd1..b8273e2 100644
--- a/include/linux/sh_timer.h
+++ b/include/linux/sh_timer.h
@@ -1,12 +1,21 @@
 #ifndef __SH_TIMER_H__
 #define __SH_TIMER_H__
 
+struct sh_timer_channel_config {
+	unsigned int index;
+	unsigned long clockevent_rating;
+	unsigned long clocksource_rating;
+};
+
 struct sh_timer_config {
 	char *name;
 	long channel_offset;
 	int timer_bit;
 	unsigned long clockevent_rating;
 	unsigned long clocksource_rating;
+	const struct sh_timer_channel_config *channels;
+	unsigned int num_channels;
+	unsigned int channels_mask;
 };
 
 #endif /* __SH_TIMER_H__ */
-- 
1.8.3.2


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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

CMT hardware devices can support multiple channels, with global
registers and per-channel registers. The sh_cmt driver currently models
the hardware with one Linux device per channel. This model makes it
difficult to handle global registers in a clean way.

Add support for a new model that uses one Linux device per timer with
multiple channels per device. This requires changes to platform data,
add new channel configuration fields.

Support for the legacy model is kept and will be removed after all
platforms switch to the new model.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++++++----------
 include/linux/sh_timer.h     |   9 ++
 2 files changed, 239 insertions(+), 69 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 5280231..8390f0f 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -53,7 +53,16 @@ struct sh_cmt_device;
  * channel registers block. All other versions have a shared start/stop register
  * located in the global space.
  *
- * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
+ * Channels are indexed from 0 to N-1 in the documentation. The channel index
+ * infers the start/stop bit position in the control register and the channel
+ * registers block address. Some CMT instances have a subset of channels
+ * available, in which case the index in the documentation doesn't match the
+ * "real" index as implemented in hardware. This is for instance the case with
+ * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
+ * in the documentation but using start/stop bit 5 and having its registers
+ * block at 0x60.
+ *
+ * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
  * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
  */
 
@@ -85,11 +94,15 @@ struct sh_cmt_info {
 
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
-	unsigned int index;
 
-	void __iomem *base;
+	unsigned int index;	/* Index in the documentation */
+	unsigned int hwidx;	/* Real hardware index */
+
+	void __iomem *iostart;
+	void __iomem *ioctrl;
 	struct irqaction irqaction;
 
+	unsigned int timer_bit;
 	unsigned long flags;
 	unsigned long match_value;
 	unsigned long next_match_value;
@@ -106,6 +119,7 @@ struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	const struct sh_cmt_info *info;
+	bool legacy;
 
 	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
@@ -113,6 +127,10 @@ struct sh_cmt_device {
 
 	struct sh_cmt_channel *channels;
 	unsigned int num_channels;
+	unsigned int hw_channels;
+
+	bool has_clockevent;
+	bool has_clocksource;
 };
 
 #define SH_CMT16_CMCSR_CMF		(1 << 7)
@@ -224,41 +242,47 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
+	if (ch->iostart)
+		return ch->cmt->info->read_control(ch->iostart, 0);
+	else
+		return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
 }
 
-static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
+				      unsigned long value)
 {
-	return ch->cmt->info->read_control(ch->base, CMCSR);
+	if (ch->iostart)
+		ch->cmt->info->write_control(ch->iostart, 0, value);
+	else
+		ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
 }
 
-static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->info->read_count(ch->base, CMCNT);
+	return ch->cmt->info->read_control(ch->ioctrl, CMCSR);
 }
 
-static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
+	ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
 }
 
-static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
-				      unsigned long value)
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	ch->cmt->info->write_control(ch->base, CMCSR, value);
+	return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_count(ch->base, CMCNT, value);
+	ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_count(ch->base, CMCOR, value);
+	ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -287,7 +311,6 @@ static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
 static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 {
-	struct sh_timer_config *cfg = ch->cmt->pdev->dev.platform_data;
 	unsigned long flags, value;
 
 	/* start stop register shared by multiple timer channels */
@@ -295,9 +318,9 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 	value = sh_cmt_read_cmstr(ch);
 
 	if (start)
-		value |= 1 << cfg->timer_bit;
+		value |= 1 << ch->timer_bit;
 	else
-		value &= ~(1 << cfg->timer_bit);
+		value &= ~(1 << ch->timer_bit);
 
 	sh_cmt_write_cmstr(ch, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
@@ -792,28 +815,71 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
-	if (clockevent_rating)
+	if (clockevent_rating) {
+		ch->cmt->has_clockevent = true;
 		sh_cmt_register_clockevent(ch, name, clockevent_rating);
+	}
 
-	if (clocksource_rating)
+	if (clocksource_rating) {
+		ch->cmt->has_clocksource = true;
 		sh_cmt_register_clocksource(ch, name, clocksource_rating);
+	}
 
 	return 0;
 }
 
 static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
-				struct sh_cmt_device *cmt)
+				const struct sh_timer_channel_config *ch_cfg,
+				unsigned int hwidx, struct sh_cmt_device *cmt)
 {
-	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	unsigned long clockevent_rating;
+	unsigned long clocksource_rating;
 	int irq;
 	int ret;
 
 	ch->cmt = cmt;
-	ch->base = cmt->mapbase_ch;
-	ch->index = index;
+	ch->index = ch_cfg ? ch_cfg->index : index;
+	ch->hwidx = hwidx;
+
+	/*
+	 * Compute the address of the channel control register block. For the
+	 * timers with a per-channel start/stop register, compute its address
+	 * as well.
+	 *
+	 * For legacy configuration the address has been mapped explicitly.
+	 */
+	if (cmt->legacy) {
+		ch->ioctrl = cmt->mapbase_ch;
+	} else {
+		switch (cmt->info->model) {
+		case SH_CMT_16BIT:
+			ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+			break;
+		case SH_CMT_32BIT:
+		case SH_CMT_48BIT:
+			ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+			break;
+		case SH_CMT_32BIT_FAST:
+			/*
+			 * The 32-bit "fast" timer has a single channel at hwidx
+			 * 5 but is located at offset 0x40 instead of 0x60 for
+			 * some reason.
+			 */
+			ch->ioctrl = cmt->mapbase + 0x40;
+			break;
+		case SH_CMT_48BIT_GEN2:
+			ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+			ch->ioctrl = ch->iostart + 0x10;
+			break;
+		}
+	}
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
-	irq = platform_get_irq(cmt->pdev, 0);
+	if (cmt->legacy)
+		irq = platform_get_irq(cmt->pdev, 0);
+	else
+		irq = platform_get_irq(cmt->pdev, ch->index);
+
 	if (irq < 0) {
 		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		return irq;
@@ -832,9 +898,20 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
+	if (ch_cfg) {
+		ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2
+			      ? 0 : ch->hwidx;
+		clockevent_rating = ch_cfg->clockevent_rating;
+		clocksource_rating = ch_cfg->clocksource_rating;
+	} else {
+		struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+		ch->timer_bit = cfg->timer_bit;
+		clockevent_rating = cfg->clockevent_rating;
+		clocksource_rating = cfg->clocksource_rating;
+	}
+
 	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      cfg->clockevent_rating,
-			      cfg->clocksource_rating);
+			      clockevent_rating, clocksource_rating);
 	if (ret) {
 		dev_err(&cmt->pdev->dev, "registration failed\n");
 		return ret;
@@ -850,97 +927,169 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	return 0;
 }
 
-static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 {
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct resource *res, *res2;
-	int ret;
-	ret = -ENXIO;
+	struct resource *mem;
 
-	cmt->pdev = pdev;
+	mem = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
+		return -ENXIO;
+	}
 
-	if (!cfg) {
-		dev_err(&cmt->pdev->dev, "missing platform data\n");
-		goto err0;
+	cmt->mapbase = ioremap_nocache(mem->start, resource_size(mem));
+	if (cmt->mapbase == NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
+		return -ENXIO;
 	}
 
+	return 0;
+}
+
+static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
+{
+	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	struct resource *res, *res2;
+
+	/* map memory, let mapbase_ch point to our channel */
 	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
-		goto err0;
+		return -ENXIO;
 	}
 
-	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
-	/* map memory, let mapbase_ch point to our channel */
 	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
 	if (cmt->mapbase_ch == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
-		goto err0;
+		return -ENXIO;
 	}
 
+	/* optional resource for the shared timer start/stop register */
+	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
+
 	/* map second resource for CMSTR */
 	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
 				       res->start - cfg->channel_offset,
 				       res2 ? resource_size(res2) : 2);
 	if (cmt->mapbase == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
-		goto err1;
+		iounmap(cmt->mapbase_ch);
+		return -ENXIO;
 	}
 
-	/* get hold of clock */
+	/* identify the model based on the resources */
+	if (resource_size(res) == 6)
+		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
+	else if (res2 && (resource_size(res2) == 4))
+		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	else
+		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+
+	return 0;
+}
+
+static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
+{
+	iounmap(cmt->mapbase);
+	if (cmt->mapbase_ch)
+		iounmap(cmt->mapbase_ch);
+}
+
+static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+{
+	struct sh_timer_config *cfg = pdev->dev.platform_data;
+	const struct platform_device_id *id = pdev->id_entry;
+	int ret;
+
+	memset(cmt, 0, sizeof(*cmt));
+	cmt->pdev = pdev;
+
+	if (!cfg) {
+		dev_err(&cmt->pdev->dev, "missing platform data\n");
+		return -ENXIO;
+	}
+
+	cmt->info = (const struct sh_cmt_info *)id->driver_data;
+	cmt->legacy = cmt->info ? false : true;
+
+	/* Get hold of clock. */
 	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
-		ret = PTR_ERR(cmt->clk);
-		goto err2;
+		return PTR_ERR(cmt->clk);
 	}
 
 	ret = clk_prepare(cmt->clk);
 	if (ret < 0)
-		goto err3;
+		goto err_clk_put;
 
-	/* identify the model based on the resources */
-	if (resource_size(res) == 6)
-		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
-	else if (res2 && (resource_size(res2) == 4))
-		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	/*
+	 * Map the memory resource(s). We need to support both the legacy
+	 * platform device configuration (with one device per channel) and the
+	 * new version (with multiple channels per device).
+	 */
+	if (cmt->legacy)
+		ret = sh_cmt_map_memory_legacy(cmt);
 	else
-		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+		ret = sh_cmt_map_memory(cmt);
 
-	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
+	if (ret < 0)
+		goto err_clk_unprepare;
+
+	/* Allocate and setup the channels. */
+	if (cmt->legacy) {
+		cmt->num_channels = 1;
+	} else {
+		cmt->num_channels = cfg->num_channels;
+		cmt->hw_channels = ~cfg->channels_mask;
+	}
+
+	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
+				GFP_KERNEL);
 	if (cmt->channels == NULL) {
 		ret = -ENOMEM;
-		goto err4;
+		goto err_unmap;
 	}
 
-	cmt->num_channels = 1;
+	if (cmt->legacy) {
+		ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit,
+					   NULL, cfg->timer_bit, cmt);
+		if (ret < 0)
+			goto err_unmap;
+	} else {
+		const struct sh_timer_channel_config *ch_cfg = cfg->channels;
+		unsigned int mask = cmt->hw_channels;
+		unsigned int i;
+
+		for (i = 0; i < cmt->num_channels; ++i) {
+			unsigned int hwidx = ffs(mask) - 1;
 
-	ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit, cmt);
-	if (ret < 0)
-		goto err4;
+			ret = sh_cmt_setup_channel(&cmt->channels[i], 0, ch_cfg,
+						   hwidx, cmt);
+			if (ret < 0)
+				goto err_unmap;
+
+			mask &= ~(1 << hwidx);
+		}
+	}
 
 	platform_set_drvdata(pdev, cmt);
 
 	return 0;
-err4:
+
+err_unmap:
 	kfree(cmt->channels);
+	sh_cmt_unmap_memory(cmt);
+err_clk_unprepare:
 	clk_unprepare(cmt->clk);
-err3:
+err_clk_put:
 	clk_put(cmt->clk);
-err2:
-	iounmap(cmt->mapbase);
-err1:
-	iounmap(cmt->mapbase_ch);
-err0:
 	return ret;
 }
 
 static int sh_cmt_probe(struct platform_device *pdev)
 {
 	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	int ret;
 
 	if (!is_early_platform_device(pdev)) {
@@ -969,7 +1118,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		return 0;
 
  out:
-	if (cfg->clockevent_rating || cfg->clocksource_rating)
+	if (cmt->has_clockevent || cmt->has_clocksource)
 		pm_runtime_irq_safe(&pdev->dev);
 	else
 		pm_runtime_idle(&pdev->dev);
@@ -982,12 +1131,24 @@ static int sh_cmt_remove(struct platform_device *pdev)
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
+static const struct platform_device_id sh_cmt_id_table[] = {
+	{ "sh_cmt", 0 },
+	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
+
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= sh_cmt_remove,
 	.driver		= {
 		.name	= "sh_cmt",
-	}
+	},
+	.id_table	= sh_cmt_id_table,
 };
 
 static int __init sh_cmt_init(void)
diff --git a/include/linux/sh_timer.h b/include/linux/sh_timer.h
index 4d9dcd1..b8273e2 100644
--- a/include/linux/sh_timer.h
+++ b/include/linux/sh_timer.h
@@ -1,12 +1,21 @@
 #ifndef __SH_TIMER_H__
 #define __SH_TIMER_H__
 
+struct sh_timer_channel_config {
+	unsigned int index;
+	unsigned long clockevent_rating;
+	unsigned long clocksource_rating;
+};
+
 struct sh_timer_config {
 	char *name;
 	long channel_offset;
 	int timer_bit;
 	unsigned long clockevent_rating;
 	unsigned long clocksource_rating;
+	const struct sh_timer_channel_config *channels;
+	unsigned int num_channels;
+	unsigned int channels_mask;
 };
 
 #endif /* __SH_TIMER_H__ */
-- 
1.8.3.2


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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

CMT hardware devices can support multiple channels, with global
registers and per-channel registers. The sh_cmt driver currently models
the hardware with one Linux device per channel. This model makes it
difficult to handle global registers in a clean way.

Add support for a new model that uses one Linux device per timer with
multiple channels per device. This requires changes to platform data,
add new channel configuration fields.

Support for the legacy model is kept and will be removed after all
platforms switch to the new model.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++++++----------
 include/linux/sh_timer.h     |   9 ++
 2 files changed, 239 insertions(+), 69 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 5280231..8390f0f 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -53,7 +53,16 @@ struct sh_cmt_device;
  * channel registers block. All other versions have a shared start/stop register
  * located in the global space.
  *
- * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
+ * Channels are indexed from 0 to N-1 in the documentation. The channel index
+ * infers the start/stop bit position in the control register and the channel
+ * registers block address. Some CMT instances have a subset of channels
+ * available, in which case the index in the documentation doesn't match the
+ * "real" index as implemented in hardware. This is for instance the case with
+ * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
+ * in the documentation but using start/stop bit 5 and having its registers
+ * block at 0x60.
+ *
+ * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
  * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
  */
 
@@ -85,11 +94,15 @@ struct sh_cmt_info {
 
 struct sh_cmt_channel {
 	struct sh_cmt_device *cmt;
-	unsigned int index;
 
-	void __iomem *base;
+	unsigned int index;	/* Index in the documentation */
+	unsigned int hwidx;	/* Real hardware index */
+
+	void __iomem *iostart;
+	void __iomem *ioctrl;
 	struct irqaction irqaction;
 
+	unsigned int timer_bit;
 	unsigned long flags;
 	unsigned long match_value;
 	unsigned long next_match_value;
@@ -106,6 +119,7 @@ struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	const struct sh_cmt_info *info;
+	bool legacy;
 
 	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
@@ -113,6 +127,10 @@ struct sh_cmt_device {
 
 	struct sh_cmt_channel *channels;
 	unsigned int num_channels;
+	unsigned int hw_channels;
+
+	bool has_clockevent;
+	bool has_clocksource;
 };
 
 #define SH_CMT16_CMCSR_CMF		(1 << 7)
@@ -224,41 +242,47 @@ static const struct sh_cmt_info sh_cmt_info[] = {
 
 static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
+	if (ch->iostart)
+		return ch->cmt->info->read_control(ch->iostart, 0);
+	else
+		return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
 }
 
-static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
+				      unsigned long value)
 {
-	return ch->cmt->info->read_control(ch->base, CMCSR);
+	if (ch->iostart)
+		ch->cmt->info->write_control(ch->iostart, 0, value);
+	else
+		ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
 }
 
-static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
 {
-	return ch->cmt->info->read_count(ch->base, CMCNT);
+	return ch->cmt->info->read_control(ch->ioctrl, CMCSR);
 }
 
-static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
+	ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
 }
 
-static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
-				      unsigned long value)
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
 {
-	ch->cmt->info->write_control(ch->base, CMCSR, value);
+	return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
 }
 
 static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_count(ch->base, CMCNT, value);
+	ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
 }
 
 static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
 				      unsigned long value)
 {
-	ch->cmt->info->write_count(ch->base, CMCOR, value);
+	ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
 }
 
 static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -287,7 +311,6 @@ static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
 
 static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 {
-	struct sh_timer_config *cfg = ch->cmt->pdev->dev.platform_data;
 	unsigned long flags, value;
 
 	/* start stop register shared by multiple timer channels */
@@ -295,9 +318,9 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
 	value = sh_cmt_read_cmstr(ch);
 
 	if (start)
-		value |= 1 << cfg->timer_bit;
+		value |= 1 << ch->timer_bit;
 	else
-		value &= ~(1 << cfg->timer_bit);
+		value &= ~(1 << ch->timer_bit);
 
 	sh_cmt_write_cmstr(ch, value);
 	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
@@ -792,28 +815,71 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 			   unsigned long clockevent_rating,
 			   unsigned long clocksource_rating)
 {
-	if (clockevent_rating)
+	if (clockevent_rating) {
+		ch->cmt->has_clockevent = true;
 		sh_cmt_register_clockevent(ch, name, clockevent_rating);
+	}
 
-	if (clocksource_rating)
+	if (clocksource_rating) {
+		ch->cmt->has_clocksource = true;
 		sh_cmt_register_clocksource(ch, name, clocksource_rating);
+	}
 
 	return 0;
 }
 
 static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
-				struct sh_cmt_device *cmt)
+				const struct sh_timer_channel_config *ch_cfg,
+				unsigned int hwidx, struct sh_cmt_device *cmt)
 {
-	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	unsigned long clockevent_rating;
+	unsigned long clocksource_rating;
 	int irq;
 	int ret;
 
 	ch->cmt = cmt;
-	ch->base = cmt->mapbase_ch;
-	ch->index = index;
+	ch->index = ch_cfg ? ch_cfg->index : index;
+	ch->hwidx = hwidx;
+
+	/*
+	 * Compute the address of the channel control register block. For the
+	 * timers with a per-channel start/stop register, compute its address
+	 * as well.
+	 *
+	 * For legacy configuration the address has been mapped explicitly.
+	 */
+	if (cmt->legacy) {
+		ch->ioctrl = cmt->mapbase_ch;
+	} else {
+		switch (cmt->info->model) {
+		case SH_CMT_16BIT:
+			ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+			break;
+		case SH_CMT_32BIT:
+		case SH_CMT_48BIT:
+			ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+			break;
+		case SH_CMT_32BIT_FAST:
+			/*
+			 * The 32-bit "fast" timer has a single channel at hwidx
+			 * 5 but is located at offset 0x40 instead of 0x60 for
+			 * some reason.
+			 */
+			ch->ioctrl = cmt->mapbase + 0x40;
+			break;
+		case SH_CMT_48BIT_GEN2:
+			ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+			ch->ioctrl = ch->iostart + 0x10;
+			break;
+		}
+	}
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
-	irq = platform_get_irq(cmt->pdev, 0);
+	if (cmt->legacy)
+		irq = platform_get_irq(cmt->pdev, 0);
+	else
+		irq = platform_get_irq(cmt->pdev, ch->index);
+
 	if (irq < 0) {
 		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		return irq;
@@ -832,9 +898,20 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
+	if (ch_cfg) {
+		ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2
+			      ? 0 : ch->hwidx;
+		clockevent_rating = ch_cfg->clockevent_rating;
+		clocksource_rating = ch_cfg->clocksource_rating;
+	} else {
+		struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+		ch->timer_bit = cfg->timer_bit;
+		clockevent_rating = cfg->clockevent_rating;
+		clocksource_rating = cfg->clocksource_rating;
+	}
+
 	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      cfg->clockevent_rating,
-			      cfg->clocksource_rating);
+			      clockevent_rating, clocksource_rating);
 	if (ret) {
 		dev_err(&cmt->pdev->dev, "registration failed\n");
 		return ret;
@@ -850,97 +927,169 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	return 0;
 }
 
-static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 {
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	struct resource *res, *res2;
-	int ret;
-	ret = -ENXIO;
+	struct resource *mem;
 
-	cmt->pdev = pdev;
+	mem = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
+		return -ENXIO;
+	}
 
-	if (!cfg) {
-		dev_err(&cmt->pdev->dev, "missing platform data\n");
-		goto err0;
+	cmt->mapbase = ioremap_nocache(mem->start, resource_size(mem));
+	if (cmt->mapbase == NULL) {
+		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
+		return -ENXIO;
 	}
 
+	return 0;
+}
+
+static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
+{
+	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
+	struct resource *res, *res2;
+
+	/* map memory, let mapbase_ch point to our channel */
 	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
-		goto err0;
+		return -ENXIO;
 	}
 
-	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
-	/* map memory, let mapbase_ch point to our channel */
 	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
 	if (cmt->mapbase_ch == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
-		goto err0;
+		return -ENXIO;
 	}
 
+	/* optional resource for the shared timer start/stop register */
+	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
+
 	/* map second resource for CMSTR */
 	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
 				       res->start - cfg->channel_offset,
 				       res2 ? resource_size(res2) : 2);
 	if (cmt->mapbase == NULL) {
 		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
-		goto err1;
+		iounmap(cmt->mapbase_ch);
+		return -ENXIO;
 	}
 
-	/* get hold of clock */
+	/* identify the model based on the resources */
+	if (resource_size(res) == 6)
+		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
+	else if (res2 && (resource_size(res2) == 4))
+		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	else
+		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+
+	return 0;
+}
+
+static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
+{
+	iounmap(cmt->mapbase);
+	if (cmt->mapbase_ch)
+		iounmap(cmt->mapbase_ch);
+}
+
+static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+{
+	struct sh_timer_config *cfg = pdev->dev.platform_data;
+	const struct platform_device_id *id = pdev->id_entry;
+	int ret;
+
+	memset(cmt, 0, sizeof(*cmt));
+	cmt->pdev = pdev;
+
+	if (!cfg) {
+		dev_err(&cmt->pdev->dev, "missing platform data\n");
+		return -ENXIO;
+	}
+
+	cmt->info = (const struct sh_cmt_info *)id->driver_data;
+	cmt->legacy = cmt->info ? false : true;
+
+	/* Get hold of clock. */
 	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
-		ret = PTR_ERR(cmt->clk);
-		goto err2;
+		return PTR_ERR(cmt->clk);
 	}
 
 	ret = clk_prepare(cmt->clk);
 	if (ret < 0)
-		goto err3;
+		goto err_clk_put;
 
-	/* identify the model based on the resources */
-	if (resource_size(res) == 6)
-		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
-	else if (res2 && (resource_size(res2) == 4))
-		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
+	/*
+	 * Map the memory resource(s). We need to support both the legacy
+	 * platform device configuration (with one device per channel) and the
+	 * new version (with multiple channels per device).
+	 */
+	if (cmt->legacy)
+		ret = sh_cmt_map_memory_legacy(cmt);
 	else
-		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+		ret = sh_cmt_map_memory(cmt);
 
-	cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
+	if (ret < 0)
+		goto err_clk_unprepare;
+
+	/* Allocate and setup the channels. */
+	if (cmt->legacy) {
+		cmt->num_channels = 1;
+	} else {
+		cmt->num_channels = cfg->num_channels;
+		cmt->hw_channels = ~cfg->channels_mask;
+	}
+
+	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
+				GFP_KERNEL);
 	if (cmt->channels == NULL) {
 		ret = -ENOMEM;
-		goto err4;
+		goto err_unmap;
 	}
 
-	cmt->num_channels = 1;
+	if (cmt->legacy) {
+		ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit,
+					   NULL, cfg->timer_bit, cmt);
+		if (ret < 0)
+			goto err_unmap;
+	} else {
+		const struct sh_timer_channel_config *ch_cfg = cfg->channels;
+		unsigned int mask = cmt->hw_channels;
+		unsigned int i;
+
+		for (i = 0; i < cmt->num_channels; ++i) {
+			unsigned int hwidx = ffs(mask) - 1;
 
-	ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit, cmt);
-	if (ret < 0)
-		goto err4;
+			ret = sh_cmt_setup_channel(&cmt->channels[i], 0, ch_cfg,
+						   hwidx, cmt);
+			if (ret < 0)
+				goto err_unmap;
+
+			mask &= ~(1 << hwidx);
+		}
+	}
 
 	platform_set_drvdata(pdev, cmt);
 
 	return 0;
-err4:
+
+err_unmap:
 	kfree(cmt->channels);
+	sh_cmt_unmap_memory(cmt);
+err_clk_unprepare:
 	clk_unprepare(cmt->clk);
-err3:
+err_clk_put:
 	clk_put(cmt->clk);
-err2:
-	iounmap(cmt->mapbase);
-err1:
-	iounmap(cmt->mapbase_ch);
-err0:
 	return ret;
 }
 
 static int sh_cmt_probe(struct platform_device *pdev)
 {
 	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	int ret;
 
 	if (!is_early_platform_device(pdev)) {
@@ -969,7 +1118,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
 		return 0;
 
  out:
-	if (cfg->clockevent_rating || cfg->clocksource_rating)
+	if (cmt->has_clockevent || cmt->has_clocksource)
 		pm_runtime_irq_safe(&pdev->dev);
 	else
 		pm_runtime_idle(&pdev->dev);
@@ -982,12 +1131,24 @@ static int sh_cmt_remove(struct platform_device *pdev)
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
+static const struct platform_device_id sh_cmt_id_table[] = {
+	{ "sh_cmt", 0 },
+	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
+
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= sh_cmt_remove,
 	.driver		= {
 		.name	= "sh_cmt",
-	}
+	},
+	.id_table	= sh_cmt_id_table,
 };
 
 static int __init sh_cmt_init(void)
diff --git a/include/linux/sh_timer.h b/include/linux/sh_timer.h
index 4d9dcd1..b8273e2 100644
--- a/include/linux/sh_timer.h
+++ b/include/linux/sh_timer.h
@@ -1,12 +1,21 @@
 #ifndef __SH_TIMER_H__
 #define __SH_TIMER_H__
 
+struct sh_timer_channel_config {
+	unsigned int index;
+	unsigned long clockevent_rating;
+	unsigned long clocksource_rating;
+};
+
 struct sh_timer_config {
 	char *name;
 	long channel_offset;
 	int timer_bit;
 	unsigned long clockevent_rating;
 	unsigned long clocksource_rating;
+	const struct sh_timer_channel_config *channels;
+	unsigned int num_channels;
+	unsigned int channels_mask;
 };
 
 #endif /* __SH_TIMER_H__ */
-- 
1.8.3.2

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

* [PATCH 12/27] clocksource: sh_cmt: Acquire default clock in the non-legacy case
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The sh_cmt driver gets the CMT functional clock using a connection ID of
"cmt_fck". While all SH SoCs create clock lookup entries with a NULL
device ID and a "cmt_fck" connection ID, the ARM SoCs use the device ID
only with a NULL connection ID. This works on legacy platforms but will
break on ARM with DT boot.

Fix the situation by using a NULL connection ID in the non-legacy
platform data case. Clock lookup entries will be renamed as platforms
get moved to new platform data. The legacy code will eventually be
dropped, leaving us with device ID based clock lookup only, compatible
with DT boot.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 8390f0f..2389e33 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -1013,7 +1013,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	cmt->legacy = cmt->info ? false : true;
 
 	/* Get hold of clock. */
-	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
+	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : NULL);
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
 		return PTR_ERR(cmt->clk);
-- 
1.8.3.2


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

* [PATCH 12/27] clocksource: sh_cmt: Acquire default clock in the non-legacy case
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The sh_cmt driver gets the CMT functional clock using a connection ID of
"cmt_fck". While all SH SoCs create clock lookup entries with a NULL
device ID and a "cmt_fck" connection ID, the ARM SoCs use the device ID
only with a NULL connection ID. This works on legacy platforms but will
break on ARM with DT boot.

Fix the situation by using a NULL connection ID in the non-legacy
platform data case. Clock lookup entries will be renamed as platforms
get moved to new platform data. The legacy code will eventually be
dropped, leaving us with device ID based clock lookup only, compatible
with DT boot.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 8390f0f..2389e33 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -1013,7 +1013,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	cmt->legacy = cmt->info ? false : true;
 
 	/* Get hold of clock. */
-	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
+	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : NULL);
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
 		return PTR_ERR(cmt->clk);
-- 
1.8.3.2


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

* [PATCH 12/27] clocksource: sh_cmt: Acquire default clock in the non-legacy case
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The sh_cmt driver gets the CMT functional clock using a connection ID of
"cmt_fck". While all SH SoCs create clock lookup entries with a NULL
device ID and a "cmt_fck" connection ID, the ARM SoCs use the device ID
only with a NULL connection ID. This works on legacy platforms but will
break on ARM with DT boot.

Fix the situation by using a NULL connection ID in the non-legacy
platform data case. Clock lookup entries will be renamed as platforms
get moved to new platform data. The legacy code will eventually be
dropped, leaving us with device ID based clock lookup only, compatible
with DT boot.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 8390f0f..2389e33 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -1013,7 +1013,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	cmt->legacy = cmt->info ? false : true;
 
 	/* Get hold of clock. */
-	cmt->clk = clk_get(&cmt->pdev->dev, "cmt_fck");
+	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : NULL);
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
 		return PTR_ERR(cmt->clk);
-- 
1.8.3.2

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

* [PATCH 13/27] clocksource: sh_cmt: Remove FSF mail address from GPL notice
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Do not include the paragraph about writing to the Free Software
Foundation's mailing address from the sample GPL notice. The FSF has
changed addresses in the past, and may do so again. Linux already
includes a copy of the GPL.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 2389e33..9f5616b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -11,10 +11,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/init.h>
-- 
1.8.3.2


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

* [PATCH 13/27] clocksource: sh_cmt: Remove FSF mail address from GPL notice
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Do not include the paragraph about writing to the Free Software
Foundation's mailing address from the sample GPL notice. The FSF has
changed addresses in the past, and may do so again. Linux already
includes a copy of the GPL.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 2389e33..9f5616b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -11,10 +11,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/init.h>
-- 
1.8.3.2


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

* [PATCH 13/27] clocksource: sh_cmt: Remove FSF mail address from GPL notice
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

Do not include the paragraph about writing to the Free Software
Foundation's mailing address from the sample GPL notice. The FSF has
changed addresses in the past, and may do so again. Linux already
includes a copy of the GPL.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 2389e33..9f5616b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -11,10 +11,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/init.h>
-- 
1.8.3.2

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

* [PATCH 14/27] clocksource: sh_cmt: Sort headers alphabetically
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

This helps locating duplicates and inserting new headers.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 9f5616b..077879b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -13,23 +13,23 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
 #include <linux/io.h>
-#include <linux/clk.h>
+#include <linux/ioport.h>
 #include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/sh_timer.h>
-#include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_timer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
 
 struct sh_cmt_device;
 
-- 
1.8.3.2


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

* [PATCH 14/27] clocksource: sh_cmt: Sort headers alphabetically
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

This helps locating duplicates and inserting new headers.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 9f5616b..077879b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -13,23 +13,23 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
 #include <linux/io.h>
-#include <linux/clk.h>
+#include <linux/ioport.h>
 #include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/sh_timer.h>
-#include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_timer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
 
 struct sh_cmt_device;
 
-- 
1.8.3.2


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

* [PATCH 14/27] clocksource: sh_cmt: Sort headers alphabetically
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

This helps locating duplicates and inserting new headers.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 9f5616b..077879b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -13,23 +13,23 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
 #include <linux/io.h>
-#include <linux/clk.h>
+#include <linux/ioport.h>
 #include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/sh_timer.h>
-#include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_timer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
 
 struct sh_cmt_device;
 
-- 
1.8.3.2

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

* [PATCH 15/27] sh: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/sh/kernel/cpu/clock-cpg.c         |   3 +-
 arch/sh/kernel/cpu/sh2/setup-sh7619.c  |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/clock-sh7264.c |   2 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7269.c |   2 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7203.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7206.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7264.c |  76 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7269.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh3/setup-sh7720.c  | 155 ++++-----------------------------
 arch/sh/kernel/cpu/sh4a/clock-sh7343.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7366.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7723.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c |   2 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7343.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7366.c |  27 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7722.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7723.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7724.c |  28 +++---
 19 files changed, 207 insertions(+), 472 deletions(-)

diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index f59b1f3..3f425f5 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -58,7 +58,8 @@ int __init __deprecated cpg_clk_init(void)
 
 	clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL);
 	clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL);
-	clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL);
+	clk_add_alias(NULL, "sh-cmt-16.0", "peripheral_clk", NULL);
+	clk_add_alias(NULL, "sh-cmt-32.0", "peripheral_clk", NULL);
 	clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL);
 
 	return ret;
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 3860b0b..73bdf66 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -152,62 +152,35 @@ static struct platform_device eth_device = {
 	.resource = eth_resources,
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xf84a0072,
-		.end	= 0xf84a0077,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 86,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xf84a0078,
-		.end	= 0xf84a007d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 87,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xf84a0078, 0x10),
+	DEFINE_RES_IRQ(86),
+	DEFINE_RES_IRQ(87),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct platform_device *sh7619_devices[] __initdata = {
@@ -215,8 +188,7 @@ static struct platform_device *sh7619_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&eth_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 };
 
 static int __init sh7619_devices_setup(void)
@@ -235,8 +207,7 @@ static struct platform_device *sh7619_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
 	&scif2_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 };
 
 #define STBCR3 0xf80a0000
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
index fdf585c..b8dcd34 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
@@ -117,7 +117,7 @@ static struct clk_lookup lookups[] = {
 	/* MSTP clocks */
 	CLKDEV_CON_ID("sci_ick", &mstp_clks[MSTP77]),
 	CLKDEV_CON_ID("vdc3", &mstp_clks[MSTP74]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP72]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[MSTP72]),
 	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
 	CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP35]),
 	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP34]),
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
index 6b78762..f7346b4 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
@@ -158,7 +158,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP72]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[MSTP72]),
 	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
 	CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP35]),
 	CLKDEV_CON_ID("adc0", &mstp_clks[MSTP32]),
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index d55a0f3..ef9d37a 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -265,62 +265,35 @@ static struct platform_device scif3_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 142,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 143,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(142),
+	DEFINE_RES_IRQ(143),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -404,8 +377,7 @@ static struct platform_device *sh7203_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -428,8 +400,7 @@ static struct platform_device *sh7203_early_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 241e745..f8c93a4 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -217,62 +217,35 @@ static struct platform_device scif3_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 140,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 144,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(140),
+	DEFINE_RES_IRQ(144),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -364,8 +337,7 @@ static struct platform_device *sh7206_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
@@ -388,8 +360,7 @@ static struct platform_device *sh7206_early_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
index ad5b0f4..838d05f 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
@@ -433,65 +433,35 @@ static struct platform_device scif7_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.name	= "CMT0",
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 175,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.name = "CMT1",
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.name	= "CMT1",
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 176,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(175),
+	DEFINE_RES_IRQ(176),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -620,8 +590,7 @@ static struct platform_device *sh7264_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -649,8 +618,7 @@ static struct platform_device *sh7264_early_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
index 3995119..3e66297 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
@@ -455,62 +455,35 @@ static struct platform_device scif7_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 188,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 189,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(188),
+	DEFINE_RES_IRQ(189),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -629,8 +602,7 @@ static struct platform_device *sh7269_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -658,8 +630,7 @@ static struct platform_device *sh7269_early_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 1d5729d..3cafd93 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -152,141 +152,32 @@ static struct platform_device usbf_device = {
 	.resource	= usbf_resources,
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0x044a0010,
-		.end	= 0x044a001b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
-	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
-};
-
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x20,
-	.timer_bit = 1,
-};
-
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0x044a0020,
-		.end	= 0x044a002b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
-	.dev = {
-		.platform_data	= &cmt1_platform_data,
-	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
-};
-
-static struct sh_timer_config cmt2_platform_data = {
-	.channel_offset = 0x30,
-	.timer_bit = 2,
-};
-
-static struct resource cmt2_resources[] = {
-	[0] = {
-		.start	= 0x044a0030,
-		.end	= 0x044a003b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
 	},
 };
 
-static struct platform_device cmt2_device = {
-	.name		= "sh_cmt",
-	.id		= 2,
-	.dev = {
-		.platform_data	= &cmt2_platform_data,
-	},
-	.resource	= cmt2_resources,
-	.num_resources	= ARRAY_SIZE(cmt2_resources),
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct sh_timer_config cmt3_platform_data = {
-	.channel_offset = 0x40,
-	.timer_bit = 3,
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0x044a0000, 0x60),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
-static struct resource cmt3_resources[] = {
-	[0] = {
-		.start	= 0x044a0040,
-		.end	= 0x044a004b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt3_device = {
-	.name		= "sh_cmt",
-	.id		= 3,
-	.dev = {
-		.platform_data	= &cmt3_platform_data,
-	},
-	.resource	= cmt3_resources,
-	.num_resources	= ARRAY_SIZE(cmt3_resources),
-};
-
-static struct sh_timer_config cmt4_platform_data = {
-	.channel_offset = 0x50,
-	.timer_bit = 4,
-};
-
-static struct resource cmt4_resources[] = {
-	[0] = {
-		.start	= 0x044a0050,
-		.end	= 0x044a005b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt4_device = {
-	.name		= "sh_cmt",
-	.id		= 4,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-32",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt4_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt4_resources,
-	.num_resources	= ARRAY_SIZE(cmt4_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -375,11 +266,7 @@ static struct platform_device tmu2_device = {
 static struct platform_device *sh7720_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
-	&cmt0_device,
-	&cmt1_device,
-	&cmt2_device,
-	&cmt3_device,
-	&cmt4_device,
+	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -398,11 +285,7 @@ arch_initcall(sh7720_devices_setup);
 static struct platform_device *sh7720_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
-	&cmt0_device,
-	&cmt1_device,
-	&cmt2_device,
-	&cmt3_device,
-	&cmt4_device,
+	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 53638e2..1628f82 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -227,7 +227,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+	CLKDEV_DEV_ID("sh-cmt-32.0k", &mstp_clks[MSTP014]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 22e485d..8a9e8af 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -225,7 +225,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[MSTP014]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index c4cb740..e40bd2a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -207,7 +207,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU]),
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]),
 
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
 
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 37c41c7..3e0a6d8 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -236,7 +236,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
 	CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 0128af3..e836d64 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -309,7 +309,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
 
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
 
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 245d192..820ce40 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -227,27 +227,27 @@ static struct platform_device jpu_device = {
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 6f56cbd..c878686 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -175,27 +175,26 @@ static struct platform_device veu1_device = {
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 5,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 5a94efc..1c0e14b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -412,27 +412,27 @@ static struct platform_device jpu_device = {
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 3c5eb09..9c08917 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -244,27 +244,27 @@ static struct platform_device veu1_device = {
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 60ebbc6..be587a9 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -647,27 +647,27 @@ static struct platform_device beu1_device = {
 	.num_resources	= ARRAY_SIZE(beu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
-- 
1.8.3.2


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

* [PATCH 15/27] sh: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/sh/kernel/cpu/clock-cpg.c         |   3 +-
 arch/sh/kernel/cpu/sh2/setup-sh7619.c  |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/clock-sh7264.c |   2 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7269.c |   2 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7203.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7206.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7264.c |  76 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7269.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh3/setup-sh7720.c  | 155 ++++-----------------------------
 arch/sh/kernel/cpu/sh4a/clock-sh7343.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7366.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7723.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c |   2 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7343.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7366.c |  27 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7722.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7723.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7724.c |  28 +++---
 19 files changed, 207 insertions(+), 472 deletions(-)

diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index f59b1f3..3f425f5 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -58,7 +58,8 @@ int __init __deprecated cpg_clk_init(void)
 
 	clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL);
 	clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL);
-	clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL);
+	clk_add_alias(NULL, "sh-cmt-16.0", "peripheral_clk", NULL);
+	clk_add_alias(NULL, "sh-cmt-32.0", "peripheral_clk", NULL);
 	clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL);
 
 	return ret;
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 3860b0b..73bdf66 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -152,62 +152,35 @@ static struct platform_device eth_device = {
 	.resource = eth_resources,
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xf84a0072,
-		.end	= 0xf84a0077,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 86,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xf84a0078,
-		.end	= 0xf84a007d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 87,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xf84a0078, 0x10),
+	DEFINE_RES_IRQ(86),
+	DEFINE_RES_IRQ(87),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct platform_device *sh7619_devices[] __initdata = {
@@ -215,8 +188,7 @@ static struct platform_device *sh7619_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&eth_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 };
 
 static int __init sh7619_devices_setup(void)
@@ -235,8 +207,7 @@ static struct platform_device *sh7619_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
 	&scif2_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 };
 
 #define STBCR3 0xf80a0000
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
index fdf585c..b8dcd34 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
@@ -117,7 +117,7 @@ static struct clk_lookup lookups[] = {
 	/* MSTP clocks */
 	CLKDEV_CON_ID("sci_ick", &mstp_clks[MSTP77]),
 	CLKDEV_CON_ID("vdc3", &mstp_clks[MSTP74]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP72]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[MSTP72]),
 	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
 	CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP35]),
 	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP34]),
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
index 6b78762..f7346b4 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
@@ -158,7 +158,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP72]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[MSTP72]),
 	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
 	CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP35]),
 	CLKDEV_CON_ID("adc0", &mstp_clks[MSTP32]),
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index d55a0f3..ef9d37a 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -265,62 +265,35 @@ static struct platform_device scif3_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 142,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 143,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(142),
+	DEFINE_RES_IRQ(143),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -404,8 +377,7 @@ static struct platform_device *sh7203_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -428,8 +400,7 @@ static struct platform_device *sh7203_early_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 241e745..f8c93a4 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -217,62 +217,35 @@ static struct platform_device scif3_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 140,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 144,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(140),
+	DEFINE_RES_IRQ(144),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -364,8 +337,7 @@ static struct platform_device *sh7206_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
@@ -388,8 +360,7 @@ static struct platform_device *sh7206_early_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
index ad5b0f4..838d05f 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
@@ -433,65 +433,35 @@ static struct platform_device scif7_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.name	= "CMT0",
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 175,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.name = "CMT1",
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.name	= "CMT1",
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 176,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(175),
+	DEFINE_RES_IRQ(176),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -620,8 +590,7 @@ static struct platform_device *sh7264_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -649,8 +618,7 @@ static struct platform_device *sh7264_early_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
index 3995119..3e66297 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
@@ -455,62 +455,35 @@ static struct platform_device scif7_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 188,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 189,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(188),
+	DEFINE_RES_IRQ(189),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -629,8 +602,7 @@ static struct platform_device *sh7269_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -658,8 +630,7 @@ static struct platform_device *sh7269_early_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 1d5729d..3cafd93 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -152,141 +152,32 @@ static struct platform_device usbf_device = {
 	.resource	= usbf_resources,
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0x044a0010,
-		.end	= 0x044a001b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
-	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
-};
-
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x20,
-	.timer_bit = 1,
-};
-
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0x044a0020,
-		.end	= 0x044a002b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
-	.dev = {
-		.platform_data	= &cmt1_platform_data,
-	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
-};
-
-static struct sh_timer_config cmt2_platform_data = {
-	.channel_offset = 0x30,
-	.timer_bit = 2,
-};
-
-static struct resource cmt2_resources[] = {
-	[0] = {
-		.start	= 0x044a0030,
-		.end	= 0x044a003b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
 	},
 };
 
-static struct platform_device cmt2_device = {
-	.name		= "sh_cmt",
-	.id		= 2,
-	.dev = {
-		.platform_data	= &cmt2_platform_data,
-	},
-	.resource	= cmt2_resources,
-	.num_resources	= ARRAY_SIZE(cmt2_resources),
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct sh_timer_config cmt3_platform_data = {
-	.channel_offset = 0x40,
-	.timer_bit = 3,
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0x044a0000, 0x60),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
-static struct resource cmt3_resources[] = {
-	[0] = {
-		.start	= 0x044a0040,
-		.end	= 0x044a004b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt3_device = {
-	.name		= "sh_cmt",
-	.id		= 3,
-	.dev = {
-		.platform_data	= &cmt3_platform_data,
-	},
-	.resource	= cmt3_resources,
-	.num_resources	= ARRAY_SIZE(cmt3_resources),
-};
-
-static struct sh_timer_config cmt4_platform_data = {
-	.channel_offset = 0x50,
-	.timer_bit = 4,
-};
-
-static struct resource cmt4_resources[] = {
-	[0] = {
-		.start	= 0x044a0050,
-		.end	= 0x044a005b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt4_device = {
-	.name		= "sh_cmt",
-	.id		= 4,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-32",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt4_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt4_resources,
-	.num_resources	= ARRAY_SIZE(cmt4_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -375,11 +266,7 @@ static struct platform_device tmu2_device = {
 static struct platform_device *sh7720_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
-	&cmt0_device,
-	&cmt1_device,
-	&cmt2_device,
-	&cmt3_device,
-	&cmt4_device,
+	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -398,11 +285,7 @@ arch_initcall(sh7720_devices_setup);
 static struct platform_device *sh7720_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
-	&cmt0_device,
-	&cmt1_device,
-	&cmt2_device,
-	&cmt3_device,
-	&cmt4_device,
+	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 53638e2..1628f82 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -227,7 +227,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+	CLKDEV_DEV_ID("sh-cmt-32.0k", &mstp_clks[MSTP014]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 22e485d..8a9e8af 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -225,7 +225,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[MSTP014]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index c4cb740..e40bd2a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -207,7 +207,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU]),
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]),
 
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
 
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 37c41c7..3e0a6d8 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -236,7 +236,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
 	CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 0128af3..e836d64 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -309,7 +309,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
 
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
 
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 245d192..820ce40 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -227,27 +227,27 @@ static struct platform_device jpu_device = {
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 6f56cbd..c878686 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -175,27 +175,26 @@ static struct platform_device veu1_device = {
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 5,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 5a94efc..1c0e14b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -412,27 +412,27 @@ static struct platform_device jpu_device = {
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 3c5eb09..9c08917 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -244,27 +244,27 @@ static struct platform_device veu1_device = {
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 60ebbc6..be587a9 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -647,27 +647,27 @@ static struct platform_device beu1_device = {
 	.num_resources	= ARRAY_SIZE(beu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
-- 
1.8.3.2


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

* [PATCH 15/27] sh: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/sh/kernel/cpu/clock-cpg.c         |   3 +-
 arch/sh/kernel/cpu/sh2/setup-sh7619.c  |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/clock-sh7264.c |   2 +-
 arch/sh/kernel/cpu/sh2a/clock-sh7269.c |   2 +-
 arch/sh/kernel/cpu/sh2a/setup-sh7203.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7206.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7264.c |  76 +++++-----------
 arch/sh/kernel/cpu/sh2a/setup-sh7269.c |  73 +++++-----------
 arch/sh/kernel/cpu/sh3/setup-sh7720.c  | 155 ++++-----------------------------
 arch/sh/kernel/cpu/sh4a/clock-sh7343.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7366.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7723.c |   2 +-
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c |   2 +-
 arch/sh/kernel/cpu/sh4a/setup-sh7343.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7366.c |  27 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7722.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7723.c |  28 +++---
 arch/sh/kernel/cpu/sh4a/setup-sh7724.c |  28 +++---
 19 files changed, 207 insertions(+), 472 deletions(-)

diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index f59b1f3..3f425f5 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -58,7 +58,8 @@ int __init __deprecated cpg_clk_init(void)
 
 	clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL);
 	clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL);
-	clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL);
+	clk_add_alias(NULL, "sh-cmt-16.0", "peripheral_clk", NULL);
+	clk_add_alias(NULL, "sh-cmt-32.0", "peripheral_clk", NULL);
 	clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL);
 
 	return ret;
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 3860b0b..73bdf66 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -152,62 +152,35 @@ static struct platform_device eth_device = {
 	.resource = eth_resources,
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xf84a0072,
-		.end	= 0xf84a0077,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 86,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xf84a0078,
-		.end	= 0xf84a007d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 87,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xf84a0078, 0x10),
+	DEFINE_RES_IRQ(86),
+	DEFINE_RES_IRQ(87),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct platform_device *sh7619_devices[] __initdata = {
@@ -215,8 +188,7 @@ static struct platform_device *sh7619_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&eth_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 };
 
 static int __init sh7619_devices_setup(void)
@@ -235,8 +207,7 @@ static struct platform_device *sh7619_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
 	&scif2_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 };
 
 #define STBCR3 0xf80a0000
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
index fdf585c..b8dcd34 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
@@ -117,7 +117,7 @@ static struct clk_lookup lookups[] = {
 	/* MSTP clocks */
 	CLKDEV_CON_ID("sci_ick", &mstp_clks[MSTP77]),
 	CLKDEV_CON_ID("vdc3", &mstp_clks[MSTP74]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP72]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[MSTP72]),
 	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
 	CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP35]),
 	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP34]),
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
index 6b78762..f7346b4 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
@@ -158,7 +158,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
 	CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP72]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[MSTP72]),
 	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
 	CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP35]),
 	CLKDEV_CON_ID("adc0", &mstp_clks[MSTP32]),
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index d55a0f3..ef9d37a 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -265,62 +265,35 @@ static struct platform_device scif3_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 142,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 143,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(142),
+	DEFINE_RES_IRQ(143),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -404,8 +377,7 @@ static struct platform_device *sh7203_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -428,8 +400,7 @@ static struct platform_device *sh7203_early_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 241e745..f8c93a4 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -217,62 +217,35 @@ static struct platform_device scif3_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 140,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 144,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(140),
+	DEFINE_RES_IRQ(144),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -364,8 +337,7 @@ static struct platform_device *sh7206_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
@@ -388,8 +360,7 @@ static struct platform_device *sh7206_early_devices[] __initdata = {
 	&scif1_device,
 	&scif2_device,
 	&scif3_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
index ad5b0f4..838d05f 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
@@ -433,65 +433,35 @@ static struct platform_device scif7_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.name	= "CMT0",
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 175,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.name = "CMT1",
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.name	= "CMT1",
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 176,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(175),
+	DEFINE_RES_IRQ(176),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -620,8 +590,7 @@ static struct platform_device *sh7264_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -649,8 +618,7 @@ static struct platform_device *sh7264_early_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
index 3995119..3e66297 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
@@ -455,62 +455,35 @@ static struct platform_device scif7_device = {
 	},
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x02,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0xfffec002,
-		.end	= 0xfffec007,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 188,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+	}, {
+		.index = 1,
+		.clockevent_rating = 125,
 	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
 };
 
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x08,
-	.timer_bit = 1,
-	.clockevent_rating = 125,
-	.clocksource_rating = 0, /* disabled due to code generation issues */
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0xfffec008,
-		.end	= 0xfffec00d,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 189,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0xfffec000, 0x10),
+	DEFINE_RES_IRQ(188),
+	DEFINE_RES_IRQ(189),
 };
 
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-16",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt1_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
@@ -629,8 +602,7 @@ static struct platform_device *sh7269_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&rtc_device,
@@ -658,8 +630,7 @@ static struct platform_device *sh7269_early_devices[] __initdata = {
 	&scif5_device,
 	&scif6_device,
 	&scif7_device,
-	&cmt0_device,
-	&cmt1_device,
+	&cmt_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 };
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 1d5729d..3cafd93 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -152,141 +152,32 @@ static struct platform_device usbf_device = {
 	.resource	= usbf_resources,
 };
 
-static struct sh_timer_config cmt0_platform_data = {
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
-};
-
-static struct resource cmt0_resources[] = {
-	[0] = {
-		.start	= 0x044a0010,
-		.end	= 0x044a001b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt0_device = {
-	.name		= "sh_cmt",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &cmt0_platform_data,
-	},
-	.resource	= cmt0_resources,
-	.num_resources	= ARRAY_SIZE(cmt0_resources),
-};
-
-static struct sh_timer_config cmt1_platform_data = {
-	.channel_offset = 0x20,
-	.timer_bit = 1,
-};
-
-static struct resource cmt1_resources[] = {
-	[0] = {
-		.start	= 0x044a0020,
-		.end	= 0x044a002b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt1_device = {
-	.name		= "sh_cmt",
-	.id		= 1,
-	.dev = {
-		.platform_data	= &cmt1_platform_data,
-	},
-	.resource	= cmt1_resources,
-	.num_resources	= ARRAY_SIZE(cmt1_resources),
-};
-
-static struct sh_timer_config cmt2_platform_data = {
-	.channel_offset = 0x30,
-	.timer_bit = 2,
-};
-
-static struct resource cmt2_resources[] = {
-	[0] = {
-		.start	= 0x044a0030,
-		.end	= 0x044a003b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
 	},
 };
 
-static struct platform_device cmt2_device = {
-	.name		= "sh_cmt",
-	.id		= 2,
-	.dev = {
-		.platform_data	= &cmt2_platform_data,
-	},
-	.resource	= cmt2_resources,
-	.num_resources	= ARRAY_SIZE(cmt2_resources),
+static struct sh_timer_config cmt_platform_data = {
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
-static struct sh_timer_config cmt3_platform_data = {
-	.channel_offset = 0x40,
-	.timer_bit = 3,
+static struct resource cmt_resources[] = {
+	DEFINE_RES_MEM(0x044a0000, 0x60),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
-static struct resource cmt3_resources[] = {
-	[0] = {
-		.start	= 0x044a0040,
-		.end	= 0x044a004b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt3_device = {
-	.name		= "sh_cmt",
-	.id		= 3,
-	.dev = {
-		.platform_data	= &cmt3_platform_data,
-	},
-	.resource	= cmt3_resources,
-	.num_resources	= ARRAY_SIZE(cmt3_resources),
-};
-
-static struct sh_timer_config cmt4_platform_data = {
-	.channel_offset = 0x50,
-	.timer_bit = 4,
-};
-
-static struct resource cmt4_resources[] = {
-	[0] = {
-		.start	= 0x044a0050,
-		.end	= 0x044a005b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt4_device = {
-	.name		= "sh_cmt",
-	.id		= 4,
+static struct platform_device cmt_device = {
+	.name		= "sh-cmt-32",
+	.id		= 0,
 	.dev = {
-		.platform_data	= &cmt4_platform_data,
+		.platform_data	= &cmt_platform_data,
 	},
-	.resource	= cmt4_resources,
-	.num_resources	= ARRAY_SIZE(cmt4_resources),
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -375,11 +266,7 @@ static struct platform_device tmu2_device = {
 static struct platform_device *sh7720_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
-	&cmt0_device,
-	&cmt1_device,
-	&cmt2_device,
-	&cmt3_device,
-	&cmt4_device,
+	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -398,11 +285,7 @@ arch_initcall(sh7720_devices_setup);
 static struct platform_device *sh7720_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
-	&cmt0_device,
-	&cmt1_device,
-	&cmt2_device,
-	&cmt3_device,
-	&cmt4_device,
+	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 53638e2..1628f82 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -227,7 +227,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+	CLKDEV_DEV_ID("sh-cmt-32.0k", &mstp_clks[MSTP014]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 22e485d..8a9e8af 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -225,7 +225,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[MSTP014]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index c4cb740..e40bd2a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -207,7 +207,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU]),
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]),
 
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
 
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 37c41c7..3e0a6d8 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -236,7 +236,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
 	CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 0128af3..e836d64 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -309,7 +309,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
 	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
 
-	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+	CLKDEV_DEV_ID("sh-cmt-16.0", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
 
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 245d192..820ce40 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -227,27 +227,27 @@ static struct platform_device jpu_device = {
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 6f56cbd..c878686 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -175,27 +175,26 @@ static struct platform_device veu1_device = {
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 5,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 5a94efc..1c0e14b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -412,27 +412,27 @@ static struct platform_device jpu_device = {
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 3c5eb09..9c08917 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -244,27 +244,27 @@ static struct platform_device veu1_device = {
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 60ebbc6..be587a9 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -647,27 +647,27 @@ static struct platform_device beu1_device = {
 	.num_resources	= ARRAY_SIZE(beu1_resources),
 };
 
+static struct sh_timer_channel_config cmt_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 200,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
-	.channel_offset = 0x60,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 200,
+	.channels = cmt_channels,
+	.num_channels = ARRAY_SIZE(cmt_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt_resources[] = {
-	[0] = {
-		.start	= 0x044a0060,
-		.end	= 0x044a006b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xf00),
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0x044a0000, 0x70),
+	DEFINE_RES_IRQ(evt2irq(0xf00)),
 };
 
 static struct platform_device cmt_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &cmt_platform_data,
-- 
1.8.3.2

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

* [PATCH 16/27] ARM: shmobile: sh7372: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-sh7372.c |  6 +++---
 arch/arm/mach-shmobile/setup-sh7372.c | 30 ++++++++++++++----------------
 2 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 2848997..5557b3d 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -565,10 +565,10 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
-	CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
-	CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.4", &mstp_clks[MSTP405]), /* CMT4 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.3", &mstp_clks[MSTP404]), /* CMT3 */
 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
-	CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.2", &mstp_clks[MSTP400]), /* CMT2 */
 
 	/* ICK */
 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 2730127..3e524d5 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -118,29 +118,27 @@ SH7372_SCIF(PORT_SCIFA, 5, 0xe6cb0000, evt2irq(0x0d40));
 SH7372_SCIF(PORT_SCIFB, 6, 0xe6c30000, evt2irq(0x0d60));
 
 /* CMT */
+static struct sh_timer_channel_config cmt2_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt2_platform_data = {
-	.name = "CMT2",
-	.channel_offset = 0x40,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt2_channels,
+	.num_channels = ARRAY_SIZE(cmt2_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt2_resources[] = {
-	[0] = {
-		.name	= "CMT2",
-		.start	= 0xe6130040,
-		.end	= 0xe613004b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x0b80), /* CMT2 */
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0xe6130000, 0x50),
+	DEFINE_RES_IRQ(evt2irq(0x0b80)),
 };
 
 static struct platform_device cmt2_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32-fast",
 	.id		= 2,
 	.dev = {
 		.platform_data	= &cmt2_platform_data,
-- 
1.8.3.2


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

* [PATCH 16/27] ARM: shmobile: sh7372: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-sh7372.c |  6 +++---
 arch/arm/mach-shmobile/setup-sh7372.c | 30 ++++++++++++++----------------
 2 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 2848997..5557b3d 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -565,10 +565,10 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
-	CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
-	CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.4", &mstp_clks[MSTP405]), /* CMT4 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.3", &mstp_clks[MSTP404]), /* CMT3 */
 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
-	CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.2", &mstp_clks[MSTP400]), /* CMT2 */
 
 	/* ICK */
 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 2730127..3e524d5 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -118,29 +118,27 @@ SH7372_SCIF(PORT_SCIFA, 5, 0xe6cb0000, evt2irq(0x0d40));
 SH7372_SCIF(PORT_SCIFB, 6, 0xe6c30000, evt2irq(0x0d60));
 
 /* CMT */
+static struct sh_timer_channel_config cmt2_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt2_platform_data = {
-	.name = "CMT2",
-	.channel_offset = 0x40,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt2_channels,
+	.num_channels = ARRAY_SIZE(cmt2_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt2_resources[] = {
-	[0] = {
-		.name	= "CMT2",
-		.start	= 0xe6130040,
-		.end	= 0xe613004b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x0b80), /* CMT2 */
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0xe6130000, 0x50),
+	DEFINE_RES_IRQ(evt2irq(0x0b80)),
 };
 
 static struct platform_device cmt2_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32-fast",
 	.id		= 2,
 	.dev = {
 		.platform_data	= &cmt2_platform_data,
-- 
1.8.3.2


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

* [PATCH 16/27] ARM: shmobile: sh7372: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-sh7372.c |  6 +++---
 arch/arm/mach-shmobile/setup-sh7372.c | 30 ++++++++++++++----------------
 2 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 2848997..5557b3d 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -565,10 +565,10 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
-	CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
-	CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.4", &mstp_clks[MSTP405]), /* CMT4 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.3", &mstp_clks[MSTP404]), /* CMT3 */
 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
-	CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
+	CLKDEV_DEV_ID("sh-cmt-32-fast.2", &mstp_clks[MSTP400]), /* CMT2 */
 
 	/* ICK */
 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 2730127..3e524d5 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -118,29 +118,27 @@ SH7372_SCIF(PORT_SCIFA, 5, 0xe6cb0000, evt2irq(0x0d40));
 SH7372_SCIF(PORT_SCIFB, 6, 0xe6c30000, evt2irq(0x0d60));
 
 /* CMT */
+static struct sh_timer_channel_config cmt2_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
+};
+
 static struct sh_timer_config cmt2_platform_data = {
-	.name = "CMT2",
-	.channel_offset = 0x40,
-	.timer_bit = 5,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+	.channels = cmt2_channels,
+	.num_channels = ARRAY_SIZE(cmt2_channels),
+	.channels_mask = 0x1f,
 };
 
 static struct resource cmt2_resources[] = {
-	[0] = {
-		.name	= "CMT2",
-		.start	= 0xe6130040,
-		.end	= 0xe613004b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x0b80), /* CMT2 */
-		.flags	= IORESOURCE_IRQ,
-	},
+	DEFINE_RES_MEM(0xe6130000, 0x50),
+	DEFINE_RES_IRQ(evt2irq(0x0b80)),
 };
 
 static struct platform_device cmt2_device = {
-	.name		= "sh_cmt",
+	.name		= "sh-cmt-32-fast",
 	.id		= 2,
 	.dev = {
 		.platform_data	= &cmt2_platform_data,
-- 
1.8.3.2

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

* [PATCH 17/27] ARM: shmobile: sh73a0: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-sh73a0.c |  2 +-
 arch/arm/mach-shmobile/setup-sh73a0.c | 45 ++++++++++++++++-------------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 23edf83..723c5c5 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -650,7 +650,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+	CLKDEV_DEV_ID("sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
 	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
 	CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
 	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index f74ab53..738bbe4 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -104,35 +104,32 @@ SH73A0_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(156));
 SH73A0_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(143));
 SH73A0_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(80));
 
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 80,
-	.clocksource_rating = 125,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+		.clocksource_rating = 125,
+	},
 };
 
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_spi(65),
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6138010, 0x200),
+	DEFINE_RES_IRQ(gic_spi(65)),
+};
+
+static struct platform_device cmt1_device = {
+	.name		= "sh-cmt-48",
+	.id		= 1,
 	.dev = {
-		.platform_data	= &cmt10_platform_data,
+		.platform_data	= &cmt1_platform_data,
 	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
+	.resource	= cmt1_resources,
+	.num_resources	= ARRAY_SIZE(cmt1_resources),
 };
 
 /* TMU */
@@ -746,7 +743,7 @@ static struct platform_device *sh73a0_devices_dt[] __initdata = {
 	&scif6_device,
 	&scif7_device,
 	&scif8_device,
-	&cmt10_device,
+	&cmt1_device,
 };
 
 static struct platform_device *sh73a0_early_devices[] __initdata = {
-- 
1.8.3.2


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

* [PATCH 17/27] ARM: shmobile: sh73a0: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-sh73a0.c |  2 +-
 arch/arm/mach-shmobile/setup-sh73a0.c | 45 ++++++++++++++++-------------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 23edf83..723c5c5 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -650,7 +650,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+	CLKDEV_DEV_ID("sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
 	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
 	CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
 	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index f74ab53..738bbe4 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -104,35 +104,32 @@ SH73A0_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(156));
 SH73A0_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(143));
 SH73A0_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(80));
 
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 80,
-	.clocksource_rating = 125,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+		.clocksource_rating = 125,
+	},
 };
 
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_spi(65),
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6138010, 0x200),
+	DEFINE_RES_IRQ(gic_spi(65)),
+};
+
+static struct platform_device cmt1_device = {
+	.name		= "sh-cmt-48",
+	.id		= 1,
 	.dev = {
-		.platform_data	= &cmt10_platform_data,
+		.platform_data	= &cmt1_platform_data,
 	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
+	.resource	= cmt1_resources,
+	.num_resources	= ARRAY_SIZE(cmt1_resources),
 };
 
 /* TMU */
@@ -746,7 +743,7 @@ static struct platform_device *sh73a0_devices_dt[] __initdata = {
 	&scif6_device,
 	&scif7_device,
 	&scif8_device,
-	&cmt10_device,
+	&cmt1_device,
 };
 
 static struct platform_device *sh73a0_early_devices[] __initdata = {
-- 
1.8.3.2


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

* [PATCH 17/27] ARM: shmobile: sh73a0: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-sh73a0.c |  2 +-
 arch/arm/mach-shmobile/setup-sh73a0.c | 45 ++++++++++++++++-------------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 23edf83..723c5c5 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -650,7 +650,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+	CLKDEV_DEV_ID("sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
 	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
 	CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
 	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index f74ab53..738bbe4 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -104,35 +104,32 @@ SH73A0_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(156));
 SH73A0_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(143));
 SH73A0_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(80));
 
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 80,
-	.clocksource_rating = 125,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+		.clocksource_rating = 125,
+	},
 };
 
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_spi(65),
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6138010, 0x200),
+	DEFINE_RES_IRQ(gic_spi(65)),
+};
+
+static struct platform_device cmt1_device = {
+	.name		= "sh-cmt-48",
+	.id		= 1,
 	.dev = {
-		.platform_data	= &cmt10_platform_data,
+		.platform_data	= &cmt1_platform_data,
 	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
+	.resource	= cmt1_resources,
+	.num_resources	= ARRAY_SIZE(cmt1_resources),
 };
 
 /* TMU */
@@ -746,7 +743,7 @@ static struct platform_device *sh73a0_devices_dt[] __initdata = {
 	&scif6_device,
 	&scif7_device,
 	&scif8_device,
-	&cmt10_device,
+	&cmt1_device,
 };
 
 static struct platform_device *sh73a0_early_devices[] __initdata = {
-- 
1.8.3.2

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

* [PATCH 18/27] ARM: shmobile: r8a73a4: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-r8a73a4.c |  2 +-
 arch/arm/mach-shmobile/setup-r8a73a4.c | 25 +++++++++++++++----------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index 7348d58..cd75821 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -597,7 +597,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]),
 	CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]),
 	CLKDEV_DEV_ID("e6510000.i2c", &mstp_clks[MSTP323]),
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.1", &mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("e60b0000.i2c", &mstp_clks[MSTP409]),
 	CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP410]),
 	CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP411]),
diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c
index cd36f80..5794229 100644
--- a/arch/arm/mach-shmobile/setup-r8a73a4.c
+++ b/arch/arm/mach-shmobile/setup-r8a73a4.c
@@ -169,20 +169,25 @@ static const struct resource thermal0_resources[] = {
 					thermal0_resources,		\
 					ARRAY_SIZE(thermal0_resources))
 
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct resource cmt10_resources[] = {
-	DEFINE_RES_MEM(0xe6130010, 0x0c),
-	DEFINE_RES_MEM(0xe6130000, 0x04),
-	DEFINE_RES_IRQ(gic_spi(120)), /* CMT1_0 */
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6130000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(120)),
 };
 
 #define r8a7790_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -196,7 +201,7 @@ void __init r8a73a4_add_dt_devices(void)
 	r8a73a4_register_scif(3);
 	r8a73a4_register_scif(4);
 	r8a73a4_register_scif(5);
-	r8a7790_register_cmt(10);
+	r8a7790_register_cmt(1);
 }
 
 /* DMA */
-- 
1.8.3.2


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

* [PATCH 18/27] ARM: shmobile: r8a73a4: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-r8a73a4.c |  2 +-
 arch/arm/mach-shmobile/setup-r8a73a4.c | 25 +++++++++++++++----------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index 7348d58..cd75821 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -597,7 +597,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]),
 	CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]),
 	CLKDEV_DEV_ID("e6510000.i2c", &mstp_clks[MSTP323]),
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.1", &mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("e60b0000.i2c", &mstp_clks[MSTP409]),
 	CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP410]),
 	CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP411]),
diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c
index cd36f80..5794229 100644
--- a/arch/arm/mach-shmobile/setup-r8a73a4.c
+++ b/arch/arm/mach-shmobile/setup-r8a73a4.c
@@ -169,20 +169,25 @@ static const struct resource thermal0_resources[] = {
 					thermal0_resources,		\
 					ARRAY_SIZE(thermal0_resources))
 
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct resource cmt10_resources[] = {
-	DEFINE_RES_MEM(0xe6130010, 0x0c),
-	DEFINE_RES_MEM(0xe6130000, 0x04),
-	DEFINE_RES_IRQ(gic_spi(120)), /* CMT1_0 */
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6130000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(120)),
 };
 
 #define r8a7790_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -196,7 +201,7 @@ void __init r8a73a4_add_dt_devices(void)
 	r8a73a4_register_scif(3);
 	r8a73a4_register_scif(4);
 	r8a73a4_register_scif(5);
-	r8a7790_register_cmt(10);
+	r8a7790_register_cmt(1);
 }
 
 /* DMA */
-- 
1.8.3.2


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

* [PATCH 18/27] ARM: shmobile: r8a73a4: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-r8a73a4.c |  2 +-
 arch/arm/mach-shmobile/setup-r8a73a4.c | 25 +++++++++++++++----------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index 7348d58..cd75821 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -597,7 +597,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]),
 	CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]),
 	CLKDEV_DEV_ID("e6510000.i2c", &mstp_clks[MSTP323]),
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.1", &mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("e60b0000.i2c", &mstp_clks[MSTP409]),
 	CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP410]),
 	CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP411]),
diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c
index cd36f80..5794229 100644
--- a/arch/arm/mach-shmobile/setup-r8a73a4.c
+++ b/arch/arm/mach-shmobile/setup-r8a73a4.c
@@ -169,20 +169,25 @@ static const struct resource thermal0_resources[] = {
 					thermal0_resources,		\
 					ARRAY_SIZE(thermal0_resources))
 
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct resource cmt10_resources[] = {
-	DEFINE_RES_MEM(0xe6130010, 0x0c),
-	DEFINE_RES_MEM(0xe6130000, 0x04),
-	DEFINE_RES_IRQ(gic_spi(120)), /* CMT1_0 */
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6130000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(120)),
 };
 
 #define r8a7790_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -196,7 +201,7 @@ void __init r8a73a4_add_dt_devices(void)
 	r8a73a4_register_scif(3);
 	r8a73a4_register_scif(4);
 	r8a73a4_register_scif(5);
-	r8a7790_register_cmt(10);
+	r8a7790_register_cmt(1);
 }
 
 /* DMA */
-- 
1.8.3.2

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

* [PATCH 19/27] ARM: shmobile: r8a7740: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-r8a7740.c |  2 +-
 arch/arm/mach-shmobile/setup-r8a7740.c | 45 ++++++++++++++++------------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index dd989f9..50d3073 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -583,7 +583,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.6",		&mstp_clks[MSTP230]),
 	CLKDEV_DEV_ID("e6cc0000.sci",		&mstp_clks[MSTP230]),
 
-	CLKDEV_DEV_ID("sh_cmt.10",		&mstp_clks[MSTP329]),
+	CLKDEV_DEV_ID("sh-cmt-48.1",		&mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("sh_fsi2",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("fe1f0000.sound",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("i2c-sh_mobile.1",	&mstp_clks[MSTP323]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 8f3c681..f88856e 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -237,35 +237,32 @@ R8A7740_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(107));
 R8A7740_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(108));
 
 /* CMT */
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
 };
 
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_spi(58),
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6138000, 0x170),
+	DEFINE_RES_IRQ(gic_spi(58)),
+};
+
+static struct platform_device cmt1_device = {
+	.name		= "sh-cmt-48",
+	.id		= 1,
 	.dev = {
-		.platform_data	= &cmt10_platform_data,
+		.platform_data	= &cmt1_platform_data,
 	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
+	.resource	= cmt1_resources,
+	.num_resources	= ARRAY_SIZE(cmt1_resources),
 };
 
 /* TMU */
@@ -400,7 +397,7 @@ static struct platform_device *r8a7740_devices_dt[] __initdata = {
 	&scif6_device,
 	&scif7_device,
 	&scif8_device,
-	&cmt10_device,
+	&cmt1_device,
 };
 
 static struct platform_device *r8a7740_early_devices[] __initdata = {
-- 
1.8.3.2


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

* [PATCH 19/27] ARM: shmobile: r8a7740: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-r8a7740.c |  2 +-
 arch/arm/mach-shmobile/setup-r8a7740.c | 45 ++++++++++++++++------------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index dd989f9..50d3073 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -583,7 +583,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.6",		&mstp_clks[MSTP230]),
 	CLKDEV_DEV_ID("e6cc0000.sci",		&mstp_clks[MSTP230]),
 
-	CLKDEV_DEV_ID("sh_cmt.10",		&mstp_clks[MSTP329]),
+	CLKDEV_DEV_ID("sh-cmt-48.1",		&mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("sh_fsi2",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("fe1f0000.sound",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("i2c-sh_mobile.1",	&mstp_clks[MSTP323]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 8f3c681..f88856e 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -237,35 +237,32 @@ R8A7740_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(107));
 R8A7740_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(108));
 
 /* CMT */
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
 };
 
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_spi(58),
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6138000, 0x170),
+	DEFINE_RES_IRQ(gic_spi(58)),
+};
+
+static struct platform_device cmt1_device = {
+	.name		= "sh-cmt-48",
+	.id		= 1,
 	.dev = {
-		.platform_data	= &cmt10_platform_data,
+		.platform_data	= &cmt1_platform_data,
 	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
+	.resource	= cmt1_resources,
+	.num_resources	= ARRAY_SIZE(cmt1_resources),
 };
 
 /* TMU */
@@ -400,7 +397,7 @@ static struct platform_device *r8a7740_devices_dt[] __initdata = {
 	&scif6_device,
 	&scif7_device,
 	&scif8_device,
-	&cmt10_device,
+	&cmt1_device,
 };
 
 static struct platform_device *r8a7740_early_devices[] __initdata = {
-- 
1.8.3.2


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

* [PATCH 19/27] ARM: shmobile: r8a7740: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/clock-r8a7740.c |  2 +-
 arch/arm/mach-shmobile/setup-r8a7740.c | 45 ++++++++++++++++------------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index dd989f9..50d3073 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -583,7 +583,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.6",		&mstp_clks[MSTP230]),
 	CLKDEV_DEV_ID("e6cc0000.sci",		&mstp_clks[MSTP230]),
 
-	CLKDEV_DEV_ID("sh_cmt.10",		&mstp_clks[MSTP329]),
+	CLKDEV_DEV_ID("sh-cmt-48.1",		&mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("sh_fsi2",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("fe1f0000.sound",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("i2c-sh_mobile.1",	&mstp_clks[MSTP323]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 8f3c681..f88856e 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -237,35 +237,32 @@ R8A7740_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(107));
 R8A7740_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(108));
 
 /* CMT */
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
+static struct sh_timer_channel_config cmt1_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 125,
+		.clocksource_rating = 125,
+	},
 };
 
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_spi(58),
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct sh_timer_config cmt1_platform_data = {
+	.channels = cmt1_channels,
+	.num_channels = ARRAY_SIZE(cmt1_channels),
 };
 
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
+static struct resource cmt1_resources[] = {
+	DEFINE_RES_MEM(0xe6138000, 0x170),
+	DEFINE_RES_IRQ(gic_spi(58)),
+};
+
+static struct platform_device cmt1_device = {
+	.name		= "sh-cmt-48",
+	.id		= 1,
 	.dev = {
-		.platform_data	= &cmt10_platform_data,
+		.platform_data	= &cmt1_platform_data,
 	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
+	.resource	= cmt1_resources,
+	.num_resources	= ARRAY_SIZE(cmt1_resources),
 };
 
 /* TMU */
@@ -400,7 +397,7 @@ static struct platform_device *r8a7740_devices_dt[] __initdata = {
 	&scif6_device,
 	&scif7_device,
 	&scif8_device,
-	&cmt10_device,
+	&cmt1_device,
 };
 
 static struct platform_device *r8a7740_early_devices[] __initdata = {
-- 
1.8.3.2

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

* [PATCH 20/27] ARM: shmobile: r8a7790: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-lager-reference.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7790.c         |  2 +-
 arch/arm/mach-shmobile/setup-r8a7790.c         | 26 ++++++++++++++++----------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 35fc0f2..4dd43b1 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -38,7 +38,7 @@ static void __init lager_add_standard_devices(void)
 
 	clk = clk_get(NULL, "cmt0");
 	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh_cmt.0");
+		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
 		clk_put(clk);
 	}
 #else
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
index 4b276ef..780466e 100644
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ b/arch/arm/mach-shmobile/clock-r8a7790.c
@@ -357,7 +357,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
 	CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
 	CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
-	CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
 	CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
 	CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
 	CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index b237268..3e5813f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -269,20 +269,26 @@ static const struct resource thermal_resources[] __initconst = {
 					thermal_resources,		\
 					ARRAY_SIZE(thermal_resources))
 
-static const struct sh_timer_config cmt00_platform_data __initconst = {
-	.name = "CMT00",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt0_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
 };
 
-static const struct resource cmt00_resources[] __initconst = {
-	DEFINE_RES_MEM(0xffca0510, 0x0c),
-	DEFINE_RES_MEM(0xffca0500, 0x04),
-	DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+static struct sh_timer_config cmt0_platform_data = {
+	.channels = cmt0_channels,
+	.num_channels = ARRAY_SIZE(cmt0_channels),
+	.channels_mask = 0x1f,
+};
+
+static struct resource cmt0_resources[] = {
+	DEFINE_RES_MEM(0xffca0000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(142)),
 };
 
 #define r8a7790_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -290,7 +296,7 @@ static const struct resource cmt00_resources[] __initconst = {
 
 void __init r8a7790_add_dt_devices(void)
 {
-	r8a7790_register_cmt(00);
+	r8a7790_register_cmt(0);
 }
 
 void __init r8a7790_add_standard_devices(void)
-- 
1.8.3.2


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

* [PATCH 20/27] ARM: shmobile: r8a7790: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-lager-reference.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7790.c         |  2 +-
 arch/arm/mach-shmobile/setup-r8a7790.c         | 26 ++++++++++++++++----------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 35fc0f2..4dd43b1 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -38,7 +38,7 @@ static void __init lager_add_standard_devices(void)
 
 	clk = clk_get(NULL, "cmt0");
 	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh_cmt.0");
+		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
 		clk_put(clk);
 	}
 #else
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
index 4b276ef..780466e 100644
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ b/arch/arm/mach-shmobile/clock-r8a7790.c
@@ -357,7 +357,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
 	CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
 	CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
-	CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
 	CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
 	CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
 	CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index b237268..3e5813f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -269,20 +269,26 @@ static const struct resource thermal_resources[] __initconst = {
 					thermal_resources,		\
 					ARRAY_SIZE(thermal_resources))
 
-static const struct sh_timer_config cmt00_platform_data __initconst = {
-	.name = "CMT00",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt0_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
 };
 
-static const struct resource cmt00_resources[] __initconst = {
-	DEFINE_RES_MEM(0xffca0510, 0x0c),
-	DEFINE_RES_MEM(0xffca0500, 0x04),
-	DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+static struct sh_timer_config cmt0_platform_data = {
+	.channels = cmt0_channels,
+	.num_channels = ARRAY_SIZE(cmt0_channels),
+	.channels_mask = 0x1f,
+};
+
+static struct resource cmt0_resources[] = {
+	DEFINE_RES_MEM(0xffca0000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(142)),
 };
 
 #define r8a7790_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -290,7 +296,7 @@ static const struct resource cmt00_resources[] __initconst = {
 
 void __init r8a7790_add_dt_devices(void)
 {
-	r8a7790_register_cmt(00);
+	r8a7790_register_cmt(0);
 }
 
 void __init r8a7790_add_standard_devices(void)
-- 
1.8.3.2


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

* [PATCH 20/27] ARM: shmobile: r8a7790: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-lager-reference.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7790.c         |  2 +-
 arch/arm/mach-shmobile/setup-r8a7790.c         | 26 ++++++++++++++++----------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 35fc0f2..4dd43b1 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -38,7 +38,7 @@ static void __init lager_add_standard_devices(void)
 
 	clk = clk_get(NULL, "cmt0");
 	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh_cmt.0");
+		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
 		clk_put(clk);
 	}
 #else
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
index 4b276ef..780466e 100644
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ b/arch/arm/mach-shmobile/clock-r8a7790.c
@@ -357,7 +357,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
 	CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
 	CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
-	CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
 	CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
 	CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
 	CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index b237268..3e5813f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -269,20 +269,26 @@ static const struct resource thermal_resources[] __initconst = {
 					thermal_resources,		\
 					ARRAY_SIZE(thermal_resources))
 
-static const struct sh_timer_config cmt00_platform_data __initconst = {
-	.name = "CMT00",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt0_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
 };
 
-static const struct resource cmt00_resources[] __initconst = {
-	DEFINE_RES_MEM(0xffca0510, 0x0c),
-	DEFINE_RES_MEM(0xffca0500, 0x04),
-	DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+static struct sh_timer_config cmt0_platform_data = {
+	.channels = cmt0_channels,
+	.num_channels = ARRAY_SIZE(cmt0_channels),
+	.channels_mask = 0x1f,
+};
+
+static struct resource cmt0_resources[] = {
+	DEFINE_RES_MEM(0xffca0000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(142)),
 };
 
 #define r8a7790_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -290,7 +296,7 @@ static const struct resource cmt00_resources[] __initconst = {
 
 void __init r8a7790_add_dt_devices(void)
 {
-	r8a7790_register_cmt(00);
+	r8a7790_register_cmt(0);
 }
 
 void __init r8a7790_add_standard_devices(void)
-- 
1.8.3.2

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

* [PATCH 21/27] ARM: shmobile: r8a7791: Switch to new style CMT device
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  0:59   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-koelsch-reference.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7791.c           |  2 +-
 arch/arm/mach-shmobile/setup-r8a7791.c           | 26 +++++++++++++++---------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
index 46879d6..e67a4be7 100644
--- a/arch/arm/mach-shmobile/board-koelsch-reference.c
+++ b/arch/arm/mach-shmobile/board-koelsch-reference.c
@@ -39,7 +39,7 @@ static void __init koelsch_add_standard_devices(void)
 
 	clk = clk_get(NULL, "cmt0");
 	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh_cmt.0");
+		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
 		clk_put(clk);
 	}
 #else
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c
index fc9248d..4dac973 100644
--- a/arch/arm/mach-shmobile/clock-r8a7791.c
+++ b/arch/arm/mach-shmobile/clock-r8a7791.c
@@ -224,7 +224,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
 	CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
 	CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
-	CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
 	CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
 	CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
 	CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index 605f4cf..a17ebb8 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -128,20 +128,26 @@ R8A7791_SCIFA(14, 0xe6c80000, gic_spi(31)); /* SCIFA5 */
 					  &scif##index##_platform_data,	       \
 					  sizeof(scif##index##_platform_data))
 
-static const struct sh_timer_config cmt00_platform_data __initconst = {
-	.name = "CMT00",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt0_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
 };
 
-static const struct resource cmt00_resources[] __initconst = {
-	DEFINE_RES_MEM(0xffca0510, 0x0c),
-	DEFINE_RES_MEM(0xffca0500, 0x04),
-	DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+static struct sh_timer_config cmt0_platform_data = {
+	.channels = cmt0_channels,
+	.num_channels = ARRAY_SIZE(cmt0_channels),
+	.channels_mask = 0x1f,
+};
+
+static struct resource cmt0_resources[] = {
+	DEFINE_RES_MEM(0xffca0000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(142)),
 };
 
 #define r8a7791_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -185,7 +191,7 @@ static const struct resource thermal_resources[] __initconst = {
 
 void __init r8a7791_add_dt_devices(void)
 {
-	r8a7791_register_cmt(00);
+	r8a7791_register_cmt(0);
 }
 
 void __init r8a7791_add_standard_devices(void)
-- 
1.8.3.2


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

* [PATCH 21/27] ARM: shmobile: r8a7791: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-koelsch-reference.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7791.c           |  2 +-
 arch/arm/mach-shmobile/setup-r8a7791.c           | 26 +++++++++++++++---------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
index 46879d6..e67a4be7 100644
--- a/arch/arm/mach-shmobile/board-koelsch-reference.c
+++ b/arch/arm/mach-shmobile/board-koelsch-reference.c
@@ -39,7 +39,7 @@ static void __init koelsch_add_standard_devices(void)
 
 	clk = clk_get(NULL, "cmt0");
 	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh_cmt.0");
+		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
 		clk_put(clk);
 	}
 #else
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c
index fc9248d..4dac973 100644
--- a/arch/arm/mach-shmobile/clock-r8a7791.c
+++ b/arch/arm/mach-shmobile/clock-r8a7791.c
@@ -224,7 +224,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
 	CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
 	CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
-	CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
 	CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
 	CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
 	CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index 605f4cf..a17ebb8 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -128,20 +128,26 @@ R8A7791_SCIFA(14, 0xe6c80000, gic_spi(31)); /* SCIFA5 */
 					  &scif##index##_platform_data,	       \
 					  sizeof(scif##index##_platform_data))
 
-static const struct sh_timer_config cmt00_platform_data __initconst = {
-	.name = "CMT00",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt0_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
 };
 
-static const struct resource cmt00_resources[] __initconst = {
-	DEFINE_RES_MEM(0xffca0510, 0x0c),
-	DEFINE_RES_MEM(0xffca0500, 0x04),
-	DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+static struct sh_timer_config cmt0_platform_data = {
+	.channels = cmt0_channels,
+	.num_channels = ARRAY_SIZE(cmt0_channels),
+	.channels_mask = 0x1f,
+};
+
+static struct resource cmt0_resources[] = {
+	DEFINE_RES_MEM(0xffca0000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(142)),
 };
 
 #define r8a7791_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -185,7 +191,7 @@ static const struct resource thermal_resources[] __initconst = {
 
 void __init r8a7791_add_dt_devices(void)
 {
-	r8a7791_register_cmt(00);
+	r8a7791_register_cmt(0);
 }
 
 void __init r8a7791_add_standard_devices(void)
-- 
1.8.3.2


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

* [PATCH 21/27] ARM: shmobile: r8a7791: Switch to new style CMT device
@ 2014-02-14  0:59   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

The CMT (Compare Match Timer) driver implements a new style of platform
data that handles the timer as a single device with multiple channel.
Switch from the old-style platform data to the new-style platform data.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-koelsch-reference.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7791.c           |  2 +-
 arch/arm/mach-shmobile/setup-r8a7791.c           | 26 +++++++++++++++---------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
index 46879d6..e67a4be7 100644
--- a/arch/arm/mach-shmobile/board-koelsch-reference.c
+++ b/arch/arm/mach-shmobile/board-koelsch-reference.c
@@ -39,7 +39,7 @@ static void __init koelsch_add_standard_devices(void)
 
 	clk = clk_get(NULL, "cmt0");
 	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh_cmt.0");
+		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
 		clk_put(clk);
 	}
 #else
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c
index fc9248d..4dac973 100644
--- a/arch/arm/mach-shmobile/clock-r8a7791.c
+++ b/arch/arm/mach-shmobile/clock-r8a7791.c
@@ -224,7 +224,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
 	CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
 	CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
-	CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+	CLKDEV_DEV_ID("sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
 	CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
 	CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
 	CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index 605f4cf..a17ebb8 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -128,20 +128,26 @@ R8A7791_SCIFA(14, 0xe6c80000, gic_spi(31)); /* SCIFA5 */
 					  &scif##index##_platform_data,	       \
 					  sizeof(scif##index##_platform_data))
 
-static const struct sh_timer_config cmt00_platform_data __initconst = {
-	.name = "CMT00",
-	.timer_bit = 0,
-	.clockevent_rating = 80,
+static struct sh_timer_channel_config cmt0_channels[] = {
+	{
+		.index = 0,
+		.clockevent_rating = 80,
+	},
 };
 
-static const struct resource cmt00_resources[] __initconst = {
-	DEFINE_RES_MEM(0xffca0510, 0x0c),
-	DEFINE_RES_MEM(0xffca0500, 0x04),
-	DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+static struct sh_timer_config cmt0_platform_data = {
+	.channels = cmt0_channels,
+	.num_channels = ARRAY_SIZE(cmt0_channels),
+	.channels_mask = 0x1f,
+};
+
+static struct resource cmt0_resources[] = {
+	DEFINE_RES_MEM(0xffca0000, 0x1004),
+	DEFINE_RES_IRQ(gic_spi(142)),
 };
 
 #define r8a7791_register_cmt(idx)					\
-	platform_device_register_resndata(&platform_bus, "sh_cmt",	\
+	platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
 					  idx, cmt##idx##_resources,	\
 					  ARRAY_SIZE(cmt##idx##_resources), \
 					  &cmt##idx##_platform_data,	\
@@ -185,7 +191,7 @@ static const struct resource thermal_resources[] __initconst = {
 
 void __init r8a7791_add_dt_devices(void)
 {
-	r8a7791_register_cmt(00);
+	r8a7791_register_cmt(0);
 }
 
 void __init r8a7791_add_standard_devices(void)
-- 
1.8.3.2

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

* [PATCH 22/27] clocksource: sh_cmt: Drop support for legacy platform data
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  1:00   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Now that all platforms have switched to the new-style platform data,
drop support for the legacy version.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 174 ++++++++++---------------------------------
 1 file changed, 39 insertions(+), 135 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 077879b..fe9694b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -115,9 +115,7 @@ struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	const struct sh_cmt_info *info;
-	bool legacy;
 
-	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
 	struct clk *clk;
 
@@ -824,58 +822,45 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 				const struct sh_timer_channel_config *ch_cfg,
 				unsigned int hwidx, struct sh_cmt_device *cmt)
 {
-	unsigned long clockevent_rating;
-	unsigned long clocksource_rating;
 	int irq;
 	int ret;
 
 	ch->cmt = cmt;
-	ch->index = ch_cfg ? ch_cfg->index : index;
+	ch->index = ch_cfg->index;
 	ch->hwidx = hwidx;
 
 	/*
 	 * Compute the address of the channel control register block. For the
 	 * timers with a per-channel start/stop register, compute its address
 	 * as well.
-	 *
-	 * For legacy configuration the address has been mapped explicitly.
 	 */
-	if (cmt->legacy) {
-		ch->ioctrl = cmt->mapbase_ch;
-	} else {
-		switch (cmt->info->model) {
-		case SH_CMT_16BIT:
-			ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
-			break;
-		case SH_CMT_32BIT:
-		case SH_CMT_48BIT:
-			ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
-			break;
-		case SH_CMT_32BIT_FAST:
-			/*
-			 * The 32-bit "fast" timer has a single channel at hwidx
-			 * 5 but is located at offset 0x40 instead of 0x60 for
-			 * some reason.
-			 */
-			ch->ioctrl = cmt->mapbase + 0x40;
-			break;
-		case SH_CMT_48BIT_GEN2:
-			ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
-			ch->ioctrl = ch->iostart + 0x10;
-			break;
-		}
+	switch (cmt->info->model) {
+	case SH_CMT_16BIT:
+		ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+		break;
+	case SH_CMT_32BIT:
+	case SH_CMT_48BIT:
+		ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+		break;
+	case SH_CMT_32BIT_FAST:
+		/*
+		 * The 32-bit "fast" timer has a single channel at hwidx 5 but
+		 * is located at offset 0x40 instead of 0x60 for some reason.
+		 */
+		ch->ioctrl = cmt->mapbase + 0x40;
+		break;
+	case SH_CMT_48BIT_GEN2:
+		ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+		ch->ioctrl = ch->iostart + 0x10;
+		break;
 	}
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
-	if (cmt->legacy)
-		irq = platform_get_irq(cmt->pdev, 0);
-	else
-		irq = platform_get_irq(cmt->pdev, ch->index);
-
+	irq = platform_get_irq(cmt->pdev, ch->index);
 	if (irq < 0) {
 		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		return irq;
@@ -894,20 +879,11 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
-	if (ch_cfg) {
-		ch->timer_bit = cmt->info->model = SH_CMT_48BIT_GEN2
-			      ? 0 : ch->hwidx;
-		clockevent_rating = ch_cfg->clockevent_rating;
-		clocksource_rating = ch_cfg->clocksource_rating;
-	} else {
-		struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
-		ch->timer_bit = cfg->timer_bit;
-		clockevent_rating = cfg->clockevent_rating;
-		clocksource_rating = cfg->clocksource_rating;
-	}
+	ch->timer_bit = cmt->info->model = SH_CMT_48BIT_GEN2 ? 0 : ch->hwidx;
 
 	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      clockevent_rating, clocksource_rating);
+			      ch_cfg->clockevent_rating,
+			      ch_cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&cmt->pdev->dev, "registration failed\n");
 		return ret;
@@ -942,59 +918,12 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 	return 0;
 }
 
-static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
-{
-	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
-	struct resource *res, *res2;
-
-	/* map memory, let mapbase_ch point to our channel */
-	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
-		return -ENXIO;
-	}
-
-	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
-	if (cmt->mapbase_ch = NULL) {
-		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
-		return -ENXIO;
-	}
-
-	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
-	/* map second resource for CMSTR */
-	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
-				       res->start - cfg->channel_offset,
-				       res2 ? resource_size(res2) : 2);
-	if (cmt->mapbase = NULL) {
-		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
-		iounmap(cmt->mapbase_ch);
-		return -ENXIO;
-	}
-
-	/* identify the model based on the resources */
-	if (resource_size(res) = 6)
-		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
-	else if (res2 && (resource_size(res2) = 4))
-		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
-	else
-		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
-
-	return 0;
-}
-
-static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
-{
-	iounmap(cmt->mapbase);
-	if (cmt->mapbase_ch)
-		iounmap(cmt->mapbase_ch);
-}
-
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	const struct platform_device_id *id = pdev->id_entry;
+	unsigned int mask;
+	unsigned int i;
 	int ret;
 
 	memset(cmt, 0, sizeof(*cmt));
@@ -1006,10 +935,9 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	}
 
 	cmt->info = (const struct sh_cmt_info *)id->driver_data;
-	cmt->legacy = cmt->info ? false : true;
 
 	/* Get hold of clock. */
-	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : NULL);
+	cmt->clk = clk_get(&cmt->pdev->dev, NULL);
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
 		return PTR_ERR(cmt->clk);
@@ -1019,26 +947,14 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	if (ret < 0)
 		goto err_clk_put;
 
-	/*
-	 * Map the memory resource(s). We need to support both the legacy
-	 * platform device configuration (with one device per channel) and the
-	 * new version (with multiple channels per device).
-	 */
-	if (cmt->legacy)
-		ret = sh_cmt_map_memory_legacy(cmt);
-	else
-		ret = sh_cmt_map_memory(cmt);
-
+	/* Map the memory resource(s). */
+	ret = sh_cmt_map_memory(cmt);
 	if (ret < 0)
 		goto err_clk_unprepare;
 
 	/* Allocate and setup the channels. */
-	if (cmt->legacy) {
-		cmt->num_channels = 1;
-	} else {
-		cmt->num_channels = cfg->num_channels;
-		cmt->hw_channels = ~cfg->channels_mask;
-	}
+	cmt->num_channels = cfg->num_channels;
+	cmt->hw_channels = ~cfg->channels_mask;
 
 	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
 				GFP_KERNEL);
@@ -1047,26 +963,15 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err_unmap;
 	}
 
-	if (cmt->legacy) {
-		ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit,
-					   NULL, cfg->timer_bit, cmt);
+	for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
+		unsigned int hwidx = ffs(mask) - 1;
+
+		ret = sh_cmt_setup_channel(&cmt->channels[i], &cfg->channels[i],
+					   hwidx, cmt);
 		if (ret < 0)
 			goto err_unmap;
-	} else {
-		const struct sh_timer_channel_config *ch_cfg = cfg->channels;
-		unsigned int mask = cmt->hw_channels;
-		unsigned int i;
-
-		for (i = 0; i < cmt->num_channels; ++i) {
-			unsigned int hwidx = ffs(mask) - 1;
 
-			ret = sh_cmt_setup_channel(&cmt->channels[i], 0, ch_cfg,
-						   hwidx, cmt);
-			if (ret < 0)
-				goto err_unmap;
-
-			mask &= ~(1 << hwidx);
-		}
+		mask &= ~(1 << hwidx);
 	}
 
 	platform_set_drvdata(pdev, cmt);
@@ -1075,7 +980,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 
 err_unmap:
 	kfree(cmt->channels);
-	sh_cmt_unmap_memory(cmt);
+	iounmap(cmt->mapbase);
 err_clk_unprepare:
 	clk_unprepare(cmt->clk);
 err_clk_put:
@@ -1128,7 +1033,6 @@ static int sh_cmt_remove(struct platform_device *pdev)
 }
 
 static const struct platform_device_id sh_cmt_id_table[] = {
-	{ "sh_cmt", 0 },
 	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
 	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
 	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
-- 
1.8.3.2


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

* [PATCH 22/27] clocksource: sh_cmt: Drop support for legacy platform data
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Now that all platforms have switched to the new-style platform data,
drop support for the legacy version.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 174 ++++++++++---------------------------------
 1 file changed, 39 insertions(+), 135 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 077879b..fe9694b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -115,9 +115,7 @@ struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	const struct sh_cmt_info *info;
-	bool legacy;
 
-	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
 	struct clk *clk;
 
@@ -824,58 +822,45 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 				const struct sh_timer_channel_config *ch_cfg,
 				unsigned int hwidx, struct sh_cmt_device *cmt)
 {
-	unsigned long clockevent_rating;
-	unsigned long clocksource_rating;
 	int irq;
 	int ret;
 
 	ch->cmt = cmt;
-	ch->index = ch_cfg ? ch_cfg->index : index;
+	ch->index = ch_cfg->index;
 	ch->hwidx = hwidx;
 
 	/*
 	 * Compute the address of the channel control register block. For the
 	 * timers with a per-channel start/stop register, compute its address
 	 * as well.
-	 *
-	 * For legacy configuration the address has been mapped explicitly.
 	 */
-	if (cmt->legacy) {
-		ch->ioctrl = cmt->mapbase_ch;
-	} else {
-		switch (cmt->info->model) {
-		case SH_CMT_16BIT:
-			ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
-			break;
-		case SH_CMT_32BIT:
-		case SH_CMT_48BIT:
-			ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
-			break;
-		case SH_CMT_32BIT_FAST:
-			/*
-			 * The 32-bit "fast" timer has a single channel at hwidx
-			 * 5 but is located at offset 0x40 instead of 0x60 for
-			 * some reason.
-			 */
-			ch->ioctrl = cmt->mapbase + 0x40;
-			break;
-		case SH_CMT_48BIT_GEN2:
-			ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
-			ch->ioctrl = ch->iostart + 0x10;
-			break;
-		}
+	switch (cmt->info->model) {
+	case SH_CMT_16BIT:
+		ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+		break;
+	case SH_CMT_32BIT:
+	case SH_CMT_48BIT:
+		ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+		break;
+	case SH_CMT_32BIT_FAST:
+		/*
+		 * The 32-bit "fast" timer has a single channel at hwidx 5 but
+		 * is located at offset 0x40 instead of 0x60 for some reason.
+		 */
+		ch->ioctrl = cmt->mapbase + 0x40;
+		break;
+	case SH_CMT_48BIT_GEN2:
+		ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+		ch->ioctrl = ch->iostart + 0x10;
+		break;
 	}
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
-	if (cmt->legacy)
-		irq = platform_get_irq(cmt->pdev, 0);
-	else
-		irq = platform_get_irq(cmt->pdev, ch->index);
-
+	irq = platform_get_irq(cmt->pdev, ch->index);
 	if (irq < 0) {
 		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		return irq;
@@ -894,20 +879,11 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
-	if (ch_cfg) {
-		ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2
-			      ? 0 : ch->hwidx;
-		clockevent_rating = ch_cfg->clockevent_rating;
-		clocksource_rating = ch_cfg->clocksource_rating;
-	} else {
-		struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
-		ch->timer_bit = cfg->timer_bit;
-		clockevent_rating = cfg->clockevent_rating;
-		clocksource_rating = cfg->clocksource_rating;
-	}
+	ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2 ? 0 : ch->hwidx;
 
 	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      clockevent_rating, clocksource_rating);
+			      ch_cfg->clockevent_rating,
+			      ch_cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&cmt->pdev->dev, "registration failed\n");
 		return ret;
@@ -942,59 +918,12 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 	return 0;
 }
 
-static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
-{
-	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
-	struct resource *res, *res2;
-
-	/* map memory, let mapbase_ch point to our channel */
-	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
-		return -ENXIO;
-	}
-
-	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
-	if (cmt->mapbase_ch == NULL) {
-		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
-		return -ENXIO;
-	}
-
-	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
-	/* map second resource for CMSTR */
-	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
-				       res->start - cfg->channel_offset,
-				       res2 ? resource_size(res2) : 2);
-	if (cmt->mapbase == NULL) {
-		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
-		iounmap(cmt->mapbase_ch);
-		return -ENXIO;
-	}
-
-	/* identify the model based on the resources */
-	if (resource_size(res) == 6)
-		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
-	else if (res2 && (resource_size(res2) == 4))
-		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
-	else
-		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
-
-	return 0;
-}
-
-static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
-{
-	iounmap(cmt->mapbase);
-	if (cmt->mapbase_ch)
-		iounmap(cmt->mapbase_ch);
-}
-
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	const struct platform_device_id *id = pdev->id_entry;
+	unsigned int mask;
+	unsigned int i;
 	int ret;
 
 	memset(cmt, 0, sizeof(*cmt));
@@ -1006,10 +935,9 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	}
 
 	cmt->info = (const struct sh_cmt_info *)id->driver_data;
-	cmt->legacy = cmt->info ? false : true;
 
 	/* Get hold of clock. */
-	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : NULL);
+	cmt->clk = clk_get(&cmt->pdev->dev, NULL);
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
 		return PTR_ERR(cmt->clk);
@@ -1019,26 +947,14 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	if (ret < 0)
 		goto err_clk_put;
 
-	/*
-	 * Map the memory resource(s). We need to support both the legacy
-	 * platform device configuration (with one device per channel) and the
-	 * new version (with multiple channels per device).
-	 */
-	if (cmt->legacy)
-		ret = sh_cmt_map_memory_legacy(cmt);
-	else
-		ret = sh_cmt_map_memory(cmt);
-
+	/* Map the memory resource(s). */
+	ret = sh_cmt_map_memory(cmt);
 	if (ret < 0)
 		goto err_clk_unprepare;
 
 	/* Allocate and setup the channels. */
-	if (cmt->legacy) {
-		cmt->num_channels = 1;
-	} else {
-		cmt->num_channels = cfg->num_channels;
-		cmt->hw_channels = ~cfg->channels_mask;
-	}
+	cmt->num_channels = cfg->num_channels;
+	cmt->hw_channels = ~cfg->channels_mask;
 
 	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
 				GFP_KERNEL);
@@ -1047,26 +963,15 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err_unmap;
 	}
 
-	if (cmt->legacy) {
-		ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit,
-					   NULL, cfg->timer_bit, cmt);
+	for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
+		unsigned int hwidx = ffs(mask) - 1;
+
+		ret = sh_cmt_setup_channel(&cmt->channels[i], &cfg->channels[i],
+					   hwidx, cmt);
 		if (ret < 0)
 			goto err_unmap;
-	} else {
-		const struct sh_timer_channel_config *ch_cfg = cfg->channels;
-		unsigned int mask = cmt->hw_channels;
-		unsigned int i;
-
-		for (i = 0; i < cmt->num_channels; ++i) {
-			unsigned int hwidx = ffs(mask) - 1;
 
-			ret = sh_cmt_setup_channel(&cmt->channels[i], 0, ch_cfg,
-						   hwidx, cmt);
-			if (ret < 0)
-				goto err_unmap;
-
-			mask &= ~(1 << hwidx);
-		}
+		mask &= ~(1 << hwidx);
 	}
 
 	platform_set_drvdata(pdev, cmt);
@@ -1075,7 +980,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 
 err_unmap:
 	kfree(cmt->channels);
-	sh_cmt_unmap_memory(cmt);
+	iounmap(cmt->mapbase);
 err_clk_unprepare:
 	clk_unprepare(cmt->clk);
 err_clk_put:
@@ -1128,7 +1033,6 @@ static int sh_cmt_remove(struct platform_device *pdev)
 }
 
 static const struct platform_device_id sh_cmt_id_table[] = {
-	{ "sh_cmt", 0 },
 	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
 	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
 	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
-- 
1.8.3.2


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

* [PATCH 22/27] clocksource: sh_cmt: Drop support for legacy platform data
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Now that all platforms have switched to the new-style platform data,
drop support for the legacy version.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/clocksource/sh_cmt.c | 174 ++++++++++---------------------------------
 1 file changed, 39 insertions(+), 135 deletions(-)

diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 077879b..fe9694b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -115,9 +115,7 @@ struct sh_cmt_device {
 	struct platform_device *pdev;
 
 	const struct sh_cmt_info *info;
-	bool legacy;
 
-	void __iomem *mapbase_ch;
 	void __iomem *mapbase;
 	struct clk *clk;
 
@@ -824,58 +822,45 @@ static int sh_cmt_register(struct sh_cmt_channel *ch, char *name,
 	return 0;
 }
 
-static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
+static int sh_cmt_setup_channel(struct sh_cmt_channel *ch,
 				const struct sh_timer_channel_config *ch_cfg,
 				unsigned int hwidx, struct sh_cmt_device *cmt)
 {
-	unsigned long clockevent_rating;
-	unsigned long clocksource_rating;
 	int irq;
 	int ret;
 
 	ch->cmt = cmt;
-	ch->index = ch_cfg ? ch_cfg->index : index;
+	ch->index = ch_cfg->index;
 	ch->hwidx = hwidx;
 
 	/*
 	 * Compute the address of the channel control register block. For the
 	 * timers with a per-channel start/stop register, compute its address
 	 * as well.
-	 *
-	 * For legacy configuration the address has been mapped explicitly.
 	 */
-	if (cmt->legacy) {
-		ch->ioctrl = cmt->mapbase_ch;
-	} else {
-		switch (cmt->info->model) {
-		case SH_CMT_16BIT:
-			ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
-			break;
-		case SH_CMT_32BIT:
-		case SH_CMT_48BIT:
-			ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
-			break;
-		case SH_CMT_32BIT_FAST:
-			/*
-			 * The 32-bit "fast" timer has a single channel at hwidx
-			 * 5 but is located at offset 0x40 instead of 0x60 for
-			 * some reason.
-			 */
-			ch->ioctrl = cmt->mapbase + 0x40;
-			break;
-		case SH_CMT_48BIT_GEN2:
-			ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
-			ch->ioctrl = ch->iostart + 0x10;
-			break;
-		}
+	switch (cmt->info->model) {
+	case SH_CMT_16BIT:
+		ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+		break;
+	case SH_CMT_32BIT:
+	case SH_CMT_48BIT:
+		ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+		break;
+	case SH_CMT_32BIT_FAST:
+		/*
+		 * The 32-bit "fast" timer has a single channel at hwidx 5 but
+		 * is located at offset 0x40 instead of 0x60 for some reason.
+		 */
+		ch->ioctrl = cmt->mapbase + 0x40;
+		break;
+	case SH_CMT_48BIT_GEN2:
+		ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+		ch->ioctrl = ch->iostart + 0x10;
+		break;
 	}
 
 	/* Request irq using setup_irq() (too early for request_irq()). */
-	if (cmt->legacy)
-		irq = platform_get_irq(cmt->pdev, 0);
-	else
-		irq = platform_get_irq(cmt->pdev, ch->index);
-
+	irq = platform_get_irq(cmt->pdev, ch->index);
 	if (irq < 0) {
 		dev_err(&cmt->pdev->dev, "failed to get irq\n");
 		return irq;
@@ -894,20 +879,11 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
 	ch->match_value = ch->max_match_value;
 	raw_spin_lock_init(&ch->lock);
 
-	if (ch_cfg) {
-		ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2
-			      ? 0 : ch->hwidx;
-		clockevent_rating = ch_cfg->clockevent_rating;
-		clocksource_rating = ch_cfg->clocksource_rating;
-	} else {
-		struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
-		ch->timer_bit = cfg->timer_bit;
-		clockevent_rating = cfg->clockevent_rating;
-		clocksource_rating = cfg->clocksource_rating;
-	}
+	ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2 ? 0 : ch->hwidx;
 
 	ret = sh_cmt_register(ch, (char *)dev_name(&cmt->pdev->dev),
-			      clockevent_rating, clocksource_rating);
+			      ch_cfg->clockevent_rating,
+			      ch_cfg->clocksource_rating);
 	if (ret) {
 		dev_err(&cmt->pdev->dev, "registration failed\n");
 		return ret;
@@ -942,59 +918,12 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 	return 0;
 }
 
-static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
-{
-	struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
-	struct resource *res, *res2;
-
-	/* map memory, let mapbase_ch point to our channel */
-	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
-		return -ENXIO;
-	}
-
-	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
-	if (cmt->mapbase_ch == NULL) {
-		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
-		return -ENXIO;
-	}
-
-	/* optional resource for the shared timer start/stop register */
-	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
-	/* map second resource for CMSTR */
-	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
-				       res->start - cfg->channel_offset,
-				       res2 ? resource_size(res2) : 2);
-	if (cmt->mapbase == NULL) {
-		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
-		iounmap(cmt->mapbase_ch);
-		return -ENXIO;
-	}
-
-	/* identify the model based on the resources */
-	if (resource_size(res) == 6)
-		cmt->info = &sh_cmt_info[SH_CMT_16BIT];
-	else if (res2 && (resource_size(res2) == 4))
-		cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
-	else
-		cmt->info = &sh_cmt_info[SH_CMT_32BIT];
-
-	return 0;
-}
-
-static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
-{
-	iounmap(cmt->mapbase);
-	if (cmt->mapbase_ch)
-		iounmap(cmt->mapbase_ch);
-}
-
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
 	struct sh_timer_config *cfg = pdev->dev.platform_data;
 	const struct platform_device_id *id = pdev->id_entry;
+	unsigned int mask;
+	unsigned int i;
 	int ret;
 
 	memset(cmt, 0, sizeof(*cmt));
@@ -1006,10 +935,9 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	}
 
 	cmt->info = (const struct sh_cmt_info *)id->driver_data;
-	cmt->legacy = cmt->info ? false : true;
 
 	/* Get hold of clock. */
-	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : NULL);
+	cmt->clk = clk_get(&cmt->pdev->dev, NULL);
 	if (IS_ERR(cmt->clk)) {
 		dev_err(&cmt->pdev->dev, "cannot get clock\n");
 		return PTR_ERR(cmt->clk);
@@ -1019,26 +947,14 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	if (ret < 0)
 		goto err_clk_put;
 
-	/*
-	 * Map the memory resource(s). We need to support both the legacy
-	 * platform device configuration (with one device per channel) and the
-	 * new version (with multiple channels per device).
-	 */
-	if (cmt->legacy)
-		ret = sh_cmt_map_memory_legacy(cmt);
-	else
-		ret = sh_cmt_map_memory(cmt);
-
+	/* Map the memory resource(s). */
+	ret = sh_cmt_map_memory(cmt);
 	if (ret < 0)
 		goto err_clk_unprepare;
 
 	/* Allocate and setup the channels. */
-	if (cmt->legacy) {
-		cmt->num_channels = 1;
-	} else {
-		cmt->num_channels = cfg->num_channels;
-		cmt->hw_channels = ~cfg->channels_mask;
-	}
+	cmt->num_channels = cfg->num_channels;
+	cmt->hw_channels = ~cfg->channels_mask;
 
 	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
 				GFP_KERNEL);
@@ -1047,26 +963,15 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err_unmap;
 	}
 
-	if (cmt->legacy) {
-		ret = sh_cmt_setup_channel(&cmt->channels[0], cfg->timer_bit,
-					   NULL, cfg->timer_bit, cmt);
+	for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
+		unsigned int hwidx = ffs(mask) - 1;
+
+		ret = sh_cmt_setup_channel(&cmt->channels[i], &cfg->channels[i],
+					   hwidx, cmt);
 		if (ret < 0)
 			goto err_unmap;
-	} else {
-		const struct sh_timer_channel_config *ch_cfg = cfg->channels;
-		unsigned int mask = cmt->hw_channels;
-		unsigned int i;
-
-		for (i = 0; i < cmt->num_channels; ++i) {
-			unsigned int hwidx = ffs(mask) - 1;
 
-			ret = sh_cmt_setup_channel(&cmt->channels[i], 0, ch_cfg,
-						   hwidx, cmt);
-			if (ret < 0)
-				goto err_unmap;
-
-			mask &= ~(1 << hwidx);
-		}
+		mask &= ~(1 << hwidx);
 	}
 
 	platform_set_drvdata(pdev, cmt);
@@ -1075,7 +980,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 
 err_unmap:
 	kfree(cmt->channels);
-	sh_cmt_unmap_memory(cmt);
+	iounmap(cmt->mapbase);
 err_clk_unprepare:
 	clk_unprepare(cmt->clk);
 err_clk_put:
@@ -1128,7 +1033,6 @@ static int sh_cmt_remove(struct platform_device *pdev)
 }
 
 static const struct platform_device_id sh_cmt_id_table[] = {
-	{ "sh_cmt", 0 },
 	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
 	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
 	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
-- 
1.8.3.2

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  1:00   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
 drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++++++----
 2 files changed, 160 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt

diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
new file mode 100644
index 0000000..28d4ab5
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
@@ -0,0 +1,75 @@
+* Renesas R-Car Compare Match Timer (CMT)
+
+The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
+inputs and programmable compare match.
+
+Channels share hadware resources but their counter and compare match value are
+independent. A particular CMT instance can implement only a subset of the
+channels supported by the CMT model. Channels indices start from 0 and are
+consecutive.
+
+Required Properties:
+
+  - compatible: must contain one of the following.
+    - "renesas,cmt-32" for the 32-bit CMT
+		(CMT0 on sh7372, sh73a0 and r8a7740)
+    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
+		(CMT[234] on sh7372, sh73a0 and r8a7740)
+    - "renasas,cmt-48" for the 48-bit CMT
+		(CMT1 on sh7372, sh73a0 and r8a7740)
+    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
+    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
+
+  - reg: base address and length of the registers block for the timer module.
+  - interrupt-parent, interrupts: interrupt-specifier for the timer, one per
+    channel.
+  - clocks: phandle and clock-specifier pair for the functional clock.
+  - clock-names: must be "fck".
+
+  - #address-cells: must be 1
+  - #size-cells: must be 0
+
+  - renesas,channels-mask: integer bitmask of the channels implemented by the
+    timer instance.
+
+
+Each channel is described by a sub-node named "channel@<idx>", where <idx> is
+the channel index.
+
+Channels Required Properties:
+
+  - reg: the channel index.
+
+Channels Optional Properties:
+
+  - clock-source-rating: rating of the timer as a clock source device.
+  - clock-event-rating: rating of the timer as a clock event device.
+
+
+Example: R8A7790 (R-Car H2) CMT0 node
+
+	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
+	them channels 0 and 1 in the documentation.
+
+	cmt0: timer@ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		channel@0 {
+			reg = <0>;
+			clock-event-rating = <80>;
+		};
+		channel@0 {
+			reg = <0>;
+			clock-source-rating = <80>;
+		};
+	};
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index fe9694b..8e46c40 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
@@ -918,10 +919,72 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 	return 0;
 }
 
+static const struct platform_device_id sh_cmt_id_table[] = {
+	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
+
+static const struct of_device_id sh_cmt_of_table[] = {
+	{ .compatible = "renesas,cmt-32", .data = &sh_cmt_info[SH_CMT_32BIT] },
+	{ .compatible = "renesas,cmt-32-fast", .data = &sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ .compatible = "renasas,cmt-48", .data = &sh_cmt_info[SH_CMT_48BIT] },
+	{ .compatible = "renesas,cmt-48-gen2", .data = &sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+
+static struct sh_timer_channel_config *
+sh_cmt_parse_dt(struct sh_cmt_device *cmt)
+{
+	struct sh_timer_channel_config *channels;
+	struct sh_timer_channel_config *channel;
+	struct device_node *np = cmt->pdev->dev.of_node;
+	struct device_node *child;
+	int ret;
+
+	cmt->num_channels = of_get_child_count(np);
+	if (cmt->num_channels = 0)
+		return ERR_PTR(-EINVAL);
+
+	ret = of_property_read_u32(np, "renesas,channels-mask",
+				   &cmt->hw_channels);
+	if (ret < 0)
+		return ERR_PTR(-EINVAL);
+
+	channels = devm_kzalloc(&cmt->pdev->dev, sizeof(*channels), GFP_KERNEL);
+	if (channels = NULL)
+		return ERR_PTR(-ENOMEM);
+
+	channel = channels;
+
+	for_each_child_of_node(np, child) {
+		u32 val;
+
+		ret = of_property_read_u32(child, "reg", &channel->index);
+		if (ret < 0)
+			return ERR_PTR(-EINVAL);
+
+		ret = of_property_read_u32(child, "clock-source-rating", &val);
+		if (ret = 0)
+			channel->clocksource_rating = val;
+		ret = of_property_read_u32(child, "clock-event-rating", &val);
+		if (ret = 0)
+			channel->clockevent_rating = val;
+
+		channel++;
+	}
+
+	return channels;
+}
+
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	const struct platform_device_id *id = pdev->id_entry;
+	const struct sh_timer_channel_config *ch_cfg;
 	unsigned int mask;
 	unsigned int i;
 	int ret;
@@ -929,13 +992,28 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	memset(cmt, 0, sizeof(*cmt));
 	cmt->pdev = pdev;
 
-	if (!cfg) {
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		const struct of_device_id *id;
+
+		id = of_match_node(sh_cmt_of_table, pdev->dev.of_node);
+		cmt->info = id->data;
+
+		ch_cfg = sh_cmt_parse_dt(cmt);
+		if (IS_ERR(ch_cfg))
+			return PTR_ERR(ch_cfg);
+	} else if (pdev->dev.platform_data) {
+		struct sh_timer_config *cfg = pdev->dev.platform_data;
+		const struct platform_device_id *id = pdev->id_entry;
+
+		cmt->info = (const struct sh_cmt_info *)id->driver_data;
+		cmt->num_channels = cfg->num_channels;
+		cmt->hw_channels = ~cfg->channels_mask;
+		ch_cfg = cfg->channels;
+	} else {
 		dev_err(&cmt->pdev->dev, "missing platform data\n");
 		return -ENXIO;
 	}
 
-	cmt->info = (const struct sh_cmt_info *)id->driver_data;
-
 	/* Get hold of clock. */
 	cmt->clk = clk_get(&cmt->pdev->dev, NULL);
 	if (IS_ERR(cmt->clk)) {
@@ -953,9 +1031,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err_clk_unprepare;
 
 	/* Allocate and setup the channels. */
-	cmt->num_channels = cfg->num_channels;
-	cmt->hw_channels = ~cfg->channels_mask;
-
 	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
 				GFP_KERNEL);
 	if (cmt->channels = NULL) {
@@ -966,7 +1041,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
 		unsigned int hwidx = ffs(mask) - 1;
 
-		ret = sh_cmt_setup_channel(&cmt->channels[i], &cfg->channels[i],
+		ret = sh_cmt_setup_channel(&cmt->channels[i], &ch_cfg[i],
 					   hwidx, cmt);
 		if (ret < 0)
 			goto err_unmap;
@@ -1032,21 +1107,12 @@ static int sh_cmt_remove(struct platform_device *pdev)
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
-static const struct platform_device_id sh_cmt_id_table[] = {
-	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
-	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
-	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
-	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
-	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
-	{ }
-};
-MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
-
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= sh_cmt_remove,
 	.driver		= {
 		.name	= "sh_cmt",
+		.of_match_table = of_match_ptr(sh_cmt_of_table),
 	},
 	.id_table	= sh_cmt_id_table,
 };
-- 
1.8.3.2


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
 drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++++++----
 2 files changed, 160 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt

diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
new file mode 100644
index 0000000..28d4ab5
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
@@ -0,0 +1,75 @@
+* Renesas R-Car Compare Match Timer (CMT)
+
+The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
+inputs and programmable compare match.
+
+Channels share hadware resources but their counter and compare match value are
+independent. A particular CMT instance can implement only a subset of the
+channels supported by the CMT model. Channels indices start from 0 and are
+consecutive.
+
+Required Properties:
+
+  - compatible: must contain one of the following.
+    - "renesas,cmt-32" for the 32-bit CMT
+		(CMT0 on sh7372, sh73a0 and r8a7740)
+    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
+		(CMT[234] on sh7372, sh73a0 and r8a7740)
+    - "renasas,cmt-48" for the 48-bit CMT
+		(CMT1 on sh7372, sh73a0 and r8a7740)
+    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
+    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
+
+  - reg: base address and length of the registers block for the timer module.
+  - interrupt-parent, interrupts: interrupt-specifier for the timer, one per
+    channel.
+  - clocks: phandle and clock-specifier pair for the functional clock.
+  - clock-names: must be "fck".
+
+  - #address-cells: must be 1
+  - #size-cells: must be 0
+
+  - renesas,channels-mask: integer bitmask of the channels implemented by the
+    timer instance.
+
+
+Each channel is described by a sub-node named "channel@<idx>", where <idx> is
+the channel index.
+
+Channels Required Properties:
+
+  - reg: the channel index.
+
+Channels Optional Properties:
+
+  - clock-source-rating: rating of the timer as a clock source device.
+  - clock-event-rating: rating of the timer as a clock event device.
+
+
+Example: R8A7790 (R-Car H2) CMT0 node
+
+	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
+	them channels 0 and 1 in the documentation.
+
+	cmt0: timer@ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		channel@0 {
+			reg = <0>;
+			clock-event-rating = <80>;
+		};
+		channel@0 {
+			reg = <0>;
+			clock-source-rating = <80>;
+		};
+	};
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index fe9694b..8e46c40 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
@@ -918,10 +919,72 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 	return 0;
 }
 
+static const struct platform_device_id sh_cmt_id_table[] = {
+	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
+
+static const struct of_device_id sh_cmt_of_table[] = {
+	{ .compatible = "renesas,cmt-32", .data = &sh_cmt_info[SH_CMT_32BIT] },
+	{ .compatible = "renesas,cmt-32-fast", .data = &sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ .compatible = "renasas,cmt-48", .data = &sh_cmt_info[SH_CMT_48BIT] },
+	{ .compatible = "renesas,cmt-48-gen2", .data = &sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+
+static struct sh_timer_channel_config *
+sh_cmt_parse_dt(struct sh_cmt_device *cmt)
+{
+	struct sh_timer_channel_config *channels;
+	struct sh_timer_channel_config *channel;
+	struct device_node *np = cmt->pdev->dev.of_node;
+	struct device_node *child;
+	int ret;
+
+	cmt->num_channels = of_get_child_count(np);
+	if (cmt->num_channels == 0)
+		return ERR_PTR(-EINVAL);
+
+	ret = of_property_read_u32(np, "renesas,channels-mask",
+				   &cmt->hw_channels);
+	if (ret < 0)
+		return ERR_PTR(-EINVAL);
+
+	channels = devm_kzalloc(&cmt->pdev->dev, sizeof(*channels), GFP_KERNEL);
+	if (channels == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	channel = channels;
+
+	for_each_child_of_node(np, child) {
+		u32 val;
+
+		ret = of_property_read_u32(child, "reg", &channel->index);
+		if (ret < 0)
+			return ERR_PTR(-EINVAL);
+
+		ret = of_property_read_u32(child, "clock-source-rating", &val);
+		if (ret == 0)
+			channel->clocksource_rating = val;
+		ret = of_property_read_u32(child, "clock-event-rating", &val);
+		if (ret == 0)
+			channel->clockevent_rating = val;
+
+		channel++;
+	}
+
+	return channels;
+}
+
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	const struct platform_device_id *id = pdev->id_entry;
+	const struct sh_timer_channel_config *ch_cfg;
 	unsigned int mask;
 	unsigned int i;
 	int ret;
@@ -929,13 +992,28 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	memset(cmt, 0, sizeof(*cmt));
 	cmt->pdev = pdev;
 
-	if (!cfg) {
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		const struct of_device_id *id;
+
+		id = of_match_node(sh_cmt_of_table, pdev->dev.of_node);
+		cmt->info = id->data;
+
+		ch_cfg = sh_cmt_parse_dt(cmt);
+		if (IS_ERR(ch_cfg))
+			return PTR_ERR(ch_cfg);
+	} else if (pdev->dev.platform_data) {
+		struct sh_timer_config *cfg = pdev->dev.platform_data;
+		const struct platform_device_id *id = pdev->id_entry;
+
+		cmt->info = (const struct sh_cmt_info *)id->driver_data;
+		cmt->num_channels = cfg->num_channels;
+		cmt->hw_channels = ~cfg->channels_mask;
+		ch_cfg = cfg->channels;
+	} else {
 		dev_err(&cmt->pdev->dev, "missing platform data\n");
 		return -ENXIO;
 	}
 
-	cmt->info = (const struct sh_cmt_info *)id->driver_data;
-
 	/* Get hold of clock. */
 	cmt->clk = clk_get(&cmt->pdev->dev, NULL);
 	if (IS_ERR(cmt->clk)) {
@@ -953,9 +1031,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err_clk_unprepare;
 
 	/* Allocate and setup the channels. */
-	cmt->num_channels = cfg->num_channels;
-	cmt->hw_channels = ~cfg->channels_mask;
-
 	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
 				GFP_KERNEL);
 	if (cmt->channels == NULL) {
@@ -966,7 +1041,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
 		unsigned int hwidx = ffs(mask) - 1;
 
-		ret = sh_cmt_setup_channel(&cmt->channels[i], &cfg->channels[i],
+		ret = sh_cmt_setup_channel(&cmt->channels[i], &ch_cfg[i],
 					   hwidx, cmt);
 		if (ret < 0)
 			goto err_unmap;
@@ -1032,21 +1107,12 @@ static int sh_cmt_remove(struct platform_device *pdev)
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
-static const struct platform_device_id sh_cmt_id_table[] = {
-	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
-	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
-	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
-	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
-	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
-	{ }
-};
-MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
-
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= sh_cmt_remove,
 	.driver		= {
 		.name	= "sh_cmt",
+		.of_match_table = of_match_ptr(sh_cmt_of_table),
 	},
 	.id_table	= sh_cmt_id_table,
 };
-- 
1.8.3.2


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: devicetree at vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
 drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++++++----
 2 files changed, 160 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt

diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
new file mode 100644
index 0000000..28d4ab5
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
@@ -0,0 +1,75 @@
+* Renesas R-Car Compare Match Timer (CMT)
+
+The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
+inputs and programmable compare match.
+
+Channels share hadware resources but their counter and compare match value are
+independent. A particular CMT instance can implement only a subset of the
+channels supported by the CMT model. Channels indices start from 0 and are
+consecutive.
+
+Required Properties:
+
+  - compatible: must contain one of the following.
+    - "renesas,cmt-32" for the 32-bit CMT
+		(CMT0 on sh7372, sh73a0 and r8a7740)
+    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
+		(CMT[234] on sh7372, sh73a0 and r8a7740)
+    - "renasas,cmt-48" for the 48-bit CMT
+		(CMT1 on sh7372, sh73a0 and r8a7740)
+    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
+    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
+
+  - reg: base address and length of the registers block for the timer module.
+  - interrupt-parent, interrupts: interrupt-specifier for the timer, one per
+    channel.
+  - clocks: phandle and clock-specifier pair for the functional clock.
+  - clock-names: must be "fck".
+
+  - #address-cells: must be 1
+  - #size-cells: must be 0
+
+  - renesas,channels-mask: integer bitmask of the channels implemented by the
+    timer instance.
+
+
+Each channel is described by a sub-node named "channel@<idx>", where <idx> is
+the channel index.
+
+Channels Required Properties:
+
+  - reg: the channel index.
+
+Channels Optional Properties:
+
+  - clock-source-rating: rating of the timer as a clock source device.
+  - clock-event-rating: rating of the timer as a clock event device.
+
+
+Example: R8A7790 (R-Car H2) CMT0 node
+
+	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
+	them channels 0 and 1 in the documentation.
+
+	cmt0: timer at ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		channel at 0 {
+			reg = <0>;
+			clock-event-rating = <80>;
+		};
+		channel at 0 {
+			reg = <0>;
+			clock-source-rating = <80>;
+		};
+	};
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index fe9694b..8e46c40 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
@@ -918,10 +919,72 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
 	return 0;
 }
 
+static const struct platform_device_id sh_cmt_id_table[] = {
+	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
+
+static const struct of_device_id sh_cmt_of_table[] = {
+	{ .compatible = "renesas,cmt-32", .data = &sh_cmt_info[SH_CMT_32BIT] },
+	{ .compatible = "renesas,cmt-32-fast", .data = &sh_cmt_info[SH_CMT_32BIT_FAST] },
+	{ .compatible = "renasas,cmt-48", .data = &sh_cmt_info[SH_CMT_48BIT] },
+	{ .compatible = "renesas,cmt-48-gen2", .data = &sh_cmt_info[SH_CMT_48BIT_GEN2] },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+
+static struct sh_timer_channel_config *
+sh_cmt_parse_dt(struct sh_cmt_device *cmt)
+{
+	struct sh_timer_channel_config *channels;
+	struct sh_timer_channel_config *channel;
+	struct device_node *np = cmt->pdev->dev.of_node;
+	struct device_node *child;
+	int ret;
+
+	cmt->num_channels = of_get_child_count(np);
+	if (cmt->num_channels == 0)
+		return ERR_PTR(-EINVAL);
+
+	ret = of_property_read_u32(np, "renesas,channels-mask",
+				   &cmt->hw_channels);
+	if (ret < 0)
+		return ERR_PTR(-EINVAL);
+
+	channels = devm_kzalloc(&cmt->pdev->dev, sizeof(*channels), GFP_KERNEL);
+	if (channels == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	channel = channels;
+
+	for_each_child_of_node(np, child) {
+		u32 val;
+
+		ret = of_property_read_u32(child, "reg", &channel->index);
+		if (ret < 0)
+			return ERR_PTR(-EINVAL);
+
+		ret = of_property_read_u32(child, "clock-source-rating", &val);
+		if (ret == 0)
+			channel->clocksource_rating = val;
+		ret = of_property_read_u32(child, "clock-event-rating", &val);
+		if (ret == 0)
+			channel->clockevent_rating = val;
+
+		channel++;
+	}
+
+	return channels;
+}
+
 static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 {
-	struct sh_timer_config *cfg = pdev->dev.platform_data;
-	const struct platform_device_id *id = pdev->id_entry;
+	const struct sh_timer_channel_config *ch_cfg;
 	unsigned int mask;
 	unsigned int i;
 	int ret;
@@ -929,13 +992,28 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	memset(cmt, 0, sizeof(*cmt));
 	cmt->pdev = pdev;
 
-	if (!cfg) {
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		const struct of_device_id *id;
+
+		id = of_match_node(sh_cmt_of_table, pdev->dev.of_node);
+		cmt->info = id->data;
+
+		ch_cfg = sh_cmt_parse_dt(cmt);
+		if (IS_ERR(ch_cfg))
+			return PTR_ERR(ch_cfg);
+	} else if (pdev->dev.platform_data) {
+		struct sh_timer_config *cfg = pdev->dev.platform_data;
+		const struct platform_device_id *id = pdev->id_entry;
+
+		cmt->info = (const struct sh_cmt_info *)id->driver_data;
+		cmt->num_channels = cfg->num_channels;
+		cmt->hw_channels = ~cfg->channels_mask;
+		ch_cfg = cfg->channels;
+	} else {
 		dev_err(&cmt->pdev->dev, "missing platform data\n");
 		return -ENXIO;
 	}
 
-	cmt->info = (const struct sh_cmt_info *)id->driver_data;
-
 	/* Get hold of clock. */
 	cmt->clk = clk_get(&cmt->pdev->dev, NULL);
 	if (IS_ERR(cmt->clk)) {
@@ -953,9 +1031,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 		goto err_clk_unprepare;
 
 	/* Allocate and setup the channels. */
-	cmt->num_channels = cfg->num_channels;
-	cmt->hw_channels = ~cfg->channels_mask;
-
 	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
 				GFP_KERNEL);
 	if (cmt->channels == NULL) {
@@ -966,7 +1041,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
 	for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
 		unsigned int hwidx = ffs(mask) - 1;
 
-		ret = sh_cmt_setup_channel(&cmt->channels[i], &cfg->channels[i],
+		ret = sh_cmt_setup_channel(&cmt->channels[i], &ch_cfg[i],
 					   hwidx, cmt);
 		if (ret < 0)
 			goto err_unmap;
@@ -1032,21 +1107,12 @@ static int sh_cmt_remove(struct platform_device *pdev)
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
-static const struct platform_device_id sh_cmt_id_table[] = {
-	{ "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
-	{ "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
-	{ "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
-	{ "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
-	{ "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
-	{ }
-};
-MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
-
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= sh_cmt_remove,
 	.driver		= {
 		.name	= "sh_cmt",
+		.of_match_table = of_match_ptr(sh_cmt_of_table),
 	},
 	.id_table	= sh_cmt_id_table,
 };
-- 
1.8.3.2

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

* [PATCH 24/27] ARM: shmobile: r8a7790: Add CMT devices to DT
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  1:00   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 54ab318..a236c7e 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -179,6 +179,44 @@
 			     <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	cmt0: timer@ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		status = "disabled";
+	};
+
+	cmt1: timer@e6130000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xe6130000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 123 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 124 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 125 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 126 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0xff>;
+
+		status = "disabled";
+	};
+
 	irqc0: interrupt-controller@e61c0000 {
 		compatible = "renesas,irqc-r8a7790", "renesas,irqc";
 		#interrupt-cells = <2>;
-- 
1.8.3.2


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

* [PATCH 24/27] ARM: shmobile: r8a7790: Add CMT devices to DT
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 54ab318..a236c7e 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -179,6 +179,44 @@
 			     <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	cmt0: timer@ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		status = "disabled";
+	};
+
+	cmt1: timer@e6130000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xe6130000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 123 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 124 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 125 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 126 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0xff>;
+
+		status = "disabled";
+	};
+
 	irqc0: interrupt-controller@e61c0000 {
 		compatible = "renesas,irqc-r8a7790", "renesas,irqc";
 		#interrupt-cells = <2>;
-- 
1.8.3.2


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

* [PATCH 24/27] ARM: shmobile: r8a7790: Add CMT devices to DT
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 54ab318..a236c7e 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -179,6 +179,44 @@
 			     <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	cmt0: timer at ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		status = "disabled";
+	};
+
+	cmt1: timer at e6130000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xe6130000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 123 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 124 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 125 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 126 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0xff>;
+
+		status = "disabled";
+	};
+
 	irqc0: interrupt-controller at e61c0000 {
 		compatible = "renesas,irqc-r8a7790", "renesas,irqc";
 		#interrupt-cells = <2>;
-- 
1.8.3.2

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

* [PATCH 25/27] ARM: shmobile: r8a7791: Add CMT devices to DT
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  1:00   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 240c4ec..bcfb998 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -162,6 +162,44 @@
 			     <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	cmt0: timer@ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		status = "disabled";
+	};
+
+	cmt1: timer@e6130000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xe6130000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 123 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 124 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 125 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 126 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0xff>;
+
+		status = "disabled";
+	};
+
 	irqc0: interrupt-controller@e61c0000 {
 		compatible = "renesas,irqc-r8a7791", "renesas,irqc";
 		#interrupt-cells = <2>;
-- 
1.8.3.2


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

* [PATCH 25/27] ARM: shmobile: r8a7791: Add CMT devices to DT
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 240c4ec..bcfb998 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -162,6 +162,44 @@
 			     <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	cmt0: timer@ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		status = "disabled";
+	};
+
+	cmt1: timer@e6130000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xe6130000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 123 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 124 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 125 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 126 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0xff>;
+
+		status = "disabled";
+	};
+
 	irqc0: interrupt-controller@e61c0000 {
 		compatible = "renesas,irqc-r8a7791", "renesas,irqc";
 		#interrupt-cells = <2>;
-- 
1.8.3.2


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

* [PATCH 25/27] ARM: shmobile: r8a7791: Add CMT devices to DT
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 240c4ec..bcfb998 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -162,6 +162,44 @@
 			     <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
+	cmt0: timer at ffca0000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xffca0000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0x60>;
+
+		status = "disabled";
+	};
+
+	cmt1: timer at e6130000 {
+		compatible = "renesas,cmt-48-gen2";
+		reg = <0 0xe6130000 0 0x1004>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 123 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 124 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 125 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 126 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		renesas,channels-mask = <0xff>;
+
+		status = "disabled";
+	};
+
 	irqc0: interrupt-controller at e61c0000 {
 		compatible = "renesas,irqc-r8a7791", "renesas,irqc";
 		#interrupt-cells = <2>;
-- 
1.8.3.2

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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  1:00   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the CMT0 device and configure channel 0 as a clock event
provider.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790-lager.dts            |  9 +++++++++
 arch/arm/mach-shmobile/board-lager-reference.c | 15 +--------------
 arch/arm/mach-shmobile/include/mach/r8a7790.h  |  1 -
 arch/arm/mach-shmobile/setup-r8a7790.c         |  7 +------
 4 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 4199ae4..54ab17d 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -84,6 +84,15 @@
 	};
 };
 
+&cmt0 {
+	status = "ok";
+
+	channel@0 {
+		reg = <0>;
+		clock-event-rating = <80>;
+	};
+};
+
 &mmcif1 {
 	pinctrl-0 = <&mmc1_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 4dd43b1..ee95a8c 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -29,23 +29,10 @@
 
 static void __init lager_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
-	/*
-	 * This is a really crude hack to provide clkdev support to the CMT
-	 * device until it gets moved to DT.
-	 */
-	struct clk *clk;
-
-	clk = clk_get(NULL, "cmt0");
-	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
-		clk_put(clk);
-	}
-#else
+#ifndef CONFIG_COMMON_CLK
 	r8a7790_clock_init();
 #endif
 
-	r8a7790_add_dt_devices();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
index 0b95bab..62b31f3 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
@@ -29,7 +29,6 @@ enum {
 };
 
 void r8a7790_add_standard_devices(void);
-void r8a7790_add_dt_devices(void);
 void r8a7790_clock_init(void);
 void r8a7790_pinmux_init(void);
 void r8a7790_pm_init(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index 3e5813f..462c81f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
 					  &cmt##idx##_platform_data,	\
 					  sizeof(struct sh_timer_config))
 
-void __init r8a7790_add_dt_devices(void)
-{
-	r8a7790_register_cmt(0);
-}
-
 void __init r8a7790_add_standard_devices(void)
 {
 	r8a7790_register_scif(0);
@@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
 	r8a7790_register_scif(7);
 	r8a7790_register_scif(8);
 	r8a7790_register_scif(9);
-	r8a7790_add_dt_devices();
+	r8a7790_register_cmt(0);
 	r8a7790_register_irqc(0);
 	r8a7790_register_thermal();
 }
-- 
1.8.3.2


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Enable the CMT0 device and configure channel 0 as a clock event
provider.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790-lager.dts            |  9 +++++++++
 arch/arm/mach-shmobile/board-lager-reference.c | 15 +--------------
 arch/arm/mach-shmobile/include/mach/r8a7790.h  |  1 -
 arch/arm/mach-shmobile/setup-r8a7790.c         |  7 +------
 4 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 4199ae4..54ab17d 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -84,6 +84,15 @@
 	};
 };
 
+&cmt0 {
+	status = "ok";
+
+	channel@0 {
+		reg = <0>;
+		clock-event-rating = <80>;
+	};
+};
+
 &mmcif1 {
 	pinctrl-0 = <&mmc1_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 4dd43b1..ee95a8c 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -29,23 +29,10 @@
 
 static void __init lager_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
-	/*
-	 * This is a really crude hack to provide clkdev support to the CMT
-	 * device until it gets moved to DT.
-	 */
-	struct clk *clk;
-
-	clk = clk_get(NULL, "cmt0");
-	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
-		clk_put(clk);
-	}
-#else
+#ifndef CONFIG_COMMON_CLK
 	r8a7790_clock_init();
 #endif
 
-	r8a7790_add_dt_devices();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
index 0b95bab..62b31f3 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
@@ -29,7 +29,6 @@ enum {
 };
 
 void r8a7790_add_standard_devices(void);
-void r8a7790_add_dt_devices(void);
 void r8a7790_clock_init(void);
 void r8a7790_pinmux_init(void);
 void r8a7790_pm_init(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index 3e5813f..462c81f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
 					  &cmt##idx##_platform_data,	\
 					  sizeof(struct sh_timer_config))
 
-void __init r8a7790_add_dt_devices(void)
-{
-	r8a7790_register_cmt(0);
-}
-
 void __init r8a7790_add_standard_devices(void)
 {
 	r8a7790_register_scif(0);
@@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
 	r8a7790_register_scif(7);
 	r8a7790_register_scif(8);
 	r8a7790_register_scif(9);
-	r8a7790_add_dt_devices();
+	r8a7790_register_cmt(0);
 	r8a7790_register_irqc(0);
 	r8a7790_register_thermal();
 }
-- 
1.8.3.2


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the CMT0 device and configure channel 0 as a clock event
provider.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790-lager.dts            |  9 +++++++++
 arch/arm/mach-shmobile/board-lager-reference.c | 15 +--------------
 arch/arm/mach-shmobile/include/mach/r8a7790.h  |  1 -
 arch/arm/mach-shmobile/setup-r8a7790.c         |  7 +------
 4 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 4199ae4..54ab17d 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -84,6 +84,15 @@
 	};
 };
 
+&cmt0 {
+	status = "ok";
+
+	channel at 0 {
+		reg = <0>;
+		clock-event-rating = <80>;
+	};
+};
+
 &mmcif1 {
 	pinctrl-0 = <&mmc1_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 4dd43b1..ee95a8c 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -29,23 +29,10 @@
 
 static void __init lager_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
-	/*
-	 * This is a really crude hack to provide clkdev support to the CMT
-	 * device until it gets moved to DT.
-	 */
-	struct clk *clk;
-
-	clk = clk_get(NULL, "cmt0");
-	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
-		clk_put(clk);
-	}
-#else
+#ifndef CONFIG_COMMON_CLK
 	r8a7790_clock_init();
 #endif
 
-	r8a7790_add_dt_devices();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
index 0b95bab..62b31f3 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
@@ -29,7 +29,6 @@ enum {
 };
 
 void r8a7790_add_standard_devices(void);
-void r8a7790_add_dt_devices(void);
 void r8a7790_clock_init(void);
 void r8a7790_pinmux_init(void);
 void r8a7790_pm_init(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index 3e5813f..462c81f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
 					  &cmt##idx##_platform_data,	\
 					  sizeof(struct sh_timer_config))
 
-void __init r8a7790_add_dt_devices(void)
-{
-	r8a7790_register_cmt(0);
-}
-
 void __init r8a7790_add_standard_devices(void)
 {
 	r8a7790_register_scif(0);
@@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
 	r8a7790_register_scif(7);
 	r8a7790_register_scif(8);
 	r8a7790_register_scif(9);
-	r8a7790_add_dt_devices();
+	r8a7790_register_cmt(0);
 	r8a7790_register_irqc(0);
 	r8a7790_register_thermal();
 }
-- 
1.8.3.2

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

* [PATCH 27/27] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree
  2014-02-14  0:59 ` Laurent Pinchart
  (?)
@ 2014-02-14  1:00   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the CMT0 device and configure channel 0 as a clock event
provider.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791-koelsch.dts            |  9 +++++++++
 arch/arm/mach-shmobile/board-koelsch-reference.c | 15 +--------------
 arch/arm/mach-shmobile/include/mach/r8a7791.h    |  1 -
 arch/arm/mach-shmobile/setup-r8a7791.c           |  7 +------
 4 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 42fd5eb..36e1c33 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -130,6 +130,15 @@
 	};
 };
 
+&cmt0 {
+	status = "ok";
+
+	channel@0 {
+		reg = <0>;
+		clock-event-rating = <80>;
+	};
+};
+
 &sata0 {
 	status = "okay";
 };
diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
index e67a4be7..abcb8da 100644
--- a/arch/arm/mach-shmobile/board-koelsch-reference.c
+++ b/arch/arm/mach-shmobile/board-koelsch-reference.c
@@ -30,22 +30,9 @@
 
 static void __init koelsch_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
-	/*
-	 * This is a really crude hack to provide clkdev support to the CMT
-	 * device until they get moved to DT.
-	 */
-	struct clk *clk;
-
-	clk = clk_get(NULL, "cmt0");
-	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
-		clk_put(clk);
-	}
-#else
+#ifndef CONFIG_COMMON_CLK
 	r8a7791_clock_init();
 #endif
-	r8a7791_add_dt_devices();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h
index 200fa69..57a37f1 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h
@@ -2,7 +2,6 @@
 #define __ASM_R8A7791_H__
 
 void r8a7791_add_standard_devices(void);
-void r8a7791_add_dt_devices(void);
 void r8a7791_clock_init(void);
 void r8a7791_pinmux_init(void);
 void r8a7791_init_early(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index a17ebb8..c1e9c0f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -189,11 +189,6 @@ static const struct resource thermal_resources[] __initconst = {
 					thermal_resources,		\
 					ARRAY_SIZE(thermal_resources))
 
-void __init r8a7791_add_dt_devices(void)
-{
-	r8a7791_register_cmt(0);
-}
-
 void __init r8a7791_add_standard_devices(void)
 {
 	r8a7791_register_scif(0);
@@ -211,7 +206,7 @@ void __init r8a7791_add_standard_devices(void)
 	r8a7791_register_scif(12);
 	r8a7791_register_scif(13);
 	r8a7791_register_scif(14);
-	r8a7791_add_dt_devices();
+	r8a7791_register_cmt(0);
 	r8a7791_register_irqc(0);
 	r8a7791_register_thermal();
 }
-- 
1.8.3.2


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

* [PATCH 27/27] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Enable the CMT0 device and configure channel 0 as a clock event
provider.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791-koelsch.dts            |  9 +++++++++
 arch/arm/mach-shmobile/board-koelsch-reference.c | 15 +--------------
 arch/arm/mach-shmobile/include/mach/r8a7791.h    |  1 -
 arch/arm/mach-shmobile/setup-r8a7791.c           |  7 +------
 4 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 42fd5eb..36e1c33 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -130,6 +130,15 @@
 	};
 };
 
+&cmt0 {
+	status = "ok";
+
+	channel@0 {
+		reg = <0>;
+		clock-event-rating = <80>;
+	};
+};
+
 &sata0 {
 	status = "okay";
 };
diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
index e67a4be7..abcb8da 100644
--- a/arch/arm/mach-shmobile/board-koelsch-reference.c
+++ b/arch/arm/mach-shmobile/board-koelsch-reference.c
@@ -30,22 +30,9 @@
 
 static void __init koelsch_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
-	/*
-	 * This is a really crude hack to provide clkdev support to the CMT
-	 * device until they get moved to DT.
-	 */
-	struct clk *clk;
-
-	clk = clk_get(NULL, "cmt0");
-	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
-		clk_put(clk);
-	}
-#else
+#ifndef CONFIG_COMMON_CLK
 	r8a7791_clock_init();
 #endif
-	r8a7791_add_dt_devices();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h
index 200fa69..57a37f1 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h
@@ -2,7 +2,6 @@
 #define __ASM_R8A7791_H__
 
 void r8a7791_add_standard_devices(void);
-void r8a7791_add_dt_devices(void);
 void r8a7791_clock_init(void);
 void r8a7791_pinmux_init(void);
 void r8a7791_init_early(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index a17ebb8..c1e9c0f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -189,11 +189,6 @@ static const struct resource thermal_resources[] __initconst = {
 					thermal_resources,		\
 					ARRAY_SIZE(thermal_resources))
 
-void __init r8a7791_add_dt_devices(void)
-{
-	r8a7791_register_cmt(0);
-}
-
 void __init r8a7791_add_standard_devices(void)
 {
 	r8a7791_register_scif(0);
@@ -211,7 +206,7 @@ void __init r8a7791_add_standard_devices(void)
 	r8a7791_register_scif(12);
 	r8a7791_register_scif(13);
 	r8a7791_register_scif(14);
-	r8a7791_add_dt_devices();
+	r8a7791_register_cmt(0);
 	r8a7791_register_irqc(0);
 	r8a7791_register_thermal();
 }
-- 
1.8.3.2


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

* [PATCH 27/27] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree
@ 2014-02-14  1:00   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14  1:00 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the CMT0 device and configure channel 0 as a clock event
provider.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791-koelsch.dts            |  9 +++++++++
 arch/arm/mach-shmobile/board-koelsch-reference.c | 15 +--------------
 arch/arm/mach-shmobile/include/mach/r8a7791.h    |  1 -
 arch/arm/mach-shmobile/setup-r8a7791.c           |  7 +------
 4 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 42fd5eb..36e1c33 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -130,6 +130,15 @@
 	};
 };
 
+&cmt0 {
+	status = "ok";
+
+	channel at 0 {
+		reg = <0>;
+		clock-event-rating = <80>;
+	};
+};
+
 &sata0 {
 	status = "okay";
 };
diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
index e67a4be7..abcb8da 100644
--- a/arch/arm/mach-shmobile/board-koelsch-reference.c
+++ b/arch/arm/mach-shmobile/board-koelsch-reference.c
@@ -30,22 +30,9 @@
 
 static void __init koelsch_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
-	/*
-	 * This is a really crude hack to provide clkdev support to the CMT
-	 * device until they get moved to DT.
-	 */
-	struct clk *clk;
-
-	clk = clk_get(NULL, "cmt0");
-	if (!IS_ERR(clk)) {
-		clk_register_clkdev(clk, NULL, "sh-cmt-48-gen2.0");
-		clk_put(clk);
-	}
-#else
+#ifndef CONFIG_COMMON_CLK
 	r8a7791_clock_init();
 #endif
-	r8a7791_add_dt_devices();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h
index 200fa69..57a37f1 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h
@@ -2,7 +2,6 @@
 #define __ASM_R8A7791_H__
 
 void r8a7791_add_standard_devices(void);
-void r8a7791_add_dt_devices(void);
 void r8a7791_clock_init(void);
 void r8a7791_pinmux_init(void);
 void r8a7791_init_early(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index a17ebb8..c1e9c0f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -189,11 +189,6 @@ static const struct resource thermal_resources[] __initconst = {
 					thermal_resources,		\
 					ARRAY_SIZE(thermal_resources))
 
-void __init r8a7791_add_dt_devices(void)
-{
-	r8a7791_register_cmt(0);
-}
-
 void __init r8a7791_add_standard_devices(void)
 {
 	r8a7791_register_scif(0);
@@ -211,7 +206,7 @@ void __init r8a7791_add_standard_devices(void)
 	r8a7791_register_scif(12);
 	r8a7791_register_scif(13);
 	r8a7791_register_scif(14);
-	r8a7791_add_dt_devices();
+	r8a7791_register_cmt(0);
 	r8a7791_register_irqc(0);
 	r8a7791_register_thermal();
 }
-- 
1.8.3.2

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14  1:00   ` Laurent Pinchart
  (?)
@ 2014-02-14  9:18     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 168+ messages in thread
From: Geert Uytterhoeven @ 2014-02-14  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 14, 2014 at 2:00 AM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> @@ -0,0 +1,75 @@
> +* Renesas R-Car Compare Match Timer (CMT)
> +
> +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock

16-bit is mentioned here ...

> +inputs and programmable compare match.
> +
> +Channels share hadware resources but their counter and compare match value are

hardware

> +independent. A particular CMT instance can implement only a subset of the
> +channels supported by the CMT model. Channels indices start from 0 and are

Channel indices

> +consecutive.
> +
> +Required Properties:
> +
> +  - compatible: must contain one of the following.

... why not add "renesas,cmt-16" here (and one extra line in the actual driver),
while you're at it?

> +    - "renesas,cmt-32" for the 32-bit CMT
> +               (CMT0 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> +               (CMT[234] on sh7372, sh73a0 and r8a7740)
> +    - "renasas,cmt-48" for the 48-bit CMT
> +               (CMT1 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> +               (CMT[01] on r8a73a4, r8a7790 and r8a7791)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14  9:18     ` Geert Uytterhoeven
  0 siblings, 0 replies; 168+ messages in thread
From: Geert Uytterhoeven @ 2014-02-14  9:18 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Linux-sh list, linux-arm-kernel, linux-kernel, Daniel Lezcano,
	Thomas Gleixner

On Fri, Feb 14, 2014 at 2:00 AM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> @@ -0,0 +1,75 @@
> +* Renesas R-Car Compare Match Timer (CMT)
> +
> +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock

16-bit is mentioned here ...

> +inputs and programmable compare match.
> +
> +Channels share hadware resources but their counter and compare match value are

hardware

> +independent. A particular CMT instance can implement only a subset of the
> +channels supported by the CMT model. Channels indices start from 0 and are

Channel indices

> +consecutive.
> +
> +Required Properties:
> +
> +  - compatible: must contain one of the following.

... why not add "renesas,cmt-16" here (and one extra line in the actual driver),
while you're at it?

> +    - "renesas,cmt-32" for the 32-bit CMT
> +               (CMT0 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> +               (CMT[234] on sh7372, sh73a0 and r8a7740)
> +    - "renasas,cmt-48" for the 48-bit CMT
> +               (CMT1 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> +               (CMT[01] on r8a73a4, r8a7790 and r8a7791)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14  9:18     ` Geert Uytterhoeven
  0 siblings, 0 replies; 168+ messages in thread
From: Geert Uytterhoeven @ 2014-02-14  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 14, 2014 at 2:00 AM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> @@ -0,0 +1,75 @@
> +* Renesas R-Car Compare Match Timer (CMT)
> +
> +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock

16-bit is mentioned here ...

> +inputs and programmable compare match.
> +
> +Channels share hadware resources but their counter and compare match value are

hardware

> +independent. A particular CMT instance can implement only a subset of the
> +channels supported by the CMT model. Channels indices start from 0 and are

Channel indices

> +consecutive.
> +
> +Required Properties:
> +
> +  - compatible: must contain one of the following.

... why not add "renesas,cmt-16" here (and one extra line in the actual driver),
while you're at it?

> +    - "renesas,cmt-32" for the 32-bit CMT
> +               (CMT0 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> +               (CMT[234] on sh7372, sh73a0 and r8a7740)
> +    - "renasas,cmt-48" for the 48-bit CMT
> +               (CMT1 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> +               (CMT[01] on r8a73a4, r8a7790 and r8a7791)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14  1:00   ` Laurent Pinchart
  (?)
@ 2014-02-14 10:58     ` Mark Rutland
  -1 siblings, 0 replies; 168+ messages in thread
From: Mark Rutland @ 2014-02-14 10:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
>  drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++++++----
>  2 files changed, 160 insertions(+), 19 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt
> 
> diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> new file mode 100644
> index 0000000..28d4ab5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> @@ -0,0 +1,75 @@
> +* Renesas R-Car Compare Match Timer (CMT)
> +
> +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
> +inputs and programmable compare match.
> +
> +Channels share hadware resources but their counter and compare match value are
> +independent. A particular CMT instance can implement only a subset of the
> +channels supported by the CMT model. Channels indices start from 0 and are
> +consecutive.
> +
> +Required Properties:
> +
> +  - compatible: must contain one of the following.
> +    - "renesas,cmt-32" for the 32-bit CMT
> +		(CMT0 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> +		(CMT[234] on sh7372, sh73a0 and r8a7740)
> +    - "renasas,cmt-48" for the 48-bit CMT
> +		(CMT1 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> +    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
> +
> +  - reg: base address and length of the registers block for the timer module.
> +  - interrupt-parent, interrupts: interrupt-specifier for the timer, one per
> +    channel.

It might make more sense to describe the interrupt on the channel
subnode. It makes it far clearer which channel has which interrupt.

> +  - clocks: phandle and clock-specifier pair for the functional clock.
> +  - clock-names: must be "fck".

It would be nice to define the list once:

- clocks: A list of phandle + clock-specifier pairs, one for each entry
  in clock-names.
- clock-names: Should contain "fck" for the functional clock.

> +
> +  - #address-cells: must be 1
> +  - #size-cells: must be 0
> +
> +  - renesas,channels-mask: integer bitmask of the channels implemented by the
> +    timer instance.

This is implied by the presence of a subnode. Either remove this or the
subnodes.

> +
> +
> +Each channel is described by a sub-node named "channel@<idx>", where <idx> is
> +the channel index.
> +
> +Channels Required Properties:
> +
> +  - reg: the channel index.
> +
> +Channels Optional Properties:
> +
> +  - clock-source-rating: rating of the timer as a clock source device.
> +  - clock-event-rating: rating of the timer as a clock event device.

This feels like a leak of Linux internals. Why do you need this?

> +
> +
> +Example: R8A7790 (R-Car H2) CMT0 node
> +
> +	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
> +	them channels 0 and 1 in the documentation.
> +
> +	cmt0: timer@ffca0000 {
> +		compatible = "renesas,cmt-48-gen2";
> +		reg = <0 0xffca0000 0 0x1004>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
> +			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		renesas,channels-mask = <0x60>;
> +
> +		channel@0 {
> +			reg = <0>;
> +			clock-event-rating = <80>;
> +		};
> +		channel@0 {
> +			reg = <0>;
> +			clock-source-rating = <80>;
> +		};

Aaargh. Use the _real_ channel IDs for the reg proeprties and get rid of
the mask. It's pointlessly confusing.

Thanks,
Mark

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 10:58     ` Mark Rutland
  0 siblings, 0 replies; 168+ messages in thread
From: Mark Rutland @ 2014-02-14 10:58 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-sh, Thomas Gleixner, Daniel Lezcano, linux-kernel,
	linux-arm-kernel

On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
>  drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++++++----
>  2 files changed, 160 insertions(+), 19 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt
> 
> diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> new file mode 100644
> index 0000000..28d4ab5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> @@ -0,0 +1,75 @@
> +* Renesas R-Car Compare Match Timer (CMT)
> +
> +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
> +inputs and programmable compare match.
> +
> +Channels share hadware resources but their counter and compare match value are
> +independent. A particular CMT instance can implement only a subset of the
> +channels supported by the CMT model. Channels indices start from 0 and are
> +consecutive.
> +
> +Required Properties:
> +
> +  - compatible: must contain one of the following.
> +    - "renesas,cmt-32" for the 32-bit CMT
> +		(CMT0 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> +		(CMT[234] on sh7372, sh73a0 and r8a7740)
> +    - "renasas,cmt-48" for the 48-bit CMT
> +		(CMT1 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> +    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
> +
> +  - reg: base address and length of the registers block for the timer module.
> +  - interrupt-parent, interrupts: interrupt-specifier for the timer, one per
> +    channel.

It might make more sense to describe the interrupt on the channel
subnode. It makes it far clearer which channel has which interrupt.

> +  - clocks: phandle and clock-specifier pair for the functional clock.
> +  - clock-names: must be "fck".

It would be nice to define the list once:

- clocks: A list of phandle + clock-specifier pairs, one for each entry
  in clock-names.
- clock-names: Should contain "fck" for the functional clock.

> +
> +  - #address-cells: must be 1
> +  - #size-cells: must be 0
> +
> +  - renesas,channels-mask: integer bitmask of the channels implemented by the
> +    timer instance.

This is implied by the presence of a subnode. Either remove this or the
subnodes.

> +
> +
> +Each channel is described by a sub-node named "channel@<idx>", where <idx> is
> +the channel index.
> +
> +Channels Required Properties:
> +
> +  - reg: the channel index.
> +
> +Channels Optional Properties:
> +
> +  - clock-source-rating: rating of the timer as a clock source device.
> +  - clock-event-rating: rating of the timer as a clock event device.

This feels like a leak of Linux internals. Why do you need this?

> +
> +
> +Example: R8A7790 (R-Car H2) CMT0 node
> +
> +	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
> +	them channels 0 and 1 in the documentation.
> +
> +	cmt0: timer@ffca0000 {
> +		compatible = "renesas,cmt-48-gen2";
> +		reg = <0 0xffca0000 0 0x1004>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
> +			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		renesas,channels-mask = <0x60>;
> +
> +		channel@0 {
> +			reg = <0>;
> +			clock-event-rating = <80>;
> +		};
> +		channel@0 {
> +			reg = <0>;
> +			clock-source-rating = <80>;
> +		};

Aaargh. Use the _real_ channel IDs for the reg proeprties and get rid of
the mask. It's pointlessly confusing.

Thanks,
Mark

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 10:58     ` Mark Rutland
  0 siblings, 0 replies; 168+ messages in thread
From: Mark Rutland @ 2014-02-14 10:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
>  drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++++++----
>  2 files changed, 160 insertions(+), 19 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/timer/renesas,cmt.txt
> 
> diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> new file mode 100644
> index 0000000..28d4ab5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> @@ -0,0 +1,75 @@
> +* Renesas R-Car Compare Match Timer (CMT)
> +
> +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
> +inputs and programmable compare match.
> +
> +Channels share hadware resources but their counter and compare match value are
> +independent. A particular CMT instance can implement only a subset of the
> +channels supported by the CMT model. Channels indices start from 0 and are
> +consecutive.
> +
> +Required Properties:
> +
> +  - compatible: must contain one of the following.
> +    - "renesas,cmt-32" for the 32-bit CMT
> +		(CMT0 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> +		(CMT[234] on sh7372, sh73a0 and r8a7740)
> +    - "renasas,cmt-48" for the 48-bit CMT
> +		(CMT1 on sh7372, sh73a0 and r8a7740)
> +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> +    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
> +
> +  - reg: base address and length of the registers block for the timer module.
> +  - interrupt-parent, interrupts: interrupt-specifier for the timer, one per
> +    channel.

It might make more sense to describe the interrupt on the channel
subnode. It makes it far clearer which channel has which interrupt.

> +  - clocks: phandle and clock-specifier pair for the functional clock.
> +  - clock-names: must be "fck".

It would be nice to define the list once:

- clocks: A list of phandle + clock-specifier pairs, one for each entry
  in clock-names.
- clock-names: Should contain "fck" for the functional clock.

> +
> +  - #address-cells: must be 1
> +  - #size-cells: must be 0
> +
> +  - renesas,channels-mask: integer bitmask of the channels implemented by the
> +    timer instance.

This is implied by the presence of a subnode. Either remove this or the
subnodes.

> +
> +
> +Each channel is described by a sub-node named "channel@<idx>", where <idx> is
> +the channel index.
> +
> +Channels Required Properties:
> +
> +  - reg: the channel index.
> +
> +Channels Optional Properties:
> +
> +  - clock-source-rating: rating of the timer as a clock source device.
> +  - clock-event-rating: rating of the timer as a clock event device.

This feels like a leak of Linux internals. Why do you need this?

> +
> +
> +Example: R8A7790 (R-Car H2) CMT0 node
> +
> +	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
> +	them channels 0 and 1 in the documentation.
> +
> +	cmt0: timer at ffca0000 {
> +		compatible = "renesas,cmt-48-gen2";
> +		reg = <0 0xffca0000 0 0x1004>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
> +			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		renesas,channels-mask = <0x60>;
> +
> +		channel at 0 {
> +			reg = <0>;
> +			clock-event-rating = <80>;
> +		};
> +		channel at 0 {
> +			reg = <0>;
> +			clock-source-rating = <80>;
> +		};

Aaargh. Use the _real_ channel IDs for the reg proeprties and get rid of
the mask. It's pointlessly confusing.

Thanks,
Mark

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14  1:00   ` Laurent Pinchart
  (?)
@ 2014-02-14 13:45     ` Sergei Shtylyov
  -1 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 14-02-2014 5:00, Laurent Pinchart wrote:

> Enable the CMT0 device and configure channel 0 as a clock event
> provider.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> index 0b95bab..62b31f3 100644
> --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> @@ -29,7 +29,6 @@ enum {
>   };
>
>   void r8a7790_add_standard_devices(void);
> -void r8a7790_add_dt_devices(void);
>   void r8a7790_clock_init(void);
>   void r8a7790_pinmux_init(void);
>   void r8a7790_pm_init(void);
> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
> index 3e5813f..462c81f 100644
> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>   					  &cmt##idx##_platform_data,	\
>   					  sizeof(struct sh_timer_config))
>
> -void __init r8a7790_add_dt_devices(void)
> -{
> -	r8a7790_register_cmt(0);
> -}
> -
>   void __init r8a7790_add_standard_devices(void)
>   {
>   	r8a7790_register_scif(0);
> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>   	r8a7790_register_scif(7);
>   	r8a7790_register_scif(8);
>   	r8a7790_register_scif(9);
> -	r8a7790_add_dt_devices();
> +	r8a7790_register_cmt(0);
>   	r8a7790_register_irqc(0);
>   	r8a7790_register_thermal();
>   }

    IMHO, these 2 files should be split into a separate patch.

WBR, Sergei


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 13:45     ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 13:45 UTC (permalink / raw)
  To: Laurent Pinchart, linux-sh
  Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Hello.

On 14-02-2014 5:00, Laurent Pinchart wrote:

> Enable the CMT0 device and configure channel 0 as a clock event
> provider.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> index 0b95bab..62b31f3 100644
> --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> @@ -29,7 +29,6 @@ enum {
>   };
>
>   void r8a7790_add_standard_devices(void);
> -void r8a7790_add_dt_devices(void);
>   void r8a7790_clock_init(void);
>   void r8a7790_pinmux_init(void);
>   void r8a7790_pm_init(void);
> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
> index 3e5813f..462c81f 100644
> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>   					  &cmt##idx##_platform_data,	\
>   					  sizeof(struct sh_timer_config))
>
> -void __init r8a7790_add_dt_devices(void)
> -{
> -	r8a7790_register_cmt(0);
> -}
> -
>   void __init r8a7790_add_standard_devices(void)
>   {
>   	r8a7790_register_scif(0);
> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>   	r8a7790_register_scif(7);
>   	r8a7790_register_scif(8);
>   	r8a7790_register_scif(9);
> -	r8a7790_add_dt_devices();
> +	r8a7790_register_cmt(0);
>   	r8a7790_register_irqc(0);
>   	r8a7790_register_thermal();
>   }

    IMHO, these 2 files should be split into a separate patch.

WBR, Sergei


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 13:45     ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 14-02-2014 5:00, Laurent Pinchart wrote:

> Enable the CMT0 device and configure channel 0 as a clock event
> provider.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> index 0b95bab..62b31f3 100644
> --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> @@ -29,7 +29,6 @@ enum {
>   };
>
>   void r8a7790_add_standard_devices(void);
> -void r8a7790_add_dt_devices(void);
>   void r8a7790_clock_init(void);
>   void r8a7790_pinmux_init(void);
>   void r8a7790_pm_init(void);
> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
> index 3e5813f..462c81f 100644
> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>   					  &cmt##idx##_platform_data,	\
>   					  sizeof(struct sh_timer_config))
>
> -void __init r8a7790_add_dt_devices(void)
> -{
> -	r8a7790_register_cmt(0);
> -}
> -
>   void __init r8a7790_add_standard_devices(void)
>   {
>   	r8a7790_register_scif(0);
> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>   	r8a7790_register_scif(7);
>   	r8a7790_register_scif(8);
>   	r8a7790_register_scif(9);
> -	r8a7790_add_dt_devices();
> +	r8a7790_register_cmt(0);
>   	r8a7790_register_irqc(0);
>   	r8a7790_register_thermal();
>   }

    IMHO, these 2 files should be split into a separate patch.

WBR, Sergei

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

* Re: [PATCH 27/27] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree
  2014-02-14  1:00   ` Laurent Pinchart
  (?)
@ 2014-02-14 13:47     ` Sergei Shtylyov
  -1 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 14-02-2014 5:00, Laurent Pinchart wrote:

> Enable the CMT0 device and configure channel 0 as a clock event
> provider.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>   arch/arm/boot/dts/r8a7791-koelsch.dts            |  9 +++++++++
>   arch/arm/mach-shmobile/board-koelsch-reference.c | 15 +--------------
>   arch/arm/mach-shmobile/include/mach/r8a7791.h    |  1 -
>   arch/arm/mach-shmobile/setup-r8a7791.c           |  7 +------

    The latter 2 files are worth splitting into a separate patch as well...

>   4 files changed, 11 insertions(+), 21 deletions(-)

WBR, Sergei


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

* Re: [PATCH 27/27] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree
@ 2014-02-14 13:47     ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 13:47 UTC (permalink / raw)
  To: Laurent Pinchart, linux-sh
  Cc: linux-arm-kernel, linux-kernel, Daniel Lezcano, Thomas Gleixner

Hello.

On 14-02-2014 5:00, Laurent Pinchart wrote:

> Enable the CMT0 device and configure channel 0 as a clock event
> provider.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>   arch/arm/boot/dts/r8a7791-koelsch.dts            |  9 +++++++++
>   arch/arm/mach-shmobile/board-koelsch-reference.c | 15 +--------------
>   arch/arm/mach-shmobile/include/mach/r8a7791.h    |  1 -
>   arch/arm/mach-shmobile/setup-r8a7791.c           |  7 +------

    The latter 2 files are worth splitting into a separate patch as well...

>   4 files changed, 11 insertions(+), 21 deletions(-)

WBR, Sergei


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

* [PATCH 27/27] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree
@ 2014-02-14 13:47     ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 14-02-2014 5:00, Laurent Pinchart wrote:

> Enable the CMT0 device and configure channel 0 as a clock event
> provider.

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>   arch/arm/boot/dts/r8a7791-koelsch.dts            |  9 +++++++++
>   arch/arm/mach-shmobile/board-koelsch-reference.c | 15 +--------------
>   arch/arm/mach-shmobile/include/mach/r8a7791.h    |  1 -
>   arch/arm/mach-shmobile/setup-r8a7791.c           |  7 +------

    The latter 2 files are worth splitting into a separate patch as well...

>   4 files changed, 11 insertions(+), 21 deletions(-)

WBR, Sergei

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14 13:45     ` Sergei Shtylyov
  (?)
@ 2014-02-14 13:48       ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sergei,

Thank you for the review.

On Friday 14 February 2014 17:45:56 Sergei Shtylyov wrote:
> On 14-02-2014 5:00, Laurent Pinchart wrote:
> > Enable the CMT0 device and configure channel 0 as a clock event
> > provider.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> > 100644
> > --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > @@ -29,7 +29,6 @@ enum {
> >  };
> >   
> >  void r8a7790_add_standard_devices(void);
> > -void r8a7790_add_dt_devices(void);
> >  void r8a7790_clock_init(void);
> >  void r8a7790_pinmux_init(void);
> >  void r8a7790_pm_init(void);
> > diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> > b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> > --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> > +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> > @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >   					  &cmt##idx##_platform_data,	\
> >   					  sizeof(struct sh_timer_config))
> > 
> > -void __init r8a7790_add_dt_devices(void)
> > -{
> > -	r8a7790_register_cmt(0);
> > -}
> > -
> >  void __init r8a7790_add_standard_devices(void)
> >  {
> >   	r8a7790_register_scif(0);
> > @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >   	r8a7790_register_scif(7);
> >   	r8a7790_register_scif(8);
> >   	r8a7790_register_scif(9);
> > -	r8a7790_add_dt_devices();
> > +	r8a7790_register_cmt(0);
> >   	r8a7790_register_irqc(0);
> >   	r8a7790_register_thermal();
> >  }
> 
>     IMHO, these 2 files should be split into a separate patch.

That could easily be done, but why ?

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 13:48       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 13:48 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

Hi Sergei,

Thank you for the review.

On Friday 14 February 2014 17:45:56 Sergei Shtylyov wrote:
> On 14-02-2014 5:00, Laurent Pinchart wrote:
> > Enable the CMT0 device and configure channel 0 as a clock event
> > provider.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> > 100644
> > --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > @@ -29,7 +29,6 @@ enum {
> >  };
> >   
> >  void r8a7790_add_standard_devices(void);
> > -void r8a7790_add_dt_devices(void);
> >  void r8a7790_clock_init(void);
> >  void r8a7790_pinmux_init(void);
> >  void r8a7790_pm_init(void);
> > diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> > b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> > --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> > +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> > @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >   					  &cmt##idx##_platform_data,	\
> >   					  sizeof(struct sh_timer_config))
> > 
> > -void __init r8a7790_add_dt_devices(void)
> > -{
> > -	r8a7790_register_cmt(0);
> > -}
> > -
> >  void __init r8a7790_add_standard_devices(void)
> >  {
> >   	r8a7790_register_scif(0);
> > @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >   	r8a7790_register_scif(7);
> >   	r8a7790_register_scif(8);
> >   	r8a7790_register_scif(9);
> > -	r8a7790_add_dt_devices();
> > +	r8a7790_register_cmt(0);
> >   	r8a7790_register_irqc(0);
> >   	r8a7790_register_thermal();
> >  }
> 
>     IMHO, these 2 files should be split into a separate patch.

That could easily be done, but why ?

-- 
Regards,

Laurent Pinchart


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 13:48       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sergei,

Thank you for the review.

On Friday 14 February 2014 17:45:56 Sergei Shtylyov wrote:
> On 14-02-2014 5:00, Laurent Pinchart wrote:
> > Enable the CMT0 device and configure channel 0 as a clock event
> > provider.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> > 100644
> > --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> > @@ -29,7 +29,6 @@ enum {
> >  };
> >   
> >  void r8a7790_add_standard_devices(void);
> > -void r8a7790_add_dt_devices(void);
> >  void r8a7790_clock_init(void);
> >  void r8a7790_pinmux_init(void);
> >  void r8a7790_pm_init(void);
> > diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> > b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> > --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> > +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> > @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >   					  &cmt##idx##_platform_data,	\
> >   					  sizeof(struct sh_timer_config))
> > 
> > -void __init r8a7790_add_dt_devices(void)
> > -{
> > -	r8a7790_register_cmt(0);
> > -}
> > -
> >  void __init r8a7790_add_standard_devices(void)
> >  {
> >   	r8a7790_register_scif(0);
> > @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >   	r8a7790_register_scif(7);
> >   	r8a7790_register_scif(8);
> >   	r8a7790_register_scif(9);
> > -	r8a7790_add_dt_devices();
> > +	r8a7790_register_cmt(0);
> >   	r8a7790_register_irqc(0);
> >   	r8a7790_register_thermal();
> >  }
> 
>     IMHO, these 2 files should be split into a separate patch.

That could easily be done, but why ?

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14 13:48       ` Laurent Pinchart
  (?)
@ 2014-02-14 14:13         ` Sergei Shtylyov
  -1 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 14-02-2014 17:48, Laurent Pinchart wrote:

>>> Enable the CMT0 device and configure channel 0 as a clock event
>>> provider.

>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3 100644
>>> --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> @@ -29,7 +29,6 @@ enum {
>>>   };
>>>
>>>   void r8a7790_add_standard_devices(void);
>>> -void r8a7790_add_dt_devices(void);
>>>   void r8a7790_clock_init(void);
>>>   void r8a7790_pinmux_init(void);
>>>   void r8a7790_pm_init(void);
>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>    					  &cmt##idx##_platform_data,	\
>>>    					  sizeof(struct sh_timer_config))
>>>
>>> -void __init r8a7790_add_dt_devices(void)
>>> -{
>>> -	r8a7790_register_cmt(0);
>>> -}
>>> -
>>>   void __init r8a7790_add_standard_devices(void)
>>>   {
>>>    	r8a7790_register_scif(0);
>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>    	r8a7790_register_scif(7);
>>>    	r8a7790_register_scif(8);
>>>    	r8a7790_register_scif(9);
>>> -	r8a7790_add_dt_devices();
>>> +	r8a7790_register_cmt(0);
>>>    	r8a7790_register_irqc(0);
>>>    	r8a7790_register_thermal();
>>>   }

>>      IMHO, these 2 files should be split into a separate patch.

> That could easily be done, but why ?

    It does not seem necessary to combine these changes in one patch. 
Remember, Simon has separate branches for boards and SoCs. So finally it's up 
to him to decide on this...

WBR, Sergei


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 14:13         ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 14:13 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

On 14-02-2014 17:48, Laurent Pinchart wrote:

>>> Enable the CMT0 device and configure channel 0 as a clock event
>>> provider.

>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3 100644
>>> --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> @@ -29,7 +29,6 @@ enum {
>>>   };
>>>
>>>   void r8a7790_add_standard_devices(void);
>>> -void r8a7790_add_dt_devices(void);
>>>   void r8a7790_clock_init(void);
>>>   void r8a7790_pinmux_init(void);
>>>   void r8a7790_pm_init(void);
>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>    					  &cmt##idx##_platform_data,	\
>>>    					  sizeof(struct sh_timer_config))
>>>
>>> -void __init r8a7790_add_dt_devices(void)
>>> -{
>>> -	r8a7790_register_cmt(0);
>>> -}
>>> -
>>>   void __init r8a7790_add_standard_devices(void)
>>>   {
>>>    	r8a7790_register_scif(0);
>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>    	r8a7790_register_scif(7);
>>>    	r8a7790_register_scif(8);
>>>    	r8a7790_register_scif(9);
>>> -	r8a7790_add_dt_devices();
>>> +	r8a7790_register_cmt(0);
>>>    	r8a7790_register_irqc(0);
>>>    	r8a7790_register_thermal();
>>>   }

>>      IMHO, these 2 files should be split into a separate patch.

> That could easily be done, but why ?

    It does not seem necessary to combine these changes in one patch. 
Remember, Simon has separate branches for boards and SoCs. So finally it's up 
to him to decide on this...

WBR, Sergei


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 14:13         ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 14-02-2014 17:48, Laurent Pinchart wrote:

>>> Enable the CMT0 device and configure channel 0 as a clock event
>>> provider.

>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3 100644
>>> --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>> @@ -29,7 +29,6 @@ enum {
>>>   };
>>>
>>>   void r8a7790_add_standard_devices(void);
>>> -void r8a7790_add_dt_devices(void);
>>>   void r8a7790_clock_init(void);
>>>   void r8a7790_pinmux_init(void);
>>>   void r8a7790_pm_init(void);
>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>    					  &cmt##idx##_platform_data,	\
>>>    					  sizeof(struct sh_timer_config))
>>>
>>> -void __init r8a7790_add_dt_devices(void)
>>> -{
>>> -	r8a7790_register_cmt(0);
>>> -}
>>> -
>>>   void __init r8a7790_add_standard_devices(void)
>>>   {
>>>    	r8a7790_register_scif(0);
>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>    	r8a7790_register_scif(7);
>>>    	r8a7790_register_scif(8);
>>>    	r8a7790_register_scif(9);
>>> -	r8a7790_add_dt_devices();
>>> +	r8a7790_register_cmt(0);
>>>    	r8a7790_register_irqc(0);
>>>    	r8a7790_register_thermal();
>>>   }

>>      IMHO, these 2 files should be split into a separate patch.

> That could easily be done, but why ?

    It does not seem necessary to combine these changes in one patch. 
Remember, Simon has separate branches for boards and SoCs. So finally it's up 
to him to decide on this...

WBR, Sergei

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14 14:13         ` Sergei Shtylyov
  (?)
@ 2014-02-14 14:22           ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sergei,

On Friday 14 February 2014 18:13:44 Sergei Shtylyov wrote:
> On 14-02-2014 17:48, Laurent Pinchart wrote:
> >>> Enable the CMT0 device and configure channel 0 as a clock event
> >>> provider.
> >>> 
> >>> Signed-off-by: Laurent Pinchart
> >>> <laurent.pinchart+renesas@ideasonboard.com>
> >>> 
> >>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> >>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> @@ -29,7 +29,6 @@ enum {
> >>>  };
> >>>   
> >>>  void r8a7790_add_standard_devices(void);
> >>> -void r8a7790_add_dt_devices(void);
> >>>  void r8a7790_clock_init(void);
> >>>  void r8a7790_pinmux_init(void);
> >>>  void r8a7790_pm_init(void);
> >>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> >>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >>>    					  &cmt##idx##_platform_data,	\
> >>>    					  sizeof(struct sh_timer_config))
> >>> 
> >>> -void __init r8a7790_add_dt_devices(void)
> >>> -{
> >>> -	r8a7790_register_cmt(0);
> >>> -}
> >>> -
> >>>  void __init r8a7790_add_standard_devices(void)
> >>>  {
> >>>    	r8a7790_register_scif(0);
> >>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >>>    	r8a7790_register_scif(7);
> >>>    	r8a7790_register_scif(8);
> >>>    	r8a7790_register_scif(9);
> >>> -	r8a7790_add_dt_devices();
> >>> +	r8a7790_register_cmt(0);
> >>>    	r8a7790_register_irqc(0);
> >>>    	r8a7790_register_thermal();
> >>>  }
> >>>   
> >> IMHO, these 2 files should be split into a separate patch.
> > 
> > That could easily be done, but why ?
> 
> It does not seem necessary to combine these changes in one patch. Remember,
> Simon has separate branches for boards and SoCs. So finally it's up to him
> to decide on this...

Right, but in this case I need to remove the CMT platform device registration 
from r8a7790_add_dt_devices() at the same time as I enable it in DT, otherwise 
we'll have two instances of the same device.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 14:22           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 14:22 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

Hi Sergei,

On Friday 14 February 2014 18:13:44 Sergei Shtylyov wrote:
> On 14-02-2014 17:48, Laurent Pinchart wrote:
> >>> Enable the CMT0 device and configure channel 0 as a clock event
> >>> provider.
> >>> 
> >>> Signed-off-by: Laurent Pinchart
> >>> <laurent.pinchart+renesas@ideasonboard.com>
> >>> 
> >>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> >>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> @@ -29,7 +29,6 @@ enum {
> >>>  };
> >>>   
> >>>  void r8a7790_add_standard_devices(void);
> >>> -void r8a7790_add_dt_devices(void);
> >>>  void r8a7790_clock_init(void);
> >>>  void r8a7790_pinmux_init(void);
> >>>  void r8a7790_pm_init(void);
> >>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> >>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >>>    					  &cmt##idx##_platform_data,	\
> >>>    					  sizeof(struct sh_timer_config))
> >>> 
> >>> -void __init r8a7790_add_dt_devices(void)
> >>> -{
> >>> -	r8a7790_register_cmt(0);
> >>> -}
> >>> -
> >>>  void __init r8a7790_add_standard_devices(void)
> >>>  {
> >>>    	r8a7790_register_scif(0);
> >>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >>>    	r8a7790_register_scif(7);
> >>>    	r8a7790_register_scif(8);
> >>>    	r8a7790_register_scif(9);
> >>> -	r8a7790_add_dt_devices();
> >>> +	r8a7790_register_cmt(0);
> >>>    	r8a7790_register_irqc(0);
> >>>    	r8a7790_register_thermal();
> >>>  }
> >>>   
> >> IMHO, these 2 files should be split into a separate patch.
> > 
> > That could easily be done, but why ?
> 
> It does not seem necessary to combine these changes in one patch. Remember,
> Simon has separate branches for boards and SoCs. So finally it's up to him
> to decide on this...

Right, but in this case I need to remove the CMT platform device registration 
from r8a7790_add_dt_devices() at the same time as I enable it in DT, otherwise 
we'll have two instances of the same device.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 14:22           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sergei,

On Friday 14 February 2014 18:13:44 Sergei Shtylyov wrote:
> On 14-02-2014 17:48, Laurent Pinchart wrote:
> >>> Enable the CMT0 device and configure channel 0 as a clock event
> >>> provider.
> >>> 
> >>> Signed-off-by: Laurent Pinchart
> >>> <laurent.pinchart+renesas@ideasonboard.com>
> >>> 
> >>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> >>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>> @@ -29,7 +29,6 @@ enum {
> >>>  };
> >>>   
> >>>  void r8a7790_add_standard_devices(void);
> >>> -void r8a7790_add_dt_devices(void);
> >>>  void r8a7790_clock_init(void);
> >>>  void r8a7790_pinmux_init(void);
> >>>  void r8a7790_pm_init(void);
> >>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> >>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> >>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >>>    					  &cmt##idx##_platform_data,	\
> >>>    					  sizeof(struct sh_timer_config))
> >>> 
> >>> -void __init r8a7790_add_dt_devices(void)
> >>> -{
> >>> -	r8a7790_register_cmt(0);
> >>> -}
> >>> -
> >>>  void __init r8a7790_add_standard_devices(void)
> >>>  {
> >>>    	r8a7790_register_scif(0);
> >>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >>>    	r8a7790_register_scif(7);
> >>>    	r8a7790_register_scif(8);
> >>>    	r8a7790_register_scif(9);
> >>> -	r8a7790_add_dt_devices();
> >>> +	r8a7790_register_cmt(0);
> >>>    	r8a7790_register_irqc(0);
> >>>    	r8a7790_register_thermal();
> >>>  }
> >>>   
> >> IMHO, these 2 files should be split into a separate patch.
> > 
> > That could easily be done, but why ?
> 
> It does not seem necessary to combine these changes in one patch. Remember,
> Simon has separate branches for boards and SoCs. So finally it's up to him
> to decide on this...

Right, but in this case I need to remove the CMT platform device registration 
from r8a7790_add_dt_devices() at the same time as I enable it in DT, otherwise 
we'll have two instances of the same device.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14  9:18     ` Geert Uytterhoeven
  (?)
@ 2014-02-14 14:35       ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 14:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Geert,

Thank you for the review.

On Friday 14 February 2014 10:18:58 Geert Uytterhoeven wrote:
> On Fri, Feb 14, 2014 at 2:00 AM, Laurent Pinchart wrote:
> > +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > @@ -0,0 +1,75 @@
> > +* Renesas R-Car Compare Match Timer (CMT)
> > +
> > +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable
> > clock
> 16-bit is mentioned here ...
> 
> > +inputs and programmable compare match.
> > +
> > +Channels share hadware resources but their counter and compare match
> > value are
>
> hardware
> 
> > +independent. A particular CMT instance can implement only a subset of the
> > +channels supported by the CMT model. Channels indices start from 0 and
> > are
> 
> Channel indices
> 
> > +consecutive.
> > +
> > +Required Properties:
> > +
> > +  - compatible: must contain one of the following.
> 
> ... why not add "renesas,cmt-16" here (and one extra line in the actual
> driver), while you're at it?

Because the 16-bit variant is only used on SuperH SoCs, so there's not much 
point in adding DT bindings for it.

> > +    - "renesas,cmt-32" for the 32-bit CMT
> > +               (CMT0 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> > +               (CMT[234] on sh7372, sh73a0 and r8a7740)
> > +    - "renasas,cmt-48" for the 48-bit CMT
> > +               (CMT1 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> > +               (CMT[01] on r8a73a4, r8a7790 and r8a7791)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 14:35       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 14:35 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Laurent Pinchart, Linux-sh list, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

Hi Geert,

Thank you for the review.

On Friday 14 February 2014 10:18:58 Geert Uytterhoeven wrote:
> On Fri, Feb 14, 2014 at 2:00 AM, Laurent Pinchart wrote:
> > +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > @@ -0,0 +1,75 @@
> > +* Renesas R-Car Compare Match Timer (CMT)
> > +
> > +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable
> > clock
> 16-bit is mentioned here ...
> 
> > +inputs and programmable compare match.
> > +
> > +Channels share hadware resources but their counter and compare match
> > value are
>
> hardware
> 
> > +independent. A particular CMT instance can implement only a subset of the
> > +channels supported by the CMT model. Channels indices start from 0 and
> > are
> 
> Channel indices
> 
> > +consecutive.
> > +
> > +Required Properties:
> > +
> > +  - compatible: must contain one of the following.
> 
> ... why not add "renesas,cmt-16" here (and one extra line in the actual
> driver), while you're at it?

Because the 16-bit variant is only used on SuperH SoCs, so there's not much 
point in adding DT bindings for it.

> > +    - "renesas,cmt-32" for the 32-bit CMT
> > +               (CMT0 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> > +               (CMT[234] on sh7372, sh73a0 and r8a7740)
> > +    - "renasas,cmt-48" for the 48-bit CMT
> > +               (CMT1 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> > +               (CMT[01] on r8a73a4, r8a7790 and r8a7791)

-- 
Regards,

Laurent Pinchart

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 14:35       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 14:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Geert,

Thank you for the review.

On Friday 14 February 2014 10:18:58 Geert Uytterhoeven wrote:
> On Fri, Feb 14, 2014 at 2:00 AM, Laurent Pinchart wrote:
> > +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > @@ -0,0 +1,75 @@
> > +* Renesas R-Car Compare Match Timer (CMT)
> > +
> > +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable
> > clock
> 16-bit is mentioned here ...
> 
> > +inputs and programmable compare match.
> > +
> > +Channels share hadware resources but their counter and compare match
> > value are
>
> hardware
> 
> > +independent. A particular CMT instance can implement only a subset of the
> > +channels supported by the CMT model. Channels indices start from 0 and
> > are
> 
> Channel indices
> 
> > +consecutive.
> > +
> > +Required Properties:
> > +
> > +  - compatible: must contain one of the following.
> 
> ... why not add "renesas,cmt-16" here (and one extra line in the actual
> driver), while you're at it?

Because the 16-bit variant is only used on SuperH SoCs, so there's not much 
point in adding DT bindings for it.

> > +    - "renesas,cmt-32" for the 32-bit CMT
> > +               (CMT0 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> > +               (CMT[234] on sh7372, sh73a0 and r8a7740)
> > +    - "renasas,cmt-48" for the 48-bit CMT
> > +               (CMT1 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> > +               (CMT[01] on r8a73a4, r8a7790 and r8a7791)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14 14:22           ` Laurent Pinchart
  (?)
@ 2014-02-14 14:36             ` Sergei Shtylyov
  -1 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 14-02-2014 18:22, Laurent Pinchart wrote:

>>>>> Enable the CMT0 device and configure channel 0 as a clock event
>>>>> provider.

>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
>>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> @@ -29,7 +29,6 @@ enum {
>>>>>   };
>>>>>
>>>>>   void r8a7790_add_standard_devices(void);
>>>>> -void r8a7790_add_dt_devices(void);
>>>>>   void r8a7790_clock_init(void);
>>>>>   void r8a7790_pinmux_init(void);
>>>>>   void r8a7790_pm_init(void);
>>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>>>     					  &cmt##idx##_platform_data,	\
>>>>>     					  sizeof(struct sh_timer_config))
>>>>>
>>>>> -void __init r8a7790_add_dt_devices(void)
>>>>> -{
>>>>> -	r8a7790_register_cmt(0);
>>>>> -}
>>>>> -
>>>>>   void __init r8a7790_add_standard_devices(void)
>>>>>   {
>>>>>     	r8a7790_register_scif(0);
>>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>>>     	r8a7790_register_scif(7);
>>>>>     	r8a7790_register_scif(8);
>>>>>     	r8a7790_register_scif(9);
>>>>> -	r8a7790_add_dt_devices();
>>>>> +	r8a7790_register_cmt(0);
>>>>>     	r8a7790_register_irqc(0);
>>>>>     	r8a7790_register_thermal();
>>>>>   }
>>>>>
>>>> IMHO, these 2 files should be split into a separate patch.
>>>
>>> That could easily be done, but why ?
>>
>> It does not seem necessary to combine these changes in one patch. Remember,
>> Simon has separate branches for boards and SoCs. So finally it's up to him
>> to decide on this...

> Right, but in this case I need to remove the CMT platform device registration
> from r8a7790_add_dt_devices()

    You're not removing anything in these 2 files, you're just replacing 
"indirect" call to r8a7790_register_cmt(0) with direct.

WBR, Sergei


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 14:36             ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 14:36 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

Hello.

On 14-02-2014 18:22, Laurent Pinchart wrote:

>>>>> Enable the CMT0 device and configure channel 0 as a clock event
>>>>> provider.

>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
>>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> @@ -29,7 +29,6 @@ enum {
>>>>>   };
>>>>>
>>>>>   void r8a7790_add_standard_devices(void);
>>>>> -void r8a7790_add_dt_devices(void);
>>>>>   void r8a7790_clock_init(void);
>>>>>   void r8a7790_pinmux_init(void);
>>>>>   void r8a7790_pm_init(void);
>>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>>>     					  &cmt##idx##_platform_data,	\
>>>>>     					  sizeof(struct sh_timer_config))
>>>>>
>>>>> -void __init r8a7790_add_dt_devices(void)
>>>>> -{
>>>>> -	r8a7790_register_cmt(0);
>>>>> -}
>>>>> -
>>>>>   void __init r8a7790_add_standard_devices(void)
>>>>>   {
>>>>>     	r8a7790_register_scif(0);
>>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>>>     	r8a7790_register_scif(7);
>>>>>     	r8a7790_register_scif(8);
>>>>>     	r8a7790_register_scif(9);
>>>>> -	r8a7790_add_dt_devices();
>>>>> +	r8a7790_register_cmt(0);
>>>>>     	r8a7790_register_irqc(0);
>>>>>     	r8a7790_register_thermal();
>>>>>   }
>>>>>
>>>> IMHO, these 2 files should be split into a separate patch.
>>>
>>> That could easily be done, but why ?
>>
>> It does not seem necessary to combine these changes in one patch. Remember,
>> Simon has separate branches for boards and SoCs. So finally it's up to him
>> to decide on this...

> Right, but in this case I need to remove the CMT platform device registration
> from r8a7790_add_dt_devices()

    You're not removing anything in these 2 files, you're just replacing 
"indirect" call to r8a7790_register_cmt(0) with direct.

WBR, Sergei


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 14:36             ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 14-02-2014 18:22, Laurent Pinchart wrote:

>>>>> Enable the CMT0 device and configure channel 0 as a clock event
>>>>> provider.

>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
>>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>> @@ -29,7 +29,6 @@ enum {
>>>>>   };
>>>>>
>>>>>   void r8a7790_add_standard_devices(void);
>>>>> -void r8a7790_add_dt_devices(void);
>>>>>   void r8a7790_clock_init(void);
>>>>>   void r8a7790_pinmux_init(void);
>>>>>   void r8a7790_pm_init(void);
>>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>>>     					  &cmt##idx##_platform_data,	\
>>>>>     					  sizeof(struct sh_timer_config))
>>>>>
>>>>> -void __init r8a7790_add_dt_devices(void)
>>>>> -{
>>>>> -	r8a7790_register_cmt(0);
>>>>> -}
>>>>> -
>>>>>   void __init r8a7790_add_standard_devices(void)
>>>>>   {
>>>>>     	r8a7790_register_scif(0);
>>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>>>     	r8a7790_register_scif(7);
>>>>>     	r8a7790_register_scif(8);
>>>>>     	r8a7790_register_scif(9);
>>>>> -	r8a7790_add_dt_devices();
>>>>> +	r8a7790_register_cmt(0);
>>>>>     	r8a7790_register_irqc(0);
>>>>>     	r8a7790_register_thermal();
>>>>>   }
>>>>>
>>>> IMHO, these 2 files should be split into a separate patch.
>>>
>>> That could easily be done, but why ?
>>
>> It does not seem necessary to combine these changes in one patch. Remember,
>> Simon has separate branches for boards and SoCs. So finally it's up to him
>> to decide on this...

> Right, but in this case I need to remove the CMT platform device registration
> from r8a7790_add_dt_devices()

    You're not removing anything in these 2 files, you're just replacing 
"indirect" call to r8a7790_register_cmt(0) with direct.

WBR, Sergei

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 10:58     ` Mark Rutland
  (?)
@ 2014-02-14 15:53       ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Thank you for the review.

On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > Cc: devicetree@vger.kernel.org
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
> >  drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++---
> >  2 files changed, 160 insertions(+), 19 deletions(-)
> >  create mode 100644
> >  Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > b/Documentation/devicetree/bindings/timer/renesas,cmt.txt new file mode
> > 100644
> > index 0000000..28d4ab5
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > @@ -0,0 +1,75 @@
> > +* Renesas R-Car Compare Match Timer (CMT)
> > +
> > +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable
> > clock
> > +inputs and programmable compare match.
> > +
> > +Channels share hadware resources but their counter and compare match
> > value are
> > +independent. A particular CMT instance can implement only a subset of the
> > +channels supported by the CMT model. Channels indices start from 0 and
> > are
> > +consecutive.
> > +
> > +Required Properties:
> > +
> > +  - compatible: must contain one of the following.
> > +    - "renesas,cmt-32" for the 32-bit CMT
> > +		(CMT0 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> > +		(CMT[234] on sh7372, sh73a0 and r8a7740)
> > +    - "renasas,cmt-48" for the 48-bit CMT
> > +		(CMT1 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> > +    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
> > +
> > +  - reg: base address and length of the registers block for the timer
> > module.
> > +  - interrupt-parent, interrupts: interrupt-specifier for the timer, one
> > per
> > +    channel.
> 
> It might make more sense to describe the interrupt on the channel
> subnode. It makes it far clearer which channel has which interrupt.

That's a good point. I'm relying on platform_get_irq() which won't support 
that usage, but I can switch to of_irq_to_resource() instead.

> > +  - clocks: phandle and clock-specifier pair for the functional clock.
> > +  - clock-names: must be "fck".
> 
> It would be nice to define the list once:
> 
> - clocks: A list of phandle + clock-specifier pairs, one for each entry
>   in clock-names.
> - clock-names: Should contain "fck" for the functional clock.

OK.

> > +
> > +  - #address-cells: must be 1
> > +  - #size-cells: must be 0
> > +
> > +  - renesas,channels-mask: integer bitmask of the channels implemented by
> > the
> > +    timer instance.
> 
> This is implied by the presence of a subnode. Either remove this or the
> subnodes.
>
> > +
> > +
> > +Each channel is described by a sub-node named "channel@<idx>", where
> > <idx> is +the channel index.
> > +
> > +Channels Required Properties:
> > +
> > +  - reg: the channel index.
> > +
> > +Channels Optional Properties:
> > +
> > +  - clock-source-rating: rating of the timer as a clock source device.
> > +  - clock-event-rating: rating of the timer as a clock event device.
> 
> This feels like a leak of Linux internals. Why do you need this?

You're right, it is. The clock source and clock event ratings are currently 
configured through platform data, I'll need to find a way to compute them in 
the driver instead.

There's still one piece of Linux-specific data I need though, as I need to 
specify for each channel whether to use it as a clock source device, a clock 
event device, both of them or none. That's configuration information that 
needs to be provided somehow.

> > +
> > +
> > +Example: R8A7790 (R-Car H2) CMT0 node
> > +
> > +	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
> > +	them channels 0 and 1 in the documentation.
> > +
> > +	cmt0: timer@ffca0000 {
> > +		compatible = "renesas,cmt-48-gen2";
> > +		reg = <0 0xffca0000 0 0x1004>;
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
> > +
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +
> > +		renesas,channels-mask = <0x60>;
> > +
> > +		channel@0 {
> > +			reg = <0>;
> > +			clock-event-rating = <80>;
> > +		};
> > +		channel@0 {
> > +			reg = <0>;
> > +			clock-source-rating = <80>;
> > +		};
> 
> Aaargh. Use the _real_ channel IDs for the reg proeprties and get rid of
> the mask. It's pointlessly confusing.

There's two real channel IDs. One of them is the value used in the hardware 
implementation (5 and 6 in this case, used to compute the channel registers 
block address) and the other one is the value used throughout the datasheet, 0 
and 1 in this case.

The later is used by the driver to reference the correct interrupt, which 
won't be needed anymore when referencing interrupts in the channel subnodes 
directly. It's also used to print messages to the kernel log and match the 
channel numbers specified in the datasheets. I could use the hardware channel 
number instead, but that might become confusing.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 15:53       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 15:53 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Laurent Pinchart, linux-sh, Thomas Gleixner, Daniel Lezcano,
	linux-kernel, linux-arm-kernel

Hi Mark,

Thank you for the review.

On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > Cc: devicetree@vger.kernel.org
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
> >  drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++---
> >  2 files changed, 160 insertions(+), 19 deletions(-)
> >  create mode 100644
> >  Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > b/Documentation/devicetree/bindings/timer/renesas,cmt.txt new file mode
> > 100644
> > index 0000000..28d4ab5
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > @@ -0,0 +1,75 @@
> > +* Renesas R-Car Compare Match Timer (CMT)
> > +
> > +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable
> > clock
> > +inputs and programmable compare match.
> > +
> > +Channels share hadware resources but their counter and compare match
> > value are
> > +independent. A particular CMT instance can implement only a subset of the
> > +channels supported by the CMT model. Channels indices start from 0 and
> > are
> > +consecutive.
> > +
> > +Required Properties:
> > +
> > +  - compatible: must contain one of the following.
> > +    - "renesas,cmt-32" for the 32-bit CMT
> > +		(CMT0 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> > +		(CMT[234] on sh7372, sh73a0 and r8a7740)
> > +    - "renasas,cmt-48" for the 48-bit CMT
> > +		(CMT1 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> > +    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
> > +
> > +  - reg: base address and length of the registers block for the timer
> > module.
> > +  - interrupt-parent, interrupts: interrupt-specifier for the timer, one
> > per
> > +    channel.
> 
> It might make more sense to describe the interrupt on the channel
> subnode. It makes it far clearer which channel has which interrupt.

That's a good point. I'm relying on platform_get_irq() which won't support 
that usage, but I can switch to of_irq_to_resource() instead.

> > +  - clocks: phandle and clock-specifier pair for the functional clock.
> > +  - clock-names: must be "fck".
> 
> It would be nice to define the list once:
> 
> - clocks: A list of phandle + clock-specifier pairs, one for each entry
>   in clock-names.
> - clock-names: Should contain "fck" for the functional clock.

OK.

> > +
> > +  - #address-cells: must be 1
> > +  - #size-cells: must be 0
> > +
> > +  - renesas,channels-mask: integer bitmask of the channels implemented by
> > the
> > +    timer instance.
> 
> This is implied by the presence of a subnode. Either remove this or the
> subnodes.
>
> > +
> > +
> > +Each channel is described by a sub-node named "channel@<idx>", where
> > <idx> is +the channel index.
> > +
> > +Channels Required Properties:
> > +
> > +  - reg: the channel index.
> > +
> > +Channels Optional Properties:
> > +
> > +  - clock-source-rating: rating of the timer as a clock source device.
> > +  - clock-event-rating: rating of the timer as a clock event device.
> 
> This feels like a leak of Linux internals. Why do you need this?

You're right, it is. The clock source and clock event ratings are currently 
configured through platform data, I'll need to find a way to compute them in 
the driver instead.

There's still one piece of Linux-specific data I need though, as I need to 
specify for each channel whether to use it as a clock source device, a clock 
event device, both of them or none. That's configuration information that 
needs to be provided somehow.

> > +
> > +
> > +Example: R8A7790 (R-Car H2) CMT0 node
> > +
> > +	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
> > +	them channels 0 and 1 in the documentation.
> > +
> > +	cmt0: timer@ffca0000 {
> > +		compatible = "renesas,cmt-48-gen2";
> > +		reg = <0 0xffca0000 0 0x1004>;
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
> > +
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +
> > +		renesas,channels-mask = <0x60>;
> > +
> > +		channel@0 {
> > +			reg = <0>;
> > +			clock-event-rating = <80>;
> > +		};
> > +		channel@0 {
> > +			reg = <0>;
> > +			clock-source-rating = <80>;
> > +		};
> 
> Aaargh. Use the _real_ channel IDs for the reg proeprties and get rid of
> the mask. It's pointlessly confusing.

There's two real channel IDs. One of them is the value used in the hardware 
implementation (5 and 6 in this case, used to compute the channel registers 
block address) and the other one is the value used throughout the datasheet, 0 
and 1 in this case.

The later is used by the driver to reference the correct interrupt, which 
won't be needed anymore when referencing interrupts in the channel subnodes 
directly. It's also used to print messages to the kernel log and match the 
channel numbers specified in the datasheets. I could use the hardware channel 
number instead, but that might become confusing.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 15:53       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Thank you for the review.

On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > Cc: devicetree at vger.kernel.org
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  .../devicetree/bindings/timer/renesas,cmt.txt      |  75 +++++++++++++++
> >  drivers/clocksource/sh_cmt.c                       | 104 +++++++++++++---
> >  2 files changed, 160 insertions(+), 19 deletions(-)
> >  create mode 100644
> >  Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > b/Documentation/devicetree/bindings/timer/renesas,cmt.txt new file mode
> > 100644
> > index 0000000..28d4ab5
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
> > @@ -0,0 +1,75 @@
> > +* Renesas R-Car Compare Match Timer (CMT)
> > +
> > +The CMT is a multi-channel 16/32/48-bit timer/counter with configurable
> > clock
> > +inputs and programmable compare match.
> > +
> > +Channels share hadware resources but their counter and compare match
> > value are
> > +independent. A particular CMT instance can implement only a subset of the
> > +channels supported by the CMT model. Channels indices start from 0 and
> > are
> > +consecutive.
> > +
> > +Required Properties:
> > +
> > +  - compatible: must contain one of the following.
> > +    - "renesas,cmt-32" for the 32-bit CMT
> > +		(CMT0 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
> > +		(CMT[234] on sh7372, sh73a0 and r8a7740)
> > +    - "renasas,cmt-48" for the 48-bit CMT
> > +		(CMT1 on sh7372, sh73a0 and r8a7740)
> > +    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
> > +    		(CMT[01] on r8a73a4, r8a7790 and r8a7791)
> > +
> > +  - reg: base address and length of the registers block for the timer
> > module.
> > +  - interrupt-parent, interrupts: interrupt-specifier for the timer, one
> > per
> > +    channel.
> 
> It might make more sense to describe the interrupt on the channel
> subnode. It makes it far clearer which channel has which interrupt.

That's a good point. I'm relying on platform_get_irq() which won't support 
that usage, but I can switch to of_irq_to_resource() instead.

> > +  - clocks: phandle and clock-specifier pair for the functional clock.
> > +  - clock-names: must be "fck".
> 
> It would be nice to define the list once:
> 
> - clocks: A list of phandle + clock-specifier pairs, one for each entry
>   in clock-names.
> - clock-names: Should contain "fck" for the functional clock.

OK.

> > +
> > +  - #address-cells: must be 1
> > +  - #size-cells: must be 0
> > +
> > +  - renesas,channels-mask: integer bitmask of the channels implemented by
> > the
> > +    timer instance.
> 
> This is implied by the presence of a subnode. Either remove this or the
> subnodes.
>
> > +
> > +
> > +Each channel is described by a sub-node named "channel@<idx>", where
> > <idx> is +the channel index.
> > +
> > +Channels Required Properties:
> > +
> > +  - reg: the channel index.
> > +
> > +Channels Optional Properties:
> > +
> > +  - clock-source-rating: rating of the timer as a clock source device.
> > +  - clock-event-rating: rating of the timer as a clock event device.
> 
> This feels like a leak of Linux internals. Why do you need this?

You're right, it is. The clock source and clock event ratings are currently 
configured through platform data, I'll need to find a way to compute them in 
the driver instead.

There's still one piece of Linux-specific data I need though, as I need to 
specify for each channel whether to use it as a clock source device, a clock 
event device, both of them or none. That's configuration information that 
needs to be provided somehow.

> > +
> > +
> > +Example: R8A7790 (R-Car H2) CMT0 node
> > +
> > +	CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
> > +	them channels 0 and 1 in the documentation.
> > +
> > +	cmt0: timer at ffca0000 {
> > +		compatible = "renesas,cmt-48-gen2";
> > +		reg = <0 0xffca0000 0 0x1004>;
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <0 142 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
> > +
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +
> > +		renesas,channels-mask = <0x60>;
> > +
> > +		channel at 0 {
> > +			reg = <0>;
> > +			clock-event-rating = <80>;
> > +		};
> > +		channel at 0 {
> > +			reg = <0>;
> > +			clock-source-rating = <80>;
> > +		};
> 
> Aaargh. Use the _real_ channel IDs for the reg proeprties and get rid of
> the mask. It's pointlessly confusing.

There's two real channel IDs. One of them is the value used in the hardware 
implementation (5 and 6 in this case, used to compute the channel registers 
block address) and the other one is the value used throughout the datasheet, 0 
and 1 in this case.

The later is used by the driver to reference the correct interrupt, which 
won't be needed anymore when referencing interrupts in the channel subnodes 
directly. It's also used to print messages to the kernel log and match the 
channel numbers specified in the datasheets. I could use the hardware channel 
number instead, but that might become confusing.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 15:53       ` Laurent Pinchart
  (?)
@ 2014-02-14 15:59         ` Josh Cartwright
  -1 siblings, 0 replies; 168+ messages in thread
From: Josh Cartwright @ 2014-02-14 15:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 14, 2014 at 04:53:08PM +0100, Laurent Pinchart wrote:
> On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> > On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > > +Channels Optional Properties:
> > > +
> > > +  - clock-source-rating: rating of the timer as a clock source device.
> > > +  - clock-event-rating: rating of the timer as a clock event device.
> >
> > This feels like a leak of Linux internals. Why do you need this?
>
> You're right, it is. The clock source and clock event ratings are currently
> configured through platform data, I'll need to find a way to compute them in
> the driver instead.
>
> There's still one piece of Linux-specific data I need though, as I need to
> specify for each channel whether to use it as a clock source device, a clock
> event device, both of them or none. That's configuration information that
> needs to be provided somehow.

Are all the channels equally capable?  We had this problem for the
cadence_ttc timer used on Zynq, and decided to just statically allocate
the first timer to be the clocksource, and the second to be the
clockevent.

Also, should the rating really be user configurable?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 15:59         ` Josh Cartwright
  0 siblings, 0 replies; 168+ messages in thread
From: Josh Cartwright @ 2014-02-14 15:59 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Daniel Lezcano,
	linux-kernel, Thomas Gleixner, linux-arm-kernel, Soren Brinkmann

On Fri, Feb 14, 2014 at 04:53:08PM +0100, Laurent Pinchart wrote:
> On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> > On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > > +Channels Optional Properties:
> > > +
> > > +  - clock-source-rating: rating of the timer as a clock source device.
> > > +  - clock-event-rating: rating of the timer as a clock event device.
> >
> > This feels like a leak of Linux internals. Why do you need this?
>
> You're right, it is. The clock source and clock event ratings are currently
> configured through platform data, I'll need to find a way to compute them in
> the driver instead.
>
> There's still one piece of Linux-specific data I need though, as I need to
> specify for each channel whether to use it as a clock source device, a clock
> event device, both of them or none. That's configuration information that
> needs to be provided somehow.

Are all the channels equally capable?  We had this problem for the
cadence_ttc timer used on Zynq, and decided to just statically allocate
the first timer to be the clocksource, and the second to be the
clockevent.

Also, should the rating really be user configurable?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 15:59         ` Josh Cartwright
  0 siblings, 0 replies; 168+ messages in thread
From: Josh Cartwright @ 2014-02-14 15:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 14, 2014 at 04:53:08PM +0100, Laurent Pinchart wrote:
> On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> > On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > > +Channels Optional Properties:
> > > +
> > > +  - clock-source-rating: rating of the timer as a clock source device.
> > > +  - clock-event-rating: rating of the timer as a clock event device.
> >
> > This feels like a leak of Linux internals. Why do you need this?
>
> You're right, it is. The clock source and clock event ratings are currently
> configured through platform data, I'll need to find a way to compute them in
> the driver instead.
>
> There's still one piece of Linux-specific data I need though, as I need to
> specify for each channel whether to use it as a clock source device, a clock
> event device, both of them or none. That's configuration information that
> needs to be provided somehow.

Are all the channels equally capable?  We had this problem for the
cadence_ttc timer used on Zynq, and decided to just statically allocate
the first timer to be the clocksource, and the second to be the
clockevent.

Also, should the rating really be user configurable?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 15:53       ` Laurent Pinchart
  (?)
@ 2014-02-14 16:01         ` Magnus Damm
  -1 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-14 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> > +Channels Optional Properties:
>> > +
>> > +  - clock-source-rating: rating of the timer as a clock source device.
>> > +  - clock-event-rating: rating of the timer as a clock event device.
>>
>> This feels like a leak of Linux internals. Why do you need this?
>
> You're right, it is. The clock source and clock event ratings are currently
> configured through platform data, I'll need to find a way to compute them in
> the driver instead.

That would be very good!

> There's still one piece of Linux-specific data I need though, as I need to
> specify for each channel whether to use it as a clock source device, a clock
> event device, both of them or none. That's configuration information that
> needs to be provided somehow.

I think you can decide clock source or clock event assignment based on
number of channels available. If you have only a single channel then
both clock event and clock source need to be supported. Otherwise use
one channel for clock source and the rest for clock events.

This is probably out of scope for this DT conversion, but it would be
neat if you somehow could specify the CPU affinity for a channel to
tie a clock event to an individual CPU core. This would make a a
per-cpu timer unless I'm mistaken. But that's more of a software
policy than anything else.

Thanks,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 16:01         ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-14 16:01 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> > +Channels Optional Properties:
>> > +
>> > +  - clock-source-rating: rating of the timer as a clock source device.
>> > +  - clock-event-rating: rating of the timer as a clock event device.
>>
>> This feels like a leak of Linux internals. Why do you need this?
>
> You're right, it is. The clock source and clock event ratings are currently
> configured through platform data, I'll need to find a way to compute them in
> the driver instead.

That would be very good!

> There's still one piece of Linux-specific data I need though, as I need to
> specify for each channel whether to use it as a clock source device, a clock
> event device, both of them or none. That's configuration information that
> needs to be provided somehow.

I think you can decide clock source or clock event assignment based on
number of channels available. If you have only a single channel then
both clock event and clock source need to be supported. Otherwise use
one channel for clock source and the rest for clock events.

This is probably out of scope for this DT conversion, but it would be
neat if you somehow could specify the CPU affinity for a channel to
tie a clock event to an individual CPU core. This would make a a
per-cpu timer unless I'm mistaken. But that's more of a software
policy than anything else.

Thanks,

/ magnus

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 16:01         ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-14 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> > +Channels Optional Properties:
>> > +
>> > +  - clock-source-rating: rating of the timer as a clock source device.
>> > +  - clock-event-rating: rating of the timer as a clock event device.
>>
>> This feels like a leak of Linux internals. Why do you need this?
>
> You're right, it is. The clock source and clock event ratings are currently
> configured through platform data, I'll need to find a way to compute them in
> the driver instead.

That would be very good!

> There's still one piece of Linux-specific data I need though, as I need to
> specify for each channel whether to use it as a clock source device, a clock
> event device, both of them or none. That's configuration information that
> needs to be provided somehow.

I think you can decide clock source or clock event assignment based on
number of channels available. If you have only a single channel then
both clock event and clock source need to be supported. Otherwise use
one channel for clock source and the rest for clock events.

This is probably out of scope for this DT conversion, but it would be
neat if you somehow could specify the CPU affinity for a channel to
tie a clock event to an individual CPU core. This would make a a
per-cpu timer unless I'm mistaken. But that's more of a software
policy than anything else.

Thanks,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 16:01         ` Magnus Damm
  (?)
@ 2014-02-14 16:12           ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> > +Channels Optional Properties:
> >> > +
> >> > +  - clock-source-rating: rating of the timer as a clock source device.
> >> > +  - clock-event-rating: rating of the timer as a clock event device.
> >> 
> >> This feels like a leak of Linux internals. Why do you need this?
> > 
> > You're right, it is. The clock source and clock event ratings are
> > currently configured through platform data, I'll need to find a way to
> > compute them in the driver instead.
> 
> That would be very good!

Any pointer would be appreciated :-) How did you compute the various ratings 
used in platform data all over the place ?

> > There's still one piece of Linux-specific data I need though, as I need to
> > specify for each channel whether to use it as a clock source device, a
> > clock event device, both of them or none. That's configuration
> > information that needs to be provided somehow.
> 
> I think you can decide clock source or clock event assignment based on
> number of channels available. If you have only a single channel then both
> clock event and clock source need to be supported. Otherwise use one channel
> for clock source and the rest for clock events.

That won't match the current situation. Look at CMT0 in r8a7790 for instance. 
There's two hardware channels available, and we only use the first one, for 
clock events only.

> This is probably out of scope for this DT conversion, but it would be neat
> if you somehow could specify the CPU affinity for a channel to tie a clock
> event to an individual CPU core. This would make a a per-cpu timer unless
> I'm mistaken. But that's more of a software policy than anything else.

Yes, that's a configuration that needs to be specified somewhere. I don't know 
where though.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 16:12           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:12 UTC (permalink / raw)
  To: Magnus Damm
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Magnus,

On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> > +Channels Optional Properties:
> >> > +
> >> > +  - clock-source-rating: rating of the timer as a clock source device.
> >> > +  - clock-event-rating: rating of the timer as a clock event device.
> >> 
> >> This feels like a leak of Linux internals. Why do you need this?
> > 
> > You're right, it is. The clock source and clock event ratings are
> > currently configured through platform data, I'll need to find a way to
> > compute them in the driver instead.
> 
> That would be very good!

Any pointer would be appreciated :-) How did you compute the various ratings 
used in platform data all over the place ?

> > There's still one piece of Linux-specific data I need though, as I need to
> > specify for each channel whether to use it as a clock source device, a
> > clock event device, both of them or none. That's configuration
> > information that needs to be provided somehow.
> 
> I think you can decide clock source or clock event assignment based on
> number of channels available. If you have only a single channel then both
> clock event and clock source need to be supported. Otherwise use one channel
> for clock source and the rest for clock events.

That won't match the current situation. Look at CMT0 in r8a7790 for instance. 
There's two hardware channels available, and we only use the first one, for 
clock events only.

> This is probably out of scope for this DT conversion, but it would be neat
> if you somehow could specify the CPU affinity for a channel to tie a clock
> event to an individual CPU core. This would make a a per-cpu timer unless
> I'm mistaken. But that's more of a software policy than anything else.

Yes, that's a configuration that needs to be specified somewhere. I don't know 
where though.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 16:12           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> > +Channels Optional Properties:
> >> > +
> >> > +  - clock-source-rating: rating of the timer as a clock source device.
> >> > +  - clock-event-rating: rating of the timer as a clock event device.
> >> 
> >> This feels like a leak of Linux internals. Why do you need this?
> > 
> > You're right, it is. The clock source and clock event ratings are
> > currently configured through platform data, I'll need to find a way to
> > compute them in the driver instead.
> 
> That would be very good!

Any pointer would be appreciated :-) How did you compute the various ratings 
used in platform data all over the place ?

> > There's still one piece of Linux-specific data I need though, as I need to
> > specify for each channel whether to use it as a clock source device, a
> > clock event device, both of them or none. That's configuration
> > information that needs to be provided somehow.
> 
> I think you can decide clock source or clock event assignment based on
> number of channels available. If you have only a single channel then both
> clock event and clock source need to be supported. Otherwise use one channel
> for clock source and the rest for clock events.

That won't match the current situation. Look at CMT0 in r8a7790 for instance. 
There's two hardware channels available, and we only use the first one, for 
clock events only.

> This is probably out of scope for this DT conversion, but it would be neat
> if you somehow could specify the CPU affinity for a channel to tie a clock
> event to an individual CPU core. This would make a a per-cpu timer unless
> I'm mistaken. But that's more of a software policy than anything else.

Yes, that's a configuration that needs to be specified somewhere. I don't know 
where though.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 15:59         ` Josh Cartwright
  (?)
@ 2014-02-14 16:15           ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Josh,

On Friday 14 February 2014 09:59:51 Josh Cartwright wrote:
> On Fri, Feb 14, 2014 at 04:53:08PM +0100, Laurent Pinchart wrote:
> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> > > On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > > > +Channels Optional Properties:
> > > > +
> > > > +  - clock-source-rating: rating of the timer as a clock source
> > > > device.
> > > > +  - clock-event-rating: rating of the timer as a clock event device.
> > > 
> > > This feels like a leak of Linux internals. Why do you need this?
> > 
> > You're right, it is. The clock source and clock event ratings are
> > currently configured through platform data, I'll need to find a way to
> > compute them in the driver instead.
> > 
> > There's still one piece of Linux-specific data I need though, as I need to
> > specify for each channel whether to use it as a clock source device, a
> > clock event device, both of them or none. That's configuration
> > information that needs to be provided somehow.
> 
> Are all the channels equally capable?  We had this problem for the
> cadence_ttc timer used on Zynq, and decided to just statically allocate
> the first timer to be the clocksource, and the second to be the
> clockevent.

No, they're not. The channels can be implemented with different counter 
widths, different available prescalers and source clocks and different power 
management features (not all of them are capable to run in all sleep states).

> Also, should the rating really be user configurable?

Probably not. I suppose the rating should be computed by the driver based on 
the source clock frequency, prescaler and counter width. Any help there would 
be very appreciated, I'm pretty new to clock source and clock event devices.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 16:15           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:15 UTC (permalink / raw)
  To: Josh Cartwright, linux-sh
  Cc: Mark Rutland, Daniel Lezcano, linux-kernel, Thomas Gleixner,
	linux-arm-kernel, Soren Brinkmann

Hi Josh,

On Friday 14 February 2014 09:59:51 Josh Cartwright wrote:
> On Fri, Feb 14, 2014 at 04:53:08PM +0100, Laurent Pinchart wrote:
> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> > > On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > > > +Channels Optional Properties:
> > > > +
> > > > +  - clock-source-rating: rating of the timer as a clock source
> > > > device.
> > > > +  - clock-event-rating: rating of the timer as a clock event device.
> > > 
> > > This feels like a leak of Linux internals. Why do you need this?
> > 
> > You're right, it is. The clock source and clock event ratings are
> > currently configured through platform data, I'll need to find a way to
> > compute them in the driver instead.
> > 
> > There's still one piece of Linux-specific data I need though, as I need to
> > specify for each channel whether to use it as a clock source device, a
> > clock event device, both of them or none. That's configuration
> > information that needs to be provided somehow.
> 
> Are all the channels equally capable?  We had this problem for the
> cadence_ttc timer used on Zynq, and decided to just statically allocate
> the first timer to be the clocksource, and the second to be the
> clockevent.

No, they're not. The channels can be implemented with different counter 
widths, different available prescalers and source clocks and different power 
management features (not all of them are capable to run in all sleep states).

> Also, should the rating really be user configurable?

Probably not. I suppose the rating should be computed by the driver based on 
the source clock frequency, prescaler and counter width. Any help there would 
be very appreciated, I'm pretty new to clock source and clock event devices.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 16:15           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Josh,

On Friday 14 February 2014 09:59:51 Josh Cartwright wrote:
> On Fri, Feb 14, 2014 at 04:53:08PM +0100, Laurent Pinchart wrote:
> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> > > On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> > > > +Channels Optional Properties:
> > > > +
> > > > +  - clock-source-rating: rating of the timer as a clock source
> > > > device.
> > > > +  - clock-event-rating: rating of the timer as a clock event device.
> > > 
> > > This feels like a leak of Linux internals. Why do you need this?
> > 
> > You're right, it is. The clock source and clock event ratings are
> > currently configured through platform data, I'll need to find a way to
> > compute them in the driver instead.
> > 
> > There's still one piece of Linux-specific data I need though, as I need to
> > specify for each channel whether to use it as a clock source device, a
> > clock event device, both of them or none. That's configuration
> > information that needs to be provided somehow.
> 
> Are all the channels equally capable?  We had this problem for the
> cadence_ttc timer used on Zynq, and decided to just statically allocate
> the first timer to be the clocksource, and the second to be the
> clockevent.

No, they're not. The channels can be implemented with different counter 
widths, different available prescalers and source clocks and different power 
management features (not all of them are capable to run in all sleep states).

> Also, should the rating really be user configurable?

Probably not. I suppose the rating should be computed by the driver based on 
the source clock frequency, prescaler and counter width. Any help there would 
be very appreciated, I'm pretty new to clock source and clock event devices.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14 14:36             ` Sergei Shtylyov
  (?)
@ 2014-02-14 16:26               ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sergei,

On Friday 14 February 2014 18:36:11 Sergei Shtylyov wrote:
> Hello.
> 
> On 14-02-2014 18:22, Laurent Pinchart wrote:
> >>>>> Enable the CMT0 device and configure channel 0 as a clock event
> >>>>> provider.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> 
> >>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> >>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> @@ -29,7 +29,6 @@ enum {
> >>>>> 
> >>>>>   };
> >>>>>   
> >>>>>   void r8a7790_add_standard_devices(void);
> >>>>> 
> >>>>> -void r8a7790_add_dt_devices(void);
> >>>>> 
> >>>>>   void r8a7790_clock_init(void);
> >>>>>   void r8a7790_pinmux_init(void);
> >>>>>   void r8a7790_pm_init(void);
> >>>>> 
> >>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> >>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >>>>>     					  &cmt##idx##_platform_data,	\
> >>>>>     					  sizeof(struct sh_timer_config))
> >>>>> 
> >>>>> -void __init r8a7790_add_dt_devices(void)
> >>>>> -{
> >>>>> -	r8a7790_register_cmt(0);
> >>>>> -}
> >>>>> -
> >>>>>  void __init r8a7790_add_standard_devices(void)
> >>>>>  {
> >>>>>     	r8a7790_register_scif(0);
> >>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >>>>> 	r8a7790_register_scif(7);
> >>>>>  	r8a7790_register_scif(8);
> >>>>>  	r8a7790_register_scif(9);
> >>>>> -	r8a7790_add_dt_devices();
> >>>>> +	r8a7790_register_cmt(0);
> >>>>> 	r8a7790_register_irqc(0);
> >>>>> 	r8a7790_register_thermal();
> >>>>> }
> >>>> 
> >>>> IMHO, these 2 files should be split into a separate patch.
> >>> 
> >>> That could easily be done, but why ?
> >> 
> >> It does not seem necessary to combine these changes in one patch.
> >> Remember, Simon has separate branches for boards and SoCs. So finally
> >> it's up to him to decide on this...
> > 
> > Right, but in this case I need to remove the CMT platform device
> > registration from r8a7790_add_dt_devices()
> 
> You're not removing anything in these 2 files, you're just replacing
> "indirect" call to r8a7790_register_cmt(0) with direct.

OK, I see what you mean now. Given that the patch removes the 
r8a7790_add_dt_devices() call from arch/arm/mach-shmobile/board-lager-
reference.c, I could indeed split those two changes into a separate patch as 
there's no-one calling the function anymore. That would introduce a dependency 
between the branches, which might not be better. I'll let Simon comment on 
what he would prefer and will act accordingly.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 16:26               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:26 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

Hi Sergei,

On Friday 14 February 2014 18:36:11 Sergei Shtylyov wrote:
> Hello.
> 
> On 14-02-2014 18:22, Laurent Pinchart wrote:
> >>>>> Enable the CMT0 device and configure channel 0 as a clock event
> >>>>> provider.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> 
> >>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> >>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> @@ -29,7 +29,6 @@ enum {
> >>>>> 
> >>>>>   };
> >>>>>   
> >>>>>   void r8a7790_add_standard_devices(void);
> >>>>> 
> >>>>> -void r8a7790_add_dt_devices(void);
> >>>>> 
> >>>>>   void r8a7790_clock_init(void);
> >>>>>   void r8a7790_pinmux_init(void);
> >>>>>   void r8a7790_pm_init(void);
> >>>>> 
> >>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> >>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >>>>>     					  &cmt##idx##_platform_data,	\
> >>>>>     					  sizeof(struct sh_timer_config))
> >>>>> 
> >>>>> -void __init r8a7790_add_dt_devices(void)
> >>>>> -{
> >>>>> -	r8a7790_register_cmt(0);
> >>>>> -}
> >>>>> -
> >>>>>  void __init r8a7790_add_standard_devices(void)
> >>>>>  {
> >>>>>     	r8a7790_register_scif(0);
> >>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >>>>> 	r8a7790_register_scif(7);
> >>>>>  	r8a7790_register_scif(8);
> >>>>>  	r8a7790_register_scif(9);
> >>>>> -	r8a7790_add_dt_devices();
> >>>>> +	r8a7790_register_cmt(0);
> >>>>> 	r8a7790_register_irqc(0);
> >>>>> 	r8a7790_register_thermal();
> >>>>> }
> >>>> 
> >>>> IMHO, these 2 files should be split into a separate patch.
> >>> 
> >>> That could easily be done, but why ?
> >> 
> >> It does not seem necessary to combine these changes in one patch.
> >> Remember, Simon has separate branches for boards and SoCs. So finally
> >> it's up to him to decide on this...
> > 
> > Right, but in this case I need to remove the CMT platform device
> > registration from r8a7790_add_dt_devices()
> 
> You're not removing anything in these 2 files, you're just replacing
> "indirect" call to r8a7790_register_cmt(0) with direct.

OK, I see what you mean now. Given that the patch removes the 
r8a7790_add_dt_devices() call from arch/arm/mach-shmobile/board-lager-
reference.c, I could indeed split those two changes into a separate patch as 
there's no-one calling the function anymore. That would introduce a dependency 
between the branches, which might not be better. I'll let Simon comment on 
what he would prefer and will act accordingly.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 16:26               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-14 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sergei,

On Friday 14 February 2014 18:36:11 Sergei Shtylyov wrote:
> Hello.
> 
> On 14-02-2014 18:22, Laurent Pinchart wrote:
> >>>>> Enable the CMT0 device and configure channel 0 as a clock event
> >>>>> provider.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> 
> >>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
> >>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
> >>>>> @@ -29,7 +29,6 @@ enum {
> >>>>> 
> >>>>>   };
> >>>>>   
> >>>>>   void r8a7790_add_standard_devices(void);
> >>>>> 
> >>>>> -void r8a7790_add_dt_devices(void);
> >>>>> 
> >>>>>   void r8a7790_clock_init(void);
> >>>>>   void r8a7790_pinmux_init(void);
> >>>>>   void r8a7790_pm_init(void);
> >>>>> 
> >>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
> >>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
> >>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
> >>>>>     					  &cmt##idx##_platform_data,	\
> >>>>>     					  sizeof(struct sh_timer_config))
> >>>>> 
> >>>>> -void __init r8a7790_add_dt_devices(void)
> >>>>> -{
> >>>>> -	r8a7790_register_cmt(0);
> >>>>> -}
> >>>>> -
> >>>>>  void __init r8a7790_add_standard_devices(void)
> >>>>>  {
> >>>>>     	r8a7790_register_scif(0);
> >>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
> >>>>> 	r8a7790_register_scif(7);
> >>>>>  	r8a7790_register_scif(8);
> >>>>>  	r8a7790_register_scif(9);
> >>>>> -	r8a7790_add_dt_devices();
> >>>>> +	r8a7790_register_cmt(0);
> >>>>> 	r8a7790_register_irqc(0);
> >>>>> 	r8a7790_register_thermal();
> >>>>> }
> >>>> 
> >>>> IMHO, these 2 files should be split into a separate patch.
> >>> 
> >>> That could easily be done, but why ?
> >> 
> >> It does not seem necessary to combine these changes in one patch.
> >> Remember, Simon has separate branches for boards and SoCs. So finally
> >> it's up to him to decide on this...
> > 
> > Right, but in this case I need to remove the CMT platform device
> > registration from r8a7790_add_dt_devices()
> 
> You're not removing anything in these 2 files, you're just replacing
> "indirect" call to r8a7790_register_cmt(0) with direct.

OK, I see what you mean now. Given that the patch removes the 
r8a7790_add_dt_devices() call from arch/arm/mach-shmobile/board-lager-
reference.c, I could indeed split those two changes into a separate patch as 
there's no-one calling the function anymore. That would introduce a dependency 
between the branches, which might not be better. I'll let Simon comment on 
what he would prefer and will act accordingly.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 16:12           ` Laurent Pinchart
  (?)
@ 2014-02-14 17:22             ` Magnus Damm
  -1 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-14 17:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> > +Channels Optional Properties:
>> >> > +
>> >> > +  - clock-source-rating: rating of the timer as a clock source device.
>> >> > +  - clock-event-rating: rating of the timer as a clock event device.
>> >>
>> >> This feels like a leak of Linux internals. Why do you need this?
>> >
>> > You're right, it is. The clock source and clock event ratings are
>> > currently configured through platform data, I'll need to find a way to
>> > compute them in the driver instead.
>>
>> That would be very good!
>
> Any pointer would be appreciated :-) How did you compute the various ratings
> used in platform data all over the place ?

Historically we used the rating to select between CMT and TMU. For
clock sources I suppose you also have the jiffy rating to consider.
And for the SMP parts we have ARM IP for TWD and arch timers that have
their ratings too. So you need to check all the timers on a particular
system and consider what you want to have operating by default. The
ARM IP timers should be preferred if available. For clock sources the
rule is probably the higher resolution the better.

>> > There's still one piece of Linux-specific data I need though, as I need to
>> > specify for each channel whether to use it as a clock source device, a
>> > clock event device, both of them or none. That's configuration
>> > information that needs to be provided somehow.
>>
>> I think you can decide clock source or clock event assignment based on
>> number of channels available. If you have only a single channel then both
>> clock event and clock source need to be supported. Otherwise use one channel
>> for clock source and the rest for clock events.
>
> That won't match the current situation. Look at CMT0 in r8a7790 for instance.
> There's two hardware channels available, and we only use the first one, for
> clock events only.

You are correct. The reason for that is that the CMT driver today is
optimized for combined clock event and clock source operation.

Historically the hardware it initially was written for (sh-mobile on
the SH arch) only had a single timer channel so combined operation was
required for tickless to work. But since you're asking how to allocate
channels then I propose checking numbers of channels available and go
from there. With that the r8a7790 support can only get better. =)

>> This is probably out of scope for this DT conversion, but it would be neat
>> if you somehow could specify the CPU affinity for a channel to tie a clock
>> event to an individual CPU core. This would make a a per-cpu timer unless
>> I'm mistaken. But that's more of a software policy than anything else.
>
> Yes, that's a configuration that needs to be specified somewhere. I don't know
> where though.

As long as you have per-channel interrupts described in DT you can
probably handle this in a generic way in the driver.

Thanks,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 17:22             ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-14 17:22 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Laurent,

On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> > +Channels Optional Properties:
>> >> > +
>> >> > +  - clock-source-rating: rating of the timer as a clock source device.
>> >> > +  - clock-event-rating: rating of the timer as a clock event device.
>> >>
>> >> This feels like a leak of Linux internals. Why do you need this?
>> >
>> > You're right, it is. The clock source and clock event ratings are
>> > currently configured through platform data, I'll need to find a way to
>> > compute them in the driver instead.
>>
>> That would be very good!
>
> Any pointer would be appreciated :-) How did you compute the various ratings
> used in platform data all over the place ?

Historically we used the rating to select between CMT and TMU. For
clock sources I suppose you also have the jiffy rating to consider.
And for the SMP parts we have ARM IP for TWD and arch timers that have
their ratings too. So you need to check all the timers on a particular
system and consider what you want to have operating by default. The
ARM IP timers should be preferred if available. For clock sources the
rule is probably the higher resolution the better.

>> > There's still one piece of Linux-specific data I need though, as I need to
>> > specify for each channel whether to use it as a clock source device, a
>> > clock event device, both of them or none. That's configuration
>> > information that needs to be provided somehow.
>>
>> I think you can decide clock source or clock event assignment based on
>> number of channels available. If you have only a single channel then both
>> clock event and clock source need to be supported. Otherwise use one channel
>> for clock source and the rest for clock events.
>
> That won't match the current situation. Look at CMT0 in r8a7790 for instance.
> There's two hardware channels available, and we only use the first one, for
> clock events only.

You are correct. The reason for that is that the CMT driver today is
optimized for combined clock event and clock source operation.

Historically the hardware it initially was written for (sh-mobile on
the SH arch) only had a single timer channel so combined operation was
required for tickless to work. But since you're asking how to allocate
channels then I propose checking numbers of channels available and go
from there. With that the r8a7790 support can only get better. =)

>> This is probably out of scope for this DT conversion, but it would be neat
>> if you somehow could specify the CPU affinity for a channel to tie a clock
>> event to an individual CPU core. This would make a a per-cpu timer unless
>> I'm mistaken. But that's more of a software policy than anything else.
>
> Yes, that's a configuration that needs to be specified somewhere. I don't know
> where though.

As long as you have per-channel interrupts described in DT you can
probably handle this in a generic way in the driver.

Thanks,

/ magnus

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-14 17:22             ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-14 17:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> > +Channels Optional Properties:
>> >> > +
>> >> > +  - clock-source-rating: rating of the timer as a clock source device.
>> >> > +  - clock-event-rating: rating of the timer as a clock event device.
>> >>
>> >> This feels like a leak of Linux internals. Why do you need this?
>> >
>> > You're right, it is. The clock source and clock event ratings are
>> > currently configured through platform data, I'll need to find a way to
>> > compute them in the driver instead.
>>
>> That would be very good!
>
> Any pointer would be appreciated :-) How did you compute the various ratings
> used in platform data all over the place ?

Historically we used the rating to select between CMT and TMU. For
clock sources I suppose you also have the jiffy rating to consider.
And for the SMP parts we have ARM IP for TWD and arch timers that have
their ratings too. So you need to check all the timers on a particular
system and consider what you want to have operating by default. The
ARM IP timers should be preferred if available. For clock sources the
rule is probably the higher resolution the better.

>> > There's still one piece of Linux-specific data I need though, as I need to
>> > specify for each channel whether to use it as a clock source device, a
>> > clock event device, both of them or none. That's configuration
>> > information that needs to be provided somehow.
>>
>> I think you can decide clock source or clock event assignment based on
>> number of channels available. If you have only a single channel then both
>> clock event and clock source need to be supported. Otherwise use one channel
>> for clock source and the rest for clock events.
>
> That won't match the current situation. Look at CMT0 in r8a7790 for instance.
> There's two hardware channels available, and we only use the first one, for
> clock events only.

You are correct. The reason for that is that the CMT driver today is
optimized for combined clock event and clock source operation.

Historically the hardware it initially was written for (sh-mobile on
the SH arch) only had a single timer channel so combined operation was
required for tickless to work. But since you're asking how to allocate
channels then I propose checking numbers of channels available and go
from there. With that the r8a7790 support can only get better. =)

>> This is probably out of scope for this DT conversion, but it would be neat
>> if you somehow could specify the CPU affinity for a channel to tie a clock
>> event to an individual CPU core. This would make a a per-cpu timer unless
>> I'm mistaken. But that's more of a software policy than anything else.
>
> Yes, that's a configuration that needs to be specified somewhere. I don't know
> where though.

As long as you have per-channel interrupts described in DT you can
probably handle this in a generic way in the driver.

Thanks,

/ magnus

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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
  2014-02-14 16:26               ` Laurent Pinchart
  (?)
@ 2014-02-14 19:56                 ` Sergei Shtylyov
  -1 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/14/2014 07:26 PM, Laurent Pinchart wrote:

>>>>>>> Enable the CMT0 device and configure channel 0 as a clock event
>>>>>>> provider.

>>>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>>>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
>>>>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> @@ -29,7 +29,6 @@ enum {
>>>>>>>
>>>>>>>    };
>>>>>>>
>>>>>>>    void r8a7790_add_standard_devices(void);
>>>>>>>
>>>>>>> -void r8a7790_add_dt_devices(void);
>>>>>>>
>>>>>>>    void r8a7790_clock_init(void);
>>>>>>>    void r8a7790_pinmux_init(void);
>>>>>>>    void r8a7790_pm_init(void);
>>>>>>>
>>>>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>>>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>>>>>      					  &cmt##idx##_platform_data,	\
>>>>>>>      					  sizeof(struct sh_timer_config))
>>>>>>>
>>>>>>> -void __init r8a7790_add_dt_devices(void)
>>>>>>> -{
>>>>>>> -	r8a7790_register_cmt(0);
>>>>>>> -}
>>>>>>> -
>>>>>>>   void __init r8a7790_add_standard_devices(void)
>>>>>>>   {
>>>>>>>      	r8a7790_register_scif(0);
>>>>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>>>>> 	r8a7790_register_scif(7);
>>>>>>>   	r8a7790_register_scif(8);
>>>>>>>   	r8a7790_register_scif(9);
>>>>>>> -	r8a7790_add_dt_devices();
>>>>>>> +	r8a7790_register_cmt(0);
>>>>>>> 	r8a7790_register_irqc(0);
>>>>>>> 	r8a7790_register_thermal();
>>>>>>> }

>>>>>> IMHO, these 2 files should be split into a separate patch.

>>>>> That could easily be done, but why ?

>>>> It does not seem necessary to combine these changes in one patch.
>>>> Remember, Simon has separate branches for boards and SoCs. So finally
>>>> it's up to him to decide on this...

>>> Right, but in this case I need to remove the CMT platform device
>>> registration from r8a7790_add_dt_devices()

>> You're not removing anything in these 2 files, you're just replacing
>> "indirect" call to r8a7790_register_cmt(0) with direct.

> OK, I see what you mean now. Given that the patch removes the
> r8a7790_add_dt_devices() call from arch/arm/mach-shmobile/board-lager-
> reference.c, I could indeed split those two changes into a separate patch as
> there's no-one calling the function anymore. That would introduce a dependency
> between the branches, which might not be better. I'll let Simon comment on
> what he would prefer and will act accordingly.

    Yes, the branch inter-dependencies are bad too. I didn't think about it, 
sorry.

WBR, Sergei


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

* Re: [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 19:56                 ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 19:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano, Thomas Gleixner

On 02/14/2014 07:26 PM, Laurent Pinchart wrote:

>>>>>>> Enable the CMT0 device and configure channel 0 as a clock event
>>>>>>> provider.

>>>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>>>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
>>>>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> @@ -29,7 +29,6 @@ enum {
>>>>>>>
>>>>>>>    };
>>>>>>>
>>>>>>>    void r8a7790_add_standard_devices(void);
>>>>>>>
>>>>>>> -void r8a7790_add_dt_devices(void);
>>>>>>>
>>>>>>>    void r8a7790_clock_init(void);
>>>>>>>    void r8a7790_pinmux_init(void);
>>>>>>>    void r8a7790_pm_init(void);
>>>>>>>
>>>>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>>>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>>>>>      					  &cmt##idx##_platform_data,	\
>>>>>>>      					  sizeof(struct sh_timer_config))
>>>>>>>
>>>>>>> -void __init r8a7790_add_dt_devices(void)
>>>>>>> -{
>>>>>>> -	r8a7790_register_cmt(0);
>>>>>>> -}
>>>>>>> -
>>>>>>>   void __init r8a7790_add_standard_devices(void)
>>>>>>>   {
>>>>>>>      	r8a7790_register_scif(0);
>>>>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>>>>> 	r8a7790_register_scif(7);
>>>>>>>   	r8a7790_register_scif(8);
>>>>>>>   	r8a7790_register_scif(9);
>>>>>>> -	r8a7790_add_dt_devices();
>>>>>>> +	r8a7790_register_cmt(0);
>>>>>>> 	r8a7790_register_irqc(0);
>>>>>>> 	r8a7790_register_thermal();
>>>>>>> }

>>>>>> IMHO, these 2 files should be split into a separate patch.

>>>>> That could easily be done, but why ?

>>>> It does not seem necessary to combine these changes in one patch.
>>>> Remember, Simon has separate branches for boards and SoCs. So finally
>>>> it's up to him to decide on this...

>>> Right, but in this case I need to remove the CMT platform device
>>> registration from r8a7790_add_dt_devices()

>> You're not removing anything in these 2 files, you're just replacing
>> "indirect" call to r8a7790_register_cmt(0) with direct.

> OK, I see what you mean now. Given that the patch removes the
> r8a7790_add_dt_devices() call from arch/arm/mach-shmobile/board-lager-
> reference.c, I could indeed split those two changes into a separate patch as
> there's no-one calling the function anymore. That would introduce a dependency
> between the branches, which might not be better. I'll let Simon comment on
> what he would prefer and will act accordingly.

    Yes, the branch inter-dependencies are bad too. I didn't think about it, 
sorry.

WBR, Sergei


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

* [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree
@ 2014-02-14 19:56                 ` Sergei Shtylyov
  0 siblings, 0 replies; 168+ messages in thread
From: Sergei Shtylyov @ 2014-02-14 19:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/14/2014 07:26 PM, Laurent Pinchart wrote:

>>>>>>> Enable the CMT0 device and configure channel 0 as a clock event
>>>>>>> provider.

>>>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

>>>>>>> diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 0b95bab..62b31f3
>>>>>>> 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
>>>>>>> @@ -29,7 +29,6 @@ enum {
>>>>>>>
>>>>>>>    };
>>>>>>>
>>>>>>>    void r8a7790_add_standard_devices(void);
>>>>>>>
>>>>>>> -void r8a7790_add_dt_devices(void);
>>>>>>>
>>>>>>>    void r8a7790_clock_init(void);
>>>>>>>    void r8a7790_pinmux_init(void);
>>>>>>>    void r8a7790_pm_init(void);
>>>>>>>
>>>>>>> diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> b/arch/arm/mach-shmobile/setup-r8a7790.c index 3e5813f..462c81f 100644
>>>>>>> --- a/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> +++ b/arch/arm/mach-shmobile/setup-r8a7790.c
>>>>>>> @@ -294,11 +294,6 @@ static struct resource cmt0_resources[] = {
>>>>>>>      					  &cmt##idx##_platform_data,	\
>>>>>>>      					  sizeof(struct sh_timer_config))
>>>>>>>
>>>>>>> -void __init r8a7790_add_dt_devices(void)
>>>>>>> -{
>>>>>>> -	r8a7790_register_cmt(0);
>>>>>>> -}
>>>>>>> -
>>>>>>>   void __init r8a7790_add_standard_devices(void)
>>>>>>>   {
>>>>>>>      	r8a7790_register_scif(0);
>>>>>>> @@ -311,7 +306,7 @@ void __init r8a7790_add_standard_devices(void)
>>>>>>> 	r8a7790_register_scif(7);
>>>>>>>   	r8a7790_register_scif(8);
>>>>>>>   	r8a7790_register_scif(9);
>>>>>>> -	r8a7790_add_dt_devices();
>>>>>>> +	r8a7790_register_cmt(0);
>>>>>>> 	r8a7790_register_irqc(0);
>>>>>>> 	r8a7790_register_thermal();
>>>>>>> }

>>>>>> IMHO, these 2 files should be split into a separate patch.

>>>>> That could easily be done, but why ?

>>>> It does not seem necessary to combine these changes in one patch.
>>>> Remember, Simon has separate branches for boards and SoCs. So finally
>>>> it's up to him to decide on this...

>>> Right, but in this case I need to remove the CMT platform device
>>> registration from r8a7790_add_dt_devices()

>> You're not removing anything in these 2 files, you're just replacing
>> "indirect" call to r8a7790_register_cmt(0) with direct.

> OK, I see what you mean now. Given that the patch removes the
> r8a7790_add_dt_devices() call from arch/arm/mach-shmobile/board-lager-
> reference.c, I could indeed split those two changes into a separate patch as
> there's no-one calling the function anymore. That would introduce a dependency
> between the branches, which might not be better. I'll let Simon comment on
> what he would prefer and will act accordingly.

    Yes, the branch inter-dependencies are bad too. I didn't think about it, 
sorry.

WBR, Sergei

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-14  0:59   ` Laurent Pinchart
  (?)
@ 2014-02-15 12:46     ` Thomas Gleixner
  -1 siblings, 0 replies; 168+ messages in thread
From: Thomas Gleixner @ 2014-02-15 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> CMT hardware devices can support multiple channels, with global
> registers and per-channel registers. The sh_cmt driver currently models
> the hardware with one Linux device per channel. This model makes it
> difficult to handle global registers in a clean way.
> 
> Add support for a new model that uses one Linux device per timer with
> multiple channels per device. This requires changes to platform data,
> add new channel configuration fields.
> 
> Support for the legacy model is kept and will be removed after all
> platforms switch to the new model.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++++++----------
>  include/linux/sh_timer.h     |   9 ++
>  2 files changed, 239 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
> index 5280231..8390f0f 100644
> --- a/drivers/clocksource/sh_cmt.c
> +++ b/drivers/clocksource/sh_cmt.c
> @@ -53,7 +53,16 @@ struct sh_cmt_device;
>   * channel registers block. All other versions have a shared start/stop register
>   * located in the global space.
>   *
> - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
> + * Channels are indexed from 0 to N-1 in the documentation. The channel index
> + * infers the start/stop bit position in the control register and the channel
> + * registers block address. Some CMT instances have a subset of channels
> + * available, in which case the index in the documentation doesn't match the
> + * "real" index as implemented in hardware. This is for instance the case with
> + * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
> + * in the documentation but using start/stop bit 5 and having its registers
> + * block at 0x60.
> + *
> + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
>   * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
>   */
>  
> @@ -85,11 +94,15 @@ struct sh_cmt_info {
>  
>  struct sh_cmt_channel {
>  	struct sh_cmt_device *cmt;
> -	unsigned int index;
>  
> -	void __iomem *base;
> +	unsigned int index;	/* Index in the documentation */
> +	unsigned int hwidx;	/* Real hardware index */
> +
> +	void __iomem *iostart;
> +	void __iomem *ioctrl;
>  	struct irqaction irqaction;

While you are at it, can you please get rid of that irqaction and use
request_irq() ?
  
Thanks,

	tglx

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-15 12:46     ` Thomas Gleixner
  0 siblings, 0 replies; 168+ messages in thread
From: Thomas Gleixner @ 2014-02-15 12:46 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-sh, linux-arm-kernel, linux-kernel, Daniel Lezcano

On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> CMT hardware devices can support multiple channels, with global
> registers and per-channel registers. The sh_cmt driver currently models
> the hardware with one Linux device per channel. This model makes it
> difficult to handle global registers in a clean way.
> 
> Add support for a new model that uses one Linux device per timer with
> multiple channels per device. This requires changes to platform data,
> add new channel configuration fields.
> 
> Support for the legacy model is kept and will be removed after all
> platforms switch to the new model.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++++++----------
>  include/linux/sh_timer.h     |   9 ++
>  2 files changed, 239 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
> index 5280231..8390f0f 100644
> --- a/drivers/clocksource/sh_cmt.c
> +++ b/drivers/clocksource/sh_cmt.c
> @@ -53,7 +53,16 @@ struct sh_cmt_device;
>   * channel registers block. All other versions have a shared start/stop register
>   * located in the global space.
>   *
> - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
> + * Channels are indexed from 0 to N-1 in the documentation. The channel index
> + * infers the start/stop bit position in the control register and the channel
> + * registers block address. Some CMT instances have a subset of channels
> + * available, in which case the index in the documentation doesn't match the
> + * "real" index as implemented in hardware. This is for instance the case with
> + * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
> + * in the documentation but using start/stop bit 5 and having its registers
> + * block at 0x60.
> + *
> + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
>   * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
>   */
>  
> @@ -85,11 +94,15 @@ struct sh_cmt_info {
>  
>  struct sh_cmt_channel {
>  	struct sh_cmt_device *cmt;
> -	unsigned int index;
>  
> -	void __iomem *base;
> +	unsigned int index;	/* Index in the documentation */
> +	unsigned int hwidx;	/* Real hardware index */
> +
> +	void __iomem *iostart;
> +	void __iomem *ioctrl;
>  	struct irqaction irqaction;

While you are at it, can you please get rid of that irqaction and use
request_irq() ?
  
Thanks,

	tglx

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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-15 12:46     ` Thomas Gleixner
  0 siblings, 0 replies; 168+ messages in thread
From: Thomas Gleixner @ 2014-02-15 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> CMT hardware devices can support multiple channels, with global
> registers and per-channel registers. The sh_cmt driver currently models
> the hardware with one Linux device per channel. This model makes it
> difficult to handle global registers in a clean way.
> 
> Add support for a new model that uses one Linux device per timer with
> multiple channels per device. This requires changes to platform data,
> add new channel configuration fields.
> 
> Support for the legacy model is kept and will be removed after all
> platforms switch to the new model.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++++++----------
>  include/linux/sh_timer.h     |   9 ++
>  2 files changed, 239 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
> index 5280231..8390f0f 100644
> --- a/drivers/clocksource/sh_cmt.c
> +++ b/drivers/clocksource/sh_cmt.c
> @@ -53,7 +53,16 @@ struct sh_cmt_device;
>   * channel registers block. All other versions have a shared start/stop register
>   * located in the global space.
>   *
> - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
> + * Channels are indexed from 0 to N-1 in the documentation. The channel index
> + * infers the start/stop bit position in the control register and the channel
> + * registers block address. Some CMT instances have a subset of channels
> + * available, in which case the index in the documentation doesn't match the
> + * "real" index as implemented in hardware. This is for instance the case with
> + * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
> + * in the documentation but using start/stop bit 5 and having its registers
> + * block at 0x60.
> + *
> + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
>   * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
>   */
>  
> @@ -85,11 +94,15 @@ struct sh_cmt_info {
>  
>  struct sh_cmt_channel {
>  	struct sh_cmt_device *cmt;
> -	unsigned int index;
>  
> -	void __iomem *base;
> +	unsigned int index;	/* Index in the documentation */
> +	unsigned int hwidx;	/* Real hardware index */
> +
> +	void __iomem *iostart;
> +	void __iomem *ioctrl;
>  	struct irqaction irqaction;

While you are at it, can you please get rid of that irqaction and use
request_irq() ?
  
Thanks,

	tglx

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-15 12:46     ` Thomas Gleixner
  (?)
@ 2014-02-16 18:18       ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-16 18:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> > CMT hardware devices can support multiple channels, with global
> > registers and per-channel registers. The sh_cmt driver currently models
> > the hardware with one Linux device per channel. This model makes it
> > difficult to handle global registers in a clean way.
> > 
> > Add support for a new model that uses one Linux device per timer with
> > multiple channels per device. This requires changes to platform data,
> > add new channel configuration fields.
> > 
> > Support for the legacy model is kept and will be removed after all
> > platforms switch to the new model.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++---------
> >  include/linux/sh_timer.h     |   9 ++
> >  2 files changed, 239 insertions(+), 69 deletions(-)
> > 
> > diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
> > index 5280231..8390f0f 100644
> > --- a/drivers/clocksource/sh_cmt.c
> > +++ b/drivers/clocksource/sh_cmt.c
> > @@ -53,7 +53,16 @@ struct sh_cmt_device;
> > 
> >   * channel registers block. All other versions have a shared start/stop
> >   register * located in the global space.
> >   *
> > 
> > - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
> > 32-bit + * Channels are indexed from 0 to N-1 in the documentation. The
> > channel index + * infers the start/stop bit position in the control
> > register and the channel + * registers block address. Some CMT instances
> > have a subset of channels + * available, in which case the index in the
> > documentation doesn't match the + * "real" index as implemented in
> > hardware. This is for instance the case with + * CMT0 on r8a7740, which
> > is a 32-bit variant with a single channel numbered 0 + * in the
> > documentation but using start/stop bit 5 and having its registers + *
> > block at 0x60.
> > + *
> > + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
> > 32-bit> 
> >   * channels only, is a 48-bit gen2 CMT with the 48-bit channels
> >   unavailable.
> >   */
> > 
> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> > 
> >  struct sh_cmt_channel {
> >  
> >  	struct sh_cmt_device *cmt;
> > 
> > -	unsigned int index;
> > 
> > -	void __iomem *base;
> > +	unsigned int index;	/* Index in the documentation */
> > +	unsigned int hwidx;	/* Real hardware index */
> > +
> > +	void __iomem *iostart;
> > +	void __iomem *ioctrl;
> > 
> >  	struct irqaction irqaction;
> 
> While you are at it, can you please get rid of that irqaction and use
> request_irq() ?

The driver claims it can't use request_irq() because the function is not 
available for early platform devices. If the situation has changed I'd gladly 
get rid of irqaction.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-16 18:18       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-16 18:18 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Laurent Pinchart, linux-sh, linux-arm-kernel, linux-kernel,
	Daniel Lezcano

Hi Thomas,

On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> > CMT hardware devices can support multiple channels, with global
> > registers and per-channel registers. The sh_cmt driver currently models
> > the hardware with one Linux device per channel. This model makes it
> > difficult to handle global registers in a clean way.
> > 
> > Add support for a new model that uses one Linux device per timer with
> > multiple channels per device. This requires changes to platform data,
> > add new channel configuration fields.
> > 
> > Support for the legacy model is kept and will be removed after all
> > platforms switch to the new model.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++---------
> >  include/linux/sh_timer.h     |   9 ++
> >  2 files changed, 239 insertions(+), 69 deletions(-)
> > 
> > diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
> > index 5280231..8390f0f 100644
> > --- a/drivers/clocksource/sh_cmt.c
> > +++ b/drivers/clocksource/sh_cmt.c
> > @@ -53,7 +53,16 @@ struct sh_cmt_device;
> > 
> >   * channel registers block. All other versions have a shared start/stop
> >   register * located in the global space.
> >   *
> > 
> > - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
> > 32-bit + * Channels are indexed from 0 to N-1 in the documentation. The
> > channel index + * infers the start/stop bit position in the control
> > register and the channel + * registers block address. Some CMT instances
> > have a subset of channels + * available, in which case the index in the
> > documentation doesn't match the + * "real" index as implemented in
> > hardware. This is for instance the case with + * CMT0 on r8a7740, which
> > is a 32-bit variant with a single channel numbered 0 + * in the
> > documentation but using start/stop bit 5 and having its registers + *
> > block at 0x60.
> > + *
> > + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
> > 32-bit> 
> >   * channels only, is a 48-bit gen2 CMT with the 48-bit channels
> >   unavailable.
> >   */
> > 
> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> > 
> >  struct sh_cmt_channel {
> >  
> >  	struct sh_cmt_device *cmt;
> > 
> > -	unsigned int index;
> > 
> > -	void __iomem *base;
> > +	unsigned int index;	/* Index in the documentation */
> > +	unsigned int hwidx;	/* Real hardware index */
> > +
> > +	void __iomem *iostart;
> > +	void __iomem *ioctrl;
> > 
> >  	struct irqaction irqaction;
> 
> While you are at it, can you please get rid of that irqaction and use
> request_irq() ?

The driver claims it can't use request_irq() because the function is not 
available for early platform devices. If the situation has changed I'd gladly 
get rid of irqaction.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-16 18:18       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-16 18:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> > CMT hardware devices can support multiple channels, with global
> > registers and per-channel registers. The sh_cmt driver currently models
> > the hardware with one Linux device per channel. This model makes it
> > difficult to handle global registers in a clean way.
> > 
> > Add support for a new model that uses one Linux device per timer with
> > multiple channels per device. This requires changes to platform data,
> > add new channel configuration fields.
> > 
> > Support for the legacy model is kept and will be removed after all
> > platforms switch to the new model.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++---------
> >  include/linux/sh_timer.h     |   9 ++
> >  2 files changed, 239 insertions(+), 69 deletions(-)
> > 
> > diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
> > index 5280231..8390f0f 100644
> > --- a/drivers/clocksource/sh_cmt.c
> > +++ b/drivers/clocksource/sh_cmt.c
> > @@ -53,7 +53,16 @@ struct sh_cmt_device;
> > 
> >   * channel registers block. All other versions have a shared start/stop
> >   register * located in the global space.
> >   *
> > 
> > - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
> > 32-bit + * Channels are indexed from 0 to N-1 in the documentation. The
> > channel index + * infers the start/stop bit position in the control
> > register and the channel + * registers block address. Some CMT instances
> > have a subset of channels + * available, in which case the index in the
> > documentation doesn't match the + * "real" index as implemented in
> > hardware. This is for instance the case with + * CMT0 on r8a7740, which
> > is a 32-bit variant with a single channel numbered 0 + * in the
> > documentation but using start/stop bit 5 and having its registers + *
> > block at 0x60.
> > + *
> > + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
> > 32-bit> 
> >   * channels only, is a 48-bit gen2 CMT with the 48-bit channels
> >   unavailable.
> >   */
> > 
> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> > 
> >  struct sh_cmt_channel {
> >  
> >  	struct sh_cmt_device *cmt;
> > 
> > -	unsigned int index;
> > 
> > -	void __iomem *base;
> > +	unsigned int index;	/* Index in the documentation */
> > +	unsigned int hwidx;	/* Real hardware index */
> > +
> > +	void __iomem *iostart;
> > +	void __iomem *ioctrl;
> > 
> >  	struct irqaction irqaction;
> 
> While you are at it, can you please get rid of that irqaction and use
> request_irq() ?

The driver claims it can't use request_irq() because the function is not 
available for early platform devices. If the situation has changed I'd gladly 
get rid of irqaction.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-16 18:18       ` Laurent Pinchart
  (?)
@ 2014-02-17  1:41         ` Magnus Damm
  -1 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  1:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Thomas,
>
> On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
>> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
>> > CMT hardware devices can support multiple channels, with global
>> > registers and per-channel registers. The sh_cmt driver currently models
>> > the hardware with one Linux device per channel. This model makes it
>> > difficult to handle global registers in a clean way.
>> >
>> > Add support for a new model that uses one Linux device per timer with
>> > multiple channels per device. This requires changes to platform data,
>> > add new channel configuration fields.
>> >
>> > Support for the legacy model is kept and will be removed after all
>> > platforms switch to the new model.
>> >
>> > Signed-off-by: Laurent Pinchart
>> > <laurent.pinchart+renesas@ideasonboard.com>
>> > ---
>> >
>> >  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++---------
>> >  include/linux/sh_timer.h     |   9 ++
>> >  2 files changed, 239 insertions(+), 69 deletions(-)
>> >
>> > diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
>> > index 5280231..8390f0f 100644
>> > --- a/drivers/clocksource/sh_cmt.c
>> > +++ b/drivers/clocksource/sh_cmt.c
>> > @@ -53,7 +53,16 @@ struct sh_cmt_device;
>> >
>> >   * channel registers block. All other versions have a shared start/stop
>> >   register * located in the global space.
>> >   *
>> >
>> > - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
>> > 32-bit + * Channels are indexed from 0 to N-1 in the documentation. The
>> > channel index + * infers the start/stop bit position in the control
>> > register and the channel + * registers block address. Some CMT instances
>> > have a subset of channels + * available, in which case the index in the
>> > documentation doesn't match the + * "real" index as implemented in
>> > hardware. This is for instance the case with + * CMT0 on r8a7740, which
>> > is a 32-bit variant with a single channel numbered 0 + * in the
>> > documentation but using start/stop bit 5 and having its registers + *
>> > block at 0x60.
>> > + *
>> > + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
>> > 32-bit>
>> >   * channels only, is a 48-bit gen2 CMT with the 48-bit channels
>> >   unavailable.
>> >   */
>> >
>> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
>> >
>> >  struct sh_cmt_channel {
>> >
>> >     struct sh_cmt_device *cmt;
>> >
>> > -   unsigned int index;
>> >
>> > -   void __iomem *base;
>> > +   unsigned int index;     /* Index in the documentation */
>> > +   unsigned int hwidx;     /* Real hardware index */
>> > +
>> > +   void __iomem *iostart;
>> > +   void __iomem *ioctrl;
>> >
>> >     struct irqaction irqaction;
>>
>> While you are at it, can you please get rid of that irqaction and use
>> request_irq() ?
>
> The driver claims it can't use request_irq() because the function is not
> available for early platform devices. If the situation has changed I'd gladly
> get rid of irqaction.

With the risk of stating the obvious, this depends on how early the
early platform device stuff is being run. The actual location may not
be the same on SH and ARM for instance.

On ARM we are doing all we can to initialize these devices as late as
ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
to remove the legacy ARM case then there is one less user of early
platform timers.

One perhaps reasonable way forward could be to use request_irq() in
case of DT and leave the legacy platform data case to rely on
irqaction.

Cheers,

/ magnus

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  1:41         ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  1:41 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Thomas Gleixner, Laurent Pinchart, SH-Linux, linux-arm-kernel,
	linux-kernel, Daniel Lezcano

Hi Laurent,

On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Thomas,
>
> On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
>> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
>> > CMT hardware devices can support multiple channels, with global
>> > registers and per-channel registers. The sh_cmt driver currently models
>> > the hardware with one Linux device per channel. This model makes it
>> > difficult to handle global registers in a clean way.
>> >
>> > Add support for a new model that uses one Linux device per timer with
>> > multiple channels per device. This requires changes to platform data,
>> > add new channel configuration fields.
>> >
>> > Support for the legacy model is kept and will be removed after all
>> > platforms switch to the new model.
>> >
>> > Signed-off-by: Laurent Pinchart
>> > <laurent.pinchart+renesas@ideasonboard.com>
>> > ---
>> >
>> >  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++---------
>> >  include/linux/sh_timer.h     |   9 ++
>> >  2 files changed, 239 insertions(+), 69 deletions(-)
>> >
>> > diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
>> > index 5280231..8390f0f 100644
>> > --- a/drivers/clocksource/sh_cmt.c
>> > +++ b/drivers/clocksource/sh_cmt.c
>> > @@ -53,7 +53,16 @@ struct sh_cmt_device;
>> >
>> >   * channel registers block. All other versions have a shared start/stop
>> >   register * located in the global space.
>> >   *
>> >
>> > - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
>> > 32-bit + * Channels are indexed from 0 to N-1 in the documentation. The
>> > channel index + * infers the start/stop bit position in the control
>> > register and the channel + * registers block address. Some CMT instances
>> > have a subset of channels + * available, in which case the index in the
>> > documentation doesn't match the + * "real" index as implemented in
>> > hardware. This is for instance the case with + * CMT0 on r8a7740, which
>> > is a 32-bit variant with a single channel numbered 0 + * in the
>> > documentation but using start/stop bit 5 and having its registers + *
>> > block at 0x60.
>> > + *
>> > + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
>> > 32-bit>
>> >   * channels only, is a 48-bit gen2 CMT with the 48-bit channels
>> >   unavailable.
>> >   */
>> >
>> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
>> >
>> >  struct sh_cmt_channel {
>> >
>> >     struct sh_cmt_device *cmt;
>> >
>> > -   unsigned int index;
>> >
>> > -   void __iomem *base;
>> > +   unsigned int index;     /* Index in the documentation */
>> > +   unsigned int hwidx;     /* Real hardware index */
>> > +
>> > +   void __iomem *iostart;
>> > +   void __iomem *ioctrl;
>> >
>> >     struct irqaction irqaction;
>>
>> While you are at it, can you please get rid of that irqaction and use
>> request_irq() ?
>
> The driver claims it can't use request_irq() because the function is not
> available for early platform devices. If the situation has changed I'd gladly
> get rid of irqaction.

With the risk of stating the obvious, this depends on how early the
early platform device stuff is being run. The actual location may not
be the same on SH and ARM for instance.

On ARM we are doing all we can to initialize these devices as late as
ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
to remove the legacy ARM case then there is one less user of early
platform timers.

One perhaps reasonable way forward could be to use request_irq() in
case of DT and leave the legacy platform data case to rely on
irqaction.

Cheers,

/ magnus

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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  1:41         ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  1:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Thomas,
>
> On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
>> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
>> > CMT hardware devices can support multiple channels, with global
>> > registers and per-channel registers. The sh_cmt driver currently models
>> > the hardware with one Linux device per channel. This model makes it
>> > difficult to handle global registers in a clean way.
>> >
>> > Add support for a new model that uses one Linux device per timer with
>> > multiple channels per device. This requires changes to platform data,
>> > add new channel configuration fields.
>> >
>> > Support for the legacy model is kept and will be removed after all
>> > platforms switch to the new model.
>> >
>> > Signed-off-by: Laurent Pinchart
>> > <laurent.pinchart+renesas@ideasonboard.com>
>> > ---
>> >
>> >  drivers/clocksource/sh_cmt.c | 299 +++++++++++++++++++++++++++++---------
>> >  include/linux/sh_timer.h     |   9 ++
>> >  2 files changed, 239 insertions(+), 69 deletions(-)
>> >
>> > diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
>> > index 5280231..8390f0f 100644
>> > --- a/drivers/clocksource/sh_cmt.c
>> > +++ b/drivers/clocksource/sh_cmt.c
>> > @@ -53,7 +53,16 @@ struct sh_cmt_device;
>> >
>> >   * channel registers block. All other versions have a shared start/stop
>> >   register * located in the global space.
>> >   *
>> >
>> > - * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
>> > 32-bit + * Channels are indexed from 0 to N-1 in the documentation. The
>> > channel index + * infers the start/stop bit position in the control
>> > register and the channel + * registers block address. Some CMT instances
>> > have a subset of channels + * available, in which case the index in the
>> > documentation doesn't match the + * "real" index as implemented in
>> > hardware. This is for instance the case with + * CMT0 on r8a7740, which
>> > is a 32-bit variant with a single channel numbered 0 + * in the
>> > documentation but using start/stop bit 5 and having its registers + *
>> > block at 0x60.
>> > + *
>> > + * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing
>> > 32-bit>
>> >   * channels only, is a 48-bit gen2 CMT with the 48-bit channels
>> >   unavailable.
>> >   */
>> >
>> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
>> >
>> >  struct sh_cmt_channel {
>> >
>> >     struct sh_cmt_device *cmt;
>> >
>> > -   unsigned int index;
>> >
>> > -   void __iomem *base;
>> > +   unsigned int index;     /* Index in the documentation */
>> > +   unsigned int hwidx;     /* Real hardware index */
>> > +
>> > +   void __iomem *iostart;
>> > +   void __iomem *ioctrl;
>> >
>> >     struct irqaction irqaction;
>>
>> While you are at it, can you please get rid of that irqaction and use
>> request_irq() ?
>
> The driver claims it can't use request_irq() because the function is not
> available for early platform devices. If the situation has changed I'd gladly
> get rid of irqaction.

With the risk of stating the obvious, this depends on how early the
early platform device stuff is being run. The actual location may not
be the same on SH and ARM for instance.

On ARM we are doing all we can to initialize these devices as late as
ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
to remove the legacy ARM case then there is one less user of early
platform timers.

One perhaps reasonable way forward could be to use request_irq() in
case of DT and leave the legacy platform data case to rely on
irqaction.

Cheers,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-14 17:22             ` Magnus Damm
  (?)
@ 2014-02-17  1:45               ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  1:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> >> > +Channels Optional Properties:
> >> >> > +
> >> >> > +  - clock-source-rating: rating of the timer as a clock source
> >> >> > device.
> >> >> > +  - clock-event-rating: rating of the timer as a clock event
> >> >> > device.
> >> >> 
> >> >> This feels like a leak of Linux internals. Why do you need this?
> >> > 
> >> > You're right, it is. The clock source and clock event ratings are
> >> > currently configured through platform data, I'll need to find a way to
> >> > compute them in the driver instead.
> >> 
> >> That would be very good!
> > 
> > Any pointer would be appreciated :-) How did you compute the various
> > ratings used in platform data all over the place ?
> 
> Historically we used the rating to select between CMT and TMU. For
> clock sources I suppose you also have the jiffy rating to consider.
> And for the SMP parts we have ARM IP for TWD and arch timers that have
> their ratings too. So you need to check all the timers on a particular
> system and consider what you want to have operating by default. The
> ARM IP timers should be preferred if available. For clock sources the
> rule is probably the higher resolution the better.
> 
> >> > There's still one piece of Linux-specific data I need though, as I need
> >> > to specify for each channel whether to use it as a clock source device,
> >> > a clock event device, both of them or none. That's configuration
> >> > information that needs to be provided somehow.
> >> 
> >> I think you can decide clock source or clock event assignment based on
> >> number of channels available. If you have only a single channel then both
> >> clock event and clock source need to be supported. Otherwise use one
> >> channel for clock source and the rest for clock events.
> > 
> > That won't match the current situation. Look at CMT0 in r8a7790 for
> > instance. There's two hardware channels available, and we only use the
> > first one, for clock events only.
> 
> You are correct. The reason for that is that the CMT driver today is
> optimized for combined clock event and clock source operation.
> 
> Historically the hardware it initially was written for (sh-mobile on
> the SH arch) only had a single timer channel so combined operation was
> required for tickless to work. But since you're asking how to allocate
> channels then I propose checking numbers of channels available and go
> from there. With that the r8a7790 support can only get better. =)
> 
> >> This is probably out of scope for this DT conversion, but it would be
> >> neat if you somehow could specify the CPU affinity for a channel to tie a
> >> clock event to an individual CPU core. This would make a a per-cpu timer
> >> unless I'm mistaken. But that's more of a software policy than anything
> >> else.
> > 
> > Yes, that's a configuration that needs to be specified somewhere. I don't
> > know where though.
> 
> As long as you have per-channel interrupts described in DT you can
> probably handle this in a generic way in the driver.

But how do we decide whether to use a single timer channel or one channel per 
CPU ? Will the kernel use one clock event device per CPU automatically ? I 
have to confess I have no idea how this works.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-17  1:45               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  1:45 UTC (permalink / raw)
  To: Magnus Damm
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Magnus,

On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> >> > +Channels Optional Properties:
> >> >> > +
> >> >> > +  - clock-source-rating: rating of the timer as a clock source
> >> >> > device.
> >> >> > +  - clock-event-rating: rating of the timer as a clock event
> >> >> > device.
> >> >> 
> >> >> This feels like a leak of Linux internals. Why do you need this?
> >> > 
> >> > You're right, it is. The clock source and clock event ratings are
> >> > currently configured through platform data, I'll need to find a way to
> >> > compute them in the driver instead.
> >> 
> >> That would be very good!
> > 
> > Any pointer would be appreciated :-) How did you compute the various
> > ratings used in platform data all over the place ?
> 
> Historically we used the rating to select between CMT and TMU. For
> clock sources I suppose you also have the jiffy rating to consider.
> And for the SMP parts we have ARM IP for TWD and arch timers that have
> their ratings too. So you need to check all the timers on a particular
> system and consider what you want to have operating by default. The
> ARM IP timers should be preferred if available. For clock sources the
> rule is probably the higher resolution the better.
> 
> >> > There's still one piece of Linux-specific data I need though, as I need
> >> > to specify for each channel whether to use it as a clock source device,
> >> > a clock event device, both of them or none. That's configuration
> >> > information that needs to be provided somehow.
> >> 
> >> I think you can decide clock source or clock event assignment based on
> >> number of channels available. If you have only a single channel then both
> >> clock event and clock source need to be supported. Otherwise use one
> >> channel for clock source and the rest for clock events.
> > 
> > That won't match the current situation. Look at CMT0 in r8a7790 for
> > instance. There's two hardware channels available, and we only use the
> > first one, for clock events only.
> 
> You are correct. The reason for that is that the CMT driver today is
> optimized for combined clock event and clock source operation.
> 
> Historically the hardware it initially was written for (sh-mobile on
> the SH arch) only had a single timer channel so combined operation was
> required for tickless to work. But since you're asking how to allocate
> channels then I propose checking numbers of channels available and go
> from there. With that the r8a7790 support can only get better. =)
> 
> >> This is probably out of scope for this DT conversion, but it would be
> >> neat if you somehow could specify the CPU affinity for a channel to tie a
> >> clock event to an individual CPU core. This would make a a per-cpu timer
> >> unless I'm mistaken. But that's more of a software policy than anything
> >> else.
> > 
> > Yes, that's a configuration that needs to be specified somewhere. I don't
> > know where though.
> 
> As long as you have per-channel interrupts described in DT you can
> probably handle this in a generic way in the driver.

But how do we decide whether to use a single timer channel or one channel per 
CPU ? Will the kernel use one clock event device per CPU automatically ? I 
have to confess I have no idea how this works.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-17  1:45               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  1:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> >> > +Channels Optional Properties:
> >> >> > +
> >> >> > +  - clock-source-rating: rating of the timer as a clock source
> >> >> > device.
> >> >> > +  - clock-event-rating: rating of the timer as a clock event
> >> >> > device.
> >> >> 
> >> >> This feels like a leak of Linux internals. Why do you need this?
> >> > 
> >> > You're right, it is. The clock source and clock event ratings are
> >> > currently configured through platform data, I'll need to find a way to
> >> > compute them in the driver instead.
> >> 
> >> That would be very good!
> > 
> > Any pointer would be appreciated :-) How did you compute the various
> > ratings used in platform data all over the place ?
> 
> Historically we used the rating to select between CMT and TMU. For
> clock sources I suppose you also have the jiffy rating to consider.
> And for the SMP parts we have ARM IP for TWD and arch timers that have
> their ratings too. So you need to check all the timers on a particular
> system and consider what you want to have operating by default. The
> ARM IP timers should be preferred if available. For clock sources the
> rule is probably the higher resolution the better.
> 
> >> > There's still one piece of Linux-specific data I need though, as I need
> >> > to specify for each channel whether to use it as a clock source device,
> >> > a clock event device, both of them or none. That's configuration
> >> > information that needs to be provided somehow.
> >> 
> >> I think you can decide clock source or clock event assignment based on
> >> number of channels available. If you have only a single channel then both
> >> clock event and clock source need to be supported. Otherwise use one
> >> channel for clock source and the rest for clock events.
> > 
> > That won't match the current situation. Look at CMT0 in r8a7790 for
> > instance. There's two hardware channels available, and we only use the
> > first one, for clock events only.
> 
> You are correct. The reason for that is that the CMT driver today is
> optimized for combined clock event and clock source operation.
> 
> Historically the hardware it initially was written for (sh-mobile on
> the SH arch) only had a single timer channel so combined operation was
> required for tickless to work. But since you're asking how to allocate
> channels then I propose checking numbers of channels available and go
> from there. With that the r8a7790 support can only get better. =)
> 
> >> This is probably out of scope for this DT conversion, but it would be
> >> neat if you somehow could specify the CPU affinity for a channel to tie a
> >> clock event to an individual CPU core. This would make a a per-cpu timer
> >> unless I'm mistaken. But that's more of a software policy than anything
> >> else.
> > 
> > Yes, that's a configuration that needs to be specified somewhere. I don't
> > know where though.
> 
> As long as you have per-channel interrupts described in DT you can
> probably handle this in a generic way in the driver.

But how do we decide whether to use a single timer channel or one channel per 
CPU ? Will the kernel use one clock event device per CPU automatically ? I 
have to confess I have no idea how this works.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-17  1:41         ` Magnus Damm
  (?)
@ 2014-02-17  1:48           ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  1:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> >> > CMT hardware devices can support multiple channels, with global
> >> > registers and per-channel registers. The sh_cmt driver currently models
> >> > the hardware with one Linux device per channel. This model makes it
> >> > difficult to handle global registers in a clean way.
> >> > 
> >> > Add support for a new model that uses one Linux device per timer with
> >> > multiple channels per device. This requires changes to platform data,
> >> > add new channel configuration fields.
> >> > 
> >> > Support for the legacy model is kept and will be removed after all
> >> > platforms switch to the new model.
> >> > 
> >> > Signed-off-by: Laurent Pinchart
> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> > ---
> >> > 
> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++++---------
> >> >  include/linux/sh_timer.h     |   9 ++
> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
> >> > 
> >> > diff --git a/drivers/clocksource/sh_cmt.c
> >> > b/drivers/clocksource/sh_cmt.c
> >> > index 5280231..8390f0f 100644
> >> > --- a/drivers/clocksource/sh_cmt.c
> >> > +++ b/drivers/clocksource/sh_cmt.c

[snip]

> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> >> > 
> >> >  struct sh_cmt_channel {
> >> >     struct sh_cmt_device *cmt;
> >> > -   unsigned int index;
> >> > -   void __iomem *base;
> >> > +   unsigned int index;     /* Index in the documentation */
> >> > +   unsigned int hwidx;     /* Real hardware index */
> >> > +
> >> > +   void __iomem *iostart;
> >> > +   void __iomem *ioctrl;
> >> > 
> >> >     struct irqaction irqaction;
> >> 
> >> While you are at it, can you please get rid of that irqaction and use
> >> request_irq() ?
> > 
> > The driver claims it can't use request_irq() because the function is not
> > available for early platform devices. If the situation has changed I'd
> > gladly get rid of irqaction.
> 
> With the risk of stating the obvious, this depends on how early the
> early platform device stuff is being run. The actual location may not
> be the same on SH and ARM for instance.
> 
> On ARM we are doing all we can to initialize these devices as late as
> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
> to remove the legacy ARM case then there is one less user of early
> platform timers.
> 
> One perhaps reasonable way forward could be to use request_irq() in
> case of DT and leave the legacy platform data case to rely on
> irqaction.

The whole point of switching from setup_irq() to request_irq() is to simplify 
the code. Adding request_irq() as an option would go in the opposite 
direction.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  1:48           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  1:48 UTC (permalink / raw)
  To: Magnus Damm
  Cc: Thomas Gleixner, Laurent Pinchart, SH-Linux, linux-arm-kernel,
	linux-kernel, Daniel Lezcano

Hi Magnus,

On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> >> > CMT hardware devices can support multiple channels, with global
> >> > registers and per-channel registers. The sh_cmt driver currently models
> >> > the hardware with one Linux device per channel. This model makes it
> >> > difficult to handle global registers in a clean way.
> >> > 
> >> > Add support for a new model that uses one Linux device per timer with
> >> > multiple channels per device. This requires changes to platform data,
> >> > add new channel configuration fields.
> >> > 
> >> > Support for the legacy model is kept and will be removed after all
> >> > platforms switch to the new model.
> >> > 
> >> > Signed-off-by: Laurent Pinchart
> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> > ---
> >> > 
> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++++---------
> >> >  include/linux/sh_timer.h     |   9 ++
> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
> >> > 
> >> > diff --git a/drivers/clocksource/sh_cmt.c
> >> > b/drivers/clocksource/sh_cmt.c
> >> > index 5280231..8390f0f 100644
> >> > --- a/drivers/clocksource/sh_cmt.c
> >> > +++ b/drivers/clocksource/sh_cmt.c

[snip]

> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> >> > 
> >> >  struct sh_cmt_channel {
> >> >     struct sh_cmt_device *cmt;
> >> > -   unsigned int index;
> >> > -   void __iomem *base;
> >> > +   unsigned int index;     /* Index in the documentation */
> >> > +   unsigned int hwidx;     /* Real hardware index */
> >> > +
> >> > +   void __iomem *iostart;
> >> > +   void __iomem *ioctrl;
> >> > 
> >> >     struct irqaction irqaction;
> >> 
> >> While you are at it, can you please get rid of that irqaction and use
> >> request_irq() ?
> > 
> > The driver claims it can't use request_irq() because the function is not
> > available for early platform devices. If the situation has changed I'd
> > gladly get rid of irqaction.
> 
> With the risk of stating the obvious, this depends on how early the
> early platform device stuff is being run. The actual location may not
> be the same on SH and ARM for instance.
> 
> On ARM we are doing all we can to initialize these devices as late as
> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
> to remove the legacy ARM case then there is one less user of early
> platform timers.
> 
> One perhaps reasonable way forward could be to use request_irq() in
> case of DT and leave the legacy platform data case to rely on
> irqaction.

The whole point of switching from setup_irq() to request_irq() is to simplify 
the code. Adding request_irq() as an option would go in the opposite 
direction.

-- 
Regards,

Laurent Pinchart


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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  1:48           ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  1:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> >> > CMT hardware devices can support multiple channels, with global
> >> > registers and per-channel registers. The sh_cmt driver currently models
> >> > the hardware with one Linux device per channel. This model makes it
> >> > difficult to handle global registers in a clean way.
> >> > 
> >> > Add support for a new model that uses one Linux device per timer with
> >> > multiple channels per device. This requires changes to platform data,
> >> > add new channel configuration fields.
> >> > 
> >> > Support for the legacy model is kept and will be removed after all
> >> > platforms switch to the new model.
> >> > 
> >> > Signed-off-by: Laurent Pinchart
> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> > ---
> >> > 
> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++++---------
> >> >  include/linux/sh_timer.h     |   9 ++
> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
> >> > 
> >> > diff --git a/drivers/clocksource/sh_cmt.c
> >> > b/drivers/clocksource/sh_cmt.c
> >> > index 5280231..8390f0f 100644
> >> > --- a/drivers/clocksource/sh_cmt.c
> >> > +++ b/drivers/clocksource/sh_cmt.c

[snip]

> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> >> > 
> >> >  struct sh_cmt_channel {
> >> >     struct sh_cmt_device *cmt;
> >> > -   unsigned int index;
> >> > -   void __iomem *base;
> >> > +   unsigned int index;     /* Index in the documentation */
> >> > +   unsigned int hwidx;     /* Real hardware index */
> >> > +
> >> > +   void __iomem *iostart;
> >> > +   void __iomem *ioctrl;
> >> > 
> >> >     struct irqaction irqaction;
> >> 
> >> While you are at it, can you please get rid of that irqaction and use
> >> request_irq() ?
> > 
> > The driver claims it can't use request_irq() because the function is not
> > available for early platform devices. If the situation has changed I'd
> > gladly get rid of irqaction.
> 
> With the risk of stating the obvious, this depends on how early the
> early platform device stuff is being run. The actual location may not
> be the same on SH and ARM for instance.
> 
> On ARM we are doing all we can to initialize these devices as late as
> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
> to remove the legacy ARM case then there is one less user of early
> platform timers.
> 
> One perhaps reasonable way forward could be to use request_irq() in
> case of DT and leave the legacy platform data case to rely on
> irqaction.

The whole point of switching from setup_irq() to request_irq() is to simplify 
the code. Adding request_irq() as an option would go in the opposite 
direction.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-17  1:45               ` Laurent Pinchart
  (?)
@ 2014-02-17  1:48                 ` Magnus Damm
  -1 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  1:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
>> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> >> > +Channels Optional Properties:
>> >> >> > +
>> >> >> > +  - clock-source-rating: rating of the timer as a clock source
>> >> >> > device.
>> >> >> > +  - clock-event-rating: rating of the timer as a clock event
>> >> >> > device.
>> >> >>
>> >> >> This feels like a leak of Linux internals. Why do you need this?
>> >> >
>> >> > You're right, it is. The clock source and clock event ratings are
>> >> > currently configured through platform data, I'll need to find a way to
>> >> > compute them in the driver instead.
>> >>
>> >> That would be very good!
>> >
>> > Any pointer would be appreciated :-) How did you compute the various
>> > ratings used in platform data all over the place ?
>>
>> Historically we used the rating to select between CMT and TMU. For
>> clock sources I suppose you also have the jiffy rating to consider.
>> And for the SMP parts we have ARM IP for TWD and arch timers that have
>> their ratings too. So you need to check all the timers on a particular
>> system and consider what you want to have operating by default. The
>> ARM IP timers should be preferred if available. For clock sources the
>> rule is probably the higher resolution the better.
>>
>> >> > There's still one piece of Linux-specific data I need though, as I need
>> >> > to specify for each channel whether to use it as a clock source device,
>> >> > a clock event device, both of them or none. That's configuration
>> >> > information that needs to be provided somehow.
>> >>
>> >> I think you can decide clock source or clock event assignment based on
>> >> number of channels available. If you have only a single channel then both
>> >> clock event and clock source need to be supported. Otherwise use one
>> >> channel for clock source and the rest for clock events.
>> >
>> > That won't match the current situation. Look at CMT0 in r8a7790 for
>> > instance. There's two hardware channels available, and we only use the
>> > first one, for clock events only.
>>
>> You are correct. The reason for that is that the CMT driver today is
>> optimized for combined clock event and clock source operation.
>>
>> Historically the hardware it initially was written for (sh-mobile on
>> the SH arch) only had a single timer channel so combined operation was
>> required for tickless to work. But since you're asking how to allocate
>> channels then I propose checking numbers of channels available and go
>> from there. With that the r8a7790 support can only get better. =)
>>
>> >> This is probably out of scope for this DT conversion, but it would be
>> >> neat if you somehow could specify the CPU affinity for a channel to tie a
>> >> clock event to an individual CPU core. This would make a a per-cpu timer
>> >> unless I'm mistaken. But that's more of a software policy than anything
>> >> else.
>> >
>> > Yes, that's a configuration that needs to be specified somewhere. I don't
>> > know where though.
>>
>> As long as you have per-channel interrupts described in DT you can
>> probably handle this in a generic way in the driver.
>
> But how do we decide whether to use a single timer channel or one channel per
> CPU ? Will the kernel use one clock event device per CPU automatically ? I
> have to confess I have no idea how this works.

I guess that's the tricky bit about timer support, it is a mix of
hardware description and software configuration. So it sounds to me
that we need some kind of software configuration interface. But it can
probably be considered when/if we add such kind of support to the
driver. Probably out of scope for now.

Regardless it seems to me that the hardware description in DT doesn't
need to care about this.

Cheers,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-17  1:48                 ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  1:48 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
>> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> >> > +Channels Optional Properties:
>> >> >> > +
>> >> >> > +  - clock-source-rating: rating of the timer as a clock source
>> >> >> > device.
>> >> >> > +  - clock-event-rating: rating of the timer as a clock event
>> >> >> > device.
>> >> >>
>> >> >> This feels like a leak of Linux internals. Why do you need this?
>> >> >
>> >> > You're right, it is. The clock source and clock event ratings are
>> >> > currently configured through platform data, I'll need to find a way to
>> >> > compute them in the driver instead.
>> >>
>> >> That would be very good!
>> >
>> > Any pointer would be appreciated :-) How did you compute the various
>> > ratings used in platform data all over the place ?
>>
>> Historically we used the rating to select between CMT and TMU. For
>> clock sources I suppose you also have the jiffy rating to consider.
>> And for the SMP parts we have ARM IP for TWD and arch timers that have
>> their ratings too. So you need to check all the timers on a particular
>> system and consider what you want to have operating by default. The
>> ARM IP timers should be preferred if available. For clock sources the
>> rule is probably the higher resolution the better.
>>
>> >> > There's still one piece of Linux-specific data I need though, as I need
>> >> > to specify for each channel whether to use it as a clock source device,
>> >> > a clock event device, both of them or none. That's configuration
>> >> > information that needs to be provided somehow.
>> >>
>> >> I think you can decide clock source or clock event assignment based on
>> >> number of channels available. If you have only a single channel then both
>> >> clock event and clock source need to be supported. Otherwise use one
>> >> channel for clock source and the rest for clock events.
>> >
>> > That won't match the current situation. Look at CMT0 in r8a7790 for
>> > instance. There's two hardware channels available, and we only use the
>> > first one, for clock events only.
>>
>> You are correct. The reason for that is that the CMT driver today is
>> optimized for combined clock event and clock source operation.
>>
>> Historically the hardware it initially was written for (sh-mobile on
>> the SH arch) only had a single timer channel so combined operation was
>> required for tickless to work. But since you're asking how to allocate
>> channels then I propose checking numbers of channels available and go
>> from there. With that the r8a7790 support can only get better. =)
>>
>> >> This is probably out of scope for this DT conversion, but it would be
>> >> neat if you somehow could specify the CPU affinity for a channel to tie a
>> >> clock event to an individual CPU core. This would make a a per-cpu timer
>> >> unless I'm mistaken. But that's more of a software policy than anything
>> >> else.
>> >
>> > Yes, that's a configuration that needs to be specified somewhere. I don't
>> > know where though.
>>
>> As long as you have per-channel interrupts described in DT you can
>> probably handle this in a generic way in the driver.
>
> But how do we decide whether to use a single timer channel or one channel per
> CPU ? Will the kernel use one clock event device per CPU automatically ? I
> have to confess I have no idea how this works.

I guess that's the tricky bit about timer support, it is a mix of
hardware description and software configuration. So it sounds to me
that we need some kind of software configuration interface. But it can
probably be considered when/if we add such kind of support to the
driver. Probably out of scope for now.

Regardless it seems to me that the hardware description in DT doesn't
need to care about this.

Cheers,

/ magnus

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-17  1:48                 ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  1:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
>> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> >> > +Channels Optional Properties:
>> >> >> > +
>> >> >> > +  - clock-source-rating: rating of the timer as a clock source
>> >> >> > device.
>> >> >> > +  - clock-event-rating: rating of the timer as a clock event
>> >> >> > device.
>> >> >>
>> >> >> This feels like a leak of Linux internals. Why do you need this?
>> >> >
>> >> > You're right, it is. The clock source and clock event ratings are
>> >> > currently configured through platform data, I'll need to find a way to
>> >> > compute them in the driver instead.
>> >>
>> >> That would be very good!
>> >
>> > Any pointer would be appreciated :-) How did you compute the various
>> > ratings used in platform data all over the place ?
>>
>> Historically we used the rating to select between CMT and TMU. For
>> clock sources I suppose you also have the jiffy rating to consider.
>> And for the SMP parts we have ARM IP for TWD and arch timers that have
>> their ratings too. So you need to check all the timers on a particular
>> system and consider what you want to have operating by default. The
>> ARM IP timers should be preferred if available. For clock sources the
>> rule is probably the higher resolution the better.
>>
>> >> > There's still one piece of Linux-specific data I need though, as I need
>> >> > to specify for each channel whether to use it as a clock source device,
>> >> > a clock event device, both of them or none. That's configuration
>> >> > information that needs to be provided somehow.
>> >>
>> >> I think you can decide clock source or clock event assignment based on
>> >> number of channels available. If you have only a single channel then both
>> >> clock event and clock source need to be supported. Otherwise use one
>> >> channel for clock source and the rest for clock events.
>> >
>> > That won't match the current situation. Look at CMT0 in r8a7790 for
>> > instance. There's two hardware channels available, and we only use the
>> > first one, for clock events only.
>>
>> You are correct. The reason for that is that the CMT driver today is
>> optimized for combined clock event and clock source operation.
>>
>> Historically the hardware it initially was written for (sh-mobile on
>> the SH arch) only had a single timer channel so combined operation was
>> required for tickless to work. But since you're asking how to allocate
>> channels then I propose checking numbers of channels available and go
>> from there. With that the r8a7790 support can only get better. =)
>>
>> >> This is probably out of scope for this DT conversion, but it would be
>> >> neat if you somehow could specify the CPU affinity for a channel to tie a
>> >> clock event to an individual CPU core. This would make a a per-cpu timer
>> >> unless I'm mistaken. But that's more of a software policy than anything
>> >> else.
>> >
>> > Yes, that's a configuration that needs to be specified somewhere. I don't
>> > know where though.
>>
>> As long as you have per-channel interrupts described in DT you can
>> probably handle this in a generic way in the driver.
>
> But how do we decide whether to use a single timer channel or one channel per
> CPU ? Will the kernel use one clock event device per CPU automatically ? I
> have to confess I have no idea how this works.

I guess that's the tricky bit about timer support, it is a mix of
hardware description and software configuration. So it sounds to me
that we need some kind of software configuration interface. But it can
probably be considered when/if we add such kind of support to the
driver. Probably out of scope for now.

Regardless it seems to me that the hardware description in DT doesn't
need to care about this.

Cheers,

/ magnus

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-17  1:48           ` Laurent Pinchart
  (?)
@ 2014-02-17  2:07             ` Magnus Damm
  -1 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 10:48 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
>> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
>> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
>> >> > CMT hardware devices can support multiple channels, with global
>> >> > registers and per-channel registers. The sh_cmt driver currently models
>> >> > the hardware with one Linux device per channel. This model makes it
>> >> > difficult to handle global registers in a clean way.
>> >> >
>> >> > Add support for a new model that uses one Linux device per timer with
>> >> > multiple channels per device. This requires changes to platform data,
>> >> > add new channel configuration fields.
>> >> >
>> >> > Support for the legacy model is kept and will be removed after all
>> >> > platforms switch to the new model.
>> >> >
>> >> > Signed-off-by: Laurent Pinchart
>> >> > <laurent.pinchart+renesas@ideasonboard.com>
>> >> > ---
>> >> >
>> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++++---------
>> >> >  include/linux/sh_timer.h     |   9 ++
>> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
>> >> >
>> >> > diff --git a/drivers/clocksource/sh_cmt.c
>> >> > b/drivers/clocksource/sh_cmt.c
>> >> > index 5280231..8390f0f 100644
>> >> > --- a/drivers/clocksource/sh_cmt.c
>> >> > +++ b/drivers/clocksource/sh_cmt.c
>
> [snip]
>
>> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
>> >> >
>> >> >  struct sh_cmt_channel {
>> >> >     struct sh_cmt_device *cmt;
>> >> > -   unsigned int index;
>> >> > -   void __iomem *base;
>> >> > +   unsigned int index;     /* Index in the documentation */
>> >> > +   unsigned int hwidx;     /* Real hardware index */
>> >> > +
>> >> > +   void __iomem *iostart;
>> >> > +   void __iomem *ioctrl;
>> >> >
>> >> >     struct irqaction irqaction;
>> >>
>> >> While you are at it, can you please get rid of that irqaction and use
>> >> request_irq() ?
>> >
>> > The driver claims it can't use request_irq() because the function is not
>> > available for early platform devices. If the situation has changed I'd
>> > gladly get rid of irqaction.
>>
>> With the risk of stating the obvious, this depends on how early the
>> early platform device stuff is being run. The actual location may not
>> be the same on SH and ARM for instance.
>>
>> On ARM we are doing all we can to initialize these devices as late as
>> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
>> to remove the legacy ARM case then there is one less user of early
>> platform timers.
>>
>> One perhaps reasonable way forward could be to use request_irq() in
>> case of DT and leave the legacy platform data case to rely on
>> irqaction.
>
> The whole point of switching from setup_irq() to request_irq() is to simplify
> the code. Adding request_irq() as an option would go in the opposite
> direction.

The point of switching to setup_irq() was not very clear to me. I
think it is fine to switch to using it over time, and I'm open to any
alternative ways forward. Usually moving in incremental steps means
more crap in the short term, but if someone could come up with a way
that involves little crap then I'm all for that! =)

Thanks,

/ magnus

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  2:07             ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  2:07 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Thomas Gleixner, Laurent Pinchart, SH-Linux, linux-arm-kernel,
	linux-kernel, Daniel Lezcano

Hi Laurent,

On Mon, Feb 17, 2014 at 10:48 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
>> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
>> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
>> >> > CMT hardware devices can support multiple channels, with global
>> >> > registers and per-channel registers. The sh_cmt driver currently models
>> >> > the hardware with one Linux device per channel. This model makes it
>> >> > difficult to handle global registers in a clean way.
>> >> >
>> >> > Add support for a new model that uses one Linux device per timer with
>> >> > multiple channels per device. This requires changes to platform data,
>> >> > add new channel configuration fields.
>> >> >
>> >> > Support for the legacy model is kept and will be removed after all
>> >> > platforms switch to the new model.
>> >> >
>> >> > Signed-off-by: Laurent Pinchart
>> >> > <laurent.pinchart+renesas@ideasonboard.com>
>> >> > ---
>> >> >
>> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++++---------
>> >> >  include/linux/sh_timer.h     |   9 ++
>> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
>> >> >
>> >> > diff --git a/drivers/clocksource/sh_cmt.c
>> >> > b/drivers/clocksource/sh_cmt.c
>> >> > index 5280231..8390f0f 100644
>> >> > --- a/drivers/clocksource/sh_cmt.c
>> >> > +++ b/drivers/clocksource/sh_cmt.c
>
> [snip]
>
>> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
>> >> >
>> >> >  struct sh_cmt_channel {
>> >> >     struct sh_cmt_device *cmt;
>> >> > -   unsigned int index;
>> >> > -   void __iomem *base;
>> >> > +   unsigned int index;     /* Index in the documentation */
>> >> > +   unsigned int hwidx;     /* Real hardware index */
>> >> > +
>> >> > +   void __iomem *iostart;
>> >> > +   void __iomem *ioctrl;
>> >> >
>> >> >     struct irqaction irqaction;
>> >>
>> >> While you are at it, can you please get rid of that irqaction and use
>> >> request_irq() ?
>> >
>> > The driver claims it can't use request_irq() because the function is not
>> > available for early platform devices. If the situation has changed I'd
>> > gladly get rid of irqaction.
>>
>> With the risk of stating the obvious, this depends on how early the
>> early platform device stuff is being run. The actual location may not
>> be the same on SH and ARM for instance.
>>
>> On ARM we are doing all we can to initialize these devices as late as
>> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
>> to remove the legacy ARM case then there is one less user of early
>> platform timers.
>>
>> One perhaps reasonable way forward could be to use request_irq() in
>> case of DT and leave the legacy platform data case to rely on
>> irqaction.
>
> The whole point of switching from setup_irq() to request_irq() is to simplify
> the code. Adding request_irq() as an option would go in the opposite
> direction.

The point of switching to setup_irq() was not very clear to me. I
think it is fine to switch to using it over time, and I'm open to any
alternative ways forward. Usually moving in incremental steps means
more crap in the short term, but if someone could come up with a way
that involves little crap then I'm all for that! =)

Thanks,

/ magnus

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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  2:07             ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-17  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Mon, Feb 17, 2014 at 10:48 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
>> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
>> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
>> >> > CMT hardware devices can support multiple channels, with global
>> >> > registers and per-channel registers. The sh_cmt driver currently models
>> >> > the hardware with one Linux device per channel. This model makes it
>> >> > difficult to handle global registers in a clean way.
>> >> >
>> >> > Add support for a new model that uses one Linux device per timer with
>> >> > multiple channels per device. This requires changes to platform data,
>> >> > add new channel configuration fields.
>> >> >
>> >> > Support for the legacy model is kept and will be removed after all
>> >> > platforms switch to the new model.
>> >> >
>> >> > Signed-off-by: Laurent Pinchart
>> >> > <laurent.pinchart+renesas@ideasonboard.com>
>> >> > ---
>> >> >
>> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++++---------
>> >> >  include/linux/sh_timer.h     |   9 ++
>> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
>> >> >
>> >> > diff --git a/drivers/clocksource/sh_cmt.c
>> >> > b/drivers/clocksource/sh_cmt.c
>> >> > index 5280231..8390f0f 100644
>> >> > --- a/drivers/clocksource/sh_cmt.c
>> >> > +++ b/drivers/clocksource/sh_cmt.c
>
> [snip]
>
>> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
>> >> >
>> >> >  struct sh_cmt_channel {
>> >> >     struct sh_cmt_device *cmt;
>> >> > -   unsigned int index;
>> >> > -   void __iomem *base;
>> >> > +   unsigned int index;     /* Index in the documentation */
>> >> > +   unsigned int hwidx;     /* Real hardware index */
>> >> > +
>> >> > +   void __iomem *iostart;
>> >> > +   void __iomem *ioctrl;
>> >> >
>> >> >     struct irqaction irqaction;
>> >>
>> >> While you are at it, can you please get rid of that irqaction and use
>> >> request_irq() ?
>> >
>> > The driver claims it can't use request_irq() because the function is not
>> > available for early platform devices. If the situation has changed I'd
>> > gladly get rid of irqaction.
>>
>> With the risk of stating the obvious, this depends on how early the
>> early platform device stuff is being run. The actual location may not
>> be the same on SH and ARM for instance.
>>
>> On ARM we are doing all we can to initialize these devices as late as
>> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
>> to remove the legacy ARM case then there is one less user of early
>> platform timers.
>>
>> One perhaps reasonable way forward could be to use request_irq() in
>> case of DT and leave the legacy platform data case to rely on
>> irqaction.
>
> The whole point of switching from setup_irq() to request_irq() is to simplify
> the code. Adding request_irq() as an option would go in the opposite
> direction.

The point of switching to setup_irq() was not very clear to me. I
think it is fine to switch to using it over time, and I'm open to any
alternative ways forward. Usually moving in incremental steps means
more crap in the short term, but if someone could come up with a way
that involves little crap then I'm all for that! =)

Thanks,

/ magnus

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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
  2014-02-17  2:07             ` Magnus Damm
  (?)
@ 2014-02-17  9:58               ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 11:07:06 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 10:48 AM, Laurent Pinchart wrote:
> > On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
> >> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> >> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> >> >> > CMT hardware devices can support multiple channels, with global
> >> >> > registers and per-channel registers. The sh_cmt driver currently
> >> >> > models the hardware with one Linux device per channel. This model
> >> >> > makes it difficult to handle global registers in a clean way.
> >> >> > 
> >> >> > Add support for a new model that uses one Linux device per timer
> >> >> > with multiple channels per device. This requires changes to platform
> >> >> > data, add new channel configuration fields.
> >> >> > 
> >> >> > Support for the legacy model is kept and will be removed after all
> >> >> > platforms switch to the new model.
> >> >> > 
> >> >> > Signed-off-by: Laurent Pinchart
> >> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> >> > ---
> >> >> > 
> >> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++--------
> >> >> >  include/linux/sh_timer.h     |   9 ++
> >> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
> >> >> > 
> >> >> > diff --git a/drivers/clocksource/sh_cmt.c
> >> >> > b/drivers/clocksource/sh_cmt.c
> >> >> > index 5280231..8390f0f 100644
> >> >> > --- a/drivers/clocksource/sh_cmt.c
> >> >> > +++ b/drivers/clocksource/sh_cmt.c
> > 
> > [snip]
> > 
> >> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> >> >> > 
> >> >> >  struct sh_cmt_channel {
> >> >> >     struct sh_cmt_device *cmt;
> >> >> > 
> >> >> > -   unsigned int index;
> >> >> > -   void __iomem *base;
> >> >> > +   unsigned int index;     /* Index in the documentation */
> >> >> > +   unsigned int hwidx;     /* Real hardware index */
> >> >> > +
> >> >> > +   void __iomem *iostart;
> >> >> > +   void __iomem *ioctrl;
> >> >> > 
> >> >> >     struct irqaction irqaction;
> >> >> 
> >> >> While you are at it, can you please get rid of that irqaction and use
> >> >> request_irq() ?
> >> > 
> >> > The driver claims it can't use request_irq() because the function is
> >> > not available for early platform devices. If the situation has changed
> >> > I'd gladly get rid of irqaction.
> >> 
> >> With the risk of stating the obvious, this depends on how early the
> >> early platform device stuff is being run. The actual location may not
> >> be the same on SH and ARM for instance.
> >> 
> >> On ARM we are doing all we can to initialize these devices as late as
> >> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
> >> to remove the legacy ARM case then there is one less user of early
> >> platform timers.
> >> 
> >> One perhaps reasonable way forward could be to use request_irq() in
> >> case of DT and leave the legacy platform data case to rely on
> >> irqaction.
> > 
> > The whole point of switching from setup_irq() to request_irq() is to
> > simplify the code. Adding request_irq() as an option would go in the
> > opposite direction.
> 
> The point of switching to setup_irq() was not very clear to me. I
> think it is fine to switch to using it over time, and I'm open to any
> alternative ways forward. Usually moving in incremental steps means
> more crap in the short term, but if someone could come up with a way
> that involves little crap then I'm all for that! =)

I've had a quick look at request_irq(). The function is defined as a static 
inline in include/linux/interrupt.h:

static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
            const char *name, void *dev)
{
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

request_threaded_irq() is implemented in kernel/irq/manage.c. I've removed the 
code paths that would never be taken when called by the sh_cmt driver, due to

- handler not being NULL
- thread_fn being NULL
- CONFIG_DEBUG_SHIRQ_FIXME not being set
- IRQF_SHARED not being set

int request_threaded_irq(unsigned int irq, irq_handler_t handler,
                         irq_handler_t thread_fn, unsigned long irqflags,
                         const char *devname, void *dev_id)
{
        struct irqaction *action;
        struct irq_desc *desc;
        int retval;

        desc = irq_to_desc(irq);
        if (!desc)
                return -EINVAL;

        if (!irq_settings_can_request(desc) ||
            WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;

        action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
        if (!action)
                return -ENOMEM;

        action->handler = handler;
        action->thread_fn = thread_fn;
        action->flags = irqflags;
        action->name = devname;
        action->dev_id = dev_id;

        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, action);
        chip_bus_sync_unlock(desc);

        if (retval)
                kfree(action);

        return retval;
}

setup_irq() is implemented in the same file as

int setup_irq(unsigned int irq, struct irqaction *act)
{
        int retval;
        struct irq_desc *desc = irq_to_desc(irq);

        if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;
        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, act);
        chip_bus_sync_unlock(desc);

        return retval;
}

The only two differences between request_irq() and setup_irq() would thus be

- the extra !irq_settings_can_request(desc) check
- the extra kzalloc() call

The former should only be true for chained IRQ handlers, which isn't the case 
here. The latter is just a kmalloc + kmap_atomic + memset as far as I can 
tell.

It thus seems safe to replace setup_irq() with request_irq().

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  9:58               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  9:58 UTC (permalink / raw)
  To: Magnus Damm
  Cc: Thomas Gleixner, Laurent Pinchart, SH-Linux, linux-arm-kernel,
	linux-kernel, Daniel Lezcano

Hi Magnus,

On Monday 17 February 2014 11:07:06 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 10:48 AM, Laurent Pinchart wrote:
> > On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
> >> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> >> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> >> >> > CMT hardware devices can support multiple channels, with global
> >> >> > registers and per-channel registers. The sh_cmt driver currently
> >> >> > models the hardware with one Linux device per channel. This model
> >> >> > makes it difficult to handle global registers in a clean way.
> >> >> > 
> >> >> > Add support for a new model that uses one Linux device per timer
> >> >> > with multiple channels per device. This requires changes to platform
> >> >> > data, add new channel configuration fields.
> >> >> > 
> >> >> > Support for the legacy model is kept and will be removed after all
> >> >> > platforms switch to the new model.
> >> >> > 
> >> >> > Signed-off-by: Laurent Pinchart
> >> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> >> > ---
> >> >> > 
> >> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++--------
> >> >> >  include/linux/sh_timer.h     |   9 ++
> >> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
> >> >> > 
> >> >> > diff --git a/drivers/clocksource/sh_cmt.c
> >> >> > b/drivers/clocksource/sh_cmt.c
> >> >> > index 5280231..8390f0f 100644
> >> >> > --- a/drivers/clocksource/sh_cmt.c
> >> >> > +++ b/drivers/clocksource/sh_cmt.c
> > 
> > [snip]
> > 
> >> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> >> >> > 
> >> >> >  struct sh_cmt_channel {
> >> >> >     struct sh_cmt_device *cmt;
> >> >> > 
> >> >> > -   unsigned int index;
> >> >> > -   void __iomem *base;
> >> >> > +   unsigned int index;     /* Index in the documentation */
> >> >> > +   unsigned int hwidx;     /* Real hardware index */
> >> >> > +
> >> >> > +   void __iomem *iostart;
> >> >> > +   void __iomem *ioctrl;
> >> >> > 
> >> >> >     struct irqaction irqaction;
> >> >> 
> >> >> While you are at it, can you please get rid of that irqaction and use
> >> >> request_irq() ?
> >> > 
> >> > The driver claims it can't use request_irq() because the function is
> >> > not available for early platform devices. If the situation has changed
> >> > I'd gladly get rid of irqaction.
> >> 
> >> With the risk of stating the obvious, this depends on how early the
> >> early platform device stuff is being run. The actual location may not
> >> be the same on SH and ARM for instance.
> >> 
> >> On ARM we are doing all we can to initialize these devices as late as
> >> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
> >> to remove the legacy ARM case then there is one less user of early
> >> platform timers.
> >> 
> >> One perhaps reasonable way forward could be to use request_irq() in
> >> case of DT and leave the legacy platform data case to rely on
> >> irqaction.
> > 
> > The whole point of switching from setup_irq() to request_irq() is to
> > simplify the code. Adding request_irq() as an option would go in the
> > opposite direction.
> 
> The point of switching to setup_irq() was not very clear to me. I
> think it is fine to switch to using it over time, and I'm open to any
> alternative ways forward. Usually moving in incremental steps means
> more crap in the short term, but if someone could come up with a way
> that involves little crap then I'm all for that! =)

I've had a quick look at request_irq(). The function is defined as a static 
inline in include/linux/interrupt.h:

static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
            const char *name, void *dev)
{
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

request_threaded_irq() is implemented in kernel/irq/manage.c. I've removed the 
code paths that would never be taken when called by the sh_cmt driver, due to

- handler not being NULL
- thread_fn being NULL
- CONFIG_DEBUG_SHIRQ_FIXME not being set
- IRQF_SHARED not being set

int request_threaded_irq(unsigned int irq, irq_handler_t handler,
                         irq_handler_t thread_fn, unsigned long irqflags,
                         const char *devname, void *dev_id)
{
        struct irqaction *action;
        struct irq_desc *desc;
        int retval;

        desc = irq_to_desc(irq);
        if (!desc)
                return -EINVAL;

        if (!irq_settings_can_request(desc) ||
            WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;

        action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
        if (!action)
                return -ENOMEM;

        action->handler = handler;
        action->thread_fn = thread_fn;
        action->flags = irqflags;
        action->name = devname;
        action->dev_id = dev_id;

        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, action);
        chip_bus_sync_unlock(desc);

        if (retval)
                kfree(action);

        return retval;
}

setup_irq() is implemented in the same file as

int setup_irq(unsigned int irq, struct irqaction *act)
{
        int retval;
        struct irq_desc *desc = irq_to_desc(irq);

        if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;
        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, act);
        chip_bus_sync_unlock(desc);

        return retval;
}

The only two differences between request_irq() and setup_irq() would thus be

- the extra !irq_settings_can_request(desc) check
- the extra kzalloc() call

The former should only be true for chained IRQ handlers, which isn't the case 
here. The latter is just a kmalloc + kmap_atomic + memset as far as I can 
tell.

It thus seems safe to replace setup_irq() with request_irq().

-- 
Regards,

Laurent Pinchart


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

* [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device
@ 2014-02-17  9:58               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 11:07:06 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 10:48 AM, Laurent Pinchart wrote:
> > On Monday 17 February 2014 10:41:31 Magnus Damm wrote:
> >> On Mon, Feb 17, 2014 at 3:18 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 13:46:54 Thomas Gleixner wrote:
> >> >> On Fri, 14 Feb 2014, Laurent Pinchart wrote:
> >> >> > CMT hardware devices can support multiple channels, with global
> >> >> > registers and per-channel registers. The sh_cmt driver currently
> >> >> > models the hardware with one Linux device per channel. This model
> >> >> > makes it difficult to handle global registers in a clean way.
> >> >> > 
> >> >> > Add support for a new model that uses one Linux device per timer
> >> >> > with multiple channels per device. This requires changes to platform
> >> >> > data, add new channel configuration fields.
> >> >> > 
> >> >> > Support for the legacy model is kept and will be removed after all
> >> >> > platforms switch to the new model.
> >> >> > 
> >> >> > Signed-off-by: Laurent Pinchart
> >> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> >> > ---
> >> >> > 
> >> >> >  drivers/clocksource/sh_cmt.c | 299 ++++++++++++++++++++++++--------
> >> >> >  include/linux/sh_timer.h     |   9 ++
> >> >> >  2 files changed, 239 insertions(+), 69 deletions(-)
> >> >> > 
> >> >> > diff --git a/drivers/clocksource/sh_cmt.c
> >> >> > b/drivers/clocksource/sh_cmt.c
> >> >> > index 5280231..8390f0f 100644
> >> >> > --- a/drivers/clocksource/sh_cmt.c
> >> >> > +++ b/drivers/clocksource/sh_cmt.c
> > 
> > [snip]
> > 
> >> >> > @@ -85,11 +94,15 @@ struct sh_cmt_info {
> >> >> > 
> >> >> >  struct sh_cmt_channel {
> >> >> >     struct sh_cmt_device *cmt;
> >> >> > 
> >> >> > -   unsigned int index;
> >> >> > -   void __iomem *base;
> >> >> > +   unsigned int index;     /* Index in the documentation */
> >> >> > +   unsigned int hwidx;     /* Real hardware index */
> >> >> > +
> >> >> > +   void __iomem *iostart;
> >> >> > +   void __iomem *ioctrl;
> >> >> > 
> >> >> >     struct irqaction irqaction;
> >> >> 
> >> >> While you are at it, can you please get rid of that irqaction and use
> >> >> request_irq() ?
> >> > 
> >> > The driver claims it can't use request_irq() because the function is
> >> > not available for early platform devices. If the situation has changed
> >> > I'd gladly get rid of irqaction.
> >> 
> >> With the risk of stating the obvious, this depends on how early the
> >> early platform device stuff is being run. The actual location may not
> >> be the same on SH and ARM for instance.
> >> 
> >> On ARM we are doing all we can to initialize these devices as late as
> >> ever possible in the MULTIPLAFORM (DT reference) case. Once we manage
> >> to remove the legacy ARM case then there is one less user of early
> >> platform timers.
> >> 
> >> One perhaps reasonable way forward could be to use request_irq() in
> >> case of DT and leave the legacy platform data case to rely on
> >> irqaction.
> > 
> > The whole point of switching from setup_irq() to request_irq() is to
> > simplify the code. Adding request_irq() as an option would go in the
> > opposite direction.
> 
> The point of switching to setup_irq() was not very clear to me. I
> think it is fine to switch to using it over time, and I'm open to any
> alternative ways forward. Usually moving in incremental steps means
> more crap in the short term, but if someone could come up with a way
> that involves little crap then I'm all for that! =)

I've had a quick look at request_irq(). The function is defined as a static 
inline in include/linux/interrupt.h:

static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
            const char *name, void *dev)
{
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

request_threaded_irq() is implemented in kernel/irq/manage.c. I've removed the 
code paths that would never be taken when called by the sh_cmt driver, due to

- handler not being NULL
- thread_fn being NULL
- CONFIG_DEBUG_SHIRQ_FIXME not being set
- IRQF_SHARED not being set

int request_threaded_irq(unsigned int irq, irq_handler_t handler,
                         irq_handler_t thread_fn, unsigned long irqflags,
                         const char *devname, void *dev_id)
{
        struct irqaction *action;
        struct irq_desc *desc;
        int retval;

        desc = irq_to_desc(irq);
        if (!desc)
                return -EINVAL;

        if (!irq_settings_can_request(desc) ||
            WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;

        action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
        if (!action)
                return -ENOMEM;

        action->handler = handler;
        action->thread_fn = thread_fn;
        action->flags = irqflags;
        action->name = devname;
        action->dev_id = dev_id;

        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, action);
        chip_bus_sync_unlock(desc);

        if (retval)
                kfree(action);

        return retval;
}

setup_irq() is implemented in the same file as

int setup_irq(unsigned int irq, struct irqaction *act)
{
        int retval;
        struct irq_desc *desc = irq_to_desc(irq);

        if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;
        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, act);
        chip_bus_sync_unlock(desc);

        return retval;
}

The only two differences between request_irq() and setup_irq() would thus be

- the extra !irq_settings_can_request(desc) check
- the extra kzalloc() call

The former should only be true for chained IRQ handlers, which isn't the case 
here. The latter is just a kmalloc + kmap_atomic + memset as far as I can 
tell.

It thus seems safe to replace setup_irq() with request_irq().

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-17  1:48                 ` Magnus Damm
  (?)
@ 2014-02-17 21:43                   ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17 21:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> >> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> >> >> > +Channels Optional Properties:
> >> >> >> > +
> >> >> >> > +  - clock-source-rating: rating of the timer as a clock source
> >> >> >> > device.
> >> >> >> > +  - clock-event-rating: rating of the timer as a clock event
> >> >> >> > device.
> >> >> >> 
> >> >> >> This feels like a leak of Linux internals. Why do you need this?
> >> >> > 
> >> >> > You're right, it is. The clock source and clock event ratings are
> >> >> > currently configured through platform data, I'll need to find a way
> >> >> > to compute them in the driver instead.
> >> >> 
> >> >> That would be very good!
> >> > 
> >> > Any pointer would be appreciated :-) How did you compute the various
> >> > ratings used in platform data all over the place ?
> >> 
> >> Historically we used the rating to select between CMT and TMU. For
> >> clock sources I suppose you also have the jiffy rating to consider.
> >> And for the SMP parts we have ARM IP for TWD and arch timers that have
> >> their ratings too. So you need to check all the timers on a particular
> >> system and consider what you want to have operating by default. The
> >> ARM IP timers should be preferred if available. For clock sources the
> >> rule is probably the higher resolution the better.
> >> 
> >> >> > There's still one piece of Linux-specific data I need though, as I
> >> >> > need to specify for each channel whether to use it as a clock source
> >> >> > device, a clock event device, both of them or none. That's
> >> >> > configuration information that needs to be provided somehow.
> >> >> 
> >> >> I think you can decide clock source or clock event assignment based on
> >> >> number of channels available. If you have only a single channel then
> >> >> both clock event and clock source need to be supported. Otherwise use
> >> >> one channel for clock source and the rest for clock events.
> >> > 
> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
> >> > instance. There's two hardware channels available, and we only use the
> >> > first one, for clock events only.
> >> 
> >> You are correct. The reason for that is that the CMT driver today is
> >> optimized for combined clock event and clock source operation.
> >> 
> >> Historically the hardware it initially was written for (sh-mobile on
> >> the SH arch) only had a single timer channel so combined operation was
> >> required for tickless to work. But since you're asking how to allocate
> >> channels then I propose checking numbers of channels available and go
> >> from there. With that the r8a7790 support can only get better. =)
> >> 
> >> >> This is probably out of scope for this DT conversion, but it would be
> >> >> neat if you somehow could specify the CPU affinity for a channel to
> >> >> tie a clock event to an individual CPU core. This would make a a per-
> >> >> cpu timer unless I'm mistaken. But that's more of a software policy
> >> >> than anything else.
> >> > 
> >> > Yes, that's a configuration that needs to be specified somewhere. I
> >> > don't know where though.
> >> 
> >> As long as you have per-channel interrupts described in DT you can
> >> probably handle this in a generic way in the driver.
> > 
> > But how do we decide whether to use a single timer channel or one channel
> > per CPU ? Will the kernel use one clock event device per CPU
> > automatically ? I have to confess I have no idea how this works.
> 
> I guess that's the tricky bit about timer support, it is a mix of
> hardware description and software configuration. So it sounds to me
> that we need some kind of software configuration interface. But it can
> probably be considered when/if we add such kind of support to the
> driver. Probably out of scope for now.
> 
> Regardless it seems to me that the hardware description in DT doesn't
> need to care about this.

I'll revisit that later. Per-CPU timers is not a high priority for now, so 
I'll just return -EAGAIN :-)

Nonetheless, specifying which timer channel to use as a clock source and which 
channel to use as a clock event device might need to be specified in DT (or 
somewhere else, but I'm not sure what other options we have here).

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-17 21:43                   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17 21:43 UTC (permalink / raw)
  To: Magnus Damm
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> >> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> >> >> > +Channels Optional Properties:
> >> >> >> > +
> >> >> >> > +  - clock-source-rating: rating of the timer as a clock source
> >> >> >> > device.
> >> >> >> > +  - clock-event-rating: rating of the timer as a clock event
> >> >> >> > device.
> >> >> >> 
> >> >> >> This feels like a leak of Linux internals. Why do you need this?
> >> >> > 
> >> >> > You're right, it is. The clock source and clock event ratings are
> >> >> > currently configured through platform data, I'll need to find a way
> >> >> > to compute them in the driver instead.
> >> >> 
> >> >> That would be very good!
> >> > 
> >> > Any pointer would be appreciated :-) How did you compute the various
> >> > ratings used in platform data all over the place ?
> >> 
> >> Historically we used the rating to select between CMT and TMU. For
> >> clock sources I suppose you also have the jiffy rating to consider.
> >> And for the SMP parts we have ARM IP for TWD and arch timers that have
> >> their ratings too. So you need to check all the timers on a particular
> >> system and consider what you want to have operating by default. The
> >> ARM IP timers should be preferred if available. For clock sources the
> >> rule is probably the higher resolution the better.
> >> 
> >> >> > There's still one piece of Linux-specific data I need though, as I
> >> >> > need to specify for each channel whether to use it as a clock source
> >> >> > device, a clock event device, both of them or none. That's
> >> >> > configuration information that needs to be provided somehow.
> >> >> 
> >> >> I think you can decide clock source or clock event assignment based on
> >> >> number of channels available. If you have only a single channel then
> >> >> both clock event and clock source need to be supported. Otherwise use
> >> >> one channel for clock source and the rest for clock events.
> >> > 
> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
> >> > instance. There's two hardware channels available, and we only use the
> >> > first one, for clock events only.
> >> 
> >> You are correct. The reason for that is that the CMT driver today is
> >> optimized for combined clock event and clock source operation.
> >> 
> >> Historically the hardware it initially was written for (sh-mobile on
> >> the SH arch) only had a single timer channel so combined operation was
> >> required for tickless to work. But since you're asking how to allocate
> >> channels then I propose checking numbers of channels available and go
> >> from there. With that the r8a7790 support can only get better. =)
> >> 
> >> >> This is probably out of scope for this DT conversion, but it would be
> >> >> neat if you somehow could specify the CPU affinity for a channel to
> >> >> tie a clock event to an individual CPU core. This would make a a per-
> >> >> cpu timer unless I'm mistaken. But that's more of a software policy
> >> >> than anything else.
> >> > 
> >> > Yes, that's a configuration that needs to be specified somewhere. I
> >> > don't know where though.
> >> 
> >> As long as you have per-channel interrupts described in DT you can
> >> probably handle this in a generic way in the driver.
> > 
> > But how do we decide whether to use a single timer channel or one channel
> > per CPU ? Will the kernel use one clock event device per CPU
> > automatically ? I have to confess I have no idea how this works.
> 
> I guess that's the tricky bit about timer support, it is a mix of
> hardware description and software configuration. So it sounds to me
> that we need some kind of software configuration interface. But it can
> probably be considered when/if we add such kind of support to the
> driver. Probably out of scope for now.
> 
> Regardless it seems to me that the hardware description in DT doesn't
> need to care about this.

I'll revisit that later. Per-CPU timers is not a high priority for now, so 
I'll just return -EAGAIN :-)

Nonetheless, specifying which timer channel to use as a clock source and which 
channel to use as a clock event device might need to be specified in DT (or 
somewhere else, but I'm not sure what other options we have here).

-- 
Regards,

Laurent Pinchart

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-17 21:43                   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-17 21:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
> >> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
> >> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
> >> >> >> > +Channels Optional Properties:
> >> >> >> > +
> >> >> >> > +  - clock-source-rating: rating of the timer as a clock source
> >> >> >> > device.
> >> >> >> > +  - clock-event-rating: rating of the timer as a clock event
> >> >> >> > device.
> >> >> >> 
> >> >> >> This feels like a leak of Linux internals. Why do you need this?
> >> >> > 
> >> >> > You're right, it is. The clock source and clock event ratings are
> >> >> > currently configured through platform data, I'll need to find a way
> >> >> > to compute them in the driver instead.
> >> >> 
> >> >> That would be very good!
> >> > 
> >> > Any pointer would be appreciated :-) How did you compute the various
> >> > ratings used in platform data all over the place ?
> >> 
> >> Historically we used the rating to select between CMT and TMU. For
> >> clock sources I suppose you also have the jiffy rating to consider.
> >> And for the SMP parts we have ARM IP for TWD and arch timers that have
> >> their ratings too. So you need to check all the timers on a particular
> >> system and consider what you want to have operating by default. The
> >> ARM IP timers should be preferred if available. For clock sources the
> >> rule is probably the higher resolution the better.
> >> 
> >> >> > There's still one piece of Linux-specific data I need though, as I
> >> >> > need to specify for each channel whether to use it as a clock source
> >> >> > device, a clock event device, both of them or none. That's
> >> >> > configuration information that needs to be provided somehow.
> >> >> 
> >> >> I think you can decide clock source or clock event assignment based on
> >> >> number of channels available. If you have only a single channel then
> >> >> both clock event and clock source need to be supported. Otherwise use
> >> >> one channel for clock source and the rest for clock events.
> >> > 
> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
> >> > instance. There's two hardware channels available, and we only use the
> >> > first one, for clock events only.
> >> 
> >> You are correct. The reason for that is that the CMT driver today is
> >> optimized for combined clock event and clock source operation.
> >> 
> >> Historically the hardware it initially was written for (sh-mobile on
> >> the SH arch) only had a single timer channel so combined operation was
> >> required for tickless to work. But since you're asking how to allocate
> >> channels then I propose checking numbers of channels available and go
> >> from there. With that the r8a7790 support can only get better. =)
> >> 
> >> >> This is probably out of scope for this DT conversion, but it would be
> >> >> neat if you somehow could specify the CPU affinity for a channel to
> >> >> tie a clock event to an individual CPU core. This would make a a per-
> >> >> cpu timer unless I'm mistaken. But that's more of a software policy
> >> >> than anything else.
> >> > 
> >> > Yes, that's a configuration that needs to be specified somewhere. I
> >> > don't know where though.
> >> 
> >> As long as you have per-channel interrupts described in DT you can
> >> probably handle this in a generic way in the driver.
> > 
> > But how do we decide whether to use a single timer channel or one channel
> > per CPU ? Will the kernel use one clock event device per CPU
> > automatically ? I have to confess I have no idea how this works.
> 
> I guess that's the tricky bit about timer support, it is a mix of
> hardware description and software configuration. So it sounds to me
> that we need some kind of software configuration interface. But it can
> probably be considered when/if we add such kind of support to the
> driver. Probably out of scope for now.
> 
> Regardless it seems to me that the hardware description in DT doesn't
> need to care about this.

I'll revisit that later. Per-CPU timers is not a high priority for now, so 
I'll just return -EAGAIN :-)

Nonetheless, specifying which timer channel to use as a clock source and which 
channel to use as a clock event device might need to be specified in DT (or 
somewhere else, but I'm not sure what other options we have here).

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-17 21:43                   ` Laurent Pinchart
  (?)
@ 2014-02-18  0:51                     ` Magnus Damm
  -1 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-18  0:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Tue, Feb 18, 2014 at 6:43 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
>> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
>> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
>> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> >> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> >> >> > +Channels Optional Properties:
>> >> >> >> > +
>> >> >> >> > +  - clock-source-rating: rating of the timer as a clock source
>> >> >> >> > device.
>> >> >> >> > +  - clock-event-rating: rating of the timer as a clock event
>> >> >> >> > device.
>> >> >> >>
>> >> >> >> This feels like a leak of Linux internals. Why do you need this?
>> >> >> >
>> >> >> > You're right, it is. The clock source and clock event ratings are
>> >> >> > currently configured through platform data, I'll need to find a way
>> >> >> > to compute them in the driver instead.
>> >> >>
>> >> >> That would be very good!
>> >> >
>> >> > Any pointer would be appreciated :-) How did you compute the various
>> >> > ratings used in platform data all over the place ?
>> >>
>> >> Historically we used the rating to select between CMT and TMU. For
>> >> clock sources I suppose you also have the jiffy rating to consider.
>> >> And for the SMP parts we have ARM IP for TWD and arch timers that have
>> >> their ratings too. So you need to check all the timers on a particular
>> >> system and consider what you want to have operating by default. The
>> >> ARM IP timers should be preferred if available. For clock sources the
>> >> rule is probably the higher resolution the better.
>> >>
>> >> >> > There's still one piece of Linux-specific data I need though, as I
>> >> >> > need to specify for each channel whether to use it as a clock source
>> >> >> > device, a clock event device, both of them or none. That's
>> >> >> > configuration information that needs to be provided somehow.
>> >> >>
>> >> >> I think you can decide clock source or clock event assignment based on
>> >> >> number of channels available. If you have only a single channel then
>> >> >> both clock event and clock source need to be supported. Otherwise use
>> >> >> one channel for clock source and the rest for clock events.
>> >> >
>> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
>> >> > instance. There's two hardware channels available, and we only use the
>> >> > first one, for clock events only.
>> >>
>> >> You are correct. The reason for that is that the CMT driver today is
>> >> optimized for combined clock event and clock source operation.
>> >>
>> >> Historically the hardware it initially was written for (sh-mobile on
>> >> the SH arch) only had a single timer channel so combined operation was
>> >> required for tickless to work. But since you're asking how to allocate
>> >> channels then I propose checking numbers of channels available and go
>> >> from there. With that the r8a7790 support can only get better. =)
>> >>
>> >> >> This is probably out of scope for this DT conversion, but it would be
>> >> >> neat if you somehow could specify the CPU affinity for a channel to
>> >> >> tie a clock event to an individual CPU core. This would make a a per-
>> >> >> cpu timer unless I'm mistaken. But that's more of a software policy
>> >> >> than anything else.
>> >> >
>> >> > Yes, that's a configuration that needs to be specified somewhere. I
>> >> > don't know where though.
>> >>
>> >> As long as you have per-channel interrupts described in DT you can
>> >> probably handle this in a generic way in the driver.
>> >
>> > But how do we decide whether to use a single timer channel or one channel
>> > per CPU ? Will the kernel use one clock event device per CPU
>> > automatically ? I have to confess I have no idea how this works.
>>
>> I guess that's the tricky bit about timer support, it is a mix of
>> hardware description and software configuration. So it sounds to me
>> that we need some kind of software configuration interface. But it can
>> probably be considered when/if we add such kind of support to the
>> driver. Probably out of scope for now.
>>
>> Regardless it seems to me that the hardware description in DT doesn't
>> need to care about this.
>
> I'll revisit that later. Per-CPU timers is not a high priority for now, so
> I'll just return -EAGAIN :-)

Thanks, that's fine.

> Nonetheless, specifying which timer channel to use as a clock source and which
> channel to use as a clock event device might need to be specified in DT (or
> somewhere else, but I'm not sure what other options we have here).

I disagree about the need for specifying clock source or clock event
channel in DT.  Since per-cpu timers is out of scope for now then why
don't we simply just let the driver automatically allocate the during
run-time?

In case one CMT channel exists:
Use that for both clock source and clock event.

In case more than one CMT channel exists:
Use one separate channel for clock source and one separate channel for
clock event.

That would cover our existing use case, no?

Thanks,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-18  0:51                     ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-18  0:51 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Laurent,

On Tue, Feb 18, 2014 at 6:43 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
>> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
>> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
>> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> >> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> >> >> > +Channels Optional Properties:
>> >> >> >> > +
>> >> >> >> > +  - clock-source-rating: rating of the timer as a clock source
>> >> >> >> > device.
>> >> >> >> > +  - clock-event-rating: rating of the timer as a clock event
>> >> >> >> > device.
>> >> >> >>
>> >> >> >> This feels like a leak of Linux internals. Why do you need this?
>> >> >> >
>> >> >> > You're right, it is. The clock source and clock event ratings are
>> >> >> > currently configured through platform data, I'll need to find a way
>> >> >> > to compute them in the driver instead.
>> >> >>
>> >> >> That would be very good!
>> >> >
>> >> > Any pointer would be appreciated :-) How did you compute the various
>> >> > ratings used in platform data all over the place ?
>> >>
>> >> Historically we used the rating to select between CMT and TMU. For
>> >> clock sources I suppose you also have the jiffy rating to consider.
>> >> And for the SMP parts we have ARM IP for TWD and arch timers that have
>> >> their ratings too. So you need to check all the timers on a particular
>> >> system and consider what you want to have operating by default. The
>> >> ARM IP timers should be preferred if available. For clock sources the
>> >> rule is probably the higher resolution the better.
>> >>
>> >> >> > There's still one piece of Linux-specific data I need though, as I
>> >> >> > need to specify for each channel whether to use it as a clock source
>> >> >> > device, a clock event device, both of them or none. That's
>> >> >> > configuration information that needs to be provided somehow.
>> >> >>
>> >> >> I think you can decide clock source or clock event assignment based on
>> >> >> number of channels available. If you have only a single channel then
>> >> >> both clock event and clock source need to be supported. Otherwise use
>> >> >> one channel for clock source and the rest for clock events.
>> >> >
>> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
>> >> > instance. There's two hardware channels available, and we only use the
>> >> > first one, for clock events only.
>> >>
>> >> You are correct. The reason for that is that the CMT driver today is
>> >> optimized for combined clock event and clock source operation.
>> >>
>> >> Historically the hardware it initially was written for (sh-mobile on
>> >> the SH arch) only had a single timer channel so combined operation was
>> >> required for tickless to work. But since you're asking how to allocate
>> >> channels then I propose checking numbers of channels available and go
>> >> from there. With that the r8a7790 support can only get better. =)
>> >>
>> >> >> This is probably out of scope for this DT conversion, but it would be
>> >> >> neat if you somehow could specify the CPU affinity for a channel to
>> >> >> tie a clock event to an individual CPU core. This would make a a per-
>> >> >> cpu timer unless I'm mistaken. But that's more of a software policy
>> >> >> than anything else.
>> >> >
>> >> > Yes, that's a configuration that needs to be specified somewhere. I
>> >> > don't know where though.
>> >>
>> >> As long as you have per-channel interrupts described in DT you can
>> >> probably handle this in a generic way in the driver.
>> >
>> > But how do we decide whether to use a single timer channel or one channel
>> > per CPU ? Will the kernel use one clock event device per CPU
>> > automatically ? I have to confess I have no idea how this works.
>>
>> I guess that's the tricky bit about timer support, it is a mix of
>> hardware description and software configuration. So it sounds to me
>> that we need some kind of software configuration interface. But it can
>> probably be considered when/if we add such kind of support to the
>> driver. Probably out of scope for now.
>>
>> Regardless it seems to me that the hardware description in DT doesn't
>> need to care about this.
>
> I'll revisit that later. Per-CPU timers is not a high priority for now, so
> I'll just return -EAGAIN :-)

Thanks, that's fine.

> Nonetheless, specifying which timer channel to use as a clock source and which
> channel to use as a clock event device might need to be specified in DT (or
> somewhere else, but I'm not sure what other options we have here).

I disagree about the need for specifying clock source or clock event
channel in DT.  Since per-cpu timers is out of scope for now then why
don't we simply just let the driver automatically allocate the during
run-time?

In case one CMT channel exists:
Use that for both clock source and clock event.

In case more than one CMT channel exists:
Use one separate channel for clock source and one separate channel for
clock event.

That would cover our existing use case, no?

Thanks,

/ magnus

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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-18  0:51                     ` Magnus Damm
  0 siblings, 0 replies; 168+ messages in thread
From: Magnus Damm @ 2014-02-18  0:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On Tue, Feb 18, 2014 at 6:43 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Magnus,
>
> On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
>> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
>> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
>> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
>> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
>> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:
>> >> >> > On Friday 14 February 2014 10:58:22 Mark Rutland wrote:
>> >> >> >> On Fri, Feb 14, 2014 at 01:00:01AM +0000, Laurent Pinchart wrote:
>> >> >> >> > +Channels Optional Properties:
>> >> >> >> > +
>> >> >> >> > +  - clock-source-rating: rating of the timer as a clock source
>> >> >> >> > device.
>> >> >> >> > +  - clock-event-rating: rating of the timer as a clock event
>> >> >> >> > device.
>> >> >> >>
>> >> >> >> This feels like a leak of Linux internals. Why do you need this?
>> >> >> >
>> >> >> > You're right, it is. The clock source and clock event ratings are
>> >> >> > currently configured through platform data, I'll need to find a way
>> >> >> > to compute them in the driver instead.
>> >> >>
>> >> >> That would be very good!
>> >> >
>> >> > Any pointer would be appreciated :-) How did you compute the various
>> >> > ratings used in platform data all over the place ?
>> >>
>> >> Historically we used the rating to select between CMT and TMU. For
>> >> clock sources I suppose you also have the jiffy rating to consider.
>> >> And for the SMP parts we have ARM IP for TWD and arch timers that have
>> >> their ratings too. So you need to check all the timers on a particular
>> >> system and consider what you want to have operating by default. The
>> >> ARM IP timers should be preferred if available. For clock sources the
>> >> rule is probably the higher resolution the better.
>> >>
>> >> >> > There's still one piece of Linux-specific data I need though, as I
>> >> >> > need to specify for each channel whether to use it as a clock source
>> >> >> > device, a clock event device, both of them or none. That's
>> >> >> > configuration information that needs to be provided somehow.
>> >> >>
>> >> >> I think you can decide clock source or clock event assignment based on
>> >> >> number of channels available. If you have only a single channel then
>> >> >> both clock event and clock source need to be supported. Otherwise use
>> >> >> one channel for clock source and the rest for clock events.
>> >> >
>> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
>> >> > instance. There's two hardware channels available, and we only use the
>> >> > first one, for clock events only.
>> >>
>> >> You are correct. The reason for that is that the CMT driver today is
>> >> optimized for combined clock event and clock source operation.
>> >>
>> >> Historically the hardware it initially was written for (sh-mobile on
>> >> the SH arch) only had a single timer channel so combined operation was
>> >> required for tickless to work. But since you're asking how to allocate
>> >> channels then I propose checking numbers of channels available and go
>> >> from there. With that the r8a7790 support can only get better. =)
>> >>
>> >> >> This is probably out of scope for this DT conversion, but it would be
>> >> >> neat if you somehow could specify the CPU affinity for a channel to
>> >> >> tie a clock event to an individual CPU core. This would make a a per-
>> >> >> cpu timer unless I'm mistaken. But that's more of a software policy
>> >> >> than anything else.
>> >> >
>> >> > Yes, that's a configuration that needs to be specified somewhere. I
>> >> > don't know where though.
>> >>
>> >> As long as you have per-channel interrupts described in DT you can
>> >> probably handle this in a generic way in the driver.
>> >
>> > But how do we decide whether to use a single timer channel or one channel
>> > per CPU ? Will the kernel use one clock event device per CPU
>> > automatically ? I have to confess I have no idea how this works.
>>
>> I guess that's the tricky bit about timer support, it is a mix of
>> hardware description and software configuration. So it sounds to me
>> that we need some kind of software configuration interface. But it can
>> probably be considered when/if we add such kind of support to the
>> driver. Probably out of scope for now.
>>
>> Regardless it seems to me that the hardware description in DT doesn't
>> need to care about this.
>
> I'll revisit that later. Per-CPU timers is not a high priority for now, so
> I'll just return -EAGAIN :-)

Thanks, that's fine.

> Nonetheless, specifying which timer channel to use as a clock source and which
> channel to use as a clock event device might need to be specified in DT (or
> somewhere else, but I'm not sure what other options we have here).

I disagree about the need for specifying clock source or clock event
channel in DT.  Since per-cpu timers is out of scope for now then why
don't we simply just let the driver automatically allocate the during
run-time?

In case one CMT channel exists:
Use that for both clock source and clock event.

In case more than one CMT channel exists:
Use one separate channel for clock source and one separate channel for
clock event.

That would cover our existing use case, no?

Thanks,

/ magnus

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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
  2014-02-18  0:51                     ` Magnus Damm
  (?)
@ 2014-02-18 11:45                       ` Laurent Pinchart
  -1 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-18 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Tuesday 18 February 2014 09:51:30 Magnus Damm wrote:
> On Tue, Feb 18, 2014 at 6:43 AM, Laurent Pinchart wrote:
> > On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
> >> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> >> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> >> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:

[snip]

> >> >> >> > There's still one piece of Linux-specific data I need though, as
> >> >> >> > I need to specify for each channel whether to use it as a clock
> >> >> >> > source device, a clock event device, both of them or none. That's
> >> >> >> > configuration information that needs to be provided somehow.
> >> >> >> 
> >> >> >> I think you can decide clock source or clock event assignment based
> >> >> >> on number of channels available. If you have only a single channel
> >> >> >> then both clock event and clock source need to be supported.
> >> >> >> Otherwise use one channel for clock source and the rest for clock
> >> >> >> events.
> >> >> > 
> >> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
> >> >> > instance. There's two hardware channels available, and we only use
> >> >> > the first one, for clock events only.
> >> >> 
> >> >> You are correct. The reason for that is that the CMT driver today is
> >> >> optimized for combined clock event and clock source operation.
> >> >> 
> >> >> Historically the hardware it initially was written for (sh-mobile on
> >> >> the SH arch) only had a single timer channel so combined operation was
> >> >> required for tickless to work. But since you're asking how to allocate
> >> >> channels then I propose checking numbers of channels available and go
> >> >> from there. With that the r8a7790 support can only get better. =)

[snip]

> > Nonetheless, specifying which timer channel to use as a clock source and
> > which channel to use as a clock event device might need to be specified
> > in DT (or somewhere else, but I'm not sure what other options we have
> > here).
>
> I disagree about the need for specifying clock source or clock event channel
> in DT.  Since per-cpu timers is out of scope for now then why don't we
> simply just let the driver automatically allocate the during run-time?
> 
> In case one CMT channel exists:
> Use that for both clock source and clock event.
> 
> In case more than one CMT channel exists:
> Use one separate channel for clock source and one separate channel for clock
> event.
> 
> That would cover our existing use case, no?

One of the issues with that approach is that the decision on what to use a 
channel for will be taken locally from a timer point of view, without a global 
system-wide view. When more than one timer is available for a given platform 
(several CMT instances for instance, or CMT + TMU) the driver will decide on 
how to configure each instance without taking the other timers into account. 
Beside leading to creating more clock sources and clock event devices than 
today (is that a problem ?), couldn't it also lead to taking sub-optimal 
decisions ?

You also mentioned that only a subset of channels have the ability to run 
during sleep states. I suppose this needs to be taken into account as well. 
Could you please elaborate on our requirements in that area ?

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-18 11:45                       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-18 11:45 UTC (permalink / raw)
  To: Magnus Damm
  Cc: Mark Rutland, Laurent Pinchart, linux-sh, Thomas Gleixner,
	Daniel Lezcano, linux-kernel, linux-arm-kernel

Hi Magnus,

On Tuesday 18 February 2014 09:51:30 Magnus Damm wrote:
> On Tue, Feb 18, 2014 at 6:43 AM, Laurent Pinchart wrote:
> > On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
> >> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> >> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> >> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:

[snip]

> >> >> >> > There's still one piece of Linux-specific data I need though, as
> >> >> >> > I need to specify for each channel whether to use it as a clock
> >> >> >> > source device, a clock event device, both of them or none. That's
> >> >> >> > configuration information that needs to be provided somehow.
> >> >> >> 
> >> >> >> I think you can decide clock source or clock event assignment based
> >> >> >> on number of channels available. If you have only a single channel
> >> >> >> then both clock event and clock source need to be supported.
> >> >> >> Otherwise use one channel for clock source and the rest for clock
> >> >> >> events.
> >> >> > 
> >> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
> >> >> > instance. There's two hardware channels available, and we only use
> >> >> > the first one, for clock events only.
> >> >> 
> >> >> You are correct. The reason for that is that the CMT driver today is
> >> >> optimized for combined clock event and clock source operation.
> >> >> 
> >> >> Historically the hardware it initially was written for (sh-mobile on
> >> >> the SH arch) only had a single timer channel so combined operation was
> >> >> required for tickless to work. But since you're asking how to allocate
> >> >> channels then I propose checking numbers of channels available and go
> >> >> from there. With that the r8a7790 support can only get better. =)

[snip]

> > Nonetheless, specifying which timer channel to use as a clock source and
> > which channel to use as a clock event device might need to be specified
> > in DT (or somewhere else, but I'm not sure what other options we have
> > here).
>
> I disagree about the need for specifying clock source or clock event channel
> in DT.  Since per-cpu timers is out of scope for now then why don't we
> simply just let the driver automatically allocate the during run-time?
> 
> In case one CMT channel exists:
> Use that for both clock source and clock event.
> 
> In case more than one CMT channel exists:
> Use one separate channel for clock source and one separate channel for clock
> event.
> 
> That would cover our existing use case, no?

One of the issues with that approach is that the decision on what to use a 
channel for will be taken locally from a timer point of view, without a global 
system-wide view. When more than one timer is available for a given platform 
(several CMT instances for instance, or CMT + TMU) the driver will decide on 
how to configure each instance without taking the other timers into account. 
Beside leading to creating more clock sources and clock event devices than 
today (is that a problem ?), couldn't it also lead to taking sub-optimal 
decisions ?

You also mentioned that only a subset of channels have the ability to run 
during sleep states. I suppose this needs to be taken into account as well. 
Could you please elaborate on our requirements in that area ?

-- 
Regards,

Laurent Pinchart


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

* [PATCH 23/27] clocksource: sh_cmt: Add DT support
@ 2014-02-18 11:45                       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2014-02-18 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On Tuesday 18 February 2014 09:51:30 Magnus Damm wrote:
> On Tue, Feb 18, 2014 at 6:43 AM, Laurent Pinchart wrote:
> > On Monday 17 February 2014 10:48:55 Magnus Damm wrote:
> >> On Mon, Feb 17, 2014 at 10:45 AM, Laurent Pinchart wrote:
> >> > On Saturday 15 February 2014 02:22:00 Magnus Damm wrote:
> >> >> On Sat, Feb 15, 2014 at 1:12 AM, Laurent Pinchart wrote:
> >> >> > On Saturday 15 February 2014 01:01:30 Magnus Damm wrote:
> >> >> >> On Sat, Feb 15, 2014 at 12:53 AM, Laurent Pinchart wrote:

[snip]

> >> >> >> > There's still one piece of Linux-specific data I need though, as
> >> >> >> > I need to specify for each channel whether to use it as a clock
> >> >> >> > source device, a clock event device, both of them or none. That's
> >> >> >> > configuration information that needs to be provided somehow.
> >> >> >> 
> >> >> >> I think you can decide clock source or clock event assignment based
> >> >> >> on number of channels available. If you have only a single channel
> >> >> >> then both clock event and clock source need to be supported.
> >> >> >> Otherwise use one channel for clock source and the rest for clock
> >> >> >> events.
> >> >> > 
> >> >> > That won't match the current situation. Look at CMT0 in r8a7790 for
> >> >> > instance. There's two hardware channels available, and we only use
> >> >> > the first one, for clock events only.
> >> >> 
> >> >> You are correct. The reason for that is that the CMT driver today is
> >> >> optimized for combined clock event and clock source operation.
> >> >> 
> >> >> Historically the hardware it initially was written for (sh-mobile on
> >> >> the SH arch) only had a single timer channel so combined operation was
> >> >> required for tickless to work. But since you're asking how to allocate
> >> >> channels then I propose checking numbers of channels available and go
> >> >> from there. With that the r8a7790 support can only get better. =)

[snip]

> > Nonetheless, specifying which timer channel to use as a clock source and
> > which channel to use as a clock event device might need to be specified
> > in DT (or somewhere else, but I'm not sure what other options we have
> > here).
>
> I disagree about the need for specifying clock source or clock event channel
> in DT.  Since per-cpu timers is out of scope for now then why don't we
> simply just let the driver automatically allocate the during run-time?
> 
> In case one CMT channel exists:
> Use that for both clock source and clock event.
> 
> In case more than one CMT channel exists:
> Use one separate channel for clock source and one separate channel for clock
> event.
> 
> That would cover our existing use case, no?

One of the issues with that approach is that the decision on what to use a 
channel for will be taken locally from a timer point of view, without a global 
system-wide view. When more than one timer is available for a given platform 
(several CMT instances for instance, or CMT + TMU) the driver will decide on 
how to configure each instance without taking the other timers into account. 
Beside leading to creating more clock sources and clock event devices than 
today (is that a problem ?), couldn't it also lead to taking sub-optimal 
decisions ?

You also mentioned that only a subset of channels have the ability to run 
during sleep states. I suppose this needs to be taken into account as well. 
Could you please elaborate on our requirements in that area ?

-- 
Regards,

Laurent Pinchart

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

end of thread, other threads:[~2014-02-18 11:45 UTC | newest]

Thread overview: 168+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-14  0:59 [PATCH 00/27] Renesas CMT (Compare Match Timer) DT bindings Laurent Pinchart
2014-02-14  0:59 ` Laurent Pinchart
2014-02-14  0:59 ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 01/27] clocksource: sh_cmt: Split channel fields from sh_cmt_priv Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 02/27] clocksource: sh_cmt: Rename struct sh_cmt_priv to sh_cmt_device Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 03/27] clocksource: sh_cmt: Split channel setup to separate function Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 04/27] clocksource: sh_cmt: Rename mapbase/mapbase_str to mapbase_ch/mapbase Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 05/27] clocksource: sh_cmt: Add memory base to sh_cmt_channel structure Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 06/27] clocksource: sh_cmt: Add index to struct sh_cmt_channel Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 07/27] clocksource: sh_cmt: Replace kmalloc + memset with kzalloc Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 08/27] clocksource: sh_cmt: Allocate channels dynamically Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 09/27] clocksource: sh_cmt: Split static information from sh_cmt_device Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 10/27] clocksource: sh_cmt: Replace hardcoded register values with macros Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 11/27] clocksource: sh_cmt: Add support for multiple channels per device Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-15 12:46   ` Thomas Gleixner
2014-02-15 12:46     ` Thomas Gleixner
2014-02-15 12:46     ` Thomas Gleixner
2014-02-16 18:18     ` Laurent Pinchart
2014-02-16 18:18       ` Laurent Pinchart
2014-02-16 18:18       ` Laurent Pinchart
2014-02-17  1:41       ` Magnus Damm
2014-02-17  1:41         ` Magnus Damm
2014-02-17  1:41         ` Magnus Damm
2014-02-17  1:48         ` Laurent Pinchart
2014-02-17  1:48           ` Laurent Pinchart
2014-02-17  1:48           ` Laurent Pinchart
2014-02-17  2:07           ` Magnus Damm
2014-02-17  2:07             ` Magnus Damm
2014-02-17  2:07             ` Magnus Damm
2014-02-17  9:58             ` Laurent Pinchart
2014-02-17  9:58               ` Laurent Pinchart
2014-02-17  9:58               ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 12/27] clocksource: sh_cmt: Acquire default clock in the non-legacy case Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 13/27] clocksource: sh_cmt: Remove FSF mail address from GPL notice Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 14/27] clocksource: sh_cmt: Sort headers alphabetically Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 15/27] sh: Switch to new style CMT device Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 16/27] ARM: shmobile: sh7372: " Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 17/27] ARM: shmobile: sh73a0: " Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 18/27] ARM: shmobile: r8a73a4: " Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 19/27] ARM: shmobile: r8a7740: " Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 20/27] ARM: shmobile: r8a7790: " Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59 ` [PATCH 21/27] ARM: shmobile: r8a7791: " Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  0:59   ` Laurent Pinchart
2014-02-14  1:00 ` [PATCH 22/27] clocksource: sh_cmt: Drop support for legacy platform data Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00 ` [PATCH 23/27] clocksource: sh_cmt: Add DT support Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  9:18   ` Geert Uytterhoeven
2014-02-14  9:18     ` Geert Uytterhoeven
2014-02-14  9:18     ` Geert Uytterhoeven
2014-02-14 14:35     ` Laurent Pinchart
2014-02-14 14:35       ` Laurent Pinchart
2014-02-14 14:35       ` Laurent Pinchart
2014-02-14 10:58   ` Mark Rutland
2014-02-14 10:58     ` Mark Rutland
2014-02-14 10:58     ` Mark Rutland
2014-02-14 15:53     ` Laurent Pinchart
2014-02-14 15:53       ` Laurent Pinchart
2014-02-14 15:53       ` Laurent Pinchart
2014-02-14 15:59       ` Josh Cartwright
2014-02-14 15:59         ` Josh Cartwright
2014-02-14 15:59         ` Josh Cartwright
2014-02-14 16:15         ` Laurent Pinchart
2014-02-14 16:15           ` Laurent Pinchart
2014-02-14 16:15           ` Laurent Pinchart
2014-02-14 16:01       ` Magnus Damm
2014-02-14 16:01         ` Magnus Damm
2014-02-14 16:01         ` Magnus Damm
2014-02-14 16:12         ` Laurent Pinchart
2014-02-14 16:12           ` Laurent Pinchart
2014-02-14 16:12           ` Laurent Pinchart
2014-02-14 17:22           ` Magnus Damm
2014-02-14 17:22             ` Magnus Damm
2014-02-14 17:22             ` Magnus Damm
2014-02-17  1:45             ` Laurent Pinchart
2014-02-17  1:45               ` Laurent Pinchart
2014-02-17  1:45               ` Laurent Pinchart
2014-02-17  1:48               ` Magnus Damm
2014-02-17  1:48                 ` Magnus Damm
2014-02-17  1:48                 ` Magnus Damm
2014-02-17 21:43                 ` Laurent Pinchart
2014-02-17 21:43                   ` Laurent Pinchart
2014-02-17 21:43                   ` Laurent Pinchart
2014-02-18  0:51                   ` Magnus Damm
2014-02-18  0:51                     ` Magnus Damm
2014-02-18  0:51                     ` Magnus Damm
2014-02-18 11:45                     ` Laurent Pinchart
2014-02-18 11:45                       ` Laurent Pinchart
2014-02-18 11:45                       ` Laurent Pinchart
2014-02-14  1:00 ` [PATCH 24/27] ARM: shmobile: r8a7790: Add CMT devices to DT Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00 ` [PATCH 25/27] ARM: shmobile: r8a7791: " Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00 ` [PATCH 26/27] ARM: shmobile: lager-reference: Enable CMT0 in device tree Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14 13:45   ` Sergei Shtylyov
2014-02-14 13:45     ` Sergei Shtylyov
2014-02-14 13:45     ` Sergei Shtylyov
2014-02-14 13:48     ` Laurent Pinchart
2014-02-14 13:48       ` Laurent Pinchart
2014-02-14 13:48       ` Laurent Pinchart
2014-02-14 14:13       ` Sergei Shtylyov
2014-02-14 14:13         ` Sergei Shtylyov
2014-02-14 14:13         ` Sergei Shtylyov
2014-02-14 14:22         ` Laurent Pinchart
2014-02-14 14:22           ` Laurent Pinchart
2014-02-14 14:22           ` Laurent Pinchart
2014-02-14 14:36           ` Sergei Shtylyov
2014-02-14 14:36             ` Sergei Shtylyov
2014-02-14 14:36             ` Sergei Shtylyov
2014-02-14 16:26             ` Laurent Pinchart
2014-02-14 16:26               ` Laurent Pinchart
2014-02-14 16:26               ` Laurent Pinchart
2014-02-14 18:56               ` Sergei Shtylyov
2014-02-14 19:56                 ` Sergei Shtylyov
2014-02-14 19:56                 ` Sergei Shtylyov
2014-02-14  1:00 ` [PATCH 27/27] ARM: shmobile: koelsch-reference: " Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14  1:00   ` Laurent Pinchart
2014-02-14 13:47   ` Sergei Shtylyov
2014-02-14 13:47     ` Sergei Shtylyov
2014-02-14 13:47     ` Sergei Shtylyov

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.