>> AT91_PMC_PCR_GCKDIV_OFFSET;
 }
 
-static struct clk * __init
-at91_clk_register_generated(struct regmap *regmap,  spinlock_t *lock, const char
-                           *name, const char **parent_names, u8 num_parents,
-                           u8 id, const struct clk_range *range)
+static struct clk_hw * __init
+at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
+                           const char *name, const char **parent_names,
+                           u8 num_parents, u8 id,
+                           const struct clk_range *range)
 {
        struct clk_generated *gck;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        gck = kzalloc(sizeof(*gck), GFP_KERNEL);
        if (!gck)
        gck->lock = lock;
        gck->range = *range;
 
-       clk = clk_register(NULL, &gck->hw);
-       if (IS_ERR(clk))
+       hw = &gck->hw;
+       ret = clk_hw_register(NULL, &gck->hw);
+       if (ret) {
                kfree(gck);
-       else
+               hw = ERR_PTR(ret);
+       } else
                clk_generated_startup(gck);
 
-       return clk;
+       return hw;
 }
 
 static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
        int num;
        u32 id;
        const char *name;
-       struct clk *clk;
+       struct clk_hw *hw;
        unsigned int num_parents;
        const char *parent_names[GENERATED_SOURCE_MAX];
        struct device_node *gcknp;
                of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
                                      &range);
 
-               clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
+               hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
                                                  parent_names, num_parents,
                                                  id, &range);
-               if (IS_ERR(clk))
+               if (IS_ERR(hw))
                        continue;
 
-               of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
+               of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
        }
 }
 CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
 
        struct clk_init_data init;
        const char *parent_name;
        struct regmap *regmap;
-       struct clk *clk;
+       int ret;
 
        regmap = syscon_node_to_regmap(of_get_parent(np));
        if (IS_ERR(regmap))
        h32mxclk->hw.init = &init;
        h32mxclk->regmap = regmap;
 
-       clk = clk_register(NULL, &h32mxclk->hw);
-       if (IS_ERR(clk)) {
+       ret = clk_hw_register(NULL, &h32mxclk->hw);
+       if (ret) {
                kfree(h32mxclk);
                return;
        }
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
 }
 CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
               of_sama5d4_clk_h32mx_setup);
 
        .is_prepared = clk_main_osc_is_prepared,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_main_osc(struct regmap *regmap,
                           const char *name,
                           const char *parent_name,
                           bool bypass)
 {
        struct clk_main_osc *osc;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name || !parent_name)
                return ERR_PTR(-EINVAL);
                                   AT91_PMC_MOSCEN,
                                   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
 
-       clk = clk_register(NULL, &osc->hw);
-       if (IS_ERR(clk))
+       hw = &osc->hw;
+       ret = clk_hw_register(NULL, &osc->hw);
+       if (ret) {
                kfree(osc);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *name = np->name;
        const char *parent_name;
        struct regmap *regmap;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
-       if (IS_ERR(clk))
+       hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
               of_at91rm9200_clk_main_osc_setup);
        .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_main_rc_osc(struct regmap *regmap,
                              const char *name,
                              u32 frequency, u32 accuracy)
 {
        struct clk_main_rc_osc *osc;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name || !frequency)
                return ERR_PTR(-EINVAL);
        osc->frequency = frequency;
        osc->accuracy = accuracy;
 
-       clk = clk_register(NULL, &osc->hw);
-       if (IS_ERR(clk))
+       hw = &osc->hw;
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
                kfree(osc);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        u32 frequency = 0;
        u32 accuracy = 0;
        const char *name = np->name;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
-       if (IS_ERR(clk))
+       hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
               of_at91sam9x5_clk_main_rc_osc_setup);
        .recalc_rate = clk_rm9200_main_recalc_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_rm9200_main(struct regmap *regmap,
                              const char *name,
                              const char *parent_name)
 {
        struct clk_rm9200_main *clkmain;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name)
                return ERR_PTR(-EINVAL);
        clkmain->hw.init = &init;
        clkmain->regmap = regmap;
 
