Title: [5312] trunk/drivers/char/bfin_timer_latency.c: [!no_src_qa!] Apply patch[#4398] from Luke Yang.
Revision
5312
Author
sonicz
Date
2008-09-18 03:53:29 -0500 (Thu, 18 Sep 2008)

Log Message

[!no_src_qa!] Apply patch[#4398] from Luke Yang.

Modified Paths

Diff

Modified: trunk/drivers/char/bfin_timer_latency.c (5311 => 5312)


--- trunk/drivers/char/bfin_timer_latency.c	2008-09-18 06:50:20 UTC (rev 5311)
+++ trunk/drivers/char/bfin_timer_latency.c	2008-09-18 08:53:29 UTC (rev 5312)
@@ -47,34 +47,53 @@
 
 struct timer_latency_data_t {
 	char value;
-	unsigned long  latency;
+	unsigned long last_latency;
+	unsigned long worst_latency;
+	unsigned long average_latency;
+	unsigned long test_number;
+	unsigned int period_sclk;
+	unsigned int period_cclk;
 };
 
 struct proc_dir_entry *timer_latency_file;
 struct timer_latency_data_t timer_latency_data;
 
 static int read_timer_latency(char *page, char **start,
-			      off_t offset, int count, int *eof,
-			      void *data)
+			      off_t offset, int count, int *eof, void *data)
 {
-	return sprintf(page, "%lu", timer_latency_data.latency);
+	return sprintf(page,
+		       "number, worst latency, average latency\n  %lu,      %lu,       %lu\n",
+		       timer_latency_data.test_number,
+		       timer_latency_data.worst_latency,
+		       timer_latency_data.average_latency);
 }
 
-
 static int write_timer_latency(struct file *file, const char *buffer,
-			   unsigned long count, void *data)
+			       unsigned long count, void *data)
 {
-	unsigned long sclk;
-	char user_value;
+	unsigned long sclk, cclk;
+	char user_value[8];
+	unsigned int wd_period_us;
+	unsigned int period_sclk;
+	unsigned int period_cclk;
 
-	copy_from_user(&(user_value), buffer, 1);
+	copy_from_user(user_value, buffer, count);
+	wd_period_us = strict_strtoul(user_value, NULL, 0);
 
-	if ((user_value == '1') && (timer_latency_data.value == 0)) {
+	if ((wd_period_us >= 100) && (timer_latency_data.value == 0)) {
 		DPRINTK("start timer_latency\n");
 		timer_latency_data.value = 1;
-		sclk = get_sclk();
-		bfin_write_WDOG_CNT(5 * sclk); /* set count time to 5 seconds */
-		/* set CYCLES counter to 0 and start it*/
+		sclk = get_sclk() / 1000000;
+		cclk = get_cclk() / 1000000;
+
+		/* convert from us to cycles */
+		timer_latency_data.period_sclk = wd_period_us * sclk;
+		timer_latency_data.period_cclk = wd_period_us * cclk;
+
+		/* set count timer cycles */
+		bfin_write_WDOG_CNT(timer_latency_data.period_sclk);
+
+		/* set CYCLES counter to 0 and start it */
 		__asm__(
 			"R2 = 0;\n\t"
 			"CYCLES = R2;\n\t"
@@ -85,17 +104,16 @@
 			"P2.H = 0xffc0;\n\t"
 			"P2.L = 0x0200;\n\t"
 			"R3 = 0x0004;\n\t"
-			"W[P2] = R3;\n\t"
+			"W[P2] = R3;\n\t"     /* start watchdog timer */
 			"SYSCFG = R2;\n\t"    /* start cycles counter */
 			: : : "R2", "R3", "P2"
 		);
 
 	}
 
-	return 1;  /* always write 1 byte*/
+	return 1;		/* always write 1 byte */
 }
 
-
 static irqreturn_t timer_latency_irq(int irq, void *dev_id)
 {
 	struct timer_latency_data_t *data = ""
@@ -105,16 +123,15 @@
 
 	/* unsigned long first_latency, second_latency, third_latency; */
 
-
 	/* get current cycle counter */
 	/*
-	asm("%0 = CYCLES; p2 = 0xFFE07040; %1 = [p2]; p2 = 0xFFE07044; %2 = [p2]; p2 = 0xFFE07048; %3 = [p2];"
-	: "=d" (cycles_past), "=d" (first_latency), "=d" (second_latency), "=d" (third_latency):); */
+	   asm("%0 = CYCLES; p2 = 0xFFE07040; %1 = [p2]; p2 = 0xFFE07044; %2 = [p2]; p2 = 0xFFE07048; %3 = [p2];"
+	   : "=d" (cycles_past), "=d" (first_latency), "=d" (second_latency), "=d" (third_latency):); */
 
-	asm("%0 = CYCLES;" : "=d" (cycles_past));
+      asm("%0 = CYCLES;":"=d"(cycles_past));
 
-	bfin_write_WDOG_CTL(0x8AD6);  /* close counter */
-	bfin_write_WDOG_CTL(0x8AD6);  /* have to write it twice to disable the timer */
+	bfin_write_WDOG_CTL(0x8AD6);	/* close counter */
+	bfin_write_WDOG_CTL(0x8AD6);	/* have to write it twice to disable the timer */
 
 	__asm__(                      /* stop CYCLES counter */
 		"R2 = SYSCFG;\n\t"
@@ -123,25 +140,43 @@
 		: : : "R2"
 	);
 
-	cclk = get_cclk();
+	latency = cycles_past - data->period_cclk;	/* latency in cycles */
 
-	/* printk("first_latency is %lu, second is %lu, third is %lu, latency is %lu\n", first_latency, second_latency, third_latency, cycles_past); */
+	DPRINTK("latecy is %lu\n", latency);
 
-	latency = cycles_past - (cclk * 5);    /* latency in us */
-	DPRINTK("latecy is %lu\n",latency);
-
 	if (bfin_read_WDOG_STAT() != 0) {
 		DPRINTK("timer_latency error!\n");
 		return IRQ_HANDLED;
 	}
 
-	data->latency = latency;
-	timer_latency_data.value = 0;
+	if (latency > data->worst_latency)
+		data->worst_latency = latency;
+	data->last_latency = latency;
+	data->test_number++;
+	data->average_latency =
+	    ((data->average_latency * (data->test_number - 1)) +
+	     latency) / (data->test_number);
 
+	/* restart watchdog timer again */
+	bfin_write_WDOG_CNT(data->period_sclk);
+
+	__asm__(
+		"R2 = 0;\n\t"
+		"CYCLES = R2;\n\t"
+		"CYCLES2 = R2;\n\t"
+		"R2 = SYSCFG;\n\t"
+		"BITSET(R2,1);\n\t"
+		"P2.H = 0xffc0;\n\t"
+		"P2.L = 0x0200;\n\t"
+		"R3 = 0x0004;\n\t"
+		"W[P2] = R3;\n\t"     /* start watchdog timer */
+		"SYSCFG = R2;\n\t"    /* start cycles counter */
+		: : : "R2", "R3", "P2"
+		);
+
 	return IRQ_HANDLED;
 }
 
-
 static int __init timer_latency_init(void)
 {
 	DPRINTK("timer_latency start!\n");
@@ -152,21 +187,23 @@
 
 	/* default value is 0 (timer is stopped) */
 	timer_latency_data.value = 0;
-	timer_latency_data.latency = 0;
+	timer_latency_data.worst_latency = 0;
+	timer_latency_data.average_latency = 0;
+	timer_latency_data.last_latency = 0;
 
 	timer_latency_file->data = ""
 	timer_latency_file->read_proc = &read_timer_latency;
 	timer_latency_file->write_proc = &write_timer_latency;
 	timer_latency_file->owner = THIS_MODULE;
 
-	request_irq(IRQ_WATCH, timer_latency_irq, IRQF_DISABLED, "timer_latency", &timer_latency_data);
+	request_irq(IRQ_WATCH, timer_latency_irq, IRQF_DISABLED,
+		    "timer_latency", &timer_latency_data);
 
 	printk(KERN_INFO "timer_latency module loaded\n");
 
-	return 0; /* everything's OK */
+	return 0;		/* everything's OK */
 }
 
-
 static void __exit timer_latency_exit(void)
 {
 	remove_proc_entry("timer_latency", NULL);
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to