I-pipe's current hooking into the GENERIC_CLOCKEVENTS infrastructure
contains an ugly out-of-band argument passing via the device structure
(delta...) and unneeded indirections of the intercepted services. This
patches overcomes both by cleanly modifying relevant properties of the
clock_event_device on takeover.

Jan
---
 include/linux/clockchips.h    |    1 
 include/linux/ipipe_tickdev.h |   11 +++++---
 kernel/ipipe/core.c           |   54 +++++++++++++++++-------------------------
 kernel/time/clockevents.c     |    1 
 4 files changed, 30 insertions(+), 37 deletions(-)

Index: linux-2.6.23.1-xeno/include/linux/clockchips.h
===================================================================
--- linux-2.6.23.1-xeno.orig/include/linux/clockchips.h
+++ linux-2.6.23.1-xeno/include/linux/clockchips.h
@@ -91,7 +91,6 @@ struct clock_event_device {
 	struct list_head	list;
 	enum clock_event_mode	mode;
 	ktime_t			next_event;
-	int64_t			delta;
 };
 
 /*
Index: linux-2.6.23.1-xeno/include/linux/ipipe_tickdev.h
===================================================================
--- linux-2.6.23.1-xeno.orig/include/linux/ipipe_tickdev.h
+++ linux-2.6.23.1-xeno/include/linux/ipipe_tickdev.h
@@ -31,21 +31,24 @@ struct tick_device;
 struct ipipe_tick_device {
 
 	void (*emul_set_mode)(enum clock_event_mode,
-			      struct ipipe_tick_device *tdev);
+			      struct clock_event_device *cdev);
 	int (*emul_set_tick)(unsigned long delta,
-			     struct ipipe_tick_device *tdev);
+			     struct clock_event_device *cdev);
 	void (*real_set_mode)(enum clock_event_mode mode,
 			      struct clock_event_device *cdev);
 	int (*real_set_tick)(unsigned long delta,
 			     struct clock_event_device *cdev);
 	struct tick_device *slave;
+	unsigned long real_max_delta_ns;
+	unsigned long real_mult;
+	int real_shift;
 };
 
 int ipipe_request_tickdev(const char *devname,
 			  void (*emumode)(enum clock_event_mode mode,
-					  struct ipipe_tick_device *tdev),
+					  struct clock_event_device *cdev),
 			  int (*emutick)(unsigned long evt,
-					 struct ipipe_tick_device *tdev),
+					 struct clock_event_device *cdev),
 			  int cpu, unsigned long *tick_freq);
 
 void ipipe_release_tickdev(int cpu);
Index: linux-2.6.23.1-xeno/kernel/ipipe/core.c
===================================================================
--- linux-2.6.23.1-xeno.orig/kernel/ipipe/core.c
+++ linux-2.6.23.1-xeno/kernel/ipipe/core.c
@@ -97,36 +97,16 @@ DECLARE_PER_CPU(struct tick_device, tick
 
 static DEFINE_PER_CPU(struct ipipe_tick_device, ipipe_tick_cpu_device);
 
-static void __ipipe_set_tick_mode(enum clock_event_mode mode,
-				  struct clock_event_device *cdev)
-{
-	struct ipipe_tick_device *itd;
-	itd = &per_cpu(ipipe_tick_cpu_device, smp_processor_id());
-	itd->emul_set_mode(mode, itd);
-}
-
-static int __ipipe_set_next_tick(unsigned long evt,
-				 struct clock_event_device *cdev)
-{
-	uint64_t delta_ns = (uint64_t)cdev->delta;
-	struct ipipe_tick_device *itd;
-
-	if (delta_ns > ULONG_MAX)
-		delta_ns = ULONG_MAX;
-
-	itd = &per_cpu(ipipe_tick_cpu_device, smp_processor_id());
-	return itd->emul_set_tick((unsigned long)delta_ns, itd);
-}
-
 int ipipe_request_tickdev(const char *devname,
 			  void (*emumode)(enum clock_event_mode mode,
-					  struct ipipe_tick_device *tdev),
+					  struct clock_event_device *cdev),
 			  int (*emutick)(unsigned long delta,
-					 struct ipipe_tick_device *tdev),
+					 struct clock_event_device *cdev),
 			  int cpu, unsigned long *tick_freq)
 {
 	struct ipipe_tick_device *itd;
 	struct tick_device *slave;
+	struct clock_event_device *evtdev;
 	unsigned long long freq;
 	unsigned long flags;
 	int status;
@@ -166,16 +146,23 @@ int ipipe_request_tickdev(const char *de
 	 * to oneshot dynamically (highres/no_hz tick mode).
 	 */
 
+	evtdev = slave->evtdev;
 	itd->slave = slave;
 	itd->emul_set_mode = emumode;
 	itd->emul_set_tick = emutick;
-	itd->real_set_mode = slave->evtdev->set_mode;
-	itd->real_set_tick = slave->evtdev->set_next_event;
-	freq = (1000000000ULL * slave->evtdev->mult) >> slave->evtdev->shift;
+	itd->real_set_mode = evtdev->set_mode;
+	itd->real_set_tick = evtdev->set_next_event;
+	itd->real_max_delta_ns = evtdev->max_delta_ns;
+	itd->real_mult = evtdev->mult;
+	itd->real_shift = evtdev->shift;
+	freq = (1000000000ULL * evtdev->mult) >> evtdev->shift;
 	*tick_freq = (unsigned long)freq;
-	slave->evtdev->set_mode = __ipipe_set_tick_mode;
-	slave->evtdev->set_next_event = __ipipe_set_next_tick;
-	status = slave->evtdev->mode;
+	evtdev->set_mode = emumode;
+	evtdev->set_next_event = emutick;
+	evtdev->max_delta_ns = ULONG_MAX;
+	evtdev->mult = 1;
+	evtdev->shift = 0;
+	status = evtdev->mode;
 out:
 	ipipe_critical_exit(flags);
 
@@ -186,6 +173,7 @@ void ipipe_release_tickdev(int cpu)
 {
 	struct ipipe_tick_device *itd;
 	struct tick_device *slave;
+	struct clock_event_device *evtdev;
 	unsigned long flags;
 
 	flags = ipipe_critical_enter(NULL);
@@ -194,8 +182,12 @@ void ipipe_release_tickdev(int cpu)
 
 	if (itd->slave != NULL) {
 		slave = &per_cpu(tick_cpu_device, cpu);
-		slave->evtdev->set_mode = itd->real_set_mode;
-		slave->evtdev->set_next_event = itd->real_set_tick;
+		evtdev = slave->evtdev;
+		evtdev->set_mode = itd->real_set_mode;
+		evtdev->set_next_event = itd->real_set_tick;
+		evtdev->max_delta_ns = itd->real_max_delta_ns;
+		evtdev->mult = itd->real_mult;
+		evtdev->shift = itd->real_shift;
 		itd->slave = NULL;
 	}
 
Index: linux-2.6.23.1-xeno/kernel/time/clockevents.c
===================================================================
--- linux-2.6.23.1-xeno.orig/kernel/time/clockevents.c
+++ linux-2.6.23.1-xeno/kernel/time/clockevents.c
@@ -84,7 +84,6 @@ int clockevents_program_event(struct clo
 		return -ETIME;
 
 	dev->next_event = expires;
-	dev->delta = delta;
 
 	if (dev->mode == CLOCK_EVT_MODE_SHUTDOWN)
 		return 0;

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to