-       clk = clk_register(NULL, &clkmain->hw);
-       if (IS_ERR(clk))
+       hw = &clkmain->hw;
+       ret = clk_hw_register(NULL, &clkmain->hw);
+       if (ret) {
                kfree(clkmain);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91_clk_register_rm9200_main(regmap, name, parent_name);
-       if (IS_ERR(clk))
+       hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
               of_at91rm9200_clk_main_setup);
        .get_parent = clk_sam9x5_main_get_parent,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_sam9x5_main(struct regmap *regmap,
                              const char *name,
                              const char **parent_names,
                              int num_parents)
 {
        struct clk_sam9x5_main *clkmain;
-       struct clk *clk = NULL;
        struct clk_init_data init;
        unsigned int status;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name)
                return ERR_PTR(-EINVAL);
        regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
        clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
 
-       clk = clk_register(NULL, &clkmain->hw);
-       if (IS_ERR(clk))
+       hw = &clkmain->hw;
+       ret = clk_hw_register(NULL, &clkmain->hw);
+       if (ret) {
                kfree(clkmain);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_names[2];
        unsigned int num_parents;
        const char *name = np->name;
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       clk = at91_clk_register_sam9x5_main(regmap, name, parent_names,
+       hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
                                            num_parents);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
               of_at91sam9x5_clk_main_setup);
 
        .get_parent = clk_master_get_parent,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_master(struct regmap *regmap,
                const char *name, int num_parents,
                const char **parent_names,
                const struct clk_master_characteristics *characteristics)
 {
        struct clk_master *master;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name || !num_parents || !parent_names)
                return ERR_PTR(-EINVAL);
        master->characteristics = characteristics;
        master->regmap = regmap;
 
