All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Add clockevet for timer-nps driver to NPS400 SoC
@ 2016-10-23 12:12 ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt, mark.rutland, daniel.lezcano
  Cc: tglx, devicetree, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Change log
---
V1 --> V2
Apply Daniel Lezcano comments:
	CLOCKSOURCE_OF_DECLARE return value
	update hotplug callbacks usage
	squash of 2 first commits.
In this version I created new commit to serve as preperation for adding clockevents.
This way the last patch is more readable with clockevent content.
---

In first version of this driver we supported clocksource for the NPS400.
The support for clockevent was taken from Synopsys ARC timer driver.
This was good for working with our simulator of NPS400.
However in NPS400 ASIC the timers behave differently than simulation.
The timers in ASIC are shared between all threads whithin a core
and hence need different driver to support this behaviour.

The idea of this design is that we got 16 HW threads per core
each represented at bimask in a shared register in this core.
So when thread wants that next clockevent expiration will produce
timer interrupt to itself the correspondance bit in this register
should be set.
So theoretically if all 16 bits are set then all HW threads will get
timer interrupt on next expiration of timer 0.

Note that we use Synopsys ARC design naming convention for the timers
where:
timer0 is used for clockevents
timer1 is used for clocksource.

Noam Camus (3):
  soc: Support for NPS HW scheduling
  clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
  clocksource: Add clockevent support to NPS400 driver

 .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
 .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
 .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++
 arch/arc/plat-eznps/include/plat/ctop.h            |    2 -
 drivers/clocksource/timer-nps.c                    |  253 ++++++++++++++++++--
 include/linux/cpuhotplug.h                         |    1 +
 include/soc/nps/mtm.h                              |   59 +++++
 7 files changed, 325 insertions(+), 37 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
 create mode 100644 include/soc/nps/mtm.h

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH v2 0/3] Add clockevet for timer-nps driver to NPS400 SoC
@ 2016-10-23 12:12 ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt, mark.rutland, daniel.lezcano
  Cc: tglx, devicetree, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Change log
---
V1 --> V2
Apply Daniel Lezcano comments:
	CLOCKSOURCE_OF_DECLARE return value
	update hotplug callbacks usage
	squash of 2 first commits.
In this version I created new commit to serve as preperation for adding clockevents.
This way the last patch is more readable with clockevent content.
---

In first version of this driver we supported clocksource for the NPS400.
The support for clockevent was taken from Synopsys ARC timer driver.
This was good for working with our simulator of NPS400.
However in NPS400 ASIC the timers behave differently than simulation.
The timers in ASIC are shared between all threads whithin a core
and hence need different driver to support this behaviour.

The idea of this design is that we got 16 HW threads per core
each represented at bimask in a shared register in this core.
So when thread wants that next clockevent expiration will produce
timer interrupt to itself the correspondance bit in this register
should be set.
So theoretically if all 16 bits are set then all HW threads will get
timer interrupt on next expiration of timer 0.

Note that we use Synopsys ARC design naming convention for the timers
where:
timer0 is used for clockevents
timer1 is used for clocksource.

Noam Camus (3):
  soc: Support for NPS HW scheduling
  clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
  clocksource: Add clockevent support to NPS400 driver

 .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
 .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
 .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++
 arch/arc/plat-eznps/include/plat/ctop.h            |    2 -
 drivers/clocksource/timer-nps.c                    |  253 ++++++++++++++++++--
 include/linux/cpuhotplug.h                         |    1 +
 include/soc/nps/mtm.h                              |   59 +++++
 7 files changed, 325 insertions(+), 37 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
 create mode 100644 include/soc/nps/mtm.h

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH v2 1/3] soc: Support for NPS HW scheduling
  2016-10-23 12:12 ` Noam Camus
@ 2016-10-23 12:12   ` Noam Camus
  -1 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt, mark.rutland, daniel.lezcano
  Cc: tglx, devicetree, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

This new header file is for NPS400 SoC (part of ARC architecture).
The header file includes macros for save/restore of HW scheduling.
The control of HW scheduling is acheived by writing core registers.
This code was moved from arc/plat-eznps so it can be used
from drivers/clocksource/, available only for CONFIG_EZNPS_MTM_EXT.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
 arch/arc/plat-eznps/include/plat/ctop.h |    2 -
 include/soc/nps/mtm.h                   |   59 +++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 include/soc/nps/mtm.h

diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
index 9d6718c..ee2e32d 100644
--- a/arch/arc/plat-eznps/include/plat/ctop.h
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -46,9 +46,7 @@
 #define CTOP_AUX_UDMC				(CTOP_AUX_BASE + 0x300)
 
 /* EZchip core instructions */
-#define CTOP_INST_HWSCHD_OFF_R3			0x3B6F00BF
 #define CTOP_INST_HWSCHD_OFF_R4			0x3C6F00BF
-#define CTOP_INST_HWSCHD_RESTORE_R3		0x3E6F70C3
 #define CTOP_INST_HWSCHD_RESTORE_R4		0x3E6F7103
 #define CTOP_INST_SCHD_RW			0x3E6F7004
 #define CTOP_INST_SCHD_RD			0x3E6F7084
diff --git a/include/soc/nps/mtm.h b/include/soc/nps/mtm.h
new file mode 100644
index 0000000..d2f5e7e
--- /dev/null
+++ b/include/soc/nps/mtm.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef SOC_NPS_MTM_H
+#define SOC_NPS_MTM_H
+
+#define CTOP_INST_HWSCHD_OFF_R3                 0x3B6F00BF
+#define CTOP_INST_HWSCHD_RESTORE_R3             0x3E6F70C3
+
+static inline void hw_schd_save(unsigned int *flags)
+{
+	__asm__ __volatile__(
+	"       .word %1\n"
+	"       st r3,[%0]\n"
+	:
+	: "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
+	: "r3", "memory");
+}
+
+static inline void hw_schd_restore(unsigned int flags)
+{
+	__asm__ __volatile__(
+	"       mov r3, %0\n"
+	"       .word %1\n"
+	:
+	: "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
+	: "r3");
+}
+
+#endif /* SOC_NPS_MTM_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH v2 1/3] soc: Support for NPS HW scheduling
@ 2016-10-23 12:12   ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt, mark.rutland, daniel.lezcano
  Cc: tglx, devicetree, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

This new header file is for NPS400 SoC (part of ARC architecture).
The header file includes macros for save/restore of HW scheduling.
The control of HW scheduling is acheived by writing core registers.
This code was moved from arc/plat-eznps so it can be used
from drivers/clocksource/, available only for CONFIG_EZNPS_MTM_EXT.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
 arch/arc/plat-eznps/include/plat/ctop.h |    2 -
 include/soc/nps/mtm.h                   |   59 +++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 include/soc/nps/mtm.h

diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
index 9d6718c..ee2e32d 100644
--- a/arch/arc/plat-eznps/include/plat/ctop.h
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -46,9 +46,7 @@
 #define CTOP_AUX_UDMC				(CTOP_AUX_BASE + 0x300)
 
 /* EZchip core instructions */
-#define CTOP_INST_HWSCHD_OFF_R3			0x3B6F00BF
 #define CTOP_INST_HWSCHD_OFF_R4			0x3C6F00BF
-#define CTOP_INST_HWSCHD_RESTORE_R3		0x3E6F70C3
 #define CTOP_INST_HWSCHD_RESTORE_R4		0x3E6F7103
 #define CTOP_INST_SCHD_RW			0x3E6F7004
 #define CTOP_INST_SCHD_RD			0x3E6F7084
diff --git a/include/soc/nps/mtm.h b/include/soc/nps/mtm.h
new file mode 100644
index 0000000..d2f5e7e
--- /dev/null
+++ b/include/soc/nps/mtm.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef SOC_NPS_MTM_H
+#define SOC_NPS_MTM_H
+
+#define CTOP_INST_HWSCHD_OFF_R3                 0x3B6F00BF
+#define CTOP_INST_HWSCHD_RESTORE_R3             0x3E6F70C3
+
+static inline void hw_schd_save(unsigned int *flags)
+{
+	__asm__ __volatile__(
+	"       .word %1\n"
+	"       st r3,[%0]\n"
+	:
+	: "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
+	: "r3", "memory");
+}
+
+static inline void hw_schd_restore(unsigned int flags)
+{
+	__asm__ __volatile__(
+	"       mov r3, %0\n"
+	"       .word %1\n"
+	:
+	: "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
+	: "r3");
+}
+
+#endif /* SOC_NPS_MTM_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH v2 2/3] clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
@ 2016-10-23 12:12   ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt, mark.rutland, daniel.lezcano
  Cc: tglx, devicetree, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

nps_setup_clocksource() should take node as only argument i.e.:
replace
int __init nps_setup_clocksource(struct device_node *node, struct clk *clk)
with
int __init nps_setup_clocksource(struct device_node *node)

This is also serve as preperation for next patch which adds support
for clockevents to nps400.
Specifically we add new function nps_get_timer_clk() to serve clocksource
and later clockevent registration.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
 drivers/clocksource/timer-nps.c |   49 ++++++++++++++++++++------------------
 1 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
index 70c149a..6156e54 100644
--- a/drivers/clocksource/timer-nps.c
+++ b/drivers/clocksource/timer-nps.c
@@ -47,6 +47,28 @@
 static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
 
 static unsigned long nps_timer_rate;
+static int nps_get_timer_clk(struct device_node *node,
+			     unsigned long *timer_freq,
+			     struct clk *clk)
+{
+	int ret;
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk)) {
+		pr_err("timer missing clk");
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("Couldn't enable parent clk\n");
+		return ret;
+	}
+
+	*timer_freq = clk_get_rate(clk);
+
+	return 0;
+}
 
 static cycle_t nps_clksrc_read(struct clocksource *clksrc)
 {
@@ -55,23 +77,17 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc)
 	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
 }
 
-static int __init nps_setup_clocksource(struct device_node *node,
-					struct clk *clk)
+static int __init nps_setup_clocksource(struct device_node *node)
 {
 	int ret, cluster;
+	struct clk *clk;
 
 	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
 		nps_msu_reg_low_addr[cluster] =
 			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
 				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		pr_err("Couldn't enable parent clock\n");
-		return ret;
-	}
-
-	nps_timer_rate = clk_get_rate(clk);
+	nps_get_timer_clk(node, &nps_timer_rate, clk);
 
 	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
 				    nps_timer_rate, 301, 32, nps_clksrc_read);
@@ -83,18 +99,5 @@ static int __init nps_setup_clocksource(struct device_node *node,
 	return ret;
 }
 
-static int __init nps_timer_init(struct device_node *node)
-{
-	struct clk *clk;
-
-	clk = of_clk_get(node, 0);
-	if (IS_ERR(clk)) {
-		pr_err("Can't get timer clock.\n");
-		return PTR_ERR(clk);
-	}
-
-	return nps_setup_clocksource(node, clk);
-}
-
 CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
-		       nps_timer_init);
+		       nps_setup_clocksource);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH v2 2/3] clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
@ 2016-10-23 12:12   ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A
  Cc: tglx-hfZtesqFncYOwBW4kG4KsQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Noam Camus

From: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

nps_setup_clocksource() should take node as only argument i.e.:
replace
int __init nps_setup_clocksource(struct device_node *node, struct clk *clk)
with
int __init nps_setup_clocksource(struct device_node *node)

This is also serve as preperation for next patch which adds support
for clockevents to nps400.
Specifically we add new function nps_get_timer_clk() to serve clocksource
and later clockevent registration.

Signed-off-by: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/clocksource/timer-nps.c |   49 ++++++++++++++++++++------------------
 1 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
index 70c149a..6156e54 100644
--- a/drivers/clocksource/timer-nps.c
+++ b/drivers/clocksource/timer-nps.c
@@ -47,6 +47,28 @@
 static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
 
 static unsigned long nps_timer_rate;
+static int nps_get_timer_clk(struct device_node *node,
+			     unsigned long *timer_freq,
+			     struct clk *clk)
+{
+	int ret;
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk)) {
+		pr_err("timer missing clk");
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("Couldn't enable parent clk\n");
+		return ret;
+	}
+
+	*timer_freq = clk_get_rate(clk);
+
+	return 0;
+}
 
 static cycle_t nps_clksrc_read(struct clocksource *clksrc)
 {
@@ -55,23 +77,17 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc)
 	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
 }
 
-static int __init nps_setup_clocksource(struct device_node *node,
-					struct clk *clk)
+static int __init nps_setup_clocksource(struct device_node *node)
 {
 	int ret, cluster;
+	struct clk *clk;
 
 	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
 		nps_msu_reg_low_addr[cluster] =
 			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
 				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		pr_err("Couldn't enable parent clock\n");
-		return ret;
-	}
-
-	nps_timer_rate = clk_get_rate(clk);
+	nps_get_timer_clk(node, &nps_timer_rate, clk);
 
 	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
 				    nps_timer_rate, 301, 32, nps_clksrc_read);
@@ -83,18 +99,5 @@ static int __init nps_setup_clocksource(struct device_node *node,
 	return ret;
 }
 
-static int __init nps_timer_init(struct device_node *node)
-{
-	struct clk *clk;
-
-	clk = of_clk_get(node, 0);
-	if (IS_ERR(clk)) {
-		pr_err("Can't get timer clock.\n");
-		return PTR_ERR(clk);
-	}
-
-	return nps_setup_clocksource(node, clk);
-}
-
 CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
-		       nps_timer_init);
+		       nps_setup_clocksource);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
@ 2016-10-23 12:12   ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt, mark.rutland, daniel.lezcano
  Cc: tglx, devicetree, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Till now we used clockevent from generic ARC driver.
This was enough as long as we worked with simple multicore SoC.
When we are working with multithread SoC each HW thread can be
scheduled to receive timer interrupt using timer mask register.
This patch will provide a way to control clock events per HW thread.

The design idea is that for each core there is dedicated regirtser
(TSI) serving all 16 HW threads.
The register is a bitmask with one bit for each HW thread.
When HW thread wants that next expiration of timer interrupt will
hit it then the proper bit should be set in this dedicated register.
When timer expires all HW threads within this core which their bit
is set at the TSI register will be interrupted.

Driver can be used from device tree by:
compatible = "ezchip,nps400-timer0" <-- for clocksource
compatible = "ezchip,nps400-timer1" <-- for clockevent

Note that name convention for timer0/timer1 was taken from legacy
ARC design. This design is our base before adding HW threads.

Signed-off-by: Noam Camus <noamca@mellanox.com>

Change-Id: Ib351e6fc7a6b691293040ae655f202f3cc2c1298
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
 .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
 .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++
 drivers/clocksource/timer-nps.c                    |  220 +++++++++++++++++++-
 include/linux/cpuhotplug.h                         |    1 +
 5 files changed, 248 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
deleted file mode 100644
index c8c03d7..0000000
--- a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-NPS Network Processor
-
-Required properties:
-
-- compatible :	should be "ezchip,nps400-timer"
-
-Clocks required for compatible = "ezchip,nps400-timer":
-- clocks : Must contain a single entry describing the clock input
-
-Example:
-
-timer {
-	compatible = "ezchip,nps400-timer";
-	clocks = <&sysclk>;
-};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
new file mode 100644
index 0000000..e3cfce8
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
@@ -0,0 +1,17 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer0"
+
+Clocks required for compatible = "ezchip,nps400-timer0":
+- interrupts : The interrupt of the first timer
+- clocks : Must contain a single entry describing the clock input
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer0";
+	interrupts = <3>;
+	clocks = <&sysclk>;
+};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
new file mode 100644
index 0000000..c0ab419
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
@@ -0,0 +1,15 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer1"
+
+Clocks required for compatible = "ezchip,nps400-timer1":
+- clocks : Must contain a single entry describing the clock input
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer1";
+	clocks = <&sysclk>;
+};
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
index 6156e54..0757328 100644
--- a/drivers/clocksource/timer-nps.c
+++ b/drivers/clocksource/timer-nps.c
@@ -46,7 +46,7 @@
 /* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
 static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
 
-static unsigned long nps_timer_rate;
+static unsigned long nps_timer1_freq;
 static int nps_get_timer_clk(struct device_node *node,
 			     unsigned long *timer_freq,
 			     struct clk *clk)
@@ -87,10 +87,10 @@ static int __init nps_setup_clocksource(struct device_node *node)
 			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
 				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
 
-	nps_get_timer_clk(node, &nps_timer_rate, clk);
+	nps_get_timer_clk(node, &nps_timer1_freq, clk);
 
-	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
-				    nps_timer_rate, 301, 32, nps_clksrc_read);
+	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
+				    nps_timer1_freq, 301, 32, nps_clksrc_read);
 	if (ret) {
 		pr_err("Couldn't register clock source.\n");
 		clk_disable_unprepare(clk);
@@ -99,5 +99,215 @@ static int __init nps_setup_clocksource(struct device_node *node)
 	return ret;
 }
 
-CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer1",
 		       nps_setup_clocksource);
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#include <soc/nps/mtm.h>
+
+/* Timer related Aux registers */
+#define AUX_REG_TIMER0_TSI	0xFFFFF850	/* timer 0 HW threads mask */
+#define NPS_REG_TIMER0_LIMIT	0x23		/* timer 0 limit */
+#define NPS_REG_TIMER0_CTRL	0x22		/* timer 0 control */
+#define NPS_REG_TIMER0_CNT	0x21		/* timer 0 count */
+
+#define TIMER0_CTRL_IE	(1 << 0) /* Interrupt when Count reaches limit */
+#define TIMER0_CTRL_NH	(1 << 1) /* Count only when CPU NOT halted */
+
+static unsigned long nps_timer0_freq;
+static unsigned long nps_timer0_irq;
+
+/*
+ * Arm the timer to interrupt after @cycles
+ */
+static void nps_clkevent_timer_event_setup(unsigned int cycles)
+{
+	write_aux_reg(NPS_REG_TIMER0_LIMIT, cycles);
+	write_aux_reg(NPS_REG_TIMER0_CNT, 0);   /* start from 0 */
+
+	write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+}
+
+static void nps_clkevent_rm_thread(bool remove_thread)
+{
+	unsigned int cflags;
+	unsigned int enabled_threads;
+	unsigned long flags;
+	int thread;
+
+	local_irq_save(flags);
+	hw_schd_save(&cflags);
+
+	enabled_threads = read_aux_reg(AUX_REG_TIMER0_TSI);
+
+	/* remove thread from TSI1 */
+	if (remove_thread) {
+		thread = read_aux_reg(CTOP_AUX_THREAD_ID);
+		enabled_threads &= ~(1 << thread);
+		write_aux_reg(AUX_REG_TIMER0_TSI, enabled_threads);
+	}
+
+	/* Re-arm the timer if needed */
+	if (!enabled_threads)
+		write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH);
+	else
+		write_aux_reg(NPS_REG_TIMER0_CTRL,
+			      TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+
+	hw_schd_restore(cflags);
+	local_irq_restore(flags);
+}
+
+static void nps_clkevent_add_thread(bool set_event)
+{
+	int thread;
+	unsigned int cflags, enabled_threads;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	hw_schd_save(&cflags);
+
+	/* add thread to TSI1 */
+	thread = read_aux_reg(CTOP_AUX_THREAD_ID);
+	enabled_threads = read_aux_reg(AUX_REG_TIMER0_TSI);
+	enabled_threads |= (1 << thread);
+	write_aux_reg(AUX_REG_TIMER0_TSI, enabled_threads);
+
+	/* set next timer event */
+	if (set_event)
+		write_aux_reg(NPS_REG_TIMER0_CTRL,
+			      TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+
+	hw_schd_restore(cflags);
+	local_irq_restore(flags);
+}
+
+static int nps_clkevent_set_next_event(unsigned long delta,
+				       struct clock_event_device *dev)
+{
+	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
+	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
+
+	nps_clkevent_add_thread(true);
+	chip->irq_unmask(&desc->irq_data);
+
+	return 0;
+}
+
+/*
+ * Whenever anyone tries to change modes, we just mask interrupts
+ * and wait for the next event to get set.
+ */
+static int nps_clkevent_timer_shutdown(struct clock_event_device *dev)
+{
+	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
+	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
+
+	chip->irq_mask(&desc->irq_data);
+
+	return 0;
+}
+
+static int nps_clkevent_set_periodic(struct clock_event_device *dev)
+{
+	nps_clkevent_add_thread(false);
+	if (read_aux_reg(CTOP_AUX_THREAD_ID) == 0)
+		nps_clkevent_timer_event_setup(nps_timer0_freq / HZ);
+
+	return 0;
+}
+
+static int nps_clkevent_set_oneshot(struct clock_event_device *dev)
+{
+	nps_clkevent_rm_thread(true);
+	nps_clkevent_timer_shutdown(dev);
+
+	return 0;
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
+	.name				=	"NPS Timer0",
+	.features			=	CLOCK_EVT_FEAT_ONESHOT |
+						CLOCK_EVT_FEAT_PERIODIC,
+	.rating				=	300,
+	.set_next_event			=	nps_clkevent_set_next_event,
+	.set_state_periodic		=	nps_clkevent_set_periodic,
+	.set_state_oneshot		=	nps_clkevent_set_oneshot,
+	.set_state_oneshot_stopped	=	nps_clkevent_timer_shutdown,
+	.set_state_shutdown		=	nps_clkevent_timer_shutdown,
+	.tick_resume			=	nps_clkevent_timer_shutdown,
+};
+
+static irqreturn_t timer_irq_handler(int irq, void *dev_id)
+{
+	/*
+	 * Note that generic IRQ core could have passed @evt for @dev_id if
+	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
+	 */
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+	int irq_reenable = clockevent_state_periodic(evt);
+
+	nps_clkevent_rm_thread(!irq_reenable);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static int nps_timer_starting_cpu(unsigned int cpu)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+
+	evt->cpumask = cpumask_of(smp_processor_id());
+
+	clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX);
+	enable_percpu_irq(nps_timer0_irq, 0);
+
+	return 0;
+}
+
+static int nps_timer_dying_cpu(unsigned int cpu)
+{
+	disable_percpu_irq(nps_timer0_irq);
+	return 0;
+}
+
+static int __init nps_setup_clockevent(struct device_node *node)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+	struct clk *clk;
+	int ret;
+
+	nps_timer0_irq = irq_of_parse_and_map(node, 0);
+	if (nps_timer0_irq <= 0) {
+		pr_err("clockevent: missing irq");
+		return -EINVAL;
+	}
+
+	nps_get_timer_clk(node, &nps_timer0_freq, clk);
+
+	/* Needs apriori irq_set_percpu_devid() done in intc map function */
+	ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
+				 "Timer0 (per-cpu-tick)", evt);
+	if (ret) {
+		pr_err("Couldn't request irq\n");
+		clk_disable_unprepare(clk);
+		return ret;
+	}
+
+	ret = cpuhp_setup_state(CPUHP_AP_NPS_TIMER_STARTING,
+				"AP_NPS_TIMER_STARTING",
+				nps_timer_starting_cpu,
+				nps_timer_dying_cpu);
+	if (ret) {
+		pr_err("Failed to setup hotplug state");
+		clk_disable_unprepare(clk);
+		return ret;
+	}
+
+	return 0;
+}
+
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clkevt, "ezchip,nps400-timer0",
+		       nps_setup_clockevent);
+#endif /* CONFIG_EZNPS_MTM_EXT */
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 34bd805..9efc1a3 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -60,6 +60,7 @@ enum cpuhp_state {
 	CPUHP_AP_MARCO_TIMER_STARTING,
 	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
 	CPUHP_AP_ARC_TIMER_STARTING,
+	CPUHP_AP_NPS_TIMER_STARTING,
 	CPUHP_AP_KVM_STARTING,
 	CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
 	CPUHP_AP_KVM_ARM_VGIC_STARTING,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
@ 2016-10-23 12:12   ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-23 12:12 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A
  Cc: tglx-hfZtesqFncYOwBW4kG4KsQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Noam Camus

From: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Till now we used clockevent from generic ARC driver.
This was enough as long as we worked with simple multicore SoC.
When we are working with multithread SoC each HW thread can be
scheduled to receive timer interrupt using timer mask register.
This patch will provide a way to control clock events per HW thread.

The design idea is that for each core there is dedicated regirtser
(TSI) serving all 16 HW threads.
The register is a bitmask with one bit for each HW thread.
When HW thread wants that next expiration of timer interrupt will
hit it then the proper bit should be set in this dedicated register.
When timer expires all HW threads within this core which their bit
is set at the TSI register will be interrupted.

Driver can be used from device tree by:
compatible = "ezchip,nps400-timer0" <-- for clocksource
compatible = "ezchip,nps400-timer1" <-- for clockevent

Note that name convention for timer0/timer1 was taken from legacy
ARC design. This design is our base before adding HW threads.

Signed-off-by: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Change-Id: Ib351e6fc7a6b691293040ae655f202f3cc2c1298
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
 .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
 .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++
 drivers/clocksource/timer-nps.c                    |  220 +++++++++++++++++++-
 include/linux/cpuhotplug.h                         |    1 +
 5 files changed, 248 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
deleted file mode 100644
index c8c03d7..0000000
--- a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-NPS Network Processor
-
-Required properties:
-
-- compatible :	should be "ezchip,nps400-timer"
-
-Clocks required for compatible = "ezchip,nps400-timer":
-- clocks : Must contain a single entry describing the clock input
-
-Example:
-
-timer {
-	compatible = "ezchip,nps400-timer";
-	clocks = <&sysclk>;
-};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
new file mode 100644
index 0000000..e3cfce8
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
@@ -0,0 +1,17 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer0"
+
+Clocks required for compatible = "ezchip,nps400-timer0":
+- interrupts : The interrupt of the first timer
+- clocks : Must contain a single entry describing the clock input
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer0";
+	interrupts = <3>;
+	clocks = <&sysclk>;
+};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
new file mode 100644
index 0000000..c0ab419
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
@@ -0,0 +1,15 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer1"
+
+Clocks required for compatible = "ezchip,nps400-timer1":
+- clocks : Must contain a single entry describing the clock input
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer1";
+	clocks = <&sysclk>;
+};
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
index 6156e54..0757328 100644
--- a/drivers/clocksource/timer-nps.c
+++ b/drivers/clocksource/timer-nps.c
@@ -46,7 +46,7 @@
 /* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
 static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
 
-static unsigned long nps_timer_rate;
+static unsigned long nps_timer1_freq;
 static int nps_get_timer_clk(struct device_node *node,
 			     unsigned long *timer_freq,
 			     struct clk *clk)
@@ -87,10 +87,10 @@ static int __init nps_setup_clocksource(struct device_node *node)
 			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
 				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
 
-	nps_get_timer_clk(node, &nps_timer_rate, clk);
+	nps_get_timer_clk(node, &nps_timer1_freq, clk);
 
-	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
-				    nps_timer_rate, 301, 32, nps_clksrc_read);
+	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
+				    nps_timer1_freq, 301, 32, nps_clksrc_read);
 	if (ret) {
 		pr_err("Couldn't register clock source.\n");
 		clk_disable_unprepare(clk);
@@ -99,5 +99,215 @@ static int __init nps_setup_clocksource(struct device_node *node)
 	return ret;
 }
 
-CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer1",
 		       nps_setup_clocksource);
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#include <soc/nps/mtm.h>
+
+/* Timer related Aux registers */
+#define AUX_REG_TIMER0_TSI	0xFFFFF850	/* timer 0 HW threads mask */
+#define NPS_REG_TIMER0_LIMIT	0x23		/* timer 0 limit */
+#define NPS_REG_TIMER0_CTRL	0x22		/* timer 0 control */
+#define NPS_REG_TIMER0_CNT	0x21		/* timer 0 count */
+
+#define TIMER0_CTRL_IE	(1 << 0) /* Interrupt when Count reaches limit */
+#define TIMER0_CTRL_NH	(1 << 1) /* Count only when CPU NOT halted */
+
+static unsigned long nps_timer0_freq;
+static unsigned long nps_timer0_irq;
+
+/*
+ * Arm the timer to interrupt after @cycles
+ */
+static void nps_clkevent_timer_event_setup(unsigned int cycles)
+{
+	write_aux_reg(NPS_REG_TIMER0_LIMIT, cycles);
+	write_aux_reg(NPS_REG_TIMER0_CNT, 0);   /* start from 0 */
+
+	write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+}
+
+static void nps_clkevent_rm_thread(bool remove_thread)
+{
+	unsigned int cflags;
+	unsigned int enabled_threads;
+	unsigned long flags;
+	int thread;
+
+	local_irq_save(flags);
+	hw_schd_save(&cflags);
+
+	enabled_threads = read_aux_reg(AUX_REG_TIMER0_TSI);
+
+	/* remove thread from TSI1 */
+	if (remove_thread) {
+		thread = read_aux_reg(CTOP_AUX_THREAD_ID);
+		enabled_threads &= ~(1 << thread);
+		write_aux_reg(AUX_REG_TIMER0_TSI, enabled_threads);
+	}
+
+	/* Re-arm the timer if needed */
+	if (!enabled_threads)
+		write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH);
+	else
+		write_aux_reg(NPS_REG_TIMER0_CTRL,
+			      TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+
+	hw_schd_restore(cflags);
+	local_irq_restore(flags);
+}
+
+static void nps_clkevent_add_thread(bool set_event)
+{
+	int thread;
+	unsigned int cflags, enabled_threads;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	hw_schd_save(&cflags);
+
+	/* add thread to TSI1 */
+	thread = read_aux_reg(CTOP_AUX_THREAD_ID);
+	enabled_threads = read_aux_reg(AUX_REG_TIMER0_TSI);
+	enabled_threads |= (1 << thread);
+	write_aux_reg(AUX_REG_TIMER0_TSI, enabled_threads);
+
+	/* set next timer event */
+	if (set_event)
+		write_aux_reg(NPS_REG_TIMER0_CTRL,
+			      TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+
+	hw_schd_restore(cflags);
+	local_irq_restore(flags);
+}
+
+static int nps_clkevent_set_next_event(unsigned long delta,
+				       struct clock_event_device *dev)
+{
+	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
+	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
+
+	nps_clkevent_add_thread(true);
+	chip->irq_unmask(&desc->irq_data);
+
+	return 0;
+}
+
+/*
+ * Whenever anyone tries to change modes, we just mask interrupts
+ * and wait for the next event to get set.
+ */
+static int nps_clkevent_timer_shutdown(struct clock_event_device *dev)
+{
+	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
+	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
+
+	chip->irq_mask(&desc->irq_data);
+
+	return 0;
+}
+
+static int nps_clkevent_set_periodic(struct clock_event_device *dev)
+{
+	nps_clkevent_add_thread(false);
+	if (read_aux_reg(CTOP_AUX_THREAD_ID) == 0)
+		nps_clkevent_timer_event_setup(nps_timer0_freq / HZ);
+
+	return 0;
+}
+
+static int nps_clkevent_set_oneshot(struct clock_event_device *dev)
+{
+	nps_clkevent_rm_thread(true);
+	nps_clkevent_timer_shutdown(dev);
+
+	return 0;
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
+	.name				=	"NPS Timer0",
+	.features			=	CLOCK_EVT_FEAT_ONESHOT |
+						CLOCK_EVT_FEAT_PERIODIC,
+	.rating				=	300,
+	.set_next_event			=	nps_clkevent_set_next_event,
+	.set_state_periodic		=	nps_clkevent_set_periodic,
+	.set_state_oneshot		=	nps_clkevent_set_oneshot,
+	.set_state_oneshot_stopped	=	nps_clkevent_timer_shutdown,
+	.set_state_shutdown		=	nps_clkevent_timer_shutdown,
+	.tick_resume			=	nps_clkevent_timer_shutdown,
+};
+
+static irqreturn_t timer_irq_handler(int irq, void *dev_id)
+{
+	/*
+	 * Note that generic IRQ core could have passed @evt for @dev_id if
+	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
+	 */
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+	int irq_reenable = clockevent_state_periodic(evt);
+
+	nps_clkevent_rm_thread(!irq_reenable);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static int nps_timer_starting_cpu(unsigned int cpu)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+
+	evt->cpumask = cpumask_of(smp_processor_id());
+
+	clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX);
+	enable_percpu_irq(nps_timer0_irq, 0);
+
+	return 0;
+}
+
+static int nps_timer_dying_cpu(unsigned int cpu)
+{
+	disable_percpu_irq(nps_timer0_irq);
+	return 0;
+}
+
+static int __init nps_setup_clockevent(struct device_node *node)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+	struct clk *clk;
+	int ret;
+
+	nps_timer0_irq = irq_of_parse_and_map(node, 0);
+	if (nps_timer0_irq <= 0) {
+		pr_err("clockevent: missing irq");
+		return -EINVAL;
+	}
+
+	nps_get_timer_clk(node, &nps_timer0_freq, clk);
+
+	/* Needs apriori irq_set_percpu_devid() done in intc map function */
+	ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
+				 "Timer0 (per-cpu-tick)", evt);
+	if (ret) {
+		pr_err("Couldn't request irq\n");
+		clk_disable_unprepare(clk);
+		return ret;
+	}
+
+	ret = cpuhp_setup_state(CPUHP_AP_NPS_TIMER_STARTING,
+				"AP_NPS_TIMER_STARTING",
+				nps_timer_starting_cpu,
+				nps_timer_dying_cpu);
+	if (ret) {
+		pr_err("Failed to setup hotplug state");
+		clk_disable_unprepare(clk);
+		return ret;
+	}
+
+	return 0;
+}
+
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clkevt, "ezchip,nps400-timer0",
+		       nps_setup_clockevent);
+#endif /* CONFIG_EZNPS_MTM_EXT */
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 34bd805..9efc1a3 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -60,6 +60,7 @@ enum cpuhp_state {
 	CPUHP_AP_MARCO_TIMER_STARTING,
 	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
 	CPUHP_AP_ARC_TIMER_STARTING,
+	CPUHP_AP_NPS_TIMER_STARTING,
 	CPUHP_AP_KVM_STARTING,
 	CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
 	CPUHP_AP_KVM_ARM_VGIC_STARTING,
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-10-23 12:12   ` Noam Camus
  (?)
@ 2016-10-30 20:41   ` Rob Herring
  -1 siblings, 0 replies; 95+ messages in thread
From: Rob Herring @ 2016-10-30 20:41 UTC (permalink / raw)
  To: Noam Camus; +Cc: mark.rutland, daniel.lezcano, tglx, devicetree, linux-kernel

On Sun, Oct 23, 2016 at 03:12:28PM +0300, Noam Camus wrote:
> From: Noam Camus <noamca@mellanox.com>
> 
> Till now we used clockevent from generic ARC driver.
> This was enough as long as we worked with simple multicore SoC.
> When we are working with multithread SoC each HW thread can be
> scheduled to receive timer interrupt using timer mask register.
> This patch will provide a way to control clock events per HW thread.
> 
> The design idea is that for each core there is dedicated regirtser
> (TSI) serving all 16 HW threads.
> The register is a bitmask with one bit for each HW thread.
> When HW thread wants that next expiration of timer interrupt will
> hit it then the proper bit should be set in this dedicated register.
> When timer expires all HW threads within this core which their bit
> is set at the TSI register will be interrupted.
> 
> Driver can be used from device tree by:
> compatible = "ezchip,nps400-timer0" <-- for clocksource
> compatible = "ezchip,nps400-timer1" <-- for clockevent
> 
> Note that name convention for timer0/timer1 was taken from legacy
> ARC design. This design is our base before adding HW threads.
> 
> Signed-off-by: Noam Camus <noamca@mellanox.com>
> 
> Change-Id: Ib351e6fc7a6b691293040ae655f202f3cc2c1298
> ---
>  .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
>  .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
>  .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++

For the binding,

Acked-by: Rob Herring <robh@kernel.org>

However, one issue below...

>  drivers/clocksource/timer-nps.c                    |  220 +++++++++++++++++++-
>  include/linux/cpuhotplug.h                         |    1 +
>  5 files changed, 248 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt


> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> index 6156e54..0757328 100644
> --- a/drivers/clocksource/timer-nps.c
> +++ b/drivers/clocksource/timer-nps.c
> @@ -46,7 +46,7 @@
>  /* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
>  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
>  
> -static unsigned long nps_timer_rate;
> +static unsigned long nps_timer1_freq;
>  static int nps_get_timer_clk(struct device_node *node,
>  			     unsigned long *timer_freq,
>  			     struct clk *clk)
> @@ -87,10 +87,10 @@ static int __init nps_setup_clocksource(struct device_node *node)
>  			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
>  				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
>  
> -	nps_get_timer_clk(node, &nps_timer_rate, clk);
> +	nps_get_timer_clk(node, &nps_timer1_freq, clk);
>  
> -	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
> -				    nps_timer_rate, 301, 32, nps_clksrc_read);
> +	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
> +				    nps_timer1_freq, 301, 32, nps_clksrc_read);
>  	if (ret) {
>  		pr_err("Couldn't register clock source.\n");
>  		clk_disable_unprepare(clk);
> @@ -99,5 +99,215 @@ static int __init nps_setup_clocksource(struct device_node *node)
>  	return ret;
>  }
>  
> -CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
> +CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer1",
>  		       nps_setup_clocksource);

You should keep the old string here for backwards compatiblity.

Rob

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 1/3] soc: Support for NPS HW scheduling
@ 2016-10-31 10:26     ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-10-31 10:26 UTC (permalink / raw)
  To: Noam Camus; +Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel

On Sun, Oct 23, 2016 at 03:12:26PM +0300, Noam Camus wrote:
> From: Noam Camus <noamca@mellanox.com>
> 
> This new header file is for NPS400 SoC (part of ARC architecture).
> The header file includes macros for save/restore of HW scheduling.
> The control of HW scheduling is acheived by writing core registers.

s/acheived/achieved/

> This code was moved from arc/plat-eznps so it can be used
> from drivers/clocksource/, available only for CONFIG_EZNPS_MTM_EXT.
> 
> Signed-off-by: Noam Camus <noamca@mellanox.com>
> ---
>  arch/arc/plat-eznps/include/plat/ctop.h |    2 -
>  include/soc/nps/mtm.h                   |   59 +++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+), 2 deletions(-)
>  create mode 100644 include/soc/nps/mtm.h
> 
> diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
> index 9d6718c..ee2e32d 100644
> --- a/arch/arc/plat-eznps/include/plat/ctop.h
> +++ b/arch/arc/plat-eznps/include/plat/ctop.h
> @@ -46,9 +46,7 @@
>  #define CTOP_AUX_UDMC				(CTOP_AUX_BASE + 0x300)
>  
>  /* EZchip core instructions */
> -#define CTOP_INST_HWSCHD_OFF_R3			0x3B6F00BF
>  #define CTOP_INST_HWSCHD_OFF_R4			0x3C6F00BF
> -#define CTOP_INST_HWSCHD_RESTORE_R3		0x3E6F70C3
>  #define CTOP_INST_HWSCHD_RESTORE_R4		0x3E6F7103
>  #define CTOP_INST_SCHD_RW			0x3E6F7004
>  #define CTOP_INST_SCHD_RD			0x3E6F7084
> diff --git a/include/soc/nps/mtm.h b/include/soc/nps/mtm.h
> new file mode 100644
> index 0000000..d2f5e7e
> --- /dev/null
> +++ b/include/soc/nps/mtm.h
> @@ -0,0 +1,59 @@
> +/*
> + * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
> + *
> + * This software is available to you under a choice of one of two
> + * licenses.  You may choose to be licensed under the terms of the GNU
> + * General Public License (GPL) Version 2, available from the file
> + * COPYING in the main directory of this source tree, or the
> + * OpenIB.org BSD license below:
> + *
> + *     Redistribution and use in source and binary forms, with or
> + *     without modification, are permitted provided that the following
> + *     conditions are met:
> + *
> + *      - Redistributions of source code must retain the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer.
> + *
> + *      - Redistributions in binary form must reproduce the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer in the documentation and/or other materials
> + *        provided with the distribution.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#ifndef SOC_NPS_MTM_H
> +#define SOC_NPS_MTM_H
> +
> +#define CTOP_INST_HWSCHD_OFF_R3                 0x3B6F00BF
> +#define CTOP_INST_HWSCHD_RESTORE_R3             0x3E6F70C3
> +
> +static inline void hw_schd_save(unsigned int *flags)
> +{
> +	__asm__ __volatile__(
> +	"       .word %1\n"
> +	"       st r3,[%0]\n"
> +	:
> +	: "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
> +	: "r3", "memory");
> +}
> +

Wouldn't make sense to change the macro name to CTOP_INST_HWSCHD_SAVE_R3 ?

> +static inline void hw_schd_restore(unsigned int flags)
> +{
> +	__asm__ __volatile__(
> +	"       mov r3, %0\n"
> +	"       .word %1\n"
> +	:
> +	: "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
> +	: "r3");
> +}
> +
> +#endif /* SOC_NPS_MTM_H */
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 1/3] soc: Support for NPS HW scheduling
@ 2016-10-31 10:26     ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-10-31 10:26 UTC (permalink / raw)
  To: Noam Camus
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	tglx-hfZtesqFncYOwBW4kG4KsQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Sun, Oct 23, 2016 at 03:12:26PM +0300, Noam Camus wrote:
> From: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> This new header file is for NPS400 SoC (part of ARC architecture).
> The header file includes macros for save/restore of HW scheduling.
> The control of HW scheduling is acheived by writing core registers.

