* the License, or (at your option) any later version.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/delay.h>
 
 #include "ccu_gate.h"
 #include "ccu_mux.h"
        .determine_rate = __clk_mux_determine_rate,
        .recalc_rate    = ccu_mux_recalc_rate,
 };
+
+/*
+ * This clock notifier is called when the frequency of the of the parent
+ * PLL clock is to be changed. The idea is to switch the parent to a
+ * stable clock, such as the main oscillator, while the PLL frequency
+ * stabilizes.
+ */
+static int ccu_mux_notifier_cb(struct notifier_block *nb,
+                              unsigned long event, void *data)
+{
+       struct ccu_mux_nb *mux = to_ccu_mux_nb(nb);
+       int ret = 0;
+
+       if (event == PRE_RATE_CHANGE) {
+               mux->original_index = ccu_mux_helper_get_parent(mux->common,
+                                                               mux->cm);
+               ret = ccu_mux_helper_set_parent(mux->common, mux->cm,
+                                               mux->bypass_index);
+       } else if (event == POST_RATE_CHANGE) {
+               ret = ccu_mux_helper_set_parent(mux->common, mux->cm,
+                                               mux->original_index);
+       }
+
+       udelay(mux->delay_us);
+
+       return notifier_from_errno(ret);
+}
+
+int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb)
+{
+       mux_nb->clk_nb.notifier_call = ccu_mux_notifier_cb;
+
+       return clk_notifier_register(clk, &mux_nb->clk_nb);
+}
 
                              struct ccu_mux_internal *cm,
                              u8 index);
 
+struct ccu_mux_nb {
+       struct notifier_block   clk_nb;
+       struct ccu_common       *common;
+       struct ccu_mux_internal *cm;
+
+       u32     delay_us;       /* How many us to wait after reparenting */
+       u8      bypass_index;   /* Which parent to temporarily use */
+       u8      original_index; /* This is set by the notifier callback */
+};
+
+#define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)
+
+int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);
+
 #endif /* _CCU_MUX_H_ */