diff mbox

ARM: Tegra: Add smp_twd clock for Tegra20

Message ID 1347528873-3799-1-git-send-email-pgaikwad@nvidia.com (mailing list archive)
State New, archived
Headers show

Commit Message

Prashant Gaikwad Sept. 13, 2012, 9:34 a.m. UTC
Clockevent's frequency is changed upon cpufreq change
notification. It fetches local timer's rate to update the
clockevent frequency. This patch adds local timer clock
for Tegra20.

Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
---
 arch/arm/mach-tegra/tegra20_clocks.c      |   19 ++++++++++++++++++
 arch/arm/mach-tegra/tegra20_clocks.h      |    1 +
 arch/arm/mach-tegra/tegra20_clocks_data.c |   30 +++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 0 deletions(-)

Comments

Stephen Warren Sept. 13, 2012, 3:57 p.m. UTC | #1
On 09/13/2012 03:34 AM, Prashant Gaikwad wrote:
> Clockevent's frequency is changed upon cpufreq change
> notification. It fetches local timer's rate to update the
> clockevent frequency. This patch adds local timer clock
> for Tegra20.

Hmm. Off-list, I'd asked you to check whether this patch, and Mike's
twd/clk-notifier changes were OK for Tegra, and part of your reponse was:

Tegra20 (Ventana)
        Tegra's for-next (common clock) + smp_twd : Panic

Is that true? If so, I can't apply this patch...
Stephen Warren Sept. 13, 2012, 5:26 p.m. UTC | #2
On 09/13/2012 09:57 AM, Stephen Warren wrote:
> On 09/13/2012 03:34 AM, Prashant Gaikwad wrote:
>> Clockevent's frequency is changed upon cpufreq change
>> notification. It fetches local timer's rate to update the
>> clockevent frequency. This patch adds local timer clock
>> for Tegra20.
> 
> Hmm. Off-list, I'd asked you to check whether this patch, and Mike's
> twd/clk-notifier changes were OK for Tegra, and part of your reponse was:
> 
> Tegra20 (Ventana)
>         Tegra's for-next (common clock) + smp_twd : Panic
> 
> Is that true? If so, I can't apply this patch...

Oh, perhaps you mean the warning below? That's exactly the issue that
Mike's patch was intended to solve, so it's not surprising that it'd be
seen as soon as we actually implement the smp_twd clock. If that's all,
then it seems OK to apply this.

