Re:Re: [PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-09-09 Thread Chao Xie

At 2014-09-04 02:04:24, "Mike Turquette"  wrote:
>Quoting Chao Xie (2014-08-25 21:38:14)
>> From: Chao Xie 
>> 
>> The register used by clk-frac may be shared with
>> other clocks.
>> So it needs to use spin lock to protect the register
>> access.
>> 
>> Signed-off-by: Chao Xie 
>
>This patch will break against the latest clk-next due to api changes.
>You can see more here[0] and use this script to update your code if you
>like[1].
>
>Basically the calls to clk_set_rate need to be changed to
>clk_provider_set_rate.

>
I see the patch set [0] is V10 now, and it is not merged to clk-next yet.
So should i wait for the patch set to be merged, then send out the updated 
patches?

>[0] 
>http://lkml.kernel.org/r/<1409758148-20104-1-git-send-email-tomeu.viz...@collabora.com>
>[1] 
>http://cgit.collabora.com/git/user/tomeu/linux.git/commit/?h=clk-refactoring-9=ea48c0d655346cce26329523cf24574f9ea8feee
>
>Regards,
>Mike
N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀�&�)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

Re:Re: [PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-09-09 Thread Chao Xie

At 2014-09-04 02:04:24, Mike Turquette mturque...@linaro.org wrote:
Quoting Chao Xie (2014-08-25 21:38:14)
 From: Chao Xie chao@marvell.com
 
 The register used by clk-frac may be shared with
 other clocks.
 So it needs to use spin lock to protect the register
 access.
 
 Signed-off-by: Chao Xie chao@marvell.com

This patch will break against the latest clk-next due to api changes.
You can see more here[0] and use this script to update your code if you
like[1].

Basically the calls to clk_set_rate need to be changed to
clk_provider_set_rate.


I see the patch set [0] is V10 now, and it is not merged to clk-next yet.
So should i wait for the patch set to be merged, then send out the updated 
patches?

[0] 
http://lkml.kernel.org/r/1409758148-20104-1-git-send-email-tomeu.viz...@collabora.com
[1] 
http://cgit.collabora.com/git/user/tomeu/linux.git/commit/?h=clk-refactoring-9id=ea48c0d655346cce26329523cf24574f9ea8feee

Regards,
Mike
N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�j:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀��)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

Re: [PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-09-03 Thread Mike Turquette
Quoting Chao Xie (2014-08-25 21:38:14)
> From: Chao Xie 
> 
> The register used by clk-frac may be shared with
> other clocks.
> So it needs to use spin lock to protect the register
> access.
> 
> Signed-off-by: Chao Xie 

This patch will break against the latest clk-next due to api changes.
You can see more here[0] and use this script to update your code if you
like[1].

Basically the calls to clk_set_rate need to be changed to
clk_provider_set_rate.

[0] 
http://lkml.kernel.org/r/<1409758148-20104-1-git-send-email-tomeu.viz...@collabora.com>
[1] 
http://cgit.collabora.com/git/user/tomeu/linux.git/commit/?h=clk-refactoring-9=ea48c0d655346cce26329523cf24574f9ea8feee

Regards,
Mike
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-09-03 Thread Mike Turquette
Quoting Chao Xie (2014-08-25 21:38:14)
 From: Chao Xie chao@marvell.com
 
 The register used by clk-frac may be shared with
 other clocks.
 So it needs to use spin lock to protect the register
 access.
 
 Signed-off-by: Chao Xie chao@marvell.com

This patch will break against the latest clk-next due to api changes.
You can see more here[0] and use this script to update your code if you
like[1].

Basically the calls to clk_set_rate need to be changed to
clk_provider_set_rate.

[0] 
http://lkml.kernel.org/r/1409758148-20104-1-git-send-email-tomeu.viz...@collabora.com
[1] 
http://cgit.collabora.com/git/user/tomeu/linux.git/commit/?h=clk-refactoring-9id=ea48c0d655346cce26329523cf24574f9ea8feee

Regards,
Mike
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie 

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i < factor->ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i > 0)
i--;
 
+   if (factor->lock)
+   spin_lock_irqsave(factor->lock, flags);
+
val = readl_relaxed(factor->base);
 
val &= ~(masks->num_mask << masks->num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor->base);
 
+   if (factor->lock)
+   spin_unlock_irqrestore(factor->lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor->ftbl = ftbl;
factor->ftbl_cnt = ftbl_cnt;
factor->hw.init = 
+   factor->lock = lock;
 
init.name = name;
init.ops = _factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t *lock);
 #endif
-- 
1.8.3.2

--
To 

[PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i  factor-ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i  0)
i--;
 
+   if (factor-lock)
+   spin_lock_irqsave(factor-lock, flags);
+
val = readl_relaxed(factor-base);
 
val = ~(masks-num_mask  masks-num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor-base);
 
+   if (factor-lock)
+   spin_unlock_irqrestore(factor-lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor-ftbl = ftbl;
factor-ftbl_cnt = ftbl_cnt;
factor-hw.init = init;
+   factor-lock = lock;
 
init.name = name;
init.ops = clk_factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t 

[PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-06-09 Thread Chao Xie
From: Chao Xie 

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i < factor->ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i > 0)
i--;
 
+   if (factor->lock)
+   spin_lock_irqsave(factor->lock, flags);
+
val = readl_relaxed(factor->base);
 
val &= ~(masks->num_mask << masks->num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor->base);
 
+   if (factor->lock)
+   spin_unlock_irqrestore(factor->lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor->ftbl = ftbl;
factor->ftbl_cnt = ftbl_cnt;
factor->hw.init = 
+   factor->lock = lock;
 
init.name = name;
init.ops = _factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t *lock);
 #endif
-- 
1.8.3.2

--
To 

[PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-06-09 Thread Chao Xie
From: Chao Xie chao@marvell.com

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i  factor-ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i  0)
i--;
 
+   if (factor-lock)
+   spin_lock_irqsave(factor-lock, flags);
+
val = readl_relaxed(factor-base);
 
val = ~(masks-num_mask  masks-num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor-base);
 
+   if (factor-lock)
+   spin_unlock_irqrestore(factor-lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor-ftbl = ftbl;
factor-ftbl_cnt = ftbl_cnt;
factor-hw.init = init;
+   factor-lock = lock;
 
init.name = name;
init.ops = clk_factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t