s/acheived/achieved/

> This code was moved from arc/plat-eznps so it can be used
> from drivers/clocksource/, available only for CONFIG_EZNPS_MTM_EXT.
> 
> Signed-off-by: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  arch/arc/plat-eznps/include/plat/ctop.h |    2 -
>  include/soc/nps/mtm.h                   |   59 +++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+), 2 deletions(-)
>  create mode 100644 include/soc/nps/mtm.h
> 
> diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
> index 9d6718c..ee2e32d 100644
> --- a/arch/arc/plat-eznps/include/plat/ctop.h
> +++ b/arch/arc/plat-eznps/include/plat/ctop.h
> @@ -46,9 +46,7 @@
>  #define CTOP_AUX_UDMC				(CTOP_AUX_BASE + 0x300)
>  
>  /* EZchip core instructions */
> -#define CTOP_INST_HWSCHD_OFF_R3			0x3B6F00BF
>  #define CTOP_INST_HWSCHD_OFF_R4			0x3C6F00BF
> -#define CTOP_INST_HWSCHD_RESTORE_R3		0x3E6F70C3
>  #define CTOP_INST_HWSCHD_RESTORE_R4		0x3E6F7103
>  #define CTOP_INST_SCHD_RW			0x3E6F7004
>  #define CTOP_INST_SCHD_RD			0x3E6F7084
> diff --git a/include/soc/nps/mtm.h b/include/soc/nps/mtm.h
> new file mode 100644
> index 0000000..d2f5e7e
> --- /dev/null
> +++ b/include/soc/nps/mtm.h
> @@ -0,0 +1,59 @@
> +/*
> + * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
> + *
> + * This software is available to you under a choice of one of two
> + * licenses.  You may choose to be licensed under the terms of the GNU
> + * General Public License (GPL) Version 2, available from the file
> + * COPYING in the main directory of this source tree, or the
> + * OpenIB.org BSD license below:
> + *
> + *     Redistribution and use in source and binary forms, with or
> + *     without modification, are permitted provided that the following
> + *     conditions are met:
> + *
> + *      - Redistributions of source code must retain the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer.
> + *
> + *      - Redistributions in binary form must reproduce the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer in the documentation and/or other materials
> + *        provided with the distribution.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#ifndef SOC_NPS_MTM_H
> +#define SOC_NPS_MTM_H
> +
> +#define CTOP_INST_HWSCHD_OFF_R3                 0x3B6F00BF
> +#define CTOP_INST_HWSCHD_RESTORE_R3             0x3E6F70C3
> +
> +static inline void hw_schd_save(unsigned int *flags)
> +{
> +	__asm__ __volatile__(
> +	"       .word %1\n"
> +	"       st r3,[%0]\n"
> +	:
> +	: "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
> +	: "r3", "memory");
> +}
> +

Wouldn't make sense to change the macro name to CTOP_INST_HWSCHD_SAVE_R3 ?

> +static inline void hw_schd_restore(unsigned int flags)
> +{
> +	__asm__ __volatile__(
> +	"       mov r3, %0\n"
> +	"       .word %1\n"
> +	:
> +	: "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
> +	: "r3");
> +}
> +
> +#endif /* SOC_NPS_MTM_H */
> -- 
> 1.7.1
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 2/3] clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
@ 2016-10-31 10:28     ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-10-31 10:28 UTC (permalink / raw)
  To: Noam Camus; +Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel

On Sun, Oct 23, 2016 at 03:12:27PM +0300, Noam Camus wrote:
> From: Noam Camus <noamca@mellanox.com>
> 
> nps_setup_clocksource() should take node as only argument i.e.:
> replace
> int __init nps_setup_clocksource(struct device_node *node, struct clk *clk)
> with
> int __init nps_setup_clocksource(struct device_node *node)
> 
> This is also serve as preperation for next patch which adds support

s/preperation/preparation/

> for clockevents to nps400.
> Specifically we add new function nps_get_timer_clk() to serve clocksource
> and later clockevent registration.
> Signed-off-by: Noam Camus <noamca@mellanox.com>
> ---
>  drivers/clocksource/timer-nps.c |   49 ++++++++++++++++++++------------------
>  1 files changed, 26 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> index 70c149a..6156e54 100644
> --- a/drivers/clocksource/timer-nps.c
> +++ b/drivers/clocksource/timer-nps.c
> @@ -47,6 +47,28 @@
>  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
>  
>  static unsigned long nps_timer_rate;
> +static int nps_get_timer_clk(struct device_node *node,
> +			     unsigned long *timer_freq,
> +			     struct clk *clk)

This function prototype does not make sense. A pointer to a clock is passed
for nothing here.

> +{
> +	int ret;
> +
> +	clk = of_clk_get(node, 0);
> +	if (IS_ERR(clk)) {
> +		pr_err("timer missing clk");
> +		return PTR_ERR(clk);
> +	}
> +
> +	ret = clk_prepare_enable(clk);
> +	if (ret) {
> +		pr_err("Couldn't enable parent clk\n");
> +		return ret;
> +	}
> +
> +	*timer_freq = clk_get_rate(clk);
> +

	timer_freq check.

	rollback on error.

> +	return 0;
> +}
>  
>  static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>  {
> @@ -55,23 +77,17 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>  	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
>  }
>  
> -static int __init nps_setup_clocksource(struct device_node *node,
> -					struct clk *clk)
> +static int __init nps_setup_clocksource(struct device_node *node)
>  {
>  	int ret, cluster;
> +	struct clk *clk;
>  
>  	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
>  		nps_msu_reg_low_addr[cluster] =
>  			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
>  				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		pr_err("Couldn't enable parent clock\n");
> -		return ret;
> -	}
> -
> -	nps_timer_rate = clk_get_rate(clk);
> +	nps_get_timer_clk(node, &nps_timer_rate, clk);

Return code check ?
  
>  	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
>  				    nps_timer_rate, 301, 32, nps_clksrc_read);
> @@ -83,18 +99,5 @@ static int __init nps_setup_clocksource(struct device_node *node,
>  	return ret;
>  }
>  
> -static int __init nps_timer_init(struct device_node *node)
> -{
> -	struct clk *clk;
> -
> -	clk = of_clk_get(node, 0);
> -	if (IS_ERR(clk)) {
> -		pr_err("Can't get timer clock.\n");
> -		return PTR_ERR(clk);
> -	}
> -
> -	return nps_setup_clocksource(node, clk);
> -}
> -
>  CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
> -		       nps_timer_init);
> +		       nps_setup_clocksource);
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 2/3] clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
@ 2016-10-31 10:28     ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-10-31 10:28 UTC (permalink / raw)
  To: Noam Camus
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	tglx-hfZtesqFncYOwBW4kG4KsQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Sun, Oct 23, 2016 at 03:12:27PM +0300, Noam Camus wrote:
> From: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> nps_setup_clocksource() should take node as only argument i.e.:
> replace
> int __init nps_setup_clocksource(struct device_node *node, struct clk *clk)
> with
> int __init nps_setup_clocksource(struct device_node *node)
> 
> This is also serve as preperation for next patch which adds support

s/preperation/preparation/

> for clockevents to nps400.
> Specifically we add new function nps_get_timer_clk() to serve clocksource
> and later clockevent registration.
> Signed-off-by: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/clocksource/timer-nps.c |   49 ++++++++++++++++++++------------------
>  1 files changed, 26 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> index 70c149a..6156e54 100644
> --- a/drivers/clocksource/timer-nps.c
> +++ b/drivers/clocksource/timer-nps.c
> @@ -47,6 +47,28 @@
>  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
>  
>  static unsigned long nps_timer_rate;
> +static int nps_get_timer_clk(struct device_node *node,
> +			     unsigned long *timer_freq,
> +			     struct clk *clk)

This function prototype does not make sense. A pointer to a clock is passed
for nothing here.

> +{
> +	int ret;
> +
> +	clk = of_clk_get(node, 0);
> +	if (IS_ERR(clk)) {
> +		pr_err("timer missing clk");
> +		return PTR_ERR(clk);
> +	}
> +
> +	ret = clk_prepare_enable(clk);
> +	if (ret) {
> +		pr_err("Couldn't enable parent clk\n");
> +		return ret;
> +	}
> +
> +	*timer_freq = clk_get_rate(clk);
> +

	timer_freq check.

	rollback on error.

> +	return 0;
> +}
>  
>  static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>  {
> @@ -55,23 +77,17 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>  	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
>  }
>  
> -static int __init nps_setup_clocksource(struct device_node *node,
> -					struct clk *clk)
> +static int __init nps_setup_clocksource(struct device_node *node)
>  {
>  	int ret, cluster;
> +	struct clk *clk;
>  
>  	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
>  		nps_msu_reg_low_addr[cluster] =
>  			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
>  				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		pr_err("Couldn't enable parent clock\n");
> -		return ret;
> -	}
> -
> -	nps_timer_rate = clk_get_rate(clk);
> +	nps_get_timer_clk(node, &nps_timer_rate, clk);

Return code check ?
  
>  	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
>  				    nps_timer_rate, 301, 32, nps_clksrc_read);
> @@ -83,18 +99,5 @@ static int __init nps_setup_clocksource(struct device_node *node,
>  	return ret;
>  }
>  
> -static int __init nps_timer_init(struct device_node *node)
> -{
> -	struct clk *clk;
> -
> -	clk = of_clk_get(node, 0);
> -	if (IS_ERR(clk)) {
> -		pr_err("Can't get timer clock.\n");
> -		return PTR_ERR(clk);
> -	}
> -
> -	return nps_setup_clocksource(node, clk);
> -}
> -
>  CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
> -		       nps_timer_init);
> +		       nps_setup_clocksource);
> -- 
> 1.7.1
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-10-23 12:12   ` Noam Camus
  (?)
  (?)
@ 2016-10-31 10:52   ` Daniel Lezcano
  2016-10-31 17:03     ` Noam Camus
  -1 siblings, 1 reply; 95+ messages in thread
From: Daniel Lezcano @ 2016-10-31 10:52 UTC (permalink / raw)
  To: Noam Camus; +Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel

On Sun, Oct 23, 2016 at 03:12:28PM +0300, Noam Camus wrote:
> From: Noam Camus <noamca@mellanox.com>
> 
> Till now we used clockevent from generic ARC driver.
> This was enough as long as we worked with simple multicore SoC.
> When we are working with multithread SoC each HW thread can be
> scheduled to receive timer interrupt using timer mask register.
> This patch will provide a way to control clock events per HW thread.
> 
> The design idea is that for each core there is dedicated regirtser

s/regirtser/register/

Hey ! re-read yourself.

> (TSI) serving all 16 HW threads.
> The register is a bitmask with one bit for each HW thread.
> When HW thread wants that next expiration of timer interrupt will
> hit it then the proper bit should be set in this dedicated register.

I'm not sure to understand this sentence. Do you mean each cpu/thread must
set a flag in the TSI register at BIT(phys_id) when they set a timer ?

> When timer expires all HW threads within this core which their bit
> is set at the TSI register will be interrupted.

Does it mean some HW threads will be wake up for nothing ?

eg. 

HWT1 sets the timer to expire within 2 seconds
HWT2 sets the timer to expire within 2 hours

When the first timer expires, that will wake up HWT1 *and* HWT2 ?

The code is a bit confusing because of the very specific design of this timer.

Below more questions for clarification.

> Driver can be used from device tree by:
> compatible = "ezchip,nps400-timer0" <-- for clocksource
> compatible = "ezchip,nps400-timer1" <-- for clockevent
> 
> Note that name convention for timer0/timer1 was taken from legacy
> ARC design. This design is our base before adding HW threads.
> 
> Signed-off-by: Noam Camus <noamca@mellanox.com>
> 
> Change-Id: Ib351e6fc7a6b691293040ae655f202f3cc2c1298
> ---
>  .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
>  .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
>  .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++
>  drivers/clocksource/timer-nps.c                    |  220 +++++++++++++++++++-
>  include/linux/cpuhotplug.h                         |    1 +
>  5 files changed, 248 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
> 
> diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
> deleted file mode 100644
> index c8c03d7..0000000
> --- a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -NPS Network Processor
> -
> -Required properties:
> -
> -- compatible :	should be "ezchip,nps400-timer"
> -
> -Clocks required for compatible = "ezchip,nps400-timer":
> -- clocks : Must contain a single entry describing the clock input
> -
> -Example:
> -
> -timer {
> -	compatible = "ezchip,nps400-timer";
> -	clocks = <&sysclk>;
> -};
> diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
> new file mode 100644
> index 0000000..e3cfce8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
> @@ -0,0 +1,17 @@
> +NPS Network Processor
> +
> +Required properties:
> +
> +- compatible :	should be "ezchip,nps400-timer0"
> +
> +Clocks required for compatible = "ezchip,nps400-timer0":
> +- interrupts : The interrupt of the first timer
> +- clocks : Must contain a single entry describing the clock input
> +
> +Example:
> +
> +timer {
> +	compatible = "ezchip,nps400-timer0";
> +	interrupts = <3>;
> +	clocks = <&sysclk>;
> +};
> diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
> new file mode 100644
> index 0000000..c0ab419
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
> @@ -0,0 +1,15 @@
> +NPS Network Processor
> +
> +Required properties:
> +
> +- compatible :	should be "ezchip,nps400-timer1"
> +
> +Clocks required for compatible = "ezchip,nps400-timer1":
> +- clocks : Must contain a single entry describing the clock input
> +
> +Example:
> +
> +timer {
> +	compatible = "ezchip,nps400-timer1";
> +	clocks = <&sysclk>;
> +};
> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> index 6156e54..0757328 100644
> --- a/drivers/clocksource/timer-nps.c
> +++ b/drivers/clocksource/timer-nps.c
> @@ -46,7 +46,7 @@
>  /* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
>  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
>  
> -static unsigned long nps_timer_rate;
> +static unsigned long nps_timer1_freq;

Why declare a global static variable for a local use in nps_setup_clocksource ? 

>  static int nps_get_timer_clk(struct device_node *node,
>  			     unsigned long *timer_freq,
>  			     struct clk *clk)
> @@ -87,10 +87,10 @@ static int __init nps_setup_clocksource(struct device_node *node)
>  			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
>  				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
>  
> -	nps_get_timer_clk(node, &nps_timer_rate, clk);
> +	nps_get_timer_clk(node, &nps_timer1_freq, clk);
>  
> -	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
> -				    nps_timer_rate, 301, 32, nps_clksrc_read);
> +	ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
> +				    nps_timer1_freq, 301, 32, nps_clksrc_read);
>  	if (ret) {
>  		pr_err("Couldn't register clock source.\n");
>  		clk_disable_unprepare(clk);
> @@ -99,5 +99,215 @@ static int __init nps_setup_clocksource(struct device_node *node)
>  	return ret;
>  }
>  
> -CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
> +CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer1",
>  		       nps_setup_clocksource);
> +
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#include <soc/nps/mtm.h>
> +
> +/* Timer related Aux registers */
> +#define AUX_REG_TIMER0_TSI	0xFFFFF850	/* timer 0 HW threads mask */
> +#define NPS_REG_TIMER0_LIMIT	0x23		/* timer 0 limit */
> +#define NPS_REG_TIMER0_CTRL	0x22		/* timer 0 control */
> +#define NPS_REG_TIMER0_CNT	0x21		/* timer 0 count */
> +
> +#define TIMER0_CTRL_IE	(1 << 0) /* Interrupt when Count reaches limit */
> +#define TIMER0_CTRL_NH	(1 << 1) /* Count only when CPU NOT halted */

Please, use BIT(nr) macro.

Can you elaborate "Count only when CPU NOT halted" ?

> +static unsigned long nps_timer0_freq;
> +static unsigned long nps_timer0_irq;
> +
> +/*
> + * Arm the timer to interrupt after @cycles
> + */
> +static void nps_clkevent_timer_event_setup(unsigned int cycles)
> +{
> +	write_aux_reg(NPS_REG_TIMER0_LIMIT, cycles);
> +	write_aux_reg(NPS_REG_TIMER0_CNT, 0);   /* start from 0 */
> +
> +	write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_IE | TIMER0_CTRL_NH);
> +}
> +
> +static void nps_clkevent_rm_thread(bool remove_thread)
> +{
> +	unsigned int cflags;
> +	unsigned int enabled_threads;
> +	unsigned long flags;
> +	int thread;
> +
> +	local_irq_save(flags);
> +	hw_schd_save(&cflags);

Can you explain why those two lines are needed ?

> +	enabled_threads = read_aux_reg(AUX_REG_TIMER0_TSI);
> +
> +	/* remove thread from TSI1 */
> +	if (remove_thread) {
> +		thread = read_aux_reg(CTOP_AUX_THREAD_ID);
> +		enabled_threads &= ~(1 << thread);
> +		write_aux_reg(AUX_REG_TIMER0_TSI, enabled_threads);
> +	}
> +
> +	/* Re-arm the timer if needed */
> +	if (!enabled_threads)
> +		write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH);
> +	else
> +		write_aux_reg(NPS_REG_TIMER0_CTRL,
> +			      TIMER0_CTRL_IE | TIMER0_CTRL_NH);
> +
> +	hw_schd_restore(cflags);
> +	local_irq_restore(flags);
> +}
> +
> +static void nps_clkevent_add_thread(bool set_event)
> +{
> +	int thread;
> +	unsigned int cflags, enabled_threads;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
> +	hw_schd_save(&cflags);
> +
> +	/* add thread to TSI1 */
> +	thread = read_aux_reg(CTOP_AUX_THREAD_ID);
> +	enabled_threads = read_aux_reg(AUX_REG_TIMER0_TSI);
> +	enabled_threads |= (1 << thread);
> +	write_aux_reg(AUX_REG_TIMER0_TSI, enabled_threads);
> +
> +	/* set next timer event */
> +	if (set_event)
> +		write_aux_reg(NPS_REG_TIMER0_CTRL,
> +			      TIMER0_CTRL_IE | TIMER0_CTRL_NH);
> +
> +	hw_schd_restore(cflags);
> +	local_irq_restore(flags);
> +}
> +
> +static int nps_clkevent_set_next_event(unsigned long delta,
> +				       struct clock_event_device *dev)
> +{
> +	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
> +	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
> +
> +	nps_clkevent_add_thread(true);
> +	chip->irq_unmask(&desc->irq_data);

Can you explain why invoking low level IRQ callbacks is needed here ?

> +	return 0;
> +}
> +
> +/*
> + * Whenever anyone tries to change modes, we just mask interrupts
> + * and wait for the next event to get set.
> + */
> +static int nps_clkevent_timer_shutdown(struct clock_event_device *dev)
> +{
> +	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
> +	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
> +
> +	chip->irq_mask(&desc->irq_data);
> +
> +	return 0;
> +}
> +
> +static int nps_clkevent_set_periodic(struct clock_event_device *dev)
> +{
> +	nps_clkevent_add_thread(false);
> +	if (read_aux_reg(CTOP_AUX_THREAD_ID) == 0)
> +		nps_clkevent_timer_event_setup(nps_timer0_freq / HZ);

Please explain this. I read only CPU0 can set the periodic timer.

> +	return 0;
> +}
> +
> +static int nps_clkevent_set_oneshot(struct clock_event_device *dev)
> +{
> +	nps_clkevent_rm_thread(true);
> +	nps_clkevent_timer_shutdown(dev);
> +
> +	return 0;
> +}
> +
> +static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
> +	.name				=	"NPS Timer0",
> +	.features			=	CLOCK_EVT_FEAT_ONESHOT |
> +						CLOCK_EVT_FEAT_PERIODIC,
> +	.rating				=	300,
> +	.set_next_event			=	nps_clkevent_set_next_event,
> +	.set_state_periodic		=	nps_clkevent_set_periodic,
> +	.set_state_oneshot		=	nps_clkevent_set_oneshot,
> +	.set_state_oneshot_stopped	=	nps_clkevent_timer_shutdown,
> +	.set_state_shutdown		=	nps_clkevent_timer_shutdown,
> +	.tick_resume			=	nps_clkevent_timer_shutdown,
> +};
> +
> +static irqreturn_t timer_irq_handler(int irq, void *dev_id)
> +{
> +	/*
> +	 * Note that generic IRQ core could have passed @evt for @dev_id if
> +	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
> +	 */
> +	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
> +	int irq_reenable = clockevent_state_periodic(evt);
> +
> +	nps_clkevent_rm_thread(!irq_reenable);
> +
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int nps_timer_starting_cpu(unsigned int cpu)
> +{
> +	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
> +
> +	evt->cpumask = cpumask_of(smp_processor_id());
> +
> +	clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX);
> +	enable_percpu_irq(nps_timer0_irq, 0);
> +
> +	return 0;
> +}
> +
> +static int nps_timer_dying_cpu(unsigned int cpu)
> +{
> +	disable_percpu_irq(nps_timer0_irq);
> +	return 0;
> +}
> +
> +static int __init nps_setup_clockevent(struct device_node *node)
> +{
> +	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
> +	struct clk *clk;

clk = 0xDEADBEEF

> +	int ret;
> +
> +	nps_timer0_irq = irq_of_parse_and_map(node, 0);
> +	if (nps_timer0_irq <= 0) {
> +		pr_err("clockevent: missing irq");
> +		return -EINVAL;
> +	}
> +
> +	nps_get_timer_clk(node, &nps_timer0_freq, clk);
> +
> +	/* Needs apriori irq_set_percpu_devid() done in intc map function */
> +	ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
> +				 "Timer0 (per-cpu-tick)", evt);
> +	if (ret) {
> +		pr_err("Couldn't request irq\n");
> +		clk_disable_unprepare(clk);

clk is on the stack, hence returning back from the function, clk is undefined.

clk_disable_unprepare(0xDEADBEEF) ==> kernel panic

It does not make sense to add the nps_get_timer_clk() function.

Better to have a couple of duplicated lines and properly rollback
from the right place instead of rollbacking supposed actions taken
from inside a function.

> +		return ret;
> +	}
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_NPS_TIMER_STARTING,
> +				"AP_NPS_TIMER_STARTING",
> +				nps_timer_starting_cpu,
> +				nps_timer_dying_cpu);
> +	if (ret) {
> +		pr_err("Failed to setup hotplug state");
> +		clk_disable_unprepare(clk);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clkevt, "ezchip,nps400-timer0",
> +		       nps_setup_clockevent);
> +#endif /* CONFIG_EZNPS_MTM_EXT */
> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index 34bd805..9efc1a3 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -60,6 +60,7 @@ enum cpuhp_state {
>  	CPUHP_AP_MARCO_TIMER_STARTING,
>  	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
>  	CPUHP_AP_ARC_TIMER_STARTING,
> +	CPUHP_AP_NPS_TIMER_STARTING,

Oops, wait. Here, arch/arc/kernel/time.c should be moved in
drivers/clocksource and consolidated with this driver.

Very likely, CPUHP_AP_ARC_TIMER_STARTING can be used for all ARC
timers.

>  	CPUHP_AP_KVM_STARTING,
>  	CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
>  	CPUHP_AP_KVM_ARM_VGIC_STARTING,
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* RE: [PATCH v2 1/3] soc: Support for NPS HW scheduling
  2016-10-31 10:26     ` Daniel Lezcano
  (?)