> [    1.287406] ------------[ cut here ]------------
> [    1.292049] WARNING: at kernel/mutex.c:198 __mutex_lock_slowpath+0x2c8/0x34c()
> [    1.299259] Modules linked in:
> [    1.302361] [<c0015118>] (unwind_backtrace+0x0/0x138) from [<c0027d3c>] (warn_slowpath_common+0x4c/0x64)
> [    1.311843] [<c0027d3c>] (warn_slowpath_common+0x4c/0x64) from [<c0027d70>] (warn_slowpath_null+0x1c/0x24)
> [    1.321497] [<c0027d70>] (warn_slowpath_null+0x1c/0x24) from [<c04a140c>] (__mutex_lock_slowpath+0x2c8/0x34c)
> [    1.331412] [<c04a140c>] (__mutex_lock_slowpath+0x2c8/0x34c) from [<c04a149c>] (mutex_lock+0xc/0x24)
> [    1.340551] [<c04a149c>] (mutex_lock+0xc/0x24) from [<c0306a04>] (clk_get_rate+0x10/0x68)
> [    1.348731] [<c0306a04>] (clk_get_rate+0x10/0x68) from [<c00148a0>] (twd_update_frequency+0x14/0x48)
> [    1.357865] [<c00148a0>] (twd_update_frequency+0x14/0x48) from [<c0070a58>] (generic_smp_call_function_single_interrupt+0xd0/0x130)
> [    1.369686] [<c0070a58>] (generic_smp_call_function_single_interrupt+0xd0/0x130) from [<c00140c4>] (handle_IPI+0xb0/0x154)
> [    1.380723] [<c00140c4>] (handle_IPI+0xb0/0x154) from [<c0008560>] (gic_handle_irq+0x54/0x5c)
> [    1.389255] [<c0008560>] (gic_handle_irq+0x54/0x5c) from [<c000e9e0>] (__irq_svc+0x40/0x70)
> [    1.397594] Exception stack(0xef083f50 to 0xef083f98)
> [    1.402643] 3f40:                                     ef083fa0 00000000 00000000 000f4240
> [    1.410815] 3f60: 00001093 00000000 00000000 c0f3d3d8 ef083f98 411fc090 00000000 00000000
> [    1.418984] 3f80: 3b9ac9ff ef083f98 c01e4728 c001f010 20000013 ffffffff
> [    1.425612] [<c000e9e0>] (__irq_svc+0x40/0x70) from [<c001f010>] (tegra_idle_enter_lp3+0x68/0x78)
> [    1.434488] [<c001f010>] (tegra_idle_enter_lp3+0x68/0x78) from [<c02d80f8>] (cpuidle_enter+0x14/0x18)
> [    1.443705] [<c02d80f8>] (cpuidle_enter+0x14/0x18) from [<c02d868c>] (cpuidle_idle_call+0xb0/0x140)
> [    1.452752] [<c02d868c>] (cpuidle_idle_call+0xb0/0x140) from [<c000fb14>] (cpu_idle+0xbc/0x110)
> [    1.461448] [<c000fb14>] (cpu_idle+0xbc/0x110) from [<0049d414>] (0x49d414)
> [    1.468421] ---[ end trace bb3563806344f4a0 ]---
Stephen Warren Sept. 13, 2012, 5:48 p.m. UTC | #3
On 09/13/2012 03:34 AM, Prashant Gaikwad wrote:
> Clockevent's frequency is changed upon cpufreq change
> notification. It fetches local timer's rate to update the
> clockevent frequency. This patch adds local timer clock
> for Tegra20.

Applied to Tegra's for-3.7/common-clk branch. I re-tested that branch,
and the final re-merge of Tegra's for-next.

A nice side-effect of this, is that you can disable CONFIG_CPU_FREQ, and
still boot (since the CPU clock isn't turned off, since smp_twd is
clk_get()d which takes a reference to the CPU clock).
Mike Turquette Sept. 13, 2012, 6:27 p.m. UTC | #4
Quoting Stephen Warren (2012-09-13 10:26:34)
> On 09/13/2012 09:57 AM, Stephen Warren wrote:
> > On 09/13/2012 03:34 AM, Prashant Gaikwad wrote:
> >> Clockevent's frequency is changed upon cpufreq change
> >> notification. It fetches local timer's rate to update the
> >> clockevent frequency. This patch adds local timer clock
> >> for Tegra20.
> > 
> > Hmm. Off-list, I'd asked you to check whether this patch, and Mike's
> > twd/clk-notifier changes were OK for Tegra, and part of your reponse was:
> > 
> > Tegra20 (Ventana)
> >         Tegra's for-next (common clock) + smp_twd : Panic
> > 
> > Is that true? If so, I can't apply this patch...
> 
> Oh, perhaps you mean the warning below? That's exactly the issue that
> Mike's patch was intended to solve, so it's not surprising that it'd be
> seen as soon as we actually implement the smp_twd clock. If that's all,
> then it seems OK to apply this.
> 

Can you confirm that the problem goes away with this patch:
http://article.gmane.org/gmane.linux.ports.arm.kernel/187488/match=

Thanks,
Mike

