diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-01-27 09:29:19 -0500 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-04-16 06:03:17 -0400 |
commit | de2d12c7e856f0fa59ea83275410a364d2b182c0 (patch) | |
tree | ecd21732c84a8afcd8b4ff96a7eca89b53dad619 /drivers/clocksource/sh_tmu.c | |
parent | 1c56cf6b048e1e1bbe08faf38b5592b373905ac5 (diff) |
clocksource: sh_tmu: Split channel fields from sh_tmu_priv
Create a new sh_tmu_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>
Diffstat (limited to 'drivers/clocksource/sh_tmu.c')
-rw-r--r-- | drivers/clocksource/sh_tmu.c | 235 |
1 files changed, 125 insertions, 110 deletions
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 8613cc90bb74..26457e1fccbb 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
@@ -35,11 +35,13 @@ | |||
35 | #include <linux/pm_domain.h> | 35 | #include <linux/pm_domain.h> |
36 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
37 | 37 | ||
38 | struct sh_tmu_priv { | 38 | struct sh_tmu_priv; |
39 | void __iomem *mapbase; | 39 | |
40 | struct clk *clk; | 40 | struct sh_tmu_channel { |
41 | struct sh_tmu_priv *tmu; | ||
42 | |||
41 | int irq; | 43 | int irq; |
42 | struct platform_device *pdev; | 44 | |
43 | unsigned long rate; | 45 | unsigned long rate; |
44 | unsigned long periodic; | 46 | unsigned long periodic; |
45 | struct clock_event_device ced; | 47 | struct clock_event_device ced; |
@@ -48,6 +50,15 @@ struct sh_tmu_priv { | |||
48 | unsigned int enable_count; | 50 | unsigned int enable_count; |
49 | }; | 51 | }; |
50 | 52 | ||
53 | struct sh_tmu_priv { | ||
54 | struct platform_device *pdev; | ||
55 | |||
56 | void __iomem *mapbase; | ||
57 | struct clk *clk; | ||
58 | |||
59 | struct sh_tmu_channel channel; | ||
60 | }; | ||
61 | |||
51 | static DEFINE_RAW_SPINLOCK(sh_tmu_lock); | 62 | static DEFINE_RAW_SPINLOCK(sh_tmu_lock); |
52 | 63 | ||
53 | #define TSTR -1 /* shared register */ | 64 | #define TSTR -1 /* shared register */ |
@@ -55,10 +66,10 @@ static DEFINE_RAW_SPINLOCK(sh_tmu_lock); | |||
55 | #define TCNT 1 /* channel register */ | 66 | #define TCNT 1 /* channel register */ |
56 | #define TCR 2 /* channel register */ | 67 | #define TCR 2 /* channel register */ |
57 | 68 | ||
58 | static inline unsigned long sh_tmu_read(struct sh_tmu_priv *p, int reg_nr) | 69 | static inline unsigned long sh_tmu_read(struct sh_tmu_channel *ch, int reg_nr) |
59 | { | 70 | { |
60 | struct sh_timer_config *cfg = p->pdev->dev.platform_data; | 71 | struct sh_timer_config *cfg = ch->tmu->pdev->dev.platform_data; |
61 | void __iomem *base = p->mapbase; | 72 | void __iomem *base = ch->tmu->mapbase; |
62 | unsigned long offs; | 73 | unsigned long offs; |
63 | 74 | ||
64 | if (reg_nr == TSTR) | 75 | if (reg_nr == TSTR) |
@@ -72,11 +83,11 @@ static inline unsigned long sh_tmu_read(struct sh_tmu_priv *p, int reg_nr) | |||
72 | return ioread32(base + offs); | 83 | return ioread32(base + offs); |
73 | } | 84 | } |
74 | 85 | ||
75 | static inline void sh_tmu_write(struct sh_tmu_priv *p, int reg_nr, | 86 | static inline void sh_tmu_write(struct sh_tmu_channel *ch, int reg_nr, |
76 | unsigned long value) | 87 | unsigned long value) |
77 | { | 88 | { |
78 | struct sh_timer_config *cfg = p->pdev->dev.platform_data; | 89 | struct sh_timer_config *cfg = ch->tmu->pdev->dev.platform_data; |
79 | void __iomem *base = p->mapbase; | 90 | void __iomem *base = ch->tmu->mapbase; |
80 | unsigned long offs; | 91 | unsigned long offs; |
81 | 92 | ||
82 | if (reg_nr == TSTR) { | 93 | if (reg_nr == TSTR) { |
@@ -92,152 +103,152 @@ static inline void sh_tmu_write(struct sh_tmu_priv *p, int reg_nr, | |||
92 | iowrite32(value, base + offs); | 103 | iowrite32(value, base + offs); |
93 | } | 104 | } |
94 | 105 | ||
95 | static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start) | 106 | static void sh_tmu_start_stop_ch(struct sh_tmu_channel *ch, int start) |
96 | { | 107 | { |
97 | struct sh_timer_config *cfg = p->pdev->dev.platform_data; | 108 | struct sh_timer_config *cfg = ch->tmu->pdev->dev.platform_data; |
98 | unsigned long flags, value; | 109 | unsigned long flags, value; |
99 | 110 | ||
100 | /* start stop register shared by multiple timer channels */ | 111 | /* start stop register shared by multiple timer channels */ |
101 | raw_spin_lock_irqsave(&sh_tmu_lock, flags); | 112 | raw_spin_lock_irqsave(&sh_tmu_lock, flags); |
102 | value = sh_tmu_read(p, TSTR); | 113 | value = sh_tmu_read(ch, TSTR); |
103 | 114 | ||
104 | if (start) | 115 | if (start) |
105 | value |= 1 << cfg->timer_bit; | 116 | value |= 1 << cfg->timer_bit; |
106 | else | 117 | else |
107 | value &= ~(1 << cfg->timer_bit); | 118 | value &= ~(1 << cfg->timer_bit); |
108 | 119 | ||
109 | sh_tmu_write(p, TSTR, value); | 120 | sh_tmu_write(ch, TSTR, value); |
110 | raw_spin_unlock_irqrestore(&sh_tmu_lock, flags); | 121 | raw_spin_unlock_irqrestore(&sh_tmu_lock, flags); |
111 | } | 122 | } |
112 | 123 | ||
113 | static int __sh_tmu_enable(struct sh_tmu_priv *p) | 124 | static int __sh_tmu_enable(struct sh_tmu_channel *ch) |
114 | { | 125 | { |
115 | int ret; | 126 | int ret; |
116 | 127 | ||
117 | /* enable clock */ | 128 | /* enable clock */ |
118 | ret = clk_enable(p->clk); | 129 | ret = clk_enable(ch->tmu->clk); |
119 | if (ret) { | 130 | if (ret) { |
120 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | 131 | dev_err(&ch->tmu->pdev->dev, "cannot enable clock\n"); |
121 | return ret; | 132 | return ret; |
122 | } | 133 | } |
123 | 134 | ||
124 | /* make sure channel is disabled */ | 135 | /* make sure channel is disabled */ |
125 | sh_tmu_start_stop_ch(p, 0); | 136 | sh_tmu_start_stop_ch(ch, 0); |
126 | 137 | ||
127 | /* maximum timeout */ | 138 | /* maximum timeout */ |
128 | sh_tmu_write(p, TCOR, 0xffffffff); | 139 | sh_tmu_write(ch, TCOR, 0xffffffff); |
129 | sh_tmu_write(p, TCNT, 0xffffffff); | 140 | sh_tmu_write(ch, TCNT, 0xffffffff); |
130 | 141 | ||
131 | /* configure channel to parent clock / 4, irq off */ | 142 | /* configure channel to parent clock / 4, irq off */ |
132 | p->rate = clk_get_rate(p->clk) / 4; | 143 | ch->rate = clk_get_rate(ch->tmu->clk) / 4; |
133 | sh_tmu_write(p, TCR, 0x0000); | 144 | sh_tmu_write(ch, TCR, 0x0000); |
134 | 145 | ||
135 | /* enable channel */ | 146 | /* enable channel */ |
136 | sh_tmu_start_stop_ch(p, 1); | 147 | sh_tmu_start_stop_ch(ch, 1); |
137 | 148 | ||
138 | return 0; | 149 | return 0; |
139 | } | 150 | } |
140 | 151 | ||
141 | static int sh_tmu_enable(struct sh_tmu_priv *p) | 152 | static int sh_tmu_enable(struct sh_tmu_channel *ch) |
142 | { | 153 | { |
143 | if (p->enable_count++ > 0) | 154 | if (ch->enable_count++ > 0) |
144 | return 0; | 155 | return 0; |
145 | 156 | ||
146 | pm_runtime_get_sync(&p->pdev->dev); | 157 | pm_runtime_get_sync(&ch->tmu->pdev->dev); |
147 | dev_pm_syscore_device(&p->pdev->dev, true); | 158 | dev_pm_syscore_device(&ch->tmu->pdev->dev, true); |
148 | 159 | ||
149 | return __sh_tmu_enable(p); | 160 | return __sh_tmu_enable(ch); |
150 | } | 161 | } |
151 | 162 | ||
152 | static void __sh_tmu_disable(struct sh_tmu_priv *p) | 163 | static void __sh_tmu_disable(struct sh_tmu_channel *ch) |
153 | { | 164 | { |
154 | /* disable channel */ | 165 | /* disable channel */ |
155 | sh_tmu_start_stop_ch(p, 0); | 166 | sh_tmu_start_stop_ch(ch, 0); |
156 | 167 | ||
157 | /* disable interrupts in TMU block */ | 168 | /* disable interrupts in TMU block */ |
158 | sh_tmu_write(p, TCR, 0x0000); | 169 | sh_tmu_write(ch, TCR, 0x0000); |
159 | 170 | ||
160 | /* stop clock */ | 171 | /* stop clock */ |
161 | clk_disable(p->clk); | 172 | clk_disable(ch->tmu->clk); |
162 | } | 173 | } |
163 | 174 | ||
164 | static void sh_tmu_disable(struct sh_tmu_priv *p) | 175 | static void sh_tmu_disable(struct sh_tmu_channel *ch) |
165 | { | 176 | { |
166 | if (WARN_ON(p->enable_count == 0)) | 177 | if (WARN_ON(ch->enable_count == 0)) |
167 | return; | 178 | return; |
168 | 179 | ||
169 | if (--p->enable_count > 0) | 180 | if (--ch->enable_count > 0) |
170 | return; | 181 | return; |
171 | 182 | ||
172 | __sh_tmu_disable(p); | 183 | __sh_tmu_disable(ch); |
173 | 184 | ||
174 | dev_pm_syscore_device(&p->pdev->dev, false); | 185 | dev_pm_syscore_device(&ch->tmu->pdev->dev, false); |
175 | pm_runtime_put(&p->pdev->dev); | 186 | pm_runtime_put(&ch->tmu->pdev->dev); |
176 | } | 187 | } |
177 | 188 | ||
178 | static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, | 189 | static void sh_tmu_set_next(struct sh_tmu_channel *ch, unsigned long delta, |
179 | int periodic) | 190 | int periodic) |
180 | { | 191 | { |
181 | /* stop timer */ | 192 | /* stop timer */ |
182 | sh_tmu_start_stop_ch(p, 0); | 193 | sh_tmu_start_stop_ch(ch, 0); |
183 | 194 | ||
184 | /* acknowledge interrupt */ | 195 | /* acknowledge interrupt */ |
185 | sh_tmu_read(p, TCR); | 196 | sh_tmu_read(ch, TCR); |
186 | 197 | ||
187 | /* enable interrupt */ | 198 | /* enable interrupt */ |
188 | sh_tmu_write(p, TCR, 0x0020); | 199 | sh_tmu_write(ch, TCR, 0x0020); |
189 | 200 | ||
190 | /* reload delta value in case of periodic timer */ | 201 | /* reload delta value in case of periodic timer */ |
191 | if (periodic) | 202 | if (periodic) |
192 | sh_tmu_write(p, TCOR, delta); | 203 | sh_tmu_write(ch, TCOR, delta); |
193 | else | 204 | else |
194 | sh_tmu_write(p, TCOR, 0xffffffff); | 205 | sh_tmu_write(ch, TCOR, 0xffffffff); |
195 | 206 | ||
196 | sh_tmu_write(p, TCNT, delta); | 207 | sh_tmu_write(ch, TCNT, delta); |
197 | 208 | ||
198 | /* start timer */ | 209 | /* start timer */ |
199 | sh_tmu_start_stop_ch(p, 1); | 210 | sh_tmu_start_stop_ch(ch, 1); |
200 | } | 211 | } |
201 | 212 | ||
202 | static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id) | 213 | static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id) |
203 | { | 214 | { |
204 | struct sh_tmu_priv *p = dev_id; | 215 | struct sh_tmu_channel *ch = dev_id; |
205 | 216 | ||
206 | /* disable or acknowledge interrupt */ | 217 | /* disable or acknowledge interrupt */ |
207 | if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) | 218 | if (ch->ced.mode == CLOCK_EVT_MODE_ONESHOT) |
208 | sh_tmu_write(p, TCR, 0x0000); | 219 | sh_tmu_write(ch, TCR, 0x0000); |
209 | else | 220 | else |
210 | sh_tmu_write(p, TCR, 0x0020); | 221 | sh_tmu_write(ch, TCR, 0x0020); |
211 | 222 | ||
212 | /* notify clockevent layer */ | 223 | /* notify clockevent layer */ |
213 | p->ced.event_handler(&p->ced); | 224 | ch->ced.event_handler(&ch->ced); |
214 | return IRQ_HANDLED; | 225 | return IRQ_HANDLED; |
215 | } | 226 | } |
216 | 227 | ||
217 | static struct sh_tmu_priv *cs_to_sh_tmu(struct clocksource *cs) | 228 | static struct sh_tmu_channel *cs_to_sh_tmu(struct clocksource *cs) |
218 | { | 229 | { |
219 | return container_of(cs, struct sh_tmu_priv, cs); | 230 | return container_of(cs, struct sh_tmu_channel, cs); |
220 | } | 231 | } |
221 | 232 | ||
222 | static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) | 233 | static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) |
223 | { | 234 | { |
224 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); | 235 | struct sh_tmu_channel *ch = cs_to_sh_tmu(cs); |
225 | 236 | ||
226 | return sh_tmu_read(p, TCNT) ^ 0xffffffff; | 237 | return sh_tmu_read(ch, TCNT) ^ 0xffffffff; |
227 | } | 238 | } |
228 | 239 | ||
229 | static int sh_tmu_clocksource_enable(struct clocksource *cs) | 240 | static int sh_tmu_clocksource_enable(struct clocksource *cs) |
230 | { | 241 | { |
231 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); | 242 | struct sh_tmu_channel *ch = cs_to_sh_tmu(cs); |
232 | int ret; | 243 | int ret; |
233 | 244 | ||
234 | if (WARN_ON(p->cs_enabled)) | 245 | if (WARN_ON(ch->cs_enabled)) |
235 | return 0; | 246 | return 0; |
236 | 247 | ||
237 | ret = sh_tmu_enable(p); | 248 | ret = sh_tmu_enable(ch); |
238 | if (!ret) { | 249 | if (!ret) { |
239 | __clocksource_updatefreq_hz(cs, p->rate); | 250 | __clocksource_updatefreq_hz(cs, ch->rate); |
240 | p->cs_enabled = true; | 251 | ch->cs_enabled = true; |
241 | } | 252 | } |
242 | 253 | ||
243 | return ret; | 254 | return ret; |
@@ -245,45 +256,45 @@ static int sh_tmu_clocksource_enable(struct clocksource *cs) | |||
245 | 256 | ||
246 | static void sh_tmu_clocksource_disable(struct clocksource *cs) | 257 | static void sh_tmu_clocksource_disable(struct clocksource *cs) |
247 | { | 258 | { |
248 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); | 259 | struct sh_tmu_channel *ch = cs_to_sh_tmu(cs); |
249 | 260 | ||
250 | if (WARN_ON(!p->cs_enabled)) | 261 | if (WARN_ON(!ch->cs_enabled)) |
251 | return; | 262 | return; |
252 | 263 | ||
253 | sh_tmu_disable(p); | 264 | sh_tmu_disable(ch); |
254 | p->cs_enabled = false; | 265 | ch->cs_enabled = false; |
255 | } | 266 | } |
256 | 267 | ||
257 | static void sh_tmu_clocksource_suspend(struct clocksource *cs) | 268 | static void sh_tmu_clocksource_suspend(struct clocksource *cs) |
258 | { | 269 | { |
259 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); | 270 | struct sh_tmu_channel *ch = cs_to_sh_tmu(cs); |
260 | 271 | ||
261 | if (!p->cs_enabled) | 272 | if (!ch->cs_enabled) |
262 | return; | 273 | return; |
263 | 274 | ||
264 | if (--p->enable_count == 0) { | 275 | if (--ch->enable_count == 0) { |
265 | __sh_tmu_disable(p); | 276 | __sh_tmu_disable(ch); |
266 | pm_genpd_syscore_poweroff(&p->pdev->dev); | 277 | pm_genpd_syscore_poweroff(&ch->tmu->pdev->dev); |
267 | } | 278 | } |
268 | } | 279 | } |
269 | 280 | ||
270 | static void sh_tmu_clocksource_resume(struct clocksource *cs) | 281 | static void sh_tmu_clocksource_resume(struct clocksource *cs) |
271 | { | 282 | { |
272 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); | 283 | struct sh_tmu_channel *ch = cs_to_sh_tmu(cs); |
273 | 284 | ||
274 | if (!p->cs_enabled) | 285 | if (!ch->cs_enabled) |
275 | return; | 286 | return; |
276 | 287 | ||
277 | if (p->enable_count++ == 0) { | 288 | if (ch->enable_count++ == 0) { |
278 | pm_genpd_syscore_poweron(&p->pdev->dev); | 289 | pm_genpd_syscore_poweron(&ch->tmu->pdev->dev); |
279 | __sh_tmu_enable(p); | 290 | __sh_tmu_enable(ch); |
280 | } | 291 | } |
281 | } | 292 | } |
282 | 293 | ||
283 | static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, | 294 | static int sh_tmu_register_clocksource(struct sh_tmu_channel *ch, |
284 | char *name, unsigned long rating) | 295 | char *name, unsigned long rating) |
285 | { | 296 | { |
286 | struct clocksource *cs = &p->cs; | 297 | struct clocksource *cs = &ch->cs; |
287 | 298 | ||
288 | cs->name = name; | 299 | cs->name = name; |
289 | cs->rating = rating; | 300 | cs->rating = rating; |
@@ -295,43 +306,43 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, | |||
295 | cs->mask = CLOCKSOURCE_MASK(32); | 306 | cs->mask = CLOCKSOURCE_MASK(32); |
296 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; | 307 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
297 | 308 | ||
298 | dev_info(&p->pdev->dev, "used as clock source\n"); | 309 | dev_info(&ch->tmu->pdev->dev, "used as clock source\n"); |
299 | 310 | ||
300 | /* Register with dummy 1 Hz value, gets updated in ->enable() */ | 311 | /* Register with dummy 1 Hz value, gets updated in ->enable() */ |
301 | clocksource_register_hz(cs, 1); | 312 | clocksource_register_hz(cs, 1); |
302 | return 0; | 313 | return 0; |
303 | } | 314 | } |
304 | 315 | ||
305 | static struct sh_tmu_priv *ced_to_sh_tmu(struct clock_event_device *ced) | 316 | static struct sh_tmu_channel *ced_to_sh_tmu(struct clock_event_device *ced) |
306 | { | 317 | { |
307 | return container_of(ced, struct sh_tmu_priv, ced); | 318 | return container_of(ced, struct sh_tmu_channel, ced); |
308 | } | 319 | } |
309 | 320 | ||
310 | static void sh_tmu_clock_event_start(struct sh_tmu_priv *p, int periodic) | 321 | static void sh_tmu_clock_event_start(struct sh_tmu_channel *ch, int periodic) |
311 | { | 322 | { |
312 | struct clock_event_device *ced = &p->ced; | 323 | struct clock_event_device *ced = &ch->ced; |
313 | 324 | ||
314 | sh_tmu_enable(p); | 325 | sh_tmu_enable(ch); |
315 | 326 | ||
316 | clockevents_config(ced, p->rate); | 327 | clockevents_config(ced, ch->rate); |
317 | 328 | ||
318 | if (periodic) { | 329 | if (periodic) { |
319 | p->periodic = (p->rate + HZ/2) / HZ; | 330 | ch->periodic = (ch->rate + HZ/2) / HZ; |
320 | sh_tmu_set_next(p, p->periodic, 1); | 331 | sh_tmu_set_next(ch, ch->periodic, 1); |
321 | } | 332 | } |
322 | } | 333 | } |
323 | 334 | ||
324 | static void sh_tmu_clock_event_mode(enum clock_event_mode mode, | 335 | static void sh_tmu_clock_event_mode(enum clock_event_mode mode, |
325 | struct clock_event_device *ced) | 336 | struct clock_event_device *ced) |
326 | { | 337 | { |
327 | struct sh_tmu_priv *p = ced_to_sh_tmu(ced); | 338 | struct sh_tmu_channel *ch = ced_to_sh_tmu(ced); |
328 | int disabled = 0; | 339 | int disabled = 0; |
329 | 340 | ||
330 | /* deal with old setting first */ | 341 | /* deal with old setting first */ |
331 | switch (ced->mode) { | 342 | switch (ced->mode) { |
332 | case CLOCK_EVT_MODE_PERIODIC: | 343 | case CLOCK_EVT_MODE_PERIODIC: |
333 | case CLOCK_EVT_MODE_ONESHOT: | 344 | case CLOCK_EVT_MODE_ONESHOT: |
334 | sh_tmu_disable(p); | 345 | sh_tmu_disable(ch); |
335 | disabled = 1; | 346 | disabled = 1; |
336 | break; | 347 | break; |
337 | default: | 348 | default: |
@@ -340,16 +351,18 @@ static void sh_tmu_clock_event_mode(enum clock_event_mode mode, | |||
340 | 351 | ||
341 | switch (mode) { | 352 | switch (mode) { |
342 | case CLOCK_EVT_MODE_PERIODIC: | 353 | case CLOCK_EVT_MODE_PERIODIC: |
343 | dev_info(&p->pdev->dev, "used for periodic clock events\n"); | 354 | dev_info(&ch->tmu->pdev->dev, |
344 | sh_tmu_clock_event_start(p, 1); | 355 | "used for periodic clock events\n"); |
356 | sh_tmu_clock_event_start(ch, 1); | ||
345 | break; | 357 | break; |
346 | case CLOCK_EVT_MODE_ONESHOT: | 358 | case CLOCK_EVT_MODE_ONESHOT: |
347 | dev_info(&p->pdev->dev, "used for oneshot clock events\n"); | 359 | dev_info(&ch->tmu->pdev->dev, |
348 | sh_tmu_clock_event_start(p, 0); | 360 | "used for oneshot clock events\n"); |
361 | sh_tmu_clock_event_start(ch, 0); | ||
349 | break; | 362 | break; |
350 | case CLOCK_EVT_MODE_UNUSED: | 363 | case CLOCK_EVT_MODE_UNUSED: |
351 | if (!disabled) | 364 | if (!disabled) |
352 | sh_tmu_disable(p); | 365 | sh_tmu_disable(ch); |
353 | break; | 366 | break; |
354 | case CLOCK_EVT_MODE_SHUTDOWN: | 367 | case CLOCK_EVT_MODE_SHUTDOWN: |
355 | default: | 368 | default: |
@@ -360,29 +373,29 @@ static void sh_tmu_clock_event_mode(enum clock_event_mode mode, | |||
360 | static int sh_tmu_clock_event_next(unsigned long delta, | 373 | static int sh_tmu_clock_event_next(unsigned long delta, |
361 | struct clock_event_device *ced) | 374 | struct clock_event_device *ced) |
362 | { | 375 | { |
363 | struct sh_tmu_priv *p = ced_to_sh_tmu(ced); | 376 | struct sh_tmu_channel *ch = ced_to_sh_tmu(ced); |
364 | 377 | ||
365 | BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); | 378 | BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); |
366 | 379 | ||
367 | /* program new delta value */ | 380 | /* program new delta value */ |
368 | sh_tmu_set_next(p, delta, 0); | 381 | sh_tmu_set_next(ch, delta, 0); |
369 | return 0; | 382 | return 0; |
370 | } | 383 | } |
371 | 384 | ||
372 | static void sh_tmu_clock_event_suspend(struct clock_event_device *ced) | 385 | static void sh_tmu_clock_event_suspend(struct clock_event_device *ced) |
373 | { | 386 | { |
374 | pm_genpd_syscore_poweroff(&ced_to_sh_tmu(ced)->pdev->dev); | 387 | pm_genpd_syscore_poweroff(&ced_to_sh_tmu(ced)->tmu->pdev->dev); |
375 | } | 388 | } |
376 | 389 | ||
377 | static void sh_tmu_clock_event_resume(struct clock_event_device *ced) | 390 | static void sh_tmu_clock_event_resume(struct clock_event_device *ced) |
378 | { | 391 | { |
379 | pm_genpd_syscore_poweron(&ced_to_sh_tmu(ced)->pdev->dev); | 392 | pm_genpd_syscore_poweron(&ced_to_sh_tmu(ced)->tmu->pdev->dev); |
380 | } | 393 | } |
381 | 394 | ||
382 | static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, | 395 | static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch, |
383 | char *name, unsigned long rating) | 396 | char *name, unsigned long rating) |
384 | { | 397 | { |
385 | struct clock_event_device *ced = &p->ced; | 398 | struct clock_event_device *ced = &ch->ced; |
386 | int ret; | 399 | int ret; |
387 | 400 | ||
388 | memset(ced, 0, sizeof(*ced)); | 401 | memset(ced, 0, sizeof(*ced)); |
@@ -397,27 +410,28 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, | |||
397 | ced->suspend = sh_tmu_clock_event_suspend; | 410 | ced->suspend = sh_tmu_clock_event_suspend; |
398 | ced->resume = sh_tmu_clock_event_resume; | 411 | ced->resume = sh_tmu_clock_event_resume; |
399 | 412 | ||
400 | dev_info(&p->pdev->dev, "used for clock events\n"); | 413 | dev_info(&ch->tmu->pdev->dev, "used for clock events\n"); |
401 | 414 | ||
402 | clockevents_config_and_register(ced, 1, 0x300, 0xffffffff); | 415 | clockevents_config_and_register(ced, 1, 0x300, 0xffffffff); |
403 | 416 | ||
404 | ret = request_irq(p->irq, sh_tmu_interrupt, | 417 | ret = request_irq(ch->irq, sh_tmu_interrupt, |
405 | IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, | 418 | IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, |
406 | dev_name(&p->pdev->dev), p); | 419 | dev_name(&ch->tmu->pdev->dev), ch); |
407 | if (ret) { | 420 | if (ret) { |
408 | dev_err(&p->pdev->dev, "failed to request irq %d\n", p->irq); | 421 | dev_err(&ch->tmu->pdev->dev, "failed to request irq %d\n", |
422 | ch->irq); | ||
409 | return; | 423 | return; |
410 | } | 424 | } |
411 | } | 425 | } |
412 | 426 | ||
413 | static int sh_tmu_register(struct sh_tmu_priv *p, char *name, | 427 | static int sh_tmu_register(struct sh_tmu_channel *ch, char *name, |
414 | unsigned long clockevent_rating, | 428 | unsigned long clockevent_rating, |
415 | unsigned long clocksource_rating) | 429 | unsigned long clocksource_rating) |
416 | { | 430 | { |
417 | if (clockevent_rating) | 431 | if (clockevent_rating) |
418 | sh_tmu_register_clockevent(p, name, clockevent_rating); | 432 | sh_tmu_register_clockevent(ch, name, clockevent_rating); |
419 | else if (clocksource_rating) | 433 | else if (clocksource_rating) |
420 | sh_tmu_register_clocksource(p, name, clocksource_rating); | 434 | sh_tmu_register_clocksource(ch, name, clocksource_rating); |
421 | 435 | ||
422 | return 0; | 436 | return 0; |
423 | } | 437 | } |
@@ -445,8 +459,8 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) | |||
445 | goto err0; | 459 | goto err0; |
446 | } | 460 | } |
447 | 461 | ||
448 | p->irq = platform_get_irq(p->pdev, 0); | 462 | p->channel.irq = platform_get_irq(p->pdev, 0); |
449 | if (p->irq < 0) { | 463 | if (p->channel.irq < 0) { |
450 | dev_err(&p->pdev->dev, "failed to get irq\n"); | 464 | dev_err(&p->pdev->dev, "failed to get irq\n"); |
451 | goto err0; | 465 | goto err0; |
452 | } | 466 | } |
@@ -470,10 +484,11 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) | |||
470 | if (ret < 0) | 484 | if (ret < 0) |
471 | goto err2; | 485 | goto err2; |
472 | 486 | ||
473 | p->cs_enabled = false; | 487 | p->channel.cs_enabled = false; |
474 | p->enable_count = 0; | 488 | p->channel.enable_count = 0; |
489 | p->channel.tmu = p; | ||
475 | 490 | ||
476 | ret = sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), | 491 | ret = sh_tmu_register(&p->channel, (char *)dev_name(&p->pdev->dev), |
477 | cfg->clockevent_rating, | 492 | cfg->clockevent_rating, |
478 | cfg->clocksource_rating); | 493 | cfg->clocksource_rating); |
479 | if (ret < 0) | 494 | if (ret < 0) |