-       clk = clk_register(NULL, &master->hw);
-       if (IS_ERR(clk)) {
+       hw = &master->hw;
+       ret = clk_hw_register(NULL, &master->hw);
+       if (ret) {
                kfree(master);
+               hw = ERR_PTR(ret);
        }
 
-       return clk;
+       return hw;
 }
 
 
 of_at91_clk_master_setup(struct device_node *np,
                         const struct clk_master_layout *layout)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        unsigned int num_parents;
        const char *parent_names[MASTER_SOURCE_MAX];
        const char *name = np->name;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91_clk_register_master(regmap, name, num_parents,
+       hw = at91_clk_register_master(regmap, name, num_parents,
                                       parent_names, layout,
                                       characteristics);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto out_free_characteristics;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
        return;
 
 out_free_characteristics:
 
        .is_enabled = clk_peripheral_is_enabled,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_peripheral(struct regmap *regmap, const char *name,
                             const char *parent_name, u32 id)
 {
        struct clk_peripheral *periph;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name || !parent_name || id > PERIPHERAL_ID_MAX)
                return ERR_PTR(-EINVAL);
        periph->hw.init = &init;
        periph->regmap = regmap;
 
-       clk = clk_register(NULL, &periph->hw);
-       if (IS_ERR(clk))
+       hw = &periph->hw;
+       ret = clk_hw_register(NULL, &periph->hw);
+       if (ret) {
                kfree(periph);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
        .set_rate = clk_sam9x5_peripheral_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
                                    const char *name, const char *parent_name,
                                    u32 id, const struct clk_range *range)
 {
        struct clk_sam9x5_peripheral *periph;
-       struct clk *clk = NULL;
        struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
 
        if (!name || !parent_name)
                return ERR_PTR(-EINVAL);
        periph->auto_div = true;
        periph->range = *range;
 
-       clk = clk_register(NULL, &periph->hw);
-       if (IS_ERR(clk))
+       hw = &periph->hw;
+       ret = clk_hw_register(NULL, &periph->hw);
+       if (ret) {
                kfree(periph);
-       else
+               hw = ERR_PTR(ret);
+       } else
                clk_sam9x5_peripheral_autodiv(periph);
 
-       return clk;
+       return hw;
 }
 
 static void __init
 {
        int num;
        u32 id;
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name;
        struct device_node *periphclknp;
                        name = periphclknp->name;
 
                if (type == PERIPHERAL_AT91RM9200) {
-                       clk = at91_clk_register_peripheral(regmap, name,
+                       hw = at91_clk_register_peripheral(regmap, name,
                                                           parent_name, id);
                } else {
                        struct clk_range range = CLK_RANGE(0, 0);
                                              "atmel,clk-output-range",
                                              &range);
 
-                       clk = at91_clk_register_sam9x5_peripheral(regmap,
+                       hw = at91_clk_register_sam9x5_peripheral(regmap,
                                                                  &pmc_pcr_lock,
                                                                  name,
                                                                  parent_name,
                                                                  id, &range);
                }
 
-               if (IS_ERR(clk))
+               if (IS_ERR(hw))
                        continue;
 
-               of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk);
+               of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
        }
 }
 
 
        .set_rate = clk_pll_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_pll(struct regmap *regmap, const char *name,
                      const char *parent_name, u8 id,
                      const struct clk_pll_layout *layout,
                      const struct clk_pll_characteristics *characteristics)
 {
        struct clk_pll *pll;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
        int offset = PLL_REG(id);
        unsigned int pllr;
+       int ret;
 
        if (id > PLL_MAX_ID)
                return ERR_PTR(-EINVAL);
        pll->div = PLL_DIV(pllr);
        pll->mul = PLL_MUL(pllr, layout);
 
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk)) {
+       hw = &pll->hw;
+       ret = clk_hw_register(NULL, &pll->hw);
+       if (ret) {
                kfree(pll);
+               hw = ERR_PTR(ret);
        }
 
-       return clk;
+       return hw;
 }
 
 
                      const struct clk_pll_layout *layout)
 {
        u32 id;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct regmap *regmap;
        const char *parent_name;
        const char *name = np->name;
        if (!characteristics)
                return;
 
-       clk = at91_clk_register_pll(regmap, name, parent_name, id, layout,
+       hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
                                    characteristics);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto out_free_characteristics;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
        return;
 
 out_free_characteristics:
 
        .set_rate = clk_plldiv_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_plldiv(struct regmap *regmap, const char *name,
                         const char *parent_name)
 {
        struct clk_plldiv *plldiv;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL);
        if (!plldiv)
        plldiv->hw.init = &init;
        plldiv->regmap = regmap;
 
-       clk = clk_register(NULL, &plldiv->hw);
-
-       if (IS_ERR(clk))
+       hw = &plldiv->hw;
+       ret = clk_hw_register(NULL, &plldiv->hw);
+       if (ret) {
                kfree(plldiv);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init
 of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91_clk_register_plldiv(regmap, name, parent_name);
-       if (IS_ERR(clk))
+       hw = at91_clk_register_plldiv(regmap, name, parent_name);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
-       return;
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
               of_at91sam9x5_clk_plldiv_setup);
 
        .set_rate = clk_programmable_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_programmable(struct regmap *regmap,
                               const char *name, const char **parent_names,
                               u8 num_parents, u8 id,
                               const struct clk_programmable_layout *layout)
 {
        struct clk_programmable *prog;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (id > PROG_ID_MAX)
                return ERR_PTR(-EINVAL);
        prog->hw.init = &init;
        prog->regmap = regmap;
 
-       clk = clk_register(NULL, &prog->hw);
-       if (IS_ERR(clk))
+       hw = &prog->hw;
+       ret = clk_hw_register(NULL, &prog->hw);
+       if (ret) {
                kfree(prog);
+               hw = &prog->hw;
+       }
 
-       return clk;
+       return hw;
 }
 
 static const struct clk_programmable_layout at91rm9200_programmable_layout = {
 {
        int num;
        u32 id;
-       struct clk *clk;
+       struct clk_hw *hw;
        unsigned int num_parents;
        const char *parent_names[PROG_SOURCE_MAX];
        const char *name;
                if (of_property_read_string(np, "clock-output-names", &name))
                        name = progclknp->name;
 
-               clk = at91_clk_register_programmable(regmap, name,
+               hw = at91_clk_register_programmable(regmap, name,
                                                     parent_names, num_parents,
                                                     id, layout);
-               if (IS_ERR(clk))
+               if (IS_ERR(hw))
                        continue;
 
-               of_clk_add_provider(progclknp, of_clk_src_simple_get, clk);
+               of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
        }
 }
 
 
        .is_prepared = clk_slow_osc_is_prepared,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_slow_osc(void __iomem *sckcr,
                           const char *name,
                           const char *parent_name,
                           bool bypass)
 {
        struct clk_slow_osc *osc;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (!sckcr || !name || !parent_name)
                return ERR_PTR(-EINVAL);
                writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
                       sckcr);
 
-       clk = clk_register(NULL, &osc->hw);
-       if (IS_ERR(clk))
+       hw = &osc->hw;
+       ret = clk_hw_register(NULL, &osc->hw);
+       if (ret) {
                kfree(osc);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
                                             void __iomem *sckcr)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
        u32 startup;
        of_property_read_u32(np, "atmel,startup-time-usec", &startup);
        bypass = of_property_read_bool(np, "atmel,osc-bypass");
 
-       clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
+       hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
                                         bypass);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 
 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
        .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_slow_rc_osc(void __iomem *sckcr,
                              const char *name,
                              unsigned long frequency,
                              unsigned long startup)
 {
        struct clk_slow_rc_osc *osc;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (!sckcr || !name)
                return ERR_PTR(-EINVAL);
        osc->accuracy = accuracy;
        osc->startup_usec = startup;
 
-       clk = clk_register(NULL, &osc->hw);
-       if (IS_ERR(clk))
+       hw = &osc->hw;
+       ret = clk_hw_register(NULL, &osc->hw);
+       if (ret) {
                kfree(osc);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
                                                void __iomem *sckcr)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        u32 frequency = 0;
        u32 accuracy = 0;
        u32 startup = 0;
        of_property_read_u32(np, "clock-accuracy", &accuracy);
        of_property_read_u32(np, "atmel,startup-time-usec", &startup);
 
-       clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
+       hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
                                            startup);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 
 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
        .get_parent = clk_sam9x5_slow_get_parent,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_sam9x5_slow(void __iomem *sckcr,
                              const char *name,
                              const char **parent_names,
                              int num_parents)
 {
        struct clk_sam9x5_slow *slowck;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (!sckcr || !name || !parent_names || !num_parents)
                return ERR_PTR(-EINVAL);
        slowck->sckcr = sckcr;
        slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
 
-       clk = clk_register(NULL, &slowck->hw);
-       if (IS_ERR(clk))
+       hw = &slowck->hw;
+       ret = clk_hw_register(NULL, &slowck->hw);
+       if (ret) {
                kfree(slowck);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
                                         void __iomem *sckcr)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_names[2];
        unsigned int num_parents;
        const char *name = np->name;
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
+       hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
                                            num_parents);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 
 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
        .get_parent = clk_sam9260_slow_get_parent,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_sam9260_slow(struct regmap *regmap,
                               const char *name,
                               const char **parent_names,
                               int num_parents)
 {
        struct clk_sam9260_slow *slowck;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (!name)
                return ERR_PTR(-EINVAL);
        slowck->hw.init = &init;
        slowck->regmap = regmap;
 
-       clk = clk_register(NULL, &slowck->hw);
-       if (IS_ERR(clk))
+       hw = &slowck->hw;
+       ret = clk_hw_register(NULL, &slowck->hw);
+       if (ret) {
                kfree(slowck);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_names[2];
        unsigned int num_parents;
        const char *name = np->name;
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       clk = at91_clk_register_sam9260_slow(regmap, name, parent_names,
+       hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
                                             num_parents);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 
 CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
 
        .set_rate = at91sam9x5_clk_smd_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
                            const char **parent_names, u8 num_parents)
 {
        struct at91sam9x5_clk_smd *smd;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        smd = kzalloc(sizeof(*smd), GFP_KERNEL);
        if (!smd)
        smd->hw.init = &init;
        smd->regmap = regmap;
 
-       clk = clk_register(NULL, &smd->hw);
-       if (IS_ERR(clk))
+       hw = &smd->hw;
+       ret = clk_hw_register(NULL, &smd->hw);
+       if (ret) {
                kfree(smd);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        unsigned int num_parents;
        const char *parent_names[SMD_SOURCE_MAX];
        const char *name = np->name;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91sam9x5_clk_register_smd(regmap, name, parent_names,
+       hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
                                          num_parents);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
               of_at91sam9x5_clk_smd_setup);
 
        .is_prepared = clk_system_is_prepared,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_system(struct regmap *regmap, const char *name,
                         const char *parent_name, u8 id)
 {
        struct clk_system *sys;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (!parent_name || id > SYSTEM_MAX_ID)
                return ERR_PTR(-EINVAL);
        sys->hw.init = &init;
        sys->regmap = regmap;
 
-       clk = clk_register(NULL, &sys->hw);
-       if (IS_ERR(clk))
+       hw = &sys->hw;
+       ret = clk_hw_register(NULL, &sys->hw);
+       if (ret) {
                kfree(sys);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
 {
        int num;
        u32 id;
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *name;
        struct device_node *sysclknp;
        const char *parent_name;
 
                parent_name = of_clk_get_parent_name(sysclknp, 0);
 
-               clk = at91_clk_register_system(regmap, name, parent_name, id);
-               if (IS_ERR(clk))
+               hw = at91_clk_register_system(regmap, name, parent_name, id);
+               if (IS_ERR(hw))
                        continue;
 
-               of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
+               of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
        }
 }
 CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
 
        .set_rate = at91sam9x5_clk_usb_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
                            const char **parent_names, u8 num_parents)
 {
        struct at91sam9x5_clk_usb *usb;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        usb = kzalloc(sizeof(*usb), GFP_KERNEL);
        if (!usb)
        usb->hw.init = &init;
        usb->regmap = regmap;
 
-       clk = clk_register(NULL, &usb->hw);
-       if (IS_ERR(clk))
+       hw = &usb->hw;
+       ret = clk_hw_register(NULL, &usb->hw);
+       if (ret) {
                kfree(usb);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
-static struct clk * __init
+static struct clk_hw * __init
 at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
                             const char *parent_name)
 {
        struct at91sam9x5_clk_usb *usb;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        usb = kzalloc(sizeof(*usb), GFP_KERNEL);
        if (!usb)
        usb->hw.init = &init;
        usb->regmap = regmap;
 
-       clk = clk_register(NULL, &usb->hw);
-       if (IS_ERR(clk))
+       hw = &usb->hw;
+       ret = clk_hw_register(NULL, &usb->hw);
+       if (ret) {
                kfree(usb);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
        .set_rate = at91rm9200_clk_usb_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
                            const char *parent_name, const u32 *divisors)
 {
        struct at91rm9200_clk_usb *usb;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        usb = kzalloc(sizeof(*usb), GFP_KERNEL);
        if (!usb)
        usb->regmap = regmap;
        memcpy(usb->divisors, divisors, sizeof(usb->divisors));
 
-       clk = clk_register(NULL, &usb->hw);
-       if (IS_ERR(clk))
+       hw = &usb->hw;
+       ret = clk_hw_register(NULL, &usb->hw);
+       if (ret) {
                kfree(usb);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        unsigned int num_parents;
        const char *parent_names[USB_SOURCE_MAX];
        const char *name = np->name;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91sam9x5_clk_register_usb(regmap, name, parent_names,
-                                         num_parents);
-       if (IS_ERR(clk))
+       hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
+                                        num_parents);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
               of_at91sam9x5_clk_usb_setup);
 
 static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91sam9n12_clk_register_usb(regmap, name, parent_name);
-       if (IS_ERR(clk))
+       hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
               of_at91sam9n12_clk_usb_setup);
 
 static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
        u32 divisors[4] = {0, 0, 0, 0};
        regmap = syscon_node_to_regmap(of_get_parent(np));
        if (IS_ERR(regmap))
                return;
-
-       clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
-       if (IS_ERR(clk))
+       hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
               of_at91rm9200_clk_usb_setup);
 
        .recalc_rate = clk_utmi_recalc_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 at91_clk_register_utmi(struct regmap *regmap,
                       const char *name, const char *parent_name)
 {
        struct clk_utmi *utmi;
-       struct clk *clk = NULL;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
        if (!utmi)
        utmi->hw.init = &init;
        utmi->regmap = regmap;
 
-       clk = clk_register(NULL, &utmi->hw);
-       if (IS_ERR(clk))
+       hw = &utmi->hw;
+       ret = clk_hw_register(NULL, &utmi->hw);
+       if (ret) {
                kfree(utmi);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
        if (IS_ERR(regmap))
                return;
 
-       clk = at91_clk_register_utmi(regmap, name, parent_name);
-       if (IS_ERR(clk))
+       hw = at91_clk_register_utmi(regmap, name, parent_name);
+       if (IS_ERR(hw))
                return;
 
-       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
        return;
 }
 CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",