> > [    1.287406] ------------[ cut here ]------------
> > [    1.292049] WARNING: at kernel/mutex.c:198 __mutex_lock_slowpath+0x2c8/0x34c()
> > [    1.299259] Modules linked in:
> > [    1.302361] [<c0015118>] (unwind_backtrace+0x0/0x138) from [<c0027d3c>] (warn_slowpath_common+0x4c/0x64)
> > [    1.311843] [<c0027d3c>] (warn_slowpath_common+0x4c/0x64) from [<c0027d70>] (warn_slowpath_null+0x1c/0x24)
> > [    1.321497] [<c0027d70>] (warn_slowpath_null+0x1c/0x24) from [<c04a140c>] (__mutex_lock_slowpath+0x2c8/0x34c)
> > [    1.331412] [<c04a140c>] (__mutex_lock_slowpath+0x2c8/0x34c) from [<c04a149c>] (mutex_lock+0xc/0x24)
> > [    1.340551] [<c04a149c>] (mutex_lock+0xc/0x24) from [<c0306a04>] (clk_get_rate+0x10/0x68)
> > [    1.348731] [<c0306a04>] (clk_get_rate+0x10/0x68) from [<c00148a0>] (twd_update_frequency+0x14/0x48)
> > [    1.357865] [<c00148a0>] (twd_update_frequency+0x14/0x48) from [<c0070a58>] (generic_smp_call_function_single_interrupt+0xd0/0x130)
> > [    1.369686] [<c0070a58>] (generic_smp_call_function_single_interrupt+0xd0/0x130) from [<c00140c4>] (handle_IPI+0xb0/0x154)
> > [    1.380723] [<c00140c4>] (handle_IPI+0xb0/0x154) from [<c0008560>] (gic_handle_irq+0x54/0x5c)
> > [    1.389255] [<c0008560>] (gic_handle_irq+0x54/0x5c) from [<c000e9e0>] (__irq_svc+0x40/0x70)
> > [    1.397594] Exception stack(0xef083f50 to 0xef083f98)
> > [    1.402643] 3f40:                                     ef083fa0 00000000 00000000 000f4240
> > [    1.410815] 3f60: 00001093 00000000 00000000 c0f3d3d8 ef083f98 411fc090 00000000 00000000
> > [    1.418984] 3f80: 3b9ac9ff ef083f98 c01e4728 c001f010 20000013 ffffffff
> > [    1.425612] [<c000e9e0>] (__irq_svc+0x40/0x70) from [<c001f010>] (tegra_idle_enter_lp3+0x68/0x78)
> > [    1.434488] [<c001f010>] (tegra_idle_enter_lp3+0x68/0x78) from [<c02d80f8>] (cpuidle_enter+0x14/0x18)
> > [    1.443705] [<c02d80f8>] (cpuidle_enter+0x14/0x18) from [<c02d868c>] (cpuidle_idle_call+0xb0/0x140)
> > [    1.452752] [<c02d868c>] (cpuidle_idle_call+0xb0/0x140) from [<c000fb14>] (cpu_idle+0xbc/0x110)
> > [    1.461448] [<c000fb14>] (cpu_idle+0xbc/0x110) from [<0049d414>] (0x49d414)
> > [    1.468421] ---[ end trace bb3563806344f4a0 ]---
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Stephen Warren Sept. 13, 2012, 6:33 p.m. UTC | #5
On 09/13/2012 12:27 PM, Mike Turquette wrote:
> Quoting Stephen Warren (2012-09-13 10:26:34)
>> On 09/13/2012 09:57 AM, Stephen Warren wrote:
>>> On 09/13/2012 03:34 AM, Prashant Gaikwad wrote:
>>>> Clockevent's frequency is changed upon cpufreq change
>>>> notification. It fetches local timer's rate to update the
>>>> clockevent frequency. This patch adds local timer clock
>>>> for Tegra20.
>>>
>>> Hmm. Off-list, I'd asked you to check whether this patch, and Mike's
>>> twd/clk-notifier changes were OK for Tegra, and part of your reponse was:
>>>
>>> Tegra20 (Ventana)
>>>         Tegra's for-next (common clock) + smp_twd : Panic
>>>
>>> Is that true? If so, I can't apply this patch...
>>
>> Oh, perhaps you mean the warning below? That's exactly the issue that
>> Mike's patch was intended to solve, so it's not surprising that it'd be
>> seen as soon as we actually implement the smp_twd clock. If that's all,
>> then it seems OK to apply this.
>>
> 
> Can you confirm that the problem goes away with this patch:
> http://article.gmane.org/gmane.linux.ports.arm.kernel/187488/match=

