sh_cmt.c 29.5 KB
Newer Older
M
Magnus Damm 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * SuperH Timer Support - CMT
 *
 *  Copyright (C) 2008 Magnus Damm
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License
 *
 * This program is distributed in the hope that it will be useful,
 * 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.
 */

16 17 18 19 20
#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/delay.h>
#include <linux/err.h>
M
Magnus Damm 已提交
21 22 23
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
24
#include <linux/ioport.h>
M
Magnus Damm 已提交
25
#include <linux/irq.h>
26
#include <linux/module.h>
27
#include <linux/platform_device.h>
28
#include <linux/pm_domain.h>
29
#include <linux/pm_runtime.h>
30 31 32
#include <linux/sh_timer.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
M
Magnus Damm 已提交
33

34
struct sh_cmt_device;
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
/*
 * 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.
 *
52 53 54 55 56 57 58 59 60 61
 * 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
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
 * 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);
};

91
struct sh_cmt_channel {
92
	struct sh_cmt_device *cmt;
M
Magnus Damm 已提交
93

94 95 96 97 98
	unsigned int index;	/* Index in the documentation */
	unsigned int hwidx;	/* Real hardware index */

	void __iomem *iostart;
	void __iomem *ioctrl;
99

100
	unsigned int timer_bit;
M
Magnus Damm 已提交
101 102 103 104 105
	unsigned long flags;
	unsigned long match_value;
	unsigned long next_match_value;
	unsigned long max_match_value;
	unsigned long rate;
106
	raw_spinlock_t lock;
M
Magnus Damm 已提交
107
	struct clock_event_device ced;
108
	struct clocksource cs;
M
Magnus Damm 已提交
109
	unsigned long total_cycles;
110
	bool cs_enabled;
111 112
};

113
struct sh_cmt_device {
114 115
	struct platform_device *pdev;

116
	const struct sh_cmt_info *info;
117
	bool legacy;
118

119
	void __iomem *mapbase_ch;
120 121 122
	void __iomem *mapbase;
	struct clk *clk;

123 124
	struct sh_cmt_channel *channels;
	unsigned int num_channels;
125 126 127

	bool has_clockevent;
	bool has_clocksource;
M
Magnus Damm 已提交
128 129
};

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
#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)

158
static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
159 160 161 162
{
	return ioread16(base + (offs << 1));
}

163 164 165 166 167 168 169
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)
170 171 172
{
	iowrite16(value, base + (offs << 1));
}
M
Magnus Damm 已提交
173

174 175 176 177 178 179
static void sh_cmt_write32(void __iomem *base, unsigned long offs,
			   unsigned long value)
{
	iowrite32(value, base + (offs << 2));
}

180 181 182 183
static const struct sh_cmt_info sh_cmt_info[] = {
	[SH_CMT_16BIT] = {
		.model = SH_CMT_16BIT,
		.width = 16,
184 185
		.overflow_bit = SH_CMT16_CMCSR_CMF,
		.clear_bits = ~SH_CMT16_CMCSR_CMF,
186 187 188 189 190 191 192 193
		.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,
194 195
		.overflow_bit = SH_CMT32_CMCSR_CMF,
		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
196 197 198 199 200 201 202 203
		.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,
204 205
		.overflow_bit = SH_CMT32_CMCSR_CMF,
		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
206 207 208 209 210 211 212 213
		.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,
214 215
		.overflow_bit = SH_CMT32_CMCSR_CMF,
		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
216 217 218 219 220 221 222 223
		.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,
224 225
		.overflow_bit = SH_CMT32_CMCSR_CMF,
		.clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
226 227 228 229 230 231 232
		.read_control = sh_cmt_read32,
		.write_control = sh_cmt_write32,
		.read_count = sh_cmt_read32,
		.write_count = sh_cmt_write32,
	},
};

M
Magnus Damm 已提交
233 234 235 236
#define CMCSR 0 /* channel register */
#define CMCNT 1 /* channel register */
#define CMCOR 2 /* channel register */

