Module: xenomai-3
Branch: next
Commit: 071f1988b3a8fd50fb96c4c0f8d818bf17fbe11a
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=071f1988b3a8fd50fb96c4c0f8d818bf17fbe11a

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Jul 15 11:02:42 2016 +0200

cobalt/clock: add limited support for handling frequency updates

This support is aimed at handling changes in the clock device
frequency while the kernel boots. No provision for handling CPUFREQ
events during runtime.

---

 include/cobalt/kernel/clock.h |    2 ++
 kernel/cobalt/clock.c         |   26 ++++++++++++++++++--------
 kernel/cobalt/posix/process.c |   14 ++++++++++++++
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index c290b1d..3dfff38 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -328,6 +328,8 @@ static inline void xnclock_init_proc(void) { }
 static inline void xnclock_cleanup_proc(void) { }
 #endif
 
+void xnclock_update_freq(unsigned long long freq);
+
 int xnclock_init(unsigned long long freq);
 
 void xnclock_cleanup(void);
diff --git a/kernel/cobalt/clock.c b/kernel/cobalt/clock.c
index 1794f0e..647eca3 100644
--- a/kernel/cobalt/clock.c
+++ b/kernel/cobalt/clock.c
@@ -819,6 +819,23 @@ void xnclock_tick(struct xnclock *clock)
 }
 EXPORT_SYMBOL_GPL(xnclock_tick);
 
+void xnclock_update_freq(unsigned long long freq)
+{
+       spl_t s;
+
+       xnlock_get_irqsave(&nklock, s);
+       clockfreq = freq;
+#ifdef XNARCH_HAVE_LLMULSHFT
+       xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
+#ifdef XNARCH_HAVE_NODIV_LLIMD
+       xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
+       xnarch_init_u32frac(&bln_frac, 1, 1000000000);
+#endif
+#endif
+       cobalt_pipeline.clock_freq = freq;
+       xnlock_put_irqrestore(&nklock, s);
+}
+
 static int set_core_clock_gravity(struct xnclock *clock,
                                  const struct xnclock_gravity *p)
 {
@@ -861,14 +878,7 @@ void xnclock_cleanup(void)
 
 int __init xnclock_init(unsigned long long freq)
 {
-       clockfreq = freq;
-#ifdef XNARCH_HAVE_LLMULSHFT
-       xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
-#ifdef XNARCH_HAVE_NODIV_LLIMD
-       xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
-       xnarch_init_u32frac(&bln_frac, 1, 1000000000);
-#endif
-#endif
+       xnclock_update_freq(freq);
        nktimerlat = xnarch_timer_calibrate();
        xnclock_reset_gravity(&nkclock);
        xnclock_register(&nkclock, &xnsched_realtime_cpus);
diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index ca0ef2b..f8cfcb4 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -1269,6 +1269,15 @@ static int handle_cleanup_event(struct mm_struct *mm)
        return KEVENT_PROPAGATE;
 }
 
+static int handle_clockfreq_event(unsigned int *p)
+{
+       unsigned int newfreq = *p;
+
+       xnclock_update_freq(newfreq);
+
+       return KEVENT_PROPAGATE;
+}
+
 int ipipe_kevent_hook(int kevent, void *data)
 {
        int ret;
@@ -1292,6 +1301,11 @@ int ipipe_kevent_hook(int kevent, void *data)
        case IPIPE_KEVT_SETAFFINITY:
                ret = handle_setaffinity_event(data);
                break;
+#ifdef IPIPE_KEVT_CLOCKFREQ
+       case IPIPE_KEVT_CLOCKFREQ:
+               ret = handle_clockfreq_event(data);
+               break;
+#endif
        default:
                ret = KEVENT_PROPAGATE;
        }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to