Module: xenomai-3
Branch: wip/drivers
Commit: 6c18d206f4d5f25b9d02d128bcfddbc3938d4236
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=6c18d206f4d5f25b9d02d128bcfddbc3938d4236

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 efd6b9e..b112a1a 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -1262,6 +1262,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;
@@ -1285,6 +1294,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