Yes, it does.

That patch is what triggered the creation of this patch (since because
of it I noticed we didn't have the smp_twd clock in our driver).
diff mbox

Patch

diff --git a/arch/arm/mach-tegra/tegra20_clocks.c b/arch/arm/mach-tegra/tegra20_clocks.c
index a4561da..deb873f 100644
--- a/arch/arm/mach-tegra/tegra20_clocks.c
+++ b/arch/arm/mach-tegra/tegra20_clocks.c
@@ -384,6 +384,25 @@  struct clk_ops tegra_super_ops = {
 	.recalc_rate = tegra20_super_clk_recalc_rate,
 };
 
+static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_tegra *c = to_clk_tegra(hw);
+	u64 rate = parent_rate;
+
+	if (c->mul != 0 && c->div != 0) {
+		rate *= c->mul;
+		rate += c->div - 1; /* round up */
+		do_div(rate, c->div);
+	}
+
+	return rate;
+}
+
+struct clk_ops tegra_twd_ops = {
+	.recalc_rate = tegra20_twd_clk_recalc_rate,
+};
+
 static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw)
 {
 	return 0;
diff --git a/arch/arm/mach-tegra/tegra20_clocks.h b/arch/arm/mach-tegra/tegra20_clocks.h
index 0e42ec0..8bfd31b 100644
--- a/arch/arm/mach-tegra/tegra20_clocks.h
+++ b/arch/arm/mach-tegra/tegra20_clocks.h
@@ -28,6 +28,7 @@  extern struct clk_ops tegra_cdev_clk_ops;
 extern struct clk_ops tegra_audio_sync_clk_ops;
 extern struct clk_ops tegra_super_ops;
 extern struct clk_ops tegra_cpu_ops;
+extern struct clk_ops tegra_twd_ops;
 extern struct clk_ops tegra_cop_ops;
 extern struct clk_ops tegra_bus_ops;
 extern struct clk_ops tegra_blink_clk_ops;
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c b/arch/arm/mach-tegra/tegra20_clocks_data.c
index 0e8ed37..dc2ad7d 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -583,6 +583,34 @@  static struct clk_tegra tegra_cclk_hw = {
 DEFINE_CLK_TEGRA(cclk, 0, &tegra_super_ops, 0, mux_cclk,
 		mux_cclk_p, NULL);
 
+static const char *mux_twd[] = {
+	"cclk",
+};
+
+static struct clk *mux_twd_p[] = {
+	&tegra_cclk,
+};
+
+static struct clk tegra_clk_twd;
+static struct clk_tegra tegra_clk_twd_hw = {
+	.hw = {
+		.clk = &tegra_clk_twd,
+	},
+	.max_rate = 1000000000,
+	.mul = 1,
+	.div = 4,
+};
+
+static struct clk tegra_clk_twd = {
+	.name = "twd",
+	.ops = &tegra_twd_ops,
+	.hw = &tegra_clk_twd_hw.hw,
+	.parent = &tegra_cclk,
+	.parent_names = mux_twd,
+	.parents = mux_twd_p,
+	.num_parents = ARRAY_SIZE(mux_twd),
+};
+
 static struct clk tegra_sclk;
 static struct clk_tegra tegra_sclk_hw = {
 	.hw = {
@@ -1023,6 +1051,7 @@  static struct clk_duplicate tegra_clk_duplicates[] = {
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"),
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
+	CLK_DUPLICATE("twd",	"smp_twd",	NULL),
 };
 
 #define CLK(dev, con, ck)	\
@@ -1053,6 +1082,7 @@  static struct clk *tegra_ptr_clks[] = {
 	&tegra_pll_x,
 	&tegra_pll_e,
 	&tegra_cclk,
+	&tegra_clk_twd,
 	&tegra_sclk,
 	&tegra_hclk,
 	&tegra_pclk,