@ 2016-10-31 12:26     ` Noam Camus
  -1 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-31 12:26 UTC (permalink / raw)
  To: Daniel Lezcano; +Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel

> From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
> Sent: Monday, October 31, 2016 12:27 PM
>> 
>> This new header file is for NPS400 SoC (part of ARC architecture).
>> The header file includes macros for save/restore of HW scheduling.
>> The control of HW scheduling is acheived by writing core registers.

>s/acheived/achieved/
Thanks will update in V4 of this patch set
...

>> +#ifndef SOC_NPS_MTM_H
>> +#define SOC_NPS_MTM_H
>> +
>> +#define CTOP_INST_HWSCHD_OFF_R3                 0x3B6F00BF
>> +#define CTOP_INST_HWSCHD_RESTORE_R3             0x3E6F70C3
>> +
>> +static inline void hw_schd_save(unsigned int *flags) {
>> +	__asm__ __volatile__(
>> +	"       .word %1\n"
>> +	"       st r3,[%0]\n"
>> +	:
>> +	: "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
>> +	: "r3", "memory");
>> +}
>> +

>Wouldn't make sense to change the macro name to CTOP_INST_HWSCHD_SAVE_R3 ?
The save of state into register (R3) by this dedicated instruction is only part of action which main purpose
Is to turn off the HW scheduler within this core (we call CTOP).
We use it  (Off/On) at places we wish to keep consistency of data where more than one HW thread can access.
So I believe this way macro name reflects properly the functionality of this instruction and the API functions
schd_save()/schd_restore() provide similar format like with IRQs.

> +static inline void hw_schd_restore(unsigned int flags) {
> +	__asm__ __volatile__(
> +	"       mov r3, %0\n"
> +	"       .word %1\n"
> +	:
> +	: "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
> +	: "r3");
> +}
> +
> +#endif /* SOC_NPS_MTM_H */
> --
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* RE: [PATCH v2 2/3] clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
  2016-10-31 10:28     ` Daniel Lezcano
  (?)
@ 2016-10-31 15:19     ` Noam Camus
  -1 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-31 15:19 UTC (permalink / raw)
  To: Daniel Lezcano; +Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel

> From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
> Sent: Monday, October 31, 2016 12:28 PM

>> From: Noam Camus <noamca@mellanox.com>
>> 
>> nps_setup_clocksource() should take node as only argument i.e.:
>> replace
>> int __init nps_setup_clocksource(struct device_node *node, struct clk 
>> *clk) with int __init nps_setup_clocksource(struct device_node *node)
>> 
>> This is also serve as preperation for next patch which adds support
>
>s/preperation/preparation/
Thanks, will fix in V4 of this patch set
...

>> +static int nps_get_timer_clk(struct device_node *node,
>> +			     unsigned long *timer_freq,
>> +			     struct clk *clk)
>
>This function prototype does not make sense. A pointer to a clock is passed for nothing here.
Thanks, I passed *clk in order for one to do rollback on error (pass clk to clk_disable_unprepare).
I will change prototype to **clk.

>> +{
>> +	int ret;
>> +
>> +	clk = of_clk_get(node, 0);
>> +	if (IS_ERR(clk)) {
>> +		pr_err("timer missing clk");
>> +		return PTR_ERR(clk);
>> +	}
>> +
>> +	ret = clk_prepare_enable(clk);
>> +	if (ret) {
>> +		pr_err("Couldn't enable parent clk\n");
>> +		return ret;
>> +	}
>> +
>> +	*timer_freq = clk_get_rate(clk);
>> +
>
>	timer_freq check.
>
>	rollback on error.
Thanks, will fix at V4

...
>> -	if (ret) {
>> -		pr_err("Couldn't enable parent clock\n");
>> -		return ret;
>> -	}
>> -
>> -	nps_timer_rate = clk_get_rate(clk);
>> +	nps_get_timer_clk(node, &nps_timer_rate, clk);

>Return code check ?
Thanks, will fix at V4
  
-Noam

^ permalink raw reply	[flat|nested] 95+ messages in thread

* RE: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-10-31 10:52   ` Daniel Lezcano
@ 2016-10-31 17:03     ` Noam Camus
  2016-10-31 17:51       ` Vineet Gupta
  2016-11-01 20:01         ` Daniel Lezcano
  0 siblings, 2 replies; 95+ messages in thread
From: Noam Camus @ 2016-10-31 17:03 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel, Vineet Gupta

>From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
>Sent: Monday, October 31, 2016 12:53 PM

>> 
>> The design idea is that for each core there is dedicated regirtser

>s/regirtser/register/

>Hey ! re-read yourself.
Thanks, I do but sometimes reading over and over and still left with such typos
Will Fix on next patch Set V4

>> (TSI) serving all 16 HW threads.
>> The register is a bitmask with one bit for each HW thread.
>> When HW thread wants that next expiration of timer interrupt will hit 
>> it then the proper bit should be set in this dedicated register.

>I'm not sure to understand this sentence. Do you mean each cpu/thread must set a flag in the TSI register at BIT(phys_id) when they set a timer ?
Correct, each thread needs to set its bit in TSI register, otherwise the he won't be interrupted by timer.

>> When timer expires all HW threads within this core which their bit is 
>> set at the TSI register will be interrupted.

>Does it mean some HW threads will be wake up for nothing ?
See below after the example you gave

>eg. 

>HWT1 sets the timer to expire within 2 seconds
>HWT2 sets the timer to expire within 2 hours

>When the first timer expires, that will wake up HWT1 *and* HWT2 ?

You are correct, indeed not optimal but much simpler than managing book keeping of all 16 threads.
Functionality wise one who registered this timer will notice that it expired too soon and will register a new one.
This is how it works now in our machines.

>The code is a bit confusing because of the very specific design of this timer.

>Below more questions for clarification.

...
>> diff --git a/drivers/clocksource/timer-nps.c 
>> b/drivers/clocksource/timer-nps.c index 6156e54..0757328 100644
>> --- a/drivers/clocksource/timer-nps.c
>> +++ b/drivers/clocksource/timer-nps.c
>> @@ -46,7 +46,7 @@
>>  /* This array is per cluster of CPUs (Each NPS400 cluster got 256 
>> CPUs) */  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] 
>> __read_mostly;
>>  
>> -static unsigned long nps_timer_rate;
>> +static unsigned long nps_timer1_freq;
>
>Why declare a global static variable for a local use in nps_setup_clocksource ? 
Indeed no need. It will be fixed at V4

...
>> +/* Timer related Aux registers */
>> +#define AUX_REG_TIMER0_TSI	0xFFFFF850	/* timer 0 HW threads mask */
>> +#define NPS_REG_TIMER0_LIMIT	0x23		/* timer 0 limit */
>> +#define NPS_REG_TIMER0_CTRL	0x22		/* timer 0 control */
>> +#define NPS_REG_TIMER0_CNT	0x21		/* timer 0 count */
>> +
>> +#define TIMER0_CTRL_IE	(1 << 0) /* Interrupt when Count reaches limit */
>> +#define TIMER0_CTRL_NH	(1 << 1) /* Count only when CPU NOT halted */

>Please, use BIT(nr) macro.
Will fix that on V4.

>Can you elaborate "Count only when CPU NOT halted" ?
The Idea here is:
The Not Halted mode flag (NH) causes cycles to be counted only when the processor is running (not halted). When set to 0 the timer will count every clock cycle. When set to 1 the timer will only count when the processor is running. The NH flag is set to 0 when the processor is Reset.
It may be used when working with JTAG (I never used it this way though).

>> +static unsigned long nps_timer0_freq; static unsigned long 
>> +nps_timer0_irq;
>> +
>> +/*
>> + * Arm the timer to interrupt after @cycles  */ static void 
>> +nps_clkevent_timer_event_setup(unsigned int cycles) {
>> +	write_aux_reg(NPS_REG_TIMER0_LIMIT, cycles);
>> +	write_aux_reg(NPS_REG_TIMER0_CNT, 0);   /* start from 0 */
>> +
>> +	write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_IE | TIMER0_CTRL_NH); 
>> +}
>> +
>> +static void nps_clkevent_rm_thread(bool remove_thread) {
>> +	unsigned int cflags;
>> +	unsigned int enabled_threads;
>> +	unsigned long flags;
>> +	int thread;
>> +
>> +	local_irq_save(flags);
>> +	hw_schd_save(&cflags);
>
>Can you explain why those two lines are needed ?
The idea is that access to shared core registers (among threads) is not done in parallel to keep their consistency.
For example Read Modified Write of TSI register is not atomic, so using two lines above avoid any interference during
this code execution.

...
>> +
>> +static int nps_clkevent_set_next_event(unsigned long delta,
>> +				       struct clock_event_device *dev) {
>> +	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
>> +	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
>> +
>> +	nps_clkevent_add_thread(true);
>> +	chip->irq_unmask(&desc->irq_data);

>Can you explain why invoking low level IRQ callbacks is needed here ?
I needed those callbacks functionality and didn't want to duplicate it here.

...
>> +
>> +static int nps_clkevent_set_periodic(struct clock_event_device *dev) 
>> +{
>> +	nps_clkevent_add_thread(false);
>> +	if (read_aux_reg(CTOP_AUX_THREAD_ID) == 0)
>> +		nps_clkevent_timer_event_setup(nps_timer0_freq / HZ);

>Please explain this. I read only CPU0 can set the periodic timer.
When system works in periodic mode for clock events we just need to set for all HW threads within same core their respective bit at TSI register. 
We also need but only once to arm the shared timer control register.
Since that for each core thread 0 is always available we choose HW thread 0 to do that.
...
>> +
>> +static int __init nps_setup_clockevent(struct device_node *node) {
>> +	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
>> +	struct clk *clk;

>clk = 0xDEADBEEF
>> +	int ret;
>> +
>> +	nps_timer0_irq = irq_of_parse_and_map(node, 0);
>> +	if (nps_timer0_irq <= 0) {
>> +		pr_err("clockevent: missing irq");
>> +		return -EINVAL;
>> +	}
>> +
>> +	nps_get_timer_clk(node, &nps_timer0_freq, clk);
>> +
>> +	/* Needs apriori irq_set_percpu_devid() done in intc map function */
>> +	ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
>> +				 "Timer0 (per-cpu-tick)", evt);
>> +	if (ret) {
>> +		pr_err("Couldn't request irq\n");
>> +		clk_disable_unprepare(clk);

>clk is on the stack, hence returning back from the function, clk is undefined.

>clk_disable_unprepare(0xDEADBEEF) ==> kernel panic

>It does not make sense to add the nps_get_timer_clk() function.

>Better to have a couple of duplicated lines and properly rollback from the right place instead of rollbacking supposed actions taken from inside a function.
As I wrote above I will use **clk for the rollback, so nps_get_timer_clk() will make sense and avoid code duplication.

>> +		return ret;
>> +	}
>> +
>> +	ret = cpuhp_setup_state(CPUHP_AP_NPS_TIMER_STARTING,
>> +				"AP_NPS_TIMER_STARTING",
>> +				nps_timer_starting_cpu,
>> +				nps_timer_dying_cpu);
>> +	if (ret) {
>> +		pr_err("Failed to setup hotplug state");
>> +		clk_disable_unprepare(clk);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clkevt, "ezchip,nps400-timer0",
>> +		       nps_setup_clockevent);
>> +#endif /* CONFIG_EZNPS_MTM_EXT */
>> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h 
>> index 34bd805..9efc1a3 100644
>> --- a/include/linux/cpuhotplug.h
>> +++ b/include/linux/cpuhotplug.h
>> @@ -60,6 +60,7 @@ enum cpuhp_state {
>> 	CPUHP_AP_MARCO_TIMER_STARTING,
>>  	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
>>  	CPUHP_AP_ARC_TIMER_STARTING,
>> +	CPUHP_AP_NPS_TIMER_STARTING,

>Oops, wait. Here, arch/arc/kernel/time.c should be moved in drivers/clocksource and consolidated with this driver.

>Very likely, CPUHP_AP_ARC_TIMER_STARTING can be used for all ARC timers.

Indeed the ARC timer driver served as my inspiration but due to HW threads handling they are not the same.
Moving drivers from arch/arc to driver/clocksource is not my call (Vineet Gupta is the maintainer of ARC)
And I think they quiet differ now so consolidation gain is not obvious.

-Noam 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-10-31 17:03     ` Noam Camus
@ 2016-10-31 17:51       ` Vineet Gupta
  2016-10-31 22:48           ` Vineet Gupta
  2016-11-01 20:01         ` Daniel Lezcano
  1 sibling, 1 reply; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 17:51 UTC (permalink / raw)
  To: Noam Camus, Daniel Lezcano
  Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel

Hi Daniel,

On 10/31/2016 10:03 AM, Noam Camus wrote:
>> Oops, wait. Here, arch/arc/kernel/time.c should be moved in drivers/clocksource and consolidated with this driver.
>> >Very likely, CPUHP_AP_ARC_TIMER_STARTING can be used for all ARC timers.
> Indeed the ARC timer driver served as my inspiration but due to HW threads handling they are not the same.
> Moving drivers from arch/arc to driver/clocksource is not my call (Vineet Gupta is the maintainer of ARC)
> And I think they quiet differ now so consolidation gain is not obvious.

Sorry this was on my todo list at low priority. Anyways took a quick look at it now.

The problem is timer code overlaps pure driver land and ARC specific code. e.g.
CONFIG_ARC_HAS_RTC clocksource needs to check whether hardware exists or not. We
currently conveniently check that from cpuinfo populated at boot time. Now either
I need to export that info as a function (which should be done anyways) - but then
define stub for !ARC. Either that or duplicate the detection code here (orig copy
in arc setup.c)

So doing this exercise cleanly would mean exporting much of
arch/arc/include/asm/{arcregs.h, mcip.h} out of ARC into include/soc/arc/*. Isn't
this kind of going back to include/asm-<arch>/* days ?

Honestly I do want to move the driver in the right place but not sure how to do
this cleanly.

Thoughts ?

-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 0/9] Move ARC timer code into drivers/clocksource/
  2016-10-31 17:51       ` Vineet Gupta
@ 2016-10-31 22:48           ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Hi,

This series addresses the long pending move of ARC timer code into
drivers/clocksource/.

- patches [1-4]/9 are improvements to arc code, paving way for later code motion.
- patches [5-8]/9 refactor the arc headers to be shared between arc and drivers
- patch 9/9 moves out the driver code/build/Kconfig bits

As review progresses/concludes, I'd like to merge [1-8] for this merge window and
clocksource maintainers can pick up the actual switch for 4.10 or even 4.9 as they
prefer.

Thx,
-Vineet

 MAINTAINERS                                        |  1 +
 arch/arc/Kconfig                                   | 12 +--
 arch/arc/configs/nsimosci_hs_smp_defconfig         |  2 +-
 arch/arc/configs/vdk_hs38_smp_defconfig            |  2 +-
 arch/arc/include/asm/arcregs.h                     | 94 +---------------------
 arch/arc/kernel/Makefile                           |  2 +-
 arch/arc/kernel/mcip.c                             |  2 +-
 arch/arc/kernel/setup.c                            | 17 +++-
 arch/arc/plat-axs10x/axs10x.c                      |  2 +-
 drivers/clocksource/Kconfig                        | 24 ++++++
 drivers/clocksource/Makefile                       |  1 +
 .../time.c => drivers/clocksource/arc_timer.c      | 69 +++++-----------
 include/soc/arc/aux.h                              | 52 ++++++++++++
 {arch/arc/include/asm => include/soc/arc}/mcip.h   | 10 +--
 include/soc/arc/timers.h                           | 24 ++++++
 include/soc/nps/common.h                           |  4 +-
 16 files changed, 151 insertions(+), 167 deletions(-)
 rename arch/arc/kernel/time.c => drivers/clocksource/arc_timer.c (83%)
 create mode 100644 include/soc/arc/aux.h
 rename {arch/arc/include/asm => include/soc/arc}/mcip.h (95%)
 create mode 100644 include/soc/arc/timers.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 0/9] Move ARC timer code into drivers/clocksource/
@ 2016-10-31 22:48           ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Hi,

This series addresses the long pending move of ARC timer code into
drivers/clocksource/.

- patches [1-4]/9 are improvements to arc code, paving way for later code motion.
- patches [5-8]/9 refactor the arc headers to be shared between arc and drivers
- patch 9/9 moves out the driver code/build/Kconfig bits

As review progresses/concludes, I'd like to merge [1-8] for this merge window and
clocksource maintainers can pick up the actual switch for 4.10 or even 4.9 as they
prefer.

Thx,
-Vineet

 MAINTAINERS                                        |  1 +
 arch/arc/Kconfig                                   | 12 +--
 arch/arc/configs/nsimosci_hs_smp_defconfig         |  2 +-
 arch/arc/configs/vdk_hs38_smp_defconfig            |  2 +-
 arch/arc/include/asm/arcregs.h                     | 94 +---------------------
 arch/arc/kernel/Makefile                           |  2 +-
 arch/arc/kernel/mcip.c                             |  2 +-
 arch/arc/kernel/setup.c                            | 17 +++-
 arch/arc/plat-axs10x/axs10x.c                      |  2 +-
 drivers/clocksource/Kconfig                        | 24 ++++++
 drivers/clocksource/Makefile                       |  1 +
 .../time.c => drivers/clocksource/arc_timer.c      | 69 +++++-----------
 include/soc/arc/aux.h                              | 52 ++++++++++++
 {arch/arc/include/asm => include/soc/arc}/mcip.h   | 10 +--
 include/soc/arc/timers.h                           | 24 ++++++
 include/soc/nps/common.h                           |  4 +-
 16 files changed, 151 insertions(+), 167 deletions(-)
 rename arch/arc/kernel/time.c => drivers/clocksource/arc_timer.c (83%)
 create mode 100644 include/soc/arc/aux.h
 rename {arch/arc/include/asm => include/soc/arc}/mcip.h (95%)
 create mode 100644 include/soc/arc/timers.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

... don't rely on cpuinfo populated in arc boot code. This paves wat for
moving this code in drivers/clocksource/

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/time.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index f927b8dc6edd..a2db010cde18 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -118,10 +118,11 @@ static struct clocksource arc_counter_gfrc = {
 
 static int __init arc_cs_setup_gfrc(struct device_node *node)
 {
-	int exists = cpuinfo_arc700[0].extn.gfrc;
+	struct mcip_bcr mp;
 	int ret;
 
-	if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
+	READ_BCR(ARC_REG_MCIP_BCR, mp);
+	if (WARN(!mp.gfrc, "Global-64-bit-Ctr clocksource not detected"))
 		return -ENXIO;
 
 	ret = arc_get_timer_clk(node);
@@ -174,10 +175,11 @@ static struct clocksource arc_counter_rtc = {
 
 static int __init arc_cs_setup_rtc(struct device_node *node)
 {
-	int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
+	struct bcr_timer timer;
 	int ret;
 
-	if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
+	READ_BCR(ARC_REG_TIMERS_BCR, timer);
+	if (WARN(!timer.rtc, "Local-64-bit-Ctr clocksource not detected"))
 		return -ENXIO;
 
 	/* Local to CPU hence not usable in SMP */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

... don't rely on cpuinfo populated in arc boot code. This paves wat for
moving this code in drivers/clocksource/

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/time.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index f927b8dc6edd..a2db010cde18 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -118,10 +118,11 @@ static struct clocksource arc_counter_gfrc = {
 
 static int __init arc_cs_setup_gfrc(struct device_node *node)
 {
-	int exists = cpuinfo_arc700[0].extn.gfrc;
+	struct mcip_bcr mp;
 	int ret;
 
-	if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
+	READ_BCR(ARC_REG_MCIP_BCR, mp);
+	if (WARN(!mp.gfrc, "Global-64-bit-Ctr clocksource not detected"))
 		return -ENXIO;
 
 	ret = arc_get_timer_clk(node);
@@ -174,10 +175,11 @@ static struct clocksource arc_counter_rtc = {
 
 static int __init arc_cs_setup_rtc(struct device_node *node)
 {
-	int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
+	struct bcr_timer timer;
 	int ret;
 
-	if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
+	READ_BCR(ARC_REG_TIMERS_BCR, timer);
+	if (WARN(!timer.rtc, "Local-64-bit-Ctr clocksource not detected"))
 		return -ENXIO;
 
 	/* Local to CPU hence not usable in SMP */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

To allow for easy movement into drivers/clocksource

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/time.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index a2db010cde18..2c51e3cafad0 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -153,14 +153,11 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
 		cycle_t  full;
 	} stamp;
 
-
-	__asm__ __volatile(
-	"1:						\n"
-	"	lr		%0, [AUX_RTC_LOW]	\n"
-	"	lr		%1, [AUX_RTC_HIGH]	\n"
-	"	lr		%2, [AUX_RTC_CTRL]	\n"
-	"	bbit0.nt	%2, 31, 1b		\n"
-	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
+	do {
+		stamp.low = read_aux_reg(AUX_RTC_LOW);
+		stamp.high = read_aux_reg(AUX_RTC_HIGH);
+		status = read_aux_reg(AUX_RTC_CTRL);
+	} while (!(status & 0x80000000UL));
 
 	return stamp.full;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

To allow for easy movement into drivers/clocksource

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/time.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index a2db010cde18..2c51e3cafad0 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -153,14 +153,11 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
 		cycle_t  full;
 	} stamp;
 
-
-	__asm__ __volatile(
-	"1:						\n"
-	"	lr		%0, [AUX_RTC_LOW]	\n"
-	"	lr		%1, [AUX_RTC_HIGH]	\n"
-	"	lr		%2, [AUX_RTC_CTRL]	\n"
-	"	bbit0.nt	%2, 31, 1b		\n"
-	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
+	do {
+		stamp.low = read_aux_reg(AUX_RTC_LOW);
+		stamp.high = read_aux_reg(AUX_RTC_HIGH);
+		status = read_aux_reg(AUX_RTC_CTRL);
+	} while (!(status & 0x80000000UL));
 
 	return stamp.full;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/setup.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 0385df77a697..595d06900061 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -234,11 +234,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
 		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
 
-	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
+	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
 		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
 		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
-		       IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
-				 CONFIG_ARC_HAS_RTC));
+		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
+		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
 
 	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
 			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/setup.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 0385df77a697..595d06900061 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -234,11 +234,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
 		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
 
-	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
+	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
 		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
 		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
-		       IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
-				 CONFIG_ARC_HAS_RTC));
+		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
+		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
 
 	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
 			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 4/9] ARC: time: move time_init() out of the driver
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/setup.c | 11 +++++++++++
 arch/arc/kernel/time.c  |  9 ---------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 595d06900061..5865bd34a7fa 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -10,6 +10,8 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/root_dev.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/cpu.h>
@@ -449,6 +451,15 @@ void __init setup_arch(char **cmdline_p)
 	arc_unwind_init();
 }
 
+/*
+ * Called from start_kernel() - boot CPU only
+ */
+void __init time_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_probe();
+}
+
 static int __init customize_machine(void)
 {
 	if (machine_desc->init_machine)
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 2c51e3cafad0..00ece39a8ae7 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -367,12 +367,3 @@ static int __init arc_of_timer_init(struct device_node *np)
 	return ret;
 }
 CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);
-
-/*
- * Called from start_kernel() - boot CPU only
- */
-void __init time_init(void)
-{
-	of_clk_init(NULL);
-	clocksource_probe();
-}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 4/9] ARC: time: move time_init() out of the driver
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/setup.c | 11 +++++++++++
 arch/arc/kernel/time.c  |  9 ---------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 595d06900061..5865bd34a7fa 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -10,6 +10,8 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/root_dev.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/cpu.h>
@@ -449,6 +451,15 @@ void __init setup_arch(char **cmdline_p)
 	arc_unwind_init();
 }
 
+/*
+ * Called from start_kernel() - boot CPU only
+ */
+void __init time_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_probe();
+}
+
 static int __init customize_machine(void)
 {
 	if (machine_desc->init_machine)
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 2c51e3cafad0..00ece39a8ae7 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -367,12 +367,3 @@ static int __init arc_of_timer_init(struct device_node *np)
 	return ret;
 }
 CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);
-
-/*
- * Called from start_kernel() - boot CPU only
- */
-void __init time_init(void)
-{
-	of_clk_init(NULL);
-	clocksource_probe();
-}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 5/9] ARC: breakout aux handling into a seperate header
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

ARC timers use aux registers for programming and this paves way for
moving ARC timer drivers into drivers/clocksource

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/arcregs.h | 85 +-----------------------------------------
 arch/arc/include/asm/mcip.h    |  2 +-
 include/soc/arc/aux.h          | 52 ++++++++++++++++++++++++++
 include/soc/nps/common.h       |  4 +-
 4 files changed, 56 insertions(+), 87 deletions(-)
 create mode 100644 include/soc/arc/aux.h

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 7f3f9f63708c..ccf5dc96713b 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -110,90 +110,7 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- ******************************************************************
- *      Inline ASM macros to read/write AUX Regs
- *      Essentially invocation of lr/sr insns from "C"
- */
-
-#if 1
-
-#define read_aux_reg(reg)	__builtin_arc_lr(reg)
-
-/* gcc builtin sr needs reg param to be long immediate */
-#define write_aux_reg(reg_immed, val)		\
-		__builtin_arc_sr((unsigned int)(val), reg_immed)
-
-#else
-
-#define read_aux_reg(reg)		\
-({					\
-	unsigned int __ret;		\
-	__asm__ __volatile__(		\
-	"	lr    %0, [%1]"		\
-	: "=r"(__ret)			\
-	: "i"(reg));			\
-	__ret;				\
-})
-
-/*
- * Aux Reg address is specified as long immediate by caller
- * e.g.
- *    write_aux_reg(0x69, some_val);
- * This generates tightest code.
- */
-#define write_aux_reg(reg_imm, val)	\
-({					\
-	__asm__ __volatile__(		\
-	"	sr   %0, [%1]	\n"	\
-	:				\
-	: "ir"(val), "i"(reg_imm));	\
-})
-
-/*
- * Aux Reg address is specified in a variable
- *  * e.g.
- *      reg_num = 0x69
- *      write_aux_reg2(reg_num, some_val);
- * This has to generate glue code to load the reg num from
- *  memory to a reg hence not recommended.
- */
-#define write_aux_reg2(reg_in_var, val)		\
-({						\
-	unsigned int tmp;			\
-						\
-	__asm__ __volatile__(			\
-	"	ld   %0, [%2]	\n\t"		\
-	"	sr   %1, [%0]	\n\t"		\
-	: "=&r"(tmp)				\
-	: "r"(val), "memory"(&reg_in_var));	\
-})
-
-#endif
-
-#define READ_BCR(reg, into)				\
-{							\
-	unsigned int tmp;				\
-	tmp = read_aux_reg(reg);			\
-	if (sizeof(tmp) == sizeof(into)) {		\
-		into = *((typeof(into) *)&tmp);		\
-	} else {					\
-		extern void bogus_undefined(void);	\
-		bogus_undefined();			\
-	}						\
-}
-
-#define WRITE_AUX(reg, into)				\
-{							\
-	unsigned int tmp;				\
-	if (sizeof(tmp) == sizeof(into)) {		\
-		tmp = (*(unsigned int *)&(into));	\
-		write_aux_reg(reg, tmp);		\
-	} else  {					\
-		extern void bogus_undefined(void);	\
-		bogus_undefined();			\
-	}						\
-}
+#include <soc/arc/aux.h>
 
 /* Helpers */
 #define TO_KB(bytes)		((bytes) >> 10)
diff --git a/arch/arc/include/asm/mcip.h b/arch/arc/include/asm/mcip.h
index c8fbe4114bad..fc28d0944801 100644
--- a/arch/arc/include/asm/mcip.h
+++ b/arch/arc/include/asm/mcip.h
@@ -13,7 +13,7 @@
 
 #ifdef CONFIG_ISA_ARCV2
 
-#include <asm/arcregs.h>
+#include <soc/arc/aux.h>
 
 #define ARC_REG_MCIP_BCR	0x0d0
 #define ARC_REG_MCIP_CMD	0x600
diff --git a/include/soc/arc/aux.h b/include/soc/arc/aux.h
new file mode 100644
index 000000000000..8c41c096a51b
--- /dev/null
+++ b/include/soc/arc/aux.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016-2017 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __SOC_ARC_AUX_H__
+#define __SOC_ARC_AUX_H__
+
+#ifdef CONFIG_ARC
+
+#define read_aux_reg(r)		__builtin_arc_lr(r)
+
+/* gcc builtin sr needs reg param to be long immediate */
+#define write_aux_reg(r, v)	__builtin_arc_sr((unsigned int)(v), r)
+
+#else
+
+#define read_aux_reg(r)		0
+#define write_aux_reg(r, v)
+
+#endif
+
+#define READ_BCR(reg, into)				\
+{							\
+	unsigned int tmp;				\
+	tmp = read_aux_reg(reg);			\
+	if (sizeof(tmp) == sizeof(into)) {		\
+		into = *((typeof(into) *)&tmp);		\
+	} else {					\
+		extern void bogus_undefined(void);	\
+		bogus_undefined();			\
+	}						\
+}
+
+#define WRITE_AUX(reg, into)				\
+{							\
+	unsigned int tmp;				\
+	if (sizeof(tmp) == sizeof(into)) {		\
+		tmp = (*(unsigned int *)&(into));	\
+		write_aux_reg(reg, tmp);		\
+	} else  {					\
+		extern void bogus_undefined(void);	\
+		bogus_undefined();			\
+	}						\
+}
+
+
+#endif
diff --git a/include/soc/nps/common.h b/include/soc/nps/common.h
index 9b1d43d671a3..b7ba05b3993f 100644
--- a/include/soc/nps/common.h
+++ b/include/soc/nps/common.h
@@ -47,6 +47,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <soc/arc/aux.h>
+
 /* In order to increase compilation test coverage */
 #ifdef CONFIG_ARC
 static inline void nps_ack_gic(void)
@@ -59,8 +61,6 @@ static inline void nps_ack_gic(void)
 }
 #else
 static inline void nps_ack_gic(void) { }
-#define write_aux_reg(r, v)
-#define read_aux_reg(r) 0
 #endif
 
 /* CPU global ID */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 5/9] ARC: breakout aux handling into a seperate header
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

