for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
                hw = at91_clk_register_system(regmap, at91rm9200_systemck[i].n,
                                              at91rm9200_systemck[i].p,
-                                             at91rm9200_systemck[i].id);
+                                             at91rm9200_systemck[i].id, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
        for (i = 0; i < data->num_sck; i++) {
                hw = at91_clk_register_system(regmap, data->sck[i].n,
                                              data->sck[i].p,
-                                             data->sck[i].id);
+                                             data->sck[i].id, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } at91sam9g45_systemck[] = {
-       { .n = "ddrck", .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "uhpck", .p = "usbck",        .id = 6 },
        { .n = "pck0",  .p = "prog0",        .id = 8 },
        { .n = "pck1",  .p = "prog1",        .id = 9 },
        for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
                hw = at91_clk_register_system(regmap, at91sam9g45_systemck[i].n,
                                              at91sam9g45_systemck[i].p,
-                                             at91sam9g45_systemck[i].id);
+                                             at91sam9g45_systemck[i].id,
+                                             at91sam9g45_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } at91sam9n12_systemck[] = {
-       { .n = "ddrck", .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "lcdck", .p = "masterck_div", .id = 3 },
        { .n = "uhpck", .p = "usbck",        .id = 6 },
        { .n = "udpck", .p = "usbck",        .id = 7 },
        for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
                hw = at91_clk_register_system(regmap, at91sam9n12_systemck[i].n,
                                              at91sam9n12_systemck[i].p,
-                                             at91sam9n12_systemck[i].id);
+                                             at91sam9n12_systemck[i].id,
+                                             at91sam9n12_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         at91sam9n12_periphck[i].n,
                                                         "masterck_div",
                                                         at91sam9n12_periphck[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
        for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
                hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n,
                                              at91sam9rl_systemck[i].p,
-                                             at91sam9rl_systemck[i].id);
+                                             at91sam9rl_systemck[i].id, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } at91sam9x5_systemck[] = {
-       { .n = "ddrck", .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "smdck", .p = "smdclk",   .id = 4 },
        { .n = "uhpck", .p = "usbck",    .id = 6 },
        { .n = "udpck", .p = "usbck",    .id = 7 },
        for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
                hw = at91_clk_register_system(regmap, at91sam9x5_systemck[i].n,
                                              at91sam9x5_systemck[i].p,
-                                             at91sam9x5_systemck[i].id);
+                                             at91sam9x5_systemck[i].id,
+                                             at91sam9x5_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
        }
 
        if (has_lcdck) {
-               hw = at91_clk_register_system(regmap, "lcdck", "masterck_div", 3);
+               hw = at91_clk_register_system(regmap, "lcdck", "masterck_div",
+                                             3, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         at91sam9x5_periphck[i].n,
                                                         "masterck_div",
                                                         at91sam9x5_periphck[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         extra_pcks[i].n,
                                                         "masterck_div",
                                                         extra_pcks[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
                                    const struct clk_pcr_layout *layout,
                                    const char *name, const char *parent_name,
                                    u32 id, const struct clk_range *range,
-                                   int chg_pid)
+                                   int chg_pid, unsigned long flags)
 {
        struct clk_sam9x5_peripheral *periph;
        struct clk_init_data init;
        init.name = name;
        init.parent_names = &parent_name;
        init.num_parents = 1;
+       init.flags = flags;
        if (chg_pid < 0) {
-               init.flags = 0;
                init.ops = &sam9x5_peripheral_ops;
        } else {
-               init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
-                            CLK_SET_RATE_PARENT;
+               init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+                             CLK_SET_RATE_PARENT;
                init.ops = &sam9x5_peripheral_chg_ops;
        }
 
 
 
 struct clk_hw * __init
 at91_clk_register_system(struct regmap *regmap, const char *name,
-                        const char *parent_name, u8 id)
+                        const char *parent_name, u8 id, unsigned long flags)
 {
        struct clk_system *sys;
        struct clk_hw *hw;
        init.ops = &system_ops;
        init.parent_names = &parent_name;
        init.num_parents = 1;
-       init.flags = CLK_SET_RATE_PARENT;
+       init.flags = CLK_SET_RATE_PARENT | flags;
 
        sys->id = id;
        sys->hw.init = &init;
 
                                                          parent_name, id);
                } else {
                        struct clk_range range = CLK_RANGE(0, 0);
+                       unsigned long flags = 0;
 
                        of_at91_get_clk_range(periphclknp,
                                              "atmel,clk-output-range",
                                              &range);
 
+                       /*
+                        * mpddr_clk feed DDR controller and is enabled by
+                        * bootloader thus we need to keep it enabled in case
+                        * there is no Linux consumer for it.
+                        */
+                       if (!strcmp(periphclknp->name, "mpddr_clk"))
+                               flags = CLK_IS_CRITICAL;
+
                        hw = at91_clk_register_sam9x5_peripheral(regmap,
                                                                 &pmc_pcr_lock,
                                                                 &dt_pcr_layout,
                                                                 name,
                                                                 parent_name,
                                                                 id, &range,
-                                                                INT_MIN);
+                                                                INT_MIN,
+                                                                flags);
                }
 
                if (IS_ERR(hw))
                return;
 
        for_each_child_of_node(np, sysclknp) {
+               unsigned long flags = 0;
+
                if (of_property_read_u32(sysclknp, "reg", &id))
                        continue;
 
 
                parent_name = of_clk_get_parent_name(sysclknp, 0);
 
-               hw = at91_clk_register_system(regmap, name, parent_name, id);
+               /*
+                * ddrck feeds DDR controller and is enabled by bootloader thus
+                * we need to keep it enabled in case there is no Linux consumer
+                * for it.
+                */
+               if (!strcmp(sysclknp->name, "ddrck"))
+                       flags = CLK_IS_CRITICAL;
+
+               hw = at91_clk_register_system(regmap, name, parent_name, id,
+                                             flags);
                if (IS_ERR(hw))
                        continue;
 
 
                                    const struct clk_pcr_layout *layout,
                                    const char *name, const char *parent_name,
                                    u32 id, const struct clk_range *range,
-                                   int chg_pid);
+                                   int chg_pid, unsigned long flags);
 
 struct clk_hw * __init
 at91_clk_register_pll(struct regmap *regmap, const char *name,
 
 struct clk_hw * __init
 at91_clk_register_system(struct regmap *regmap, const char *name,
-                        const char *parent_name, u8 id);
+                        const char *parent_name, u8 id, unsigned long flags);
 
 struct clk_hw * __init
 at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } sam9x60_systemck[] = {
-       { .n = "ddrck",  .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck",  .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "uhpck",  .p = "usbck",    .id = 6 },
        { .n = "pck0",   .p = "prog0",    .id = 8 },
        { .n = "pck1",   .p = "prog1",    .id = 9 },
 
 static const struct {
        char *n;
+       unsigned long flags;
        u8 id;
 } sam9x60_periphck[] = {
        { .n = "pioA_clk",   .id = 2, },
        { .n = "pioD_clk",   .id = 44, },
        { .n = "tcb1_clk",   .id = 45, },
        { .n = "dbgu_clk",   .id = 47, },
-       { .n = "mpddr_clk",  .id = 49, },
+       /*
+        * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
+        * need to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "mpddr_clk",  .id = 49, .flags = CLK_IS_CRITICAL },
 };
 
 static const struct {
        for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
                hw = at91_clk_register_system(regmap, sam9x60_systemck[i].n,
                                              sam9x60_systemck[i].p,
-                                             sam9x60_systemck[i].id);
+                                             sam9x60_systemck[i].id,
+                                             sam9x60_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         sam9x60_periphck[i].n,
                                                         "masterck_div",
                                                         sam9x60_periphck[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN,
+                                                        sam9x60_periphck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } sama5d2_systemck[] = {
-       { .n = "ddrck", .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "lcdck", .p = "masterck_div", .id = 3 },
        { .n = "uhpck", .p = "usbck",        .id = 6 },
        { .n = "udpck", .p = "usbck",        .id = 7 },
 
 static const struct {
        char *n;
+       unsigned long flags;
        u8 id;
 } sama5d2_periphck[] = {
        { .n = "dma0_clk",    .id = 6, },
        { .n = "aes_clk",     .id = 9, },
        { .n = "aesb_clk",    .id = 10, },
        { .n = "sha_clk",     .id = 12, },
-       { .n = "mpddr_clk",   .id = 13, },
+       /*
+        * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
+        * need to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "mpddr_clk",   .id = 13, .flags = CLK_IS_CRITICAL },
        { .n = "matrix0_clk", .id = 15, },
        { .n = "sdmmc0_hclk", .id = 31, },
        { .n = "sdmmc1_hclk", .id = 32, },
        for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
                hw = at91_clk_register_system(regmap, sama5d2_systemck[i].n,
                                              sama5d2_systemck[i].p,
-                                             sama5d2_systemck[i].id);
+                                             sama5d2_systemck[i].id,
+                                             sama5d2_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         sama5d2_periphck[i].n,
                                                         "masterck_div",
                                                         sama5d2_periphck[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN,
+                                                        sama5d2_periphck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         "h32mxck",
                                                         sama5d2_periph32ck[i].id,
                                                         &sama5d2_periph32ck[i].r,
-                                                        INT_MIN);
+                                                        INT_MIN, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } sama5d3_systemck[] = {
-       { .n = "ddrck", .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "lcdck", .p = "masterck_div", .id = 3 },
        { .n = "smdck", .p = "smdclk",       .id = 4 },
        { .n = "uhpck", .p = "usbck",        .id = 6 },
        char *n;
        u8 id;
        struct clk_range r;
+       unsigned long flags;
 } sama5d3_periphck[] = {
        { .n = "dbgu_clk", .id = 2, },
        { .n = "hsmc_clk", .id = 5, },
        { .n = "tdes_clk", .id = 44, },
        { .n = "trng_clk", .id = 45, },
        { .n = "fuse_clk", .id = 48, },
-       { .n = "mpddr_clk", .id = 49, },
+       /*
+        * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
+        * need to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "mpddr_clk", .id = 49, .flags = CLK_IS_CRITICAL },
 };
 
 static void __init sama5d3_pmc_setup(struct device_node *np)
        for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
                hw = at91_clk_register_system(regmap, sama5d3_systemck[i].n,
                                              sama5d3_systemck[i].p,
-                                             sama5d3_systemck[i].id);
+                                             sama5d3_systemck[i].id,
+                                             sama5d3_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         "masterck_div",
                                                         sama5d3_periphck[i].id,
                                                         &sama5d3_periphck[i].r,
-                                                        INT_MIN);
+                                                        INT_MIN,
+                                                        sama5d3_periphck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
 
 static const struct {
        char *n;
        char *p;
+       unsigned long flags;
        u8 id;
 } sama5d4_systemck[] = {
-       { .n = "ddrck", .p = "masterck_div", .id = 2 },
+       /*
+        * ddrck feeds DDR controller and is enabled by bootloader thus we need
+        * to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
        { .n = "lcdck", .p = "masterck_div", .id = 3 },
        { .n = "smdck", .p = "smdclk",       .id = 4 },
        { .n = "uhpck", .p = "usbck",        .id = 6 },
 
 static const struct {
        char *n;
+       unsigned long flags;
        u8 id;
 } sama5d4_periphck[] = {
        { .n = "dma0_clk", .id = 8 },
        { .n = "cpkcc_clk", .id = 10 },
        { .n = "aesb_clk", .id = 13 },
-       { .n = "mpddr_clk", .id = 16 },
+       /*
+        * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
+        * need to keep it enabled in case there is no Linux consumer for it.
+        */
+       { .n = "mpddr_clk", .id = 16, .flags = CLK_IS_CRITICAL },
        { .n = "matrix0_clk", .id = 18 },
        { .n = "vdec_clk", .id = 19 },
        { .n = "dma1_clk", .id = 50 },
        for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
                hw = at91_clk_register_system(regmap, sama5d4_systemck[i].n,
                                              sama5d4_systemck[i].p,
-                                             sama5d4_systemck[i].id);
+                                             sama5d4_systemck[i].id,
+                                             sama5d4_systemck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         sama5d4_periphck[i].n,
                                                         "masterck_div",
                                                         sama5d4_periphck[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN,
+                                                        sama5d4_periphck[i].flags);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                         sama5d4_periph32ck[i].n,
                                                         "h32mxck",
                                                         sama5d4_periph32ck[i].id,
-                                                        &range, INT_MIN);
+                                                        &range, INT_MIN, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
 
        for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
                hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n,
                                              sama7g5_systemck[i].p,
-                                             sama7g5_systemck[i].id);
+                                             sama7g5_systemck[i].id, 0);
                if (IS_ERR(hw))
                        goto err_free;
 
                                                sama7g5_periphck[i].id,
                                                &sama7g5_periphck[i].r,
                                                sama7g5_periphck[i].chgp ? 0 :
-                                               INT_MIN);
+                                               INT_MIN, 0);
                if (IS_ERR(hw))
                        goto err_free;