unsigned long   m, min_m, max_m;
 };
 
+static unsigned long ccu_nm_calc_rate(unsigned long parent,
+                                     unsigned long n, unsigned long m)
+{
+       u64 rate = parent;
+
+       rate *= n;
+       do_div(rate, m);
+
+       return rate;
+}
+
 static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
                             struct _ccu_nm *nm)
 {
 
        for (_n = nm->min_n; _n <= nm->max_n; _n++) {
                for (_m = nm->min_m; _m <= nm->max_m; _m++) {
-                       unsigned long tmp_rate = parent * _n  / _m;
+                       unsigned long tmp_rate = ccu_nm_calc_rate(parent,
+                                                                 _n, _m);
 
                        if (tmp_rate > rate)
                                continue;
        if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm))
                rate = ccu_sdm_helper_read_rate(&nm->common, &nm->sdm, m, n);
        else
-               rate = parent_rate * n / m;
+               rate = ccu_nm_calc_rate(parent_rate, n, m);
 
        if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
                rate /= nm->fixed_post_div;
        _nm.max_m = nm->m.max ?: 1 << nm->m.width;
 
        ccu_nm_find_best(*parent_rate, rate, &_nm);
-       rate = *parent_rate * _nm.n / _nm.m;
+       rate = ccu_nm_calc_rate(*parent_rate, _nm.n, _nm.m);
 
        if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
                rate /= nm->fixed_post_div;