ARC timers use aux registers for programming and this paves way for
moving ARC timer drivers into drivers/clocksource

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/arcregs.h | 85 +-----------------------------------------
 arch/arc/include/asm/mcip.h    |  2 +-
 include/soc/arc/aux.h          | 52 ++++++++++++++++++++++++++
 include/soc/nps/common.h       |  4 +-
 4 files changed, 56 insertions(+), 87 deletions(-)
 create mode 100644 include/soc/arc/aux.h

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 7f3f9f63708c..ccf5dc96713b 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -110,90 +110,7 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- ******************************************************************
- *      Inline ASM macros to read/write AUX Regs
- *      Essentially invocation of lr/sr insns from "C"
- */
-
-#if 1
-
-#define read_aux_reg(reg)	__builtin_arc_lr(reg)
-
-/* gcc builtin sr needs reg param to be long immediate */
-#define write_aux_reg(reg_immed, val)		\
-		__builtin_arc_sr((unsigned int)(val), reg_immed)
-
-#else
-
-#define read_aux_reg(reg)		\
-({					\
-	unsigned int __ret;		\
-	__asm__ __volatile__(		\
-	"	lr    %0, [%1]"		\
-	: "=r"(__ret)			\
-	: "i"(reg));			\
-	__ret;				\
-})
-
-/*
- * Aux Reg address is specified as long immediate by caller
- * e.g.
- *    write_aux_reg(0x69, some_val);
- * This generates tightest code.
- */
-#define write_aux_reg(reg_imm, val)	\
-({					\
-	__asm__ __volatile__(		\
-	"	sr   %0, [%1]	\n"	\
-	:				\
-	: "ir"(val), "i"(reg_imm));	\
-})
-
-/*
- * Aux Reg address is specified in a variable
- *  * e.g.
- *      reg_num = 0x69
- *      write_aux_reg2(reg_num, some_val);
- * This has to generate glue code to load the reg num from
- *  memory to a reg hence not recommended.
- */
-#define write_aux_reg2(reg_in_var, val)		\
-({						\
-	unsigned int tmp;			\
-						\
-	__asm__ __volatile__(			\
-	"	ld   %0, [%2]	\n\t"		\
-	"	sr   %1, [%0]	\n\t"		\
-	: "=&r"(tmp)				\
-	: "r"(val), "memory"(&reg_in_var));	\
-})
-
-#endif
-
-#define READ_BCR(reg, into)				\
-{							\
-	unsigned int tmp;				\
-	tmp = read_aux_reg(reg);			\
-	if (sizeof(tmp) == sizeof(into)) {		\
-		into = *((typeof(into) *)&tmp);		\
-	} else {					\
-		extern void bogus_undefined(void);	\
-		bogus_undefined();			\
-	}						\
-}
-
-#define WRITE_AUX(reg, into)				\
-{							\
-	unsigned int tmp;				\
-	if (sizeof(tmp) == sizeof(into)) {		\
-		tmp = (*(unsigned int *)&(into));	\
-		write_aux_reg(reg, tmp);		\
-	} else  {					\
-		extern void bogus_undefined(void);	\
-		bogus_undefined();			\
-	}						\
-}
+#include <soc/arc/aux.h>
 
 /* Helpers */
 #define TO_KB(bytes)		((bytes) >> 10)
diff --git a/arch/arc/include/asm/mcip.h b/arch/arc/include/asm/mcip.h
index c8fbe4114bad..fc28d0944801 100644
--- a/arch/arc/include/asm/mcip.h
+++ b/arch/arc/include/asm/mcip.h
@@ -13,7 +13,7 @@
 
 #ifdef CONFIG_ISA_ARCV2
 
-#include <asm/arcregs.h>
+#include <soc/arc/aux.h>
 
 #define ARC_REG_MCIP_BCR	0x0d0
 #define ARC_REG_MCIP_CMD	0x600
diff --git a/include/soc/arc/aux.h b/include/soc/arc/aux.h
new file mode 100644
index 000000000000..8c41c096a51b
--- /dev/null
+++ b/include/soc/arc/aux.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016-2017 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __SOC_ARC_AUX_H__
+#define __SOC_ARC_AUX_H__
+
+#ifdef CONFIG_ARC
+
+#define read_aux_reg(r)		__builtin_arc_lr(r)
+
+/* gcc builtin sr needs reg param to be long immediate */
+#define write_aux_reg(r, v)	__builtin_arc_sr((unsigned int)(v), r)
+
+#else
+
+#define read_aux_reg(r)		0
+#define write_aux_reg(r, v)
+
+#endif
+
+#define READ_BCR(reg, into)				\
+{							\
+	unsigned int tmp;				\
+	tmp = read_aux_reg(reg);			\
+	if (sizeof(tmp) == sizeof(into)) {		\
+		into = *((typeof(into) *)&tmp);		\
+	} else {					\
+		extern void bogus_undefined(void);	\
+		bogus_undefined();			\
+	}						\
+}
+
+#define WRITE_AUX(reg, into)				\
+{							\
+	unsigned int tmp;				\
+	if (sizeof(tmp) == sizeof(into)) {		\
+		tmp = (*(unsigned int *)&(into));	\
+		write_aux_reg(reg, tmp);		\
+	} else  {					\
+		extern void bogus_undefined(void);	\
+		bogus_undefined();			\
+	}						\
+}
+
+
+#endif
diff --git a/include/soc/nps/common.h b/include/soc/nps/common.h
index 9b1d43d671a3..b7ba05b3993f 100644
--- a/include/soc/nps/common.h
+++ b/include/soc/nps/common.h
@@ -47,6 +47,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <soc/arc/aux.h>
+
 /* In order to increase compilation test coverage */
 #ifdef CONFIG_ARC
 static inline void nps_ack_gic(void)
@@ -59,8 +61,6 @@ static inline void nps_ack_gic(void)
 }
 #else
 static inline void nps_ack_gic(void) { }
-#define write_aux_reg(r, v)
-#define read_aux_reg(r) 0
 #endif
 
 /* CPU global ID */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 6/9] ARC: move mcip.h into include/soc and adjust the includes
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Also remove the depedency on ARCv2, to increase compile coverage for
!ARCV2 builds

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/mcip.c                           | 2 +-
 arch/arc/kernel/time.c                           | 2 +-
 arch/arc/plat-axs10x/axs10x.c                    | 2 +-
 {arch/arc/include/asm => include/soc/arc}/mcip.h | 8 ++------
 4 files changed, 5 insertions(+), 9 deletions(-)
 rename {arch/arc/include/asm => include/soc/arc}/mcip.h (96%)

diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index c424d5abc318..0651e0a2e8b1 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -11,8 +11,8 @@
 #include <linux/smp.h>
 #include <linux/irq.h>
 #include <linux/spinlock.h>
+#include <soc/arc/mcip.h>
 #include <asm/irqflags-arcv2.h>
-#include <asm/mcip.h>
 #include <asm/setup.h>
 
 static DEFINE_RAW_SPINLOCK(mcip_lock);
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 00ece39a8ae7..f1ebe45bfcdf 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -40,7 +40,7 @@
 #include <asm/irq.h>
 #include <asm/arcregs.h>
 
-#include <asm/mcip.h>
+#include <soc/arc/mcip.h>
 
 /* Timer related Aux registers */
 #define ARC_REG_TIMER0_LIMIT	0x23	/* timer 0 limit */
diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
index 86548701023c..38ff349d7f2a 100644
--- a/arch/arc/plat-axs10x/axs10x.c
+++ b/arch/arc/plat-axs10x/axs10x.c
@@ -21,7 +21,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/io.h>
 #include <asm/mach_desc.h>
-#include <asm/mcip.h>
+#include <soc/arc/mcip.h>
 
 #define AXS_MB_CGU		0xE0010000
 #define AXS_MB_CREG		0xE0011000
diff --git a/arch/arc/include/asm/mcip.h b/include/soc/arc/mcip.h
similarity index 96%
rename from arch/arc/include/asm/mcip.h
rename to include/soc/arc/mcip.h
index fc28d0944801..6902c2a8bd23 100644
--- a/arch/arc/include/asm/mcip.h
+++ b/include/soc/arc/mcip.h
@@ -8,10 +8,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_MCIP_H
-#define __ASM_MCIP_H
-
-#ifdef CONFIG_ISA_ARCV2
+#ifndef __SOC_ARC_MCIP_H
+#define __SOC_ARC_MCIP_H
 
 #include <soc/arc/aux.h>
 
@@ -103,5 +101,3 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
 }
 
 #endif
-
-#endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 6/9] ARC: move mcip.h into include/soc and adjust the includes
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Also remove the depedency on ARCv2, to increase compile coverage for
!ARCV2 builds

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/mcip.c                           | 2 +-
 arch/arc/kernel/time.c                           | 2 +-
 arch/arc/plat-axs10x/axs10x.c                    | 2 +-
 {arch/arc/include/asm => include/soc/arc}/mcip.h | 8 ++------
 4 files changed, 5 insertions(+), 9 deletions(-)
 rename {arch/arc/include/asm => include/soc/arc}/mcip.h (96%)

diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index c424d5abc318..0651e0a2e8b1 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -11,8 +11,8 @@
 #include <linux/smp.h>
 #include <linux/irq.h>
 #include <linux/spinlock.h>
+#include <soc/arc/mcip.h>
 #include <asm/irqflags-arcv2.h>
-#include <asm/mcip.h>
 #include <asm/setup.h>
 
 static DEFINE_RAW_SPINLOCK(mcip_lock);
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 00ece39a8ae7..f1ebe45bfcdf 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -40,7 +40,7 @@
 #include <asm/irq.h>
 #include <asm/arcregs.h>
 
-#include <asm/mcip.h>
+#include <soc/arc/mcip.h>
 
 /* Timer related Aux registers */
 #define ARC_REG_TIMER0_LIMIT	0x23	/* timer 0 limit */
diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
index 86548701023c..38ff349d7f2a 100644
--- a/arch/arc/plat-axs10x/axs10x.c
+++ b/arch/arc/plat-axs10x/axs10x.c
@@ -21,7 +21,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/io.h>
 #include <asm/mach_desc.h>
-#include <asm/mcip.h>
+#include <soc/arc/mcip.h>
 
 #define AXS_MB_CGU		0xE0010000
 #define AXS_MB_CREG		0xE0011000
diff --git a/arch/arc/include/asm/mcip.h b/include/soc/arc/mcip.h
similarity index 96%
rename from arch/arc/include/asm/mcip.h
rename to include/soc/arc/mcip.h
index fc28d0944801..6902c2a8bd23 100644
--- a/arch/arc/include/asm/mcip.h
+++ b/include/soc/arc/mcip.h
@@ -8,10 +8,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_MCIP_H
-#define __ASM_MCIP_H
-
-#ifdef CONFIG_ISA_ARCV2
+#ifndef __SOC_ARC_MCIP_H
+#define __SOC_ARC_MCIP_H
 
 #include <soc/arc/aux.h>
 
@@ -103,5 +101,3 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
 }
 
 #endif
-
-#endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 7/9] ARC: breakout timer stuff into a seperate header
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/arcregs.h |  9 +--------
 arch/arc/kernel/time.c         |  2 +-
 include/soc/arc/timers.h       | 24 ++++++++++++++++++++++++
 3 files changed, 26 insertions(+), 9 deletions(-)
 create mode 100644 include/soc/arc/timers.h

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index ccf5dc96713b..a17aa4558832 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -20,7 +20,6 @@
 #define ARC_REG_FP_V2_BCR	0xc8	/* ARCv2 FPU */
 #define ARC_REG_SLC_BCR		0xce
 #define ARC_REG_DCCM_BUILD	0x74	/* DCCM size (common) */
-#define ARC_REG_TIMERS_BCR	0x75
 #define ARC_REG_AP_BCR		0x76
 #define ARC_REG_ICCM_BUILD	0x78	/* ICCM size (common) */
 #define ARC_REG_XY_MEM_BCR	0x79
@@ -206,13 +205,7 @@ struct bcr_fp_arcv2 {
 #endif
 };
 
-struct bcr_timer {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
-#else
-	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
-#endif
-};
+#include <soc/arc/timers.h>
 
 struct bcr_bpu_arcompact {
 #ifdef CONFIG_CPU_BIG_ENDIAN
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index f1ebe45bfcdf..dad3a9933c4c 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -38,8 +38,8 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <asm/irq.h>
-#include <asm/arcregs.h>
 
+#include <soc/arc/timers.h>
 #include <soc/arc/mcip.h>
 
 /* Timer related Aux registers */
diff --git a/include/soc/arc/timers.h b/include/soc/arc/timers.h
new file mode 100644
index 000000000000..79484fafabfa
--- /dev/null
+++ b/include/soc/arc/timers.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOC_ARC_TIMERS_H
+#define __SOC_ARC_TIMERS_H
+
+#include <soc/arc/aux.h>
+
+#define ARC_REG_TIMERS_BCR	0x75
+
+struct bcr_timer {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
+#else
+	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
+#endif
+};
+
+#endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 7/9] ARC: breakout timer stuff into a seperate header
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/arcregs.h |  9 +--------
 arch/arc/kernel/time.c         |  2 +-
 include/soc/arc/timers.h       | 24 ++++++++++++++++++++++++
 3 files changed, 26 insertions(+), 9 deletions(-)
 create mode 100644 include/soc/arc/timers.h

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index ccf5dc96713b..a17aa4558832 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -20,7 +20,6 @@
 #define ARC_REG_FP_V2_BCR	0xc8	/* ARCv2 FPU */
 #define ARC_REG_SLC_BCR		0xce
 #define ARC_REG_DCCM_BUILD	0x74	/* DCCM size (common) */
-#define ARC_REG_TIMERS_BCR	0x75
 #define ARC_REG_AP_BCR		0x76
 #define ARC_REG_ICCM_BUILD	0x78	/* ICCM size (common) */
 #define ARC_REG_XY_MEM_BCR	0x79
@@ -206,13 +205,7 @@ struct bcr_fp_arcv2 {
 #endif
 };
 
-struct bcr_timer {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
-#else
-	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
-#endif
-};
+#include <soc/arc/timers.h>
 
 struct bcr_bpu_arcompact {
 #ifdef CONFIG_CPU_BIG_ENDIAN
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index f1ebe45bfcdf..dad3a9933c4c 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -38,8 +38,8 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <asm/irq.h>
-#include <asm/arcregs.h>
 
+#include <soc/arc/timers.h>
 #include <soc/arc/mcip.h>
 
 /* Timer related Aux registers */
diff --git a/include/soc/arc/timers.h b/include/soc/arc/timers.h
new file mode 100644
index 000000000000..79484fafabfa
--- /dev/null
+++ b/include/soc/arc/timers.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOC_ARC_TIMERS_H
+#define __SOC_ARC_TIMERS_H
+
+#include <soc/arc/aux.h>
+
+#define ARC_REG_TIMERS_BCR	0x75
+
+struct bcr_timer {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
+#else
+	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
+#endif
+};
+
+#endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 8/9] ARC: timer: rename config options
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/Kconfig                           | 4 ++--
 arch/arc/configs/nsimosci_hs_smp_defconfig | 2 +-
 arch/arc/configs/vdk_hs38_smp_defconfig    | 2 +-
 arch/arc/kernel/setup.c                    | 4 ++--
 arch/arc/kernel/time.c                     | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index bd204bfa29ed..b4499f97035a 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -410,12 +410,12 @@ config ARC_HAS_DIV_REM
 	bool "Insn: div, divu, rem, remu"
 	default y
 
-config ARC_HAS_RTC
+config ARC_TIMER_RTC
 	bool "Local 64-bit r/o cycle counter"
 	default n
 	depends on !SMP
 
-config ARC_HAS_GFRC
+config ARC_TIMER_GFRC
 	bool "SMP synchronized 64-bit cycle counter"
 	default y
 	depends on SMP
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index 6da71ba253a9..9782fe512244 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -21,7 +21,7 @@ CONFIG_MODULES=y
 CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
-# CONFIG_ARC_HAS_GFRC is not set
+# CONFIG_ARC_TIMER_GFRC is not set
 CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu"
 CONFIG_PREEMPT=y
 # CONFIG_COMPACTION is not set
diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig
index 969b206d6c67..a927389d02d8 100644
--- a/arch/arc/configs/vdk_hs38_smp_defconfig
+++ b/arch/arc/configs/vdk_hs38_smp_defconfig
@@ -15,7 +15,7 @@ CONFIG_ARC_PLAT_AXS10X=y
 CONFIG_AXS103=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
-# CONFIG_ARC_HAS_GFRC is not set
+# CONFIG_ARC_TIMER_GFRC is not set
 CONFIG_ARC_UBOOT_SUPPORT=y
 CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
 CONFIG_PREEMPT=y
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 5865bd34a7fa..4855335b956b 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -239,8 +239,8 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
 		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
 		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
-		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
-		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
+		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMER_RTC),
+		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMER_GFRC));
 
 	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
 			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dad3a9933c4c..676b14b7a9be 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -81,7 +81,7 @@ static int noinline arc_get_timer_clk(struct device_node *node)
 
 /********** Clock Source Device *********/
 
-#ifdef CONFIG_ARC_HAS_GFRC
+#ifdef CONFIG_ARC_TIMER_GFRC
 
 static cycle_t arc_read_gfrc(struct clocksource *cs)
 {
@@ -135,7 +135,7 @@ CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
 
 #endif
 
-#ifdef CONFIG_ARC_HAS_RTC
+#ifdef CONFIG_ARC_TIMER_RTC
 
 #define AUX_RTC_CTRL	0x103
 #define AUX_RTC_LOW	0x104
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 8/9] ARC: timer: rename config options
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Kconfig                           | 4 ++--
 arch/arc/configs/nsimosci_hs_smp_defconfig | 2 +-
 arch/arc/configs/vdk_hs38_smp_defconfig    | 2 +-
 arch/arc/kernel/setup.c                    | 4 ++--
 arch/arc/kernel/time.c                     | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index bd204bfa29ed..b4499f97035a 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -410,12 +410,12 @@ config ARC_HAS_DIV_REM
 	bool "Insn: div, divu, rem, remu"
 	default y
 
-config ARC_HAS_RTC
+config ARC_TIMER_RTC
 	bool "Local 64-bit r/o cycle counter"
 	default n
 	depends on !SMP
 
-config ARC_HAS_GFRC
+config ARC_TIMER_GFRC
 	bool "SMP synchronized 64-bit cycle counter"
 	default y
 	depends on SMP
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index 6da71ba253a9..9782fe512244 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -21,7 +21,7 @@ CONFIG_MODULES=y
 CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
-# CONFIG_ARC_HAS_GFRC is not set
+# CONFIG_ARC_TIMER_GFRC is not set
 CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu"
 CONFIG_PREEMPT=y
 # CONFIG_COMPACTION is not set
diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig
index 969b206d6c67..a927389d02d8 100644
--- a/arch/arc/configs/vdk_hs38_smp_defconfig
+++ b/arch/arc/configs/vdk_hs38_smp_defconfig
@@ -15,7 +15,7 @@ CONFIG_ARC_PLAT_AXS10X=y
 CONFIG_AXS103=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
-# CONFIG_ARC_HAS_GFRC is not set
+# CONFIG_ARC_TIMER_GFRC is not set
 CONFIG_ARC_UBOOT_SUPPORT=y
 CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
 CONFIG_PREEMPT=y
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 5865bd34a7fa..4855335b956b 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -239,8 +239,8 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
 		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
 		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
-		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
-		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
+		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMER_RTC),
+		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMER_GFRC));
 
 	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
 			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dad3a9933c4c..676b14b7a9be 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -81,7 +81,7 @@ static int noinline arc_get_timer_clk(struct device_node *node)
 
 /********** Clock Source Device *********/
 
-#ifdef CONFIG_ARC_HAS_GFRC
+#ifdef CONFIG_ARC_TIMER_GFRC
 
 static cycle_t arc_read_gfrc(struct clocksource *cs)
 {
@@ -135,7 +135,7 @@ CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
 
 #endif
 
-#ifdef CONFIG_ARC_HAS_RTC
+#ifdef CONFIG_ARC_TIMER_RTC
 
 #define AUX_RTC_CTRL	0x103
 #define AUX_RTC_LOW	0x104
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-10-31 22:48             ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin,
	Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 MAINTAINERS                                        |  1 +
 arch/arc/Kconfig                                   | 12 +--------
 arch/arc/kernel/Makefile                           |  2 +-
 drivers/clocksource/Kconfig                        | 24 ++++++++++++++++++
 drivers/clocksource/Makefile                       |  1 +
 .../time.c => drivers/clocksource/arc_timer.c      | 29 ++++++----------------
 6 files changed, 35 insertions(+), 34 deletions(-)
 rename arch/arc/kernel/time.c => drivers/clocksource/arc_timer.c (90%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3d838cf49f81..57b56ff1dd68 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11632,6 +11632,7 @@ S:	Supported
 F:	arch/arc/
 F:	Documentation/devicetree/bindings/arc/*
 F:	Documentation/devicetree/bindings/interrupt-controller/snps,arc*
+F:	drivers/clocksource/arc_timer.c
 F:	drivers/tty/serial/arc_uart.c
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
 
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index b4499f97035a..8768a509d5e7 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -8,9 +8,9 @@
 
 config ARC
 	def_bool y
+	select ARC_TIMER
 	select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
 	select BUILDTIME_EXTABLE_SORT
-	select CLKSRC_OF
 	select CLONE_BACKWARDS
 	select COMMON_CLK
 	select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
@@ -410,16 +410,6 @@ config ARC_HAS_DIV_REM
 	bool "Insn: div, divu, rem, remu"
 	default y
 
-config ARC_TIMER_RTC
-	bool "Local 64-bit r/o cycle counter"
-	default n
-	depends on !SMP
-
-config ARC_TIMER_GFRC
-	bool "SMP synchronized 64-bit cycle counter"
-	default y
-	depends on SMP
-
 config ARC_NUMBER_OF_INTERRUPTS
 	int "Number of interrupts"
 	range 8 240
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index cfcdedf52ff8..8942c5c3b4c5 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -8,7 +8,7 @@
 # Pass UTS_MACHINE for user_regset definition
 CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
-obj-y	:= arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
+obj-y	:= arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
 obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
 obj-$(CONFIG_ISA_ARCOMPACT)		+= entry-compact.o intc-compact.o
 obj-$(CONFIG_ISA_ARCV2)			+= entry-arcv2.o intc-arcv2.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index e2c6e43cf8ca..73feaadc1924 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -282,6 +282,30 @@ config CLKSRC_MPS2
 	select CLKSRC_MMIO
 	select CLKSRC_OF
 
+config ARC_TIMER
+	bool "Enable timers for ARC Cores"
+	select CLKSRC_OF if OF
+
+if ARC_TIMER
+
+config ARC_TIMER_RTC
+	bool "64-bit cycle counter in HS38 cores"
+	default y if ARC
+	depends on !SMP
+	help
+	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
+	  It is implemented inside the core thus can't be used in SMP systems
+
+config ARC_TIMER_GFRC
+	bool "64-bit cycle counter in ARConnect block in HS38x cores"
+	default y if ARC
+	depends on SMP
+	help
+	  This counter can be used as clocksource in SMP HS38 SoCs.
+	  It sits outside the core thus can be used in SMP systems
+
+endif
+
 config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cf87f407f1ad..e78480cb47f4 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,3 +69,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
 obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
 obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
 obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
+obj-$(CONFIG_ARC_TIMER)			+= arc_timer.o
diff --git a/arch/arc/kernel/time.c b/drivers/clocksource/arc_timer.c
similarity index 90%
rename from arch/arc/kernel/time.c
rename to drivers/clocksource/arc_timer.c
index 676b14b7a9be..ec37b6c5e903 100644
--- a/arch/arc/kernel/time.c
+++ b/drivers/clocksource/arc_timer.c
@@ -1,32 +1,18 @@
 /*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
- * vineetg: Jan 1011
- *  -sched_clock( ) no longer jiffies based. Uses the same clocksource
- *   as gtod
- *
- * Rajeshwarr/Vineetg: Mar 2008
- *  -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
- *   for arch independent gettimeofday()
- *  -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
- *
- * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
  */
 
-/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
- * Each can programmed to go from @count to @limit and optionally
- * interrupt when that happens.
- * A write to Control Register clears the Interrupt
- *
- * We've designated TIMER0 for events (clockevents)
- * while TIMER1 for free running (clocksource)
+/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be
+ * programmed to go from @count to @limit and optionally interrupt.
+ * We've designated TIMER0 for clockevents and TIMER1 for clocksource
  *
- * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
- * which however is currently broken
+ * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP)
+ * which are suitable for UP and SMP based clocksources respectively
  */
 
 #include <linux/interrupt.h>
@@ -37,7 +23,6 @@
 #include <linux/cpu.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
-#include <asm/irq.h>
 
 #include <soc/arc/timers.h>
 #include <soc/arc/mcip.h>
@@ -281,7 +266,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
 	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
 	 */
 	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
-	int irq_reenable = clockevent_state_periodic(evt);
+	int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
 
 	/*
 	 * Any write to CTRL reg ACks the interrupt, we rewrite the
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-10-31 22:48             ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-10-31 22:48 UTC (permalink / raw)
  To: linux-snps-arc

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 MAINTAINERS                                        |  1 +
 arch/arc/Kconfig                                   | 12 +--------
 arch/arc/kernel/Makefile                           |  2 +-
 drivers/clocksource/Kconfig                        | 24 ++++++++++++++++++
 drivers/clocksource/Makefile                       |  1 +
 .../time.c => drivers/clocksource/arc_timer.c      | 29 ++++++----------------
 6 files changed, 35 insertions(+), 34 deletions(-)
 rename arch/arc/kernel/time.c => drivers/clocksource/arc_timer.c (90%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3d838cf49f81..57b56ff1dd68 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11632,6 +11632,7 @@ S:	Supported
 F:	arch/arc/
 F:	Documentation/devicetree/bindings/arc/*
 F:	Documentation/devicetree/bindings/interrupt-controller/snps,arc*
+F:	drivers/clocksource/arc_timer.c
 F:	drivers/tty/serial/arc_uart.c
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
 
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index b4499f97035a..8768a509d5e7 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -8,9 +8,9 @@
 
 config ARC
 	def_bool y
+	select ARC_TIMER
 	select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
 	select BUILDTIME_EXTABLE_SORT
-	select CLKSRC_OF
 	select CLONE_BACKWARDS
 	select COMMON_CLK
 	select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
@@ -410,16 +410,6 @@ config ARC_HAS_DIV_REM
 	bool "Insn: div, divu, rem, remu"
 	default y
 
-config ARC_TIMER_RTC
-	bool "Local 64-bit r/o cycle counter"
-	default n
-	depends on !SMP
-
-config ARC_TIMER_GFRC
-	bool "SMP synchronized 64-bit cycle counter"
-	default y
-	depends on SMP
-
 config ARC_NUMBER_OF_INTERRUPTS
 	int "Number of interrupts"
 	range 8 240
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index cfcdedf52ff8..8942c5c3b4c5 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -8,7 +8,7 @@
 # Pass UTS_MACHINE for user_regset definition
 CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
-obj-y	:= arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
+obj-y	:= arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
 obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
 obj-$(CONFIG_ISA_ARCOMPACT)		+= entry-compact.o intc-compact.o
 obj-$(CONFIG_ISA_ARCV2)			+= entry-arcv2.o intc-arcv2.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index e2c6e43cf8ca..73feaadc1924 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -282,6 +282,30 @@ config CLKSRC_MPS2
 	select CLKSRC_MMIO
 	select CLKSRC_OF
 
+config ARC_TIMER
+	bool "Enable timers for ARC Cores"
+	select CLKSRC_OF if OF
+
+if ARC_TIMER
+
+config ARC_TIMER_RTC
+	bool "64-bit cycle counter in HS38 cores"
+	default y if ARC
+	depends on !SMP
+	help
+	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
+	  It is implemented inside the core thus can't be used in SMP systems
+
+config ARC_TIMER_GFRC
+	bool "64-bit cycle counter in ARConnect block in HS38x cores"
+	default y if ARC
+	depends on SMP
+	help
+	  This counter can be used as clocksource in SMP HS38 SoCs.
+	  It sits outside the core thus can be used in SMP systems
+
+endif
+
 config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cf87f407f1ad..e78480cb47f4 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,3 +69,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
 obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
 obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
 obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
+obj-$(CONFIG_ARC_TIMER)			+= arc_timer.o
diff --git a/arch/arc/kernel/time.c b/drivers/clocksource/arc_timer.c
similarity index 90%
rename from arch/arc/kernel/time.c
rename to drivers/clocksource/arc_timer.c
index 676b14b7a9be..ec37b6c5e903 100644
--- a/arch/arc/kernel/time.c
+++ b/drivers/clocksource/arc_timer.c
@@ -1,32 +1,18 @@
 /*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
- * vineetg: Jan 1011
- *  -sched_clock( ) no longer jiffies based. Uses the same clocksource
- *   as gtod
- *
- * Rajeshwarr/Vineetg: Mar 2008
- *  -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
- *   for arch independent gettimeofday()
- *  -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
- *
- * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
  */
 
-/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
- * Each can programmed to go from @count to @limit and optionally
- * interrupt when that happens.
- * A write to Control Register clears the Interrupt
- *
- * We've designated TIMER0 for events (clockevents)
- * while TIMER1 for free running (clocksource)
+/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be
+ * programmed to go from @count to @limit and optionally interrupt.
+ * We've designated TIMER0 for clockevents and TIMER1 for clocksource
  *
- * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
- * which however is currently broken
+ * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP)
+ * which are suitable for UP and SMP based clocksources respectively
  */
 
 #include <linux/interrupt.h>
@@ -37,7 +23,6 @@
 #include <linux/cpu.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
-#include <asm/irq.h>
 
 #include <soc/arc/timers.h>
 #include <soc/arc/mcip.h>
@@ -281,7 +266,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
 	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
 	 */
 	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
