* [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
@ 2012-12-14 5:53 ` Magnus Damm
2012-12-14 5:53 ` [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup() Magnus Damm
` (8 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:53 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
Magnus Damm
From: Magnus Damm <damm@opensource.se>
Make sure clk_put() is called in case of failure in sh_cmt_setup().
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- 0001/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 12:50:02.000000000 +0900
@@ -708,17 +708,19 @@ static int sh_cmt_setup(struct sh_cmt_pr
cfg->clocksource_rating);
if (ret) {
dev_err(&p->pdev->dev, "registration failed\n");
- goto err1;
+ goto err2;
}
p->cs_enabled = false;
ret = setup_irq(irq, &p->irqaction);
if (ret) {
dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
- goto err1;
+ goto err2;
}
return 0;
+err2:
+ clk_put(p->clk);
err1:
iounmap(p->mapbase);
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
2012-12-14 5:53 ` [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Magnus Damm
@ 2012-12-14 5:53 ` Magnus Damm
2012-12-14 5:53 ` [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call Magnus Damm
` (7 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:53 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
tglx
From: Magnus Damm <damm@opensource.se>
Move the setup of spinlock and max_match_value to sh_cmt_setup().
There's no need to defer those steps until sh_cmt_register().
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- 0002/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 12:52:35.000000000 +0900
@@ -625,14 +625,6 @@ static int sh_cmt_register(struct sh_cmt
unsigned long clockevent_rating,
unsigned long clocksource_rating)
{
- if (p->width = (sizeof(p->max_match_value) * 8))
- p->max_match_value = ~0;
- else
- p->max_match_value = (1 << p->width) - 1;
-
- p->match_value = p->max_match_value;
- raw_spin_lock_init(&p->lock);
-
if (clockevent_rating)
sh_cmt_register_clockevent(p, name, clockevent_rating);
@@ -703,6 +695,14 @@ static int sh_cmt_setup(struct sh_cmt_pr
p->clear_bits = ~0xc000;
}
+ if (p->width = (sizeof(p->max_match_value) * 8))
+ p->max_match_value = ~0;
+ else
+ p->max_match_value = (1 << p->width) - 1;
+
+ p->match_value = p->max_match_value;
+ raw_spin_lock_init(&p->lock);
+
ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
cfg->clockevent_rating,
cfg->clocksource_rating);
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
2012-12-14 5:53 ` [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Magnus Damm
2012-12-14 5:53 ` [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup() Magnus Damm
@ 2012-12-14 5:53 ` Magnus Damm
2012-12-14 5:54 ` [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions Magnus Damm
` (6 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:53 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
Magnus Damm
From: Magnus Damm <damm@opensource.se>
Cleanup the use of platform_set_drvdata() to reduce code size
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- 0003/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 12:54:59.000000000 +0900
@@ -649,8 +649,6 @@ static int sh_cmt_setup(struct sh_cmt_pr
goto err0;
}
- platform_set_drvdata(pdev, p);
-
res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&p->pdev->dev, "failed to get I/O memory\n");
@@ -718,6 +716,8 @@ static int sh_cmt_setup(struct sh_cmt_pr
goto err2;
}
+ platform_set_drvdata(pdev, p);
+
return 0;
err2:
clk_put(p->clk);
@@ -753,7 +753,6 @@ static int __devinit sh_cmt_probe(struct
ret = sh_cmt_setup(p, pdev);
if (ret) {
kfree(p);
- platform_set_drvdata(pdev, NULL);
pm_runtime_idle(&pdev->dev);
return ret;
}
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (2 preceding siblings ...)
2012-12-14 5:53 ` [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call Magnus Damm
@ 2012-12-14 5:54 ` Magnus Damm
2012-12-14 5:54 ` [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update Magnus Damm
` (5 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:54 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
tglx
From: Magnus Damm <damm@opensource.se>
Introduce sh_cmt_read_cmstr/cmcsr/cmcnt() and
sh_cmt_write_cmstr/cmcsr/cmcnt/cmcor() to in the
future allow us to split counter registers from
control registers and reduce code complexity by
removing sh_cmt_read() and sh_cmt_write().
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 71 ++++++++++++++++++++++++++++++++----------
1 file changed, 55 insertions(+), 16 deletions(-)
--- 0001/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 10:50:15.000000000 +0900
@@ -86,6 +86,21 @@ static inline unsigned long sh_cmt_read(
return ioread16(base + offs);
}
+static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
+{
+ return sh_cmt_read(p, CMSTR);
+}
+
+static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
+{
+ return sh_cmt_read(p, CMCSR);
+}
+
+static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
+{
+ return sh_cmt_read(p, CMCNT);
+}
+
static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
unsigned long value)
{
@@ -112,21 +127,45 @@ static inline void sh_cmt_write(struct s
iowrite16(value, base + offs);
}
+static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
+ unsigned long value)
+{
+ sh_cmt_write(p, CMSTR, value);
+}
+
+static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
+ unsigned long value)
+{
+ sh_cmt_write(p, CMCSR, value);
+}
+
+static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
+ unsigned long value)
+{
+ sh_cmt_write(p, CMCNT, value);
+}
+
+static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
+ unsigned long value)
+{
+ sh_cmt_write(p, CMCOR, value);
+}
+
static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
int *has_wrapped)
{
unsigned long v1, v2, v3;
int o1, o2;
- o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
/* Make sure the timer value is stable. Stolen from acpi_pm.c */
do {
o2 = o1;
- v1 = sh_cmt_read(p, CMCNT);
- v2 = sh_cmt_read(p, CMCNT);
- v3 = sh_cmt_read(p, CMCNT);
- o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ v1 = sh_cmt_read_cmcnt(p);
+ v2 = sh_cmt_read_cmcnt(p);
+ v3 = sh_cmt_read_cmcnt(p);
+ o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
|| (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
@@ -142,14 +181,14 @@ static void sh_cmt_start_stop_ch(struct
/* start stop register shared by multiple timer channels */
raw_spin_lock_irqsave(&sh_cmt_lock, flags);
- value = sh_cmt_read(p, CMSTR);
+ value = sh_cmt_read_cmstr(p);
if (start)
value |= 1 << cfg->timer_bit;
else
value &= ~(1 << cfg->timer_bit);
- sh_cmt_write(p, CMSTR, value);
+ sh_cmt_write_cmstr(p, value);
raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
}
@@ -173,14 +212,14 @@ static int sh_cmt_enable(struct sh_cmt_p
/* configure channel, periodic mode and maximum timeout */
if (p->width = 16) {
*rate = clk_get_rate(p->clk) / 512;
- sh_cmt_write(p, CMCSR, 0x43);
+ sh_cmt_write_cmcsr(p, 0x43);
} else {
*rate = clk_get_rate(p->clk) / 8;
- sh_cmt_write(p, CMCSR, 0x01a4);
+ sh_cmt_write_cmcsr(p, 0x01a4);
}
- sh_cmt_write(p, CMCOR, 0xffffffff);
- sh_cmt_write(p, CMCNT, 0);
+ sh_cmt_write_cmcor(p, 0xffffffff);
+ sh_cmt_write_cmcnt(p, 0);
/*
* According to the sh73a0 user's manual, as CMCNT can be operated
@@ -194,12 +233,12 @@ static int sh_cmt_enable(struct sh_cmt_p
* take RCLKx2 at maximum.
*/
for (k = 0; k < 100; k++) {
- if (!sh_cmt_read(p, CMCNT))
+ if (!sh_cmt_read_cmcnt(p))
break;
udelay(1);
}
- if (sh_cmt_read(p, CMCNT)) {
+ if (sh_cmt_read_cmcnt(p)) {
dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
ret = -ETIMEDOUT;
goto err1;
@@ -222,7 +261,7 @@ static void sh_cmt_disable(struct sh_cmt
sh_cmt_start_stop_ch(p, 0);
/* disable interrupts in CMT block */
- sh_cmt_write(p, CMCSR, 0);
+ sh_cmt_write_cmcsr(p, 0);
/* stop clock */
clk_disable(p->clk);
@@ -270,7 +309,7 @@ static void sh_cmt_clock_event_program_v
if (new_match > p->max_match_value)
new_match = p->max_match_value;
- sh_cmt_write(p, CMCOR, new_match);
+ sh_cmt_write_cmcor(p, new_match);
now = sh_cmt_get_counter(p, &has_wrapped);
if (has_wrapped && (new_match > p->match_value)) {
@@ -346,7 +385,7 @@ static irqreturn_t sh_cmt_interrupt(int
struct sh_cmt_priv *p = dev_id;
/* clear flags */
- sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
+ sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits);
/* update clock source counter to begin with if enabled
* the wrap flag should be cleared by the timer specific
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (3 preceding siblings ...)
2012-12-14 5:54 ` [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions Magnus Damm
@ 2012-12-14 5:54 ` Magnus Damm
2012-12-14 5:54 ` [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR " Magnus Damm
` (4 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:54 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
Magnus Damm
From: Magnus Damm <damm@opensource.se>
Update hardware register access code for CMSTR and CMCSR
from using sh_cmt_read() and sh_cmt_write() to make use
of 16-bit register access functions such as sh_cmt_read16()
and sh_cmt_write16(). Also update sh_cmt_read() and
sh_cmt_write() now when the special cases are gone.
This patch moves us one step closer to the goal of separating
counter register access functions from control control register
functions.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 66 +++++++++++++++++++-----------------------
1 file changed, 30 insertions(+), 36 deletions(-)
--- 0005/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 12:58:01.000000000 +0900
@@ -56,44 +56,46 @@ struct sh_cmt_priv {
bool cs_enabled;
};
-static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
+static inline unsigned long sh_cmt_read16(void __iomem *base,
+ unsigned long offs)
+{
+ return ioread16(base + (offs << 1));
+}
+
+static inline void sh_cmt_write16(void __iomem *base, unsigned long offs,
+ unsigned long value)
+{
+ iowrite16(value, base + (offs << 1));
+}
-#define CMSTR -1 /* shared register */
#define CMCSR 0 /* channel register */
#define CMCNT 1 /* channel register */
#define CMCOR 2 /* channel register */
static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
{
- struct sh_timer_config *cfg = p->pdev->dev.platform_data;
void __iomem *base = p->mapbase;
- unsigned long offs;
+ unsigned long offs = reg_nr;
- if (reg_nr = CMSTR) {
- offs = 0;
- base -= cfg->channel_offset;
- } else
- offs = reg_nr;
-
- if (p->width = 16)
+ if (p->width = 16) {
offs <<= 1;
- else {
+ return ioread16(base + offs);
+ } else {
offs <<= 2;
- if ((reg_nr = CMCNT) || (reg_nr = CMCOR))
- return ioread32(base + offs);
+ return ioread32(base + offs);
}
-
- return ioread16(base + offs);
}
static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
{
- return sh_cmt_read(p, CMSTR);
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+
+ return sh_cmt_read16(p->mapbase - cfg->channel_offset, 0);
}
static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
{
- return sh_cmt_read(p, CMCSR);
+ return sh_cmt_read16(p->mapbase, CMCSR);
}
static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
@@ -104,39 +106,30 @@ static inline unsigned long sh_cmt_read_
static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
unsigned long value)
{
- struct sh_timer_config *cfg = p->pdev->dev.platform_data;
void __iomem *base = p->mapbase;
- unsigned long offs;
-
- if (reg_nr = CMSTR) {
- offs = 0;
- base -= cfg->channel_offset;
- } else
- offs = reg_nr;
+ unsigned long offs = reg_nr;
- if (p->width = 16)
+ if (p->width = 16) {
offs <<= 1;
- else {
+ iowrite16(value, base + offs);
+ } else {
offs <<= 2;
- if ((reg_nr = CMCNT) || (reg_nr = CMCOR)) {
- iowrite32(value, base + offs);
- return;
- }
+ iowrite32(value, base + offs);
}
-
- iowrite16(value, base + offs);
}
static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
unsigned long value)
{
- sh_cmt_write(p, CMSTR, value);
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+
+ sh_cmt_write16(p->mapbase - cfg->channel_offset, 0, value);
}
static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
unsigned long value)
{
- sh_cmt_write(p, CMCSR, value);
+ sh_cmt_write16(p->mapbase, CMCSR, value);
}
static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
@@ -173,6 +166,7 @@ static unsigned long sh_cmt_get_counter(
return v2;
}
+static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
{
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (4 preceding siblings ...)
2012-12-14 5:54 ` [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update Magnus Damm
@ 2012-12-14 5:54 ` Magnus Damm
2012-12-14 5:54 ` [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks Magnus Damm
` (3 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:54 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
tglx
From: Magnus Damm <damm@opensource.se>
Break out the CMCNT and CMCOR register access code
into separate 16-bit and 32-bit functions that are
hooked into callbacks at init time. This reduces
the amount of software calculations happening at
runtime.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 62 +++++++++++++++++-------------------------
1 file changed, 26 insertions(+), 36 deletions(-)
--- 0006/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 13:00:20.000000000 +0900
@@ -54,38 +54,39 @@ struct sh_cmt_priv {
struct clocksource cs;
unsigned long total_cycles;
bool cs_enabled;
+
+ /* callbacks for CMCNT and CMCOR access */
+ unsigned long (*read_count)(void __iomem *base, unsigned long offs);
+ void (*write_count)(void __iomem *base, unsigned long offs,
+ unsigned long value);
};
-static inline unsigned long sh_cmt_read16(void __iomem *base,
- unsigned long offs)
+static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
{
return ioread16(base + (offs << 1));
}
-static inline void sh_cmt_write16(void __iomem *base, unsigned long offs,
- unsigned long value)
+static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs)
+{
+ return ioread32(base + (offs << 2));
+}
+
+static void sh_cmt_write16(void __iomem *base, unsigned long offs,
+ unsigned long value)
{
iowrite16(value, base + (offs << 1));
}
+static void sh_cmt_write32(void __iomem *base, unsigned long offs,
+ unsigned long value)
+{
+ iowrite32(value, base + (offs << 2));
+}
+
#define CMCSR 0 /* channel register */
#define CMCNT 1 /* channel register */
#define CMCOR 2 /* channel register */
-static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
-{
- void __iomem *base = p->mapbase;
- unsigned long offs = reg_nr;
-
- if (p->width = 16) {
- offs <<= 1;
- return ioread16(base + offs);
- } else {
- offs <<= 2;
- return ioread32(base + offs);
- }
-}
-
static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
{
struct sh_timer_config *cfg = p->pdev->dev.platform_data;
@@ -100,22 +101,7 @@ static inline unsigned long sh_cmt_read_
static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
{
- return sh_cmt_read(p, CMCNT);
-}
-
-static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
- unsigned long value)
-{
- void __iomem *base = p->mapbase;
- unsigned long offs = reg_nr;
-
- if (p->width = 16) {
- offs <<= 1;
- iowrite16(value, base + offs);
- } else {
- offs <<= 2;
- iowrite32(value, base + offs);
- }
+ return p->read_count(p->mapbase, CMCNT);
}
static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
@@ -135,13 +121,13 @@ static inline void sh_cmt_write_cmcsr(st
static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
unsigned long value)
{
- sh_cmt_write(p, CMCNT, value);
+ p->write_count(p->mapbase, CMCNT, value);
}
static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
unsigned long value)
{
- sh_cmt_write(p, CMCOR, value);
+ p->write_count(p->mapbase, CMCOR, value);
}
static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
@@ -718,10 +704,14 @@ static int sh_cmt_setup(struct sh_cmt_pr
if (resource_size(res) = 6) {
p->width = 16;
+ p->read_count = sh_cmt_read16;
+ p->write_count = sh_cmt_write16;
p->overflow_bit = 0x80;
p->clear_bits = ~0x80;
} else {
p->width = 32;
+ p->read_count = sh_cmt_read32;
+ p->write_count = sh_cmt_write32;
p->overflow_bit = 0x8000;
p->clear_bits = ~0xc000;
}
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (5 preceding siblings ...)
2012-12-14 5:54 ` [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR " Magnus Damm
@ 2012-12-14 5:54 ` Magnus Damm
2012-12-14 5:54 ` [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment Magnus Damm
` (2 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:54 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, tglx,
Magnus Damm
From: Magnus Damm <damm@opensource.se>
This patch adds control register callbacks for the CMT
driver. At this point only 16-bit access is supported
but in the future this will be updated to allow 32-bit
access as well.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
--- 0004/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 11:28:57.000000000 +0900
@@ -55,6 +55,11 @@ struct sh_cmt_priv {
unsigned long total_cycles;
bool cs_enabled;
+ /* callbacks for CMSTR and CMCSR access */
+ unsigned long (*read_control)(void __iomem *base, unsigned long offs);
+ void (*write_control)(void __iomem *base, unsigned long offs,
+ unsigned long value);
+
/* callbacks for CMCNT and CMCOR access */
unsigned long (*read_count)(void __iomem *base, unsigned long offs);
void (*write_count)(void __iomem *base, unsigned long offs,
@@ -94,12 +99,12 @@ static inline unsigned long sh_cmt_read_
{
struct sh_timer_config *cfg = p->pdev->dev.platform_data;
- return sh_cmt_read16(p->mapbase - cfg->channel_offset, 0);
+ return p->read_control(p->mapbase - cfg->channel_offset, 0);
}
static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
{
- return sh_cmt_read16(p->mapbase, CMCSR);
+ return p->read_control(p->mapbase, CMCSR);
}
static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
@@ -112,13 +117,13 @@ static inline void sh_cmt_write_cmstr(st
{
struct sh_timer_config *cfg = p->pdev->dev.platform_data;
- sh_cmt_write16(p->mapbase - cfg->channel_offset, 0, value);
+ p->write_control(p->mapbase - cfg->channel_offset, 0, value);
}
static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
unsigned long value)
{
- sh_cmt_write16(p->mapbase, CMCSR, value);
+ p->write_control(p->mapbase, CMCSR, value);
}
static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
@@ -714,6 +719,9 @@ static int sh_cmt_setup(struct sh_cmt_pr
goto err1;
}
+ p->read_control = sh_cmt_read16;
+ p->write_control = sh_cmt_write16;
+
if (resource_size(res) = 6) {
p->width = 16;
p->read_count = sh_cmt_read16;
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (6 preceding siblings ...)
2012-12-14 5:54 ` [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks Magnus Damm
@ 2012-12-14 5:54 ` Magnus Damm
2012-12-19 17:57 ` [PATCH 00/08] clocksource: sh_cmt: CMT driver update John Stultz
2013-02-13 9:45 ` Guennadi Liakhovetski
9 siblings, 0 replies; 12+ messages in thread
From: Magnus Damm @ 2012-12-14 5:54 UTC (permalink / raw)
To: linux-kernel
Cc: linux-sh, johnstul, horms, shinya.kuribayashi.px, Magnus Damm,
tglx
From: Magnus Damm <damm@opensource.se>
Add a comment about different register layouts
supported by the CMT driver.
Signed-off-by: Magnus Damm <damm@opensource.se>
---
drivers/clocksource/sh_cmt.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- 0005/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c 2012-12-14 11:43:10.000000000 +0900
@@ -66,6 +66,21 @@ struct sh_cmt_priv {
unsigned long value);
};
+/* Examples of supported CMT timer register layouts and I/O access widths:
+ *
+ * "16-bit counter and 16-bit control" as found on sh7263:
+ * CMSTR 0xfffec000 16-bit
+ * CMCSR 0xfffec002 16-bit
+ * CMCNT 0xfffec004 16-bit
+ * CMCOR 0xfffec006 16-bit
+ *
+ * "32-bit counter and 16-bit control" as found on sh7372, sh73a0, r8a7740:
+ * CMSTR 0xffca0000 16-bit
+ * CMCSR 0xffca0060 16-bit
+ * CMCNT 0xffca0064 32-bit
+ * CMCOR 0xffca0068 32-bit
+ */
+
static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
{
return ioread16(base + (offs << 1));
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 00/08] clocksource: sh_cmt: CMT driver update
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (7 preceding siblings ...)
2012-12-14 5:54 ` [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment Magnus Damm
@ 2012-12-19 17:57 ` John Stultz
2013-02-13 9:45 ` Guennadi Liakhovetski
9 siblings, 0 replies; 12+ messages in thread
From: John Stultz @ 2012-12-19 17:57 UTC (permalink / raw)
To: Magnus Damm; +Cc: linux-kernel, linux-sh, horms, shinya.kuribayashi.px, tglx
On 12/13/2012 09:53 PM, Magnus Damm wrote:
> clocksource: sh_cmt: CMT driver update
>
> [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
> [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
> [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
> [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
> [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
> [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
> [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
> [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
>
> This patch series contains a couple of driver updates from Kuribayashi-san
> together with some register access changes from me. The register access
> changes work towards adding support for 32-bit only CMT hardware, but
> the final bits are not yet included in this series due to lack of hardware.
>
> Patches 1-3:
> Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
> Signed-off-by: Magnus Damm <damm@opensource.se>
>
> Patches 4-8:
> Signed-off-by: Magnus Damm <damm@opensource.se>
Due to unfamiliarity with the hardware, I can't really review these
changes, so I'd prefer they be merged through the arch tree, where it
can get proper review/testing.
Acked-by: John Stultz <john.stultz@linaro.org>
thanks
-john
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 00/08] clocksource: sh_cmt: CMT driver update
2012-12-14 5:53 [PATCH 00/08] clocksource: sh_cmt: CMT driver update Magnus Damm
` (8 preceding siblings ...)
2012-12-19 17:57 ` [PATCH 00/08] clocksource: sh_cmt: CMT driver update John Stultz
@ 2013-02-13 9:45 ` Guennadi Liakhovetski
2013-02-13 10:54 ` Simon Horman
9 siblings, 1 reply; 12+ messages in thread
From: Guennadi Liakhovetski @ 2013-02-13 9:45 UTC (permalink / raw)
To: Magnus Damm
Cc: linux-kernel, linux-sh, johnstul, horms, shinya.kuribayashi.px,
tglx
Hi Magnus
On Fri, 14 Dec 2012, Magnus Damm wrote:
> clocksource: sh_cmt: CMT driver update
>
> [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
> [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
> [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
> [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
> [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
> [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
> [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
> [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
On a kzm9g board with -reference DT configuration and on armadillo800eva:
Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Thanks
Guennadi
> This patch series contains a couple of driver updates from Kuribayashi-san
> together with some register access changes from me. The register access
> changes work towards adding support for 32-bit only CMT hardware, but
> the final bits are not yet included in this series due to lack of hardware.
>
> Patches 1-3:
> Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
> Signed-off-by: Magnus Damm <damm@opensource.se>
>
> Patches 4-8:
> Signed-off-by: Magnus Damm <damm@opensource.se>
> ---
>
> drivers/clocksource/sh_cmt.c | 257 ++++++++++++++++++++++++------------------
> 1 file changed, 152 insertions(+), 105 deletions(-)
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 00/08] clocksource: sh_cmt: CMT driver update
2013-02-13 9:45 ` Guennadi Liakhovetski
@ 2013-02-13 10:54 ` Simon Horman
0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2013-02-13 10:54 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: Magnus Damm, linux-kernel, linux-sh, johnstul,
shinya.kuribayashi.px, tglx
On Wed, Feb 13, 2013 at 10:45:13AM +0100, Guennadi Liakhovetski wrote:
> Hi Magnus
>
> On Fri, 14 Dec 2012, Magnus Damm wrote:
>
> > clocksource: sh_cmt: CMT driver update
> >
> > [PATCH 01/08] clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails
> > [PATCH 02/08] clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup()
> > [PATCH 03/08] clocksource: sh_cmt: Consolidate platform_set_drvdata() call
> > [PATCH 04/08] clocksource: sh_cmt: Introduce per-register functions
> > [PATCH 05/08] clocksource: sh_cmt: CMSTR and CMCSR register access update
> > [PATCH 06/08] clocksource: sh_cmt: CMCNT and CMCOR register access update
> > [PATCH 07/08] clocksource: sh_cmt: Add control register callbacks
> > [PATCH 08/08] clocksource: sh_cmt: Add CMT register layout comment
>
> On a kzm9g board with -reference DT configuration and on armadillo800eva:
>
> Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Thanks, I have applied these to the clocksource branch.
^ permalink raw reply [flat|nested] 12+ messages in thread