237
static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
238
{
239 240 241 242
	if (ch->iostart)
		return ch->cmt->info->read_control(ch->iostart, 0);
	else
		return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
243 244
}

245 246
static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
				      unsigned long value)
247
{
248 249 250 251
	if (ch->iostart)
		ch->cmt->info->write_control(ch->iostart, 0, value);
	else
		ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
252 253
}

254
static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
255
{
256
	return ch->cmt->info->read_control(ch->ioctrl, CMCSR);
M
Magnus Damm 已提交
257 258
}

259
static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
260 261
				      unsigned long value)
{
262
	ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
263 264
}

265
static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
266
{
267
	return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
268 269
}

270
static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
271 272
				      unsigned long value)
{
273
	ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
274 275
}

276
static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
277 278
				      unsigned long value)
{
279
	ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
280 281
}

282
static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
M
Magnus Damm 已提交
283 284 285
					int *has_wrapped)
{
	unsigned long v1, v2, v3;
286 287
	int o1, o2;

288
	o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
M
Magnus Damm 已提交
289 290 291

	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
	do {
292
		o2 = o1;
293 294 295
		v1 = sh_cmt_read_cmcnt(ch);
		v2 = sh_cmt_read_cmcnt(ch);
		v3 = sh_cmt_read_cmcnt(ch);
296
		o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
297 298
	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
M
Magnus Damm 已提交
299

300
	*has_wrapped = o1;
M
Magnus Damm 已提交
301 302 303
	return v2;
}

304
static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
M
Magnus Damm 已提交
305

306
static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
M
Magnus Damm 已提交
307 308 309 310
{
	unsigned long flags, value;

	/* start stop register shared by multiple timer channels */
311
	raw_spin_lock_irqsave(&sh_cmt_lock, flags);
312
	value = sh_cmt_read_cmstr(ch);
M
Magnus Damm 已提交
313 314

	if (start)
315
		value |= 1 << ch->timer_bit;
M
Magnus Damm 已提交
316
	else
317
		value &= ~(1 << ch->timer_bit);
M
Magnus Damm 已提交
318

319
	sh_cmt_write_cmstr(ch, value);
320
	raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
M
Magnus Damm 已提交
321 322
}

323
static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
M
Magnus Damm 已提交
324
{
325
	int k, ret;
M
Magnus Damm 已提交
326

327 328
	pm_runtime_get_sync(&ch->cmt->pdev->dev);
	dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
329

330
	/* enable clock */
331
	ret = clk_enable(ch->cmt->clk);
M
Magnus Damm 已提交
332
	if (ret) {
333 334
		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot enable clock\n",
			ch->index);
335
		goto err0;
M
Magnus Damm 已提交
336 337 338
	}

	/* make sure channel is disabled */
339
	sh_cmt_start_stop_ch(ch, 0);
M
Magnus Damm 已提交
340 341

	/* configure channel, periodic mode and maximum timeout */
342
	if (ch->cmt->info->width == 16) {
343
		*rate = clk_get_rate(ch->cmt->clk) / 512;
344 345
		sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
				   SH_CMT16_CMCSR_CKS512);
M
Magnus Damm 已提交
346
	} else {
347
		*rate = clk_get_rate(ch->cmt->clk) / 8;
348 349 350 351
		sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM |
				   SH_CMT32_CMCSR_CMTOUT_IE |
				   SH_CMT32_CMCSR_CMR_IRQ |
				   SH_CMT32_CMCSR_CKS_RCLK8);
M
Magnus Damm 已提交
352
	}
M
Magnus Damm 已提交
353

354 355
	sh_cmt_write_cmcor(ch, 0xffffffff);
	sh_cmt_write_cmcnt(ch, 0);
M
Magnus Damm 已提交
356