-	int irq_reenable = clockevent_state_periodic(evt);
+	int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
 
 	/*
 	 * Any write to CTRL reg ACks the interrupt, we rewrite the
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-01  0:01               ` kbuild test robot
  -1 siblings, 0 replies; 95+ messages in thread
From: kbuild test robot @ 2016-11-01  0:01 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: kbuild-all, Daniel Lezcano, tglx, linux-kernel, linux-snps-arc,
	Noam Camus, Alexey.Brodkin, Vineet Gupta

[-- Attachment #1: Type: text/plain, Size: 15110 bytes --]

Hi Vineet,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.9-rc3]
[cannot apply to arc/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/Move-ARC-timer-code-into-drivers-clocksource/20161101-065452
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All error/warnings (new ones prefixed by >>):

>> drivers/clocksource/arc_timer.c:237:19: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration
               struct clock_event_device *dev)
                      ^~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:243:45: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration
    static int arc_clkevent_set_periodic(struct clock_event_device *dev)
                                                ^~~~~~~~~~~~~~~~~~
   In file included from include/asm-generic/percpu.h:6:0,
                    from arch/ia64/include/asm/percpu.h:45,
                    from arch/ia64/include/asm/processor.h:77,
                    from arch/ia64/include/asm/thread_info.h:11,
                    from include/linux/thread_info.h:58,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/ia64/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:59,
                    from include/linux/interrupt.h:8,
                    from drivers/clocksource/arc_timer.c:18:
>> drivers/clocksource/arc_timer.c:253:30: error: variable 'arc_clockevent_device' has initializer but incomplete type
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
                                 ^
   include/linux/percpu-defs.h:95:13: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
     __typeof__(type) name
                ^~~~
>> drivers/clocksource/arc_timer.c:253:8: note: in expansion of macro 'DEFINE_PER_CPU'
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
           ^~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:254:2: error: unknown field 'name' specified in initializer
     .name   = "ARC Timer0",
     ^
>> drivers/clocksource/arc_timer.c:254:12: warning: excess elements in struct initializer
     .name   = "ARC Timer0",
               ^~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:254:12: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:255:2: error: unknown field 'features' specified in initializer
     .features  = CLOCK_EVT_FEAT_ONESHOT |
     ^
>> drivers/clocksource/arc_timer.c:255:15: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared here (not in a function)
     .features  = CLOCK_EVT_FEAT_ONESHOT |
                  ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:256:7: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared here (not in a function)
          CLOCK_EVT_FEAT_PERIODIC,
          ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:255:15: warning: excess elements in struct initializer
     .features  = CLOCK_EVT_FEAT_ONESHOT |
                  ^~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:255:15: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:257:2: error: unknown field 'rating' specified in initializer
     .rating   = 300,
     ^
   drivers/clocksource/arc_timer.c:257:14: warning: excess elements in struct initializer
     .rating   = 300,
                 ^~~
   drivers/clocksource/arc_timer.c:257:14: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:258:2: error: unknown field 'set_next_event' specified in initializer
     .set_next_event  = arc_clkevent_set_next_event,
     ^
   drivers/clocksource/arc_timer.c:258:21: warning: excess elements in struct initializer
     .set_next_event  = arc_clkevent_set_next_event,
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:258:21: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:259:2: error: unknown field 'set_state_periodic' specified in initializer
     .set_state_periodic = arc_clkevent_set_periodic,
     ^
   drivers/clocksource/arc_timer.c:259:24: warning: excess elements in struct initializer
     .set_state_periodic = arc_clkevent_set_periodic,
                           ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:259:24: note: (near initialization for 'arc_clockevent_device')
   drivers/clocksource/arc_timer.c: In function 'timer_irq_handler':
>> drivers/clocksource/arc_timer.c:268:9: error: invalid use of undefined type 'struct clock_event_device'
     struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
            ^~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:269:36: error: implicit declaration of function 'clockevent_state_periodic' [-Werror=implicit-function-declaration]
     int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:278:5: error: dereferencing pointer to incomplete type 'struct clock_event_device'
     evt->event_handler(evt);
        ^~
   drivers/clocksource/arc_timer.c: In function 'arc_timer_starting_cpu':
   drivers/clocksource/arc_timer.c:286:9: error: invalid use of undefined type 'struct clock_event_device'
     struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
            ^~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:290:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
     clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c: In function 'arc_clockevent_setup':
   drivers/clocksource/arc_timer.c:306:9: error: invalid use of undefined type 'struct clock_event_device'
     struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
            ^~~~~~~~~~~~~~~~~~
   In file included from include/asm-generic/percpu.h:6:0,
                    from arch/ia64/include/asm/percpu.h:45,
                    from arch/ia64/include/asm/processor.h:77,
                    from arch/ia64/include/asm/thread_info.h:11,
                    from include/linux/thread_info.h:58,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/ia64/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:59,
                    from include/linux/interrupt.h:8,
                    from drivers/clocksource/arc_timer.c:18:
   drivers/clocksource/arc_timer.c: At top level:
>> drivers/clocksource/arc_timer.c:253:50: error: storage size of 'arc_clockevent_device' isn't known
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
                                                     ^
   include/linux/percpu-defs.h:95:19: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
     __typeof__(type) name
                      ^~~~
>> drivers/clocksource/arc_timer.c:253:8: note: in expansion of macro 'DEFINE_PER_CPU'
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
           ^~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/arc_clockevent_device +253 drivers/clocksource/arc_timer.c

d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  231  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  232  	write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  233  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  234  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  235  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  236  static int arc_clkevent_set_next_event(unsigned long delta,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @237  				       struct clock_event_device *dev)
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  238  {
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  239  	arc_timer_event_setup(delta);
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  240  	return 0;
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  241  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  242  
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16  243  static int arc_clkevent_set_periodic(struct clock_event_device *dev)
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  244  {
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  245  	/*
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  246  	 * At X Hz, 1 sec = 1000ms -> X cycles;
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  247  	 *		      10ms -> X / 100 cycles
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  248  	 */
77c8d0d6b arch/arc/kernel/time.c          Vineet Gupta        2016-01-01  249  	arc_timer_event_setup(arc_timer_freq / HZ);
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16  250  	return 0;
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  251  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  252  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @253  static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @254  	.name			= "ARC Timer0",
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16 @255  	.features		= CLOCK_EVT_FEAT_ONESHOT |
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16 @256  				  CLOCK_EVT_FEAT_PERIODIC,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @257  	.rating			= 300,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @258  	.set_next_event		= arc_clkevent_set_next_event,
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16 @259  	.set_state_periodic	= arc_clkevent_set_periodic,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  260  };
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  261  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  262  static irqreturn_t timer_irq_handler(int irq, void *dev_id)
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  263  {
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  264  	/*
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  265  	 * Note that generic IRQ core could have passed @evt for @dev_id if
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  266  	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  267  	 */
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25 @268  	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
31aaee97f drivers/clocksource/arc_timer.c Vineet Gupta        2016-10-31 @269  	int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  270  
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  271  	/*
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  272  	 * Any write to CTRL reg ACks the interrupt, we rewrite the
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  273  	 * Count when [N]ot [H]alted bit.
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  274  	 * And re-arm it if perioid by [I]nterrupt [E]nable bit
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  275  	 */
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  276  	write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH);
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  277  
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25 @278  	evt->event_handler(evt);
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  279  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  280  	return IRQ_HANDLED;
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  281  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  282  
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13  283  
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13  284  static int arc_timer_starting_cpu(unsigned int cpu)
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  285  {
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  286  	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  287  
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  288  	evt->cpumask = cpumask_of(smp_processor_id());
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  289  
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13 @290  	clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  291  	enable_percpu_irq(arc_timer_irq, 0);
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13  292  	return 0;
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  293  }

:::::: The code at line 253 was first introduced by commit
:::::: d8005e6b95268cbb50db3773d5f180c32a9434fe ARC: Timers/counters/delay management

:::::: TO: Vineet Gupta <vgupta@synopsys.com>
:::::: CC: Vineet Gupta <vgupta@synopsys.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 45102 bytes --]

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-01  0:01               ` kbuild test robot
  0 siblings, 0 replies; 95+ messages in thread
From: kbuild test robot @ 2016-11-01  0:01 UTC (permalink / raw)
  To: linux-snps-arc

Hi Vineet,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.9-rc3]
[cannot apply to arc/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/Move-ARC-timer-code-into-drivers-clocksource/20161101-065452
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All error/warnings (new ones prefixed by >>):

>> drivers/clocksource/arc_timer.c:237:19: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration
               struct clock_event_device *dev)
                      ^~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:243:45: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration
    static int arc_clkevent_set_periodic(struct clock_event_device *dev)
                                                ^~~~~~~~~~~~~~~~~~
   In file included from include/asm-generic/percpu.h:6:0,
                    from arch/ia64/include/asm/percpu.h:45,
                    from arch/ia64/include/asm/processor.h:77,
                    from arch/ia64/include/asm/thread_info.h:11,
                    from include/linux/thread_info.h:58,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/ia64/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:59,
                    from include/linux/interrupt.h:8,
                    from drivers/clocksource/arc_timer.c:18:
>> drivers/clocksource/arc_timer.c:253:30: error: variable 'arc_clockevent_device' has initializer but incomplete type
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
                                 ^
   include/linux/percpu-defs.h:95:13: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
     __typeof__(type) name
                ^~~~
>> drivers/clocksource/arc_timer.c:253:8: note: in expansion of macro 'DEFINE_PER_CPU'
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
           ^~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:254:2: error: unknown field 'name' specified in initializer
     .name   = "ARC Timer0",
     ^
>> drivers/clocksource/arc_timer.c:254:12: warning: excess elements in struct initializer
     .name   = "ARC Timer0",
               ^~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:254:12: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:255:2: error: unknown field 'features' specified in initializer
     .features  = CLOCK_EVT_FEAT_ONESHOT |
     ^
>> drivers/clocksource/arc_timer.c:255:15: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared here (not in a function)
     .features  = CLOCK_EVT_FEAT_ONESHOT |
                  ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:256:7: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared here (not in a function)
          CLOCK_EVT_FEAT_PERIODIC,
          ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:255:15: warning: excess elements in struct initializer
     .features  = CLOCK_EVT_FEAT_ONESHOT |
                  ^~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:255:15: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:257:2: error: unknown field 'rating' specified in initializer
     .rating   = 300,
     ^
   drivers/clocksource/arc_timer.c:257:14: warning: excess elements in struct initializer
     .rating   = 300,
                 ^~~
   drivers/clocksource/arc_timer.c:257:14: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:258:2: error: unknown field 'set_next_event' specified in initializer
     .set_next_event  = arc_clkevent_set_next_event,
     ^
   drivers/clocksource/arc_timer.c:258:21: warning: excess elements in struct initializer
     .set_next_event  = arc_clkevent_set_next_event,
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:258:21: note: (near initialization for 'arc_clockevent_device')
>> drivers/clocksource/arc_timer.c:259:2: error: unknown field 'set_state_periodic' specified in initializer
     .set_state_periodic = arc_clkevent_set_periodic,
     ^
   drivers/clocksource/arc_timer.c:259:24: warning: excess elements in struct initializer
     .set_state_periodic = arc_clkevent_set_periodic,
                           ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c:259:24: note: (near initialization for 'arc_clockevent_device')
   drivers/clocksource/arc_timer.c: In function 'timer_irq_handler':
>> drivers/clocksource/arc_timer.c:268:9: error: invalid use of undefined type 'struct clock_event_device'
     struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
            ^~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:269:36: error: implicit declaration of function 'clockevent_state_periodic' [-Werror=implicit-function-declaration]
     int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:278:5: error: dereferencing pointer to incomplete type 'struct clock_event_device'
     evt->event_handler(evt);
        ^~
   drivers/clocksource/arc_timer.c: In function 'arc_timer_starting_cpu':
   drivers/clocksource/arc_timer.c:286:9: error: invalid use of undefined type 'struct clock_event_device'
     struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
            ^~~~~~~~~~~~~~~~~~
>> drivers/clocksource/arc_timer.c:290:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
     clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/arc_timer.c: In function 'arc_clockevent_setup':
   drivers/clocksource/arc_timer.c:306:9: error: invalid use of undefined type 'struct clock_event_device'
     struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
            ^~~~~~~~~~~~~~~~~~
   In file included from include/asm-generic/percpu.h:6:0,
                    from arch/ia64/include/asm/percpu.h:45,
                    from arch/ia64/include/asm/processor.h:77,
                    from arch/ia64/include/asm/thread_info.h:11,
                    from include/linux/thread_info.h:58,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/ia64/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:59,
                    from include/linux/interrupt.h:8,
                    from drivers/clocksource/arc_timer.c:18:
   drivers/clocksource/arc_timer.c: At top level:
>> drivers/clocksource/arc_timer.c:253:50: error: storage size of 'arc_clockevent_device' isn't known
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
                                                     ^
   include/linux/percpu-defs.h:95:19: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
     __typeof__(type) name
                      ^~~~
>> drivers/clocksource/arc_timer.c:253:8: note: in expansion of macro 'DEFINE_PER_CPU'
    static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
           ^~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/arc_clockevent_device +253 drivers/clocksource/arc_timer.c

d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  231  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  232  	write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  233  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  234  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  235  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  236  static int arc_clkevent_set_next_event(unsigned long delta,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @237  				       struct clock_event_device *dev)
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  238  {
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  239  	arc_timer_event_setup(delta);
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  240  	return 0;
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  241  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  242  
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16  243  static int arc_clkevent_set_periodic(struct clock_event_device *dev)
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  244  {
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  245  	/*
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  246  	 * At X Hz, 1 sec = 1000ms -> X cycles;
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  247  	 *		      10ms -> X / 100 cycles
c9a98e184 arch/arc/kernel/time.c          Vineet Gupta        2014-06-25  248  	 */
77c8d0d6b arch/arc/kernel/time.c          Vineet Gupta        2016-01-01  249  	arc_timer_event_setup(arc_timer_freq / HZ);
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16  250  	return 0;
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  251  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  252  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @253  static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @254  	.name			= "ARC Timer0",
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16 @255  	.features		= CLOCK_EVT_FEAT_ONESHOT |
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16 @256  				  CLOCK_EVT_FEAT_PERIODIC,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @257  	.rating			= 300,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18 @258  	.set_next_event		= arc_clkevent_set_next_event,
aeec6cdad arch/arc/kernel/time.c          Viresh Kumar        2015-07-16 @259  	.set_state_periodic	= arc_clkevent_set_periodic,
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  260  };
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  261  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  262  static irqreturn_t timer_irq_handler(int irq, void *dev_id)
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  263  {
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  264  	/*
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  265  	 * Note that generic IRQ core could have passed @evt for @dev_id if
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  266  	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  267  	 */
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25 @268  	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
31aaee97f drivers/clocksource/arc_timer.c Vineet Gupta        2016-10-31 @269  	int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  270  
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  271  	/*
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  272  	 * Any write to CTRL reg ACks the interrupt, we rewrite the
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  273  	 * Count when [N]ot [H]alted bit.
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  274  	 * And re-arm it if perioid by [I]nterrupt [E]nable bit
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  275  	 */
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  276  	write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH);
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25  277  
f8b34c3fd arch/arc/kernel/time.c          Vineet Gupta        2014-01-25 @278  	evt->event_handler(evt);
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  279  
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  280  	return IRQ_HANDLED;
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  281  }
d8005e6b9 arch/arc/kernel/time.c          Vineet Gupta        2013-01-18  282  
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13  283  
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13  284  static int arc_timer_starting_cpu(unsigned int cpu)
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  285  {
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  286  	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  287  
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  288  	evt->cpumask = cpumask_of(smp_processor_id());
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  289  
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13 @290  	clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  291  	enable_percpu_irq(arc_timer_irq, 0);
ecd8081f6 arch/arc/kernel/time.c          Anna-Maria Gleixner 2016-07-13  292  	return 0;
eec3c58ef arch/arc/kernel/time.c          Noam Camus          2016-01-01  293  }

:::::: The code at line 253 was first introduced by commit
:::::: d8005e6b95268cbb50db3773d5f180c32a9434fe ARC: Timers/counters/delay management

:::::: TO: Vineet Gupta <vgupta at synopsys.com>
:::::: CC: Vineet Gupta <vgupta at synopsys.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 45102 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-snps-arc/attachments/20161101/6a1b541d/attachment-0001.gz>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-01  0:01               ` kbuild test robot
@ 2016-11-01  0:45                 ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-01  0:45 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Daniel Lezcano, tglx, linux-kernel, linux-snps-arc,
	Noam Camus, Alexey.Brodkin

