aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/sh_cmt.c
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2012-12-14 00:54:19 -0500
committerSimon Horman <horms+renesas@verge.net.au>2013-03-12 13:24:36 -0400
commita6a912ca43843d43590ce5f1cbc85cbc7ac14bba (patch)
treed160d1be938a9ef05363bc40c83db001cd402e9d /drivers/clocksource/sh_cmt.c
parent587acb3dd5cf387de1325309e831fd0f560d1bf6 (diff)
clocksource: sh_cmt: CMCNT and CMCOR register access update
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> Acked-by: John Stultz <john.stultz@linaro.org> Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/clocksource/sh_cmt.c')
-rw-r--r--drivers/clocksource/sh_cmt.c62
1 files changed, 26 insertions, 36 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index eefacc3ac4f2..da904d7f7530 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -54,38 +54,39 @@ struct sh_cmt_priv {
54 struct clocksource cs; 54 struct clocksource cs;
55 unsigned long total_cycles; 55 unsigned long total_cycles;
56 bool cs_enabled; 56 bool cs_enabled;
57
58 /* callbacks for CMCNT and CMCOR access */
59 unsigned long (*read_count)(void __iomem *base, unsigned long offs);
60 void (*write_count)(void __iomem *base, unsigned long offs,
61 unsigned long value);
57}; 62};
58 63
59static inline unsigned long sh_cmt_read16(void __iomem *base, 64static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
60 unsigned long offs)
61{ 65{
62 return ioread16(base + (offs << 1)); 66 return ioread16(base + (offs << 1));
63} 67}
64 68
65static inline void sh_cmt_write16(void __iomem *base, unsigned long offs, 69static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs)
66 unsigned long value) 70{
71 return ioread32(base + (offs << 2));
72}
73
74static void sh_cmt_write16(void __iomem *base, unsigned long offs,
75 unsigned long value)
67{ 76{
68 iowrite16(value, base + (offs << 1)); 77 iowrite16(value, base + (offs << 1));
69} 78}
70 79
80static void sh_cmt_write32(void __iomem *base, unsigned long offs,
81 unsigned long value)
82{
83 iowrite32(value, base + (offs << 2));
84}
85
71#define CMCSR 0 /* channel register */ 86#define CMCSR 0 /* channel register */
72#define CMCNT 1 /* channel register */ 87#define CMCNT 1 /* channel register */
73#define CMCOR 2 /* channel register */ 88#define CMCOR 2 /* channel register */
74 89
75static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
76{
77 void __iomem *base = p->mapbase;
78 unsigned long offs = reg_nr;
79
80 if (p->width == 16) {
81 offs <<= 1;
82 return ioread16(base + offs);
83 } else {
84 offs <<= 2;
85 return ioread32(base + offs);
86 }
87}
88
89static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) 90static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
90{ 91{
91 struct sh_timer_config *cfg = p->pdev->dev.platform_data; 92 struct sh_timer_config *cfg = p->pdev->dev.platform_data;
@@ -100,22 +101,7 @@ static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
100 101
101static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) 102static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
102{ 103{
103 return sh_cmt_read(p, CMCNT); 104 return p->read_count(p->mapbase, CMCNT);
104}
105
106static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
107 unsigned long value)
108{
109 void __iomem *base = p->mapbase;
110 unsigned long offs = reg_nr;
111
112 if (p->width == 16) {
113 offs <<= 1;
114 iowrite16(value, base + offs);
115 } else {
116 offs <<= 2;
117 iowrite32(value, base + offs);
118 }
119} 105}
120 106
121static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, 107static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
@@ -135,13 +121,13 @@ static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
135static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, 121static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
136 unsigned long value) 122 unsigned long value)
137{ 123{
138 sh_cmt_write(p, CMCNT, value); 124 p->write_count(p->mapbase, CMCNT, value);
139} 125}
140 126
141static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p, 127static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
142 unsigned long value) 128 unsigned long value)
143{ 129{
144 sh_cmt_write(p, CMCOR, value); 130 p->write_count(p->mapbase, CMCOR, value);
145} 131}
146 132
147static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, 133static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
@@ -718,10 +704,14 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
718 704
719 if (resource_size(res) == 6) { 705 if (resource_size(res) == 6) {
720 p->width = 16; 706 p->width = 16;
707 p->read_count = sh_cmt_read16;
708 p->write_count = sh_cmt_write16;
721 p->overflow_bit = 0x80; 709 p->overflow_bit = 0x80;
722 p->clear_bits = ~0x80; 710 p->clear_bits = ~0x80;
723 } else { 711 } else {
724 p->width = 32; 712 p->width = 32;
713 p->read_count = sh_cmt_read32;
714 p->write_count = sh_cmt_write32;
725 p->overflow_bit = 0x8000; 715 p->overflow_bit = 0x8000;
726 p->clear_bits = ~0xc000; 716 p->clear_bits = ~0xc000;
727 } 717 }