357 358 359 360 361 362 363 364 365 366 367 368
	/*
	 * According to the sh73a0 user's manual, as CMCNT can be operated
	 * only by the RCLK (Pseudo 32 KHz), there's one restriction on
	 * modifying CMCNT register; two RCLK cycles are necessary before
	 * this register is either read or any modification of the value
	 * it holds is reflected in the LSI's actual operation.
	 *
	 * While at it, we're supposed to clear out the CMCNT as of this
	 * moment, so make sure it's processed properly here.  This will
	 * take RCLKx2 at maximum.
	 */
	for (k = 0; k < 100; k++) {
369
		if (!sh_cmt_read_cmcnt(ch))
370 371 372 373
			break;
		udelay(1);
	}

374
	if (sh_cmt_read_cmcnt(ch)) {
375 376
		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
			ch->index);
377 378 379 380
		ret = -ETIMEDOUT;
		goto err1;
	}

M
Magnus Damm 已提交
381
	/* enable channel */
382
	sh_cmt_start_stop_ch(ch, 1);
M
Magnus Damm 已提交
383
	return 0;
384 385
 err1:
	/* stop clock */
386
	clk_disable(ch->cmt->clk);
387 388 389

 err0:
	return ret;
M
Magnus Damm 已提交
390 391
}

392
static void sh_cmt_disable(struct sh_cmt_channel *ch)
M
Magnus Damm 已提交
393 394
{
	/* disable channel */
395
	sh_cmt_start_stop_ch(ch, 0);
M
Magnus Damm 已提交
396

397
	/* disable interrupts in CMT block */
398
	sh_cmt_write_cmcsr(ch, 0);
399

400
	/* stop clock */
401
	clk_disable(ch->cmt->clk);
402

403 404
	dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
	pm_runtime_put(&ch->cmt->pdev->dev);
M
Magnus Damm 已提交
405 406 407 408 409 410 411 412 413
}

/* private flags */
#define FLAG_CLOCKEVENT (1 << 0)
#define FLAG_CLOCKSOURCE (1 << 1)
#define FLAG_REPROGRAM (1 << 2)
#define FLAG_SKIPEVENT (1 << 3)
#define FLAG_IRQCONTEXT (1 << 4)

414
static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
M
Magnus Damm 已提交
415 416 417
					      int absolute)
{
	unsigned long new_match;
418
	unsigned long value = ch->next_match_value;
M
Magnus Damm 已提交
419 420 421 422
	unsigned long delay = 0;
	unsigned long now = 0;
	int has_wrapped;

423 424
	now = sh_cmt_get_counter(ch, &has_wrapped);
	ch->flags |= FLAG_REPROGRAM; /* force reprogram */
M
Magnus Damm 已提交
425 426 427 428 429 430

	if (has_wrapped) {
		/* we're competing with the interrupt handler.
		 *  -> let the interrupt handler reprogram the timer.
		 *  -> interrupt number two handles the event.
		 */
431
		ch->flags |= FLAG_SKIPEVENT;
M
Magnus Damm 已提交
432 433 434 435 436 437 438 439 440 441 442
		return;
	}

	if (absolute)
		now = 0;

	do {
		/* reprogram the timer hardware,
		 * but don't save the new match value yet.
		 */
		new_match = now + value + delay;
443 444
		if (new_match > ch->max_match_value)
			new_match = ch->max_match_value;
M
Magnus Damm 已提交
445

446
		sh_cmt_write_cmcor(ch, new_match);
M
Magnus Damm 已提交
447

448 449
		now = sh_cmt_get_counter(ch, &has_wrapped);
		if (has_wrapped && (new_match > ch->match_value)) {
M
Magnus Damm 已提交
450 451 452 453 454 455
			/* 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.
			 */
456
			ch->flags |= FLAG_SKIPEVENT;
M
Magnus Damm 已提交
457 458 459 460 461 462 463 464 465 466
			break;
		}

		if (has_wrapped) {
			/* we are changing to a smaller match value,
			 * so the wrap must be caused by the counter
			 * matching the new value.
			 * -> save programmed match value.
			 * -> let isr handle the event.
			 */
467
			ch->match_value = new_match;
M
Magnus Damm 已提交
468 469 470 471 472 473 474 475 476 477
			break;
		}

		/* be safe: verify hardware settings */
		if (now < new_match) {
			/* timer value is below match value, all good.
			 * this makes sure we won't miss any match events.
			 * -> save programmed match value.
			 * -> let isr handle the event.
			 */
478
			ch->match_value = new_match;
M
Magnus Damm 已提交
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
			break;
		}

		/* the counter has reached a value greater
		 * than our new match value. and since the
		 * has_wrapped flag isn't set we must have
		 * programmed a too close event.
		 * -> increase delay and retry.
		 */
		if (delay)
			delay <<= 1;
		else
			delay = 1;

		if (!delay)
494 495
			dev_warn(&ch->cmt->pdev->dev, "ch%u: too long delay\n",
				 ch->index);
M
Magnus Damm 已提交
496 497 498 499

	} while (delay);
}