On 10/31/2016 05:01 PM, kbuild test robot wrote:
> Hi Vineet,
> 
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.9-rc3]
> [cannot apply to arc/for-next]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> [Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
> [Check https://git-scm.com/docs/git-format-patch for more information]
> 
> url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/Move-ARC-timer-code-into-drivers-clocksource/20161101-065452
> config: ia64-allmodconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 6.2.0
> reproduce:
>         wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # save the attached .config to linux build tree
>         make.cross ARCH=ia64 
> 
> All error/warnings (new ones prefixed by >>):
> 
>>> >> drivers/clocksource/arc_timer.c:237:19: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration
>                struct clock_event_device *dev)
>                       ^~~~~~~~~~~~~~~~~~
>    drivers/clocksource/arc_timer.c:243:45: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration

So I'd build tested the series for ARM (32 bit) and x86 (64 bit).
Seems this requires a depends on GENERIC_CLOCKEVENTS. Will fix it along with other
comments !

Thx for reporting.
-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-01  0:45                 ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-01  0:45 UTC (permalink / raw)
  To: linux-snps-arc

On 10/31/2016 05:01 PM, kbuild test robot wrote:
> Hi Vineet,
> 
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.9-rc3]
> [cannot apply to arc/for-next]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> [Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
> [Check https://git-scm.com/docs/git-format-patch for more information]
> 
> url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/Move-ARC-timer-code-into-drivers-clocksource/20161101-065452
> config: ia64-allmodconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 6.2.0
> reproduce:
>         wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # save the attached .config to linux build tree
>         make.cross ARCH=ia64 
> 
> All error/warnings (new ones prefixed by >>):
> 
>>> >> drivers/clocksource/arc_timer.c:237:19: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration
>                struct clock_event_device *dev)
>                       ^~~~~~~~~~~~~~~~~~
>    drivers/clocksource/arc_timer.c:243:45: warning: 'struct clock_event_device' declared inside parameter list will not be visible outside of this definition or declaration

So I'd build tested the series for ARM (32 bit) and x86 (64 bit).
Seems this requires a depends on GENERIC_CLOCKEVENTS. Will fix it along with other
comments !

Thx for reporting.
-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* RE: [PATCH 5/9] ARC: breakout aux handling into a seperate header
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-01  7:49               ` Noam Camus
  -1 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-11-01  7:49 UTC (permalink / raw)
  To: Vineet Gupta, Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Alexey.Brodkin

>From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
>Sent: Tuesday, November 1, 2016 12:48 AM

>ARC timers use aux registers for programming and this paves way for moving ARC timer drivers into drivers/clocksource

Maybe in this patch or just another one could you move from timer.c to the new soc header all timer related Aux registers definitions?
This could be used by timer-nps driver.
 
i.e.:
/* Timer related Aux registers */
#define ARC_REG_TIMER0_LIMIT    0x23    /* timer 0 limit */
#define ARC_REG_TIMER0_CTRL     0x22    /* timer 0 control */
#define ARC_REG_TIMER0_CNT      0x21    /* timer 0 count */
#define ARC_REG_TIMER1_LIMIT    0x102   /* timer 1 limit */
#define ARC_REG_TIMER1_CTRL     0x101   /* timer 1 control */
#define ARC_REG_TIMER1_CNT      0x100   /* timer 1 count */

#define TIMER_CTRL_IE   (1 << 0) /* Interrupt when Count reaches limit */
#define TIMER_CTRL_NH   (1 << 1) /* Count only when CPU NOT halted */

#define ARC_TIMER_MAX   0xFFFFFFFF

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 5/9] ARC: breakout aux handling into a seperate header
@ 2016-11-01  7:49               ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-11-01  7:49 UTC (permalink / raw)
  To: linux-snps-arc

>From: Vineet Gupta [mailto:Vineet.Gupta1 at synopsys.com] 
>Sent: Tuesday, November 1, 2016 12:48 AM

>ARC timers use aux registers for programming and this paves way for moving ARC timer drivers into drivers/clocksource

Maybe in this patch or just another one could you move from timer.c to the new soc header all timer related Aux registers definitions?
This could be used by timer-nps driver.
 
i.e.:
/* Timer related Aux registers */
#define ARC_REG_TIMER0_LIMIT    0x23    /* timer 0 limit */
#define ARC_REG_TIMER0_CTRL     0x22    /* timer 0 control */
#define ARC_REG_TIMER0_CNT      0x21    /* timer 0 count */
#define ARC_REG_TIMER1_LIMIT    0x102   /* timer 1 limit */
#define ARC_REG_TIMER1_CTRL     0x101   /* timer 1 control */
#define ARC_REG_TIMER1_CNT      0x100   /* timer 1 count */

#define TIMER_CTRL_IE   (1 << 0) /* Interrupt when Count reaches limit */
#define TIMER_CTRL_NH   (1 << 1) /* Count only when CPU NOT halted */

#define ARC_TIMER_MAX   0xFFFFFFFF

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
@ 2016-11-01 20:01         ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-01 20:01 UTC (permalink / raw)
  To: Noam Camus
  Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel, Vineet Gupta

On Mon, Oct 31, 2016 at 05:03:40PM +0000, Noam Camus wrote:
> >From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
> >Sent: Monday, October 31, 2016 12:53 PM
> 
> >> 
> >> The design idea is that for each core there is dedicated regirtser
> 
> >s/regirtser/register/
> 
> >Hey ! re-read yourself.
> Thanks, I do but sometimes reading over and over and still left with such typos
> Will Fix on next patch Set V4
> 
> >> (TSI) serving all 16 HW threads.
> >> The register is a bitmask with one bit for each HW thread.
> >> When HW thread wants that next expiration of timer interrupt will hit 
> >> it then the proper bit should be set in this dedicated register.
> 
> >I'm not sure to understand this sentence. Do you mean each cpu/thread must
> >set a flag in the TSI register at BIT(phys_id) when they set a timer ?
> Correct, each thread needs to set its bit in TSI register, otherwise the he
> won't be interrupted by timer.
> 
> >> When timer expires all HW threads within this core which their bit is 
> >> set at the TSI register will be interrupted.
> 
> >Does it mean some HW threads will be wake up for nothing ?
> See below after the example you gave
> 
> >eg. 
> 
> >HWT1 sets the timer to expire within 2 seconds
> >HWT2 sets the timer to expire within 2 hours
> 
> >When the first timer expires, that will wake up HWT1 *and* HWT2 ?
> 
> You are correct, indeed not optimal but much simpler than managing book
> keeping of all 16 threads.  Functionality wise one who registered this timer
> will notice that it expired too soon and will register a new one.  This is how
> it works now in our machines.

Assuming cpu0 and cpu1 are sibling, does

taskset 0x1 time sleep 2 & taskset 0x2 time sleep 3

give a correct result without a dmesg log ?

Can you give the content of the /proc/timer_list ?

I'm not sure it is safe to have this kind of spurious interrupt for the time
framework.

> >The code is a bit confusing because of the very specific design of this timer.
> 
> >Below more questions for clarification.
> 
> ...
> >> diff --git a/drivers/clocksource/timer-nps.c 
> >> b/drivers/clocksource/timer-nps.c index 6156e54..0757328 100644
> >> --- a/drivers/clocksource/timer-nps.c
> >> +++ b/drivers/clocksource/timer-nps.c
> >> @@ -46,7 +46,7 @@
> >>  /* This array is per cluster of CPUs (Each NPS400 cluster got 256 
> >> CPUs) */  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] 
> >> __read_mostly;
> >>  
> >> -static unsigned long nps_timer_rate;
> >> +static unsigned long nps_timer1_freq;
> >
> >Why declare a global static variable for a local use in nps_setup_clocksource ? 
> Indeed no need. It will be fixed at V4
> 
> ...
> >> +/* Timer related Aux registers */
> >> +#define AUX_REG_TIMER0_TSI	0xFFFFF850	/* timer 0 HW threads mask */
> >> +#define NPS_REG_TIMER0_LIMIT	0x23		/* timer 0 limit */
> >> +#define NPS_REG_TIMER0_CTRL	0x22		/* timer 0 control */
> >> +#define NPS_REG_TIMER0_CNT	0x21		/* timer 0 count */
> >> +
> >> +#define TIMER0_CTRL_IE	(1 << 0) /* Interrupt when Count reaches limit */
> >> +#define TIMER0_CTRL_NH	(1 << 1) /* Count only when CPU NOT halted */
> 
> >Please, use BIT(nr) macro.
> Will fix that on V4.
> 
> >Can you elaborate "Count only when CPU NOT halted" ?
> The Idea here is:
> The Not Halted mode flag (NH) causes cycles to be counted only when the
> processor is running (not halted). When set to 0 the timer will count every
> clock cycle. When set to 1 the timer will only count when the processor is
> running. The NH flag is set to 0 when the processor is Reset.

When is the processor halted ? At idle time ?

There is an inconsistency here:

 - If the power management of the CPU allows to power it down and the timer
   belongs to the same power domain to the CPU, then it will be powered down
   also. In this case, the C3STOP flag must be used and the CPU wakeup must be
   delegated to a backup timer.

 - If there is no power management on the CPU. The timer must continue to
   count cycles in order to wake up the CPU if it is halted (assuming it
   is clock gated).

In both cases, TIMER0_CTRL_NH is not needed.

Or is the CPU halted *only* when debugging it ?

> It may be used when working with JTAG (I never used it this way though).
> 
> >> +static unsigned long nps_timer0_freq; static unsigned long 
> >> +nps_timer0_irq;
> >> +
> >> +/*
> >> + * Arm the timer to interrupt after @cycles  */ static void 
> >> +nps_clkevent_timer_event_setup(unsigned int cycles) {
> >> +	write_aux_reg(NPS_REG_TIMER0_LIMIT, cycles);
> >> +	write_aux_reg(NPS_REG_TIMER0_CNT, 0);   /* start from 0 */
> >> +
> >> +	write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_IE | TIMER0_CTRL_NH); 
> >> +}
> >> +
> >> +static void nps_clkevent_rm_thread(bool remove_thread) {
> >> +	unsigned int cflags;
> >> +	unsigned int enabled_threads;
> >> +	unsigned long flags;
> >> +	int thread;
> >> +
> >> +	local_irq_save(flags);
> >> +	hw_schd_save(&cflags);
> >
> >Can you explain why those two lines are needed ?
> The idea is that access to shared core registers (among threads) is not done
> in parallel to keep their consistency.  For example Read Modified Write of TSI
> register is not atomic, so using two lines above avoid any interference during
> this code execution.

Mmmh, I'm not used to hardware scheduling. Why hw_schd_save() is needed ?

regmap provides the API to deal with read/write of shared register.

> >> +
> >> +static int nps_clkevent_set_next_event(unsigned long delta,
> >> +				       struct clock_event_device *dev) {
> >> +	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
> >> +	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
> >> +
> >> +	nps_clkevent_add_thread(true);
> >> +	chip->irq_unmask(&desc->irq_data);
> 
> >Can you explain why invoking low level IRQ callbacks is needed here ?
> I needed those callbacks functionality and didn't want to duplicate it here.

If you need these callbacks here, then there is probably an issue with the
driver design.

> >> +
> >> +static int nps_clkevent_set_periodic(struct clock_event_device *dev) 
> >> +{
> >> +	nps_clkevent_add_thread(false);
> >> +	if (read_aux_reg(CTOP_AUX_THREAD_ID) == 0)
> >> +		nps_clkevent_timer_event_setup(nps_timer0_freq / HZ);
> 
> >Please explain this. I read only CPU0 can set the periodic timer.
> When system works in periodic mode for clock events we just need to set for
> all HW threads within same core their respective bit at TSI register.  We also
> need but only once to arm the shared timer control register.  Since that for
> each core thread 0 is always available we choose HW thread 0 to do that.  ...

I see. Please, add the explanation as a comment in the code.

> >> +static int __init nps_setup_clockevent(struct device_node *node) {
> >> +	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
> >> +	struct clk *clk;
> 
> >clk = 0xDEADBEEF
> >> +	int ret;
> >> +
> >> +	nps_timer0_irq = irq_of_parse_and_map(node, 0);
> >> +	if (nps_timer0_irq <= 0) {
> >> +		pr_err("clockevent: missing irq");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	nps_get_timer_clk(node, &nps_timer0_freq, clk);
> >> +
> >> +	/* Needs apriori irq_set_percpu_devid() done in intc map function */
> >> +	ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
> >> +				 "Timer0 (per-cpu-tick)", evt);
> >> +	if (ret) {
> >> +		pr_err("Couldn't request irq\n");
> >> +		clk_disable_unprepare(clk);
> 
> >clk is on the stack, hence returning back from the function, clk is
> >undefined.
> 
> >clk_disable_unprepare(0xDEADBEEF) ==> kernel panic
> 
> >It does not make sense to add the nps_get_timer_clk() function.
> 
> >Better to have a couple of duplicated lines and properly rollback from the
> >right place instead of rollbacking supposed actions taken from inside a
> >function.
> As I wrote above I will use **clk for the rollback, so nps_get_timer_clk()
> will make sense and avoid code duplication.
> 
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = cpuhp_setup_state(CPUHP_AP_NPS_TIMER_STARTING,
> >> +				"AP_NPS_TIMER_STARTING",
> >> +				nps_timer_starting_cpu,
> >> +				nps_timer_dying_cpu);
> >> +	if (ret) {
> >> +		pr_err("Failed to setup hotplug state");
> >> +		clk_disable_unprepare(clk);
> >> +		return ret;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clkevt, "ezchip,nps400-timer0",
> >> +		       nps_setup_clockevent);
> >> +#endif /* CONFIG_EZNPS_MTM_EXT */
> >> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h 
> >> index 34bd805..9efc1a3 100644
> >> --- a/include/linux/cpuhotplug.h
> >> +++ b/include/linux/cpuhotplug.h
> >> @@ -60,6 +60,7 @@ enum cpuhp_state {
> >> 	CPUHP_AP_MARCO_TIMER_STARTING,
> >>  	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
> >>  	CPUHP_AP_ARC_TIMER_STARTING,
> >> +	CPUHP_AP_NPS_TIMER_STARTING,
> 
> >Oops, wait. Here, arch/arc/kernel/time.c should be moved in
> >drivers/clocksource and consolidated with this driver.
> 
> >Very likely, CPUHP_AP_ARC_TIMER_STARTING can be used for all ARC timers.
> 
> Indeed the ARC timer driver served as my inspiration but due to HW threads
> handling they are not the same.  Moving drivers from arch/arc to
> driver/clocksource is not my call (Vineet Gupta is the maintainer of ARC) And
> I think they quiet differ now so consolidation gain is not obvious.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
@ 2016-11-01 20:01         ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-01 20:01 UTC (permalink / raw)
  To: Noam Camus
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	tglx-hfZtesqFncYOwBW4kG4KsQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Vineet Gupta

On Mon, Oct 31, 2016 at 05:03:40PM +0000, Noam Camus wrote:
> >From: Daniel Lezcano [mailto:daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org] 
> >Sent: Monday, October 31, 2016 12:53 PM
> 
> >> 
> >> The design idea is that for each core there is dedicated regirtser
> 
> >s/regirtser/register/
> 
> >Hey ! re-read yourself.
> Thanks, I do but sometimes reading over and over and still left with such typos
> Will Fix on next patch Set V4
> 
> >> (TSI) serving all 16 HW threads.
> >> The register is a bitmask with one bit for each HW thread.
> >> When HW thread wants that next expiration of timer interrupt will hit 
> >> it then the proper bit should be set in this dedicated register.
> 
> >I'm not sure to understand this sentence. Do you mean each cpu/thread must
> >set a flag in the TSI register at BIT(phys_id) when they set a timer ?
> Correct, each thread needs to set its bit in TSI register, otherwise the he
> won't be interrupted by timer.
> 
> >> When timer expires all HW threads within this core which their bit is 
> >> set at the TSI register will be interrupted.
> 
> >Does it mean some HW threads will be wake up for nothing ?
> See below after the example you gave
> 
> >eg. 
> 
> >HWT1 sets the timer to expire within 2 seconds
> >HWT2 sets the timer to expire within 2 hours
> 
> >When the first timer expires, that will wake up HWT1 *and* HWT2 ?
> 
> You are correct, indeed not optimal but much simpler than managing book
> keeping of all 16 threads.  Functionality wise one who registered this timer
> will notice that it expired too soon and will register a new one.  This is how
> it works now in our machines.

Assuming cpu0 and cpu1 are sibling, does

taskset 0x1 time sleep 2 & taskset 0x2 time sleep 3

give a correct result without a dmesg log ?

Can you give the content of the /proc/timer_list ?

I'm not sure it is safe to have this kind of spurious interrupt for the time
framework.

> >The code is a bit confusing because of the very specific design of this timer.
> 
> >Below more questions for clarification.
> 
> ...
> >> diff --git a/drivers/clocksource/timer-nps.c 
> >> b/drivers/clocksource/timer-nps.c index 6156e54..0757328 100644
> >> --- a/drivers/clocksource/timer-nps.c
> >> +++ b/drivers/clocksource/timer-nps.c
> >> @@ -46,7 +46,7 @@
> >>  /* This array is per cluster of CPUs (Each NPS400 cluster got 256 
> >> CPUs) */  static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] 
> >> __read_mostly;
> >>  
> >> -static unsigned long nps_timer_rate;
> >> +static unsigned long nps_timer1_freq;
> >
> >Why declare a global static variable for a local use in nps_setup_clocksource ? 
> Indeed no need. It will be fixed at V4
> 
> ...
> >> +/* Timer related Aux registers */
> >> +#define AUX_REG_TIMER0_TSI	0xFFFFF850	/* timer 0 HW threads mask */
> >> +#define NPS_REG_TIMER0_LIMIT	0x23		/* timer 0 limit */
> >> +#define NPS_REG_TIMER0_CTRL	0x22		/* timer 0 control */
> >> +#define NPS_REG_TIMER0_CNT	0x21		/* timer 0 count */
> >> +
> >> +#define TIMER0_CTRL_IE	(1 << 0) /* Interrupt when Count reaches limit */
> >> +#define TIMER0_CTRL_NH	(1 << 1) /* Count only when CPU NOT halted */
> 
> >Please, use BIT(nr) macro.
> Will fix that on V4.
> 
> >Can you elaborate "Count only when CPU NOT halted" ?
> The Idea here is:
> The Not Halted mode flag (NH) causes cycles to be counted only when the
> processor is running (not halted). When set to 0 the timer will count every
> clock cycle. When set to 1 the timer will only count when the processor is
> running. The NH flag is set to 0 when the processor is Reset.

When is the processor halted ? At idle time ?

There is an inconsistency here:

 - If the power management of the CPU allows to power it down and the timer
   belongs to the same power domain to the CPU, then it will be powered down
   also. In this case, the C3STOP flag must be used and the CPU wakeup must be
   delegated to a backup timer.

 - If there is no power management on the CPU. The timer must continue to
   count cycles in order to wake up the CPU if it is halted (assuming it
   is clock gated).

In both cases, TIMER0_CTRL_NH is not needed.

Or is the CPU halted *only* when debugging it ?

> It may be used when working with JTAG (I never used it this way though).
> 
> >> +static unsigned long nps_timer0_freq; static unsigned long 
> >> +nps_timer0_irq;
> >> +
> >> +/*
> >> + * Arm the timer to interrupt after @cycles  */ static void 
> >> +nps_clkevent_timer_event_setup(unsigned int cycles) {
> >> +	write_aux_reg(NPS_REG_TIMER0_LIMIT, cycles);
> >> +	write_aux_reg(NPS_REG_TIMER0_CNT, 0);   /* start from 0 */
> >> +
> >> +	write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_IE | TIMER0_CTRL_NH); 
> >> +}
> >> +
> >> +static void nps_clkevent_rm_thread(bool remove_thread) {
> >> +	unsigned int cflags;
> >> +	unsigned int enabled_threads;
> >> +	unsigned long flags;
> >> +	int thread;
> >> +
> >> +	local_irq_save(flags);
> >> +	hw_schd_save(&cflags);
> >
> >Can you explain why those two lines are needed ?
> The idea is that access to shared core registers (among threads) is not done
> in parallel to keep their consistency.  For example Read Modified Write of TSI
> register is not atomic, so using two lines above avoid any interference during
> this code execution.

Mmmh, I'm not used to hardware scheduling. Why hw_schd_save() is needed ?

regmap provides the API to deal with read/write of shared register.

> >> +
> >> +static int nps_clkevent_set_next_event(unsigned long delta,
> >> +				       struct clock_event_device *dev) {
> >> +	struct irq_desc *desc = irq_to_desc(nps_timer0_irq);
> >> +	struct irq_chip *chip = irq_data_get_irq_chip(&desc->irq_data);
> >> +
> >> +	nps_clkevent_add_thread(true);
> >> +	chip->irq_unmask(&desc->irq_data);
> 
> >Can you explain why invoking low level IRQ callbacks is needed here ?
> I needed those callbacks functionality and didn't want to duplicate it here.

If you need these callbacks here, then there is probably an issue with the
driver design.

> >> +
> >> +static int nps_clkevent_set_periodic(struct clock_event_device *dev) 
> >> +{
> >> +	nps_clkevent_add_thread(false);
> >> +	if (read_aux_reg(CTOP_AUX_THREAD_ID) == 0)
> >> +		nps_clkevent_timer_event_setup(nps_timer0_freq / HZ);
> 
> >Please explain this. I read only CPU0 can set the periodic timer.
> When system works in periodic mode for clock events we just need to set for
> all HW threads within same core their respective bit at TSI register.  We also
> need but only once to arm the shared timer control register.  Since that for
> each core thread 0 is always available we choose HW thread 0 to do that.  ...

I see. Please, add the explanation as a comment in the code.

> >> +static int __init nps_setup_clockevent(struct device_node *node) {
> >> +	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
> >> +	struct clk *clk;
> 
> >clk = 0xDEADBEEF
> >> +	int ret;
> >> +
> >> +	nps_timer0_irq = irq_of_parse_and_map(node, 0);
> >> +	if (nps_timer0_irq <= 0) {
> >> +		pr_err("clockevent: missing irq");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	nps_get_timer_clk(node, &nps_timer0_freq, clk);
> >> +
> >> +	/* Needs apriori irq_set_percpu_devid() done in intc map function */
> >> +	ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
> >> +				 "Timer0 (per-cpu-tick)", evt);
> >> +	if (ret) {
> >> +		pr_err("Couldn't request irq\n");
> >> +		clk_disable_unprepare(clk);
> 
> >clk is on the stack, hence returning back from the function, clk is
> >undefined.
> 
> >clk_disable_unprepare(0xDEADBEEF) ==> kernel panic
> 
> >It does not make sense to add the nps_get_timer_clk() function.
> 
> >Better to have a couple of duplicated lines and properly rollback from the
> >right place instead of rollbacking supposed actions taken from inside a
> >function.
> As I wrote above I will use **clk for the rollback, so nps_get_timer_clk()
> will make sense and avoid code duplication.
> 
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = cpuhp_setup_state(CPUHP_AP_NPS_TIMER_STARTING,
> >> +				"AP_NPS_TIMER_STARTING",
> >> +				nps_timer_starting_cpu,
> >> +				nps_timer_dying_cpu);
> >> +	if (ret) {
> >> +		pr_err("Failed to setup hotplug state");
> >> +		clk_disable_unprepare(clk);
> >> +		return ret;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clkevt, "ezchip,nps400-timer0",
> >> +		       nps_setup_clockevent);
> >> +#endif /* CONFIG_EZNPS_MTM_EXT */
> >> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h 
> >> index 34bd805..9efc1a3 100644
> >> --- a/include/linux/cpuhotplug.h
> >> +++ b/include/linux/cpuhotplug.h
> >> @@ -60,6 +60,7 @@ enum cpuhp_state {
> >> 	CPUHP_AP_MARCO_TIMER_STARTING,
> >>  	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
> >>  	CPUHP_AP_ARC_TIMER_STARTING,
> >> +	CPUHP_AP_NPS_TIMER_STARTING,
> 
> >Oops, wait. Here, arch/arc/kernel/time.c should be moved in
> >drivers/clocksource and consolidated with this driver.
> 
> >Very likely, CPUHP_AP_ARC_TIMER_STARTING can be used for all ARC timers.
> 
> Indeed the ARC timer driver served as my inspiration but due to HW threads
> handling they are not the same.  Moving drivers from arch/arc to
> driver/clocksource is not my call (Vineet Gupta is the maintainer of ARC) And
> I think they quiet differ now so consolidation gain is not obvious.


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-01 20:42               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-01 20:42 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:16PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---
>  MAINTAINERS                                        |  1 +
>  arch/arc/Kconfig                                   | 12 +--------
>  arch/arc/kernel/Makefile                           |  2 +-
>  drivers/clocksource/Kconfig                        | 24 ++++++++++++++++++
>  drivers/clocksource/Makefile                       |  1 +
>  .../time.c => drivers/clocksource/arc_timer.c      | 29 ++++++----------------
>  6 files changed, 35 insertions(+), 34 deletions(-)
>  rename arch/arc/kernel/time.c => drivers/clocksource/arc_timer.c (90%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3d838cf49f81..57b56ff1dd68 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11632,6 +11632,7 @@ S:	Supported
>  F:	arch/arc/
>  F:	Documentation/devicetree/bindings/arc/*
>  F:	Documentation/devicetree/bindings/interrupt-controller/snps,arc*
> +F:	drivers/clocksource/arc_timer.c
>  F:	drivers/tty/serial/arc_uart.c
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
>  
> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
> index b4499f97035a..8768a509d5e7 100644
> --- a/arch/arc/Kconfig
> +++ b/arch/arc/Kconfig
> @@ -8,9 +8,9 @@
>  
>  config ARC
>  	def_bool y
> +	select ARC_TIMER
>  	select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
>  	select BUILDTIME_EXTABLE_SORT
> -	select CLKSRC_OF
>  	select CLONE_BACKWARDS
>  	select COMMON_CLK
>  	select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
> @@ -410,16 +410,6 @@ config ARC_HAS_DIV_REM
>  	bool "Insn: div, divu, rem, remu"
>  	default y
>  
> -config ARC_TIMER_RTC
> -	bool "Local 64-bit r/o cycle counter"
> -	default n
> -	depends on !SMP
> -
> -config ARC_TIMER_GFRC
> -	bool "SMP synchronized 64-bit cycle counter"
> -	default y
> -	depends on SMP
> -
>  config ARC_NUMBER_OF_INTERRUPTS
>  	int "Number of interrupts"
>  	range 8 240
> diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
> index cfcdedf52ff8..8942c5c3b4c5 100644
> --- a/arch/arc/kernel/Makefile
> +++ b/arch/arc/kernel/Makefile
> @@ -8,7 +8,7 @@
>  # Pass UTS_MACHINE for user_regset definition
>  CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
>  
> -obj-y	:= arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
> +obj-y	:= arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
>  obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
>  obj-$(CONFIG_ISA_ARCOMPACT)		+= entry-compact.o intc-compact.o
>  obj-$(CONFIG_ISA_ARCV2)			+= entry-arcv2.o intc-arcv2.o
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index e2c6e43cf8ca..73feaadc1924 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -282,6 +282,30 @@ config CLKSRC_MPS2
>  	select CLKSRC_MMIO
>  	select CLKSRC_OF
>  
> +config ARC_TIMER
> +	bool "Enable timers for ARC Cores"
> +	select CLKSRC_OF if OF
> +
> +if ARC_TIMER
> +
> +config ARC_TIMER_RTC
> +	bool "64-bit cycle counter in HS38 cores"
> +	default y if ARC
> +	depends on !SMP
> +	help
> +	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> +	  It is implemented inside the core thus can't be used in SMP systems
> +
> +config ARC_TIMER_GFRC
> +	bool "64-bit cycle counter in ARConnect block in HS38x cores"
> +	default y if ARC
> +	depends on SMP
> +	help
> +	  This counter can be used as clocksource in SMP HS38 SoCs.
> +	  It sits outside the core thus can be used in SMP systems
> +
> +endif
> +

Please stay consistent with the rest of the Kconfig.

config ARC_TIMER_RTC
	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
	select CLKSRC_OF
	help
	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
	  It is implemented inside the core thus can't be used in SMP systems.

config ARC_TIMER_GFRC
	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
	select CLKSRC_OF
	help
	  This counter can be used as clocksource in SMP HS38 SoCs.
	  It sits outside the core thus can be used in SMP systems


Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
it is SMP or not.

One question:

Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
own clocksource ? It seems you are assuming a clocksource can be used on SMP
only if the clocksource is unique and shared across the cores.


>  config ARM_ARCH_TIMER
>  	bool
>  	select CLKSRC_OF if OF
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index cf87f407f1ad..e78480cb47f4 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -69,3 +69,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
>  obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
>  obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
>  obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
> +obj-$(CONFIG_ARC_TIMER)			+= arc_timer.o
> diff --git a/arch/arc/kernel/time.c b/drivers/clocksource/arc_timer.c
> similarity index 90%
> rename from arch/arc/kernel/time.c
> rename to drivers/clocksource/arc_timer.c
> index 676b14b7a9be..ec37b6c5e903 100644
> --- a/arch/arc/kernel/time.c
> +++ b/drivers/clocksource/arc_timer.c
> @@ -1,32 +1,18 @@
>  /*
> + * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
>   * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
> - *
> - * vineetg: Jan 1011
> - *  -sched_clock( ) no longer jiffies based. Uses the same clocksource
> - *   as gtod
> - *
> - * Rajeshwarr/Vineetg: Mar 2008
> - *  -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
> - *   for arch independent gettimeofday()
> - *  -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
> - *
> - * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
>   */
>  
> -/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
> - * Each can programmed to go from @count to @limit and optionally
> - * interrupt when that happens.
> - * A write to Control Register clears the Interrupt
> - *
> - * We've designated TIMER0 for events (clockevents)
> - * while TIMER1 for free running (clocksource)
> +/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be
> + * programmed to go from @count to @limit and optionally interrupt.
> + * We've designated TIMER0 for clockevents and TIMER1 for clocksource
>   *
> - * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
> - * which however is currently broken
> + * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP)
> + * which are suitable for UP and SMP based clocksources respectively
>   */
>  
>  #include <linux/interrupt.h>
> @@ -37,7 +23,6 @@
>  #include <linux/cpu.h>
>  #include <linux/of.h>
>  #include <linux/of_irq.h>
> -#include <asm/irq.h>
>  
>  #include <soc/arc/timers.h>
>  #include <soc/arc/mcip.h>
> @@ -281,7 +266,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
>  	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
>  	 */
>  	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
> -	int irq_reenable = clockevent_state_periodic(evt);
> +	int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
>  
>  	/*
>  	 * Any write to CTRL reg ACks the interrupt, we rewrite the
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-01 20:42               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-01 20:42 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:16PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  MAINTAINERS                                        |  1 +
>  arch/arc/Kconfig                                   | 12 +--------
>  arch/arc/kernel/Makefile                           |  2 +-
>  drivers/clocksource/Kconfig                        | 24 ++++++++++++++++++
>  drivers/clocksource/Makefile                       |  1 +
>  .../time.c => drivers/clocksource/arc_timer.c      | 29 ++++++----------------
>  6 files changed, 35 insertions(+), 34 deletions(-)
>  rename arch/arc/kernel/time.c => drivers/clocksource/arc_timer.c (90%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3d838cf49f81..57b56ff1dd68 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11632,6 +11632,7 @@ S:	Supported
>  F:	arch/arc/
>  F:	Documentation/devicetree/bindings/arc/*
>  F:	Documentation/devicetree/bindings/interrupt-controller/snps,arc*
> +F:	drivers/clocksource/arc_timer.c
>  F:	drivers/tty/serial/arc_uart.c
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
>  
> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
> index b4499f97035a..8768a509d5e7 100644
> --- a/arch/arc/Kconfig
> +++ b/arch/arc/Kconfig
> @@ -8,9 +8,9 @@
>  
>  config ARC
>  	def_bool y
> +	select ARC_TIMER
>  	select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
>  	select BUILDTIME_EXTABLE_SORT
> -	select CLKSRC_OF
>  	select CLONE_BACKWARDS
>  	select COMMON_CLK
>  	select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
> @@ -410,16 +410,6 @@ config ARC_HAS_DIV_REM
>  	bool "Insn: div, divu, rem, remu"
>  	default y
>  
> -config ARC_TIMER_RTC
> -	bool "Local 64-bit r/o cycle counter"
> -	default n
> -	depends on !SMP
> -
> -config ARC_TIMER_GFRC
> -	bool "SMP synchronized 64-bit cycle counter"
> -	default y
> -	depends on SMP
> -
>  config ARC_NUMBER_OF_INTERRUPTS
>  	int "Number of interrupts"
>  	range 8 240
> diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
> index cfcdedf52ff8..8942c5c3b4c5 100644
> --- a/arch/arc/kernel/Makefile
> +++ b/arch/arc/kernel/Makefile
> @@ -8,7 +8,7 @@
>  # Pass UTS_MACHINE for user_regset definition
>  CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
>  
> -obj-y	:= arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
> +obj-y	:= arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
>  obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
>  obj-$(CONFIG_ISA_ARCOMPACT)		+= entry-compact.o intc-compact.o
>  obj-$(CONFIG_ISA_ARCV2)			+= entry-arcv2.o intc-arcv2.o
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index e2c6e43cf8ca..73feaadc1924 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -282,6 +282,30 @@ config CLKSRC_MPS2
>  	select CLKSRC_MMIO
>  	select CLKSRC_OF
>  
> +config ARC_TIMER
> +	bool "Enable timers for ARC Cores"
> +	select CLKSRC_OF if OF
> +
> +if ARC_TIMER
> +
> +config ARC_TIMER_RTC
> +	bool "64-bit cycle counter in HS38 cores"
> +	default y if ARC
> +	depends on !SMP
> +	help
> +	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> +	  It is implemented inside the core thus can't be used in SMP systems
> +
> +config ARC_TIMER_GFRC
> +	bool "64-bit cycle counter in ARConnect block in HS38x cores"
> +	default y if ARC
> +	depends on SMP
> +	help
> +	  This counter can be used as clocksource in SMP HS38 SoCs.
> +	  It sits outside the core thus can be used in SMP systems
> +
> +endif
> +

Please stay consistent with the rest of the Kconfig.

config ARC_TIMER_RTC
	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
	select CLKSRC_OF
	help
	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
	  It is implemented inside the core thus can't be used in SMP systems.

config ARC_TIMER_GFRC
	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
	select CLKSRC_OF
	help
	  This counter can be used as clocksource in SMP HS38 SoCs.
	  It sits outside the core thus can be used in SMP systems


Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
it is SMP or not.

One question:

Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
own clocksource ? It seems you are assuming a clocksource can be used on SMP
only if the clocksource is unique and shared across the cores.


>  config ARM_ARCH_TIMER
>  	bool
>  	select CLKSRC_OF if OF
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index cf87f407f1ad..e78480cb47f4 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -69,3 +69,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
>  obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
>  obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
>  obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
> +obj-$(CONFIG_ARC_TIMER)			+= arc_timer.o
> diff --git a/arch/arc/kernel/time.c b/drivers/clocksource/arc_timer.c
> similarity index 90%
> rename from arch/arc/kernel/time.c
> rename to drivers/clocksource/arc_timer.c
> index 676b14b7a9be..ec37b6c5e903 100644
> --- a/arch/arc/kernel/time.c
> +++ b/drivers/clocksource/arc_timer.c
> @@ -1,32 +1,18 @@
>  /*
> + * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
>   * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
> - *
> - * vineetg: Jan 1011
> - *  -sched_clock( ) no longer jiffies based. Uses the same clocksource
> - *   as gtod
> - *
> - * Rajeshwarr/Vineetg: Mar 2008
> - *  -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
> - *   for arch independent gettimeofday()
> - *  -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
> - *
> - * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
>   */
>  
> -/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
> - * Each can programmed to go from @count to @limit and optionally
> - * interrupt when that happens.
> - * A write to Control Register clears the Interrupt
> - *
> - * We've designated TIMER0 for events (clockevents)
> - * while TIMER1 for free running (clocksource)
> +/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be
> + * programmed to go from @count to @limit and optionally interrupt.
> + * We've designated TIMER0 for clockevents and TIMER1 for clocksource
>   *
> - * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
> - * which however is currently broken
> + * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP)
> + * which are suitable for UP and SMP based clocksources respectively
>   */
>  
>  #include <linux/interrupt.h>
> @@ -37,7 +23,6 @@
>  #include <linux/cpu.h>
>  #include <linux/of.h>
>  #include <linux/of_irq.h>
> -#include <asm/irq.h>
>  
>  #include <soc/arc/timers.h>
>  #include <soc/arc/mcip.h>
> @@ -281,7 +266,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
>  	 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
>  	 */
>  	struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
> -	int irq_reenable = clockevent_state_periodic(evt);
> +	int irq_reenable __maybe_unused = clockevent_state_periodic(evt);
>  
>  	/*
>  	 * Any write to CTRL reg ACks the interrupt, we rewrite the
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-01 20:42               ` Daniel Lezcano
@ 2016-11-01 20:57                 ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-01 20:57 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

Hi Daniel,

On 11/01/2016 01:42 PM, Daniel Lezcano wrote:
> Please stay consistent with the rest of the Kconfig.
> 
> config ARC_TIMER_RTC
> 	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
> 	select CLKSRC_OF
> 	help
> 	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> 	  It is implemented inside the core thus can't be used in SMP systems.
> 
> config ARC_TIMER_GFRC
> 	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
> 	select CLKSRC_OF
> 	help
> 	  This counter can be used as clocksource in SMP HS38 SoCs.
> 	  It sits outside the core thus can be used in SMP systems
> 

Yes I did so already :-) Although I also added a default y if ARC to both, but as
you say that is better done in ARC Kconfig.

> Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
> it is SMP or not.
> 
> One question:
> 
> Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
> own clocksource ? It seems you are assuming a clocksource can be used on SMP
> only if the clocksource is unique and shared across the cores.

Thats what I thought so far. Thing is, the individual core's counters could get
out of sync, simply because non masters cores were halted to begin with and came
up at different points in real time. so a gtod might return different value
depending on what core it landed on. Does clocksource also does ticks broadcasts
and such to keep things in sync ?

Because of the git mv you, diff didn't include bulk of driver code which would
make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?

Thx,
-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-01 20:57                 ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-01 20:57 UTC (permalink / raw)
  To: linux-snps-arc

Hi Daniel,

On 11/01/2016 01:42 PM, Daniel Lezcano wrote:
> Please stay consistent with the rest of the Kconfig.
> 
> config ARC_TIMER_RTC
> 	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
> 	select CLKSRC_OF
> 	help
> 	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> 	  It is implemented inside the core thus can't be used in SMP systems.
> 
> config ARC_TIMER_GFRC
> 	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
> 	select CLKSRC_OF
> 	help
> 	  This counter can be used as clocksource in SMP HS38 SoCs.
> 	  It sits outside the core thus can be used in SMP systems
> 

Yes I did so already :-) Although I also added a default y if ARC to both, but as
you say that is better done in ARC Kconfig.

> Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
> it is SMP or not.
> 
> One question:
> 
> Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
> own clocksource ? It seems you are assuming a clocksource can be used on SMP
> only if the clocksource is unique and shared across the cores.

Thats what I thought so far. Thing is, the individual core's counters could get
out of sync, simply because non masters cores were halted to begin with and came
up at different points in real time. so a gtod might return different value
depending on what core it landed on. Does clocksource also does ticks broadcasts
and such to keep things in sync ?

Because of the git mv you, diff didn't include bulk of driver code which would
make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?

Thx,
-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-01 20:57                 ` Vineet Gupta
@ 2016-11-02  0:19                   ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-02  0:19 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Tue, Nov 01, 2016 at 01:57:05PM -0700, Vineet Gupta wrote:
> Hi Daniel,
> 
> On 11/01/2016 01:42 PM, Daniel Lezcano wrote:
> > Please stay consistent with the rest of the Kconfig.
> > 
> > config ARC_TIMER_RTC
> > 	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> > 	  It is implemented inside the core thus can't be used in SMP systems.
> > 
> > config ARC_TIMER_GFRC
> > 	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter can be used as clocksource in SMP HS38 SoCs.
> > 	  It sits outside the core thus can be used in SMP systems
> > 
> 
> Yes I did so already :-) Although I also added a default y if ARC to both, but as
> you say that is better done in ARC Kconfig.
> 
> > Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
> > it is SMP or not.
> > 
> > One question:
> > 
> > Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
> > own clocksource ? It seems you are assuming a clocksource can be used on SMP
> > only if the clocksource is unique and shared across the cores.
> 
> Thats what I thought so far. Thing is, the individual core's counters could get
> out of sync, simply because non masters cores were halted to begin with and came
> up at different points in real time. so a gtod might return different value
> depending on what core it landed on. Does clocksource also does ticks broadcasts
> and such to keep things in sync ?

Sounds like it is similar than the TSC. Do you agree to have a try by setting
the CONFIG_HAVE_UNSTABLE_SCHED_CLOCK option ?

If you can use those per cpu clocksource, performances on your system may
improve with the sched_clock().
 
> Because of the git mv you, diff didn't include bulk of driver code which would
> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?

That means I will review and comment existing code. It is not a problem for me
if you agree to do the changes.

  -- Daniel

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-02  0:19                   ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-02  0:19 UTC (permalink / raw)
  To: linux-snps-arc

On Tue, Nov 01, 2016@01:57:05PM -0700, Vineet Gupta wrote:
> Hi Daniel,
> 
> On 11/01/2016 01:42 PM, Daniel Lezcano wrote:
> > Please stay consistent with the rest of the Kconfig.
> > 
> > config ARC_TIMER_RTC
> > 	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> > 	  It is implemented inside the core thus can't be used in SMP systems.
> > 
> > config ARC_TIMER_GFRC
> > 	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter can be used as clocksource in SMP HS38 SoCs.
> > 	  It sits outside the core thus can be used in SMP systems
> > 
> 
> Yes I did so already :-) Although I also added a default y if ARC to both, but as
> you say that is better done in ARC Kconfig.
> 
> > Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
> > it is SMP or not.
> > 
> > One question:
> > 
> > Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
> > own clocksource ? It seems you are assuming a clocksource can be used on SMP
> > only if the clocksource is unique and shared across the cores.
> 
> Thats what I thought so far. Thing is, the individual core's counters could get
> out of sync, simply because non masters cores were halted to begin with and came
> up at different points in real time. so a gtod might return different value
> depending on what core it landed on. Does clocksource also does ticks broadcasts
> and such to keep things in sync ?

Sounds like it is similar than the TSC. Do you agree to have a try by setting
the CONFIG_HAVE_UNSTABLE_SCHED_CLOCK option ?

If you can use those per cpu clocksource, performances on your system may
improve with the sched_clock().
 
> Because of the git mv you, diff didn't include bulk of driver code which would
> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?

That means I will review and comment existing code. It is not a problem for me
if you agree to do the changes.

  -- Daniel

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-02  0:19                   ` Daniel Lezcano
@ 2016-11-02  1:03                     ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-02  1:03 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On 11/01/2016 05:19 PM, Daniel Lezcano wrote:
>>>
>>> One question:
>>>
>>> Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
>>> own clocksource ? It seems you are assuming a clocksource can be used on SMP
>>> only if the clocksource is unique and shared across the cores.
>>
>> Thats what I thought so far. Thing is, the individual core's counters could get
>> out of sync, simply because non masters cores were halted to begin with and came
>> up at different points in real time. so a gtod might return different value
>> depending on what core it landed on. Does clocksource also does ticks broadcasts
>> and such to keep things in sync ?
> 
> Sounds like it is similar than the TSC. Do you agree to have a try by setting
> the CONFIG_HAVE_UNSTABLE_SCHED_CLOCK option ?

I'm not sure why we would want to enable extra stuff - I see work queues and bunch
of per cpu counting / math to adjust for the variance, if this was enabled. Anyhow
see more below.

> If you can use those per cpu clocksource, performances on your system may
> improve with the sched_clock().

Couple of things

1. Currently we don't hookup sched clock to any counter at all (on my todo list
for a while). So we only get jiffies64 based value - I know that sucks - causes
scheduling to be not super accurate etc - potentially affects benchmarks etc - but
that can be fixed easily / independent of this.

2. Say we did have sched_clock() driven by hardware - in SMP system I would still
prefer it to be driven by "common" GFRC and not "per cpu" RTC. The overhead of
HAVE_UNSTABLE_SCHED_CLOCK looks way way more than reading GFRC counter like this.

	local_irq_save(flags);

	__mcip_cmd(CMD_GFRC_READ_LO, 0);
	stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK);

	__mcip_cmd(CMD_GFRC_READ_HI, 0);
	stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK);

	local_irq_restore(flags);

GFRC reading by 2 cores concurrently doesn't require any synchronization at all.
The irq disabling around it is to make sure we didn't get a bogus readout lest an
interrupt came in between the read of 2 words. But if sched_clock can guarantee
that irqs are disable - I can probably even remove it at least for the purpose of
sched clock.

However I think we are digressing here a bit. IMHO, what clock we choose to drive
sched should not really be driven by the driver. It must be for the arch to decide.

We should first focus on how the clockevent/sources are programmed first and then
dive into sched_clock_xx as that doesn't exist at the moment for ARC.

>  
>> Because of the git mv you, diff didn't include bulk of driver code which would
>> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
> 
> That means I will review and comment existing code. It is not a problem for me
> if you agree to do the changes.

Sure, the whole point is to make things better as an outcome of review. I have no
issues changing code provided we don't add major performance regressions.

Thx,
-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-02  1:03                     ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-02  1:03 UTC (permalink / raw)
  To: linux-snps-arc

On 11/01/2016 05:19 PM, Daniel Lezcano wrote:
>>>
>>> One question:
>>>
>>> Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
>>> own clocksource ? It seems you are assuming a clocksource can be used on SMP
>>> only if the clocksource is unique and shared across the cores.
>>
>> Thats what I thought so far. Thing is, the individual core's counters could get
>> out of sync, simply because non masters cores were halted to begin with and came
>> up at different points in real time. so a gtod might return different value
>> depending on what core it landed on. Does clocksource also does ticks broadcasts
>> and such to keep things in sync ?
> 
> Sounds like it is similar than the TSC. Do you agree to have a try by setting
> the CONFIG_HAVE_UNSTABLE_SCHED_CLOCK option ?

I'm not sure why we would want to enable extra stuff - I see work queues and bunch
of per cpu counting / math to adjust for the variance, if this was enabled. Anyhow
see more below.

> If you can use those per cpu clocksource, performances on your system may
> improve with the sched_clock().

Couple of things

1. Currently we don't hookup sched clock to any counter at all (on my todo list
for a while). So we only get jiffies64 based value - I know that sucks - causes
scheduling to be not super accurate etc - potentially affects benchmarks etc - but
that can be fixed easily / independent of this.

2. Say we did have sched_clock() driven by hardware - in SMP system I would still
prefer it to be driven by "common" GFRC and not "per cpu" RTC. The overhead of
HAVE_UNSTABLE_SCHED_CLOCK looks way way more than reading GFRC counter like this.

	local_irq_save(flags);

	__mcip_cmd(CMD_GFRC_READ_LO, 0);
	stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK);

	__mcip_cmd(CMD_GFRC_READ_HI, 0);
	stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK);

	local_irq_restore(flags);

GFRC reading by 2 cores concurrently doesn't require any synchronization at all.
The irq disabling around it is to make sure we didn't get a bogus readout lest an
interrupt came in between the read of 2 words. But if sched_clock can guarantee
that irqs are disable - I can probably even remove it at least for the purpose of
sched clock.

However I think we are digressing here a bit. IMHO, what clock we choose to drive
sched should not really be driven by the driver. It must be for the arch to decide.

We should first focus on how the clockevent/sources are programmed first and then
dive into sched_clock_xx as that doesn't exist at the moment for ARC.

>  
>> Because of the git mv you, diff didn't include bulk of driver code which would
>> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
> 
> That means I will review and comment existing code. It is not a problem for me
> if you agree to do the changes.

Sure, the whole point is to make things better as an outcome of review. I have no
issues changing code provided we don't add major performance regressions.

