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;
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