500
static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
M
Magnus Damm 已提交
501
{
502
	if (delta > ch->max_match_value)
503 504
		dev_warn(&ch->cmt->pdev->dev, "ch%u: delta out of range\n",
			 ch->index);
M
Magnus Damm 已提交
505

506 507
	ch->next_match_value = delta;
	sh_cmt_clock_event_program_verify(ch, 0);
508 509
}

510
static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
511 512 513
{
	unsigned long flags;

514 515 516
	raw_spin_lock_irqsave(&ch->lock, flags);
	__sh_cmt_set_next(ch, delta);
	raw_spin_unlock_irqrestore(&ch->lock, flags);
M
Magnus Damm 已提交
517 518 519 520
}

static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
{
521
	struct sh_cmt_channel *ch = dev_id;
M
Magnus Damm 已提交
522 523

	/* clear flags */
524 525
	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
			   ch->cmt->info->clear_bits);
M
Magnus Damm 已提交
526 527 528 529 530

	/* 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.
	 */
531 532
	if (ch->flags & FLAG_CLOCKSOURCE)
		ch->total_cycles += ch->match_value + 1;
M
Magnus Damm 已提交
533

534 535
	if (!(ch->flags & FLAG_REPROGRAM))
		ch->next_match_value = ch->max_match_value;
M
Magnus Damm 已提交
536

537
	ch->flags |= FLAG_IRQCONTEXT;
M
Magnus Damm 已提交
538

539 540 541 542 543
	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;
M
Magnus Damm 已提交
544 545
			}

546
			ch->ced.event_handler(&ch->ced);
M
Magnus Damm 已提交
547 548 549
		}
	}

550
	ch->flags &= ~FLAG_SKIPEVENT;
M
Magnus Damm 已提交
551

552 553 554
	if (ch->flags & FLAG_REPROGRAM) {
		ch->flags &= ~FLAG_REPROGRAM;
		sh_cmt_clock_event_program_verify(ch, 1);
M
Magnus Damm 已提交
555

556 557 558 559
		if (ch->flags & FLAG_CLOCKEVENT)
			if ((ch->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
			    || (ch->match_value == ch->next_match_value))
				ch->flags &= ~FLAG_REPROGRAM;
M
Magnus Damm 已提交
560 561
	}

562
	ch->flags &= ~FLAG_IRQCONTEXT;
M
Magnus Damm 已提交
563 564 565 566

	return IRQ_HANDLED;
}

567
static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
M
Magnus Damm 已提交
568 569 570 571
{
	int ret = 0;
	unsigned long flags;

572
	raw_spin_lock_irqsave(&ch->lock, flags);
M
Magnus Damm 已提交
573

574 575
	if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
		ret = sh_cmt_enable(ch, &ch->rate);
M
Magnus Damm 已提交
576 577 578

	if (ret)
		goto out;
579
	ch->flags |= flag;
M
Magnus Damm 已提交
580 581

	/* setup timeout if no clockevent */
582 583
	if ((flag == FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT)))
		__sh_cmt_set_next(ch, ch->max_match_value);
M
Magnus Damm 已提交
584
 out:
585
	raw_spin_unlock_irqrestore(&ch->lock, flags);
M
Magnus Damm 已提交
586 587 588 589

	return ret;
}