Thx,
-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-02  1:03                     ` Vineet Gupta
@ 2016-11-03 16:40                       ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 16:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On 11/01/2016 06:03 PM, Vineet Gupta wrote:
>>> Because of the git mv you, diff didn't include bulk of driver code which would
>>> >> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
>> > 
>> > That means I will review and comment existing code. It is not a problem for me
>> > if you agree to do the changes.
> Sure, the whole point is to make things better as an outcome of review. I have no
> issues changing code provided we don't add major performance regressions.

So just wondering if I could have some comments on the initial import of driver
before I send out a v2.

The issue is git mv didn't show bulk of code being moved. Shall I send a v2 with a
different ordering so I introduce the driver first, with new headers, new Kconfig
items etc and then as a subsequent patch prune those bits from arch/arc/* ?

-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 16:40                       ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 16:40 UTC (permalink / raw)
  To: linux-snps-arc

On 11/01/2016 06:03 PM, Vineet Gupta wrote:
>>> Because of the git mv you, diff didn't include bulk of driver code which would
>>> >> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
>> > 
>> > That means I will review and comment existing code. It is not a problem for me
>> > if you agree to do the changes.
> Sure, the whole point is to make things better as an outcome of review. I have no
> issues changing code provided we don't add major performance regressions.

So just wondering if I could have some comments on the initial import of driver
before I send out a v2.

The issue is git mv didn't show bulk of code being moved. Shall I send a v2 with a
different ordering so I introduce the driver first, with new headers, new Kconfig
items etc and then as a subsequent patch prune those bits from arch/arc/* ?

-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-03 16:40                       ` Vineet Gupta
@ 2016-11-03 16:50                         ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 16:50 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Thu, Nov 03, 2016 at 09:40:23AM -0700, Vineet Gupta wrote:
> On 11/01/2016 06:03 PM, Vineet Gupta wrote:
> >>> Because of the git mv you, diff didn't include bulk of driver code which would
> >>> >> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
> >> > 
> >> > That means I will review and comment existing code. It is not a problem for me
> >> > if you agree to do the changes.
> > Sure, the whole point is to make things better as an outcome of review. I have no
> > issues changing code provided we don't add major performance regressions.
> 
> So just wondering if I could have some comments on the initial import of driver
> before I send out a v2.

Yeah, ok. Let me comment the other patches of the series and then you can send a V2.
 
> The issue is git mv didn't show bulk of code being moved. Shall I send a v2 with a
> different ordering so I introduce the driver first, with new headers, new Kconfig
> items etc and then as a subsequent patch prune those bits from arch/arc/* ?
> 
> -Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 16:50                         ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 16:50 UTC (permalink / raw)
  To: linux-snps-arc

On Thu, Nov 03, 2016@09:40:23AM -0700, Vineet Gupta wrote:
> On 11/01/2016 06:03 PM, Vineet Gupta wrote:
> >>> Because of the git mv you, diff didn't include bulk of driver code which would
> >>> >> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
> >> > 
> >> > That means I will review and comment existing code. It is not a problem for me
> >> > if you agree to do the changes.
> > Sure, the whole point is to make things better as an outcome of review. I have no
> > issues changing code provided we don't add major performance regressions.
> 
> So just wondering if I could have some comments on the initial import of driver
> before I send out a v2.

Yeah, ok. Let me comment the other patches of the series and then you can send a V2.
 
> The issue is git mv didn't show bulk of code being moved. Shall I send a v2 with a
> different ordering so I introduce the driver first, with new headers, new Kconfig
> items etc and then as a subsequent patch prune those bits from arch/arc/* ?
> 
> -Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-03 17:00               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:00 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:08PM -0700, Vineet Gupta wrote:
> ... don't rely on cpuinfo populated in arc boot code. This paves wat for
> moving this code in drivers/clocksource/
> 
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---
>  arch/arc/kernel/time.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index f927b8dc6edd..a2db010cde18 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -118,10 +118,11 @@ static struct clocksource arc_counter_gfrc = {
>  
>  static int __init arc_cs_setup_gfrc(struct device_node *node)
>  {
> -	int exists = cpuinfo_arc700[0].extn.gfrc;
> +	struct mcip_bcr mp;
>  	int ret;
>  
> -	if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
> +	READ_BCR(ARC_REG_MCIP_BCR, mp);
> +	if (WARN(!mp.gfrc, "Global-64-bit-Ctr clocksource not detected"))

Take the opportunity to replace this WARN by a pr_err.

>  		return -ENXIO;
>  
>  	ret = arc_get_timer_clk(node);
> @@ -174,10 +175,11 @@ static struct clocksource arc_counter_rtc = {
>  
>  static int __init arc_cs_setup_rtc(struct device_node *node)
>  {
> -	int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
> +	struct bcr_timer timer;
>  	int ret;
>  
> -	if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
> +	READ_BCR(ARC_REG_TIMERS_BCR, timer);
> +	if (WARN(!timer.rtc, "Local-64-bit-Ctr clocksource not detected"))
>  		return -ENXIO;o

Ditto and                    ^^

So the READ_BCR() is only there to check the timer is physically present ?

>  	/* Local to CPU hence not usable in SMP */
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
@ 2016-11-03 17:00               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:00 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:08PM -0700, Vineet Gupta wrote:
> ... don't rely on cpuinfo populated in arc boot code. This paves wat for
> moving this code in drivers/clocksource/
> 
> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  arch/arc/kernel/time.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index f927b8dc6edd..a2db010cde18 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -118,10 +118,11 @@ static struct clocksource arc_counter_gfrc = {
>  
>  static int __init arc_cs_setup_gfrc(struct device_node *node)
>  {
> -	int exists = cpuinfo_arc700[0].extn.gfrc;
> +	struct mcip_bcr mp;
>  	int ret;
>  
> -	if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
> +	READ_BCR(ARC_REG_MCIP_BCR, mp);
> +	if (WARN(!mp.gfrc, "Global-64-bit-Ctr clocksource not detected"))

Take the opportunity to replace this WARN by a pr_err.

>  		return -ENXIO;
>  
>  	ret = arc_get_timer_clk(node);
> @@ -174,10 +175,11 @@ static struct clocksource arc_counter_rtc = {
>  
>  static int __init arc_cs_setup_rtc(struct device_node *node)
>  {
> -	int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
> +	struct bcr_timer timer;
>  	int ret;
>  
> -	if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
> +	READ_BCR(ARC_REG_TIMERS_BCR, timer);
> +	if (WARN(!timer.rtc, "Local-64-bit-Ctr clocksource not detected"))
>  		return -ENXIO;o

Ditto and                    ^^

So the READ_BCR() is only there to check the timer is physically present ?

>  	/* Local to CPU hence not usable in SMP */
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-03 17:02               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:02 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:09PM -0700, Vineet Gupta wrote:
> To allow for easy movement into drivers/clocksource
> 
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---
>  arch/arc/kernel/time.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index a2db010cde18..2c51e3cafad0 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -153,14 +153,11 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
>  		cycle_t  full;
>  	} stamp;
>  
> -
> -	__asm__ __volatile(
> -	"1:						\n"
> -	"	lr		%0, [AUX_RTC_LOW]	\n"
> -	"	lr		%1, [AUX_RTC_HIGH]	\n"
> -	"	lr		%2, [AUX_RTC_CTRL]	\n"
> -	"	bbit0.nt	%2, 31, 1b		\n"
> -	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
> +	do {
> +		stamp.low = read_aux_reg(AUX_RTC_LOW);
> +		stamp.high = read_aux_reg(AUX_RTC_HIGH);
> +		status = read_aux_reg(AUX_RTC_CTRL);
> +	} while (!(status & 0x80000000UL));

Replace the literal 0x80000000UL by a macro.

What is the 'status' for ?
  
>  	return stamp.full;
>  }
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm
@ 2016-11-03 17:02               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:02 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:09PM -0700, Vineet Gupta wrote:
> To allow for easy movement into drivers/clocksource
> 
> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  arch/arc/kernel/time.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index a2db010cde18..2c51e3cafad0 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -153,14 +153,11 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
>  		cycle_t  full;
>  	} stamp;
>  
> -
> -	__asm__ __volatile(
> -	"1:						\n"
> -	"	lr		%0, [AUX_RTC_LOW]	\n"
> -	"	lr		%1, [AUX_RTC_HIGH]	\n"
> -	"	lr		%2, [AUX_RTC_CTRL]	\n"
> -	"	bbit0.nt	%2, 31, 1b		\n"
> -	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
> +	do {
> +		stamp.low = read_aux_reg(AUX_RTC_LOW);
> +		stamp.high = read_aux_reg(AUX_RTC_HIGH);
> +		status = read_aux_reg(AUX_RTC_CTRL);
> +	} while (!(status & 0x80000000UL));

Replace the literal 0x80000000UL by a macro.

What is the 'status' for ?
  
>  	return stamp.full;
>  }
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-03 17:09               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:09 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:10PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

Why not add a message in drivers/clocksource/clksrc-probe.c when a timer inits
successfully ? and then get rid of this code.

> ---
>  arch/arc/kernel/setup.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
> index 0385df77a697..595d06900061 100644
> --- a/arch/arc/kernel/setup.c
> +++ b/arch/arc/kernel/setup.c
> @@ -234,11 +234,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
>  		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
>  		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
>  
> -	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
> +	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
>  		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
>  		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
> -		       IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
> -				 CONFIG_ARC_HAS_RTC));
> +		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
> +		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
>  
>  	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
>  			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
@ 2016-11-03 17:09               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:09 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:10PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>

Why not add a message in drivers/clocksource/clksrc-probe.c when a timer inits
successfully ? and then get rid of this code.

> ---
>  arch/arc/kernel/setup.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
> index 0385df77a697..595d06900061 100644
> --- a/arch/arc/kernel/setup.c
> +++ b/arch/arc/kernel/setup.c
> @@ -234,11 +234,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
>  		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
>  		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
>  
> -	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
> +	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
>  		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
>  		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
> -		       IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
> -				 CONFIG_ARC_HAS_RTC));
> +		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
> +		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
>  
>  	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
>  			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 4/9] ARC: time: move time_init() out of the driver
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-03 17:15               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:15 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:11PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 4/9] ARC: time: move time_init() out of the driver
@ 2016-11-03 17:15               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:15 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:11PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 6/9] ARC: move mcip.h into include/soc and adjust the includes
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-03 17:20               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:20 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:13PM -0700, Vineet Gupta wrote:
> Also remove the depedency on ARCv2, to increase compile coverage for
> !ARCV2 builds

s/depedency/dependency/

Acked-by: Daniel Lezcano <daniel.lezcnao@linaro.org>

> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---
>  arch/arc/kernel/mcip.c                           | 2 +-
>  arch/arc/kernel/time.c                           | 2 +-
>  arch/arc/plat-axs10x/axs10x.c                    | 2 +-
>  {arch/arc/include/asm => include/soc/arc}/mcip.h | 8 ++------
>  4 files changed, 5 insertions(+), 9 deletions(-)
>  rename {arch/arc/include/asm => include/soc/arc}/mcip.h (96%)
> 
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index c424d5abc318..0651e0a2e8b1 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -11,8 +11,8 @@
>  #include <linux/smp.h>
>  #include <linux/irq.h>
>  #include <linux/spinlock.h>
> +#include <soc/arc/mcip.h>
>  #include <asm/irqflags-arcv2.h>
> -#include <asm/mcip.h>
>  #include <asm/setup.h>
>  
>  static DEFINE_RAW_SPINLOCK(mcip_lock);
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index 00ece39a8ae7..f1ebe45bfcdf 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -40,7 +40,7 @@
>  #include <asm/irq.h>
>  #include <asm/arcregs.h>
>  
> -#include <asm/mcip.h>
> +#include <soc/arc/mcip.h>
>  
>  /* Timer related Aux registers */
>  #define ARC_REG_TIMER0_LIMIT	0x23	/* timer 0 limit */
> diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
> index 86548701023c..38ff349d7f2a 100644
> --- a/arch/arc/plat-axs10x/axs10x.c
> +++ b/arch/arc/plat-axs10x/axs10x.c
> @@ -21,7 +21,7 @@
>  #include <asm/asm-offsets.h>
>  #include <asm/io.h>
>  #include <asm/mach_desc.h>
> -#include <asm/mcip.h>
> +#include <soc/arc/mcip.h>
>  
>  #define AXS_MB_CGU		0xE0010000
>  #define AXS_MB_CREG		0xE0011000
> diff --git a/arch/arc/include/asm/mcip.h b/include/soc/arc/mcip.h
> similarity index 96%
> rename from arch/arc/include/asm/mcip.h
> rename to include/soc/arc/mcip.h
> index fc28d0944801..6902c2a8bd23 100644
> --- a/arch/arc/include/asm/mcip.h
> +++ b/include/soc/arc/mcip.h
> @@ -8,10 +8,8 @@
>   * published by the Free Software Foundation.
>   */
>  
> -#ifndef __ASM_MCIP_H
> -#define __ASM_MCIP_H
> -
> -#ifdef CONFIG_ISA_ARCV2
> +#ifndef __SOC_ARC_MCIP_H
> +#define __SOC_ARC_MCIP_H
>  
>  #include <soc/arc/aux.h>
>  
> @@ -103,5 +101,3 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
>  }
>  
>  #endif
> -
> -#endif
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 6/9] ARC: move mcip.h into include/soc and adjust the includes
@ 2016-11-03 17:20               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:20 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:13PM -0700, Vineet Gupta wrote:
> Also remove the depedency on ARCv2, to increase compile coverage for
> !ARCV2 builds

s/depedency/dependency/

Acked-by: Daniel Lezcano <daniel.lezcnao at linaro.org>

> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  arch/arc/kernel/mcip.c                           | 2 +-
>  arch/arc/kernel/time.c                           | 2 +-
>  arch/arc/plat-axs10x/axs10x.c                    | 2 +-
>  {arch/arc/include/asm => include/soc/arc}/mcip.h | 8 ++------
>  4 files changed, 5 insertions(+), 9 deletions(-)
>  rename {arch/arc/include/asm => include/soc/arc}/mcip.h (96%)
> 
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index c424d5abc318..0651e0a2e8b1 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -11,8 +11,8 @@
>  #include <linux/smp.h>
>  #include <linux/irq.h>
>  #include <linux/spinlock.h>
> +#include <soc/arc/mcip.h>
>  #include <asm/irqflags-arcv2.h>
> -#include <asm/mcip.h>
>  #include <asm/setup.h>
>  
>  static DEFINE_RAW_SPINLOCK(mcip_lock);
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index 00ece39a8ae7..f1ebe45bfcdf 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -40,7 +40,7 @@
>  #include <asm/irq.h>
>  #include <asm/arcregs.h>
>  
> -#include <asm/mcip.h>
> +#include <soc/arc/mcip.h>
>  
>  /* Timer related Aux registers */
>  #define ARC_REG_TIMER0_LIMIT	0x23	/* timer 0 limit */
> diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
> index 86548701023c..38ff349d7f2a 100644
> --- a/arch/arc/plat-axs10x/axs10x.c
> +++ b/arch/arc/plat-axs10x/axs10x.c
> @@ -21,7 +21,7 @@
>  #include <asm/asm-offsets.h>
>  #include <asm/io.h>
>  #include <asm/mach_desc.h>
> -#include <asm/mcip.h>
> +#include <soc/arc/mcip.h>
>  
>  #define AXS_MB_CGU		0xE0010000
>  #define AXS_MB_CREG		0xE0011000
> diff --git a/arch/arc/include/asm/mcip.h b/include/soc/arc/mcip.h
> similarity index 96%
> rename from arch/arc/include/asm/mcip.h
> rename to include/soc/arc/mcip.h
> index fc28d0944801..6902c2a8bd23 100644
> --- a/arch/arc/include/asm/mcip.h
> +++ b/include/soc/arc/mcip.h
> @@ -8,10 +8,8 @@
>   * published by the Free Software Foundation.
>   */
>  
> -#ifndef __ASM_MCIP_H
> -#define __ASM_MCIP_H
> -
> -#ifdef CONFIG_ISA_ARCV2
> +#ifndef __SOC_ARC_MCIP_H
> +#define __SOC_ARC_MCIP_H
>  
>  #include <soc/arc/aux.h>
>  
> @@ -103,5 +101,3 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
>  }
>  
>  #endif
> -
> -#endif
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 7/9] ARC: breakout timer stuff into a seperate header
  2016-10-31 22:48             ` Vineet Gupta
@ 2016-11-03 17:25               ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:25 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

s/seperate/separate/

On Mon, Oct 31, 2016 at 03:48:14PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---
>  arch/arc/include/asm/arcregs.h |  9 +--------
>  arch/arc/kernel/time.c         |  2 +-
>  include/soc/arc/timers.h       | 24 ++++++++++++++++++++++++
>  3 files changed, 26 insertions(+), 9 deletions(-)
>  create mode 100644 include/soc/arc/timers.h
> 
> diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
> index ccf5dc96713b..a17aa4558832 100644
> --- a/arch/arc/include/asm/arcregs.h
> +++ b/arch/arc/include/asm/arcregs.h
> @@ -20,7 +20,6 @@
>  #define ARC_REG_FP_V2_BCR	0xc8	/* ARCv2 FPU */
>  #define ARC_REG_SLC_BCR		0xce
>  #define ARC_REG_DCCM_BUILD	0x74	/* DCCM size (common) */
> -#define ARC_REG_TIMERS_BCR	0x75
>  #define ARC_REG_AP_BCR		0x76
>  #define ARC_REG_ICCM_BUILD	0x78	/* ICCM size (common) */
>  #define ARC_REG_XY_MEM_BCR	0x79
> @@ -206,13 +205,7 @@ struct bcr_fp_arcv2 {
>  #endif
>  };
>  
> -struct bcr_timer {
> -#ifdef CONFIG_CPU_BIG_ENDIAN
> -	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
> -#else
> -	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
> -#endif
> -};
> +#include <soc/arc/timers.h>
>  
>  struct bcr_bpu_arcompact {
>  #ifdef CONFIG_CPU_BIG_ENDIAN
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index f1ebe45bfcdf..dad3a9933c4c 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -38,8 +38,8 @@
>  #include <linux/of.h>
>  #include <linux/of_irq.h>
>  #include <asm/irq.h>
> -#include <asm/arcregs.h>
>  
> +#include <soc/arc/timers.h>
>  #include <soc/arc/mcip.h>
>  
>  /* Timer related Aux registers */
> diff --git a/include/soc/arc/timers.h b/include/soc/arc/timers.h
> new file mode 100644
> index 000000000000..79484fafabfa
> --- /dev/null
> +++ b/include/soc/arc/timers.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __SOC_ARC_TIMERS_H
> +#define __SOC_ARC_TIMERS_H
> +
> +#include <soc/arc/aux.h>
> +
> +#define ARC_REG_TIMERS_BCR	0x75
> +
> +struct bcr_timer {
> +#ifdef CONFIG_CPU_BIG_ENDIAN
> +	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
> +#else
> +	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
> +#endif
> +};
> +
> +#endif
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 7/9] ARC: breakout timer stuff into a seperate header
@ 2016-11-03 17:25               ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:25 UTC (permalink / raw)
  To: linux-snps-arc

s/seperate/separate/

On Mon, Oct 31, 2016@03:48:14PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  arch/arc/include/asm/arcregs.h |  9 +--------
>  arch/arc/kernel/time.c         |  2 +-
>  include/soc/arc/timers.h       | 24 ++++++++++++++++++++++++
>  3 files changed, 26 insertions(+), 9 deletions(-)
>  create mode 100644 include/soc/arc/timers.h
> 
> diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
> index ccf5dc96713b..a17aa4558832 100644
> --- a/arch/arc/include/asm/arcregs.h
> +++ b/arch/arc/include/asm/arcregs.h
> @@ -20,7 +20,6 @@
>  #define ARC_REG_FP_V2_BCR	0xc8	/* ARCv2 FPU */
>  #define ARC_REG_SLC_BCR		0xce
>  #define ARC_REG_DCCM_BUILD	0x74	/* DCCM size (common) */
> -#define ARC_REG_TIMERS_BCR	0x75
>  #define ARC_REG_AP_BCR		0x76
>  #define ARC_REG_ICCM_BUILD	0x78	/* ICCM size (common) */
>  #define ARC_REG_XY_MEM_BCR	0x79
> @@ -206,13 +205,7 @@ struct bcr_fp_arcv2 {
>  #endif
>  };
>  
> -struct bcr_timer {
> -#ifdef CONFIG_CPU_BIG_ENDIAN
> -	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
> -#else
> -	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
> -#endif
> -};
> +#include <soc/arc/timers.h>
>  
>  struct bcr_bpu_arcompact {
>  #ifdef CONFIG_CPU_BIG_ENDIAN
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index f1ebe45bfcdf..dad3a9933c4c 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -38,8 +38,8 @@
>  #include <linux/of.h>
>  #include <linux/of_irq.h>
>  #include <asm/irq.h>
> -#include <asm/arcregs.h>
>  
> +#include <soc/arc/timers.h>
>  #include <soc/arc/mcip.h>
>  
>  /* Timer related Aux registers */
> diff --git a/include/soc/arc/timers.h b/include/soc/arc/timers.h
> new file mode 100644
> index 000000000000..79484fafabfa
> --- /dev/null
> +++ b/include/soc/arc/timers.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __SOC_ARC_TIMERS_H
> +#define __SOC_ARC_TIMERS_H
> +
> +#include <soc/arc/aux.h>
> +
> +#define ARC_REG_TIMERS_BCR	0x75
> +
> +struct bcr_timer {
> +#ifdef CONFIG_CPU_BIG_ENDIAN
> +	unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
> +#else
> +	unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
> +#endif
> +};
> +
> +#endif
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 0/9] Move ARC timer code into drivers/clocksource/
  2016-10-31 22:48           ` Vineet Gupta
@ 2016-11-03 17:28             ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:28 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Mon, Oct 31, 2016 at 03:48:07PM -0700, Vineet Gupta wrote:
> Hi,
> 
> This series addresses the long pending move of ARC timer code into
> drivers/clocksource/.
> 
> - patches [1-4]/9 are improvements to arc code, paving way for later code motion.
> - patches [5-8]/9 refactor the arc headers to be shared between arc and drivers
> - patch 9/9 moves out the driver code/build/Kconfig bits
> 
> As review progresses/concludes, I'd like to merge [1-8] for this merge window and
> clocksource maintainers can pick up the actual switch for 4.10 or even 4.9 as they
> prefer.
> 

The different patches deserve a longer change description.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 0/9] Move ARC timer code into drivers/clocksource/
@ 2016-11-03 17:28             ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:28 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Oct 31, 2016@03:48:07PM -0700, Vineet Gupta wrote:
> Hi,
> 
> This series addresses the long pending move of ARC timer code into
> drivers/clocksource/.
> 
> - patches [1-4]/9 are improvements to arc code, paving way for later code motion.
> - patches [5-8]/9 refactor the arc headers to be shared between arc and drivers
> - patch 9/9 moves out the driver code/build/Kconfig bits
> 
> As review progresses/concludes, I'd like to merge [1-8] for this merge window and
> clocksource maintainers can pick up the actual switch for 4.10 or even 4.9 as they
> prefer.
> 

The different patches deserve a longer change description.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-01 20:57                 ` Vineet Gupta
@ 2016-11-03 17:33                   ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:33 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Tue, Nov 01, 2016 at 01:57:05PM -0700, Vineet Gupta wrote:
> Hi Daniel,
> 
> On 11/01/2016 01:42 PM, Daniel Lezcano wrote:
> > Please stay consistent with the rest of the Kconfig.
> > 
> > config ARC_TIMER_RTC
> > 	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> > 	  It is implemented inside the core thus can't be used in SMP systems.
> > 
> > config ARC_TIMER_GFRC
> > 	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter can be used as clocksource in SMP HS38 SoCs.
> > 	  It sits outside the core thus can be used in SMP systems
> > 
> 
> Yes I did so already :-) Although I also added a default y if ARC to both, but as
> you say that is better done in ARC Kconfig.
> 
> > Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
> > it is SMP or not.
> > 
> > One question:
> > 
> > Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
> > own clocksource ? It seems you are assuming a clocksource can be used on SMP
> > only if the clocksource is unique and shared across the cores.
> 

As now the clksrc-probe is correctly handling the errors, if the rtc and the
gfrc are both defined in the DT, you can fail to init the rtc one with a simple
test in the init function:

	if (IS_DEFINED(CONFIG_SMP))
		return -EINVAL;

So, you can inconditionaly compile in both RTC and GFRC, no ? That would be
cleaner and prevent a different kernel config.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 17:33                   ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:33 UTC (permalink / raw)
  To: linux-snps-arc

On Tue, Nov 01, 2016@01:57:05PM -0700, Vineet Gupta wrote:
> Hi Daniel,
> 
> On 11/01/2016 01:42 PM, Daniel Lezcano wrote:
> > Please stay consistent with the rest of the Kconfig.
> > 
> > config ARC_TIMER_RTC
> > 	bool "64-bit cycle counter in HS38 cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter provides 64-bit resolution vs. the 32-bit TIMER1.
> > 	  It is implemented inside the core thus can't be used in SMP systems.
> > 
> > config ARC_TIMER_GFRC
> > 	bool "64-bit cycle counter in ARConnect block in HS38x cores" if COMPILE_TEST
> > 	select CLKSRC_OF
> > 	help
> > 	  This counter can be used as clocksource in SMP HS38 SoCs.
> > 	  It sits outside the core thus can be used in SMP systems
> > 
> 
> Yes I did so already :-) Although I also added a default y if ARC to both, but as
> you say that is better done in ARC Kconfig.
> 
> > Then in the ARC's Kconfig you select ARC_TIMER_RTC or ARC_TIMER_GFRC depending
> > it is SMP or not.
> > 
> > One question:
> > 
> > Why ARC_TIMER_RTC can't be used in a SMP system ? Doesn't have each core its
> > own clocksource ? It seems you are assuming a clocksource can be used on SMP
> > only if the clocksource is unique and shared across the cores.
> 

As now the clksrc-probe is correctly handling the errors, if the rtc and the
gfrc are both defined in the DT, you can fail to init the rtc one with a simple
test in the init function:

	if (IS_DEFINED(CONFIG_SMP))
		return -EINVAL;

So, you can inconditionaly compile in both RTC and GFRC, no ? That would be
cleaner and prevent a different kernel config.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
  2016-11-03 17:00               ` Daniel Lezcano
