#include <linux/clk-provider.h>
 #include "clkc.h"
 
-#define to_meson_clk_audio_divider(_hw) container_of(_hw, \
-                               struct meson_clk_audio_divider, hw)
+static inline struct meson_clk_audio_div_data *
+meson_clk_audio_div_data(struct clk_regmap *clk)
+{
+       return (struct meson_clk_audio_div_data *)clk->data;
+}
 
 static int _div_round(unsigned long parent_rate, unsigned long rate,
                      unsigned long flags)
        return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
 }
 
-static int _valid_divider(struct clk_hw *hw, int divider)
+static int _valid_divider(unsigned int width, int divider)
 {
-       struct meson_clk_audio_divider *adiv =
-               to_meson_clk_audio_divider(hw);
-       int max_divider;
-       u8 width;
-
-       width = adiv->div.width;
-       max_divider = 1 << width;
+       int max_divider = 1 << width;
 
        return clamp(divider, 1, max_divider);
 }
 static unsigned long audio_divider_recalc_rate(struct clk_hw *hw,
                                               unsigned long parent_rate)
 {
-       struct meson_clk_audio_divider *adiv =
-               to_meson_clk_audio_divider(hw);
-       struct parm *p;
-       unsigned long reg, divider;
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
+       unsigned long divider;
 
-       p = &adiv->div;
-       reg = readl(adiv->base + p->reg_off);
-       divider = PARM_GET(p->width, p->shift, reg) + 1;
+       divider = meson_parm_read(clk->map, &adiv->div);
 
        return DIV_ROUND_UP_ULL((u64)parent_rate, divider);
 }
                                     unsigned long rate,
                                     unsigned long *parent_rate)
 {
-       struct meson_clk_audio_divider *adiv =
-               to_meson_clk_audio_divider(hw);
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
        unsigned long max_prate;
        int divider;
 
        if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
                divider = _div_round(*parent_rate, rate, adiv->flags);
-               divider = _valid_divider(hw, divider);
+               divider = _valid_divider(adiv->div.width, divider);
                return DIV_ROUND_UP_ULL((u64)*parent_rate, divider);
        }
 
 
        /* Get the corresponding rounded down divider */
        divider = max_prate / rate;
-       divider = _valid_divider(hw, divider);
+       divider = _valid_divider(adiv->div.width, divider);
 
        /* Get actual rate of the parent */
        *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
                                  unsigned long rate,
                                  unsigned long parent_rate)
 {
-       struct meson_clk_audio_divider *adiv =
-               to_meson_clk_audio_divider(hw);
-       struct parm *p;
-       unsigned long reg, flags = 0;
-       int val;
-
-       val = _get_val(parent_rate, rate);
-
-       if (adiv->lock)
-               spin_lock_irqsave(adiv->lock, flags);
-       else
-               __acquire(adiv->lock);
-
-       p = &adiv->div;
-       reg = readl(adiv->base + p->reg_off);
-       reg = PARM_SET(p->width, p->shift, reg, val);
-       writel(reg, adiv->base + p->reg_off);
-
-       if (adiv->lock)
-               spin_unlock_irqrestore(adiv->lock, flags);
-       else
-               __release(adiv->lock);
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
+       int val = _get_val(parent_rate, rate);
+
+       meson_parm_write(clk->map, &adiv->div, val);
 
        return 0;
 }
 
        },
 };
 
-static struct meson_clk_audio_divider gxbb_cts_amclk_div = {
-       .div = {
-               .reg_off = HHI_AUD_CLK_CNTL,
-               .shift   = 0,
-               .width   = 8,
+static struct clk_regmap gxbb_cts_amclk_div = {
+       .data = &(struct meson_clk_audio_div_data){
+               .div = {
+                       .reg_off = HHI_AUD_CLK_CNTL,
+                       .shift   = 0,
+                       .width   = 8,
+               },
+               .flags = CLK_DIVIDER_ROUND_CLOSEST,
        },
-       .flags = CLK_DIVIDER_ROUND_CLOSEST,
-       .lock = &meson_clk_lock,
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_div",
                .ops = &meson_clk_audio_divider_ops,
        &gxl_gp0_pll,
 };
 
-static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
-       &gxbb_cts_amclk_div,
-};
-
 static struct clk_regmap *const gx_clk_regmaps[] = {
        &gxbb_clk81,
        &gxbb_ddr,
        &gxbb_mpll0,
        &gxbb_mpll1,
        &gxbb_mpll2,
+       &gxbb_cts_amclk_div,
 };
 
 struct clkc_data {
        struct meson_clk_pll *const *clk_plls;
        unsigned int clk_plls_count;
-       struct meson_clk_audio_divider *const *clk_audio_dividers;
-       unsigned int clk_audio_dividers_count;
        struct clk_hw_onecell_data *hw_onecell_data;
 };
 
 static const struct clkc_data gxbb_clkc_data = {
        .clk_plls = gxbb_clk_plls,
        .clk_plls_count = ARRAY_SIZE(gxbb_clk_plls),
-       .clk_audio_dividers = gxbb_audio_dividers,
-       .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
        .hw_onecell_data = &gxbb_hw_onecell_data,
 };
 
 static const struct clkc_data gxl_clkc_data = {
        .clk_plls = gxl_clk_plls,
        .clk_plls_count = ARRAY_SIZE(gxl_clk_plls),
-       .clk_audio_dividers = gxbb_audio_dividers,
-       .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
        .hw_onecell_data = &gxl_hw_onecell_data,
 };
 
        for (i = 0; i < clkc_data->clk_plls_count; i++)
                clkc_data->clk_plls[i]->base = clk_base;
 
-       /* Populate base address for the audio dividers */
-       for (i = 0; i < clkc_data->clk_audio_dividers_count; i++)
-               clkc_data->clk_audio_dividers[i]->base = clk_base;
-
        /* Populate regmap for the common regmap backed clocks */
        for (i = 0; i < ARRAY_SIZE(gx_clk_regmaps); i++)
                gx_clk_regmaps[i]->map = map;