590
static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag)
M
Magnus Damm 已提交
591 592 593 594
{
	unsigned long flags;
	unsigned long f;

595
	raw_spin_lock_irqsave(&ch->lock, flags);
M
Magnus Damm 已提交
596

597 598
	f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
	ch->flags &= ~flag;
M
Magnus Damm 已提交
599

600 601
	if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
		sh_cmt_disable(ch);
M
Magnus Damm 已提交
602 603

	/* adjust the timeout to maximum if only clocksource left */
604 605
	if ((flag == FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE))
		__sh_cmt_set_next(ch, ch->max_match_value);
M
Magnus Damm 已提交
606

607
	raw_spin_unlock_irqrestore(&ch->lock, flags);
M
Magnus Damm 已提交
608 609
}

610
static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
611
{
612
	return container_of(cs, struct sh_cmt_channel, cs);
613 614 615 616
}

static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
{
617
	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
618 619 620 621
	unsigned long flags, raw;
	unsigned long value;
	int has_wrapped;

622 623 624
	raw_spin_lock_irqsave(&ch->lock, flags);
	value = ch->total_cycles;
	raw = sh_cmt_get_counter(ch, &has_wrapped);
625 626

	if (unlikely(has_wrapped))
627 628
		raw += ch->match_value + 1;
	raw_spin_unlock_irqrestore(&ch->lock, flags);
629 630 631 632 633 634

	return value + raw;
}

static int sh_cmt_clocksource_enable(struct clocksource *cs)
{
635
	int ret;
636
	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
637

638
	WARN_ON(ch->cs_enabled);
639

640
	ch->total_cycles = 0;
641

642
	ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE);
643
	if (!ret) {
644 645
		__clocksource_updatefreq_hz(cs, ch->rate);
		ch->cs_enabled = true;
646
	}
647
	return ret;
648 649 650 651
}

static void sh_cmt_clocksource_disable(struct clocksource *cs)
{
652
	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
653

654
	WARN_ON(!ch->cs_enabled);
655

656 657
	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
	ch->cs_enabled = false;
658 659
}

660 661
static void sh_cmt_clocksource_suspend(struct clocksource *cs)
{
662
	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
663

664 665
	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
666 667
}

668 669
static void sh_cmt_clocksource_resume(struct clocksource *cs)
{
670
	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
671

672 673
	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
	sh_cmt_start(ch, FLAG_CLOCKSOURCE);
674 675
}

676
static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
677
				       const char *name)
678
{
679
	struct clocksource *cs = &ch->cs;
680 681

	cs->name = name;
682
	cs->rating = 125;
683 684 685
	cs->read = sh_cmt_clocksource_read;
	cs->enable = sh_cmt_clocksource_enable;
	cs->disable = sh_cmt_clocksource_disable;
686
	cs->suspend = sh_cmt_clocksource_suspend;
687
	cs->resume = sh_cmt_clocksource_resume;
688 689
	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
690

691 692
	dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
		 ch->index);
693

694 695
	/* Register with dummy 1 Hz value, gets updated in ->enable() */
	clocksource_register_hz(cs, 1);
696 697 698
	return 0;
}

699
static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
M
Magnus Damm 已提交
700
{
701
	return container_of(ced, struct sh_cmt_channel, ced);
M
Magnus Damm 已提交
702 703
}

704
static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
M
Magnus Damm 已提交
705
{
706
	struct clock_event_device *ced = &ch->ced;
M
Magnus Damm 已提交
707

708
	sh_cmt_start(ch, FLAG_CLOCKEVENT);
M
Magnus Damm 已提交
709 710 711 712

	/* TODO: calculate good shift from rate and counter bit width */

	ced->shift = 32;
713 714
	ced->mult = div_sc(ch->rate, NSEC_PER_SEC, ced->shift);
	ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
M
Magnus Damm 已提交
715 716 717
	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);

	if (periodic)
718
		sh_cmt_set_next(ch, ((ch->rate + HZ/2) / HZ) - 1);
M
Magnus Damm 已提交
719
	else
720
		sh_cmt_set_next(ch, ch->max_match_value);