@ 2016-11-03 17:41                 ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:41 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On 11/03/2016 10:00 AM, Daniel Lezcano wrote:
> On Mon, Oct 31, 2016 at 03:48:08PM -0700, Vineet Gupta wrote:
>> ... don't rely on cpuinfo populated in arc boot code. This paves wat for
>> moving this code in drivers/clocksource/
>>
>> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
>> ---
>>  arch/arc/kernel/time.c | 10 ++++++----
>>  1 file changed, 6 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
>> index f927b8dc6edd..a2db010cde18 100644
>> --- a/arch/arc/kernel/time.c
>> +++ b/arch/arc/kernel/time.c
>> @@ -118,10 +118,11 @@ static struct clocksource arc_counter_gfrc = {
>>  
>>  static int __init arc_cs_setup_gfrc(struct device_node *node)
>>  {
>> -	int exists = cpuinfo_arc700[0].extn.gfrc;
>> +	struct mcip_bcr mp;
>>  	int ret;
>>  
>> -	if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
>> +	READ_BCR(ARC_REG_MCIP_BCR, mp);
>> +	if (WARN(!mp.gfrc, "Global-64-bit-Ctr clocksource not detected"))
> 
> Take the opportunity to replace this WARN by a pr_err.

OK.

> 
>>  		return -ENXIO;
>>  
>>  	ret = arc_get_timer_clk(node);
>> @@ -174,10 +175,11 @@ static struct clocksource arc_counter_rtc = {
>>  
>>  static int __init arc_cs_setup_rtc(struct device_node *node)
>>  {
>> -	int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
>> +	struct bcr_timer timer;
>>  	int ret;
>>  
>> -	if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
>> +	READ_BCR(ARC_REG_TIMERS_BCR, timer);
>> +	if (WARN(!timer.rtc, "Local-64-bit-Ctr clocksource not detected"))
>>  		return -ENXIO;o
> 
> Ditto and                    ^^
> 
> So the READ_BCR() is only there to check the timer is physically present ?

Yep, due to configurable nature of cores, we have Build Config Registers to detect
at runtime what is present or not. This allows for boot printing at the minimum.
This is defined in arcregs.h and in newly introduced soc/arc/aux.h

> 
>>  	/* Local to CPU hence not usable in SMP */
>> -- 
>> 2.7.4
>>
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
@ 2016-11-03 17:41                 ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:41 UTC (permalink / raw)
  To: linux-snps-arc

On 11/03/2016 10:00 AM, Daniel Lezcano wrote:
> On Mon, Oct 31, 2016@03:48:08PM -0700, Vineet Gupta wrote:
>> ... don't rely on cpuinfo populated in arc boot code. This paves wat for
>> moving this code in drivers/clocksource/
>>
>> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
>> ---
>>  arch/arc/kernel/time.c | 10 ++++++----
>>  1 file changed, 6 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
>> index f927b8dc6edd..a2db010cde18 100644
>> --- a/arch/arc/kernel/time.c
>> +++ b/arch/arc/kernel/time.c
>> @@ -118,10 +118,11 @@ static struct clocksource arc_counter_gfrc = {
>>  
>>  static int __init arc_cs_setup_gfrc(struct device_node *node)
>>  {
>> -	int exists = cpuinfo_arc700[0].extn.gfrc;
>> +	struct mcip_bcr mp;
>>  	int ret;
>>  
>> -	if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
>> +	READ_BCR(ARC_REG_MCIP_BCR, mp);
>> +	if (WARN(!mp.gfrc, "Global-64-bit-Ctr clocksource not detected"))
> 
> Take the opportunity to replace this WARN by a pr_err.

OK.

> 
>>  		return -ENXIO;
>>  
>>  	ret = arc_get_timer_clk(node);
>> @@ -174,10 +175,11 @@ static struct clocksource arc_counter_rtc = {
>>  
>>  static int __init arc_cs_setup_rtc(struct device_node *node)
>>  {
>> -	int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
>> +	struct bcr_timer timer;
>>  	int ret;
>>  
>> -	if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
>> +	READ_BCR(ARC_REG_TIMERS_BCR, timer);
>> +	if (WARN(!timer.rtc, "Local-64-bit-Ctr clocksource not detected"))
>>  		return -ENXIO;o
> 
> Ditto and                    ^^
> 
> So the READ_BCR() is only there to check the timer is physically present ?

Yep, due to configurable nature of cores, we have Build Config Registers to detect
at runtime what is present or not. This allows for boot printing at the minimum.
This is defined in arcregs.h and in newly introduced soc/arc/aux.h

> 
>>  	/* Local to CPU hence not usable in SMP */
>> -- 
>> 2.7.4
>>
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm
  2016-11-03 17:02               ` Daniel Lezcano
@ 2016-11-03 17:45                 ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:45 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Noam Camus, tglx, linux-snps-arc, Alexey.Brodkin, linux-kernel

On 11/03/2016 10:02 AM, Daniel Lezcano wrote:
> On Mon, Oct 31, 2016 at 03:48:09PM -0700, Vineet Gupta wrote:
>> To allow for easy movement into drivers/clocksource
>>
>> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
>> ---
>>  arch/arc/kernel/time.c | 13 +++++--------
>>  1 file changed, 5 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
>> index a2db010cde18..2c51e3cafad0 100644
>> --- a/arch/arc/kernel/time.c
>> +++ b/arch/arc/kernel/time.c
>> @@ -153,14 +153,11 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
>>  		cycle_t  full;
>>  	} stamp;
>>  
>> -
>> -	__asm__ __volatile(
>> -	"1:						\n"
>> -	"	lr		%0, [AUX_RTC_LOW]	\n"
>> -	"	lr		%1, [AUX_RTC_HIGH]	\n"
>> -	"	lr		%2, [AUX_RTC_CTRL]	\n"
>> -	"	bbit0.nt	%2, 31, 1b		\n"
>> -	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
>> +	do {
>> +		stamp.low = read_aux_reg(AUX_RTC_LOW);
>> +		stamp.high = read_aux_reg(AUX_RTC_HIGH);
>> +		status = read_aux_reg(AUX_RTC_CTRL);
>> +	} while (!(status & 0x80000000UL));
> 
> Replace the literal 0x80000000UL by a macro.

OK !


> What is the 'status' for ?

Hardware keeps a internal state machine for atomic readout of low/high. So if an
interrupt is taken between reading low and high, or if high increments after low
is read, then the bit forces a loop to retry.

>   
>>  	return stamp.full;
>>  }
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm
@ 2016-11-03 17:45                 ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:45 UTC (permalink / raw)
  To: linux-snps-arc

On 11/03/2016 10:02 AM, Daniel Lezcano wrote:
> On Mon, Oct 31, 2016@03:48:09PM -0700, Vineet Gupta wrote:
>> To allow for easy movement into drivers/clocksource
>>
>> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
>> ---
>>  arch/arc/kernel/time.c | 13 +++++--------
>>  1 file changed, 5 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
>> index a2db010cde18..2c51e3cafad0 100644
>> --- a/arch/arc/kernel/time.c
>> +++ b/arch/arc/kernel/time.c
>> @@ -153,14 +153,11 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
>>  		cycle_t  full;
>>  	} stamp;
>>  
>> -
>> -	__asm__ __volatile(
>> -	"1:						\n"
>> -	"	lr		%0, [AUX_RTC_LOW]	\n"
>> -	"	lr		%1, [AUX_RTC_HIGH]	\n"
>> -	"	lr		%2, [AUX_RTC_CTRL]	\n"
>> -	"	bbit0.nt	%2, 31, 1b		\n"
>> -	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
>> +	do {
>> +		stamp.low = read_aux_reg(AUX_RTC_LOW);
>> +		stamp.high = read_aux_reg(AUX_RTC_HIGH);
>> +		status = read_aux_reg(AUX_RTC_CTRL);
>> +	} while (!(status & 0x80000000UL));
> 
> Replace the literal 0x80000000UL by a macro.

OK !


> What is the 'status' for ?

Hardware keeps a internal state machine for atomic readout of low/high. So if an
interrupt is taken between reading low and high, or if high increments after low
is read, then the bit forces a loop to retry.

>   
>>  	return stamp.full;
>>  }
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
  2016-11-03 17:09               ` Daniel Lezcano
@ 2016-11-03 17:47                 ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:47 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On 11/03/2016 10:09 AM, Daniel Lezcano wrote:
> On Mon, Oct 31, 2016 at 03:48:10PM -0700, Vineet Gupta wrote:
>> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> 
> Why not add a message in drivers/clocksource/clksrc-probe.c when a timer inits
> successfully ? and then get rid of this code.

At boot I have bunch of cod which prints all the major hardware blocks and thus
would like to print it. We also print if a feature is present but not supported
etc. So I like to keep all of that here.

Also same code is used for /proc/cpuinfo.

> 
>> ---
>>  arch/arc/kernel/setup.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
>> index 0385df77a697..595d06900061 100644
>> --- a/arch/arc/kernel/setup.c
>> +++ b/arch/arc/kernel/setup.c
>> @@ -234,11 +234,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
>>  		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
>>  		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
>>  
>> -	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
>> +	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
>>  		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
>>  		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
>> -		       IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
>> -				 CONFIG_ARC_HAS_RTC));
>> +		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
>> +		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
>>  
>>  	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
>>  			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
>> -- 
>> 2.7.4
>>
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
@ 2016-11-03 17:47                 ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:47 UTC (permalink / raw)
  To: linux-snps-arc

On 11/03/2016 10:09 AM, Daniel Lezcano wrote:
> On Mon, Oct 31, 2016@03:48:10PM -0700, Vineet Gupta wrote:
>> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> 
> Why not add a message in drivers/clocksource/clksrc-probe.c when a timer inits
> successfully ? and then get rid of this code.

At boot I have bunch of cod which prints all the major hardware blocks and thus
would like to print it. We also print if a feature is present but not supported
etc. So I like to keep all of that here.

Also same code is used for /proc/cpuinfo.

> 
>> ---
>>  arch/arc/kernel/setup.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
>> index 0385df77a697..595d06900061 100644
>> --- a/arch/arc/kernel/setup.c
>> +++ b/arch/arc/kernel/setup.c
>> @@ -234,11 +234,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
>>  		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
>>  		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
>>  
>> -	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
>> +	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
>>  		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
>>  		       IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
>> -		       IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
>> -				 CONFIG_ARC_HAS_RTC));
>> +		       IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_HAS_RTC),
>> +		       IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_HAS_GFRC));
>>  
>>  	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
>>  			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
>> -- 
>> 2.7.4
>>
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
  2016-11-03 17:47                 ` Vineet Gupta
@ 2016-11-03 17:51                   ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:51 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Thu, Nov 03, 2016 at 10:47:19AM -0700, Vineet Gupta wrote:
> On 11/03/2016 10:09 AM, Daniel Lezcano wrote:
> > On Mon, Oct 31, 2016 at 03:48:10PM -0700, Vineet Gupta wrote:
> >> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> > 
> > Why not add a message in drivers/clocksource/clksrc-probe.c when a timer inits
> > successfully ? and then get rid of this code.
> 
> At boot I have bunch of cod which prints all the major hardware blocks and thus
> would like to print it. We also print if a feature is present but not supported
> etc. So I like to keep all of that here.
> 
> Also same code is used for /proc/cpuinfo.

Ok, I see. Thanks for the clarification.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers
@ 2016-11-03 17:51                   ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 17:51 UTC (permalink / raw)
  To: linux-snps-arc

On Thu, Nov 03, 2016@10:47:19AM -0700, Vineet Gupta wrote:
> On 11/03/2016 10:09 AM, Daniel Lezcano wrote:
> > On Mon, Oct 31, 2016@03:48:10PM -0700, Vineet Gupta wrote:
> >> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> > 
> > Why not add a message in drivers/clocksource/clksrc-probe.c when a timer inits
> > successfully ? and then get rid of this code.
> 
> At boot I have bunch of cod which prints all the major hardware blocks and thus
> would like to print it. We also print if a feature is present but not supported
> etc. So I like to keep all of that here.
> 
> Also same code is used for /proc/cpuinfo.

Ok, I see. Thanks for the clarification.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-03 16:50                         ` Daniel Lezcano
@ 2016-11-03 17:57                           ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:57 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

Hi Daniel,

On 11/03/2016 09:50 AM, Daniel Lezcano wrote:
> On Thu, Nov 03, 2016 at 09:40:23AM -0700, Vineet Gupta wrote:
>> On 11/01/2016 06:03 PM, Vineet Gupta wrote:
>>>>> Because of the git mv you, diff didn't include bulk of driver code which would
>>>>>>> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
>>>>>
>>>>> That means I will review and comment existing code. It is not a problem for me
>>>>> if you agree to do the changes.
>>> Sure, the whole point is to make things better as an outcome of review. I have no
>>> issues changing code provided we don't add major performance regressions.
>>
>> So just wondering if I could have some comments on the initial import of driver
>> before I send out a v2.
> 
> Yeah, ok. Let me comment the other patches of the series and then you can send a V2.

Thx for taking a quick look - this is a good start. How about the actual driver
itself, do you want to take a quick look there as well before v2 ?

>  
>> The issue is git mv didn't show bulk of code being moved. Shall I send a v2 with a
>> different ordering so I introduce the driver first, with new headers, new Kconfig
>> items etc and then as a subsequent patch prune those bits from arch/arc/* ?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 17:57                           ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 17:57 UTC (permalink / raw)
  To: linux-snps-arc

Hi Daniel,

On 11/03/2016 09:50 AM, Daniel Lezcano wrote:
> On Thu, Nov 03, 2016@09:40:23AM -0700, Vineet Gupta wrote:
>> On 11/01/2016 06:03 PM, Vineet Gupta wrote:
>>>>> Because of the git mv you, diff didn't include bulk of driver code which would
>>>>>>> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
>>>>>
>>>>> That means I will review and comment existing code. It is not a problem for me
>>>>> if you agree to do the changes.
>>> Sure, the whole point is to make things better as an outcome of review. I have no
>>> issues changing code provided we don't add major performance regressions.
>>
>> So just wondering if I could have some comments on the initial import of driver
>> before I send out a v2.
> 
> Yeah, ok. Let me comment the other patches of the series and then you can send a V2.

Thx for taking a quick look - this is a good start. How about the actual driver
itself, do you want to take a quick look there as well before v2 ?

>  
>> The issue is git mv didn't show bulk of code being moved. Shall I send a v2 with a
>> different ordering so I introduce the driver first, with new headers, new Kconfig
>> items etc and then as a subsequent patch prune those bits from arch/arc/* ?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-03 17:57                           ` Vineet Gupta
@ 2016-11-03 18:11                             ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 18:11 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Thu, Nov 03, 2016 at 10:57:48AM -0700, Vineet Gupta wrote:
> Hi Daniel,
> 
> On 11/03/2016 09:50 AM, Daniel Lezcano wrote:
> > On Thu, Nov 03, 2016 at 09:40:23AM -0700, Vineet Gupta wrote:
> >> On 11/01/2016 06:03 PM, Vineet Gupta wrote:
> >>>>> Because of the git mv you, diff didn't include bulk of driver code which would
> >>>>>>> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
> >>>>>
> >>>>> That means I will review and comment existing code. It is not a problem for me
> >>>>> if you agree to do the changes.
> >>> Sure, the whole point is to make things better as an outcome of review. I have no
> >>> issues changing code provided we don't add major performance regressions.
> >>
> >> So just wondering if I could have some comments on the initial import of driver
> >> before I send out a v2.
> > 
> > Yeah, ok. Let me comment the other patches of the series and then you can send a V2.
> 
> Thx for taking a quick look - this is a good start. How about the actual driver
> itself, do you want to take a quick look there as well before v2 ?

At the first glance, with your changes it is acceptable to be moved. Perhaps,
you can have a look to remove the BIG_ENDIAN stuff in the clock read function.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 18:11                             ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 18:11 UTC (permalink / raw)
  To: linux-snps-arc

On Thu, Nov 03, 2016@10:57:48AM -0700, Vineet Gupta wrote:
> Hi Daniel,
> 
> On 11/03/2016 09:50 AM, Daniel Lezcano wrote:
> > On Thu, Nov 03, 2016@09:40:23AM -0700, Vineet Gupta wrote:
> >> On 11/01/2016 06:03 PM, Vineet Gupta wrote:
> >>>>> Because of the git mv you, diff didn't include bulk of driver code which would
> >>>>>>> make for bulk of review anyways. So perhaps in v2 I don't do the git mv. OK ?
> >>>>>
> >>>>> That means I will review and comment existing code. It is not a problem for me
> >>>>> if you agree to do the changes.
> >>> Sure, the whole point is to make things better as an outcome of review. I have no
> >>> issues changing code provided we don't add major performance regressions.
> >>
> >> So just wondering if I could have some comments on the initial import of driver
> >> before I send out a v2.
> > 
> > Yeah, ok. Let me comment the other patches of the series and then you can send a V2.
> 
> Thx for taking a quick look - this is a good start. How about the actual driver
> itself, do you want to take a quick look there as well before v2 ?

At the first glance, with your changes it is acceptable to be moved. Perhaps,
you can have a look to remove the BIG_ENDIAN stuff in the clock read function.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-03 17:33                   ` Daniel Lezcano
@ 2016-11-03 18:14                     ` Daniel Lezcano
  -1 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 18:14 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On Thu, Nov 03, 2016 at 06:33:17PM +0100, Daniel Lezcano wrote:

[ ... ]

> As now the clksrc-probe is correctly handling the errors, if the rtc and the
> gfrc are both defined in the DT, you can fail to init the rtc one with a simple
> test in the init function:
> 
> 	if (IS_DEFINED(CONFIG_SMP))
> 		return -EINVAL;
> 
> So, you can inconditionaly compile in both RTC and GFRC, no ? That would be
> cleaner and prevent a different kernel config.

Ah, actually I suggested something which is already there :)

Perhaps, the if SMP does not make sense in the Kconfig, no ?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 18:14                     ` Daniel Lezcano
  0 siblings, 0 replies; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-03 18:14 UTC (permalink / raw)
  To: linux-snps-arc

On Thu, Nov 03, 2016@06:33:17PM +0100, Daniel Lezcano wrote:

[ ... ]

> As now the clksrc-probe is correctly handling the errors, if the rtc and the
> gfrc are both defined in the DT, you can fail to init the rtc one with a simple
> test in the init function:
> 
> 	if (IS_DEFINED(CONFIG_SMP))
> 		return -EINVAL;
> 
> So, you can inconditionaly compile in both RTC and GFRC, no ? That would be
> cleaner and prevent a different kernel config.

Ah, actually I suggested something which is already there :)

Perhaps, the if SMP does not make sense in the Kconfig, no ?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-03 18:11                             ` Daniel Lezcano
@ 2016-11-03 18:43                               ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 18:43 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On 11/03/2016 11:11 AM, Daniel Lezcano wrote:
>> Thx for taking a quick look - this is a good start. How about the actual driver
>> > itself, do you want to take a quick look there as well before v2 ?
> At the first glance, with your changes it is acceptable to be moved. Perhaps,
> you can have a look to remove the BIG_ENDIAN stuff in the clock read function.
> 

OK addressed that as well !

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 18:43                               ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 18:43 UTC (permalink / raw)
  To: linux-snps-arc

On 11/03/2016 11:11 AM, Daniel Lezcano wrote:
>> Thx for taking a quick look - this is a good start. How about the actual driver
>> > itself, do you want to take a quick look there as well before v2 ?
> At the first glance, with your changes it is acceptable to be moved. Perhaps,
> you can have a look to remove the BIG_ENDIAN stuff in the clock read function.
> 

OK addressed that as well !

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH 9/9] clocksource: import ARC timer driver
  2016-11-03 17:33                   ` Daniel Lezcano
@ 2016-11-03 18:47                     ` Vineet Gupta
  -1 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 18:47 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: tglx, linux-kernel, linux-snps-arc, Noam Camus, Alexey.Brodkin

On 11/03/2016 10:33 AM, Daniel Lezcano wrote:
> As now the clksrc-probe is correctly handling the errors, if the rtc and the
> gfrc are both defined in the DT, you can fail to init the rtc one with a simple
> test in the init function:
> 
> 	if (IS_DEFINED(CONFIG_SMP))
> 		return -EINVAL;
> 
> So, you can inconditionaly compile in both RTC and GFRC, no ? That would be
> cleaner and prevent a different kernel config.

That's a very good idea. So now I envision
CONFIG_ARC_TIMERS		# legacy TIMER0 / TIMER1
CONFIG_ARC_64BIT_TIMERS		# rtc, gfrc

I need this distinction at the min to be able to select them from ARC Kconfig.

-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [PATCH 9/9] clocksource: import ARC timer driver
@ 2016-11-03 18:47                     ` Vineet Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Vineet Gupta @ 2016-11-03 18:47 UTC (permalink / raw)
  To: linux-snps-arc

On 11/03/2016 10:33 AM, Daniel Lezcano wrote:
> As now the clksrc-probe is correctly handling the errors, if the rtc and the
> gfrc are both defined in the DT, you can fail to init the rtc one with a simple
> test in the init function:
> 
> 	if (IS_DEFINED(CONFIG_SMP))
> 		return -EINVAL;
> 
> So, you can inconditionaly compile in both RTC and GFRC, no ? That would be
> cleaner and prevent a different kernel config.

That's a very good idea. So now I envision
CONFIG_ARC_TIMERS		# legacy TIMER0 / TIMER1
CONFIG_ARC_64BIT_TIMERS		# rtc, gfrc

I need this distinction at the min to be able to select them from ARC Kconfig.

-Vineet

^ permalink raw reply	[flat|nested] 95+ messages in thread

* RE: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-11-01 20:01         ` Daniel Lezcano
  (?)
@ 2016-11-08  8:30         ` Noam Camus
  2016-11-10 10:34           ` Daniel Lezcano
  -1 siblings, 1 reply; 95+ messages in thread
From: Noam Camus @ 2016-11-08  8:30 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel, Vineet Gupta

> From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
> Sent: Tuesday, November 1, 2016 10:02 PM
...
>Assuming cpu0 and cpu1 are sibling, does

>taskset 0x1 time sleep 2 & taskset 0x2 time sleep 3

I will use 16,17 instead of 0,1
>give a correct result without a dmesg log ?
[root@192.168.8.2 /]$ [root@192.168.8.2 /]$ taskset 65536 time sleep 2 & taskset 131072 time sleep 3
real    0m 2.54s
user    0m 0.04s
sys     0m 0.14s
real    0m 3.47s
user    0m 0.00s
sys     0m 0.15s
[1]+  Done                       taskset 65536 time sleep 2

Seem OK to me.

> Can you give the content of the /proc/timer_list ?
[root@192.168.8.2 /]$ cat /proc/timer_list
Timer List Version: v0.8
HRTIMER_MAX_CLOCK_BASES: 4
now at 2421277626774 nsecs

cpu: 0
 clock 0:
  .base:       9fccb540
  .index:      0
  .resolution: 1 nsecs
  .get_time:   ktime_get
  .offset:     0 nsecs
active timers:
 #0: <9fccb69c>, tick_sched_timer, S:01
 # expires at 2421140000000-2421140000000 nsecs [in -137626774 to -137626774 nsecs]
 clock 1:
  .base:       9fccb560
  .index:      1
  .resolution: 1 nsecs
  .get_time:   ktime_get_real
  .offset:     0 nsecs
active timers:
 clock 2:
  .base:       9fccb580
  .index:      2
  .resolution: 1 nsecs
  .get_time:   ktime_get_boottime
  .offset:     0 nsecs
active timers:
 clock 3:
  .base:       9fccb5a0
  .index:      3
  .resolution: 1 nsecs
  .get_time:   ktime_get_clocktai
  .offset:     0 nsecs
active timers:
  .expires_next   : 2421140000000 nsecs
  .hres_active    : 1
  .nr_events      : 615427
  .nr_retries     : 10052
  .nr_hangs       : 37
  .max_hang_time  : 682411010
  .nohz_mode      : 2
  .last_tick      : 0 nsecs
  .tick_stopped   : 0
  .idle_jiffies   : 0
  .idle_calls     : 0
  .idle_sleeps    : 0
  .idle_entrytime : 2421131605769 nsecs
  .idle_waketime  : 0 nsecs
  .idle_exittime  : 0 nsecs
  .idle_sleeptime : 1900903609165 nsecs
  .iowait_sleeptime: 0 nsecs
  .last_jiffies   : 0
  .next_timer     : 0
  .idle_expires   : 0 nsecs
jiffies: 212114

cpu: 16
 clock 0:
  .base:       9fcd7540
  .index:      0
  .resolution: 1 nsecs
  .get_time:   ktime_get
  .offset:     0 nsecs
active timers:
 clock 1:
  .base:       9fcd7560
  .index:      1
  .resolution: 1 nsecs
  .get_time:   ktime_get_real
  .offset:     0 nsecs
active timers:
 clock 2:
  .base:       9fcd7580
  .index:      2
  .resolution: 1 nsecs
  .get_time:   ktime_get_boottime
  .offset:     0 nsecs
active timers:
 clock 3:
  .base:       9fcd75a0
  .index:      3
  .resolution: 1 nsecs
  .get_time:   ktime_get_clocktai
  .offset:     0 nsecs
active timers:
  .expires_next   : 9223372036854775807 nsecs
  .hres_active    : 1
  .nr_events      : 18
  .nr_retries     : 1
  .nr_hangs       : 0
  .max_hang_time  : 0
  .nohz_mode      : 2
  .last_tick      : 2410120000000 nsecs
  .tick_stopped   : 1
  .idle_jiffies   : 211017
  .idle_calls     : 27
  .idle_sleeps    : 27
  .idle_entrytime : 2410189597725 nsecs
  .idle_waketime  : 2410189342725 nsecs
  .idle_exittime  : 2410110197721 nsecs
  .idle_sleeptime : 2408852044732 nsecs
  .iowait_sleeptime: 0 nsecs
  .last_jiffies   : 211019
  .next_timer     : 9223372036854775807
  .idle_expires   : 9223372036854775807 nsecs
jiffies: 212114

cpu: 17
 clock 0:
  .base:       9fce3540
  .index:      0
  .resolution: 1 nsecs
  .get_time:   ktime_get
  .offset:     0 nsecs
active timers:
 clock 1:
  .base:       9fce3560
  .index:      1
  .resolution: 1 nsecs
  .get_time:   ktime_get_real
  .offset:     0 nsecs
active timers:
 clock 2:
  .base:       9fce3580
  .index:      2
  .resolution: 1 nsecs
  .get_time:   ktime_get_boottime
  .offset:     0 nsecs
active timers:
 clock 3:
  .base:       9fce35a0
  .index:      3
  .resolution: 1 nsecs
  .get_time:   ktime_get_clocktai
  .offset:     0 nsecs
active timers:
  .expires_next   : 9223372036854775807 nsecs
  .hres_active    : 1
  .nr_events      : 22
  .nr_retries     : 1
  .nr_hangs       : 0
  .max_hang_time  : 0
  .nohz_mode      : 2
  .last_tick      : 2412120000000 nsecs
  .tick_stopped   : 1
  .idle_jiffies   : 211212
  .idle_calls     : 32
  .idle_sleeps    : 32
  .idle_entrytime : 2412123353729 nsecs
  .idle_waketime  : 2412123049733 nsecs
  .idle_exittime  : 2412110161733 nsecs
  .idle_sleeptime : 2410832354720 nsecs
  .iowait_sleeptime: 0 nsecs
  .last_jiffies   : 211213
  .next_timer     : 9223372036854775807
  .idle_expires   : 9223372036854775807 nsecs
jiffies: 212114

Tick Device: mode:     1
Per CPU device: 0
Clock Event Device: ARC Timer0
 max_delta_ns:   51539607733
 min_delta_ns:   1000
 mult:           178956970
 shift:          31
 mode:           3
 next_event:     2421140000000 nsecs
 set_next_event: arc_clkevent_set_next_event
 periodic: arc_clkevent_set_periodic
 event_handler:  hrtimer_interrupt
 retries:        0

Tick Device: mode:     1
Per CPU device: 16
Clock Event Device: ARC Timer0
 max_delta_ns:   51539607733
 min_delta_ns:   1000
 mult:           178956970
 shift:          31
 mode:           3
 next_event:     9223372036854775807 nsecs
 set_next_event: arc_clkevent_set_next_event
 periodic: arc_clkevent_set_periodic
 event_handler:  hrtimer_interrupt
 retries:        2

Tick Device: mode:     1
Per CPU device: 17
Clock Event Device: ARC Timer0
 max_delta_ns:   51539607733
 min_delta_ns:   1000
 mult:           178956970
 shift:          31
 mode:           3
 next_event:     9223372036854775807 nsecs
 set_next_event: arc_clkevent_set_next_event
 periodic: arc_clkevent_set_periodic
 event_handler:  hrtimer_interrupt
 retries:        2

-Noam

^ permalink raw reply	[flat|nested] 95+ messages in thread

* Re: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-11-08  8:30         ` Noam Camus
@ 2016-11-10 10:34           ` Daniel Lezcano
  2016-11-10 13:00             ` Noam Camus
  0 siblings, 1 reply; 95+ messages in thread
From: Daniel Lezcano @ 2016-11-10 10:34 UTC (permalink / raw)
  To: Noam Camus
  Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel, Vineet Gupta

On 08/11/2016 09:30, Noam Camus wrote:
>> From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
>> Sent: Tuesday, November 1, 2016 10:02 PM
> ...
>> Assuming cpu0 and cpu1 are sibling, does
> 
>> taskset 0x1 time sleep 2 & taskset 0x2 time sleep 3
> 
> I will use 16,17 instead of 0,1
>> give a correct result without a dmesg log ?
> [root@192.168.8.2 /]$ [root@192.168.8.2 /]$ taskset 65536 time sleep 2 & taskset 131072 time sleep 3

Thanks for providing the numbers.

So there is no weird messages in dmesg ?

> real    0m 2.54s
> user    0m 0.04s
> sys     0m 0.14s
> real    0m 3.47s
> user    0m 0.00s
> sys     0m 0.15s
> [1]+  Done                       taskset 65536 time sleep 2
> 
> Seem OK to me.

I'm not sure of that.

2.54 instead of 2
3.47 instead of 3

0.02 time drift could be acceptable but 0.54 or 0.47 is too much.

And 0.15 in sys also a big number AFAICT.

Is the system in NO_HZ ?



-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 95+ messages in thread

* RE: [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver
  2016-11-10 10:34           ` Daniel Lezcano
@ 2016-11-10 13:00             ` Noam Camus
  0 siblings, 0 replies; 95+ messages in thread
From: Noam Camus @ 2016-11-10 13:00 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: robh+dt, mark.rutland, tglx, devicetree, linux-kernel, Vineet Gupta

>From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
>Sent: Thursday, November 10, 2016 12:34 PM

>>> give a correct result without a dmesg log ?
>> [root@192.168.8.2 /]$ [root@192.168.8.2 /]$ taskset 65536 time sleep 2 
>> & taskset 131072 time sleep 3

>Thanks for providing the numbers.

>So there is no weird messages in dmesg ?
Yes, no weird messages, all seem normal.

>> real    0m 2.54s
>> user    0m 0.04s
>> sys     0m 0.14s
>> real    0m 3.47s
>> user    0m 0.00s
>> sys     0m 0.15s
>> [1]+  Done                       taskset 65536 time sleep 2
>> 
>> Seem OK to me.

>I'm not sure of that.

>2.54 instead of 2
>3.47 instead of 3

>0.02 time drift could be acceptable but 0.54 or 0.47 is too much.

>And 0.15 in sys also a big number AFAICT.

>Is the system in NO_HZ ?

We are handling system with NOHZ_FULL 
This was run under simulation and result are reasonable (indeed not perfect) AFAICT.

-Noam

^ permalink raw reply	[flat|nested] 95+ messages in thread

end of thread, other threads:[~2016-11-10 13:01 UTC | newest]

Thread overview: 95+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-23 12:12 [PATCH v2 0/3] Add clockevet for timer-nps driver to NPS400 SoC Noam Camus
2016-10-23 12:12 ` Noam Camus
2016-10-23 12:12 ` [PATCH v2 1/3] soc: Support for NPS HW scheduling Noam Camus
2016-10-23 12:12   ` Noam Camus
2016-10-31 10:26   ` Daniel Lezcano
2016-10-31 10:26     ` Daniel Lezcano
2016-10-31 12:26     ` Noam Camus
2016-10-23 12:12 ` [PATCH v2 2/3] clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer Noam Camus
2016-10-23 12:12   ` Noam Camus
2016-10-31 10:28   ` Daniel Lezcano
2016-10-31 10:28     ` Daniel Lezcano
2016-10-31 15:19     ` Noam Camus
2016-10-23 12:12 ` [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver Noam Camus
2016-10-23 12:12   ` Noam Camus
2016-10-30 20:41   ` Rob Herring
2016-10-31 10:52   ` Daniel Lezcano
2016-10-31 17:03     ` Noam Camus
2016-10-31 17:51       ` Vineet Gupta
2016-10-31 22:48         ` [PATCH 0/9] Move ARC timer code into drivers/clocksource/ Vineet Gupta
2016-10-31 22:48           ` Vineet Gupta
2016-10-31 22:48           ` [PATCH 1/9] ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-03 17:00             ` Daniel Lezcano
2016-11-03 17:00               ` Daniel Lezcano
2016-11-03 17:41               ` Vineet Gupta
2016-11-03 17:41                 ` Vineet Gupta
2016-10-31 22:48           ` [PATCH 2/9] ARC: timer: rtc: implement read loop in "C" vs. inline asm Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-03 17:02             ` Daniel Lezcano
2016-11-03 17:02               ` Daniel Lezcano
2016-11-03 17:45               ` Vineet Gupta
2016-11-03 17:45                 ` Vineet Gupta
2016-10-31 22:48           ` [PATCH 3/9] ARC: timer: gfrc: boot print alongside other timers Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-03 17:09             ` Daniel Lezcano
2016-11-03 17:09               ` Daniel Lezcano
2016-11-03 17:47               ` Vineet Gupta
2016-11-03 17:47                 ` Vineet Gupta
2016-11-03 17:51                 ` Daniel Lezcano
2016-11-03 17:51                   ` Daniel Lezcano
2016-10-31 22:48           ` [PATCH 4/9] ARC: time: move time_init() out of the driver Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-03 17:15             ` Daniel Lezcano
2016-11-03 17:15               ` Daniel Lezcano
2016-10-31 22:48           ` [PATCH 5/9] ARC: breakout aux handling into a seperate header Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-01  7:49             ` Noam Camus
2016-11-01  7:49               ` Noam Camus
2016-10-31 22:48           ` [PATCH 6/9] ARC: move mcip.h into include/soc and adjust the includes Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-03 17:20             ` Daniel Lezcano
2016-11-03 17:20               ` Daniel Lezcano
2016-10-31 22:48           ` [PATCH 7/9] ARC: breakout timer stuff into a seperate header Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-03 17:25             ` Daniel Lezcano
2016-11-03 17:25               ` Daniel Lezcano
2016-10-31 22:48           ` [PATCH 8/9] ARC: timer: rename config options Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-10-31 22:48           ` [PATCH 9/9] clocksource: import ARC timer driver Vineet Gupta
2016-10-31 22:48             ` Vineet Gupta
2016-11-01  0:01             ` kbuild test robot
2016-11-01  0:01               ` kbuild test robot
2016-11-01  0:45               ` Vineet Gupta
2016-11-01  0:45                 ` Vineet Gupta
2016-11-01 20:42             ` Daniel Lezcano
2016-11-01 20:42               ` Daniel Lezcano
2016-11-01 20:57               ` Vineet Gupta
2016-11-01 20:57                 ` Vineet Gupta
2016-11-02  0:19                 ` Daniel Lezcano
2016-11-02  0:19                   ` Daniel Lezcano
2016-11-02  1:03                   ` Vineet Gupta
2016-11-02  1:03                     ` Vineet Gupta
2016-11-03 16:40                     ` Vineet Gupta
2016-11-03 16:40                       ` Vineet Gupta
2016-11-03 16:50                       ` Daniel Lezcano
2016-11-03 16:50                         ` Daniel Lezcano
2016-11-03 17:57                         ` Vineet Gupta
2016-11-03 17:57                           ` Vineet Gupta
2016-11-03 18:11                           ` Daniel Lezcano
2016-11-03 18:11                             ` Daniel Lezcano
2016-11-03 18:43                             ` Vineet Gupta
2016-11-03 18:43                               ` Vineet Gupta
2016-11-03 17:33                 ` Daniel Lezcano
2016-11-03 17:33                   ` Daniel Lezcano
2016-11-03 18:14                   ` Daniel Lezcano
2016-11-03 18:14                     ` Daniel Lezcano
2016-11-03 18:47                   ` Vineet Gupta
2016-11-03 18:47                     ` Vineet Gupta
2016-11-03 17:28           ` [PATCH 0/9] Move ARC timer code into drivers/clocksource/ Daniel Lezcano
2016-11-03 17:28             ` Daniel Lezcano
2016-11-01 20:01       ` [PATCH v2 3/3] clocksource: Add clockevent support to NPS400 driver Daniel Lezcano
2016-11-01 20:01         ` Daniel Lezcano
2016-11-08  8:30         ` Noam Camus
2016-11-10 10:34           ` Daniel Lezcano
2016-11-10 13:00             ` Noam Camus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.