CPM2 Timers API
PATCH 1/1 CPM2 Timers API
Two patches:
cpm-timer.patch:
The base timers API for CPM2 timers
cpm-timer.mpc85xx-devices.patch:
MPC85xx support
Signature · 2 lines
Jason McMullan <[email protected]> TimeSys Corporation
Description: MPC85xx support for CPM2 timers
Date: Thu Mar 31 14:49:49 EST 2005
Patches: linux-2.6.12-rc1.bk
Difference summary:
arch/ppc/syslib/mpc85xx_devices.c | 25 +++++++++++++++++++++++++ arch/ppc/syslib/mpc85xx_sys.c | 17 ++++++++++------- include/asm-ppc/mpc85xx.h | 1 + 3 files changed, 36 insertions(+), 7 deletions(-)
arch/ppc/syslib/mpc85xx_devices.c +25 -0
@@ -19,6 +19,8 @@#include <linux/serial_8250.h> #include <linux/fsl_devices.h> #include <asm/mpc85xx.h> +#include <asm/cpm2.h> +#include <asm/immap_cpm2.h> #include <asm/irq.h> #include <asm/ppc_sys.h>
@@ -61,8 +63,14 @@ .iotype = UPIO_MEM, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ, }, + [2] = { + .flags = 0 + } }; +#define CPM2_OFFSET (t) ((void *)(&((cpm2_map_t *)NULL)->t)-NULL) +#define CPM2_END (t) (CPM2_OFFSET(t)+(sizeof(((cpm2_map_t *)NULL)->t))-1) +struct platform_device ppc_sys_platform_devices[] = { [MPC85xx_TSEC1] = { .name ="fsl-gianfar" ,
@@ -534,6 +542,23 @@ }, }, }, + [MPC85xx_CPM_TIMER] = { + .name = "fsl-cpm-timer", + .id = 0, + .num_resources = 2, + .resource = (struct resource []) { + { + .start =CPM2_OFFSET (im_cpmtimer), + .end =CPM2_END (im_cpmtimer), + .flags =IORESOURCE_MEM , + }, + { + .start =SIU_INT_TIMER1 , + .end =SIU_INT_TIMER4 , + .flags =IORESOURCE_IRQ , + }, + }, + }, #endif /* CONFIG_CPM2 */ };
arch/ppc/syslib/mpc85xx_sys.c +10 -7
@@ -36,7 +36,7 @@ .ppc_sys_name = "8560", .mask = 0xFFFF0000, .value = 0x80700000, - .num_devices = 19, + .num_devices = 20, .device_list = (enum ppc_sys_devices []) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -46,13 +46,14 @@ MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_SCC4, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3, MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2, + MPC85xx_CPM_TIMER, }, }, { .ppc_sys_name ="8541" , .mask = 0xFFFF0000, .value = 0x80720000, - .num_devices = 13, + .num_devices = 14, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -60,13 +61,14 @@ MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, + MPC85xx_CPM_TIMER, }, }, { .ppc_sys_name ="8541E" , .mask = 0xFFFF0000, .value = 0x807A0000, - .num_devices = 14, + .num_devices = 15, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -74,13 +76,14 @@ MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, + MPC85xx_CPM_TIMER, }, }, { .ppc_sys_name ="8555" , .mask = 0xFFFF0000, .value = 0x80710000, - .num_devices = 19, + .num_devices = 20, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -90,14 +93,14 @@ MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2, - MPC85xx_CPM_USB, + MPC85xx_CPM_USB, MPC85xx_CPM_TIMER, }, }, { .ppc_sys_name ="8555E" , .mask = 0xFFFF0000, .value = 0x80790000, - .num_devices = 20, + .num_devices = 21, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -107,7 +110,7 @@ MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2, - MPC85xx_CPM_USB, + MPC85xx_CPM_USB, MPC85xx_CPM_TIMER, }, }, { /* default match */
include/asm-ppc/mpc85xx.h +1 -0
@@ -127,6 +127,7 @@ MPC85xx_CPM_MCC2, MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2, + MPC85xx_CPM_TIMER, };#endif /* CONFIG_85xx */
Description: CPM2 Timers API
Date: Thu Mar 31 14:49:49 EST 2005
Patches: linux-2.6.12-rc1.bk
Difference summary:
arch/ppc/Kconfig | 6 arch/ppc/syslib/Makefile | 1 arch/ppc/syslib/cpm_timer.c | 522 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/cpm_timer.h | 74 ++++++ 4 files changed, 603 insertions(+)
arch/ppc/Kconfig +6 -0
@@ -713,6 +713,12 @@ you wish to build a kernel for a machine with a CPM2 coprocessor on it (826x, 827x, 8560). +config CPM_TIMER + tristate "CPM2 Timers" + depends on 8260 || 85xx + help + Includes kernel support for CPM2 timers + config PPC_CHRP bool depends on PPC_MULTIPLATFORM
arch/ppc/syslib/cpm_timer.c +522 -0
522 lines not on this page · raw message
arch/ppc/syslib/Makefile +1 -0
@@ -84,6 +84,7 @@ obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o +obj-$(CONFIG_CPM_TIMER) += cpm_timer.o ifeq ($(CONFIG_PPC_GEN550),y) obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen550_dbg.o
include/asm-ppc/cpm_timer.h +74 -0
74 lines not on this page · raw message
A brown bag error handling and Lindent patch, to be applied in that order, to my previous CPM timers patch.
Signature · 2 lines
Jason McMullan <[email protected]> TimeSys Corporation
arch/ppc/syslib/cpm_timer.c renamed from arch/ppc/syslib/cpm_timer.c.orig +7 -3
@@ -114,12 +114,16 @@ tm->start = (timer_id>>4 )&0xf ; tm->end = timer_id &0xf ; -if (tm->start >3 ) +if (tm->start >3 ) { +kfree (tm);return -EINVAL ; + }if ((tm->end != tm->start) && - ((tm->start &1 ) || (tm->end != (tm->start+1 )))) -return -EINVAL ; + ((tm->start &1 ) || (tm->end != (tm->start+1 )))) { +kfree (tm); +return -EINVAL ; + } err =request_resource (&cpm_timer_resource,tm);if (err <0 ) {
arch/ppc/syslib/cpm_timer.c +47 -44
242 lines not on this page · raw message
And here's the test-case kernel module....
Signature · 2 lines
Jason McMullan <[email protected]> TimeSys Corporation
/*
* CPM Timers test
*
* Copyright 2004, Timesys Corp.
* Jason McMullan <[email protected]>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <asm/cpm_timer.h>
static int failed = 0;
static volatile int once, every;
static wait_queue_head_t queue;
#define FAILED(x, args...) do { failed++; printk(KERN_INFO "cpm_timer_test: " x , ## args ); if (tm != NULL) { cpm_timer_stop(tm); cpm_timer_free(tm); } return -EINVAL; } while (0)
static void cpm_timer_test_callback(cpm_timer_t tm, void *data)
{
if (data == &once) {
unsigned long val = cpm_timer_get_ticks(tm);
printk(KERN_INFO "cpm_timer_test: Called once at tick %ld.\n",
val);
once++;
wmb();
}
if (data == &every) {
unsigned long val = cpm_timer_get_ticks(tm);
printk(KERN_INFO
"cpm_timer_test: Called every(%d), tick %ld.\n", every,
val);
every++;
if (every > 5)
cpm_timer_call_none(tm);
wmb();
}
wake_up_interruptible(&queue);
}static int test_timer(int timer_id)
{
cpm_timer_t tm = NULL;
int err;
unsigned long res, val;
printk(KERN_INFO "cpm_timer_test: Test timer ID 0x%.2x\n", timer_id);
err = cpm_timer_alloc(timer_id, &tm);
if (err < 0)
FAILED("Can't allocate timer 0x%.2x\n", timer_id);
res = cpm_timer_get_resolution(tm);
printk(KERN_INFO "cpm_timer_test: nanoseconds/tick = %ld\n", res);
val = cpm_timer_get_ticks(tm);
printk(KERN_INFO "cpm_timer_test: current value = %ld\n", val);
cpm_timer_stop(tm);
cpm_timer_reset(tm);
val = cpm_timer_get_ticks(tm);
printk(KERN_INFO "cpm_timer_test: value after stop/reset= %ld\n", val);
if (val != 0)
FAILED("Timer 0x%.2x didn't stop!\n", timer_id);
cpm_timer_start(tm);
udelay(5);
val = cpm_timer_get_ticks(tm);
udelay(5);
res = cpm_timer_get_ticks(tm);
printk(KERN_INFO "cpm_timer_test: value after 5 us= %ld\n", val);
printk(KERN_INFO "cpm_timer_test: value after 10 us= %ld\n", res);
if (val == 0 || res == 0)
FAILED("Timer 0x%.2x didn't increment!\n", timer_id);
init_waitqueue_head(&queue);
once = 0;
err =
cpm_timer_call_once(tm, 50000, cpm_timer_test_callback,
(void *)&once);
if (err < 0)
FAILED("Can't call cpm_timer_call_once for 0x%.2x\n", timer_id);
printk(KERN_INFO "cpm_timer_test: Waiting for one-shot...\n");
cpm_timer_start(tm);
err = wait_event_interruptible(queue, once != 0);
if (err < 0)
FAILED("Interrupted sleep for 0x%.2x\n", timer_id);
every = 0;
err =
cpm_timer_call_every(tm, 50000, cpm_timer_test_callback,
(void *)&every);
if (err < 0)
FAILED("Can't call cpm_timer_call_every for 0x%.2x\n",
timer_id);
printk(KERN_INFO "cpm_timer_test: Waiting for multi-shot x5...\n");
cpm_timer_start(tm);
err = wait_event_interruptible(queue, every > 5);
if (err < 0)
FAILED("Interrupted sleep for 0x%.2x\n", timer_id);
cpm_timer_call_none(tm);
printk(KERN_INFO "cpm_timer_test: Counted up to %d.\n", every);
cpm_timer_stop(tm);
cpm_timer_free(tm);
return 0;
}static int cpm_timer_test_init(void)
{
int err;
printk(KERN_INFO "CPM2 Timer Test Module.\n");#define TEST(x) do { err=test_timer(x); if (err != 0) goto bad; } while (0)
TEST(CPM2_TIMER16_1);
TEST(CPM2_TIMER16_2);
TEST(CPM2_TIMER16_3);
TEST(CPM2_TIMER16_4);
TEST(CPM2_TIMER32_1);
TEST(CPM2_TIMER32_2);
bad:
if (failed) {
printk(KERN_INFO "cpm_timer_test: FAILED %d tests\n", failed);
} else {
printk(KERN_INFO "cpm_timer_test: PASSED\n");
}
return 0;
}static void cpm_timer_test_exit(void)
{
printk(KERN_INFO "CPM2 Timer Test Module unloaded.\n");
return;
}MODULE_LICENSE("GPL");module_init(cpm_timer_test_init);module_exit(cpm_timer_test_exit);