M
Magnus Damm 已提交
721 722 723 724 725
}

static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
				    struct clock_event_device *ced)
{
726
	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
M
Magnus Damm 已提交
727 728 729 730 731

	/* deal with old setting first */
	switch (ced->mode) {
	case CLOCK_EVT_MODE_PERIODIC:
	case CLOCK_EVT_MODE_ONESHOT:
732
		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
M
Magnus Damm 已提交
733 734 735 736 737 738 739
		break;
	default:
		break;
	}

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
740
		dev_info(&ch->cmt->pdev->dev,
741
			 "ch%u: used for periodic clock events\n", ch->index);
742
		sh_cmt_clock_event_start(ch, 1);
M
Magnus Damm 已提交
743 744
		break;
	case CLOCK_EVT_MODE_ONESHOT:
745
		dev_info(&ch->cmt->pdev->dev,
746
			 "ch%u: used for oneshot clock events\n", ch->index);
747
		sh_cmt_clock_event_start(ch, 0);
M
Magnus Damm 已提交
748 749 750
		break;
	case CLOCK_EVT_MODE_SHUTDOWN:
	case CLOCK_EVT_MODE_UNUSED:
751
		sh_cmt_stop(ch, FLAG_CLOCKEVENT);
M
Magnus Damm 已提交
752 753 754 755 756 757 758 759 760
		break;
	default:
		break;
	}
}

static int sh_cmt_clock_event_next(unsigned long delta,
				   struct clock_event_device *ced)
{
761
	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
M
Magnus Damm 已提交
762 763

	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
764 765
	if (likely(ch->flags & FLAG_IRQCONTEXT))
		ch->next_match_value = delta - 1;
M
Magnus Damm 已提交
766
	else
767
		sh_cmt_set_next(ch, delta - 1);
M
Magnus Damm 已提交
768 769 770 771

	return 0;
}

772 773
static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
{
774
	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
775

776 777
	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
	clk_unprepare(ch->cmt->clk);
778 779 780 781
}

static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
{
782
	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
783

784 785
	clk_prepare(ch->cmt->clk);
	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
786 787
}

788
static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
789
				       const char *name)
M
Magnus Damm 已提交
790
{
791
	struct clock_event_device *ced = &ch->ced;
M
Magnus Damm 已提交
792 793 794 795

	ced->name = name;
	ced->features = CLOCK_EVT_FEAT_PERIODIC;
	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
796
	ced->rating = 125;
797
	ced->cpumask = cpu_possible_mask;
M
Magnus Damm 已提交
798 799
	ced->set_next_event = sh_cmt_clock_event_next;
	ced->set_mode = sh_cmt_clock_event_mode;
800 801
	ced->suspend = sh_cmt_clock_event_suspend;
	ced->resume = sh_cmt_clock_event_resume;
M
Magnus Damm 已提交
802

803 804
	dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
		 ch->index);
M
Magnus Damm 已提交
805 806 807
	clockevents_register_device(ced);
}

808
static int sh_cmt_register(struct sh_cmt_channel *ch, const char *name,
809
			   bool clockevent, bool clocksource)
M
Magnus Damm 已提交
810
{
811 812
	if (clockevent) {
		ch->cmt->has_clockevent = true;
813
		sh_cmt_register_clockevent(ch, name);
814
	}
M
Magnus Damm 已提交
815

816 817
	if (clocksource) {
		ch->cmt->has_clocksource = true;
818
		sh_cmt_register_clocksource(ch, name);
819
	}
820

M
Magnus Damm 已提交
821 822 823
	return 0;
}

824
static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
825 826
				unsigned int hwidx, bool clockevent,
				bool clocksource, struct sh_cmt_device *cmt)
827 828 829 830
{
	int irq;
	int ret;

831 832 833 834
	/* Skip unused channels. */
	if (!clockevent && !clocksource)
		return 0;

835
	ch->cmt = cmt;
836
	ch->index = index;
837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
	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;
		}
	}

	if (cmt->legacy)
		irq = platform_get_irq(cmt->pdev, 0);
	else
		irq = platform_get_irq(cmt->pdev, ch->index);
