diff options
author | Magnus Damm <damm@opensource.se> | 2012-12-14 00:54:19 -0500 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-03-12 13:24:36 -0400 |
commit | a6a912ca43843d43590ce5f1cbc85cbc7ac14bba (patch) | |
tree | d160d1be938a9ef05363bc40c83db001cd402e9d /drivers/clocksource/sh_cmt.c | |
parent | 587acb3dd5cf387de1325309e831fd0f560d1bf6 (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.c | 62 |
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 | ||
59 | static inline unsigned long sh_cmt_read16(void __iomem *base, | 64 | static 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 | ||
65 | static inline void sh_cmt_write16(void __iomem *base, unsigned long offs, | 69 | static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs) |
66 | unsigned long value) | 70 | { |
71 | return ioread32(base + (offs << 2)); | ||
72 | } | ||
73 | |||
74 | static 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 | ||
80 | static 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 | ||
75 | static 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 | |||
89 | static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) | 90 | static 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 | ||
101 | static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) | 102 | static 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 | |||
106 | static 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 | ||
121 | static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, | 107 | static 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, | |||
135 | static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, | 121 | static 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 | ||
141 | static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p, | 127 | static 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 | ||
147 | static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, | 133 | static 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 | } |