876 877

	if (irq < 0) {
878 879
		dev_err(&cmt->pdev->dev, "ch%u: failed to get irq\n",
			ch->index);
880 881 882
		return irq;
	}

883
	if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
884 885
		ch->max_match_value = ~0;
	else
886
		ch->max_match_value = (1 << cmt->info->width) - 1;
887 888 889 890

	ch->match_value = ch->max_match_value;
	raw_spin_lock_init(&ch->lock);

891 892 893 894 895 896 897
	if (cmt->legacy) {
		ch->timer_bit = ch->hwidx;
	} else {
		ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2
			      ? 0 : ch->hwidx;
	}

898
	ret = sh_cmt_register(ch, dev_name(&cmt->pdev->dev),
899
			      clockevent, clocksource);
900
	if (ret) {
901 902
		dev_err(&cmt->pdev->dev, "ch%u: registration failed\n",
			ch->index);
903 904 905 906 907 908 909 910
		return ret;
	}
	ch->cs_enabled = false;

	ret = request_irq(irq, sh_cmt_interrupt,
			  IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
			  dev_name(&cmt->pdev->dev), ch);
	if (ret) {
911 912
		dev_err(&cmt->pdev->dev, "ch%u: failed to request irq %d\n",
			ch->index, irq);
913 914 915 916 917 918
		return ret;
	}

	return 0;
}

919
static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
M
Magnus Damm 已提交
920
{
921
	struct resource *mem;
M
Magnus Damm 已提交
922

923 924 925 926 927
	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;
	}
M
Magnus Damm 已提交
928

929 930 931 932
	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;
M
Magnus Damm 已提交
933 934
	}

935 936 937 938 939 940 941 942 943
	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 */
944
	res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
M
Magnus Damm 已提交
945
	if (!res) {
946
		dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
947
		return -ENXIO;
M
Magnus Damm 已提交
948 949
	}

950 951
	cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
	if (cmt->mapbase_ch == NULL) {
952
		dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
953
		return -ENXIO;
M
Magnus Damm 已提交
954 955
	}

956 957 958
	/* optional resource for the shared timer start/stop register */
	res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);

959
	/* map second resource for CMSTR */
960 961 962 963
	cmt->mapbase = ioremap_nocache(res2 ? res2->start :
				       res->start - cfg->channel_offset,
				       res2 ? resource_size(res2) : 2);
	if (cmt->mapbase == NULL) {
964
		dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
965 966
		iounmap(cmt->mapbase_ch);
		return -ENXIO;
967 968
	}

969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
	/* 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 hw_channels;
	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. */
1006
	cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : "fck");
1007 1008
	if (IS_ERR(cmt->clk)) {
		dev_err(&cmt->pdev->dev, "cannot get clock\n");
1009
		return PTR_ERR(cmt->clk);
M
Magnus Damm 已提交
1010 1011
	}

1012
	ret = clk_prepare(cmt->clk);
1013
	if (ret < 0)
1014
		goto err_clk_put;
1015

1016 1017 1018 1019 1020 1021 1022
	/*
	 * 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);
1023
	else
1024
		ret = sh_cmt_map_memory(cmt);
M
Magnus Damm 已提交
1025

1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
	if (ret < 0)
		goto err_clk_unprepare;

	/* Allocate and setup the channels. */
	if (cmt->legacy) {
		cmt->num_channels = 1;
		hw_channels = 0;
	} else {
		cmt->num_channels = hweight8(cfg->channels_mask);
		hw_channels = cfg->channels_mask;
	}

	cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
				GFP_KERNEL);
1040 1041
	if (cmt->channels == NULL) {
		ret = -ENOMEM;
1042
		goto err_unmap;
1043 1044
	}

1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
	if (cmt->legacy) {
		ret = sh_cmt_setup_channel(&cmt->channels[0],
					   cfg->timer_bit, cfg->timer_bit,
					   cfg->clockevent_rating != 0,
					   cfg->clocksource_rating != 0, cmt);
		if (ret < 0)
			goto err_unmap;
	} else {
		unsigned int mask = hw_channels;
		unsigned int i;
1055

1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
		/*
		 * Use the first channel as a clock event device and the second
		 * channel as a clock source. If only one channel is available
		 * use it for both.
		 */
		for (i = 0; i < cmt->num_channels; ++i) {
			unsigned int hwidx = ffs(mask) - 1;
			bool clocksource = i == 1 || cmt->num_channels == 1;
			bool clockevent = i == 0;

			ret = sh_cmt_setup_channel(&cmt->channels[i], i, hwidx,
						   clockevent, clocksource,
						   cmt);
			if (ret < 0)
				goto err_unmap;

			mask &= ~(1 << hwidx);
		}
	}
1075

1076
	platform_set_drvdata(pdev, cmt);
1077

1078
	return 0;
1079 1080

err_unmap:
1081
	kfree(cmt->channels);
1082 1083
	sh_cmt_unmap_memory(cmt);
err_clk_unprepare:
1084
	clk_unprepare(cmt->clk);
1085
err_clk_put:
1086
	clk_put(cmt->clk);
M
Magnus Damm 已提交
1087 1088 1089
	return ret;
}

1090
static int sh_cmt_probe(struct platform_device *pdev)
M
Magnus Damm 已提交
1091
{
1092
	struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
M
Magnus Damm 已提交
1093 1094
	int ret;

1095
	if (!is_early_platform_device(pdev)) {
1096 1097
		pm_runtime_set_active(&pdev->dev);
		pm_runtime_enable(&pdev->dev);
1098
	}
1099

1100
	if (cmt) {
1101
		dev_info(&pdev->dev, "kept as earlytimer\n");
1102
		goto out;
1103 1104
	}

1105
	cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
1106
	if (cmt == NULL) {
M
Magnus Damm 已提交
1107 1108 1109 1110
		dev_err(&pdev->dev, "failed to allocate driver data\n");
		return -ENOMEM;
	}

1111
	ret = sh_cmt_setup(cmt, pdev);
M
Magnus Damm 已提交
1112
	if (ret) {
1113
		kfree(cmt);
1114 1115
		pm_runtime_idle(&pdev->dev);
		return ret;
M
Magnus Damm 已提交
1116
	}
1117 1118 1119 1120
	if (is_early_platform_device(pdev))
		return 0;

 out:
1121
	if (cmt->has_clockevent || cmt->has_clocksource)
1122 1123 1124 1125 1126
		pm_runtime_irq_safe(&pdev->dev);
	else
		pm_runtime_idle(&pdev->dev);

	return 0;
M
Magnus Damm 已提交
1127 1128
}

1129
static int sh_cmt_remove(struct platform_device *pdev)
M
Magnus Damm 已提交
1130 1131 1132 1133
{
	return -EBUSY; /* cannot unregister clockevent and clocksource */
}

1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
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);

M
Magnus Damm 已提交
1145 1146
static struct platform_driver sh_cmt_device_driver = {
	.probe		= sh_cmt_probe,
1147
	.remove		= sh_cmt_remove,
M
Magnus Damm 已提交
1148 1149
	.driver		= {
		.name	= "sh_cmt",
1150 1151
	},
	.id_table	= sh_cmt_id_table,
M
Magnus Damm 已提交
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
};

static int __init sh_cmt_init(void)
{
	return platform_driver_register(&sh_cmt_device_driver);
}

static void __exit sh_cmt_exit(void)
{
	platform_driver_unregister(&sh_cmt_device_driver);
}

1164
early_platform_init("earlytimer", &sh_cmt_device_driver);
1165
subsys_initcall(sh_cmt_init);
M
Magnus Damm 已提交
1166 1167 1168 1169 1170
module_exit(sh_cmt_exit);

MODULE_AUTHOR("Magnus Damm");
MODULE_DESCRIPTION("SuperH CMT Timer Driver");
MODULE_LICENSE("GPL v2");