From Vineet.Gupta1 at synopsys.com  Tue Dec  1 00:30:18 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Tue, 1 Dec 2015 08:30:18 +0000
Subject: ARC stable backport request
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D433E@IN01WEMBXA.internal.synopsys.com>

Hi,

Please add upstream commit 30b9dbee895ff ("ARC: Fix silly typo in MAINTAINERS
file") to stable releases.

This depends on 9acdc911b55569145 ("MAINTAINERS: Add public mailing list for ARC")
which was already marked for stable inclusion and is hitting the stable trees ATM.

Thx,
-Vineet


From noamc at ezchip.com  Tue Dec  1 05:02:47 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:47 +0200
Subject: [PATCH v3 00/18] *** SUBJECT HERE ***
Message-ID: <1448974985-11487-1-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

v3:
1)	irqchip: use MACROS instead of structures to decribe
	registers.
2)	clocksource: use 32bit counter and avoid 2 halfs read
	of 64bit dance.

v2:
1)	Remove out of tree platform include path
2)	Move atomic/bitop/cmpxchg for platform to end.
	Remove macro duplication.
	Fix some bad implementation.
3)	define cpu_relax_lowlatency() for platform.
4)	rename init_irq_cpu() to init_per_cpu()
	reorder call to init_per_cpu() for secondary
	use it instead of init_cpu_smp().
5)	set res_service to call stext
6)	fix build failure for CTOP_AUX_BASE at assembly code
7)	Use ilog2 for mtm_init_nat()
8)	Add CLKSRC_NPS option to Kconfig
	change nps_clksrc_read() to be more readable.

General summay:
This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threads. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (17):
  Documentation: Add EZchip vendor to binding list
  ARC: [plat-eznps] define IPI_IRQ
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  ARC: Mark secondary cpu online only after all HW setup is done
  ARC: add CONFIG_CLKSRC_OF support to time_init()
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (1):
  ARC: [plat-eznps] Use dedicated cpu_relax()

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |    9 +
 arch/arc/Makefile                                  |    5 +
 arch/arc/boot/dts/eznps.dts                        |   76 ++++++
 arch/arc/configs/nps_defconfig                     |   85 +++++++
 arch/arc/include/asm/atomic.h                      |   79 ++++++-
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   54 +++++
 arch/arc/include/asm/cmpxchg.h                     |   87 ++++++--
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/irq.h                         |    4 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   36 +++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    4 +-
 arch/arc/include/asm/spinlock.h                    |   14 +
 arch/arc/kernel/ctx_sw.c                           |   13 +
 arch/arc/kernel/irq.c                              |    4 +-
 arch/arc/kernel/mcip.c                             |    2 +-
 arch/arc/kernel/smp.c                              |   14 +-
 arch/arc/kernel/time.c                             |    4 +
 arch/arc/mm/tlb.c                                  |   12 +
 arch/arc/plat-eznps/Kconfig                        |   34 +++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   75 ++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  250 ++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
 arch/arc/plat-eznps/include/plat/smp.h             |   26 ++
 arch/arc/plat-eznps/mtm.c                          |  133 +++++++++++
 arch/arc/plat-eznps/platform.c                     |   27 ++
 arch/arc/plat-eznps/smp.c                          |  149 ++++++++++++
 drivers/clocksource/Kconfig                        |    7 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   63 +++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  213 +++++++++++++++++
 40 files changed, 1576 insertions(+), 36 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c



From noamc at ezchip.com  Tue Dec  1 05:02:48 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:48 +0200
Subject: [PATCH v3 01/18] Documentation: Add EZchip vendor to binding list
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-2-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..f8b5e9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Proccessor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d4..d7bff8a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -82,6 +82,7 @@ eukrea  Eukr??a Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 focaltech	FocalTech Systems Co.,Ltd
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:49 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:49 +0200
Subject: [PATCH v3 02/18] ARC: [plat-eznps] define IPI_IRQ
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-3-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:50 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:50 +0200
Subject: [PATCH v3 03/18] clocksource: Add NPS400 timers driver
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-4-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: John Stultz <john.stultz at linaro.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 ++++
 drivers/clocksource/Kconfig                        |    7 ++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   63 ++++++++++++++++++++
 4 files changed, 82 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..c5102c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,11 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer"
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer";
+};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 71cfdf7..98b12c5 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,6 +131,13 @@ config CLKSRC_TI_32K
 	  This option enables support for Texas Instruments 32.768 Hz clocksource
 	  available on many OMAP-like platforms.
 
+config CLKSRC_NPS
+	bool "NPS400 clocksource driver" if COMPILE_TEST
+	select CLKSRC_OF if OF
+	help
+	  NPS400 clocksource support.
+	  Got 64 bit counter with update rate up to 1000MHz.
+
 config CLKSRC_STM32
 	bool "Clocksource for STM32 SoCs" if !ARCH_STM32
 	depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 56bd16e..20969b0 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
 obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..ef8f287
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clocksource.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <plat/ctop.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
+
+static cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
+
+	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(32),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nps_setup_clocksource(struct device_node *node)
+{
+	struct clocksource *clksrc = &nps_counter;
+	unsigned long rate, dt_root;
+	int ret, cluster;
+
+	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);
+
+	dt_root = of_get_flat_dt_root();
+	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);
+
+	ret = clocksource_register_hz(clksrc, rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+CLOCKSOURCE_OF_DECLARE(nps_400, "ezchip,nps400-timer",
+		       nps_setup_clocksource);
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:51 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:51 +0200
Subject: [PATCH v3 04/18] irqchip: add nps Internal and external irqchips
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-5-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  213 ++++++++++++++++++++
 3 files changed, 231 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 177f78f..b95b954 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..bb8d547
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+#include <plat/mtm.h>
+
+#define NPS_MSU_EN_CFG	0x80	/* MSU Enable Configuration Register */
+#define MSU_EN		BIT(0)  /* MSU block enable */
+#define IPI_EN		BIT(16) /* Enable service of incoming IPI Messages */
+#define GIM0_EN		BIT(17) /* Enable service of incoming GIM 0 messages */
+#define GIM1_EN		BIT(18) /* Enable service of incoming GIM 1 messages */
+
+#define NPS_GIM_P_POL	0x110	/* Peripheral interrupts source polarity */
+#define NPS_GIM_P_SENS	0x114	/* Peripheral interrupts sensitivity */
+#define GIM_UART	BIT(7)
+#define GIM_LAN_TX	(BIT(10) | BIT(25))
+#define GIM_LAN_RX	(BIT(11) | BIT(26))
+#define GIM_PERIPH_ALL	(GIM_UART | GIM_LAN_TX | GIM_LAN_RX)
+
+#define NPS_GIM_P_DST10	0x13A	/* Peripheral Interrupt Destination (LAN RX) */
+#define NPS_GIM_P_DST11	0x13B	/* Peripheral Interrupt Destination (LAN TX) */
+#define NPS_GIM_P_DST25	0x149	/* Peripheral Interrupt Destination (LAN RX) */
+#define NPS_GIM_P_DST26	0x14A	/* Peripheral Interrupt Destination (LAN TX) */
+#define DST_IS		BIT(26) /* Interrupt select for line 7 */
+
+#define NPS_GIM_P_EN	0x100	/* Peripheral interrupts source enable */
+#define NPS_GIM_P_BLK	0x118	/* Peripheral interrupts blocking for sources */
+
+/* Messaging and Scheduling Unit:
+ * Provides message management for a CPU cluster.
+ */
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	u32 value = MSU_EN | IPI_EN | GIM0_EN | GIM1_EN;
+
+	/* Enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+/* Global Interrupt Manager:
+ * Configures and manages up to 64 interrupts from peripherals,
+ * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
+ * Receives the interrupts and transmits them to relevant CPU.
+ */
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_addr, reg_val;
+
+	/* IRQ polarity, low or high level, negative or positive edge */
+	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_POL);
+	reg_val = ioread32be(reg_addr);
+	reg_val &= ~GIM_PERIPH_ALL;
+	iowrite32be(reg_val, reg_addr);
+
+	/* IRQ type level or edge */
+	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_SENS);
+	reg_val = ioread32be(reg_addr);
+	reg_val |= GIM_LAN_TX;
+	iowrite32be(reg_val, reg_addr);
+
+	/* GIM interrupt select type for debug LAN interrupts (both sides) */
+	reg_val = DST_IS;
+	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST10);
+	iowrite32be(reg_val, reg_addr);
+	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST11);
+	iowrite32be(reg_val, reg_addr);
+	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST25);
+	iowrite32be(reg_val, reg_addr);
+	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST26);
+	iowrite32be(reg_val, reg_addr);
+
+	/* CTOP IRQ lines should be defined as blocking in GIM */
+	iowrite32be(GIM_PERIPH_ALL,
+		    nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_BLK));
+
+	/* Enable CTOP IRQ lines in GIM */
+	iowrite32be(GIM_PERIPH_ALL,
+		    nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_EN));
+}
+
+/*
+ * NPS400 core includes a Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ *
+ * NOTE: AUX_IENABLE and CTOP_AUX_IACK are auxiliary registers
+ * with private HW copy per CPU.
+ */
+
+static void nps400_irq_mask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << data->hwirq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << data->hwirq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
+
+	/* Don't ack before all device access is done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
+}
+
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hw)
+{
+	switch (irq) {
+	case TIMER0_IRQ:
+#if defined(CONFIG_SMP)
+	case IPI_IRQ:
+#endif
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
+					 handle_percpu_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	eznps_configure_msu();
+	eznps_configure_gim();
+
+	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	/* with this we don't need to export nps400_root_domain */
+	irq_set_default_host(nps400_root_domain);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:53 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:53 +0200
Subject: [PATCH v3 06/18] ARC: rwlock: disable interrupts in !LLSC variant
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-7-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

If we hold rwlock and interrupt occures we may
end up spinning on it for ever during softirq.
Note that this lock is an internal lock
and since the lock is free to be used from any context,
the lock needs to be IRQ-safe.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:52 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:52 +0200
Subject: [PATCH v3 05/18] ARC: Set vmalloc size from configuration
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-6-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

This introduce build error since PGDIR_SIZE() cannot use "1UL"
ibecause it is called from mm/tlbex.S by VMALLOC_START.
Using _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/pgtable.h   |    2 +-
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..689ccb3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -468,6 +468,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 1d694c1..8a77ccd 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -109,18 +109,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index daf2bf5..843e1a5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:54 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:54 +0200
Subject: [PATCH v3 07/18] ARC: rename smp operation init_irq_cpu() to
 init_per_cpu()
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-8-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This will better reflect its description i.e. "any needed setup..."
and not just do an "IPI request".

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/smp.h |    4 ++--
 arch/arc/kernel/irq.c      |    4 ++--
 arch/arc/kernel/mcip.c     |    2 +-
 arch/arc/kernel/smp.c      |    4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 133c867..9913804 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  * @init_early_smp:	A SMP specific h/w block can init itself
  * 			Could be common across platforms so not covered by
  * 			mach_desc->init_early()
- * @init_irq_cpu:	Called for each core so SMP h/w block driver can do
+ * @init_per_cpu:	Called for each core so SMP h/w block driver can do
  * 			any needed setup per cpu (e.g. IPI request)
  * @cpu_kick:		For Master to kickstart a cpu (optionally at a PC)
  * @ipi_send:		To send IPI to a @cpu
@@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
 struct plat_smp_ops {
 	const char 	*info;
 	void		(*init_early_smp)(void);
-	void		(*init_irq_cpu)(int cpu);
+	void		(*init_per_cpu)(int cpu);
 	void		(*cpu_kick)(int cpu, unsigned long pc);
 	void		(*ipi_send)(int cpu);
 	void		(*ipi_clear)(int irq);
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 2ee2265..a650650 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -29,8 +29,8 @@ void __init init_IRQ(void)
 
 #ifdef CONFIG_SMP
 	/* a SMP H/w block could do IPI IRQ request here */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(smp_processor_id());
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(smp_processor_id());
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(smp_processor_id());
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 74a9b07..bd237ac 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
 	.info		= smp_cpuinfo_buf,
 	.init_early_smp	= mcip_probe_n_setup,
-	.init_irq_cpu	= mcip_setup_per_cpu,
+	.init_per_cpu	= mcip_setup_per_cpu,
 	.ipi_send	= mcip_ipi_send,
 	.ipi_clear	= mcip_ipi_clear,
 };
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5805878..0b061a4 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -132,8 +132,8 @@ void start_kernel_secondary(void)
 	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
 	/* Some SMP H/w setup - for each cpu */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(cpu);
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(cpu);
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:55 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:55 +0200
Subject: [PATCH v3 08/18] ARC: Mark secondary cpu online only after all HW
 setup is done
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-9-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up().
For ARC it returns as soon as new cpu's status becomes online,
However secondary may still do HW initializing,
machine or platform hook level.

So turn secondary online only after all HW setup is done.
Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/smp.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 0b061a4..bc0e4f6 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,11 +126,6 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
-	notify_cpu_starting(cpu);
-	set_cpu_online(cpu, true);
-
-	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
-
 	/* Some SMP H/w setup - for each cpu */
 	if (plat_smp_ops.init_per_cpu)
 		plat_smp_ops.init_per_cpu(cpu);
@@ -138,6 +133,11 @@ void start_kernel_secondary(void)
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
 
+	notify_cpu_starting(cpu);
+	set_cpu_online(cpu, true);
+
+	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
+
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:56 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:56 +0200
Subject: [PATCH v3 09/18] ARC: add CONFIG_CLKSRC_OF support to time_init()
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-10-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

External clock source can be used if included by one of
DTS file of a chosen platform.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/time.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..ea0c47d 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -283,6 +283,10 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_probe();
+#endif
+
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
 }
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:57 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:57 +0200
Subject: [PATCH v3 10/18] ARC: [plat-eznps] Add eznps board defconfig and dts
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-11-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   76 +++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..4d4832a
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	/* 512M */
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+		};
+
+		uart at f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clock-frequency = <83333333>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		ethernet at f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:59 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:59 +0200
Subject: [PATCH v3 12/18] ARC: [plat-eznps] Use dedicated user stack top
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-13-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 8a77ccd..41142ab 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -122,7 +122,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 843e1a5..01f85e5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:02:58 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:02:58 +0200
Subject: [PATCH v3 11/18] ARC: [plat-eznps] Add eznps platform
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-12-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   75 +++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  250 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 ++++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   26 ++++
 arch/arc/plat-eznps/mtm.c               |  133 ++++++++++++++++
 arch/arc/plat-eznps/platform.c          |   27 ++++
 arch/arc/plat-eznps/smp.c               |  149 ++++++++++++++++++
 10 files changed, 767 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b..abb1897 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4257,6 +4257,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc at ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare at suse.com>
 L:	lm-sensors at lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..051fdca
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_NPS
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..b4dee38
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .init.text, "ax", at progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; For HW thread != 0 there is no work.
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; With no cache coherency mechanism D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; check for boot CPU
+	lr	r3, [CTOP_AUX_GLOBAL_ID]
+	cmp	r3, 0
+	jeq	stext
+
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..25a08dc
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#define NPS_HOST_REG_BASE			0xF6000000
+
+/* core auxiliary registers */
+#ifdef __ASSEMBLY__
+#define CTOP_AUX_BASE				(-0x800)
+#else
+#define CTOP_AUX_BASE				0xFFFFF800
+#endif
+
+#define CTOP_AUX_GLOBAL_ID			(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID			(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID			(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID			(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID		(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID		(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID			(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL			(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY			(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC				(CTOP_AUX_BASE + 0x030)
+#define AUX_REG_TSI1				(CTOP_AUX_BASE + 0x050)
+#define CTOP_AUX_EFLAGS				(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK				(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1				(CTOP_AUX_BASE + 0x08C)
+#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		0x3e6f7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
+#define CTOP_INST_SCHD_RW			0x3e6f7004
+#define CTOP_INST_SCHD_RD			0x3e6f7084
+#define CTOP_INST_ASRI_0_R3			0x3b56003e
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED		_BITUL(28)
+
+#ifndef __ASSEMBLY__
+#define NPS_MSU_BLKID				0x018
+#define NPS_CRG_BLKID				0x480
+#define NPS_CRG_SYNC_BIT			_BITUL(0)
+#define NPS_GIM_BLKID				0x5C0
+
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physically,
+ * and not like the id's physically came with each cluster.
+ * Below table is 4x4 mesh of core clusters as it layout on chip.
+ * Cluster ids are in format: logical (physical)
+ *
+ *    -----------------   ------------------
+ * 3 |  5 (3)   7 (7)  | | 13 (11)   15 (15)|
+ *
+ * 2 |  4 (2)   6 (6)  | | 12 (10)   14 (14)|
+ *    -----------------   ------------------
+ * 1 |  1 (1)   3 (5)  | |  9  (9)   11 (13)|
+ *
+ * 0 |  0 (0)   2 (4)  | |  8  (8)   10 (12)|
+ *    -----------------   ------------------
+ *       0       1            2        3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	__asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32     base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			st_cnt:8, __reserved:8,
+			hs_cnt:8, __reserved1:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+
+/* CRG registers */
+#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+#endif /* __ASEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..06b59bd
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern void res_service(void);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..aaaaffd
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	log_nat = ilog2(nat);
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..12efeb6
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <asm/mach_desc.h>
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..87849a3
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = (u32)res_service;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+static void eznps_init_per_cpu(int cpu)
+{
+	smp_ipi_irq_setup(cpu, IPI_IRQ);
+
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+	.init_per_cpu	= eznps_init_per_cpu,
+};
+
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:03:00 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:03:00 +0200
Subject: [PATCH v3 13/18] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-14-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We need our own implementaions since we lack LLSC support.
Our extended ISA provided with optimized solution for all 32bit
operations we see in these three headers.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/atomic.h  |   79 +++++++++++++++++++++++++++++++++++-
 arch/arc/include/asm/bitops.h  |   54 +++++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h |   87 +++++++++++++++++++++++++++++++++-------
 3 files changed, 202 insertions(+), 18 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index 7730d30..a626996 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #define atomic_read(v)  READ_ONCE((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -180,12 +181,84 @@ ATOMIC_OP(andnot, &= ~, bic)
 ATOMIC_OP(or, |=, or)
 ATOMIC_OP(xor, ^=, xor)
 
-#undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
-#undef ATOMIC_OP
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	temp c_op i;							\
+									\
+	return temp;							\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..5a29185 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,7 @@
 #include <asm/smp.h>
 #endif
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +156,53 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#else /* CONFIG_ARC_PLAT_EZNPS */
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	nr = old = (1UL << (nr & 0x1f));				\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	return (old & nr) != 0;					\
+}
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +244,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#else
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..6d320d3 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -66,21 +67,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
 
 #endif /* CONFIG_ARC_HAS_LLSC */
 
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
-				(unsigned long)(o), (unsigned long)(n)))
-
-/*
- * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
- * just to gaurantee semantics.
- * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
- * which also happens to be atomic_ops_lock.
- *
- * Thus despite semantically being different, implementation of atomic_cmpxchg()
- * is same as cmpxchg().
- */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-
-
 /*
  * xchg (reg with memory) based on "Native atomic" EX insn
  */
@@ -143,6 +129,63 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
 
 #endif
 
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	/*
+	 * Explicit full memory barrier needed before/after
+	 */
+	smp_mb();
+
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	smp_mb();
+
+	return new;
+}
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		/*
+		 * Explicit full memory barrier needed before/after
+		 */
+		smp_mb();
+
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		smp_mb();
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 /*
  * "atomic" variant of xchg()
  * REQ: It needs to follow the same serialization rules as other atomic_xxx()
@@ -158,4 +201,18 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+
+/*
+ * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
+ * just to gaurantee semantics.
+ * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
+ * which also happens to be atomic_ops_lock.
+ *
+ * Thus despite semantically being different, implementation of atomic_cmpxchg()
+ * is same as cmpxchg().
+ */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
 #endif
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:03:01 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:03:01 +0200
Subject: [PATCH v3 14/18] ARC: [plat-eznps] Use dedicated SMP barriers
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-15-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..a559732 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,7 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +42,13 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:03:02 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:03:02 +0200
Subject: [PATCH v3 15/18] ARC: [plat-eznps] Use dedicated identity auxiliary
 register.
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-16-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 5d446df..6f4cb0d 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -67,9 +70,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -107,6 +117,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:03:03 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:03:03 +0200
Subject: [PATCH v3 16/18] ARC: [plat-eznps] Use dedicated cpu_relax()
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-17-git-send-email-noamc@ezchip.com>

From: Tal Zilcer <talz at ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Implementing cpu_relax_lowlatency() with barrier()
Since with current semantics of cpu_relax() it may take a
while till yielded CPU will get back.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 41142ab..974b878 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,9 +57,18 @@ struct task_struct;
  * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
  * get optimised away by gcc
  */
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
+#else
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#endif
 
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax_lowlatency() cpu_relax()
+#else
+#define cpu_relax_lowlatency() barrier()
+#endif
 
 #define copy_segments(tsk, mm)      do { } while (0)
 #define release_segments(mm)        do { } while (0)
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:03:04 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:03:04 +0200
Subject: [PATCH v3 17/18] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-18-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1



From noamc at ezchip.com  Tue Dec  1 05:03:05 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 1 Dec 2015 15:03:05 +0200
Subject: [PATCH v3 18/18] ARC: Add eznps platform to Kconfig and Makefile
In-Reply-To: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
Message-ID: <1448974985-11487-19-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 689ccb3..8153b79 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index cf0cf34..1357e48 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,11 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1



From marc.zyngier at arm.com  Tue Dec  1 05:29:26 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 01 Dec 2015 13:29:26 +0000
Subject: [PATCH v3 04/18] irqchip: add nps Internal and external irqchips
In-Reply-To: <1448974985-11487-5-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-5-git-send-email-noamc@ezchip.com>
Message-ID: <565DA0B6.5080903@arm.com>

On 01/12/15 13:02, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> Adding EZchip NPS400 support.
> NPS internal interrupts are internally handled at
> Multi Thread Manager (MTM) that is signaled for deactivating
> an interrupt.
> External interrupts is handled also at Global Interrupt
> Controller (GIC) e.g. serial and network devices.
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Jason Cooper <jason at lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
>  drivers/irqchip/Makefile                           |    1 +
>  drivers/irqchip/irq-eznps.c                        |  213 ++++++++++++++++++++
>  3 files changed, 231 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
>  create mode 100644 drivers/irqchip/irq-eznps.c
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
> new file mode 100644
> index 0000000..888b2b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
> @@ -0,0 +1,17 @@
> +EZchip NPS Interrupt Controller
> +
> +Required properties:
> +
> +- compatible : should be "ezchip,nps400-ic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> +  interrupt source. The value shall be 1.

So you never have to encode the interrupt trigger type? Do you only
support edge or level?

> +
> +
> +Example:
> +
> +intc: interrupt-controller {
> +	compatible = "ezchip,nps400-ic";
> +	interrupt-controller;
> +	#interrupt-cells = <1>;
> +};
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 177f78f..b95b954 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
>  obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
>  obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
>  obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
> +obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
> diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
> new file mode 100644
> index 0000000..bb8d547
> --- /dev/null
> +++ b/drivers/irqchip/irq-eznps.c
> @@ -0,0 +1,213 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/irqdomain.h>
> +#include <linux/irqchip.h>
> +#include <asm/irq.h>
> +#include <plat/mtm.h>
> +
> +#define NPS_MSU_EN_CFG	0x80	/* MSU Enable Configuration Register */
> +#define MSU_EN		BIT(0)  /* MSU block enable */
> +#define IPI_EN		BIT(16) /* Enable service of incoming IPI Messages */
> +#define GIM0_EN		BIT(17) /* Enable service of incoming GIM 0 messages */
> +#define GIM1_EN		BIT(18) /* Enable service of incoming GIM 1 messages */
> +
> +#define NPS_GIM_P_POL	0x110	/* Peripheral interrupts source polarity */
> +#define NPS_GIM_P_SENS	0x114	/* Peripheral interrupts sensitivity */
> +#define GIM_UART	BIT(7)
> +#define GIM_LAN_TX	(BIT(10) | BIT(25))
> +#define GIM_LAN_RX	(BIT(11) | BIT(26))
> +#define GIM_PERIPH_ALL	(GIM_UART | GIM_LAN_TX | GIM_LAN_RX)
> +
> +#define NPS_GIM_P_DST10	0x13A	/* Peripheral Interrupt Destination (LAN RX) */
> +#define NPS_GIM_P_DST11	0x13B	/* Peripheral Interrupt Destination (LAN TX) */
> +#define NPS_GIM_P_DST25	0x149	/* Peripheral Interrupt Destination (LAN RX) */
> +#define NPS_GIM_P_DST26	0x14A	/* Peripheral Interrupt Destination (LAN TX) */
> +#define DST_IS		BIT(26) /* Interrupt select for line 7 */
> +
> +#define NPS_GIM_P_EN	0x100	/* Peripheral interrupts source enable */
> +#define NPS_GIM_P_BLK	0x118	/* Peripheral interrupts blocking for sources */

Are these the interrupts the peripherals are using? If yes, they really
have nothing to do here...

> +
> +/* Messaging and Scheduling Unit:
> + * Provides message management for a CPU cluster.
> + */
> +static void __init eznps_configure_msu(void)
> +{
> +	int cpu;
> +	u32 value = MSU_EN | IPI_EN | GIM0_EN | GIM1_EN;
> +
> +	/* Enable IPI and GIM messages on all clusters */
> +	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
> +		iowrite32be(value,
> +			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
> +}
> +
> +/* Global Interrupt Manager:
> + * Configures and manages up to 64 interrupts from peripherals,
> + * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
> + * Receives the interrupts and transmits them to relevant CPU.
> + */
> +static void __init eznps_configure_gim(void)
> +{
> +	u32 reg_addr, reg_val;
> +
> +	/* IRQ polarity, low or high level, negative or positive edge */
> +	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_POL);
> +	reg_val = ioread32be(reg_addr);
> +	reg_val &= ~GIM_PERIPH_ALL;
> +	iowrite32be(reg_val, reg_addr);
> +
> +	/* IRQ type level or edge */
> +	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_SENS);
> +	reg_val = ioread32be(reg_addr);
> +	reg_val |= GIM_LAN_TX;
> +	iowrite32be(reg_val, reg_addr);
> +
> +	/* GIM interrupt select type for debug LAN interrupts (both sides) */
> +	reg_val = DST_IS;
> +	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST10);
> +	iowrite32be(reg_val, reg_addr);
> +	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST11);
> +	iowrite32be(reg_val, reg_addr);
> +	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST25);
> +	iowrite32be(reg_val, reg_addr);
> +	reg_addr = nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_DST26);
> +	iowrite32be(reg_val, reg_addr);
> +
> +	/* CTOP IRQ lines should be defined as blocking in GIM */
> +	iowrite32be(GIM_PERIPH_ALL,
> +		    nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_BLK));
> +
> +	/* Enable CTOP IRQ lines in GIM */
> +	iowrite32be(GIM_PERIPH_ALL,
> +		    nps_host_reg_non_cl(NPS_GIM_BLKID, NPS_GIM_P_EN));
> +}
> +
> +/*
> + * NPS400 core includes a Interrupt Controller (IC) support.
> + * All cores can deactivate level irqs at first level control
> + * at cores mesh layer called MTM.
> + * For devices out side chip e.g. uart, network there is another
> + * level called Global Interrupt Manager (GIM).
> + * This second level can control level and edge interrupt.
> + *
> + * NOTE: AUX_IENABLE and CTOP_AUX_IACK are auxiliary registers
> + * with private HW copy per CPU.
> + */
> +
> +static void nps400_irq_mask(struct irq_data *data)
> +{
> +	unsigned int ienb;
> +
> +	ienb = read_aux_reg(AUX_IENABLE);
> +	ienb &= ~(1 << data->hwirq);
> +	write_aux_reg(AUX_IENABLE, ienb);
> +}
> +
> +static void nps400_irq_unmask(struct irq_data *data)
> +{
> +	unsigned int ienb;
> +
> +	ienb = read_aux_reg(AUX_IENABLE);
> +	ienb |= (1 << data->hwirq);
> +	write_aux_reg(AUX_IENABLE, ienb);
> +}
> +
> +static void nps400_irq_eoi_global(struct irq_data *data)
> +{
> +	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
> +
> +	/* Don't ack before all device access is done */
> +	mb();
> +
> +	__asm__ __volatile__ (
> +	"       .word %0\n"
> +	:
> +	: "i"(CTOP_INST_RSPI_GIC_0_R12)
> +	: "memory");

Silly question: why cannot you just write the actual instruction instead
of shoving the instruction like this? Also, .inst would be more
appropriate...

> +}
> +
> +static void nps400_irq_eoi(struct irq_data *data)
> +{
> +	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
> +}
> +
> +
> +static struct irq_chip nps400_irq_chip_fasteoi = {
> +	.name		= "NPS400 IC Global",
> +	.irq_mask	= nps400_irq_mask,
> +	.irq_unmask	= nps400_irq_unmask,
> +	.irq_eoi	= nps400_irq_eoi_global,
> +};
> +
> +static struct irq_chip nps400_irq_chip_percpu = {
> +	.name		= "NPS400 IC",
> +	.irq_mask	= nps400_irq_mask,
> +	.irq_unmask	= nps400_irq_unmask,
> +	.irq_eoi	= nps400_irq_eoi,
> +};
> +
> +static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
> +			  irq_hw_number_t hw)
> +{
> +	switch (irq) {
> +	case TIMER0_IRQ:
> +#if defined(CONFIG_SMP)
> +	case IPI_IRQ:
> +#endif
> +		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
> +					 handle_percpu_irq);
> +	break;
> +	default:
> +		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
> +					 handle_fasteoi_irq);
> +	break;
> +	}

No. This is just wrong. Either you get per interrupt information from
the device tree to configure the interrupt the right way, or you have
different interrupt controllers for each device.

But using the Linux irq number is always wrong. You should only consider
the hwirq.

> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops nps400_irq_ops = {
> +	.xlate = irq_domain_xlate_onecell,
> +	.map = nps400_irq_map,
> +};
> +
> +static struct irq_domain *nps400_root_domain;
> +
> +static int __init nps400_of_init(struct device_node *node,
> +				 struct device_node *parent)
> +{
> +	if (parent)
> +		panic("DeviceTree incore ic not a root irq controller\n");
> +
> +	eznps_configure_msu();
> +	eznps_configure_gim();
> +
> +	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
> +						   &nps400_irq_ops, NULL);

And that's why you can get away with the above horror. Don't use legacy
domains. This stuff is by no mean legacy.

> +
> +	if (!nps400_root_domain)
> +		panic("nps400 root irq domain not avail\n");
> +
> +	/* with this we don't need to export nps400_root_domain */
> +	irq_set_default_host(nps400_root_domain);
> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From CARLOS.PALMINHA at synopsys.com  Tue Dec  1 11:39:30 2015
From: CARLOS.PALMINHA at synopsys.com (Carlos Palminha)
Date: Tue, 1 Dec 2015 19:39:30 +0000
Subject: Non existing DMA functions in ARC: dma_alloc_attrs, dma_free_attrs,
 dma_mmap_attrs
Message-ID: <565DF772.4060802@synopsys.com>

Hi guys,

I'm bringing up a new ARC PGU driver for DRM framework with latest kernel tree.
I'm using ARC AXS101 as a base and selected one the DRM required config: HAVE_DMA_ATTRS due to some memory allocation helpers in DRM.

I'm getting some errors with DMA functions not implemented in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs

Any clue?

Regards,
C.Palminha

---
include/linux/dma-mapping.h: In function ?dma_alloc_writecombine?:
include/linux/dma-mapping.h:283:2: error: implicit declaration of function ?dma_alloc_attrs? [-Werror=implicit-function-declaration]
  return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
  ^
include/linux/dma-mapping.h:283:2: warning: return makes pointer from integer without a cast [enabled by default]
include/linux/dma-mapping.h: In function ?dma_free_writecombine?:
include/linux/dma-mapping.h:291:2: error: implicit declaration of function ?dma_free_attrs? [-Werror=implicit-function-declaration]
  return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
  ^
include/linux/dma-mapping.h:291:2: warning: ?return? with a value, in function returning void [enabled by default]
include/linux/dma-mapping.h: In function ?dma_mmap_writecombine?:
include/linux/dma-mapping.h:301:2: error: implicit declaration of function ?dma_mmap_attrs? [-Werror=implicit-function-declaration]
  return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);



From Vineet.Gupta1 at synopsys.com  Tue Dec  1 22:32:25 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 2 Dec 2015 06:32:25 +0000
Subject: Non existing DMA functions in ARC: dma_alloc_attrs,
 dma_free_attrs, dma_mmap_attrs
References: <565DF772.4060802@synopsys.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D45E5@IN01WEMBXA.internal.synopsys.com>

On Wednesday 02 December 2015 01:09 AM, Carlos Palminha wrote:
> Hi guys,
>
> I'm bringing up a new ARC PGU driver for DRM framework with latest kernel tree.
> I'm using ARC AXS101 as a base and selected one the DRM required config: HAVE_DMA_ATTRS due to some memory allocation helpers in DRM.
>
> I'm getting some errors with DMA functions not implemented in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>
> Any clue?
>
> Regards,
> C.Palminha
>
> ---
> include/linux/dma-mapping.h: In function ?dma_alloc_writecombine?:
> include/linux/dma-mapping.h:283:2: error: implicit declaration of function ?dma_alloc_attrs? [-Werror=implicit-function-declaration]
>   return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);

This is because ARC port current lacks support for dma_attr_t and associated helpers.
There is a series in flight in linux-next, by Christoph, which already addresses that.

You can either cherry-pick those or in the interim use the hack attached.

P.S. Per your comment at top, I'm assuming you are working off of mainline 4.3 or 4.4

-Vineet

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-donot-merge-minimal-dma_attr_t-support-for-ARC.patch
Type: text/x-patch
Size: 1981 bytes
Desc: 0001-donot-merge-minimal-dma_attr_t-support-for-ARC.patch
URL: <http://lists.infradead.org/pipermail/linux-snps-arc/attachments/20151202/e8a2bb0b/attachment.bin>

From noamc at ezchip.com  Wed Dec  2 07:08:51 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 2 Dec 2015 15:08:51 +0000
Subject: [PATCH v3 04/18] irqchip: add nps Internal and external irqchips
In-Reply-To: <565DA0B6.5080903@arm.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-5-git-send-email-noamc@ezchip.com>
 <565DA0B6.5080903@arm.com>
Message-ID: <DB5PR02MB114150510832BA29D46A8A4AD60E0@DB5PR02MB1141.eurprd02.prod.outlook.com>

>From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
>Sent: Tuesday, December 01, 2015 3:29 PM

> +  interrupt source. The value shall be 1.

>So you never have to encode the interrupt trigger type? Do you only support edge or level?
I Always use level sensitive.

> +
> +#define NPS_GIM_P_EN	0x100	/* Peripheral interrupts source enable */
> +#define NPS_GIM_P_BLK	0x118	/* Peripheral interrupts blocking for sources */

>>Are these the interrupts the peripherals are using? If yes, they really have nothing to do here...
I will move this from here 
>> +	__asm__ __volatile__ (
>> +	"       .word %0\n"
>> +	:
>> +	: "i"(CTOP_INST_RSPI_GIC_0_R12)
>> +	: "memory");

>Silly question: why cannot you just write the actual instruction instead of shoving the instruction like this? Also, .inst would be more appropriate...
[Noam Camus] Since this is instruction that yet is not part of up-streamed binutils of ARC.  Now ARC maintainer can build our kernel with generic ARC toolchain. 

>> +static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
>> +			  irq_hw_number_t hw)
>> +{
>> +	switch (irq) {
>> +	case TIMER0_IRQ:
>> +#if defined(CONFIG_SMP)
>> +	case IPI_IRQ:
>> +#endif
>> +		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
>> +					 handle_percpu_irq);
>> +	break;
>> +	default:
>> +		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
>> +					 handle_fasteoi_irq);
>> +	break;
>> +	}

>No. This is just wrong. Either you get per interrupt information from the device tree to configure the interrupt the right way, or you have different interrupt controllers for each device.
I am not sure how you want me to get it from DTB? Please refer to some reference.

>But using the Linux irq number is always wrong. You should only consider the hwirq.
I will change

> +
> +	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
> +						   &nps400_irq_ops, NULL);

>And that's why you can get away with the above horror. Don't use legacy domains. This stuff is by no mean legacy.
So what is my alternative here?

-Noam


From CARLOS.PALMINHA at synopsys.com  Wed Dec  2 16:24:02 2015
From: CARLOS.PALMINHA at synopsys.com (Carlos Palminha)
Date: Thu, 3 Dec 2015 00:24:02 +0000
Subject: Non existing DMA functions in ARC: dma_alloc_attrs,
 dma_free_attrs, dma_mmap_attrs
In-Reply-To: <C060B4F571DB524BB6D72E2C236D8FB002199FE6@DE02WEMBXB.internal.synopsys.com>
References: <C060B4F571DB524BB6D72E2C236D8FB002199FE6@DE02WEMBXB.internal.synopsys.com>
Message-ID: <565F8BA2.4000506@synopsys.com>

Hi Vineet,

I cherry picked those commits and now i'm getting a different error.

any clue? Am i testing "untested" code?! :)

Regards,
C.Palminha

---
  CC      init/do_mounts.o
In file included from include/linux/skbuff.h:34:0,
                 from include/linux/icmpv6.h:4,
                 from include/linux/ipv6.h:71,
                 from include/net/ipv6.h:16,
                 from include/linux/sunrpc/clnt.h:27,
                 from include/linux/nfs_fs.h:30,
                 from init/do_mounts.c:32:
include/linux/dma-mapping.h: In function ?dma_set_coherent_mask?:
include/linux/dma-mapping.h:104:2: error: implicit declaration of function ?dma_supported? [-Werror=implicit-function-declaration]
  if (!dma_supported(dev, mask))
  ^
include/linux/dma-mapping.h: In function ?dma_set_mask_and_coherent?:
include/linux/dma-mapping.h:119:2: error: implicit declaration of function ?dma_set_mask? [-Werror=implicit-function-declaration]
  int rc = dma_set_mask(dev, mask);
  ^
include/linux/dma-mapping.h: In function ?dma_zalloc_coherent?:
include/linux/dma-mapping.h:190:2: error: implicit declaration of function ?dma_alloc_coherent? [-Werror=implicit-function-declaration]
  void *ret = dma_alloc_coherent(dev, size, dma_handle,
  ^
include/linux/dma-mapping.h:190:14: warning: initialization makes pointer from integer without a cast [enabled by default]
  void *ret = dma_alloc_coherent(dev, size, dma_handle,
              ^
In file included from include/linux/icmpv6.h:4:0,
                 from include/linux/ipv6.h:71,
                 from include/net/ipv6.h:16,
                 from include/linux/sunrpc/clnt.h:27,
                 from include/linux/nfs_fs.h:30,
                 from init/do_mounts.c:32:
include/linux/skbuff.h: In function ?skb_frag_dma_map?:
include/linux/skbuff.h:2510:2: error: implicit declaration of function ?dma_map_page? [-Werror=implicit-function-declaration]
  return dma_map_page(dev, skb_frag_page(frag),



On 02-12-2015 13:19, Carlos Palminha wrote:
> Hi Vineet,
> 
> I'm using drm-next (its currently based on 4.4-rc3).
> 
> Regarding linux-next DMA patches I assume you are talking about these 3 commits:
> * 19ab4d3aff0426058fe36aae4ac56320a6e4c6be
> * 8ee24f794c2dfff85930f25eab4f11a9bde7f920
> * c27a81903ba596c879a45e3028135a4f37fb1837
> 
> Regards,
> C.Palminha
> 
> -----Original Message-----
> From: Vineet Gupta 
> Sent: quarta-feira, 2 de Dezembro de 2015 06:32
> To: Carlos Palminha; linux-snps-arc at lists.infradead.org
> Cc: Alexey Brodkin
> Subject: Re: Non existing DMA functions in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
> 
> On Wednesday 02 December 2015 01:09 AM, Carlos Palminha wrote:
>> Hi guys,
>>
>> I'm bringing up a new ARC PGU driver for DRM framework with latest kernel tree.
>> I'm using ARC AXS101 as a base and selected one the DRM required config: HAVE_DMA_ATTRS due to some memory allocation helpers in DRM.
>>
>> I'm getting some errors with DMA functions not implemented in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>>
>> Any clue?
>>
>> Regards,
>> C.Palminha
>>
>> ---
>> include/linux/dma-mapping.h: In function 'dma_alloc_writecombine':
>> include/linux/dma-mapping.h:283:2: error: implicit declaration of function 'dma_alloc_attrs' [-Werror=implicit-function-declaration]
>>   return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
> 
> This is because ARC port current lacks support for dma_attr_t and associated helpers.
> There is a series in flight in linux-next, by Christoph, which already addresses that.
> 
> You can either cherry-pick those or in the interim use the hack attached.
> 
> P.S. Per your comment at top, I'm assuming you are working off of mainline 4.3 or 4.4
> 
> -Vineet
> 


From CARLOS.PALMINHA at synopsys.com  Wed Dec  2 05:19:40 2015
From: CARLOS.PALMINHA at synopsys.com (Carlos Palminha)
Date: Wed, 2 Dec 2015 13:19:40 +0000
Subject: Non existing DMA functions in ARC: dma_alloc_attrs,
 dma_free_attrs, dma_mmap_attrs
Message-ID: <C060B4F571DB524BB6D72E2C236D8FB002199FE6@DE02WEMBXB.internal.synopsys.com>

Hi Vineet,

I'm using drm-next (its currently based on 4.4-rc3).

Regarding linux-next DMA patches I assume you are talking about these 3 commits:
* 19ab4d3aff0426058fe36aae4ac56320a6e4c6be
* 8ee24f794c2dfff85930f25eab4f11a9bde7f920
* c27a81903ba596c879a45e3028135a4f37fb1837

Regards,
C.Palminha

-----Original Message-----
From: Vineet Gupta 
Sent: quarta-feira, 2 de Dezembro de 2015 06:32
To: Carlos Palminha; linux-snps-arc at lists.infradead.org
Cc: Alexey Brodkin
Subject: Re: Non existing DMA functions in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs

On Wednesday 02 December 2015 01:09 AM, Carlos Palminha wrote:
> Hi guys,
>
> I'm bringing up a new ARC PGU driver for DRM framework with latest kernel tree.
> I'm using ARC AXS101 as a base and selected one the DRM required config: HAVE_DMA_ATTRS due to some memory allocation helpers in DRM.
>
> I'm getting some errors with DMA functions not implemented in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>
> Any clue?
>
> Regards,
> C.Palminha
>
> ---
> include/linux/dma-mapping.h: In function 'dma_alloc_writecombine':
> include/linux/dma-mapping.h:283:2: error: implicit declaration of function 'dma_alloc_attrs' [-Werror=implicit-function-declaration]
>   return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);

This is because ARC port current lacks support for dma_attr_t and associated helpers.
There is a series in flight in linux-next, by Christoph, which already addresses that.

You can either cherry-pick those or in the interim use the hack attached.

P.S. Per your comment at top, I'm assuming you are working off of mainline 4.3 or 4.4

-Vineet



From Vineet.Gupta1 at synopsys.com  Wed Dec  2 19:57:33 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 03:57:33 +0000
Subject: Non existing DMA functions in ARC: dma_alloc_attrs,
 dma_free_attrs, dma_mmap_attrs
References: <C060B4F571DB524BB6D72E2C236D8FB002199FE6@DE02WEMBXB.internal.synopsys.com>
 <565F8BA2.4000506@synopsys.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D483A@IN01WEMBXA.internal.synopsys.com>

On Thursday 03 December 2015 05:54 AM, Carlos Palminha wrote:
> Hi Vineet,
>
> I cherry picked those commits and now i'm getting a different error.
>
> any clue? Am i testing "untested" code?! :)
>
> Regards,
> C.Palminha
>
> ---
>   CC      init/do_mounts.o
> In file included from include/linux/skbuff.h:34:0,
>                  from include/linux/icmpv6.h:4,
>                  from include/linux/ipv6.h:71,
>                  from include/net/ipv6.h:16,
>                  from include/linux/sunrpc/clnt.h:27,
>                  from include/linux/nfs_fs.h:30,
>                  from init/do_mounts.c:32:
> include/linux/dma-mapping.h: In function ?dma_set_coherent_mask?:
> include/linux/dma-mapping.h:104:2: error: implicit declaration of function ?dma_supported? [-Werror=implicit-function-declaration]
>   if (!dma_supported(dev, mask))
>   ^
> include/linux/dma-mapping.h: In function ?dma_set_mask_and_coherent?:
> include/linux/dma-mapping.h:119:2: error: implicit declaration of function ?dma_set_mask? [-Werror=implicit-function-declaration]
>   int rc = dma_set_mask(dev, mask);
>   ^
> include/linux/dma-mapping.h: In function ?dma_zalloc_coherent?:
> include/linux/dma-mapping.h:190:2: error: implicit declaration of function ?dma_alloc_coherent? [-Werror=implicit-function-declaration]
>   void *ret = dma_alloc_coherent(dev, size, dma_handle,
>   ^
> include/linux/dma-mapping.h:190:14: warning: initialization makes pointer from integer without a cast [enabled by default]
>   void *ret = dma_alloc_coherent(dev, size, dma_handle,
>               ^
> In file included from include/linux/icmpv6.h:4:0,
>                  from include/linux/ipv6.h:71,
>                  from include/net/ipv6.h:16,
>                  from include/linux/sunrpc/clnt.h:27,
>                  from include/linux/nfs_fs.h:30,
>                  from init/do_mounts.c:32:
> include/linux/skbuff.h: In function ?skb_frag_dma_map?:
> include/linux/skbuff.h:2510:2: error: implicit declaration of function ?dma_map_page? [-Werror=implicit-function-declaration]
>   return dma_map_page(dev, skb_frag_page(frag),

I'm not sure what exact code you are building off - linux-next of today builds
just fine !
Can u not baseline ur work off linux-next

-Vineet


>
>
> On 02-12-2015 13:19, Carlos Palminha wrote:
>> Hi Vineet,
>>
>> I'm using drm-next (its currently based on 4.4-rc3).
>>
>> Regarding linux-next DMA patches I assume you are talking about these 3 commits:
>> * 19ab4d3aff0426058fe36aae4ac56320a6e4c6be
>> * 8ee24f794c2dfff85930f25eab4f11a9bde7f920
>> * c27a81903ba596c879a45e3028135a4f37fb1837
>>
>> Regards,
>> C.Palminha
>>
>> -----Original Message-----
>> From: Vineet Gupta 
>> Sent: quarta-feira, 2 de Dezembro de 2015 06:32
>> To: Carlos Palminha; linux-snps-arc at lists.infradead.org
>> Cc: Alexey Brodkin
>> Subject: Re: Non existing DMA functions in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>>
>> On Wednesday 02 December 2015 01:09 AM, Carlos Palminha wrote:
>>> Hi guys,
>>>
>>> I'm bringing up a new ARC PGU driver for DRM framework with latest kernel tree.
>>> I'm using ARC AXS101 as a base and selected one the DRM required config: HAVE_DMA_ATTRS due to some memory allocation helpers in DRM.
>>>
>>> I'm getting some errors with DMA functions not implemented in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>>>
>>> Any clue?
>>>
>>> Regards,
>>> C.Palminha
>>>
>>> ---
>>> include/linux/dma-mapping.h: In function 'dma_alloc_writecombine':
>>> include/linux/dma-mapping.h:283:2: error: implicit declaration of function 'dma_alloc_attrs' [-Werror=implicit-function-declaration]
>>>   return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
>> This is because ARC port current lacks support for dma_attr_t and associated helpers.
>> There is a series in flight in linux-next, by Christoph, which already addresses that.
>>
>> You can either cherry-pick those or in the interim use the hack attached.
>>
>> P.S. Per your comment at top, I'm assuming you are working off of mainline 4.3 or 4.4
>>
>> -Vineet
>>



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:40:58 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:10:58 +0530
Subject: [RFC 00/17] ARC Dwarf unwinder improvements
Message-ID: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>

Hi guys,

In light of perf -g stalling (as unwinder was taking ~3million cycles for non
existent entries), I've revamped the dwarf unwinder.

There are some optim tweaks and much of it is "De-generalization" for things
which we can safely assume on ARC.

Crude Instrumentation shows following improvements per unwinder call:
 - Avg time come down from ~4650 cycles to ~2794 cycles (+40%)
 - Max time come down 9793 cycles to 5987 cycles

This is on a SMP FPGA config @ 75 MHz

It seems much of time (65%) is taken for binary lookup thru ~12k FDE entries,
roughly 13 lookups, each likely a dcache miss.


git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc   # topic-unwinder-rework-4-instrument

-Vineet

Vineet Gupta (17):
  ARC: dw2 unwind: Elide generation of const propagated clones
  ARC: dw2 unwind: remove unused cruft
  ARC: dw2 unwind: Remove handling of for signal frame
  ARC: dw2 unwind: Remove FP based unwinding
  ARC: dw2 unwind: Better printing
  ARC: dw2 unwind: Don't verify Main FDE Table size everytime
  ARC: dw2 unwind: Refactor the FDE lookup table (eh_frame_header) code
  ARC: dw2 unwind: Don't verify FDE lookup table metadata
  ARC: dw2 unwind: Use striaght forward code to implement binary lookup
  ARC: dw2 unwind: CIE parsing/validation done only once at startup
  ARC: dw2 unwind: Elide REG_INVALID check
  ARC: dw2 unwind: Elide a loop if DW_CFA_register not present
  ARC: dw2 unwind: Assume all regs to be unsigned long
  ARC: dw2 unwind: No need for __get_user
  ARC: dw2 unwind: Single exit point for instrumentation
  ARC: dw2 unwind: skip regs not updated
  xxx: instrument

 arch/arc/include/asm/unwind.h |  47 +--
 arch/arc/kernel/Makefile      |   1 +
 arch/arc/kernel/unwind.c      | 806 ++++++++++++++++--------------------------
 3 files changed, 313 insertions(+), 541 deletions(-)

-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:40:59 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:10:59 +0530
Subject: [PATCH 01/17] ARC: dw2 unwind: Elide generation of const propagated
 clones
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-2-git-send-email-vgupta@synopsys.com>

arc_unwind_core() is entry point into the actual dwarf unwinder and it
gets called by various kernel APIs which provide the unwinding context
(e.g. current task vs. a specific task, current pt_regs vs. some other
crash context's pt_regs...)

Currently multiple const propagated clones of arc_unwind_core() are
generated, which seems superfluous. The only performance critical call
is for perf callgrap unwinding, which being in a different compilation
unit, uses ths vanilla, non cp version anyways.

So prevent the clone functions generation

bloat-o-meter report

| add/remove: 0/1 grow/shrink: 4/0 up/down: 40/-1152 (-1112)
| function                                     old     new   delta
| save_stack_trace                               4      16     +12
| save_stack_trace_tsk                           4      14     +10
| get_wchan                                      4      14     +10
| show_stacktrace                               40      48      +8
| arc_unwind_core.constprop                   1152       -   -1152

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index e7f3625a19b5..f90e5fd6d5c8 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -7,6 +7,7 @@
 
 # Pass UTS_MACHINE for user_regset definition
 CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
+CFLAGS_stacktrace.o	+= -fno-ipa-cp-clone
 
 obj-y	:= arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
 obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:02 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:02 +0530
Subject: [PATCH 04/17] ARC: dw2 unwind: Remove FP based unwinding
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-5-git-send-email-vgupta@synopsys.com>

FP is disabled for ARC and even if it was enabled, it won't help with
unwinding given ARC ABI so remove it.

Typical ABI would
 - save BLINK (return address) on stack
 - save FP on stack
 - anchor FP for this frame
 - save any callee-regs and/or carve frame for local vars

Thus FP remains fixed for frame and can be used to determine BLINK.

ARC ABI historically required saving callee-regs before anchoring FP,
thus rendering it useless for finding BLINK.

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/unwind.h | 11 +----------
 arch/arc/kernel/unwind.c      | 45 ++-----------------------------------------
 2 files changed, 3 insertions(+), 53 deletions(-)

diff --git a/arch/arc/include/asm/unwind.h b/arch/arc/include/asm/unwind.h
index 559ef55abce1..03ace2cc8bc5 100644
--- a/arch/arc/include/asm/unwind.h
+++ b/arch/arc/include/asm/unwind.h
@@ -58,17 +58,7 @@ struct unwind_frame_info {
 #define UNW_PC(frame)		((frame)->regs.r63)
 #define UNW_SP(frame)		((frame)->regs.r28)
 #define UNW_BLINK(frame)	((frame)->regs.r31)
-
-/* Rajesh FIXME */
-#ifdef CONFIG_FRAME_POINTER
 #define UNW_FP(frame)		((frame)->regs.r27)
-#define FRAME_RETADDR_OFFSET	4
-#define FRAME_LINK_OFFSET	0
-#define STACK_BOTTOM_UNW(tsk)	STACK_LIMIT((tsk)->thread.ksp)
-#define STACK_TOP_UNW(tsk)	((tsk)->thread.ksp)
-#else
-#define UNW_FP(frame)		((void)(frame), 0)
-#endif
 
 #define STACK_LIMIT(ptr)	(((ptr) - 1) & ~(THREAD_SIZE - 1))
 
@@ -128,6 +118,7 @@ extern void unwind_remove_table(void *handle, int init_only);
 #define UNW_PC(frame) ((void)(frame), 0)
 #define UNW_SP(frame) ((void)(frame), 0)
 #define UNW_FP(frame) ((void)(frame), 0)
+#define UNW_FP(frame) ((void)(frame), 0)
 
 static inline void arc_unwind_init(void)
 {
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 2f4a67f5a863..0993a81e112b 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -1057,50 +1057,9 @@ int arc_unwind(struct unwind_frame_info *frame)
 				fde = NULL;
 		}
 	}
-	if (cie == NULL || fde == NULL) {
-#ifdef CONFIG_FRAME_POINTER
-		unsigned long top, bottom;
-
-		top = STACK_TOP_UNW(frame->task);
-		bottom = STACK_BOTTOM_UNW(frame->task);
-#if FRAME_RETADDR_OFFSET < 0
-		if (UNW_SP(frame) < top && UNW_FP(frame) <= UNW_SP(frame)
-		    && bottom < UNW_FP(frame)
-#else
-		if (UNW_SP(frame) > top && UNW_FP(frame) >= UNW_SP(frame)
-		    && bottom > UNW_FP(frame)
-#endif
-		    && !((UNW_SP(frame) | UNW_FP(frame))
-			 & (sizeof(unsigned long) - 1))) {
-			unsigned long link;
-
-			if (!__get_user(link, (unsigned long *)
-					(UNW_FP(frame) + FRAME_LINK_OFFSET))
-#if FRAME_RETADDR_OFFSET < 0
-			    && link > bottom && link < UNW_FP(frame)
-#else
-			    && link > UNW_FP(frame) && link < bottom
-#endif
-			    && !(link & (sizeof(link) - 1))
-			    && !__get_user(UNW_PC(frame),
-					   (unsigned long *)(UNW_FP(frame)
-						+ FRAME_RETADDR_OFFSET)))
-			{
-				UNW_SP(frame) =
-				    UNW_FP(frame) + FRAME_RETADDR_OFFSET
-#if FRAME_RETADDR_OFFSET < 0
-				    -
-#else
-				    +
-#endif
-				    sizeof(UNW_PC(frame));
-				UNW_FP(frame) = link;
-				return 0;
-			}
-		}
-#endif
+	if (cie == NULL || fde == NULL)
 		return -ENXIO;
-	}
+
 	state.org = startLoc;
 	memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
 
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:03 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:03 +0530
Subject: [PATCH 05/17] ARC: dw2 unwind: Better printing
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-6-git-send-email-vgupta@synopsys.com>

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 0993a81e112b..2bb3c1c048bb 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -629,40 +629,40 @@ static signed fde_pointer_type(const u32 *cie)
 	return DW_EH_PE_native | DW_EH_PE_abs;
 }
 
-static int advance_loc(unsigned long delta, struct unwind_state *state)
+static int advance_loc(unsigned long delta, struct unwind_state *state, char *str)
 {
 	state->loc += delta * state->codeAlign;
 
 	/* FIXME_Rajesh: Probably we are defining for the initial range as well;
 	   return delta > 0;
 	 */
-	unw_debug("delta %3lu => loc 0x%lx: ", delta, state->loc);
+	unw_debug("%sdelta %3lu => loc 0x%lx\n", str, delta, state->loc);
 	return 1;
 }
 
 static void set_rule(uleb128_t reg, enum item_location where, uleb128_t value,
-		     struct unwind_state *state)
+		     struct unwind_state *state, char *str)
 {
 	if (reg < ARRAY_SIZE(state->regs)) {
 		state->regs[reg].where = where;
 		state->regs[reg].value = value;
 
 #ifdef UNWIND_DEBUG
-		unw_debug("r%lu: ", reg);
 		switch (where) {
 		case Nowhere:
-			unw_debug("s ");
+			unw_debug("%sr%lu: s \n", str, reg);
 			break;
 		case Memory:
-			unw_debug("c(%lu) ", value);
+			unw_debug("%sr%lu: c(%lu) \n", str, reg, value);
 			break;
 		case Register:
-			unw_debug("r(%lu) ", value);
+			unw_debug("%sr%lu: r(%lu) \n", str, reg, value);
 			break;
 		case Value:
-			unw_debug("v(%lu) ", value);
+			unw_debug("%sr%lu: v(%lu) \n", str, reg, value);
 			break;
 		default:
+			unw_debug("%sr%lu: ???\n", str, reg);
 			break;
 		}
 #endif
@@ -689,6 +689,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 			return result;
 	}
 	for (ptr.p8 = start; result && ptr.p8 < end;) {
+		char *str = NULL;
 		switch (*ptr.p8 >> 6) {
 			uleb128_t value;
 
@@ -707,59 +708,52 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 				unw_debug("cfa_set_loc: 0x%lx ", state->loc);
 				break;
 			case DW_CFA_advance_loc1:
-				unw_debug("\ncfa advance loc1:");
+				str = "cfa advance loc1:";
 				result = ptr.p8 < end
-				    && advance_loc(*ptr.p8++, state);
+				    && advance_loc(*ptr.p8++, state, str);
 				break;
 			case DW_CFA_advance_loc2:
 				value = *ptr.p8++;
 				value += *ptr.p8++ << 8;
-				unw_debug("\ncfa advance loc2:");
+				str = "cfa advance loc2:";
 				result = ptr.p8 <= end + 2
-				    /* && advance_loc(*ptr.p16++, state); */
-				    && advance_loc(value, state);
+				    /* && advance_loc(*ptr.p16++, state, str); */
+				    && advance_loc(value, state, str);
 				break;
 			case DW_CFA_advance_loc4:
-				unw_debug("\ncfa advance loc4:");
+				str = "cfa advance loc4:";
 				result = ptr.p8 <= end + 4
-				    && advance_loc(*ptr.p32++, state);
+				    && advance_loc(*ptr.p32++, state, str);
 				break;
 			case DW_CFA_offset_extended:
 				value = get_uleb128(&ptr.p8, end);
-				unw_debug("cfa_offset_extended: ");
-				set_rule(value, Memory,
-					 get_uleb128(&ptr.p8, end), state);
+				str = "cfa_offset_extended: ";
+				set_rule(value, Memory, get_uleb128(&ptr.p8, end), state, str);
 				break;
 			case DW_CFA_val_offset:
 				value = get_uleb128(&ptr.p8, end);
-				set_rule(value, Value,
-					 get_uleb128(&ptr.p8, end), state);
+				set_rule(value, Value, get_uleb128(&ptr.p8, end), state, str);
 				break;
 			case DW_CFA_offset_extended_sf:
 				value = get_uleb128(&ptr.p8, end);
-				set_rule(value, Memory,
-					 get_sleb128(&ptr.p8, end), state);
+				set_rule(value, Memory, get_sleb128(&ptr.p8, end), state, str);
 				break;
 			case DW_CFA_val_offset_sf:
 				value = get_uleb128(&ptr.p8, end);
-				set_rule(value, Value,
-					 get_sleb128(&ptr.p8, end), state);
+				set_rule(value, Value, get_sleb128(&ptr.p8, end), state, str);
 				break;
 			case DW_CFA_restore_extended:
-				unw_debug("cfa_restore_extended: ");
+				str = "cfa_restore_extended: ";
 			case DW_CFA_undefined:
-				unw_debug("cfa_undefined: ");
+				str = "cfa_undefined: ";
 			case DW_CFA_same_value:
-				unw_debug("cfa_same_value: ");
-				set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0,
-					 state);
+				str = "cfa_same_value: ";
+				set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0, state, str);
 				break;
 			case DW_CFA_register:
-				unw_debug("cfa_register: ");
+				str = "cfa_register: ";
 				value = get_uleb128(&ptr.p8, end);
-				set_rule(value,
-					 Register,
-					 get_uleb128(&ptr.p8, end), state);
+				set_rule(value, Register, get_uleb128(&ptr.p8, end), state, str);
 				break;
 			case DW_CFA_remember_state:
 				unw_debug("cfa_remember_state: ");
@@ -798,8 +792,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 				/*nobreak*/
 			case DW_CFA_def_cfa_offset:
 				state->cfa.offs = get_uleb128(&ptr.p8, end);
-				unw_debug("cfa_def_cfa_offset: 0x%lx ",
-					  state->cfa.offs);
+				unw_debug("cfa_def_cfa_offset: r%ld: %ld\n",
+					  state->cfa.reg, state->cfa.offs);
 				break;
 			case DW_CFA_def_cfa_sf:
 				state->cfa.reg = get_uleb128(&ptr.p8, end);
@@ -824,7 +818,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 					 Memory,
 					 (uleb128_t) 0 - get_uleb128(&ptr.p8,
 								     end),
-					 state);
+					 state, str);
 				break;
 			case DW_CFA_GNU_window_save:
 			default:
@@ -834,18 +828,17 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 			}
 			break;
 		case 1:
-			unw_debug("\ncfa_adv_loc: ");
-			result = advance_loc(*ptr.p8++ & 0x3f, state);
+			str = "cfa_adv_loc: ";
+			result = advance_loc(*ptr.p8++ & 0x3f, state, str);
 			break;
 		case 2:
-			unw_debug("cfa_offset: ");
+			str = "cfa_offset: ";
 			value = *ptr.p8++ & 0x3f;
-			set_rule(value, Memory, get_uleb128(&ptr.p8, end),
-				 state);
+			set_rule(value, Memory, get_uleb128(&ptr.p8, end), state, str);
 			break;
 		case 3:
-			unw_debug("cfa_restore: ");
-			set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
+			str = "cfa_restore: ";
+			set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state, str);
 			break;
 		}
 
@@ -879,15 +872,16 @@ int arc_unwind(struct unwind_frame_info *frame)
 	unsigned long *fptr;
 	unsigned long addr;
 
-	unw_debug("\n\nUNWIND FRAME:\n");
-	unw_debug("PC: 0x%lx BLINK: 0x%lx, SP: 0x%lx, FP: 0x%x\n",
-		  UNW_PC(frame), UNW_BLINK(frame), UNW_SP(frame),
-		  UNW_FP(frame));
+	unw_debug("\nUNWIND FRAME: -------------------------------------\n");
+	unw_debug("PC\t\t: 0x%lx %pS\nr31 [BLINK]\t: 0x%lx %pS\nr28 [SP]\t: 0x%lx\nr27 [FP]\t: 0x%lx\n",
+		  UNW_PC(frame), (void *)UNW_PC(frame),
+		  UNW_BLINK(frame), (void *)UNW_BLINK(frame),
+		  UNW_SP(frame), UNW_FP(frame));
 
 	if (UNW_PC(frame) == 0)
 		return -EINVAL;
 
-#ifdef UNWIND_DEBUG
+#ifdef UNWIND_DEBUG0
 	{
 		unsigned long *sptr = (unsigned long *)UNW_SP(frame);
 		unw_debug("\nStack Dump:\n");
@@ -1063,7 +1057,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 	state.org = startLoc;
 	memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
 
-	unw_debug("\nProcess instructions\n");
+	unw_debug("\nProcess CFA\n");
 
 	/* process instructions
 	 * For ARC, we optimize by having blink(retAddrReg) with
@@ -1078,33 +1072,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 	    || state.cfa.offs % sizeof(unsigned long))
 		return -EIO;
 
-#ifdef UNWIND_DEBUG
-	unw_debug("\n");
-
-	unw_debug("\nRegister State Based on the rules parsed from FDE:\n");
-	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
-
-		if (REG_INVALID(i))
-			continue;
-
-		switch (state.regs[i].where) {
-		case Nowhere:
-			break;
-		case Memory:
-			unw_debug(" r%d: c(%lu),", i, state.regs[i].value);
-			break;
-		case Register:
-			unw_debug(" r%d: r(%lu),", i, state.regs[i].value);
-			break;
-		case Value:
-			unw_debug(" r%d: v(%lu),", i, state.regs[i].value);
-			break;
-		}
-	}
-
-	unw_debug("\n");
-#endif
-
 	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
 	startLoc = min_t(unsigned long, UNW_SP(frame), cfa);
 	endLoc = max_t(unsigned long, UNW_SP(frame), cfa);
@@ -1113,7 +1080,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 		endLoc = max(STACK_LIMIT(cfa), cfa);
 	}
 
-	unw_debug("\nCFA reg: 0x%lx, offset: 0x%lx =>  0x%lx\n",
+	unw_debug("\nCFA reg: r%ld, off: %ld => [SP] 0x%lx\n",
 		  state.cfa.reg, state.cfa.offs, cfa);
 
 	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
@@ -1232,7 +1199,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 
 			break;
 		}
-		unw_debug("r%d: 0x%lx ", i, *fptr);
+		unw_debug("r%d: 0x%lx\n", i, *fptr);
 	}
 
 	return 0;
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:04 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:04 +0530
Subject: [PATCH 06/17] ARC: dw2 unwind: Don't verify Main FDE Table size
 everytime
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-7-git-send-email-vgupta@synopsys.com>

This is already done at boot time in setup_unwind_table()

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 2bb3c1c048bb..f57a0d50185c 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -892,8 +892,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 #endif
 
 	table = find_table(pc);
-	if (table != NULL
-	    && !(table->size & (sizeof(*fde) - 1))) {
+	if (table != NULL) {
 		const u8 *hdr = table->header;
 		unsigned long tableSize;
 
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:00 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:00 +0530
Subject: [PATCH 02/17] ARC: dw2 unwind: remove unused cruft
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-3-git-send-email-vgupta@synopsys.com>

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/unwind.h | 34 +++++++++-------------------------
 arch/arc/kernel/unwind.c      | 15 +--------------
 2 files changed, 10 insertions(+), 39 deletions(-)

diff --git a/arch/arc/include/asm/unwind.h b/arch/arc/include/asm/unwind.h
index 7ca628b6ee2a..0e7f48e2686a 100644
--- a/arch/arc/include/asm/unwind.h
+++ b/arch/arc/include/asm/unwind.h
@@ -72,6 +72,15 @@ struct unwind_frame_info {
 
 #define STACK_LIMIT(ptr)	(((ptr) - 1) & ~(THREAD_SIZE - 1))
 
+#define EXTRA_INFO(f) { \
+		BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
+				% FIELD_SIZEOF(struct unwind_frame_info, f)) \
+				+ offsetof(struct unwind_frame_info, f) \
+				/ FIELD_SIZEOF(struct unwind_frame_info, f), \
+				FIELD_SIZEOF(struct unwind_frame_info, f) \
+	}
+#define PTREGS_INFO(f) EXTRA_INFO(regs.f)
+
 #define UNW_REGISTER_INFO \
 	PTREGS_INFO(r0), \
 	PTREGS_INFO(r1), \
@@ -117,31 +126,6 @@ extern void *unwind_add_table(struct module *module, const void *table_start,
 			      unsigned long table_size);
 extern void unwind_remove_table(void *handle, int init_only);
 
-static inline int
-arch_unwind_init_running(struct unwind_frame_info *info,
-			 int (*callback) (struct unwind_frame_info *info,
-					  void *arg),
-			 void *arg)
-{
-	return 0;
-}
-
-static inline int arch_unw_user_mode(const struct unwind_frame_info *info)
-{
-	return 0;
-}
-
-static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
-{
-	return;
-}
-
-static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
-					    struct pt_regs *regs)
-{
-	return;
-}
-
 #else
 
 #define UNW_PC(frame) ((void)(frame), 0)
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 7352475451f6..44983b4d9e78 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -43,23 +43,10 @@ do {						\
 
 #define MAX_STACK_DEPTH 8
 
-#define EXTRA_INFO(f) { \
-		BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
-				% FIELD_SIZEOF(struct unwind_frame_info, f)) \
-				+ offsetof(struct unwind_frame_info, f) \
-				/ FIELD_SIZEOF(struct unwind_frame_info, f), \
-				FIELD_SIZEOF(struct unwind_frame_info, f) \
-	}
-#define PTREGS_INFO(f) EXTRA_INFO(regs.f)
-
 static const struct {
 	unsigned offs:BITS_PER_LONG / 2;
 	unsigned width:BITS_PER_LONG / 2;
-} reg_info[] = {
-UNW_REGISTER_INFO};
-
-#undef PTREGS_INFO
-#undef EXTRA_INFO
+} reg_info[] = { UNW_REGISTER_INFO };
 
 #ifndef REG_INVALID
 #define REG_INVALID(r) (reg_info[r].width == 0)
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:07 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:07 +0530
Subject: [PATCH 09/17] ARC: dw2 unwind: Use striaght forward code to implement
 binary lookup
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-10-git-send-email-vgupta@synopsys.com>

The {start, pc} entries are already word aligned, no need to use
read_pointer() inefficiency !

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 9b34038a7582..6a09ffa0b697 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -866,7 +866,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 	const u8 *ptr = NULL, *end = NULL;
 	unsigned long pc = UNW_PC(frame);
 	unsigned long startLoc = 0, endLoc = 0, cfa;
-	unsigned i;
+	unsigned i, s, e;
 	signed ptrType = -1;
 	uleb128_t retAddrReg = 0;
 	const struct unwind_table *table;
@@ -874,7 +874,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 	unsigned long *fptr;
 	unsigned long addr;
 	struct eh_frame_header *hdr;
-	unsigned long hdrEntrySz;
 
 	unw_debug("\nUNWIND FRAME: -------------------------------------\n");
 	unw_debug("PC\t\t: 0x%lx %pS\nr31 [BLINK]\t: 0x%lx %pS\nr28 [SP]\t: 0x%lx\nr27 [FP]\t: 0x%lx\n",
@@ -903,28 +902,23 @@ int arc_unwind(struct unwind_frame_info *frame)
 	if (hdr == NULL)
 		return -EINVAL;
 
-	hdrEntrySz = sizeof(unsigned long);
-	BUILD_BUG_ON(hdrEntrySz != sizeof(hdr->table[0].start));
+	s = i = 0;
+	e = hdr->fde_count - 1;
 
-	ptr = (const u8*)(hdr->table);
-	end = (const u8*)(hdr) + table->hdrsz;
-	i = hdr->fde_count;
-
-			do {
-				const u8 *cur = ptr + (i / 2) * (2 * hdrEntrySz);
-
-				startLoc = read_pointer(&cur, cur + hdrEntrySz, hdr->table_enc);
-				if (pc < startLoc)
-					i /= 2;
-				else {
-					ptr = cur - hdrEntrySz;
-					i = (i + 1) / 2;
-				}
-			} while (startLoc && i > 1);
-			if (i == 1
-			    && (startLoc = read_pointer(&ptr, ptr + hdrEntrySz, hdr->table_enc)) != 0
-			    && pc >= startLoc)
-				fde = (void *)read_pointer(&ptr, ptr + hdrEntrySz, hdr->table_enc);
+	do {
+		if (pc < startLoc)
+			e = i;
+		else
+			s = i;
+		i = s + (e - s) / 2;
+		startLoc = hdr->table[i].start;
+		unw_debug("s %d e %d i %d startLoc %lx\n", s, e, i, startLoc)
+	} while ((e - s) > 1);
+
+	if (pc >= startLoc)
+		fde = (u32 *)hdr->table[i].fde;
+	else
+		return -EINVAL;
 
 	if (fde != NULL) {
 		cie = cie_for_fde(fde, table);
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:06 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:06 +0530
Subject: [PATCH 08/17] ARC: dw2 unwind: Don't verify FDE lookup table metadata
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-9-git-send-email-vgupta@synopsys.com>

FDE Lookup table (eh_frame_header or it's equivalent constructed by hand)
is already setup correctly in setup_unwind_table(). There's no point
to re-parse it's header for every unwind call

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 9f5ed6873c52..9b34038a7582 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -900,35 +900,16 @@ int arc_unwind(struct unwind_frame_info *frame)
 		return -EINVAL;
 
 	hdr = table->header;
+	if (hdr == NULL)
+		return -EINVAL;
 
-	smp_rmb();
-	if (hdr && hdr->version == 1) {
-		switch (hdr->table_enc & DW_EH_PE_FORM) {
-		case DW_EH_PE_native:
-			hdrEntrySz = sizeof(unsigned long);
-			break;
-		case DW_EH_PE_data2:
-			hdrEntrySz = 2;
-			break;
-		case DW_EH_PE_data4:
-			hdrEntrySz = 4;
-			break;
-		case DW_EH_PE_data8:
-			hdrEntrySz = 8;
-			break;
-		default:
-			hdrEntrySz = 0;
-			break;
-		}
+	hdrEntrySz = sizeof(unsigned long);
+	BUILD_BUG_ON(hdrEntrySz != sizeof(hdr->table[0].start));
+
+	ptr = (const u8*)(hdr->table);
+	end = (const u8*)(hdr) + table->hdrsz;
+	i = hdr->fde_count;
 
-		ptr = (const u8*)(hdr->eh_frame_ptr);
-		end = (const u8*)(hdr) + table->hdrsz;
-		if (hdrEntrySz
-		    && read_pointer(&ptr, end, hdr->eh_frame_ptr_enc) /* eh_frame_ptr */
-		    == (unsigned long)table->address
-		    && (i = read_pointer(&ptr, end, hdr->fde_count_enc)) > 0 /* fde_count */
-		    && i == (end - ptr) / (2 * hdrEntrySz)
-		    && !((end - ptr) % (2 * hdrEntrySz))) {
 			do {
 				const u8 *cur = ptr + (i / 2) * (2 * hdrEntrySz);
 
@@ -944,8 +925,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 			    && (startLoc = read_pointer(&ptr, ptr + hdrEntrySz, hdr->table_enc)) != 0
 			    && pc >= startLoc)
 				fde = (void *)read_pointer(&ptr, ptr + hdrEntrySz, hdr->table_enc);
-		}
-	}
 
 	if (fde != NULL) {
 		cie = cie_for_fde(fde, table);
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:01 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:01 +0530
Subject: [PATCH 03/17] ARC: dw2 unwind: Remove handling of for signal frame
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-4-git-send-email-vgupta@synopsys.com>

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/unwind.h |  3 ---
 arch/arc/kernel/unwind.c      | 11 ++---------
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/arch/arc/include/asm/unwind.h b/arch/arc/include/asm/unwind.h
index 0e7f48e2686a..559ef55abce1 100644
--- a/arch/arc/include/asm/unwind.h
+++ b/arch/arc/include/asm/unwind.h
@@ -116,9 +116,6 @@ struct unwind_frame_info {
 	PTREGS_INFO(r31), \
 	PTREGS_INFO(r63)
 
-#define UNW_DEFAULT_RA(raItem, dataAlign) \
-	((raItem).where == Memory && !((raItem).value * (dataAlign) + 4))
-
 extern int arc_unwind(struct unwind_frame_info *frame);
 extern void arc_unwind_init(void);
 extern void arc_unwind_setup(void);
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 44983b4d9e78..2f4a67f5a863 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -869,7 +869,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
 	const u32 *fde = NULL, *cie = NULL;
 	const u8 *ptr = NULL, *end = NULL;
-	unsigned long pc = UNW_PC(frame) - frame->call_frame;
+	unsigned long pc = UNW_PC(frame);
 	unsigned long startLoc = 0, endLoc = 0, cfa;
 	unsigned i;
 	signed ptrType = -1;
@@ -988,7 +988,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 		state.cieEnd = ptr;	/* keep here temporarily */
 		ptr = (const u8 *)(cie + 2);
 		end = (const u8 *)(cie + 1) + *cie;
-		frame->call_frame = 1;
 		if ((state.version = *ptr) != 1)
 			cie = NULL;	/* unsupported version */
 		else if (*++ptr) {
@@ -1003,7 +1002,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 					case 'R':
 						continue;
 					case 'S':
-						frame->call_frame = 0;
+						/* signal frame not handled */
 						continue;
 					default:
 						break;
@@ -1147,12 +1146,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 	unw_debug("\n");
 #endif
 
-	/* update frame */
-#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
-	if (frame->call_frame
-	    && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
-		frame->call_frame = 0;
-#endif
 	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
 	startLoc = min_t(unsigned long, UNW_SP(frame), cfa);
 	endLoc = max_t(unsigned long, UNW_SP(frame), cfa);
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:08 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:08 +0530
Subject: [PATCH 10/17] ARC: dw2 unwind: CIE parsing/validation done only once
 at startup
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-11-git-send-email-vgupta@synopsys.com>

There is only 1 CIE per unwind table and applicable to all FDEs, so
validate it only once. No need to do validate it when prcoessing the FDE
itself.

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 6a09ffa0b697..f2a486d9dac2 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -122,6 +122,13 @@ static struct unwind_table {
 	} core, init;
 	const void *address;
 	unsigned long size;
+	struct cie {
+		unsigned version:8, aug:8, pad:16;
+		uleb128_t codeAlign;
+		sleb128_t dataAlign;
+		int       fde_pointer_type;
+		uleb128_t retAddrReg;
+	} cie;
 	struct eh_frame_header *header;
 	unsigned long hdrsz;
 	struct unwind_table *link;
@@ -140,20 +147,18 @@ struct unwind_item {
 
 struct unwind_state {
 	uleb128_t loc, org;
-	const u8 *cieStart, *cieEnd;
 	uleb128_t codeAlign;
 	sleb128_t dataAlign;
 	struct cfa {
 		uleb128_t reg, offs;
 	} cfa;
 	struct unwind_item regs[ARRAY_SIZE(reg_info)];
-	unsigned stackDepth:8;
-	unsigned version:8;
+	unsigned stackDepth;
 	const u8 *label;
 	const u8 *stack[MAX_STACK_DEPTH];
 };
 
-static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
+static struct cfa seed_CFA = { ARRAY_SIZE(reg_info), 1 };
 
 static struct unwind_table *find_table(unsigned long pc)
 {
@@ -214,7 +219,7 @@ void __init arc_unwind_init(void)
 
 static const u32 bad_cie, not_fde;
 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
-static signed fde_pointer_type(const u32 *cie);
+static int cie_validate(const u32 *cie, struct cie *t_cie);
 
 static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
 {
@@ -245,7 +250,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
 	unsigned long tableSize = table->size, hdrSize;
 	unsigned n;
 	const u32 *fde;
+	int ptrType;
 	struct eh_frame_header *header;
+	int n_cie = 0, len = 0;
+	char cie_orig[64];
 
 	if (table->header)
 		return;
@@ -261,19 +269,26 @@ static void __init setup_unwind_table(struct unwind_table *table,
 	     tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
 	     tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
 		const u32 *cie = cie_for_fde(fde, table);
-		signed ptrType;
 
-		if (cie == &not_fde)
+		if (cie == &not_fde) {
+			if (n_cie++ == 0) {
+				len = cie_validate(&fde[0], &table->cie);
+				if (!len)
+					panic("Invalid CIE\n");
+
+				memcpy(&cie_orig[0], &fde[0], len);
+			} else {
+				if (memcmp(&fde[0], &cie_orig[0], len) != 0)
+					panic("Multiple CIEs not same\n");
+			}
 			continue;
+		}
 		if (cie == NULL || cie == &bad_cie)
 			return;
-		ptrType = fde_pointer_type(cie);
-		if (ptrType < 0)
-			return;
 
 		ptr = (const u8 *)(fde + 2);
 		if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
-								ptrType)) {
+								table->cie.fde_pointer_type)) {
 			/* FIXME_Rajesh We have 4 instances of null addresses
 			 * instead of the initial loc addr
 			 * return;
@@ -303,19 +318,17 @@ static void __init setup_unwind_table(struct unwind_table *table,
 
 	BUILD_BUG_ON(offsetof(typeof(*header), table)
 		     % __alignof(typeof(*header->table)));
+
+	ptrType = table->cie.fde_pointer_type;
 	for (fde = table->address, tableSize = table->size, n = 0;
 	     tableSize;
 	     tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
-		/* const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); */
-		const u32 *cie = (const u32 *)(fde[1]);
-
 		if (fde[1] == 0xffffffff)
 			continue;	/* this is a CIE */
 		ptr = (const u8 *)(fde + 2);
 		header->table[n].start = read_pointer(&ptr,
-						      (const u8 *)(fde + 1) +
-						      *fde,
-						      fde_pointer_type(cie));
+						      (const u8 *)(fde + 1) + *fde,
+						      ptrType);
 		header->table[n].fde = (unsigned long)fde;
 		++n;
 	}
@@ -572,65 +585,6 @@ static unsigned long read_pointer(const u8 **pLoc, const void *end,
 	return value;
 }
 
-static signed fde_pointer_type(const u32 *cie)
-{
-	const u8 *ptr = (const u8 *)(cie + 2);
-	unsigned version = *ptr;
-
-	if (version != 1)
-		return -1;	/* unsupported */
-
-	if (*++ptr) {
-		const char *aug;
-		const u8 *end = (const u8 *)(cie + 1) + *cie;
-		uleb128_t len;
-
-		/* check if augmentation size is first (and thus present) */
-		if (*ptr != 'z')
-			return -1;
-
-		/* check if augmentation string is nul-terminated */
-		aug = (const void *)ptr;
-		ptr = memchr(aug, 0, end - ptr);
-		if (ptr == NULL)
-			return -1;
-
-		++ptr;		/* skip terminator */
-		get_uleb128(&ptr, end);	/* skip code alignment */
-		get_sleb128(&ptr, end);	/* skip data alignment */
-		/* skip return address column */
-		version <= 1 ? (void) ++ptr : (void)get_uleb128(&ptr, end);
-		len = get_uleb128(&ptr, end);	/* augmentation length */
-
-		if (ptr + len < ptr || ptr + len > end)
-			return -1;
-
-		end = ptr + len;
-		while (*++aug) {
-			if (ptr >= end)
-				return -1;
-			switch (*aug) {
-			case 'L':
-				++ptr;
-				break;
-			case 'P':{
-					signed ptrType = *ptr++;
-
-					if (!read_pointer(&ptr, end, ptrType)
-					    || ptr > end)
-						return -1;
-				}
-				break;
-			case 'R':
-				return *ptr;
-			default:
-				return -1;
-			}
-		}
-	}
-	return DW_EH_PE_native | DW_EH_PE_abs;
-}
-
 static int advance_loc(unsigned long delta, struct unwind_state *state, char *str)
 {
 	state->loc += delta * state->codeAlign;
@@ -682,14 +636,6 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 	int result = 1;
 	u8 opcode;
 
-	if (start != state->cieStart) {
-		state->loc = state->org;
-		result =
-		    processCFI(state->cieStart, state->cieEnd, 0, ptrType,
-			       state);
-		if (targetLoc == 0 && state->label == NULL)
-			return result;
-	}
 	for (ptr.p8 = start; result && ptr.p8 < end;) {
 		char *str = NULL;
 		switch (*ptr.p8 >> 6) {
@@ -775,7 +721,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 
 					state->label =
 					    state->stack[state->stackDepth - 1];
-					memcpy(&state->cfa, &badCFA,
+					memcpy(&state->cfa, &seed_CFA,
 					       sizeof(state->cfa));
 					memset(state->regs, 0,
 					       sizeof(state->regs));
@@ -857,12 +803,102 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 		targetLoc < state->loc && */  state->label == NULL));
 }
 
+/*
+ * Returns length of CIE (0 if invalid)
+ */
+static int cie_validate(const u32 *cie, struct cie *t_cie)
+{
+	const u8 *ptr = NULL, *end = NULL;
+	u8 version;
+	uleb128_t retAddrReg = 0;
+	int ptrType = DW_EH_PE_native | DW_EH_PE_abs;
+	struct unwind_state state;
+
+	if (cie == NULL)
+		return 0;
+
+	ptr = (const u8 *)(cie + 2);
+	end = (const u8 *)(cie + 1) + *cie;
+	if ((version = *ptr) != 1)
+		return 0;	/* unsupported version */
+
+	t_cie->version = version;
+
+	if (*++ptr) {
+		/* check if augmentation size is first (thus present) */
+		if (*ptr == 'z') {
+			t_cie->aug = 1;
+			while (++ptr < end && *ptr) {
+				switch (*ptr) {
+				/* chk for ignorable or already handled
+				 * nul-terminated augmentation string */
+				case 'L':
+				case 'P':
+				case 'R':
+					continue;
+				case 'S':	/* signal frame */
+					continue;
+				default:
+					break;
+				}
+				break;
+			}
+		}
+		if (ptr >= end || *ptr)
+			return 0;
+	}
+	++ptr;	/* skip terminator */
+
+	t_cie->codeAlign = get_uleb128(&ptr, end);
+	t_cie->dataAlign = get_sleb128(&ptr, end);
+
+	if (t_cie->codeAlign == 0 || t_cie->dataAlign == 0 || ptr >= end)
+		return 0;
+
+	retAddrReg = version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
+	t_cie->retAddrReg = retAddrReg;
+
+	/* skip augmentation data */
+	if (((const char *)(cie + 2))[1] == 'z') {
+		get_uleb128(&ptr, end);  /* augSize */
+
+		if (*ptr++ == 'R')	/* FDE pointer encoding type */
+			ptrType = *ptr;
+	}
+	t_cie->fde_pointer_type = ptrType;
+
+	if (ptr > end
+	    || retAddrReg >= ARRAY_SIZE(reg_info)
+	    || REG_INVALID(retAddrReg)
+	    || reg_info[retAddrReg].width != sizeof(unsigned long))
+		return 0;
+
+	unw_debug("\nDwarf Unwinder setup: CIE Info:\n");
+	unw_debug("code Align: %lu\n", t_cie->codeAlign);
+	unw_debug("data Align: %ld\n", t_cie->dataAlign);
+	unw_debug("Return Address register r%d\n",  (int)t_cie->retAddrReg);
+	unw_debug("FDE pointer type %d\n",  ptrType);
+	unw_debug("CFI Instructions for CIE:\n");
+
+	memset(&state, sizeof(state), 0);
+
+	/* CIE has rules for Default CFA */
+	if (!processCFI(ptr, end, 0, ptrType, &state)
+	    || state.cfa.reg >= ARRAY_SIZE(reg_info)
+	    || state.cfa.offs % sizeof(unsigned long))
+		return 0;
+
+	memcpy(&seed_CFA, &state.cfa, sizeof(state.cfa));
+
+	return end - (const u8 *)cie;
+}
+
 /* Unwind to previous to frame.  Returns 0 if successful, negative
  * number in case of an error. */
 int arc_unwind(struct unwind_frame_info *frame)
 {
 #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
-	const u32 *fde = NULL, *cie = NULL;
+	const u32 *fde = NULL;
 	const u8 *ptr = NULL, *end = NULL;
 	unsigned long pc = UNW_PC(frame);
 	unsigned long startLoc = 0, endLoc = 0, cfa;
@@ -920,107 +956,41 @@ int arc_unwind(struct unwind_frame_info *frame)
 	else
 		return -EINVAL;
 
-	if (fde != NULL) {
-		cie = cie_for_fde(fde, table);
-		ptr = (const u8 *)(fde + 2);
-		if (cie != NULL
-		    && cie != &bad_cie
-		    && cie != &not_fde
-		    && (ptrType = fde_pointer_type(cie)) >= 0
-		    && read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType) == startLoc) {
-			if (!(ptrType & DW_EH_PE_indirect))
-				ptrType &= DW_EH_PE_FORM | DW_EH_PE_signed;
-				endLoc = startLoc + read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType);
-			if (pc >= endLoc) {
-				fde = NULL;
-				cie = NULL;
-			}
-		} else {
-			fde = NULL;
-			cie = NULL;
-		}
-	}
-	if (cie != NULL) {
-		memset(&state, 0, sizeof(state));
-		state.cieEnd = ptr;	/* keep here temporarily */
-		ptr = (const u8 *)(cie + 2);
-		end = (const u8 *)(cie + 1) + *cie;
-		if ((state.version = *ptr) != 1)
-			cie = NULL;	/* unsupported version */
-		else if (*++ptr) {
-			/* check if augmentation size is first (thus present) */
-			if (*ptr == 'z') {
-				while (++ptr < end && *ptr) {
-					switch (*ptr) {
-					/* chk for ignorable or already handled
-					 * nul-terminated augmentation string */
-					case 'L':
-					case 'P':
-					case 'R':
-						continue;
-					case 'S':
-						/* signal frame not handled */
-						continue;
-					default:
-						break;
-					}
-					break;
-				}
-			}
-			if (ptr >= end || *ptr)
-				cie = NULL;
-		}
-		++ptr;
-	}
-	if (cie != NULL) {
-		/* get code aligment factor */
-		state.codeAlign = get_uleb128(&ptr, end);
-		/* get data aligment factor */
-		state.dataAlign = get_sleb128(&ptr, end);
-		if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
-			cie = NULL;
-		else {
-			retAddrReg =
-			    state.version <= 1 ? *ptr++ : get_uleb128(&ptr,
-								      end);
-			unw_debug("CIE Frame Info:\n");
-			unw_debug("return Address register 0x%lx\n",
-				  retAddrReg);
-			unw_debug("data Align: %ld\n", state.dataAlign);
-			unw_debug("code Align: %lu\n", state.codeAlign);
-			/* skip augmentation */
-			if (((const char *)(cie + 2))[1] == 'z') {
-				uleb128_t augSize = get_uleb128(&ptr, end);
-
-				ptr += augSize;
-			}
-			if (ptr > end || retAddrReg >= ARRAY_SIZE(reg_info)
-			    || REG_INVALID(retAddrReg)
-			    || reg_info[retAddrReg].width !=
-			    sizeof(unsigned long))
-				cie = NULL;
-		}
+	memset(&state, 0, sizeof(state));
+	ptr = (const u8 *)(fde + 2);
+	end = (const u8 *)(fde + 1) + *fde;
+
+	ptrType = table->cie.fde_pointer_type;
+	if (read_pointer(&ptr, end, ptrType) != startLoc)
+		return -EINVAL;
+
+	if (!(ptrType & DW_EH_PE_indirect))
+		ptrType &= DW_EH_PE_FORM | DW_EH_PE_signed;
+
+	endLoc = startLoc + read_pointer(&ptr, end, ptrType);
+
+	/* For symbols not present, this is mostly hit (not startLoc check above) */
+	if (pc >= endLoc) {
+		unw_debug("Unwindo info missing for PC %lx: {%lx,%lx}\n",
+			  pc, startLoc, endLoc);
+		return -EINVAL;
 	}
-	if (cie != NULL) {
-		state.cieStart = ptr;
-		ptr = state.cieEnd;
-		state.cieEnd = end;
-		end = (const u8 *)(fde + 1) + *fde;
-		/* skip augmentation */
-		if (((const char *)(cie + 2))[1] == 'z') {
-			uleb128_t augSize = get_uleb128(&ptr, end);
-
-			if ((ptr += augSize) > end)
-				fde = NULL;
-		}
+
+	if (table->cie.aug) {
+		uleb128_t augSize = get_uleb128(&ptr, end);
+
+		if ((ptr += augSize) > end)
+			return -EINVAL;
 	}
-	if (cie == NULL || fde == NULL)
-		return -ENXIO;
 
-	state.org = startLoc;
-	memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
+	state.org = state.loc = startLoc;
+	memcpy(&state.cfa, &seed_CFA, sizeof(state.cfa));
+	state.codeAlign = table->cie.codeAlign;
+	state.dataAlign = table->cie.dataAlign;
+
+	retAddrReg =  table->cie.retAddrReg;
 
-	unw_debug("\nProcess CFA\n");
+	unw_debug("\nProcess FDE:\n");
 
 	/* process instructions
 	 * For ARC, we optimize by having blink(retAddrReg) with
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:05 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:05 +0530
Subject: [PATCH 07/17] ARC: dw2 unwind: Refactor the FDE lookup table
 (eh_frame_header) code
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-8-git-send-email-vgupta@synopsys.com>

 - Reduce 1 level of indenatation
 - Use struct members to identify what's going on !
 - Nothing semantical

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index f57a0d50185c..9f5ed6873c52 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -101,6 +101,20 @@ static const struct {
 typedef unsigned long uleb128_t;
 typedef signed long sleb128_t;
 
+struct eh_frame_hdr_table_entry {
+	unsigned long start, fde;
+};
+
+struct eh_frame_header {
+	u8 version;
+	u8 eh_frame_ptr_enc;
+	u8 fde_count_enc;
+	u8 table_enc;
+	unsigned long eh_frame_ptr;
+	unsigned int fde_count;
+	struct eh_frame_hdr_table_entry table[];
+} __attribute__ ((__packed__));
+
 static struct unwind_table {
 	struct {
 		unsigned long pc;
@@ -108,7 +122,7 @@ static struct unwind_table {
 	} core, init;
 	const void *address;
 	unsigned long size;
-	const unsigned char *header;
+	struct eh_frame_header *header;
 	unsigned long hdrsz;
 	struct unwind_table *link;
 	const char *name;
@@ -185,7 +199,7 @@ static void init_unwind_table(struct unwind_table *table, const char *name,
 
 	table->hdrsz = header_size;
 	smp_wmb();
-	table->header = header_start;
+	table->header = (struct eh_frame_header *)header_start;
 	table->link = NULL;
 	table->name = name;
 }
@@ -202,10 +216,6 @@ static const u32 bad_cie, not_fde;
 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
 static signed fde_pointer_type(const u32 *cie);
 
-struct eh_frame_hdr_table_entry {
-	unsigned long start, fde;
-};
-
 static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
 {
 	const struct eh_frame_hdr_table_entry *e1 = p1;
@@ -235,15 +245,7 @@ static void __init setup_unwind_table(struct unwind_table *table,
 	unsigned long tableSize = table->size, hdrSize;
 	unsigned n;
 	const u32 *fde;
-	struct {
-		u8 version;
-		u8 eh_frame_ptr_enc;
-		u8 fde_count_enc;
-		u8 table_enc;
-		unsigned long eh_frame_ptr;
-		unsigned int fde_count;
-		struct eh_frame_hdr_table_entry table[];
-	} __attribute__ ((__packed__)) *header;
+	struct eh_frame_header *header;
 
 	if (table->header)
 		return;
@@ -326,7 +328,7 @@ static void __init setup_unwind_table(struct unwind_table *table,
 
 	table->hdrsz = hdrSize;
 	smp_wmb();
-	table->header = (const void *)header;
+	table->header = header;
 }
 
 static void *__init balloc(unsigned long sz)
@@ -871,6 +873,8 @@ int arc_unwind(struct unwind_frame_info *frame)
 	struct unwind_state state;
 	unsigned long *fptr;
 	unsigned long addr;
+	struct eh_frame_header *hdr;
+	unsigned long hdrEntrySz;
 
 	unw_debug("\nUNWIND FRAME: -------------------------------------\n");
 	unw_debug("PC\t\t: 0x%lx %pS\nr31 [BLINK]\t: 0x%lx %pS\nr28 [SP]\t: 0x%lx\nr27 [FP]\t: 0x%lx\n",
@@ -892,88 +896,75 @@ int arc_unwind(struct unwind_frame_info *frame)
 #endif
 
 	table = find_table(pc);
-	if (table != NULL) {
-		const u8 *hdr = table->header;
-		unsigned long tableSize;
-
-		smp_rmb();
-		if (hdr && hdr[0] == 1) {
-			switch (hdr[3] & DW_EH_PE_FORM) {
-			case DW_EH_PE_native:
-				tableSize = sizeof(unsigned long);
-				break;
-			case DW_EH_PE_data2:
-				tableSize = 2;
-				break;
-			case DW_EH_PE_data4:
-				tableSize = 4;
-				break;
-			case DW_EH_PE_data8:
-				tableSize = 8;
-				break;
-			default:
-				tableSize = 0;
-				break;
-			}
-			ptr = hdr + 4;
-			end = hdr + table->hdrsz;
-			if (tableSize && read_pointer(&ptr, end, hdr[1])
-			    == (unsigned long)table->address
-			    && (i = read_pointer(&ptr, end, hdr[2])) > 0
-			    && i == (end - ptr) / (2 * tableSize)
-			    && !((end - ptr) % (2 * tableSize))) {
-				do {
-					const u8 *cur =
-					    ptr + (i / 2) * (2 * tableSize);
-
-					startLoc = read_pointer(&cur,
-								cur + tableSize,
-								hdr[3]);
-					if (pc < startLoc)
-						i /= 2;
-					else {
-						ptr = cur - tableSize;
-						i = (i + 1) / 2;
-					}
-				} while (startLoc && i > 1);
-				if (i == 1
-				    && (startLoc = read_pointer(&ptr,
-								ptr + tableSize,
-								hdr[3])) != 0
-				    && pc >= startLoc)
-					fde = (void *)read_pointer(&ptr,
-								   ptr +
-								   tableSize,
-								   hdr[3]);
-			}
+	if (table == NULL)
+		return -EINVAL;
+
+	hdr = table->header;
+
+	smp_rmb();
+	if (hdr && hdr->version == 1) {
+		switch (hdr->table_enc & DW_EH_PE_FORM) {
+		case DW_EH_PE_native:
+			hdrEntrySz = sizeof(unsigned long);
+			break;
+		case DW_EH_PE_data2:
+			hdrEntrySz = 2;
+			break;
+		case DW_EH_PE_data4:
+			hdrEntrySz = 4;
+			break;
+		case DW_EH_PE_data8:
+			hdrEntrySz = 8;
+			break;
+		default:
+			hdrEntrySz = 0;
+			break;
 		}
 
-		if (fde != NULL) {
-			cie = cie_for_fde(fde, table);
-			ptr = (const u8 *)(fde + 2);
-			if (cie != NULL
-			    && cie != &bad_cie
-			    && cie != &not_fde
-			    && (ptrType = fde_pointer_type(cie)) >= 0
-			    && read_pointer(&ptr,
-					    (const u8 *)(fde + 1) + *fde,
-					    ptrType) == startLoc) {
-				if (!(ptrType & DW_EH_PE_indirect))
-					ptrType &=
-					    DW_EH_PE_FORM | DW_EH_PE_signed;
-				endLoc =
-				    startLoc + read_pointer(&ptr,
-							    (const u8 *)(fde +
-									 1) +
-							    *fde, ptrType);
-				if (pc >= endLoc) {
-					fde = NULL;
-					cie = NULL;
+		ptr = (const u8*)(hdr->eh_frame_ptr);
+		end = (const u8*)(hdr) + table->hdrsz;
+		if (hdrEntrySz
+		    && read_pointer(&ptr, end, hdr->eh_frame_ptr_enc) /* eh_frame_ptr */
+		    == (unsigned long)table->address
+		    && (i = read_pointer(&ptr, end, hdr->fde_count_enc)) > 0 /* fde_count */
+		    && i == (end - ptr) / (2 * hdrEntrySz)
+		    && !((end - ptr) % (2 * hdrEntrySz))) {
+			do {
+				const u8 *cur = ptr + (i / 2) * (2 * hdrEntrySz);
+
+				startLoc = read_pointer(&cur, cur + hdrEntrySz, hdr->table_enc);
+				if (pc < startLoc)
+					i /= 2;
+				else {
+					ptr = cur - hdrEntrySz;
+					i = (i + 1) / 2;
 				}
-			} else {
+			} while (startLoc && i > 1);
+			if (i == 1
+			    && (startLoc = read_pointer(&ptr, ptr + hdrEntrySz, hdr->table_enc)) != 0
+			    && pc >= startLoc)
+				fde = (void *)read_pointer(&ptr, ptr + hdrEntrySz, hdr->table_enc);
+		}
+	}
+
+	if (fde != NULL) {
+		cie = cie_for_fde(fde, table);
+		ptr = (const u8 *)(fde + 2);
+		if (cie != NULL
+		    && cie != &bad_cie
+		    && cie != &not_fde
+		    && (ptrType = fde_pointer_type(cie)) >= 0
+		    && read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType) == startLoc) {
+			if (!(ptrType & DW_EH_PE_indirect))
+				ptrType &= DW_EH_PE_FORM | DW_EH_PE_signed;
+				endLoc = startLoc + read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType);
+			if (pc >= endLoc) {
 				fde = NULL;
 				cie = NULL;
 			}
+		} else {
+			fde = NULL;
+			cie = NULL;
 		}
 	}
 	if (cie != NULL) {
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:10 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:10 +0530
Subject: [PATCH 12/17] ARC: dw2 unwind: Elide a loop if DW_CFA_register not
 present
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-13-git-send-email-vgupta@synopsys.com>

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index b1a520afcbcb..6eb377c102c6 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -149,7 +149,7 @@ struct unwind_state {
 		uleb128_t reg, offs;
 	} cfa;
 	struct unwind_item regs[ARRAY_SIZE(reg_info)];
-	unsigned stackDepth;
+	unsigned stackDepth:8, has_cfa_register:8;
 	const u8 *label;
 	const u8 *stack[MAX_STACK_DEPTH];
 };
@@ -697,6 +697,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 			case DW_CFA_register:
 				str = "cfa_register: ";
 				value = get_uleb128(&ptr.p8, end);
+				state->has_cfa_register = 1;
 				set_rule(value, Register, get_uleb128(&ptr.p8, end), state, str);
 				break;
 			case DW_CFA_remember_state:
@@ -1010,11 +1011,18 @@ int arc_unwind(struct unwind_frame_info *frame)
 	unw_debug("\nCFA reg: r%ld, off: %ld => [SP] 0x%lx\n",
 		  state.cfa.reg, state.cfa.offs, cfa);
 
-	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
-		switch (state.regs[i].where) {
-		default:
-			break;
-		case Register:
+	/*
+	 * For DW_CFA_register instruction, save registers initial state
+	 * Note that a seperate pass is needed (vs. doing this in main loop below)
+	 * to capture state of those regs at time of entry into function since
+	 * the main loop below can possibly clobber them due to CFA ops of
+	 * function being processed
+	 *
+	 * Since ARC gcc doesn't seem to generate those (ABI thing ?) try to
+	 * optimize out the loop
+	 */
+	for (i = 0; state.has_cfa_register && i < ARRAY_SIZE(state.regs); ++i) {
+		if (state.regs[i].where == Register) {
 			if (state.regs[i].value >= ARRAY_SIZE(reg_info))
 				return -EIO;
 			switch (reg_info[state.regs[i].value].width) {
@@ -1039,7 +1047,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 			default:
 				return -EIO;
 			}
-			break;
 		}
 	}
 
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:11 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:11 +0530
Subject: [PATCH 13/17] ARC: dw2 unwind: Assume all regs to be unsigned long
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-14-git-send-email-vgupta@synopsys.com>

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/unwind.h |  3 +-
 arch/arc/kernel/unwind.c      | 74 +++----------------------------------------
 2 files changed, 6 insertions(+), 71 deletions(-)

diff --git a/arch/arc/include/asm/unwind.h b/arch/arc/include/asm/unwind.h
index 03ace2cc8bc5..a1dbcf6cb361 100644
--- a/arch/arc/include/asm/unwind.h
+++ b/arch/arc/include/asm/unwind.h
@@ -66,8 +66,7 @@ struct unwind_frame_info {
 		BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
 				% FIELD_SIZEOF(struct unwind_frame_info, f)) \
 				+ offsetof(struct unwind_frame_info, f) \
-				/ FIELD_SIZEOF(struct unwind_frame_info, f), \
-				FIELD_SIZEOF(struct unwind_frame_info, f) \
+				/ FIELD_SIZEOF(struct unwind_frame_info, f) \
 	}
 #define PTREGS_INFO(f) EXTRA_INFO(regs.f)
 
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 6eb377c102c6..b2053b55d076 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -45,7 +45,6 @@ do {						\
 
 static const struct {
 	unsigned offs:BITS_PER_LONG / 2;
-	unsigned width:BITS_PER_LONG / 2;
 } reg_info[] = { UNW_REGISTER_INFO };
 
 #define DW_CFA_nop                          0x00
@@ -996,7 +995,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 	    || state.loc > endLoc
 /*	   || state.regs[retAddrReg].where == Nowhere */
 	    || state.cfa.reg >= ARRAY_SIZE(reg_info)
-	    || reg_info[state.cfa.reg].width != sizeof(unsigned long)
 	    || state.cfa.offs % sizeof(unsigned long))
 		return -EIO;
 
@@ -1025,28 +1023,8 @@ int arc_unwind(struct unwind_frame_info *frame)
 		if (state.regs[i].where == Register) {
 			if (state.regs[i].value >= ARRAY_SIZE(reg_info))
 				return -EIO;
-			switch (reg_info[state.regs[i].value].width) {
-			case sizeof(u8):
-				state.regs[i].value =
-				FRAME_REG(state.regs[i].value, const u8);
-				break;
-			case sizeof(u16):
-				state.regs[i].value =
-				FRAME_REG(state.regs[i].value, const u16);
-				break;
-			case sizeof(u32):
-				state.regs[i].value =
-				FRAME_REG(state.regs[i].value, const u32);
-				break;
-#ifdef CONFIG_64BIT
-			case sizeof(u64):
-				state.regs[i].value =
-				FRAME_REG(state.regs[i].value, const u64);
-				break;
-#endif
-			default:
-				return -EIO;
-			}
+
+			state.regs[i].value = FRAME_REG(state.regs[i].value, unsigned long);
 		}
 	}
 
@@ -1056,35 +1034,15 @@ int arc_unwind(struct unwind_frame_info *frame)
 
 		switch (state.regs[i].where) {
 		case Nowhere:
-			if (reg_info[i].width != sizeof(UNW_SP(frame))
-			    || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
+			if (&FRAME_REG(i, __typeof__(UNW_SP(frame)))
 			    != &UNW_SP(frame))
 				continue;
 			UNW_SP(frame) = cfa;
 			break;
 		case Register:
-			switch (reg_info[i].width) {
-			case sizeof(u8):
-				FRAME_REG(i, u8) = state.regs[i].value;
-				break;
-			case sizeof(u16):
-				FRAME_REG(i, u16) = state.regs[i].value;
-				break;
-			case sizeof(u32):
-				FRAME_REG(i, u32) = state.regs[i].value;
-				break;
-#ifdef CONFIG_64BIT
-			case sizeof(u64):
-				FRAME_REG(i, u64) = state.regs[i].value;
-				break;
-#endif
-			default:
-				return -EIO;
-			}
+			FRAME_REG(i, unsigned long) = state.regs[i].value;
 			break;
 		case Value:
-			if (reg_info[i].width != sizeof(unsigned long))
-				return -EIO;
 			FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
 			    * state.dataAlign;
 			break;
@@ -1098,29 +1056,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 			    || addr + sizeof(unsigned long) > endLoc)
 					return -EIO;
 
-			switch (reg_info[i].width) {
-			case sizeof(u8):
-				__get_user(FRAME_REG(i, u8),
-					   (u8 __user *)addr);
-				break;
-			case sizeof(u16):
-				__get_user(FRAME_REG(i, u16),
-					   (u16 __user *)addr);
-				break;
-			case sizeof(u32):
-				__get_user(FRAME_REG(i, u32),
-					   (u32 __user *)addr);
-				break;
-#ifdef CONFIG_64BIT
-			case sizeof(u64):
-				__get_user(FRAME_REG(i, u64),
-					   (u64 __user *)addr);
-				break;
-#endif
-			default:
-				return -EIO;
-			}
-
+			__get_user(FRAME_REG(i, unsigned long), (unsigned long __user *)addr);
 			break;
 		}
 		unw_debug("r%d: 0x%lx\n", i, *fptr);
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:12 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:12 +0530
Subject: [PATCH 14/17] ARC: dw2 unwind: No need for __get_user
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-15-git-send-email-vgupta@synopsys.com>

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/unwind.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index b2053b55d076..4f739716f908 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -1056,7 +1056,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 			    || addr + sizeof(unsigned long) > endLoc)
 					return -EIO;
 
-			__get_user(FRAME_REG(i, unsigned long), (unsigned long __user *)addr);
+			FRAME_REG(i, unsigned long) = *(unsigned long *)addr;
 			break;
 		}
 		unw_debug("r%d: 0x%lx\n", i, *fptr);
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:15 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:15 +0530
Subject: [PATCH 17/17] xxx: instrument
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-18-git-send-email-vgupta@synopsys.com>

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/unwind.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index d5ffb4a78104..91f310465970 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -889,6 +889,19 @@ static int cie_validate(const u32 *cie, struct cie *t_cie)
 	return end - (const u8 *)cie;
 }
 
+#define UNWIND_INSTRUMENT
+
+#ifdef UNWIND_INSTRUMENT
+u32 unw_t_min = 0xffffff, unw_t_max, unw_t_n;
+u64 unw_t_avg;
+
+static unsigned int get_c(void)
+{
+       write_aux_reg(0x600, 0x42);             // ARC_REG_MCIP_CMD
+       return read_aux_reg(0x602);     // ARC_REG_MCIP_READBACK
+}
+#endif
+
 /* Unwind to previous to frame.  Returns 0 if successful, negative
  * number in case of an error. */
 int arc_unwind(struct unwind_frame_info *frame)
@@ -907,7 +920,9 @@ int arc_unwind(struct unwind_frame_info *frame)
 	unsigned long addr;
 	struct eh_frame_header *hdr;
 	int ret = -EINVAL;
-
+#ifdef UNWIND_INSTRUMENT
+	unsigned int t0 = get_c(), t1, delta;
+#endif
 	unw_debug("\nUNWIND FRAME: -------------------------------------\n");
 	unw_debug("PC\t\t: 0x%lx %pS\nr31 [BLINK]\t: 0x%lx %pS\nr28 [SP]\t: 0x%lx\nr27 [FP]\t: 0x%lx\n",
 		  UNW_PC(frame), (void *)UNW_PC(frame),
@@ -1072,6 +1087,15 @@ int arc_unwind(struct unwind_frame_info *frame)
 	ret = 0;
 bad_unw:
 
+#ifdef UNWIND_INSTRUMENT
+	t1 = get_c();
+	delta = t1 - t0;
+	unw_t_min = min(unw_t_min, delta);
+	unw_t_max = max(unw_t_max, delta);
+	unw_t_n++;
+	unw_t_avg += delta;
+	printk("unw %d %s %lx\n", delta, !ret ? "O K":"nok", pc);
+#endif
 	return ret;
 #undef FRAME_REG
 }
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:14 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:14 +0530
Subject: [PATCH 16/17] ARC: dw2 unwind: skip regs not updated
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-17-git-send-email-vgupta@synopsys.com>

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index e02d974ea789..d5ffb4a78104 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -142,13 +142,14 @@ struct unwind_item {
 
 struct unwind_state {
 	uleb128_t loc, org;
+	uleb128_t first_reg;
 	uleb128_t codeAlign;
 	sleb128_t dataAlign;
 	struct cfa {
 		uleb128_t reg, offs;
 	} cfa;
 	struct unwind_item regs[ARRAY_SIZE(reg_info)];
-	unsigned stackDepth:8, has_cfa_register:8;
+	unsigned stackDepth:8, has_cfa_register:8, pad:16;
 	const u8 *label;
 	const u8 *stack[MAX_STACK_DEPTH];
 };
@@ -597,6 +598,7 @@ static void set_rule(uleb128_t reg, enum item_location where, uleb128_t value,
 	if (reg < ARRAY_SIZE(state->regs)) {
 		state->regs[reg].where = where;
 		state->regs[reg].value = value;
+		state->first_reg = min(reg, state->first_reg);
 
 #ifdef UNWIND_DEBUG
 		switch (where) {
@@ -979,6 +981,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 			goto bad_unw;
 	}
 
+	state.first_reg = 13;
 	state.org = state.loc = startLoc;
 	memcpy(&state.cfa, &seed_CFA, sizeof(state.cfa));
 	state.codeAlign = table->cie.codeAlign;
@@ -1032,9 +1035,9 @@ int arc_unwind(struct unwind_frame_info *frame)
 		}
 	}
 
-	unw_debug("\nRegister state after evaluation with realtime Stack:\n");
+	unw_debug("\nRegister state after evaluation with realtime Stack @ %ld :\n", state.first_reg);
 	fptr = (unsigned long *)(&frame->regs);
-	for (i = 0; i < ARRAY_SIZE(state.regs); ++i, fptr++) {
+	for (i = state.first_reg; i < ARRAY_SIZE(state.regs); ++i, fptr++) {
 
 		switch (state.regs[i].where) {
 		case Nowhere:
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:09 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:09 +0530
Subject: [PATCH 11/17] ARC: dw2 unwind: Elide REG_INVALID check
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-12-git-send-email-vgupta@synopsys.com>

REG_INVALID checks if reg_info[*].width is zero, which is compile time
contant set to NON zero. No point in checking it.

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index f2a486d9dac2..b1a520afcbcb 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -48,10 +48,6 @@ static const struct {
 	unsigned width:BITS_PER_LONG / 2;
 } reg_info[] = { UNW_REGISTER_INFO };
 
-#ifndef REG_INVALID
-#define REG_INVALID(r) (reg_info[r].width == 0)
-#endif
-
 #define DW_CFA_nop                          0x00
 #define DW_CFA_set_loc                      0x01
 #define DW_CFA_advance_loc1                 0x02
@@ -868,9 +864,7 @@ static int cie_validate(const u32 *cie, struct cie *t_cie)
 	t_cie->fde_pointer_type = ptrType;
 
 	if (ptr > end
-	    || retAddrReg >= ARRAY_SIZE(reg_info)
-	    || REG_INVALID(retAddrReg)
-	    || reg_info[retAddrReg].width != sizeof(unsigned long))
+	    || retAddrReg >= ARRAY_SIZE(reg_info))
 		return 0;
 
 	unw_debug("\nDwarf Unwinder setup: CIE Info:\n");
@@ -1017,19 +1011,11 @@ int arc_unwind(struct unwind_frame_info *frame)
 		  state.cfa.reg, state.cfa.offs, cfa);
 
 	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
-		if (REG_INVALID(i)) {
-			if (state.regs[i].where == Nowhere)
-				continue;
-			return -EIO;
-		}
 		switch (state.regs[i].where) {
 		default:
 			break;
 		case Register:
-			if (state.regs[i].value >= ARRAY_SIZE(reg_info)
-			    || REG_INVALID(state.regs[i].value)
-			    || reg_info[i].width >
-			    reg_info[state.regs[i].value].width)
+			if (state.regs[i].value >= ARRAY_SIZE(reg_info))
 				return -EIO;
 			switch (reg_info[state.regs[i].value].width) {
 			case sizeof(u8):
@@ -1061,8 +1047,6 @@ int arc_unwind(struct unwind_frame_info *frame)
 	fptr = (unsigned long *)(&frame->regs);
 	for (i = 0; i < ARRAY_SIZE(state.regs); ++i, fptr++) {
 
-		if (REG_INVALID(i))
-			continue;
 		switch (state.regs[i].where) {
 		case Nowhere:
 			if (reg_info[i].width != sizeof(UNW_SP(frame))
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Thu Dec  3 04:41:13 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 3 Dec 2015 18:11:13 +0530
Subject: [PATCH 15/17] ARC: dw2 unwind: Single exit point for instrumentation
In-Reply-To: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
References: <1449146475-15335-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449146475-15335-16-git-send-email-vgupta@synopsys.com>

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 4f739716f908..e02d974ea789 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -904,6 +904,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 	unsigned long *fptr;
 	unsigned long addr;
 	struct eh_frame_header *hdr;
+	int ret = -EINVAL;
 
 	unw_debug("\nUNWIND FRAME: -------------------------------------\n");
 	unw_debug("PC\t\t: 0x%lx %pS\nr31 [BLINK]\t: 0x%lx %pS\nr28 [SP]\t: 0x%lx\nr27 [FP]\t: 0x%lx\n",
@@ -912,7 +913,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 		  UNW_SP(frame), UNW_FP(frame));
 
 	if (UNW_PC(frame) == 0)
-		return -EINVAL;
+		goto bad_unw;
 
 #ifdef UNWIND_DEBUG0
 	{
@@ -926,11 +927,11 @@ int arc_unwind(struct unwind_frame_info *frame)
 
 	table = find_table(pc);
 	if (table == NULL)
-		return -EINVAL;
+		goto bad_unw;
 
 	hdr = table->header;
 	if (hdr == NULL)
-		return -EINVAL;
+		goto bad_unw;
 
 	s = i = 0;
 	e = hdr->fde_count - 1;
@@ -948,7 +949,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 	if (pc >= startLoc)
 		fde = (u32 *)hdr->table[i].fde;
 	else
-		return -EINVAL;
+		goto bad_unw;
 
 	memset(&state, 0, sizeof(state));
 	ptr = (const u8 *)(fde + 2);
@@ -956,7 +957,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 
 	ptrType = table->cie.fde_pointer_type;
 	if (read_pointer(&ptr, end, ptrType) != startLoc)
-		return -EINVAL;
+		goto bad_unw;
 
 	if (!(ptrType & DW_EH_PE_indirect))
 		ptrType &= DW_EH_PE_FORM | DW_EH_PE_signed;
@@ -967,14 +968,15 @@ int arc_unwind(struct unwind_frame_info *frame)
 	if (pc >= endLoc) {
 		unw_debug("Unwindo info missing for PC %lx: {%lx,%lx}\n",
 			  pc, startLoc, endLoc);
-		return -EINVAL;
+		ret = -ENOENT;
+		goto bad_unw;
 	}
 
 	if (table->cie.aug) {
 		uleb128_t augSize = get_uleb128(&ptr, end);
 
 		if ((ptr += augSize) > end)
-			return -EINVAL;
+			goto bad_unw;
 	}
 
 	state.org = state.loc = startLoc;
@@ -995,8 +997,10 @@ int arc_unwind(struct unwind_frame_info *frame)
 	    || state.loc > endLoc
 /*	   || state.regs[retAddrReg].where == Nowhere */
 	    || state.cfa.reg >= ARRAY_SIZE(reg_info)
-	    || state.cfa.offs % sizeof(unsigned long))
-		return -EIO;
+	    || state.cfa.offs % sizeof(unsigned long)) {
+		ret = -EIO;
+		goto bad_unw;
+	}
 
 	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
 	startLoc = min_t(unsigned long, UNW_SP(frame), cfa);
@@ -1022,7 +1026,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 	for (i = 0; state.has_cfa_register && i < ARRAY_SIZE(state.regs); ++i) {
 		if (state.regs[i].where == Register) {
 			if (state.regs[i].value >= ARRAY_SIZE(reg_info))
-				return -EIO;
+				goto bad_unw;
 
 			state.regs[i].value = FRAME_REG(state.regs[i].value, unsigned long);
 		}
@@ -1054,7 +1058,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 			    || addr < startLoc
 			    || addr + sizeof(unsigned long) < addr
 			    || addr + sizeof(unsigned long) > endLoc)
-					return -EIO;
+					goto bad_unw;
 
 			FRAME_REG(i, unsigned long) = *(unsigned long *)addr;
 			break;
@@ -1062,7 +1066,10 @@ int arc_unwind(struct unwind_frame_info *frame)
 		unw_debug("r%d: 0x%lx\n", i, *fptr);
 	}
 
-	return 0;
+	ret = 0;
+bad_unw:
+
+	return ret;
 #undef FRAME_REG
 }
 EXPORT_SYMBOL(arc_unwind);
-- 
1.9.1



From marc.zyngier at arm.com  Thu Dec  3 10:33:35 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 03 Dec 2015 18:33:35 +0000
Subject: [PATCH v3 04/18] irqchip: add nps Internal and external irqchips
In-Reply-To: <DB5PR02MB114150510832BA29D46A8A4AD60E0@DB5PR02MB1141.eurprd02.prod.outlook.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-5-git-send-email-noamc@ezchip.com>
 <565DA0B6.5080903@arm.com>
 <DB5PR02MB114150510832BA29D46A8A4AD60E0@DB5PR02MB1141.eurprd02.prod.outlook.com>
Message-ID: <56608AFF.80302@arm.com>

Hi Noam,

On 02/12/15 15:08, Noam Camus wrote:
>> From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
>> Sent: Tuesday, December 01, 2015 3:29 PM
> 
>> +  interrupt source. The value shall be 1.
> 
>> So you never have to encode the interrupt trigger type? Do you only support edge or level?
> I Always use level sensitive.
> 
>> +
>> +#define NPS_GIM_P_EN	0x100	/* Peripheral interrupts source enable */
>> +#define NPS_GIM_P_BLK	0x118	/* Peripheral interrupts blocking for sources */
> 
>>> Are these the interrupts the peripherals are using? If yes, they really have nothing to do here...
> I will move this from here 
>>> +	__asm__ __volatile__ (
>>> +	"       .word %0\n"
>>> +	:
>>> +	: "i"(CTOP_INST_RSPI_GIC_0_R12)
>>> +	: "memory");
> 
>> Silly question: why cannot you just write the actual instruction
>> instead of shoving the instruction like this? Also, .inst would be
>> more appropriate...
> [Noam Camus] Since this is instruction that yet is not part of
> up-streamed binutils of ARC.  Now ARC maintainer can build our kernel
> with generic ARC toolchain.

OK. If you decide to carry on using this, I'd still recommend using
.inst instead of .word, so that you can get a proper disassembly.

>>> +static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
>>> +			  irq_hw_number_t hw)
>>> +{
>>> +	switch (irq) {
>>> +	case TIMER0_IRQ:
>>> +#if defined(CONFIG_SMP)
>>> +	case IPI_IRQ:
>>> +#endif
>>> +		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
>>> +					 handle_percpu_irq);
>>> +	break;
>>> +	default:
>>> +		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
>>> +					 handle_fasteoi_irq);
>>> +	break;
>>> +	}
> 
>> No. This is just wrong. Either you get per interrupt information
>> from the device tree to configure the interrupt the right way, or
>> you have different interrupt controllers for each device.
> I am not sure how you want me to get it from DTB? Please refer to
> some reference.

Here, you are assuming that 'irq' is a hardware number, while there is
no reason why it should be (it only works because you are using legacy
domains, more on that later).

Your switch/case statement should be based on the 'hw' parameter,
because that is your HW IRQ number. the irq parameter can be completely
random, and will eventually be once you fix the rest of the driver.

Also, can you always tell the per-cpu property of your interrupt based
on its number? If you can, then it is fine.

>> But using the Linux irq number is always wrong. You should only consider the hwirq.
> I will change
> 
>> +
>> +	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
>> +						   &nps400_irq_ops, NULL);
> 
>> And that's why you can get away with the above horror. Don't use
>> legacy domains. This stuff is by no mean legacy.
> So what is my alternative here?

Your alternative is to use irq_domain_add_linear, for example, and to
make sure that you always refer to the hw number when manipulating the
HW. You will quickly notice that the Linux IRQ number has nothing to do
with the HW one, and you'll be able to quickly iron out the bugs.

Looking forward to reviewing your next version.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From daniel.lezcano at linaro.org  Fri Dec  4 00:07:29 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 4 Dec 2015 09:07:29 +0100
Subject: [PATCH v3 01/18] Documentation: Add EZchip vendor to binding list
In-Reply-To: <1448974985-11487-2-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-2-git-send-email-noamc@ezchip.com>
Message-ID: <566149C1.8070502@linaro.org>

On 12/01/2015 02:02 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> Add EZchip to vendor prefixes list.
> EZchip introduce the NPS platform for the ARC architecture.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Acked-by: Rob Herring <robh+dt at kernel.org>
> Cc: Pawel Moll <pawel.moll at arm.com>
> ---
>   Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
>   .../devicetree/bindings/vendor-prefixes.txt        |    1 +
>   2 files changed, 8 insertions(+), 0 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
>
> diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
> new file mode 100644
> index 0000000..f8b5e9b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arc/eznps.txt
> @@ -0,0 +1,7 @@
> +EZchip NPS Network Proccessor Platforms Device Tree Bindings

Processor

-- 
  <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



From daniel.lezcano at linaro.org  Fri Dec  4 01:13:11 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 4 Dec 2015 10:13:11 +0100
Subject: [PATCH v3 03/18] clocksource: Add NPS400 timers driver
In-Reply-To: <1448974985-11487-4-git-send-email-noamc@ezchip.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-4-git-send-email-noamc@ezchip.com>
Message-ID: <56615927.30201@linaro.org>

On 12/01/2015 02:02 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> Add internal tick generator which is shared by all cores.
> Each cluster of cores view it through dedicated address.
> This is used for SMP system where all CPUs synced by same
> clock source.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: John Stultz <john.stultz at linaro.org>
> Acked-by: Vineet Gupta <vgupta at synopsys.com>

[ ... ]

> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 56bd16e..20969b0 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -46,6 +46,7 @@ obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
>   obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
>   obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
>   obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
> +obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o

CONFIG_CLKSRC_NPS

>
>   obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
>   obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> new file mode 100644
> index 0000000..ef8f287
> --- /dev/null
> +++ b/drivers/clocksource/timer-nps.c
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/clocksource.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <plat/ctop.h>

Why do you need this header ? nps_host_reg ?

We prevent to include headers from <plat> in the drivers directory. You 
should find a way to get rid of it.

> +#define NPS_MSU_TICK_LOW	0xC8
> +#define NPS_CLUSTER_OFFSET	8
> +#define NPS_CLUSTER_NUM		16
> +
> +static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;

Perhaps a small optimization...

static DEFINE_PER_CPU_READ_MOSTLY(void __iomem *, baseaddr);

static cycle_t nps_clksrc_read(struct clocksource *clksrc)
{
	void __iomem *base = per_cpu(baseaddr, raw_smp_processor_id());

	return (cycle_t)ioread32be(base);
}

and in the init function:

for_each_cpu(cpu) {
	per_cpu(baseaddr, cpu) = nps_host_reg(cpu,
					NPS_MSU_BLKID,
					NPS_MSU_TICK_LOW
}

> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
> +
> +	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);

AFAICT, there is a memory barrier with ioread32be, are you really sure 
we have to use it in this code path ?

> +}
> +
> +static struct clocksource nps_counter = {
> +	.name	= "EZnps-tick",
> +	.rating = 301,
> +	.read   = nps_clksrc_read,
> +	.mask   = CLOCKSOURCE_MASK(32),
> +	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static void __init nps_setup_clocksource(struct device_node *node)
> +{
> +	struct clocksource *clksrc = &nps_counter;
> +	unsigned long rate, dt_root;
> +	int ret, cluster;
> +
> +	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);

> +
> +	dt_root = of_get_flat_dt_root();
> +	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);

I don't get why this is done this way. The Kconfig option help says the 
clocksource rate is 1GHz but in the DT the clock is 88MHz.

It would be cleaner to define a fixed clock and then add a phandle in 
the DT.

	timer_clk: timer_clk {
		#clock-cells = <0>;
		compatible = "fixed-clock";
		clock-frequency = <123456789>;
	};

	timer {
		compatible = "ezchip,nps400-timer";
		clocks = <&timer_clk>;
	}

That will result in the same code than the other drivers.

	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		pr_err("%s: invalid clock\n", np->full_name);
		return;
	}

  	rate = clk_get_rate(clk);


> +	ret = clocksource_register_hz(clksrc, rate);
> +	if (ret)
> +		pr_err("Couldn't register clock source.\n");
> +}
> +
> +CLOCKSOURCE_OF_DECLARE(nps_400, "ezchip,nps400-timer",
> +		       nps_setup_clocksource);
>


-- 
  <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



From noamc at ezchip.com  Fri Dec  4 03:46:03 2015
From: noamc at ezchip.com (Noam Camus)
Date: Fri, 4 Dec 2015 11:46:03 +0000
Subject: [PATCH v3 01/18] Documentation: Add EZchip vendor to binding list
In-Reply-To: <566149C1.8070502@linaro.org>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-2-git-send-email-noamc@ezchip.com>,
 <566149C1.8070502@linaro.org>
Message-ID: <DB5PR02MB11417AEA313B24A716D9B722D60C0@DB5PR02MB1141.eurprd02.prod.outlook.com>

>From: Daniel Lezcano <daniel.lezcano at linaro.org>
>Sent: Friday, December 4, 2015 10:07 AM
>>
>> diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
>> new file mode 100644
>> index 0000000..f8b5e9b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arc/eznps.txt
>> @@ -0,0 +1,7 @@
>> +EZchip NPS Network Proccessor Platforms Device Tree Bindings
>
>Processor
Thanks
--
  <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



From noamc at ezchip.com  Fri Dec  4 04:26:32 2015
From: noamc at ezchip.com (Noam Camus)
Date: Fri, 4 Dec 2015 12:26:32 +0000
Subject: [PATCH v3 03/18] clocksource: Add NPS400 timers driver
In-Reply-To: <56615927.30201@linaro.org>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-4-git-send-email-noamc@ezchip.com>,
 <56615927.30201@linaro.org>
Message-ID: <DB5PR02MB1141916F4F399704A15F4AE5D60C0@DB5PR02MB1141.eurprd02.prod.outlook.com>

>From: Daniel Lezcano <daniel.lezcano at linaro.org>
>Sent: Friday, December 4, 2015 11:13 AM
>> +obj-$(CONFIG_ARC_PLAT_EZNPS) += timer-nps.o

>CONFIG_CLKSRC_NPS
I wish this driver to be build only for this specific ARC platform.
This clock source is embedded in our SoC.
It is not meant to be built for any other architecture.
This is why below I include header from our ARC platform to avoid code duplicity.

>> +#include <plat/ctop.h>

>Why do you need this header ? nps_host_reg ?
Correct we use common code from our platform.

>We prevent to include headers from <plat> in the drivers directory. You
>should find a way to get rid of it.

The Only way I can think of is code duplicity and I prefer not to.
I see some include to asm/mach headers in clocksource, what is the difference?
Could you suggest a better place for me to place my header file.

>> +static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
>
>Perhaps a small optimization...
Thanks

>static DEFINE_PER_CPU_READ_MOSTLY(void __iomem *, baseaddr);

>static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>{
>       void __iomem *base = per_cpu(baseaddr, raw_smp_processor_id());
>
 >       return (cycle_t)ioread32be(base);
>}

>and in the init function:

>for_each_cpu(cpu) {
>       per_cpu(baseaddr, cpu) = nps_host_reg(cpu,
>                                      NPS_MSU_BLKID,
>                                    NPS_MSU_TICK_LOW
>}
Thanks again


>> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>> +{
>> +     int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
>> +
>> +     return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);

>,AFAICT, there is a memory barrier with ioread32be, are you really sure
>we have to use it in this code path ?
Are you saying to remove use of ioread32be?
What should I use instead?

>> +
>> +     dt_root = of_get_flat_dt_root();
>> +     rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);

>I don't get why this is done this way. The Kconfig option help says the
>clocksource rate is 1GHz but in the DT the clock is 88MHz.
It says that clock source is up to 1GHz

>It would be cleaner to define a fixed clock and then add a phandle in
>the DT.

>        timer_clk: timer_clk {
>               #clock-cells = <0>;
>                compatible = "fixed-clock";
>               clock-frequency = <123456789>;
>        };

>        timer {
>               compatible = "ezchip,nps400-timer";
>                clocks = <&timer_clk>;
>       }

>That will result in the same code than the other drivers.

>      clk = of_clk_get(np, 0);
>     if (IS_ERR(clk)) {
>              pr_err("%s: invalid clock\n", np->full_name);
>               return;
>        }

>      rate = clk_get_rate(clk);
Once again thanks I will fix this.

-Noam


From daniel.lezcano at linaro.org  Fri Dec  4 04:52:22 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 4 Dec 2015 13:52:22 +0100
Subject: [PATCH v3 03/18] clocksource: Add NPS400 timers driver
In-Reply-To: <DB5PR02MB1141916F4F399704A15F4AE5D60C0@DB5PR02MB1141.eurprd02.prod.outlook.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-4-git-send-email-noamc@ezchip.com>
 <56615927.30201@linaro.org>
 <DB5PR02MB1141916F4F399704A15F4AE5D60C0@DB5PR02MB1141.eurprd02.prod.outlook.com>
Message-ID: <56618C86.7020407@linaro.org>

On 12/04/2015 01:26 PM, Noam Camus wrote:
>> From: Daniel Lezcano <daniel.lezcano at linaro.org>
>> Sent: Friday, December 4, 2015 11:13 AM
>>> +obj-$(CONFIG_ARC_PLAT_EZNPS) += timer-nps.o
>
>> CONFIG_CLKSRC_NPS
> I wish this driver to be build only for this specific ARC platform.
> This clock source is embedded in our SoC.

I understand but we are removing all platform specific Kconfig options 
from the drivers. If CONFIG_CLKSRC_NPS is selected by 
CONFIG_ARC_PLAT_EZNPS only, the result is the same.

By the way, it is probable the "if COMPILE_TEST" option is added later 
to the option. We are trying to have the drivers to be compilable on 
different platforms in order to increase the compilation test coverage. 
It is useful for instance when we touch a common code which impact all 
the drivers, we don't need the specific platform to compile on it and we 
minimize a cross compile toolchain usage. Hence compilation failure on 
ARC will be detected sooner, before the next merge window happens.

For this reason, having common code in the driver is important and 
including a platform breaks the current effort.

> It is not meant to be built for any other architecture.
> This is why below I include header from our ARC platform to avoid code duplicity.
>
>>> +#include <plat/ctop.h>
>
>> Why do you need this header ? nps_host_reg ?
> Correct we use common code from our platform.
>
>> We prevent to include headers from <plat> in the drivers directory. You
>> should find a way to get rid of it.
>
> The Only way I can think of is code duplicity and I prefer not to.
> I see some include to asm/mach headers in clocksource, what is the difference?

The difference is <asm> includes are architecture dependent and could be 
acceptable if there is no choice (all arm timers use the same 
functionality from these headers), while <plat> includes are platform 
specific, so restricted to a specific platform.

> Could you suggest a better place for me to place my header file.

Yes, perhaps:

include/soc/nps
drivers/soc/nps

>>> +static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
>>
>> Perhaps a small optimization...
> Thanks
>
>> static DEFINE_PER_CPU_READ_MOSTLY(void __iomem *, baseaddr);
>
>> static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>> {
>>        void __iomem *base = per_cpu(baseaddr, raw_smp_processor_id());
>>
>   >       return (cycle_t)ioread32be(base);
>> }
>
>> and in the init function:
>
>> for_each_cpu(cpu) {
>>        per_cpu(baseaddr, cpu) = nps_host_reg(cpu,
>>                                       NPS_MSU_BLKID,
>>                                     NPS_MSU_TICK_LOW
>> }
> Thanks again
>
>
>>> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
>>> +{
>>> +     int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
>>> +
>>> +     return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
>
>> ,AFAICT, there is a memory barrier with ioread32be, are you really sure
>> we have to use it in this code path ?
> Are you saying to remove use of ioread32be?
> What should I use instead?

Never mind, I looked at the arm's ioread32be definition where there is a 
memory barrier. With this architecture ioread32be uses the generic one 
without the memory barrier (well, yes it uses one in the raw_readl asm 
implementation but we can't do anything).

>>> +
>>> +     dt_root = of_get_flat_dt_root();
>>> +     rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);
>
>> I don't get why this is done this way. The Kconfig option help says the
>> clocksource rate is 1GHz but in the DT the clock is 88MHz.
> It says that clock source is up to 1GHz

ah ok.

>> It would be cleaner to define a fixed clock and then add a phandle in
>> the DT.
>
>>         timer_clk: timer_clk {
>>                #clock-cells = <0>;
>>                 compatible = "fixed-clock";
>>                clock-frequency = <123456789>;
>>         };
>
>>         timer {
>>                compatible = "ezchip,nps400-timer";
>>                 clocks = <&timer_clk>;
>>        }
>
>> That will result in the same code than the other drivers.
>
>>       clk = of_clk_get(np, 0);
>>      if (IS_ERR(clk)) {
>>               pr_err("%s: invalid clock\n", np->full_name);
>>                return;
>>         }
>
>>       rate = clk_get_rate(clk);
> Once again thanks I will fix this.
>
> -Noam
>


-- 
  <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



From Alexey.Brodkin at synopsys.com  Fri Dec  4 11:22:06 2015
From: Alexey.Brodkin at synopsys.com (Alexey Brodkin)
Date: Fri,  4 Dec 2015 22:22:06 +0300
Subject: [PATCH] ARC: [axs10x] enable DW DMA controller
Message-ID: <1449256926-16786-1-git-send-email-abrodkin@synopsys.com>

From: Nelson Pereira <npereira at synopsys.com>

ARC SDP baseboard among other peripherals sports
DesignWare DMA controller.

This enables support of that device.
Note typically DW DMA controller is used with external devices
connected to ARC SDP board via HAPS Extension bus.

Signed-off-by: Nelson Pereira <npereira at synopsys.com>
Cc: Vineet Gupta <vgupta at synopsys.com>
Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
---
 arch/arc/boot/dts/axs10x_mb.dtsi      | 16 ++++++++++++++++
 arch/arc/configs/axs101_defconfig     |  5 +++++
 arch/arc/configs/axs103_defconfig     |  5 +++++
 arch/arc/configs/axs103_smp_defconfig |  5 +++++
 4 files changed, 31 insertions(+)

diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
index f3db321..1e57580 100644
--- a/arch/arc/boot/dts/axs10x_mb.dtsi
+++ b/arch/arc/boot/dts/axs10x_mb.dtsi
@@ -220,5 +220,21 @@
 				reg = <2>;
 			};
 		};
+
+		dmac: dmac at 0x80000 {
+			compatible = "snps,dma-spear1340";
+			reg = <0x80000 0x1000>;
+			interrupts = <9>;
+			dma-channels = <4>;
+			dma-requests = <16>;
+			dma-masters = <2>;
+			#dma-cells = <3>;
+			chan_allocation_order = <1>;
+			chan_priority = <1>;
+			block_size = <0xfff>;
+			data_width = <3 3>;
+			clocks = <&apbclk>;
+			clock-names = "hclk";
+		};
 	};
 };
diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 562dac6..405474f 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -90,6 +90,11 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC_CORE=y
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index 83a6d8d..570f06f 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -96,6 +96,11 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC_CORE=y
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index f1e1c84..16cfce8 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -97,6 +97,11 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC_CORE=y
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
-- 
2.4.3



From Vineet.Gupta1 at synopsys.com  Sat Dec  5 02:14:32 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Sat, 5 Dec 2015 10:14:32 +0000
Subject: [PATCH] ARC: [axs10x] enable DW DMA controller
References: <1449256926-16786-1-git-send-email-abrodkin@synopsys.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D4B6E@IN01WEMBXA.internal.synopsys.com>

On Saturday 05 December 2015 12:52 AM, Alexey Brodkin wrote:
> From: Nelson Pereira <npereira at synopsys.com>
>
> ARC SDP baseboard among other peripherals sports
> DesignWare DMA controller.
>
> This enables support of that device.
> Note typically DW DMA controller is used with external devices
> connected to ARC SDP board via HAPS Extension bus.

Such a board config needs to have it's own defconfig / DT (if needed). There's no
point in enabling this for rest of the world who don't have a use case for this IP.

So nack !

-Vineet
>
> Signed-off-by: Nelson Pereira <npereira at synopsys.com>
> Cc: Vineet Gupta <vgupta at synopsys.com>
> Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
> ---
>  arch/arc/boot/dts/axs10x_mb.dtsi      | 16 ++++++++++++++++
>  arch/arc/configs/axs101_defconfig     |  5 +++++
>  arch/arc/configs/axs103_defconfig     |  5 +++++
>  arch/arc/configs/axs103_smp_defconfig |  5 +++++
>  4 files changed, 31 insertions(+)
>
> diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
> index f3db321..1e57580 100644
> --- a/arch/arc/boot/dts/axs10x_mb.dtsi
> +++ b/arch/arc/boot/dts/axs10x_mb.dtsi
> @@ -220,5 +220,21 @@
>  				reg = <2>;
>  			};
>  		};
> +
> +		dmac: dmac at 0x80000 {
> +			compatible = "snps,dma-spear1340";
> +			reg = <0x80000 0x1000>;
> +			interrupts = <9>;
> +			dma-channels = <4>;
> +			dma-requests = <16>;
> +			dma-masters = <2>;
> +			#dma-cells = <3>;
> +			chan_allocation_order = <1>;
> +			chan_priority = <1>;
> +			block_size = <0xfff>;
> +			data_width = <3 3>;
> +			clocks = <&apbclk>;
> +			clock-names = "hclk";
> +		};
>  	};
>  };
> diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
> index 562dac6..405474f 100644
> --- a/arch/arc/configs/axs101_defconfig
> +++ b/arch/arc/configs/axs101_defconfig
> @@ -90,6 +90,11 @@ CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_PLTFM=y
>  CONFIG_MMC_DW=y
>  CONFIG_MMC_DW_IDMAC=y
> +CONFIG_DMADEVICES=y
> +CONFIG_DW_DMAC_CORE=y
> +CONFIG_DW_DMAC=y
> +CONFIG_DMA_ENGINE=y
> +CONFIG_DMA_OF=y
>  # CONFIG_IOMMU_SUPPORT is not set
>  CONFIG_EXT3_FS=y
>  CONFIG_EXT4_FS=y
> diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
> index 83a6d8d..570f06f 100644
> --- a/arch/arc/configs/axs103_defconfig
> +++ b/arch/arc/configs/axs103_defconfig
> @@ -96,6 +96,11 @@ CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_PLTFM=y
>  CONFIG_MMC_DW=y
>  CONFIG_MMC_DW_IDMAC=y
> +CONFIG_DMADEVICES=y
> +CONFIG_DW_DMAC_CORE=y
> +CONFIG_DW_DMAC=y
> +CONFIG_DMA_ENGINE=y
> +CONFIG_DMA_OF=y
>  # CONFIG_IOMMU_SUPPORT is not set
>  CONFIG_EXT3_FS=y
>  CONFIG_EXT4_FS=y
> diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
> index f1e1c84..16cfce8 100644
> --- a/arch/arc/configs/axs103_smp_defconfig
> +++ b/arch/arc/configs/axs103_smp_defconfig
> @@ -97,6 +97,11 @@ CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_PLTFM=y
>  CONFIG_MMC_DW=y
>  CONFIG_MMC_DW_IDMAC=y
> +CONFIG_DMADEVICES=y
> +CONFIG_DW_DMAC_CORE=y
> +CONFIG_DW_DMAC=y
> +CONFIG_DMA_ENGINE=y
> +CONFIG_DMA_OF=y
>  # CONFIG_IOMMU_SUPPORT is not set
>  CONFIG_EXT3_FS=y
>  CONFIG_EXT4_FS=y



From Alexey.Brodkin at synopsys.com  Mon Dec  7 01:12:27 2015
From: Alexey.Brodkin at synopsys.com (Alexey Brodkin)
Date: Mon, 7 Dec 2015 09:12:27 +0000
Subject: [PATCH] ARC: [axs10x] enable DW DMA controller
In-Reply-To: <C2D7FE5348E1B147BCA15975FBA23075F44D4B6E@IN01WEMBXA.internal.synopsys.com>
References: <1449256926-16786-1-git-send-email-abrodkin@synopsys.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D4B6E@IN01WEMBXA.internal.synopsys.com>
Message-ID: <1449479546.2772.3.camel@synopsys.com>

Hi Vineet,

On Sat, 2015-12-05 at 10:14 +0000, Vineet Gupta wrote:
> On Saturday 05 December 2015 12:52 AM, Alexey Brodkin wrote:
> > From: Nelson Pereira <npereira at synopsys.com>
> > 
> > ARC SDP baseboard among other peripherals sports
> > DesignWare DMA controller.
> > 
> > This enables support of that device.
> > Note typically DW DMA controller is used with external devices
> > connected to ARC SDP board via HAPS Extension bus.
> 
> Such a board config needs to have it's own defconfig / DT (if needed). There's no
> point in enabling this for rest of the world who don't have a use case for this IP.
> 
> So nack !

I see rationale behind this decision but:
1) How enabled DMA controller hurts other users of the same SDP board
2) That DMA controller exists in SDP anyway - that's not a special flavor of ARC SDP
3) Another defconfig and .dts adds another item for verification while
   enabling DW DMA in our current defconfigs allows usage of the same one binaries for
   all purposes on ARC SDP.

-Alexey

From noamc at ezchip.com  Mon Dec  7 03:19:28 2015
From: noamc at ezchip.com (Noam Camus)
Date: Mon, 7 Dec 2015 11:19:28 +0000
Subject: [PATCH v3 04/18] irqchip: add nps Internal and external irqchips
In-Reply-To: <56608AFF.80302@arm.com>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-5-git-send-email-noamc@ezchip.com>
 <565DA0B6.5080903@arm.com>
 <DB5PR02MB114150510832BA29D46A8A4AD60E0@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <56608AFF.80302@arm.com>
Message-ID: <DB5PR02MB114151DD38ACFD58CFFDB2C3D6090@DB5PR02MB1141.eurprd02.prod.outlook.com>

From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
Sent: Thursday, December 03, 2015 8:34 PM

>>> Silly question: why cannot you just write the actual instruction 
>>> instead of shoving the instruction like this? Also, .inst would be 
>>> more appropriate...
>> [Noam Camus] Since this is instruction that yet is not part of 
>> up-streamed binutils of ARC.  Now ARC maintainer can build our kernel 
>> with generic ARC toolchain.

>OK. If you decide to carry on using this, I'd still recommend using .inst instead of .word, so that you can get a proper disassembly.
Seem to me that ".inst" is ARM Machine directive.

>Also, can you always tell the per-cpu property of your interrupt based on its number? If you can, then it is fine.
Yes I can, and I am using this knowledge.

>Your alternative is to use irq_domain_add_linear, for example, and to make sure that you always refer to the hw number when manipulating the HW. You will quickly notice that the Linux IRQ number has nothing to do with the HW one, and you'll be able to quickly iron out the bugs.

Indeed when I moved from legacy to linear map I had to call irq_create_mapping() for my percpu IRQs and that's it.
Thanks

-Noam


From Alexey.Brodkin at synopsys.com  Mon Dec  7 03:21:37 2015
From: Alexey.Brodkin at synopsys.com (Alexey Brodkin)
Date: Mon,  7 Dec 2015 14:21:37 +0300
Subject: [PATCH] ARC: [axs10x] cap ethernet phy to 100 Mbit/sec
Message-ID: <1449487297-10093-1-git-send-email-abrodkin@synopsys.com>

Current ARC SDP boards cannot reliably handle 1Gbit
Ethernet connections due to limitations in hardware.

To make sure networking is stable on the board we're
limiting phy to 100 Mbit.

Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
Cc: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/boot/dts/axs10x_mb.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
index f3db321..44a578c 100644
--- a/arch/arc/boot/dts/axs10x_mb.dtsi
+++ b/arch/arc/boot/dts/axs10x_mb.dtsi
@@ -46,6 +46,7 @@
 			snps,pbl = < 32 >;
 			clocks = <&apbclk>;
 			clock-names = "stmmaceth";
+			max-speed = <100>;
 		};
 
 		ehci at 0x40000 {
-- 
2.5.0



From Vineet.Gupta1 at synopsys.com  Mon Dec  7 06:09:41 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Mon, 7 Dec 2015 14:09:41 +0000
Subject: [PATCH] ARC: [axs10x] cap ethernet phy to 100 Mbit/sec
References: <1449487297-10093-1-git-send-email-abrodkin@synopsys.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D4DB7@IN01WEMBXA.internal.synopsys.com>

On Monday 07 December 2015 04:52 PM, Alexey Brodkin wrote:

Current ARC SDP boards cannot reliably handle 1Gbit
Ethernet connections due to limitations in hardware.

To make sure networking is stable on the board we're
limiting phy to 100 Mbit.

Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com><mailto:abrodkin at synopsys.com>
Cc: Vineet Gupta <vgupta at synopsys.com><mailto:vgupta at synopsys.com>

LGTM - added to for-curr for 4.4 !

Thx,
-Vineet


From noamc at ezchip.com  Tue Dec  8 05:00:23 2015
From: noamc at ezchip.com (Noam Camus)
Date: Tue, 8 Dec 2015 13:00:23 +0000
Subject: [PATCH v3 03/18] clocksource: Add NPS400 timers driver
In-Reply-To: <56615927.30201@linaro.org>
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-4-git-send-email-noamc@ezchip.com>
 <56615927.30201@linaro.org>
Message-ID: <DB5PR02MB114169D551B609CFC6F13E53D6080@DB5PR02MB1141.eurprd02.prod.outlook.com>

From: Daniel Lezcano [mailto:daniel.lezcano at linaro.org] 
Sent: Friday, December 04, 2015 11:13 AM


>It would be cleaner to define a fixed clock and then add a phandle in the DT.

>	timer_clk: timer_clk {
>		#clock-cells = <0>;
>		compatible = "fixed-clock";
>		clock-frequency = <123456789>;
>	};

>	timer {
>		compatible = "ezchip,nps400-timer";
>		clocks = <&timer_clk>;
>	}

>That will result in the same code than the other drivers.

>	clk = of_clk_get(np, 0);
>	if (IS_ERR(clk)) {
>		pr_err("%s: invalid clock\n", np->full_name);
>		return;
>	}

>  	rate = clk_get_rate(clk);

Seem like my driver comes before "fixed-clock" driver so I failed since I got no clocksource provider.
How can this be solved?

-Noam

From Vineet.Gupta1 at synopsys.com  Tue Dec  8 05:11:05 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Tue, 8 Dec 2015 18:41:05 +0530
Subject: [PATCH] sched/fair: [cosmetic] match ifdef/endif CONFIG_NO_HZ_COMMON
Message-ID: <1449580265-8532-1-git-send-email-vgupta@synopsys.com>

Spotted this when debuggign something completely different and trying to
unravel CONFIG_NO_HZ{,_COMMON,,_IDLE}

It seems we can clean up the legacy CONFIG_NO_HZ option, but first
remove it's proliferation.

Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 kernel/sched/fair.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index f04fda8f669c..0995a3dccd58 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4408,7 +4408,7 @@ void update_cpu_load_nohz(void)
 	}
 	raw_spin_unlock(&this_rq->lock);
 }
-#endif /* CONFIG_NO_HZ */
+#endif /* CONFIG_NO_HZ_COMMON */
 
 /*
  * Called from scheduler_tick()
-- 
1.9.1



From CARLOS.PALMINHA at synopsys.com  Wed Dec  9 16:10:46 2015
From: CARLOS.PALMINHA at synopsys.com (Carlos Palminha)
Date: Thu, 10 Dec 2015 00:10:46 +0000
Subject: Non existing DMA functions in ARC: dma_alloc_attrs,
 dma_free_attrs, dma_mmap_attrs
In-Reply-To: <C2D7FE5348E1B147BCA15975FBA23075F44D483A@IN01WEMBXA.internal.synopsys.com>
References: <C060B4F571DB524BB6D72E2C236D8FB002199FE6@DE02WEMBXB.internal.synopsys.com>
 <565F8BA2.4000506@synopsys.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D483A@IN01WEMBXA.internal.synopsys.com>
Message-ID: <5668C306.6020001@synopsys.com>

Hi Vineet,

I just used it against 4.4-rc4 and its compiling and linking fine. :)

Regards,
C.Palminha

On 03-12-2015 03:57, Vineet Gupta wrote:
> On Thursday 03 December 2015 05:54 AM, Carlos Palminha wrote:
>> Hi Vineet,
>>
>> I cherry picked those commits and now i'm getting a different error.
>>
>> any clue? Am i testing "untested" code?! :)
>>
>> Regards,
>> C.Palminha
>>
>> ---
>>   CC      init/do_mounts.o
>> In file included from include/linux/skbuff.h:34:0,
>>                  from include/linux/icmpv6.h:4,
>>                  from include/linux/ipv6.h:71,
>>                  from include/net/ipv6.h:16,
>>                  from include/linux/sunrpc/clnt.h:27,
>>                  from include/linux/nfs_fs.h:30,
>>                  from init/do_mounts.c:32:
>> include/linux/dma-mapping.h: In function ?dma_set_coherent_mask?:
>> include/linux/dma-mapping.h:104:2: error: implicit declaration of function ?dma_supported? [-Werror=implicit-function-declaration]
>>   if (!dma_supported(dev, mask))
>>   ^
>> include/linux/dma-mapping.h: In function ?dma_set_mask_and_coherent?:
>> include/linux/dma-mapping.h:119:2: error: implicit declaration of function ?dma_set_mask? [-Werror=implicit-function-declaration]
>>   int rc = dma_set_mask(dev, mask);
>>   ^
>> include/linux/dma-mapping.h: In function ?dma_zalloc_coherent?:
>> include/linux/dma-mapping.h:190:2: error: implicit declaration of function ?dma_alloc_coherent? [-Werror=implicit-function-declaration]
>>   void *ret = dma_alloc_coherent(dev, size, dma_handle,
>>   ^
>> include/linux/dma-mapping.h:190:14: warning: initialization makes pointer from integer without a cast [enabled by default]
>>   void *ret = dma_alloc_coherent(dev, size, dma_handle,
>>               ^
>> In file included from include/linux/icmpv6.h:4:0,
>>                  from include/linux/ipv6.h:71,
>>                  from include/net/ipv6.h:16,
>>                  from include/linux/sunrpc/clnt.h:27,
>>                  from include/linux/nfs_fs.h:30,
>>                  from init/do_mounts.c:32:
>> include/linux/skbuff.h: In function ?skb_frag_dma_map?:
>> include/linux/skbuff.h:2510:2: error: implicit declaration of function ?dma_map_page? [-Werror=implicit-function-declaration]
>>   return dma_map_page(dev, skb_frag_page(frag),
> 
> I'm not sure what exact code you are building off - linux-next of today builds
> just fine !
> Can u not baseline ur work off linux-next
> 
> -Vineet
> 
> 
>>
>>
>> On 02-12-2015 13:19, Carlos Palminha wrote:
>>> Hi Vineet,
>>>
>>> I'm using drm-next (its currently based on 4.4-rc3).
>>>
>>> Regarding linux-next DMA patches I assume you are talking about these 3 commits:
>>> * 19ab4d3aff0426058fe36aae4ac56320a6e4c6be
>>> * 8ee24f794c2dfff85930f25eab4f11a9bde7f920
>>> * c27a81903ba596c879a45e3028135a4f37fb1837
>>>
>>> Regards,
>>> C.Palminha
>>>
>>> -----Original Message-----
>>> From: Vineet Gupta 
>>> Sent: quarta-feira, 2 de Dezembro de 2015 06:32
>>> To: Carlos Palminha; linux-snps-arc at lists.infradead.org
>>> Cc: Alexey Brodkin
>>> Subject: Re: Non existing DMA functions in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>>>
>>> On Wednesday 02 December 2015 01:09 AM, Carlos Palminha wrote:
>>>> Hi guys,
>>>>
>>>> I'm bringing up a new ARC PGU driver for DRM framework with latest kernel tree.
>>>> I'm using ARC AXS101 as a base and selected one the DRM required config: HAVE_DMA_ATTRS due to some memory allocation helpers in DRM.
>>>>
>>>> I'm getting some errors with DMA functions not implemented in ARC: dma_alloc_attrs, dma_free_attrs, dma_mmap_attrs
>>>>
>>>> Any clue?
>>>>
>>>> Regards,
>>>> C.Palminha
>>>>
>>>> ---
>>>> include/linux/dma-mapping.h: In function 'dma_alloc_writecombine':
>>>> include/linux/dma-mapping.h:283:2: error: implicit declaration of function 'dma_alloc_attrs' [-Werror=implicit-function-declaration]
>>>>   return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
>>> This is because ARC port current lacks support for dma_attr_t and associated helpers.
>>> There is a series in flight in linux-next, by Christoph, which already addresses that.
>>>
>>> You can either cherry-pick those or in the interim use the hack attached.
>>>
>>> P.S. Per your comment at top, I'm assuming you are working off of mainline 4.3 or 4.4
>>>
>>> -Vineet
>>>
> 


From Vineet.Gupta1 at synopsys.com  Wed Dec  9 23:05:12 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 10 Dec 2015 07:05:12 +0000
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec
 10, 17:33
References: <20151210063403.1.54732@94a655e5a217>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>

On Thursday 10 December 2015 12:05 PM, noreply at ellerman.id.au wrote:
> FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec 10, 17:33
>
> http://kisskb.ellerman.id.au/kisskb/buildresult/12564629/
>
> Commit:   Add linux-next specific files for 20151210
>           8225f4e85cb03daea14661380745886ce01fd83a
> Compiler: arc-buildroot-linux-uclibc-gcc (Buildroot 2015.08.1) 4.8.4
>
> Possible errors
> ---------------
>
> include/linux/jiffies.h:10:33: fatal error: generated/timeconst.h: No such file or directory
> make[2]: *** [kernel/bounds.s] Error 1
> make[1]: *** [prepare0] Error 2
> make: *** [sub-make] Error 2
>
> No warnings found in log.

Hi Michael,

It is weird that no other arch build show similar errors.
Building same linux-next on my machine seems to be fine as well.

>From looking at logs it looks like some sort of a make / paralle jobs timing issue
at build farm.

P.S. Could you also update system to also cc lkml and
linux-snps-arc at lists.infradead.org for such errors.

Thx,
-Vineet




From mpe at ellerman.id.au  Thu Dec 10 01:04:01 2015
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Thu, 10 Dec 2015 20:04:01 +1100
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec
 10, 17:33
In-Reply-To: <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>
References: <20151210063403.1.54732@94a655e5a217>
 <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>
Message-ID: <1449738241.7156.1.camel@ellerman.id.au>

On Thu, 2015-12-10 at 07:05 +0000, Vineet Gupta wrote:

> On Thursday 10 December 2015 12:05 PM, noreply at ellerman.id.au wrote:

> > FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec 10, 17:33
> > 
> > http://kisskb.ellerman.id.au/kisskb/buildresult/12564629/
> > 
> > Commit:   Add linux-next specific files for 20151210
> >           8225f4e85cb03daea14661380745886ce01fd83a
> > Compiler: arc-buildroot-linux-uclibc-gcc (Buildroot 2015.08.1) 4.8.4
> > 
> > Possible errors
> > ---------------
> > 
> > include/linux/jiffies.h:10:33: fatal error: generated/timeconst.h: No such file or directory
> > make[2]: *** [kernel/bounds.s] Error 1
> > make[1]: *** [prepare0] Error 2
> > make: *** [sub-make] Error 2
> > 
> > No warnings found in log.
> 
> Hi Michael,
> 
> It is weird that no other arch build show similar errors.
> Building same linux-next on my machine seems to be fine as well.

That is weird. I'll ask it to rebuild it and see if it happens again.

Do you build with -j?

> From looking at logs it looks like some sort of a make / paralle jobs timing issue
> at build farm.
> 
> P.S. Could you also update system to also cc lkml and
> linux-snps-arc at lists.infradead.org for such errors.

I'll add the arc list, I don't like to cc lkml so as not to annoy people with
too many error mails.

cheers



From Vineet.Gupta1 at synopsys.com  Thu Dec 10 01:25:54 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 10 Dec 2015 09:25:54 +0000
Subject: percpu irq APIs and perf
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>

Hi Marc / Daniel / Jason,

I had a couple of questions about percpu irq API, hopefully you can help answer.

On ARM, how do u handle requesting per cpu IRQs - specifically usage of request_percpu_irq() / enable_percpu_irq() API.
It seems, for using them, we obviously need to explicitly set irq as percpu and as a consequence explicitly enable autoen (since former disables that). See arch/arc/kernel/irq.c: arc_request_percpu_irq() called by ARC per cpu timer setup.

    if (!cpu)  {
           irq_set_percpu_devid()   <--- disables AUTOEN
           irq_modify_status(IRQ_NOAUTOEN)  <-- to undo side-effect of above
           request_percpu_irq
    }
    enable_percpu_irq

I don't see pattern in general for drivers/clocksource/ and/or arm_arch_timer.c for PPI case.

Further there is an ordering requirement as in request_percpu_irq() needs to be called only for the first calling core, and enable_percpu_irq() on each one. If enable is done ahead of request it obviously fails.

For ARC I've historically used a wrapper arc_request_percpu_irq() [pseudo code above] - which has an inherent assumption (now realize fragile) that it will be called on core0 first thus guaranteeing the ordering above. This is true for timer, IPI etc but not for other late probed peripherals - specially perf.

Infact ARC perf probe open codes on_each_cpu() to ensure irq request is done locally first.

But this all falls apart, when perf probe happens on coreX (not core0), causing enable to be called ahead of request anyways. This is what I'm running into now.

I think the solution is to call request_percpu_irq() on whatever core hits first and call enable_percpu_irq() from a cpu up notifier. But I think the notifier won't run on boot cpu ?  Or is there a better way to clean up all this mess.

FWIW, I see this issue on 3.18 kernel but not latest 4.4-rcX because in 3.18 arc perf probe invariably happens on coreX (due to init task migration right after clocksource switch - something which doesn't happen on 4.4 likely due to recent timer core changes).

Thx,
-Vineet



From Vineet.Gupta1 at synopsys.com  Thu Dec 10 01:28:47 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 10 Dec 2015 14:58:47 +0530
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec 10, 
 17:33
In-Reply-To: <1449738241.7156.1.camel@ellerman.id.au>
References: <20151210063403.1.54732@94a655e5a217>
 <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>
 <1449738241.7156.1.camel@ellerman.id.au>
Message-ID: <566945CF.5000807@synopsys.com>

On Thursday 10 December 2015 02:34 PM, Michael Ellerman wrote:

> That is weird. I'll ask it to rebuild it and see if it happens again.
> 
> Do you build with -j?

I did now - but still no error at my end.


>> From looking at logs it looks like some sort of a make / paralle jobs timing issue
>> at build farm.
>>
>> P.S. Could you also update system to also cc lkml and
>> linux-snps-arc at lists.infradead.org for such errors.
> 
> I'll add the arc list, I don't like to cc lkml so as not to annoy people with
> too many error mails.

OK - thx.

-Vineet


From marc.zyngier at arm.com  Thu Dec 10 01:55:26 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 10 Dec 2015 09:55:26 +0000
Subject: percpu irq APIs and perf
In-Reply-To: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
Message-ID: <56694C0E.5050707@arm.com>

Hi Vinnet,

On 10/12/15 09:25, Vineet Gupta wrote:
> Hi Marc / Daniel / Jason,
> 
> I had a couple of questions about percpu irq API, hopefully you can help answer.
> 
> On ARM, how do u handle requesting per cpu IRQs - specifically usage
> of request_percpu_irq() / enable_percpu_irq() API.
> It seems, for using them, we obviously need to explicitly set irq as
> percpu and as a consequence explicitly enable autoen (since former
> disables that). See arch/arc/kernel/irq.c: arc_request_percpu_irq()
> called by ARC per cpu timer setup.

Indeed. The interrupt controller code flags these interrupts as being
per-cpu, and we do rely on each CPU performing an enable_percpu_irq().

So the way the whole thing flows is as such:
- Interrupt controller (GIC) flags the PPIs (Private Peripheral
Interrupt) as per-CPU (hwirq 16 to 31 are replicated per CPU) very early
in the boot process
- request_percpu_irq() only occurs once, usually on the boot CPU (but
that's not a requirement)
- each CPU executes enable_percpu_irq(), which touches per-CPU
registers. This usually involves a CPU notifier to enable/disable the
interrupt when hotplug is on.


>     if (!cpu)  {
>            irq_set_percpu_devid()   <--- disables AUTOEN
>            irq_modify_status(IRQ_NOAUTOEN)  <-- to undo side-effect of above
>            request_percpu_irq
>     }
>     enable_percpu_irq
> 
> I don't see pattern in general for drivers/clocksource/ and/or
> arm_arch_timer.c for PPI case.

You can have a look at arch/arm/smp/smp_twd.c which is probably less
cryptic.

> Further there is an ordering requirement as in request_percpu_irq()
> needs to be called only for the first calling core, and
> enable_percpu_irq() on each one. If enable is done ahead of request
> it obviously fails.

Yup.

> For ARC I've historically used a wrapper arc_request_percpu_irq()
> [pseudo code above] - which has an inherent assumption (now realize
> fragile) that it will be called on core0 first thus guaranteeing the
> ordering above. This is true for timer, IPI etc but not for other
> late probed peripherals - specially perf.
> 
> Infact ARC perf probe open codes on_each_cpu() to ensure irq request
> is done locally first.
> 
> But this all falls apart, when perf probe happens on coreX (not
> core0), causing enable to be called ahead of request anyways. This is
> what I'm running into now.
> 
> I think the solution is to call request_percpu_irq() on whatever core
> hits first and call enable_percpu_irq() from a cpu up notifier. But I
> think the notifier won't run on boot cpu ?  Or is there a better way
> to clean up all this mess.

I think that's pretty much it.

See drivers/perf/arm_pmu.c::cpu_pmu_request_irq() for example.

> FWIW, I see this issue on 3.18 kernel but not latest 4.4-rcX because
> in 3.18 arc perf probe invariably happens on coreX (due to init task
> migration right after clocksource switch - something which doesn't
> happen on 4.4 likely due to recent timer core changes).

Hope this helps,

	M.
-- 
Jazz is not dead. It just smells funny...


From mpe at ellerman.id.au  Thu Dec 10 02:16:31 2015
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Thu, 10 Dec 2015 21:16:31 +1100
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec
 10, 17:33
In-Reply-To: <566945CF.5000807@synopsys.com>
References: <20151210063403.1.54732@94a655e5a217>
 <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>
 <1449738241.7156.1.camel@ellerman.id.au> <566945CF.5000807@synopsys.com>
Message-ID: <1449742591.7156.4.camel@ellerman.id.au>

On Thu, 2015-12-10 at 14:58 +0530, Vineet Gupta wrote:
> On Thursday 10 December 2015 02:34 PM, Michael Ellerman wrote:
> > That is weird. I'll ask it to rebuild it and see if it happens again.
> > 
> > Do you build with -j?
> 
> I did now - but still no error at my end.

OK.

It rebuilt OK the second time:

  http://kisskb.ozlabs.ibm.com/kisskb/buildresult/12564629/

So there might be a gremlin in the Makefiles somewhere.

cheers



From Alexey.Brodkin at synopsys.com  Thu Dec 10 06:16:14 2015
From: Alexey.Brodkin at synopsys.com (Alexey Brodkin)
Date: Thu, 10 Dec 2015 14:16:14 +0000
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec
 10, 17:33
In-Reply-To: <566945CF.5000807@synopsys.com>
References: <20151210063403.1.54732@94a655e5a217>
 <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>
 <1449738241.7156.1.camel@ellerman.id.au> <566945CF.5000807@synopsys.com>
Message-ID: <1449756974.4047.3.camel@synopsys.com>

Hi Michael,

On Thu, 2015-12-10 at 14:58 +0530, Vineet Gupta wrote:
> On Thursday 10 December 2015 02:34 PM, Michael Ellerman wrote:
> 
> > That is weird. I'll ask it to rebuild it and see if it happens again.
> > 
> > Do you build with -j?
> 
> I did now - but still no error at my end.

I always build our kernels with -j4 or even -j8 depending on the machine I use
and I've never seen issues with parallel building.

Latest I tried was 4.4-rc4.

-Alexey

From mpe at ellerman.id.au  Thu Dec 10 19:58:08 2015
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Fri, 11 Dec 2015 14:58:08 +1100
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Thu Dec
 10, 17:33
In-Reply-To: <1449756974.4047.3.camel@synopsys.com>
References: <20151210063403.1.54732@94a655e5a217>
 <C2D7FE5348E1B147BCA15975FBA23075F44D53D7@IN01WEMBXA.internal.synopsys.com>
 <1449738241.7156.1.camel@ellerman.id.au> <566945CF.5000807@synopsys.com>
 <1449756974.4047.3.camel@synopsys.com>
Message-ID: <1449806288.21866.10.camel@ellerman.id.au>

On Thu, 2015-12-10 at 14:16 +0000, Alexey Brodkin wrote:
> Hi Michael,
> On Thu, 2015-12-10 at 14:58 +0530, Vineet Gupta wrote:
> > On Thursday 10 December 2015 02:34 PM, Michael Ellerman wrote:
> > > That is weird. I'll ask it to rebuild it and see if it happens again.
> > > 
> > > Do you build with -j?
> > 
> > I did now - but still no error at my end.
> 
> I always build our kernels with -j4 or even -j8 depending on the machine I use
> and I've never seen issues with parallel building.

I just saw the same failure on another arch, so it doesn't look like its
anything to do with arc.

cheers



From Vineet.Gupta1 at synopsys.com  Thu Dec 10 21:26:02 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 05:26:02 +0000
Subject: percpu irq APIs and perf
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
 <56694C0E.5050707@arm.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>

Hi Marc,

On Thursday 10 December 2015 03:26 PM, Marc Zyngier wrote:
> Hi Vinnet,
>
> On 10/12/15 09:25, Vineet Gupta wrote:
>> Hi Marc / Daniel / Jason,
>>
>> I had a couple of questions about percpu irq API, hopefully you can help answer.
>>
>> On ARM, how do u handle requesting per cpu IRQs - specifically usage
>> of request_percpu_irq() / enable_percpu_irq() API.
>> It seems, for using them, we obviously need to explicitly set irq as
>> percpu and as a consequence explicitly enable autoen (since former
>> disables that). See arch/arc/kernel/irq.c: arc_request_percpu_irq()
>> called by ARC per cpu timer setup.
> Indeed. The interrupt controller code flags these interrupts as being
> per-cpu, and we do rely on each CPU performing an enable_percpu_irq().
>
> So the way the whole thing flows is as such:
> - Interrupt controller (GIC) flags the PPIs (Private Peripheral
> Interrupt) as per-CPU (hwirq 16 to 31 are replicated per CPU) very early
> in the boot process

Thx for your reply and the pointers

irq-gic.c seems to be doing

   irq_set_status_flags(irq, IRQ_NOAUTOEN);

So it is setting NOAUTOEN, which is already the case per side effect of
irq_set_percpu_devid(). No harm in making it explicit.
So this will make __setup_irq() skip irq_startup() and instead rely on
enable_precpu_irq() to be called even for the local core.

I think we can make percpu irq API a bit easier to use.

(1) First thing which request_percpu_irq() does is check for
irq_settings_is_per_cpu_devid(). Thus irq_set_percpu_devid() can be built into the
API itself eliding the need to set it apriori.

(2) It seems that disabling autoen by default for percpu irq makes sense as
evident from drivers/net/ethernet/marvell/mvneta.c where users want to control
this. However the comment there is misleading

    /* Even though the documentation says that request_percpu_irq
     * doesn't enable the interrupts automatically, it actually
     * does so on the local CPU.
     *
     * Make sure it's disabled.
     */

Either sme core code is clearing NOAUTOEN or calling enable_precpu_irq() making
request_percpu_irq() enable it.

IMHO it makes more sense to make autoen explicit in the API.
Perhaps introduce a API flavour, which takes the autoen as arg.
It could take flags to make it more extensible / future safe but that will be an
overkill I think.

Do let me know what you think and I can send RFC patches to same effect.

Thx,
-Vineet


From Vineet.Gupta1 at synopsys.com  Thu Dec 10 23:58:51 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 07:58:51 +0000
Subject: [PATCH v3 04/18] irqchip: add nps Internal and external irqchips
References: <1448974985-11487-1-git-send-email-noamc@ezchip.com>
 <1448974985-11487-5-git-send-email-noamc@ezchip.com>
 <565DA0B6.5080903@arm.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D5A17@IN01WEMBXA.internal.synopsys.com>

On Tuesday 01 December 2015 06:59 PM, Marc Zyngier wrote:
>> +static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
>> > +			  irq_hw_number_t hw)
>> > +{
>> > +	switch (irq) {
>> > +	case TIMER0_IRQ:
>> > +#if defined(CONFIG_SMP)
>> > +	case IPI_IRQ:
>> > +#endif
>> > +		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
>> > +					 handle_percpu_irq);
>> > +	break;
>> > +	default:
>> > +		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
>> > +					 handle_fasteoi_irq);
>> > +	break;
>> > +	}
> No. This is just wrong. Either you get per interrupt information from
> the device tree to configure the interrupt the right way, or you have
> different interrupt controllers for each device.
> 
> But using the Linux irq number is always wrong. You should only consider
> the hwirq.

The source is this incorrectness is ARC core intc code which also does the same
thing and we get away with it because of the legacy domain usage.

I'll fix that up.

Thx,
-Vineet


From Vineet.Gupta1 at synopsys.com  Fri Dec 11 03:19:10 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 16:49:10 +0530
Subject: [PATCH 0/3] ARC perf interrpt fixes
Message-ID: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>

Hi Thomas, Marc, Peter

Fixed a bunch of perf interrupt issues in ARC port.
Apologies for extraneous CC. I think I'm doing the right thing here, and things
start to work after these patches, but still running by domain experts to keep
them in loop :-)

Thx,
-Vineet

Vineet Gupta (3):
  ARCv2: intc: Fix random perf irq disabling in SMP setup
  ARC: intc: No need to clear IRQ_NOAUTOEN
  ARCv2: perf: Ensure perf intr gets enabled on all cores

 arch/arc/kernel/intc-arcv2.c | 15 +++++++++++++--
 arch/arc/kernel/irq.c        | 13 ++++++++-----
 arch/arc/kernel/perf_event.c | 32 +++++++++-----------------------
 3 files changed, 30 insertions(+), 30 deletions(-)

-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Fri Dec 11 03:19:11 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 16:49:11 +0530
Subject: [PATCH 1/3] ARCv2: intc: Fix random perf irq disabling in SMP setup
In-Reply-To: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>
References: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449832753-6767-2-git-send-email-vgupta@synopsys.com>

As part of fixing another perf issue, observed that after a perf run,
the interrupt got disabled on one/more cores.

| [ARCLinux]# cat /proc/interrupts | grep perf
|  20:    0      0      0       0  ARCv2 core Intc  20 ARC perf counters
|
| [ARCLinux]# perf record -c 20000 /sbin/hackbench
| Running with 10*40 (== 400) tasks.
|
| [ARCLinux]# cat /proc/interrupts | grep perf
|  20:    0    522      8    51916  ARCv2 core Intc  20 ARC perf counters
|
| [ARCLinux]# perf record -c 20000 /sbin/hackbench
| Running with 10*40 (== 400) tasks.
|
| [ARCLinux]# cat /proc/interrupts | grep perf
|  20:    0    522      8   104368  ARCv2 core Intc  20 ARC perf counters

Turns out that despite requesting perf irq as percpu, the flow handler
registered was not handle_percpu_irq()

Given that on ARCv2 cores, IRQs < 24 are always private to cpu, we
register the right handler at the very onset.

Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: stable at vger.kernel.org #4.2+
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/intc-arcv2.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
index 26c156827479..0394f9f61b46 100644
--- a/arch/arc/kernel/intc-arcv2.c
+++ b/arch/arc/kernel/intc-arcv2.c
@@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
 static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
 			 irq_hw_number_t hw)
 {
-	if (irq == TIMER0_IRQ || irq == IPI_IRQ)
+	/*
+	 * core intc IRQs [16, 23]:
+	 * Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
+	 */
+	if (hw < 24) {
+		/*
+		 * A subsequent request_percpu_irq() fails if percpu_devid is
+		 * not set. That in turns sets NOAUTOEN, meaning each core needs
+		 * to call enable_percpu_irq()
+		 */
+		irq_set_percpu_devid(irq);
 		irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
-	else
+	} else {
 		irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
+	}
 
 	return 0;
 }
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Fri Dec 11 03:19:12 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 16:49:12 +0530
Subject: [PATCH 2/3] ARC: intc: No need to clear IRQ_NOAUTOEN
In-Reply-To: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>
References: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449832753-6767-3-git-send-email-vgupta@synopsys.com>

arc_request_percpu_irq() is called by all cores to request/enable percpu
irq. It has some "prep" calls needed by genirq:
 - setup percpu devid
 - disable IRQ_NOAUTOEN

However given that enable_percpu_irq() is called enayways, latter can be
avoided.

We are now left with irq_set_percpu_devid() quirk and that too for
ARCompact builds only, since previous patch updated ARCv2 intc to do this
in the "right" place, i.e. irq map function.

By next release, this will ultimately be fixed for ARCompact as well.

Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/irq.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 2ee226546c6a..d736678d2724 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -60,14 +60,17 @@ void arc_request_percpu_irq(int irq, int cpu,
 	if (!cpu) {
 		int rc;
 
+#ifdef CONFIG_ISA_ARCOMPACT
 		/*
-		 * These 2 calls are essential to making percpu IRQ APIs work
-		 * Ideally these details could be hidden in irq chip map function
-		 * but the issue is IPIs IRQs being static (non-DT) and platform
-		 * specific, so we can't identify them there.
+		 * A subsequent request_percpu_irq() fails if percpu_devid is
+		 * not set. That in turns sets NOAUTOEN, meaning each core needs
+		 * to call enable_percpu_irq()
+		 *
+		 * For ARCv2, this is done in irq map function since we know
+		 * which irqs are strictly per cpu
 		 */
 		irq_set_percpu_devid(irq);
-		irq_modify_status(irq, IRQ_NOAUTOEN, 0);  /* @irq, @clr, @set */
+#endif
 
 		rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
 		if (rc)
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Fri Dec 11 03:19:13 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 16:49:13 +0530
Subject: [PATCH 3/3] ARCv2: perf: Ensure perf intr gets enabled on all cores
In-Reply-To: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>
References: <1449832753-6767-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1449832753-6767-4-git-send-email-vgupta@synopsys.com>

This was the second perf intr issue

perf sampling on multicore requires intr to be enabled on all cores.
ARC perf probe code used helper arc_request_percpu_irq() which calls
 - request_percpu_irq() on core0
 - enable_percpu_irq() on all all cores (including core0)

genirq requires that request be made ahead of enable call.
However if perf probe happened on non core0 (observed on a 3.18 kernel),
enable would get called ahead of request, failing obviously and
rendering perf intr disabled on all such cores

[   11.120000] 1 ARC perf       : 8 counters (48 bits), 113 conditions, [overflow IRQ support]
[   11.130000] 1 -----> enable_percpu_irq() IRQ 20 failed
[   11.140000] 3 -----> enable_percpu_irq() IRQ 20 failed
[   11.140000] 2 -----> enable_percpu_irq() IRQ 20 failed
[   11.140000] 0 =====> request_percpu_irq() IRQ 20
[   11.140000] 0 -----> enable_percpu_irq() IRQ 20

Fix this fragility, by calling request_percpu_irq() on whatever core
calls probe (there is no requirement on which core calls this anyways)
and then calling enable on each cores.

Interestingly this started as invesigation of STAR 9000838902:
"sporadically IRQs enabled on perf prob"

which was about occassional boot spew as request_percpu_irq got called
non-locally (from an IPI), and re-enabled interrupts in following path
proc_mkdir ->  spin_unlock_irq()

which the irq work code didn't like.

| ARC perf     : 8 counters (48 bits), 113 conditions, [overflow IRQ support]
|
| BUG: failure at ../kernel/irq_work.c:135/irq_work_run_list()!
| CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.10-01127-g285efb8e66d1 #2
|
| Stack Trace:
|  arc_unwind_core.constprop.1+0x94/0x104
|  dump_stack+0x62/0x98
|  irq_work_run_list+0xb0/0xb4
|  irq_work_run+0x22/0x3c
|  do_IPI+0x74/0x9c
|  handle_irq_event_percpu+0x34/0x164
|  handle_percpu_irq+0x58/0x78
|  generic_handle_irq+0x1e/0x2c
|  arch_do_IRQ+0x3c/0x60
|  ret_from_exception+0x0/0x8

Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-snps-arc at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/perf_event.c | 32 +++++++++-----------------------
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c
index 0c08bb1ce15a..8b134cfe5e1f 100644
--- a/arch/arc/kernel/perf_event.c
+++ b/arch/arc/kernel/perf_event.c
@@ -428,12 +428,11 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
 
 #endif /* CONFIG_ISA_ARCV2 */
 
-void arc_cpu_pmu_irq_init(void)
+static void arc_cpu_pmu_irq_init(void *data)
 {
-	struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu);
+	int irq = *(int *)data;
 
-	arc_request_percpu_irq(arc_pmu->irq, smp_processor_id(), arc_pmu_intr,
-			       "ARC perf counters", pmu_cpu);
+	enable_percpu_irq(irq, IRQ_TYPE_NONE);
 
 	/* Clear all pending interrupt flags */
 	write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
@@ -515,7 +514,6 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
 	if (has_interrupts) {
 		int irq = platform_get_irq(pdev, 0);
-		unsigned long flags;
 
 		if (irq < 0) {
 			pr_err("Cannot get IRQ number for the platform\n");
@@ -524,24 +522,12 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
 		arc_pmu->irq = irq;
 
-		/*
-		 * arc_cpu_pmu_irq_init() needs to be called on all cores for
-		 * their respective local PMU.
-		 * However we use opencoded on_each_cpu() to ensure it is called
-		 * on core0 first, so that arc_request_percpu_irq() sets up
-		 * AUTOEN etc. Otherwise enable_percpu_irq() fails to enable
-		 * perf IRQ on non master cores.
-		 * see arc_request_percpu_irq()
-		 */
-		preempt_disable();
-		local_irq_save(flags);
-		arc_cpu_pmu_irq_init();
-		local_irq_restore(flags);
-		smp_call_function((smp_call_func_t)arc_cpu_pmu_irq_init, 0, 1);
-		preempt_enable();
-
-		/* Clean all pending interrupt flags */
-		write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
+		/* intc map function ensures irq_set_percpu_devid() called */
+		request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters",
+				   this_cpu_ptr(&arc_pmu_cpu));
+
+		on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
+
 	} else
 		arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 
-- 
1.9.1



From marc.zyngier at arm.com  Fri Dec 11 03:23:56 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 11 Dec 2015 11:23:56 +0000
Subject: percpu irq APIs and perf
In-Reply-To: <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
 <56694C0E.5050707@arm.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>
Message-ID: <566AB24C.3040407@arm.com>

On Fri, 11 Dec 2015 05:26:02 +0000
Vineet Gupta <Vineet.Gupta1 at synopsys.com> wrote:

Hi Vineet,

> Hi Marc,
> 
> On Thursday 10 December 2015 03:26 PM, Marc Zyngier wrote:
> > Hi Vinnet,
> >
> > On 10/12/15 09:25, Vineet Gupta wrote:
> >> Hi Marc / Daniel / Jason,
> >>
> >> I had a couple of questions about percpu irq API, hopefully you can help answer.
> >>
> >> On ARM, how do u handle requesting per cpu IRQs - specifically usage
> >> of request_percpu_irq() / enable_percpu_irq() API.
> >> It seems, for using them, we obviously need to explicitly set irq as
> >> percpu and as a consequence explicitly enable autoen (since former
> >> disables that). See arch/arc/kernel/irq.c: arc_request_percpu_irq()
> >> called by ARC per cpu timer setup.
> > Indeed. The interrupt controller code flags these interrupts as being
> > per-cpu, and we do rely on each CPU performing an enable_percpu_irq().
> >
> > So the way the whole thing flows is as such:
> > - Interrupt controller (GIC) flags the PPIs (Private Peripheral
> > Interrupt) as per-CPU (hwirq 16 to 31 are replicated per CPU) very early
> > in the boot process
> 
> Thx for your reply and the pointers
> 
> irq-gic.c seems to be doing
> 
>    irq_set_status_flags(irq, IRQ_NOAUTOEN);
> 
> So it is setting NOAUTOEN, which is already the case per side effect of
> irq_set_percpu_devid(). No harm in making it explicit.

Indeed, this looks completely superfluous. I'll fix that.

> So this will make __setup_irq() skip irq_startup() and instead rely on
> enable_precpu_irq() to be called even for the local core.
> 
> I think we can make percpu irq API a bit easier to use.
> 
> (1) First thing which request_percpu_irq() does is check for
> irq_settings_is_per_cpu_devid(). Thus irq_set_percpu_devid() can be built into the
> API itself eliding the need to set it apriori.

I don't think we can. At least in the case I'm concerned about (GIC's
PPIs), this is a hardware requirement. You cannot turn a global
interrupt into a per-CPU one, nor the other way around. We also have
drivers (at least our PMUs) that do test the state of that interrupt
(per-CPU or not) to find out how they should be requested.

I agree that the API is probably not the ideal one, but there is HW
constraints that we cannot just ignore.

> (2) It seems that disabling autoen by default for percpu irq makes sense as
> evident from drivers/net/ethernet/marvell/mvneta.c where users want to control
> this. However the comment there is misleading
> 
>     /* Even though the documentation says that request_percpu_irq
>      * doesn't enable the interrupts automatically, it actually
>      * does so on the local CPU.
>      *
>      * Make sure it's disabled.
>      */
> 
> Either sme core code is clearing NOAUTOEN or calling enable_precpu_irq() making
> request_percpu_irq() enable it.

If that's the case, this is a bug. Nobody should enable that interrupt
until the driver has chosen to do so.

> IMHO it makes more sense to make autoen explicit in the API.
> Perhaps introduce a API flavour, which takes the autoen as arg.
> It could take flags to make it more extensible / future safe but that will be an
> overkill I think.

But auto-enabling cannot be done from a single CPU. It can only be done
from the core that is going to be delivered that interrupt. This
requires access to registers that are simply not available to other CPUs.

> Do let me know what you think and I can send RFC patches to same effect.

If you can find an elegant way to do this and keep the existing
semantics, I'm all ear!

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From Vineet.Gupta1 at synopsys.com  Fri Dec 11 04:20:22 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 11 Dec 2015 17:50:22 +0530
Subject: percpu irq APIs and perf
In-Reply-To: <566AB24C.3040407@arm.com>
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
 <56694C0E.5050707@arm.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>
 <566AB24C.3040407@arm.com>
Message-ID: <566ABF86.9030308@synopsys.com>

Hi Marc,

On Friday 11 December 2015 04:53 PM, Marc Zyngier wrote:
> On Fri, 11 Dec 2015 05:26:02 +0000
>> I think we can make percpu irq API a bit easier to use.
>>
>> (1) First thing which request_percpu_irq() does is check for
>> irq_settings_is_per_cpu_devid(). Thus irq_set_percpu_devid() can be built into the
>> API itself eliding the need to set it apriori.
> 
> I don't think we can. At least in the case I'm concerned about (GIC's
> PPIs), this is a hardware requirement. You cannot turn a global
> interrupt into a per-CPU one, nor the other way around.

Understood.

> We also have
> drivers (at least our PMUs) that do test the state of that interrupt
> (per-CPU or not) to find out how they should be requested.

But they call request_percpu_irq() only after determining that irq is percpu.
Otherwise they will call vanilla request_irq()
e.g. drivers/perf/arm/arc_pmu.c

Which means that request_percpu_irq() can safely assume that caller absolutely
wants percpu semantics and hence do equivalent of irq_set_percpu_devid()
internally - NO. I'm sure I'm missing something.


> I agree that the API is probably not the ideal one, but there is HW
> constraints that we cannot just ignore.

The API is pretty nice :-) there are these quirks which I want to avoid.
My naive'ity in this area of code fails me to see how the hardware constraint is
coming into play.


>> (2) It seems that disabling autoen by default for percpu irq makes sense as
>> evident from drivers/net/ethernet/marvell/mvneta.c where users want to control
>> this. However the comment there is misleading
>>
>>     /* Even though the documentation says that request_percpu_irq
>>      * doesn't enable the interrupts automatically, it actually
>>      * does so on the local CPU.
>>      *
>>      * Make sure it's disabled.
>>      */
>>
>> Either sme core code is clearing NOAUTOEN or calling enable_precpu_irq() making
>> request_percpu_irq() enable it.
> 
> If that's the case, this is a bug. Nobody should enable that interrupt
> until the driver has chosen to do so.

Perhaps Maxim can shed more light as this seems to be his comment.


>> IMHO it makes more sense to make autoen explicit in the API.
>> Perhaps introduce a API flavour, which takes the autoen as arg.
>> It could take flags to make it more extensible / future safe but that will be an
>> overkill I think.
> 
> But auto-enabling cannot be done from a single CPU. It can only be done
> from the core that is going to be delivered that interrupt. This
> requires access to registers that are simply not available to other CPUs.

I'm not talking about eliminating enable_percpu_irq() call from all cores and
still getting the auto-enable semantics. What I mean is doing the equivalent of

     irq_set_status_flags(irq, IRQ_NOAUTOEN);

from within request_percpu_irq_xxx() based on an additional arg (vs. doing it
aprioiri outside).

OTOH, thinking a bit more abt this, I think the current semantics of auto-disable
w/o any arg is just fine. Most percpu irqs in general purpose drivers would want
the auto-disable anyways. Only for core irws such as timer / IPI etc do we want
auto-enable.

Thx,
-Vineet



From marc.zyngier at arm.com  Fri Dec 11 09:58:28 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 11 Dec 2015 17:58:28 +0000
Subject: percpu irq APIs and perf
In-Reply-To: <566ABF86.9030308@synopsys.com>
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
 <56694C0E.5050707@arm.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>
 <566AB24C.3040407@arm.com> <566ABF86.9030308@synopsys.com>
Message-ID: <566B0EC4.5060000@arm.com>

Vineet,

On 11/12/15 12:20, Vineet Gupta wrote:
> Hi Marc,
> 
> On Friday 11 December 2015 04:53 PM, Marc Zyngier wrote:
>> On Fri, 11 Dec 2015 05:26:02 +0000
>>> I think we can make percpu irq API a bit easier to use.
>>>
>>> (1) First thing which request_percpu_irq() does is check for
>>> irq_settings_is_per_cpu_devid(). Thus irq_set_percpu_devid() can be built into the
>>> API itself eliding the need to set it apriori.
>>
>> I don't think we can. At least in the case I'm concerned about (GIC's
>> PPIs), this is a hardware requirement. You cannot turn a global
>> interrupt into a per-CPU one, nor the other way around.
> 
> Understood.
> 
>> We also have
>> drivers (at least our PMUs) that do test the state of that interrupt
>> (per-CPU or not) to find out how they should be requested.
> 
> But they call request_percpu_irq() only after determining that irq is percpu.
> Otherwise they will call vanilla request_irq()
> e.g. drivers/perf/arm/arc_pmu.c
> 
> Which means that request_percpu_irq() can safely assume that caller absolutely
> wants percpu semantics and hence do equivalent of irq_set_percpu_devid()
> internally - NO. I'm sure I'm missing something.

It actually works the other way around. The caller cannot find out about
the per-cpu property of the interrupt just by looking at the virtual IRQ
number. It needs to ask the core code about it, and that's why the GIC
tags these interrupts as per-cpu.

>> I agree that the API is probably not the ideal one, but there is HW
>> constraints that we cannot just ignore.
> 
> The API is pretty nice :-) there are these quirks which I want to avoid.
> My naive'ity in this area of code fails me to see how the hardware constraint is
> coming into play.
> 
> 
>>> (2) It seems that disabling autoen by default for percpu irq makes sense as
>>> evident from drivers/net/ethernet/marvell/mvneta.c where users want to control
>>> this. However the comment there is misleading
>>>
>>>     /* Even though the documentation says that request_percpu_irq
>>>      * doesn't enable the interrupts automatically, it actually
>>>      * does so on the local CPU.
>>>      *
>>>      * Make sure it's disabled.
>>>      */
>>>
>>> Either sme core code is clearing NOAUTOEN or calling enable_precpu_irq() making
>>> request_percpu_irq() enable it.
>>
>> If that's the case, this is a bug. Nobody should enable that interrupt
>> until the driver has chosen to do so.
> 
> Perhaps Maxim can shed more light as this seems to be his comment.
> 
> 
>>> IMHO it makes more sense to make autoen explicit in the API.
>>> Perhaps introduce a API flavour, which takes the autoen as arg.
>>> It could take flags to make it more extensible / future safe but that will be an
>>> overkill I think.
>>
>> But auto-enabling cannot be done from a single CPU. It can only be done
>> from the core that is going to be delivered that interrupt. This
>> requires access to registers that are simply not available to other CPUs.
> 
> I'm not talking about eliminating enable_percpu_irq() call from all cores and
> still getting the auto-enable semantics. What I mean is doing the equivalent of
> 
>      irq_set_status_flags(irq, IRQ_NOAUTOEN);
> 
> from within request_percpu_irq_xxx() based on an additional arg (vs. doing it
> aprioiri outside).
> 
> OTOH, thinking a bit more abt this, I think the current semantics of auto-disable
> w/o any arg is just fine. Most percpu irqs in general purpose drivers would want
> the auto-disable anyways. Only for core irws such as timer / IPI etc do we want
> auto-enable.

So assuming we can do this (forgetting about any form of HW limitation):
CPU0 request the per-CPU IRQ with an AUTOEN flag. What happens on CPU1?
Are you expecting it to immediately be able to take interrupts? What
handler data gets passed to it?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From Vineet.Gupta1 at synopsys.com  Sun Dec 13 21:50:39 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Mon, 14 Dec 2015 05:50:39 +0000
Subject: percpu irq APIs and perf
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
 <56694C0E.5050707@arm.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>
 <566AB24C.3040407@arm.com> <566ABF86.9030308@synopsys.com>
 <566B0EC4.5060000@arm.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F44D5D39@IN01WEMBXA.internal.synopsys.com>

On Friday 11 December 2015 11:28 PM, Marc Zyngier wrote:
>>> But auto-enabling cannot be done from a single CPU. It can only be done
>>> >> from the core that is going to be delivered that interrupt. This
>>> >> requires access to registers that are simply not available to other CPUs.
>> > 
>> > I'm not talking about eliminating enable_percpu_irq() call from all cores and
>> > still getting the auto-enable semantics. What I mean is doing the equivalent of
>> > 
>> >      irq_set_status_flags(irq, IRQ_NOAUTOEN);
>> > 
>> > from within request_percpu_irq_xxx() based on an additional arg (vs. doing it
>> > aprioiri outside).
>> > 
>> > OTOH, thinking a bit more abt this, I think the current semantics of auto-disable
>> > w/o any arg is just fine. Most percpu irqs in general purpose drivers would want
>> > the auto-disable anyways. Only for core irws such as timer / IPI etc do we want
>> > auto-enable.
> So assuming we can do this (forgetting about any form of HW limitation):
> CPU0 request the per-CPU IRQ with an AUTOEN flag. What happens on CPU1?
> Are you expecting it to immediately be able to take interrupts? What
> handler data gets passed to it?

Right - autoen=true will only help on CPU0. Others will still need to call enable
- for register tinkling etc. A true autoen API should have done that across the
board which it clearly can't and hence is pointless.

Thx,
-Vineet


From maxime.ripard at free-electrons.com  Mon Dec 14 00:43:24 2015
From: maxime.ripard at free-electrons.com (maxime.ripard at free-electrons.com)
Date: Mon, 14 Dec 2015 09:43:24 +0100
Subject: percpu irq APIs and perf
In-Reply-To: <566ABF86.9030308@synopsys.com>
References: <C2D7FE5348E1B147BCA15975FBA23075F44D580B@IN01WEMBXA.internal.synopsys.com>
 <56694C0E.5050707@arm.com>
 <C2D7FE5348E1B147BCA15975FBA23075F44D59B9@IN01WEMBXA.internal.synopsys.com>
 <566AB24C.3040407@arm.com> <566ABF86.9030308@synopsys.com>
Message-ID: <20151214084324.GE19456@lukather>

Hi,

On Fri, Dec 11, 2015 at 05:50:22PM +0530, Vineet Gupta wrote:
> >> (2) It seems that disabling autoen by default for percpu irq makes sense as
> >> evident from drivers/net/ethernet/marvell/mvneta.c where users want to control
> >> this. However the comment there is misleading
> >>
> >>     /* Even though the documentation says that request_percpu_irq
> >>      * doesn't enable the interrupts automatically, it actually
> >>      * does so on the local CPU.
> >>      *
> >>      * Make sure it's disabled.
> >>      */
> >>
> >> Either sme core code is clearing NOAUTOEN or calling enable_precpu_irq() making
> >> request_percpu_irq() enable it.
> > 
> > If that's the case, this is a bug. Nobody should enable that interrupt
> > until the driver has chosen to do so.
> 
> Perhaps Maxim can shed more light as this seems to be his comment.

I don't really have the full context here, but we did this in order to
allow RX queue interrupts to be enabled on a particular CPU.

The IP was supposed to do that by itself, but we hadn't figure that
out at the time. So what we ended up doing is disabling the interrupts
by default and then enable it only on the CPU meant to receive the
queue interrupts.

What we found out doing so was that the per-cpu interrupts were
enabled on the cpu calling request_percpu_irq, and so that's why it
ended up with that comment.

I also fixed the documentation accordingly in a1b7febd725a.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-snps-arc/attachments/20151214/540099ea/attachment.sig>

From noamc at ezchip.com  Tue Dec 15 17:10:19 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:19 +0200
Subject: [PATCH v4 00/19] Adding plat-eznps to ARC
Message-ID: <1450228238-4499-1-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

v4:
1) irqchip -- use irq_domain_add_linear()
2) clocksource -- use of_clk_get()
3) New header at include/soc use by platform and drivers
4) update DTS file for above fixed drivers

v3:
1)	irqchip: use MACROS instead of structures to decribe
	registers.
2)	clocksource: use 32bit counter and avoid 2 halfs read
	of 64bit dance.

v2:
1)	Remove out of tree platform include path
2)	Move atomic/bitop/cmpxchg for platform to end.
	Remove macro duplication.
	Fix some bad implementation.
3)	define cpu_relax_lowlatency() for platform.
4)	rename init_irq_cpu() to init_per_cpu()
	reorder call to init_per_cpu() for secondary
	use it instead of init_cpu_smp().
5)	set res_service to call stext
6)	fix build failure for CTOP_AUX_BASE at assembly code
7)	Use ilog2 for mtm_init_nat()
8)	Add CLKSRC_NPS option to Kconfig
	change nps_clksrc_read() to be more readable.

General summay:
This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threads. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (18):
  Documentation: Add EZchip vendor to binding list
  soc: Support for EZchip SoC
  ARC: [plat-eznps] define IPI_IRQ
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  ARC: Mark secondary cpu online only after all HW setup is done
  ARC: Add clock from device tree to time_init()
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (1):
  ARC: [plat-eznps] Use dedicated cpu_relax()

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   15 ++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |    9 +
 arch/arc/Makefile                                  |    5 +
 arch/arc/boot/dts/eznps.dts                        |   93 +++++++++
 arch/arc/configs/nps_defconfig                     |   85 +++++++++
 arch/arc/include/asm/atomic.h                      |   79 ++++++++-
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   54 ++++++
 arch/arc/include/asm/cmpxchg.h                     |   87 +++++++--
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/irq.h                         |    4 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   36 +++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    4 +-
 arch/arc/include/asm/spinlock.h                    |   14 ++
 arch/arc/kernel/ctx_sw.c                           |   13 ++
 arch/arc/kernel/irq.c                              |    4 +-
 arch/arc/kernel/mcip.c                             |    2 +-
 arch/arc/kernel/smp.c                              |   14 +-
 arch/arc/kernel/time.c                             |   10 +-
 arch/arc/mm/tlb.c                                  |   12 ++
 arch/arc/plat-eznps/Kconfig                        |   34 ++++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   75 ++++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  198 ++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 ++++++
 arch/arc/plat-eznps/include/plat/smp.h             |   26 +++
 arch/arc/plat-eznps/mtm.c                          |  133 +++++++++++++
 arch/arc/plat-eznps/platform.c                     |  102 ++++++++++
 arch/arc/plat-eznps/smp.c                          |  156 +++++++++++++++
 drivers/clocksource/Kconfig                        |    7 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   68 +++++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  131 +++++++++++++
 include/soc/nps/common.h                           |  123 ++++++++++++
 41 files changed, 1678 insertions(+), 37 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c
 create mode 100644 include/soc/nps/common.h



From noamc at ezchip.com  Tue Dec 15 17:10:20 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:20 +0200
Subject: [PATCH v4 01/19] Documentation: Add EZchip vendor to binding list
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-2-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..1aa50c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Processor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d4..d7bff8a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -82,6 +82,7 @@ eukrea  Eukr??a Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 focaltech	FocalTech Systems Co.,Ltd
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:21 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:21 +0200
Subject: [PATCH v4 02/19] soc: Support for EZchip SoC
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-3-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This header file is for NPS400 SoC.
It includes macros for accessing memory mapped registers.
These are functional registers that core can use to configure SoC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 include/soc/nps/common.h |  123 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 123 insertions(+), 0 deletions(-)
 create mode 100644 include/soc/nps/common.h

diff --git a/include/soc/nps/common.h b/include/soc/nps/common.h
new file mode 100644
index 0000000..3bc30a8
--- /dev/null
+++ b/include/soc/nps/common.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef SOC_NPS_COMMON_H
+#define SOC_NPS_COMMON_H
+
+#define NPS_HOST_REG_BASE			0xF6000000
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5B60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+
+#ifndef __ASSEMBLY__
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physically,
+ * and not like the id's physically came with each cluster.
+ * Below table is 4x4 mesh of core clusters as it layout on chip.
+ * Cluster ids are in format: logical (physical)
+ *
+ *    -----------------   ------------------
+ * 3 |  5 (3)   7 (7)  | | 13 (11)   15 (15)|
+ *
+ * 2 |  4 (2)   6 (6)  | | 12 (10)   14 (14)|
+ *    -----------------   ------------------
+ * 1 |  1 (1)   3 (5)  | |  9  (9)   11 (13)|
+ *
+ * 0 |  0 (0)   2 (4)  | |  8  (8)   10 (12)|
+ *    -----------------   ------------------
+ *       0       1            2        3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	 __asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32 base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+#endif /* __ASSEMBLY__ */
+
+#endif /* SOC_NPS_COMMON_H */
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:22 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:22 +0200
Subject: [PATCH v4 03/19] ARC: [plat-eznps] define IPI_IRQ
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-4-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:23 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:23 +0200
Subject: [PATCH v4 04/19] clocksource: Add NPS400 timers driver
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-5-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: John Stultz <john.stultz at linaro.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   15 ++++
 drivers/clocksource/Kconfig                        |    7 ++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   68 ++++++++++++++++++++
 4 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..c8c03d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,15 @@
+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/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 71cfdf7..98b12c5 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,6 +131,13 @@ config CLKSRC_TI_32K
 	  This option enables support for Texas Instruments 32.768 Hz clocksource
 	  available on many OMAP-like platforms.
 
+config CLKSRC_NPS
+	bool "NPS400 clocksource driver" if COMPILE_TEST
+	select CLKSRC_OF if OF
+	help
+	  NPS400 clocksource support.
+	  Got 64 bit counter with update rate up to 1000MHz.
+
 config CLKSRC_STM32
 	bool "Clocksource for STM32 SoCs" if !ARCH_STM32
 	depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 56bd16e..056cffd 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
 obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
+obj-$(CONFIG_CLKSRC_NPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..d0a0603
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <soc/nps/common.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+/* 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 cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
+
+	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(32),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nps_setup_clocksource(struct device_node *node)
+{
+	struct clocksource *clksrc = &nps_counter;
+	struct clk *clk;
+	unsigned long rate;
+	int ret, cluster;
+
+	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);
+
+	clk = of_clk_get(node, 0);
+	BUG_ON(IS_ERR(clk));
+	clk_prepare_enable(clk);
+	rate = clk_get_rate(clk);
+
+	ret = clocksource_register_hz(clksrc, rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
+		       nps_setup_clocksource);
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:24 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:24 +0200
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-6-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 +++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  131 ++++++++++++++++++++
 3 files changed, 149 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 177f78f..b95b954 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..fc6d59a
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+
+/*
+ * NPS400 core includes a Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ *
+ * NOTE: AUX_IENABLE and CTOP_AUX_IACK are auxiliary registers
+ * with private HW copy per CPU.
+ */
+
+static void nps400_irq_mask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << data->hwirq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << data->hwirq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
+
+	/* Don't ack before all device access is done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
+}
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
+			  irq_hw_number_t hw)
+{
+	switch (hw) {
+	case TIMER0_IRQ:
+#if defined(CONFIG_SMP)
+	case IPI_IRQ:
+#endif
+		irq_set_chip_and_handler(virq, &nps400_irq_chip_percpu,
+					 handle_percpu_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(virq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	/* with this we don't need to export nps400_root_domain */
+	irq_set_default_host(nps400_root_domain);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:25 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:25 +0200
Subject: [PATCH v4 06/19] ARC: Set vmalloc size from configuration
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-7-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

This introduce build error since PGDIR_SIZE() cannot use "1UL"
ibecause it is called from mm/tlbex.S by VMALLOC_START.
Using _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/pgtable.h   |    2 +-
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..689ccb3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -468,6 +468,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 1d694c1..8a77ccd 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -109,18 +109,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index daf2bf5..843e1a5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:26 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:26 +0200
Subject: [PATCH v4 07/19] ARC: rwlock: disable interrupts in !LLSC variant
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-8-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

If we hold rwlock and interrupt occures we may
end up spinning on it for ever during softirq.
Note that this lock is an internal lock
and since the lock is free to be used from any context,
the lock needs to be IRQ-safe.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:27 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:27 +0200
Subject: [PATCH v4 08/19] ARC: rename smp operation init_irq_cpu() to
 init_per_cpu()
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-9-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This will better reflect its description i.e. "any needed setup..."
and not just do an "IPI request".

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/smp.h |    4 ++--
 arch/arc/kernel/irq.c      |    4 ++--
 arch/arc/kernel/mcip.c     |    2 +-
 arch/arc/kernel/smp.c      |    4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 133c867..9913804 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  * @init_early_smp:	A SMP specific h/w block can init itself
  * 			Could be common across platforms so not covered by
  * 			mach_desc->init_early()
- * @init_irq_cpu:	Called for each core so SMP h/w block driver can do
+ * @init_per_cpu:	Called for each core so SMP h/w block driver can do
  * 			any needed setup per cpu (e.g. IPI request)
  * @cpu_kick:		For Master to kickstart a cpu (optionally at a PC)
  * @ipi_send:		To send IPI to a @cpu
@@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
 struct plat_smp_ops {
 	const char 	*info;
 	void		(*init_early_smp)(void);
-	void		(*init_irq_cpu)(int cpu);
+	void		(*init_per_cpu)(int cpu);
 	void		(*cpu_kick)(int cpu, unsigned long pc);
 	void		(*ipi_send)(int cpu);
 	void		(*ipi_clear)(int irq);
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 2ee2265..a650650 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -29,8 +29,8 @@ void __init init_IRQ(void)
 
 #ifdef CONFIG_SMP
 	/* a SMP H/w block could do IPI IRQ request here */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(smp_processor_id());
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(smp_processor_id());
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(smp_processor_id());
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 74a9b07..bd237ac 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
 	.info		= smp_cpuinfo_buf,
 	.init_early_smp	= mcip_probe_n_setup,
-	.init_irq_cpu	= mcip_setup_per_cpu,
+	.init_per_cpu	= mcip_setup_per_cpu,
 	.ipi_send	= mcip_ipi_send,
 	.ipi_clear	= mcip_ipi_clear,
 };
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5805878..0b061a4 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -132,8 +132,8 @@ void start_kernel_secondary(void)
 	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
 	/* Some SMP H/w setup - for each cpu */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(cpu);
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(cpu);
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:28 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:28 +0200
Subject: [PATCH v4 09/19] ARC: Mark secondary cpu online only after all HW
 setup is done
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-10-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up().
For ARC it returns as soon as new cpu's status becomes online,
However secondary may still do HW initializing,
machine or platform hook level.

So turn secondary online only after all HW setup is done.
Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/smp.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 0b061a4..bc0e4f6 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,11 +126,6 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
-	notify_cpu_starting(cpu);
-	set_cpu_online(cpu, true);
-
-	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
-
 	/* Some SMP H/w setup - for each cpu */
 	if (plat_smp_ops.init_per_cpu)
 		plat_smp_ops.init_per_cpu(cpu);
@@ -138,6 +133,11 @@ void start_kernel_secondary(void)
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
 
+	notify_cpu_starting(cpu);
+	set_cpu_online(cpu, true);
+
+	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
+
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:29 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:29 +0200
Subject: [PATCH v4 10/19] ARC: Add clock from device tree to time_init()
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-11-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

External clock source can be used if included by one of
DTS file of a chosen platform.
Clocksource may be depend on some clk from DTS as the
real source of this clock.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/time.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..8b9acf3 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -29,6 +29,8 @@
  * which however is currently broken
  */
 
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
@@ -38,7 +40,6 @@
 #include <linux/init.h>
 #include <linux/timex.h>
 #include <linux/profile.h>
-#include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <asm/irq.h>
 #include <asm/arcregs.h>
@@ -283,6 +284,13 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_COMMON_CLK
+	of_clk_init(NULL);
+#endif
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_probe();
+#endif
+
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
 }
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:30 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:30 +0200
Subject: [PATCH v4 11/19] ARC: [plat-eznps] Add eznps board defconfig and dts
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-12-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   93 ++++++++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++
 2 files changed, 178 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..763c880
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,93 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	aliases {
+		ethernet0 = &gmac0;
+		pll = &sysclk;
+	};
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	/* 512M */
+	};
+
+	clocks {
+		sysclk: sysclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <83333333>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+			clocks = <&sysclk>;
+			clock-names="sysclk";
+		};
+
+		uart at f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clocks = <&sysclk>;
+			clock-names="baudclk";
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		gmac0: ethernet at f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			/* Filled in by U-Boot */
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:32 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:32 +0200
Subject: [PATCH v4 13/19] ARC: [plat-eznps] Use dedicated user stack top
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-14-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 8a77ccd..41142ab 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -122,7 +122,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 843e1a5..01f85e5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:31 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:31 +0200
Subject: [PATCH v4 12/19] ARC: [plat-eznps] Add eznps platform
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-13-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   75 ++++++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  198 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   26 ++++
 arch/arc/plat-eznps/mtm.c               |  133 +++++++++++++++++++++
 arch/arc/plat-eznps/platform.c          |  102 ++++++++++++++++
 arch/arc/plat-eznps/smp.c               |  156 ++++++++++++++++++++++++
 10 files changed, 797 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b..abb1897 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4257,6 +4257,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc at ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare at suse.com>
 L:	lm-sensors at lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..051fdca
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_NPS
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..b4dee38
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .init.text, "ax", at progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; For HW thread != 0 there is no work.
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; With no cache coherency mechanism D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; check for boot CPU
+	lr	r3, [CTOP_AUX_GLOBAL_ID]
+	cmp	r3, 0
+	jeq	stext
+
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..5844913
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#include <soc/nps/common.h>
+
+/* core auxiliary registers */
+#ifdef __ASSEMBLY__
+#define CTOP_AUX_BASE				(-0x800)
+#else
+#define CTOP_AUX_BASE				0xFFFFF800
+#endif
+
+#define CTOP_AUX_GLOBAL_ID			(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID			(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID			(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID			(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID		(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID		(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID			(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL			(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY			(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC				(CTOP_AUX_BASE + 0x030)
+#define CTOP_AUX_EFLAGS				(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK				(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1				(CTOP_AUX_BASE + 0x08C)
+#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		0x3E6F7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3E6F7103
+#define CTOP_INST_SCHD_RW			0x3E6F7004
+#define CTOP_INST_SCHD_RD			0x3E6F7084
+#define CTOP_INST_ASRI_0_R3			0x3B56003E
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4A664C00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4A664C01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4A664C02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4A664C04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4A664C05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4A664C06
+#define CTOP_INST_RSPI_GIC_0_R12		0x3C56117E
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED		_BITUL(28)
+
+#define NPS_MSU_BLKID				0x018
+#define NPS_MSU_EN_CFG				0x80
+#define NPS_CRG_BLKID				0x480
+#define NPS_CRG_SYNC_BIT			_BITUL(0)
+#define NPS_GIM_BLKID				0x5C0
+
+/* GIM registers and fields*/
+#define NPS_GIM_UART_LINE			_BITUL(7)
+#define NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE	_BITUL(10)
+#define NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE	_BITUL(11)
+#define NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE	_BITUL(25)
+#define NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE	_BITUL(26)
+
+#ifndef __ASSEMBLY__
+/* Functional registers definition */
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_msu_en_cfg {
+	union {
+		struct {
+			u32     __reserved1:11,
+			rtc_en:1, ipc_en:1, gim_1_en:1,
+			gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
+			buff_e_alc_bmuw:1, buff_i_rls_bmuw:1, buff_i_alc_bmuw:1,
+			buff_e_rls_bmue:1, buff_e_alc_bmue:1, buff_i_rls_bmue:1,
+			buff_i_alc_bmue:1, __reserved2:1, buff_e_pre_en:1,
+			buff_i_pre_en:1, pmuw_ja_en:1, pmue_ja_en:1,
+			pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_gim_p_int_dst {
+	union {
+		struct {
+			u32 int_out_en:1, __reserved1:4,
+			is:1, intm:2, __reserved2:4,
+			nid:4, __reserved3:4, cid:4,
+			 __reserved4:4, tid:4;
+		};
+		u32 value;
+	};
+};
+
+/* AUX registers definition */
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			st_cnt:8, __reserved:8,
+			hs_cnt:8, __reserved1:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+/* CRG registers */
+#define REG_GEN_PURP_0          nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+/* GIM registers */
+#define REG_GIM_P_INT_EN_0      nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
+#define REG_GIM_P_INT_POL_0     nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
+#define REG_GIM_P_INT_SENS_0    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
+#define REG_GIM_P_INT_BLK_0     nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
+#define REG_GIM_P_INT_DST_10    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
+#define REG_GIM_P_INT_DST_11    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
+#define REG_GIM_P_INT_DST_25    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x149)
+#define REG_GIM_P_INT_DST_26    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x14A)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..06b59bd
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern void res_service(void);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..aaaaffd
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	log_nat = ilog2(nat);
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..7ad6d2b
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/mach_desc.h>
+#include <plat/mtm.h>
+
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
+
+	msu_en_cfg.msu_en = 1;
+	msu_en_cfg.ipi_en = 1;
+	msu_en_cfg.gim_0_en = 1;
+	msu_en_cfg.gim_1_en = 1;
+
+	/* enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(msu_en_cfg.value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_value;
+	u32 gim_int_lines;
+	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
+
+	gim_int_lines = NPS_GIM_UART_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE;
+
+	/*
+	 * IRQ polarity
+	 * low or high level
+	 * negative or positive edge
+	 */
+	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
+	reg_value &= ~gim_int_lines;
+	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
+
+	/* IRQ type level or edge */
+	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
+	reg_value |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE;
+	reg_value |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE;
+	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
+
+	/*
+	 * GIM interrupt select type for
+	 * dbg_lan TX and RX interrupts
+	 * should be type 1
+	 * type 0 = IRQ line 6
+	 * type 1 = IRQ line 7
+	 */
+	gim_p_int_dst.is = 1;
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_25);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_26);
+
+	/*
+	 * CTOP IRQ lines should be defined
+	 * as blocking in GIM
+	*/
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
+
+	/* enable CTOP IRQ lines in GIM */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
+}
+
+static void __init eznps_early_init(void)
+{
+	eznps_configure_msu();
+	eznps_configure_gim();
+}
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+	.init_early	= eznps_early_init,
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..4ed400c
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = (u32)res_service;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+static void eznps_init_per_cpu(int cpu)
+{
+	/* Create mapping for all per cpu IRQs */
+	if (cpu == 0) {
+		irq_create_mapping(NULL, TIMER0_IRQ);
+		irq_create_mapping(NULL, IPI_IRQ);
+	}
+
+	smp_ipi_irq_setup(cpu, IPI_IRQ);
+
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+	.init_per_cpu	= eznps_init_per_cpu,
+};
+
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:34 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:34 +0200
Subject: [PATCH v4 15/19] ARC: [plat-eznps] Use dedicated SMP barriers
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-16-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..a559732 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,7 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +42,13 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:33 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:33 +0200
Subject: [PATCH v4 14/19] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-15-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We need our own implementaions since we lack LLSC support.
Our extended ISA provided with optimized solution for all 32bit
operations we see in these three headers.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/atomic.h  |   79 +++++++++++++++++++++++++++++++++++-
 arch/arc/include/asm/bitops.h  |   54 +++++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h |   87 +++++++++++++++++++++++++++++++++-------
 3 files changed, 202 insertions(+), 18 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index 7730d30..a626996 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #define atomic_read(v)  READ_ONCE((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -180,12 +181,84 @@ ATOMIC_OP(andnot, &= ~, bic)
 ATOMIC_OP(or, |=, or)
 ATOMIC_OP(xor, ^=, xor)
 
-#undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
-#undef ATOMIC_OP
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	temp c_op i;							\
+									\
+	return temp;							\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..5a29185 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,7 @@
 #include <asm/smp.h>
 #endif
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +156,53 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#else /* CONFIG_ARC_PLAT_EZNPS */
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	nr = old = (1UL << (nr & 0x1f));				\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	return (old & nr) != 0;					\
+}
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +244,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#else
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..6d320d3 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -66,21 +67,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
 
 #endif /* CONFIG_ARC_HAS_LLSC */
 
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
-				(unsigned long)(o), (unsigned long)(n)))
-
-/*
- * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
- * just to gaurantee semantics.
- * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
- * which also happens to be atomic_ops_lock.
- *
- * Thus despite semantically being different, implementation of atomic_cmpxchg()
- * is same as cmpxchg().
- */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-
-
 /*
  * xchg (reg with memory) based on "Native atomic" EX insn
  */
@@ -143,6 +129,63 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
 
 #endif
 
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	/*
+	 * Explicit full memory barrier needed before/after
+	 */
+	smp_mb();
+
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	smp_mb();
+
+	return new;
+}
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		/*
+		 * Explicit full memory barrier needed before/after
+		 */
+		smp_mb();
+
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		smp_mb();
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 /*
  * "atomic" variant of xchg()
  * REQ: It needs to follow the same serialization rules as other atomic_xxx()
@@ -158,4 +201,18 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+
+/*
+ * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
+ * just to gaurantee semantics.
+ * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
+ * which also happens to be atomic_ops_lock.
+ *
+ * Thus despite semantically being different, implementation of atomic_cmpxchg()
+ * is same as cmpxchg().
+ */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
 #endif
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:35 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:35 +0200
Subject: [PATCH v4 16/19] ARC: [plat-eznps] Use dedicated identity auxiliary
 register.
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-17-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 5d446df..6f4cb0d 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -67,9 +70,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -107,6 +117,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:36 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:36 +0200
Subject: [PATCH v4 17/19] ARC: [plat-eznps] Use dedicated cpu_relax()
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-18-git-send-email-noamc@ezchip.com>

From: Tal Zilcer <talz at ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Implementing cpu_relax_lowlatency() with barrier()
Since with current semantics of cpu_relax() it may take a
while till yielded CPU will get back.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 41142ab..974b878 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,9 +57,18 @@ struct task_struct;
  * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
  * get optimised away by gcc
  */
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
+#else
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#endif
 
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax_lowlatency() cpu_relax()
+#else
+#define cpu_relax_lowlatency() barrier()
+#endif
 
 #define copy_segments(tsk, mm)      do { } while (0)
 #define release_segments(mm)        do { } while (0)
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:37 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:37 +0200
Subject: [PATCH v4 18/19] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-19-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1



From noamc at ezchip.com  Tue Dec 15 17:10:38 2015
From: noamc at ezchip.com (Noam Camus)
Date: Wed, 16 Dec 2015 03:10:38 +0200
Subject: [PATCH v4 19/19] ARC: Add eznps platform to Kconfig and Makefile
In-Reply-To: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
Message-ID: <1450228238-4499-20-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 689ccb3..8153b79 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index cf0cf34..1357e48 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,11 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1



From marc.zyngier at arm.com  Wed Dec 16 01:30:56 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 16 Dec 2015 09:30:56 +0000
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <1450228238-4499-6-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
Message-ID: <56712F50.6050404@arm.com>

On 16/12/15 01:10, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> Adding EZchip NPS400 support.
> NPS internal interrupts are internally handled at
> Multi Thread Manager (MTM) that is signaled for deactivating
> an interrupt.
> External interrupts is handled also at Global Interrupt
> Controller (GIC) e.g. serial and network devices.
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Jason Cooper <jason at lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  .../interrupt-controller/ezchip,nps400-ic.txt      |   17 +++
>  drivers/irqchip/Makefile                           |    1 +
>  drivers/irqchip/irq-eznps.c                        |  131 ++++++++++++++++++++
>  3 files changed, 149 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
>  create mode 100644 drivers/irqchip/irq-eznps.c
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
> new file mode 100644
> index 0000000..888b2b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
> @@ -0,0 +1,17 @@
> +EZchip NPS Interrupt Controller
> +
> +Required properties:
> +
> +- compatible : should be "ezchip,nps400-ic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> +  interrupt source. The value shall be 1.
> +
> +
> +Example:
> +
> +intc: interrupt-controller {
> +	compatible = "ezchip,nps400-ic";
> +	interrupt-controller;
> +	#interrupt-cells = <1>;
> +};
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 177f78f..b95b954 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
>  obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
>  obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
>  obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
> +obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
> diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
> new file mode 100644
> index 0000000..fc6d59a
> --- /dev/null
> +++ b/drivers/irqchip/irq-eznps.c
> @@ -0,0 +1,131 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/irqdomain.h>
> +#include <linux/irqchip.h>
> +#include <asm/irq.h>
> +
> +/*
> + * NPS400 core includes a Interrupt Controller (IC) support.
> + * All cores can deactivate level irqs at first level control
> + * at cores mesh layer called MTM.
> + * For devices out side chip e.g. uart, network there is another
> + * level called Global Interrupt Manager (GIM).
> + * This second level can control level and edge interrupt.
> + *
> + * NOTE: AUX_IENABLE and CTOP_AUX_IACK are auxiliary registers
> + * with private HW copy per CPU.
> + */
> +
> +static void nps400_irq_mask(struct irq_data *data)
> +{
> +	unsigned int ienb;
> +
> +	ienb = read_aux_reg(AUX_IENABLE);
> +	ienb &= ~(1 << data->hwirq);
> +	write_aux_reg(AUX_IENABLE, ienb);
> +}
> +
> +static void nps400_irq_unmask(struct irq_data *data)
> +{
> +	unsigned int ienb;
> +
> +	ienb = read_aux_reg(AUX_IENABLE);
> +	ienb |= (1 << data->hwirq);
> +	write_aux_reg(AUX_IENABLE, ienb);
> +}
> +
> +static void nps400_irq_eoi_global(struct irq_data *data)
> +{
> +	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
> +
> +	/* Don't ack before all device access is done */
> +	mb();
> +
> +	__asm__ __volatile__ (
> +	"       .word %0\n"
> +	:
> +	: "i"(CTOP_INST_RSPI_GIC_0_R12)
> +	: "memory");
> +}
> +
> +static void nps400_irq_eoi(struct irq_data *data)
> +{
> +	write_aux_reg(CTOP_AUX_IACK, 1 << data->hwirq);
> +}
> +
> +static struct irq_chip nps400_irq_chip_fasteoi = {
> +	.name		= "NPS400 IC Global",
> +	.irq_mask	= nps400_irq_mask,
> +	.irq_unmask	= nps400_irq_unmask,
> +	.irq_eoi	= nps400_irq_eoi_global,
> +};
> +
> +static struct irq_chip nps400_irq_chip_percpu = {
> +	.name		= "NPS400 IC",
> +	.irq_mask	= nps400_irq_mask,
> +	.irq_unmask	= nps400_irq_unmask,
> +	.irq_eoi	= nps400_irq_eoi,
> +};
> +
> +static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
> +			  irq_hw_number_t hw)
> +{
> +	switch (hw) {
> +	case TIMER0_IRQ:
> +#if defined(CONFIG_SMP)
> +	case IPI_IRQ:
> +#endif
> +		irq_set_chip_and_handler(virq, &nps400_irq_chip_percpu,
> +					 handle_percpu_irq);
> +	break;
> +	default:
> +		irq_set_chip_and_handler(virq, &nps400_irq_chip_fasteoi,
> +					 handle_fasteoi_irq);
> +	break;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops nps400_irq_ops = {
> +	.xlate = irq_domain_xlate_onecell,
> +	.map = nps400_irq_map,
> +};
> +
> +static struct irq_domain *nps400_root_domain;
> +
> +static int __init nps400_of_init(struct device_node *node,
> +				 struct device_node *parent)
> +{
> +	if (parent)
> +		panic("DeviceTree incore ic not a root irq controller\n");
> +
> +	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
> +						   &nps400_irq_ops, NULL);
> +
> +	if (!nps400_root_domain)
> +		panic("nps400 root irq domain not avail\n");
> +
> +	/* with this we don't need to export nps400_root_domain */
> +	irq_set_default_host(nps400_root_domain);

Why do you need this? Devices should have their interrupt-parent
pointing to this node, and irq_find_host should sort it out. I must be
missing some information (only being CC'd on this single patch).

> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
> 

Another thing I'm not seeing here is where is the interrupt actually
taken. This code only contains the EOI part, but not the ACK side, as
well as the reverse lookup hwirq -> irq). Where is that code?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From Vineet.Gupta1 at synopsys.com  Wed Dec 16 04:23:58 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 16 Dec 2015 17:53:58 +0530
Subject: [PATCH 0/2] ARC dwarf unwinder fixes
Message-ID: <1450268640-23055-1-git-send-email-vgupta@synopsys.com>

Wreckage of removal of slowpath linear search

Vineet Gupta (2):
  ARC: dw2 unwind: Reinstante unwinding out of modules
  ARC: dw2 unwind: Ignore CIE version !=1 gracefully instead of bailing

 arch/arc/include/asm/unwind.h |  4 ----
 arch/arc/kernel/setup.c       |  1 -
 arch/arc/kernel/unwind.c      | 53 ++++++++++++++++++++++++++++---------------
 3 files changed, 35 insertions(+), 23 deletions(-)

-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Wed Dec 16 04:24:00 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 16 Dec 2015 17:54:00 +0530
Subject: [PATCH 2/2] ARC: dw2 unwind: Ignore CIE version !=1 gracefully
 instead of bailing
In-Reply-To: <1450268640-23055-1-git-send-email-vgupta@synopsys.com>
References: <1450268640-23055-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1450268640-23055-3-git-send-email-vgupta@synopsys.com>

ARC dwarf unwinder only supports CIE version == 1
The boot time dwarf sanitizer (part of binary lookup table constructor)
would simply bail if it saw CIE version == 3, rendering unwinder with a
NULL lookup table.

It seems libgcc linked with kernel does have such entries.

With fallback linear search removed, and a NULL binary lookup table,
unwinder fails to generate any stack trace.

So allow graceful ignoring of unsupported CIE entries.

This problem was initially seen in Alexey's setup (and not mine) as he
was using buildroot built toolchain (libgcc) which doesn't get built with
CFLAGS_FOR_TARGET="-gdwarf-2 which is my default

Fixes STAR 9000985048: "kernel unwinder broken with stock tools"

Fixes: 2e22502c080f ARC: dw2 unwind: Remove falllback linear search thru FDE entries
Reported-by Alexey Brodkin <abrodkin at synopsys.com>
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>

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

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 9f9ecc15556e..cf2828ab0905 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -293,13 +293,13 @@ static void init_unwind_hdr(struct unwind_table *table,
 		const u32 *cie = cie_for_fde(fde, table);
 		signed ptrType;
 
-		if (cie == &not_fde)
+		if (cie == &not_fde)	/* only process FDE here */
 			continue;
 		if (cie == NULL || cie == &bad_cie)
-			return;
+			continue;	/* say FDE->CIE.version != 1 */
 		ptrType = fde_pointer_type(cie);
 		if (ptrType < 0)
-			return;
+			continue;
 
 		ptr = (const u8 *)(fde + 2);
 		if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
@@ -343,6 +343,10 @@ static void init_unwind_hdr(struct unwind_table *table,
 
 		if (fde[1] == 0xffffffff)
 			continue;	/* this is a CIE */
+
+		if (*(u8 *)(cie + 2) != 1)
+			continue;	/* FDE->CIE.version not supported */
+
 		ptr = (const u8 *)(fde + 2);
 		header->table[n].start = read_pointer(&ptr,
 						      (const u8 *)(fde + 1) +
@@ -519,7 +523,8 @@ static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
 
 	if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde)
 	    || (*cie & (sizeof(*cie) - 1))
-	    || (cie[1] != 0xffffffff))
+	    || (cie[1] != 0xffffffff)
+	    || ( *(u8 *)(cie + 2) != 1))   /* version 1 supported */
 		return NULL;	/* this is not a (valid) CIE */
 	return cie;
 }
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Wed Dec 16 04:23:59 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 16 Dec 2015 17:53:59 +0530
Subject: [PATCH 1/2] ARC: dw2 unwind: Reinstante unwinding out of modules
In-Reply-To: <1450268640-23055-1-git-send-email-vgupta@synopsys.com>
References: <1450268640-23055-1-git-send-email-vgupta@synopsys.com>
Message-ID: <1450268640-23055-2-git-send-email-vgupta@synopsys.com>

The fix which removed linear searching of dwarf (because binary lookup
data always exists) missed out on the fact that modules don't get the
binary lookup tables info. This caused unwinding out of modules to stop
working.

So add binary lookup header setup (equivalent of eh_frame_hdr setup) to
modules as well.

While at it, confine the header setup to within unwinder code,
reducing one API exposed out of unwinder code.

Fixes: 2e22502c080f ARC: dw2 unwind: Remove falllback linear search thru FDE entries
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/unwind.h |  4 ----
 arch/arc/kernel/setup.c       |  1 -
 arch/arc/kernel/unwind.c      | 40 ++++++++++++++++++++++++++--------------
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/arch/arc/include/asm/unwind.h b/arch/arc/include/asm/unwind.h
index 7ca628b6ee2a..c11a25bb8158 100644
--- a/arch/arc/include/asm/unwind.h
+++ b/arch/arc/include/asm/unwind.h
@@ -112,7 +112,6 @@ struct unwind_frame_info {
 
 extern int arc_unwind(struct unwind_frame_info *frame);
 extern void arc_unwind_init(void);
-extern void arc_unwind_setup(void);
 extern void *unwind_add_table(struct module *module, const void *table_start,
 			      unsigned long table_size);
 extern void unwind_remove_table(void *handle, int init_only);
@@ -152,9 +151,6 @@ static inline void arc_unwind_init(void)
 {
 }
 
-static inline void arc_unwind_setup(void)
-{
-}
 #define unwind_add_table(a, b, c)
 #define unwind_remove_table(a, b)
 
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index c33e77c0ad3e..e1b87444ea9a 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -429,7 +429,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
 	arc_unwind_init();
-	arc_unwind_setup();
 }
 
 static int __init customize_machine(void)
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 7352475451f6..9f9ecc15556e 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -170,6 +170,23 @@ static struct unwind_table *find_table(unsigned long pc)
 
 static unsigned long read_pointer(const u8 **pLoc,
 				  const void *end, signed ptrType);
+static void init_unwind_hdr(struct unwind_table *table,
+			    void *(*alloc) (unsigned long));
+
+/*
+ * wrappers for header alloc (vs. calling one vs. other at call site)
+ * to elide section mismatches warnings
+ */
+static void *__init unw_hdr_alloc_early(unsigned long sz)
+{
+	return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
+				       MAX_DMA_ADDRESS);
+}
+
+static void *unw_hdr_alloc(unsigned long sz)
+{
+	return kmalloc(sz, GFP_KERNEL);
+}
 
 static void init_unwind_table(struct unwind_table *table, const char *name,
 			      const void *core_start, unsigned long core_size,
@@ -209,6 +226,8 @@ void __init arc_unwind_init(void)
 			  __start_unwind, __end_unwind - __start_unwind,
 			  NULL, 0);
 	  /*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
+
+	init_unwind_hdr(&root_table, unw_hdr_alloc_early);
 }
 
 static const u32 bad_cie, not_fde;
@@ -241,8 +260,8 @@ static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
 	e2->fde = v;
 }
 
-static void __init setup_unwind_table(struct unwind_table *table,
-				      void *(*alloc) (unsigned long))
+static void init_unwind_hdr(struct unwind_table *table,
+			    void *(*alloc) (unsigned long))
 {
 	const u8 *ptr;
 	unsigned long tableSize = table->size, hdrSize;
@@ -300,9 +319,11 @@ static void __init setup_unwind_table(struct unwind_table *table,
 
 	hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
 	    + 2 * n * sizeof(unsigned long);
+
 	header = alloc(hdrSize);
 	if (!header)
 		return;
+
 	header->version = 1;
 	header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
 	header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
@@ -342,18 +363,6 @@ static void __init setup_unwind_table(struct unwind_table *table,
 	table->header = (const void *)header;
 }
 
-static void *__init balloc(unsigned long sz)
-{
-	return __alloc_bootmem_nopanic(sz,
-				       sizeof(unsigned int),
-				       __pa(MAX_DMA_ADDRESS));
-}
-
-void __init arc_unwind_setup(void)
-{
-	setup_unwind_table(&root_table, balloc);
-}
-
 #ifdef CONFIG_MODULES
 
 static struct unwind_table *last_table;
@@ -377,6 +386,8 @@ void *unwind_add_table(struct module *module, const void *table_start,
 			  table_start, table_size,
 			  NULL, 0);
 
+	init_unwind_hdr(table, unw_hdr_alloc);
+
 #ifdef UNWIND_DEBUG
 	unw_debug("Table added for [%s] %lx %lx\n",
 		module->name, table->core.pc, table->core.range);
@@ -439,6 +450,7 @@ void unwind_remove_table(void *handle, int init_only)
 	info.init_only = init_only;
 
 	unlink_table(&info); /* XXX: SMP */
+	kfree(table->header);
 	kfree(table);
 }
 
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Wed Dec 16 21:28:55 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Thu, 17 Dec 2015 10:58:55 +0530
Subject: + arc-convert-to-dma_map_ops.patch added to -mm tree
In-Reply-To: <20151124075047.GA29572@lst.de>
References: <564b9e3a.DaXj5xWV8Mzu1fPX%akpm@linux-foundation.org>
 <C2D7FE5348E1B147BCA15975FBA23075F44D2EEF@IN01WEMBXA.internal.synopsys.com>
 <20151124075047.GA29572@lst.de>
Message-ID: <56724817.7090003@synopsys.com>

On Tuesday 24 November 2015 01:20 PM, hch at lst.de wrote:
> Hi Vineet,
> 
> the original version went through the buildbot, which succeeded.  It seems
> like the official buildbot does not support arc, and might benefit from
> helping to set up an arc environment.  However in the meantime Guenther
> send me output from his buildbot and I sent a fix for arc.
> 

Hi Andrew, Christoph

The dma mapping conversion build error fixlet (below) exists as a separate patch
which will break bisectability. Will it be possible to squash it into the orig commit.

Thx,
-Vineet

commit 7f33b4a409493b81c24741dbad6700aae99d8ed0
Author: Christoph Hellwig <hch at lst.de>
Date:   Fri Dec 11 15:59:33 2015 +1100

    arc: dma mapping fixes

    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Reported-by: Guenter Roeck <linux at roeck-us.net>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>





From akpm at linux-foundation.org  Wed Dec 16 21:43:26 2015
From: akpm at linux-foundation.org (Andrew Morton)
Date: Wed, 16 Dec 2015 21:43:26 -0800
Subject: + arc-convert-to-dma_map_ops.patch added to -mm tree
In-Reply-To: <56724817.7090003@synopsys.com>
References: <564b9e3a.DaXj5xWV8Mzu1fPX%akpm@linux-foundation.org>
 <C2D7FE5348E1B147BCA15975FBA23075F44D2EEF@IN01WEMBXA.internal.synopsys.com>
 <20151124075047.GA29572@lst.de> <56724817.7090003@synopsys.com>
Message-ID: <20151216214326.82515ce1.akpm@linux-foundation.org>

On Thu, 17 Dec 2015 10:58:55 +0530 Vineet Gupta <Vineet.Gupta1 at synopsys.com> wrote:

> On Tuesday 24 November 2015 01:20 PM, hch at lst.de wrote:
> > Hi Vineet,
> > 
> > the original version went through the buildbot, which succeeded.  It seems
> > like the official buildbot does not support arc, and might benefit from
> > helping to set up an arc environment.  However in the meantime Guenther
> > send me output from his buildbot and I sent a fix for arc.
> > 
> 
> Hi Andrew, Christoph
> 
> The dma mapping conversion build error fixlet (below) exists as a separate patch
> which will break bisectability. Will it be possible to squash it into the orig commit.
> 

That's the plan.  In http://ozlabs.org/~akpm/mmots/series you'll see

arc-convert-to-dma_map_ops.patch
arc-convert-to-dma_map_ops-fix.patch

I keep the base patch(es) and its fixes separate for various
tacking/history/bookkeeping reasons and fold them all together just
before sending things off to Linus.



From daniel.lezcano at linaro.org  Thu Dec 17 05:12:20 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 17 Dec 2015 14:12:20 +0100
Subject: [PATCH v4 04/19] clocksource: Add NPS400 timers driver
In-Reply-To: <1450228238-4499-5-git-send-email-noamc@ezchip.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-5-git-send-email-noamc@ezchip.com>
Message-ID: <5672B4B4.2010305@linaro.org>

On 12/16/2015 02:10 AM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> Add internal tick generator which is shared by all cores.
> Each cluster of cores view it through dedicated address.
> This is used for SMP system where all CPUs synced by same
> clock source.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: John Stultz <john.stultz at linaro.org>
> Acked-by: Vineet Gupta <vgupta at synopsys.com>

[ ... ]

> +	clk_prepare_enable(clk);
> +	rate = clk_get_rate(clk);

With the return value checked:

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

Thanks !

   -- Daniel


-- 
  <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



From noreply at ellerman.id.au  Fri Dec 18 00:52:00 2015
From: noreply at ellerman.id.au (noreply at ellerman.id.au)
Date: Fri, 18 Dec 2015 08:52:00 -0000
Subject: kisskb: FAILED linux-next/axs103_smp_defconfig/arcv2 Fri Dec 18, 19:50
Message-ID: <20151218085200.1.53295@21ab0802fddb>

FAILED linux-next/axs103_smp_defconfig/arcv2 Fri Dec 18, 19:50

http://kisskb.ellerman.id.au/kisskb/buildresult/12571320/

Commit:   Add linux-next specific files for 20151218
          f7ac28a6971b43a2ee8bb47c0ef931b38f7888cf
Compiler: arc-buildroot-linux-uclibc-gcc (Buildroot 2015.08.1) 4.8.4

Possible errors
---------------

     harderr = icmp_err_convert[code].fatal;
kernel/time/timekeeping.c:1096: undefined reference to `stop_machine'
mm/page_alloc.c:4508: undefined reference to `stop_machine'
make[1]: *** [vmlinux] Error 1
make: *** [sub-make] Error 2

Possible warnings (111)
----------------------

kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sched/core.c:3162:1: warning: control reaches end of non-void function [-Wreturn-type]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:818:21: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:95:8: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:695:17: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized]
ipc/shm.c:1219:2: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:1268:13: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/kernel.h:724:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
include/linux/rbtree.h:83:28: warning: 'rb_parent' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/rbtree.h:86:11: warning: 'rb_link' may be used uninitialized in this function [-Wmaybe-uninitialized]
mm/mmap.c:672:17: warning: 'prev' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/namei.c:1767:10: warning: 'seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/gpio/gpiolib.c:193:20: warning: 'iterator' may be used uninitialized in this function [-Wmaybe-uninitialized]
block/cfq-iosched.c:3775:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/namei.c:3237:10: warning: 'seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
drivers/base/regmap/regmap-mmio.c:113:1: warning: control reaches end of non-void function [-Wreturn-type]
arch/arc/include/asm/elf.h:58:29: warning: integer overflow in expression [-Woverflow]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
lib/cpumask.c:178:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/buffer_head.h:363:2: warning: 'blocknr' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/buffer_head.h:370:2: warning: 'blocknr' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/datagram.c:99:5: warning: 'last' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/datagram.c:99:5: warning: 'last' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/ethtool.c:260:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_extents.h:224:8: warning: '*((void *)&zero_ex+8)' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_extents.h:225:12: warning: '*((void *)&zero_ex+6)' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:3113:2: warning: 'zero_ex.ee_block' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/neighbour.c:3180:10: warning: 'p_name' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/extents.c:2306:14: warning: 'lblock' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:2305:14: warning: 'len' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U3c78>.key[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U3c78>.key[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:26: warning: 'saddr.<U3c78>.a4.vif' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U3c78>.a4.addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.<U3c78>.a4.addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/tcp_metrics.c:1079:7: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U3c78>.key[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U3c78>.key[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/tty/serial/8250/8250_core.c:163:19: warning: 'i' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/usb/storage/transport.c:473:40: warning: 'partial' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/usb/storage/transport.c:499:15: warning: 'partial' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/tcp_input.c:4224:49: warning: array subscript is above array bounds [-Warray-bounds]
net/ipv4/ping.c:559:37: warning: 'code' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:532:3: warning: 'type' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:513:48: warning: 'icmph' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:690:21: warning: 'type' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:476:63: warning: 'code' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/fib_trie.c:909:11: warning: 'local_tp' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/xfrm/xfrm_policy.c:1599:7: warning: 'dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1116:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/packet/af_packet.c:2098:33: warning: 'hdrlen' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1026:20: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1237:8: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/sunrpc/svc_xprt.h:174:1: warning: control reaches end of non-void function [-Wreturn-type]
net/unix/af_unix.c:1694:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcsock.c:779:6: warning: 'optname' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcsock.c:779:6: warning: 'level' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcauth_unix.c:282:12: warning: 'sin6' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1153:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1144:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1153:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1144:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1694:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1207:12: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/xfrm/xfrm_policy.c:1599:7: warning: 'dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]



From noamc at ezchip.com  Fri Dec 18 02:37:03 2015
From: noamc at ezchip.com (Noam Camus)
Date: Fri, 18 Dec 2015 10:37:03 +0000
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <56712F50.6050404@arm.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
 <56712F50.6050404@arm.com>
Message-ID: <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>

From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
Sent: Wednesday, December 16, 2015 11:31 AM

>> +static int __init nps400_of_init(struct device_node *node,
>> +				 struct device_node *parent)
>> +{
>> +	if (parent)
>> +		panic("DeviceTree incore ic not a root irq controller\n");
>> +
>> +	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
>> +						   &nps400_irq_ops, NULL);
>> +
>> +	if (!nps400_root_domain)
>> +		panic("nps400 root irq domain not avail\n");
>> +
>> +	/* with this we don't need to export nps400_root_domain */
>> +	irq_set_default_host(nps400_root_domain);

>Why do you need this? Devices should have their interrupt-parent pointing to this node, and irq_find_host should sort it >out. I must be missing some information (only being CC'd on this single patch).
Sorry, I will CC you by my next version, in the meantime please refer to:
https://lkml.org/lkml/2015/12/15/864

I need this for my per CPU irqs such timer and IPI which do not come from some external device but from CPUs.
For these IRQs I am calling to irq_create_mapping() from my platform at arch/arc and at that point I got no irqdomain and using irq_find_host() is not good since I got no device_node (at most I can have DT root).
Is there device_node for DT root? 
Please advise what to do?

>> +
>> +	return 0;
>> +}
>> +IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", 
>> +nps400_of_init);
>> 

>Another thing I'm not seeing here is where is the interrupt actually taken. This code only contains the EOI part, but not the ACK side, as well as the reverse lookup hwirq -> irq). Where is that code?

ACK is an optional handler and is not needed by my platform.
I will add comment that since my IRQs are EOI based I do not need an ACK.

I do not understand reverse lookup remark, where is it missing?
Could you point me to an example for such reverse lookup? 

Regards,
Noam


From marc.zyngier at arm.com  Fri Dec 18 03:21:17 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 18 Dec 2015 11:21:17 +0000
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
 <56712F50.6050404@arm.com>
 <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
Message-ID: <5673EC2D.5040307@arm.com>

On 18/12/15 10:37, Noam Camus wrote:
> From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
> Sent: Wednesday, December 16, 2015 11:31 AM
> 
>>> +static int __init nps400_of_init(struct device_node *node,
>>> +				 struct device_node *parent)
>>> +{
>>> +	if (parent)
>>> +		panic("DeviceTree incore ic not a root irq controller\n");
>>> +
>>> +	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
>>> +						   &nps400_irq_ops, NULL);
>>> +
>>> +	if (!nps400_root_domain)
>>> +		panic("nps400 root irq domain not avail\n");
>>> +
>>> +	/* with this we don't need to export nps400_root_domain */
>>> +	irq_set_default_host(nps400_root_domain);
> 
>> Why do you need this? Devices should have their interrupt-parent pointing to this node, and irq_find_host should sort it >out. I must be missing some information (only being CC'd on this single patch).
> Sorry, I will CC you by my next version, in the meantime please refer to:
> https://lkml.org/lkml/2015/12/15/864
> 
> I need this for my per CPU irqs such timer and IPI which do not come
> from some external device but from CPUs. For these IRQs I am calling
> to irq_create_mapping() from my platform at arch/arc and at that
> point I got no irqdomain and using irq_find_host() is not good since
> I got no device_node (at most I can have DT root).

That's a problem. You should never do that for your timer (doing a
request_irq will do the right thing, and that's what your timer driver
already does).

As for initializing your IPIs, they are usually outside of the IRQ
space, so you should handle them separately (and get your irqchip to
initialize them).

> Is there device_node for DT root? 
> Please advise what to do?
> 
>>> +
>>> +	return 0;
>>> +}
>>> +IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", 
>>> +nps400_of_init);
>>>
> 
>> Another thing I'm not seeing here is where is the interrupt actually taken. This code only contains the EOI part, but not the ACK side, as well as the reverse lookup hwirq -> irq). Where is that code?
> 
> ACK is an optional handler and is not needed by my platform.
> I will add comment that since my IRQs are EOI based I do not need an ACK.

What I'm talking about is not the irq_ack method that the irqchip can
provide, but the action your perform on your interrupt controller to
extract the hwirq number and find out what corresponding Linux interrupt
has fired.

> 
> I do not understand reverse lookup remark, where is it missing?
> Could you point me to an example for such reverse lookup? 

See for example:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/irqchip/irq-sun4i.c#n136

This is the function (sun4i_handle_irq) that is executed almost
immediately after the IRQ is asserted. The CPU reads the hwirq from the
interrupt controller, and use handle_domain_irq() to call the
corresponding handler (by doing a lookup in the domain).

I couldn't find out in your platform code where you are doing that.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From Vineet.Gupta1 at synopsys.com  Fri Dec 18 04:11:09 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 18 Dec 2015 12:11:09 +0000
Subject: [GIT PULL] ARC fixes for 4.4-rc6
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F4E81E1F@us01wembx1.internal.synopsys.com>

Hi Linus,

We ran into a bunch of show stopper issues for perf and stack unwinding.
Please pull.

----------------->
The following changes since commit 31ade3b83e1821da5fbb2f11b5b3d4ab2ec39db8:

  Linux 4.4-rc3 (2015-11-29 18:58:26 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git/
tags/arc-fixes-for-4.4-rc6

for you to fetch changes up to 575a9d4e2c09675c05db2bc781c5c33153ce932f:

  ARC: smp: Rename platform hook @init_cpu_smp -> @init_per_cpu (2015-12-17
12:56:56 +0530)

----------------------------------------------------------------
ARC Fixes

 - perf interrupts on SMP: Not enabled (at boot) and disabled (at runtime)
 - stack unwinder regression (for modules, ignoring dwarf3)
 - nsim hosed for non default kernel link base builds

----------------------------------------------------------------
Alexey Brodkin (1):
      ARC: [axs10x] cap ethernet phy to 100 Mbit/sec

Noam Camus (1):
      ARC: rename smp operation init_irq_cpu() to init_per_cpu()

Vineet Gupta (8):
      ARCv2: intc: Fix random perf irq disabling in SMP setup
      ARC: intc: No need to clear IRQ_NOAUTOEN
      ARCv2: perf: Ensure perf intr gets enabled on all cores
      ARC: intc: Document arc_request_percpu_irq() better
      ARC: [plat-sim] unbork non default CONFIG_LINUX_LINK_BASE
      ARC: dw2 unwind: Reinstante unwinding out of modules
      ARC: dw2 unwind: Ignore CIE version !=1 gracefully instead of bailing
      ARC: smp: Rename platform hook @init_cpu_smp -> @init_per_cpu

 arch/arc/Kconfig                 |  1 +
 arch/arc/boot/dts/axs10x_mb.dtsi |  1 +
 arch/arc/boot/dts/nsim_hs.dts    |  3 ++-
 arch/arc/include/asm/mach_desc.h |  4 +--
 arch/arc/include/asm/smp.h       |  4 +--
 arch/arc/include/asm/unwind.h    |  4 ---
 arch/arc/kernel/intc-arcv2.c     | 15 ++++++++++--
 arch/arc/kernel/irq.c            | 33 ++++++++++++++++++-------
 arch/arc/kernel/mcip.c           |  2 +-
 arch/arc/kernel/perf_event.c     | 32 +++++++-----------------
 arch/arc/kernel/setup.c          |  1 -
 arch/arc/kernel/smp.c            |  8 +++---
 arch/arc/kernel/unwind.c         | 53 ++++++++++++++++++++++++++--------------
 arch/arc/mm/init.c               |  4 ++-
 14 files changed, 97 insertions(+), 68 deletions(-)


From noamc at ezchip.com  Fri Dec 18 06:29:29 2015
From: noamc at ezchip.com (Noam Camus)
Date: Fri, 18 Dec 2015 14:29:29 +0000
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <5673EC2D.5040307@arm.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
 <56712F50.6050404@arm.com>
 <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <5673EC2D.5040307@arm.com>
Message-ID: <DB5PR02MB1141A1E0BE574A713957650BD6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>

>From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
>Sent: Friday, December 18, 2015 1:21 PM

>> I need this for my per CPU irqs such timer and IPI which do not come 
>> from some external device but from CPUs. For these IRQs I am calling 
>> to irq_create_mapping() from my platform at arch/arc and at that point 
>> I got no irqdomain and using irq_find_host() is not good since I got 
>> no device_node (at most I can have DT root).

>That's a problem. You should never do that for your timer (doing a request_irq will do the right thing, and that's what your timer driver already does).

Please be more specific, from all that I wrote what is the problem?
When I use request_irq() it fail without the mapping and mapping fail without a domain.
Never do what?
What should I do then?

>As for initializing your IPIs, they are usually outside of the IRQ space, so you should handle them separately (and get your irqchip to initialize them).
I am handling all my IRQs within same irqchip, which is the only one I have. So I am not sure what you expect here.
Please be more elaborate.

>> 
>> Another thing I'm not seeing here is where is the interrupt actually taken. This code only contains the EOI part, but not the ACK side, as well as the reverse lookup hwirq -> irq). Where is that code?
>> 
>> ACK is an optional handler and is not needed by my platform.
>> I will add comment that since my IRQs are EOI based I do not need an ACK.

>What I'm talking about is not the irq_ack method that the irqchip can provide, but the action your perform on your interrupt controller to extract the hwirq number and find out what corresponding Linux interrupt has fired.

>> 
>> I do not understand reverse lookup remark, where is it missing?
>> Could you point me to an example for such reverse lookup? 

>See for example:

>https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/irqchip/irq-sun4i.c#n136

>This is the function (sun4i_handle_irq) that is executed almost immediately after the IRQ is asserted. The CPU reads the hwirq from the interrupt controller, and use handle_domain_irq() to call the corresponding handler (by doing a lookup in the domain).

>I couldn't find out in your platform code where you are doing that.

OK, this is seem much like exclusively ARM stuff.
Note that I am working with ARC (seem alike) here and we do not define CONFIG_HANDLE_DOMAIN_IRQ and do not implement set_handle_irq().

So for ARC this reverse mapping is something we can leave without (maybe because we are kind of a legacy domain).

Note that this patch is part of a set I introduce to ARC as a new platform.
You can view my tree and the patch set at:
https://github.com/EZchip/linux/commits/EZ-arc-for-next-basic-reviewd-DO-NOT-COMMENT

-Noam


From marc.zyngier at arm.com  Fri Dec 18 08:31:27 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 18 Dec 2015 16:31:27 +0000
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <DB5PR02MB1141A1E0BE574A713957650BD6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
 <56712F50.6050404@arm.com>
 <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <5673EC2D.5040307@arm.com>
 <DB5PR02MB1141A1E0BE574A713957650BD6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
Message-ID: <567434DF.2030201@arm.com>

On 18/12/15 14:29, Noam Camus wrote:
>> From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
>> Sent: Friday, December 18, 2015 1:21 PM
> 
>>> I need this for my per CPU irqs such timer and IPI which do not come 
>>> from some external device but from CPUs. For these IRQs I am calling 
>>> to irq_create_mapping() from my platform at arch/arc and at that point 
>>> I got no irqdomain and using irq_find_host() is not good since I got 
>>> no device_node (at most I can have DT root).
> 
>> That's a problem. You should never do that for your timer (doing a request_irq will do the right thing, and that's what your timer driver already does).
> 
> Please be more specific, from all that I wrote what is the problem?

Calling irq_create_mapping out of the blue like you do it here:

+static void eznps_init_per_cpu(int cpu)
+{
+	/* Create mapping for all per cpu IRQs */
+	if (cpu == 0) {
+		irq_create_mapping(NULL, TIMER0_IRQ);
+		irq_create_mapping(NULL, IPI_IRQ);
+	}

is simply not acceptable.

> When I use request_irq() it fail without the mapping and mapping fail without a domain.

Grmbl...

That's not completely surprising:

+		timer {
+			compatible = "ezchip,nps400-timer";
+			clocks = <&sysclk>;
+			clock-names="sysclk";
+		};

Where is the interrupt?

> Never do what?
> What should I do then?

Maybe you should start by looking how the other architectures have
solved that exact problem at least half a dozen time.

> 
>> As for initializing your IPIs, they are usually outside of the IRQ
>> space, so you should handle them separately (and get your irqchip
>> to initialize them).
> I am handling all my IRQs within same irqchip, which is the only one 
> I have. So I am not sure what you expect here. Please be more 
> elaborate.

Do not create a mapping for IPIs. Full stop. Handle them independently
from your normal IRQs.

>>>
>>> Another thing I'm not seeing here is where is the interrupt actually taken. This code only contains the EOI part, but not the ACK side, as well as the reverse lookup hwirq -> irq). Where is that code?
>>>
>>> ACK is an optional handler and is not needed by my platform.
>>> I will add comment that since my IRQs are EOI based I do not need an ACK.
> 
>> What I'm talking about is not the irq_ack method that the irqchip can provide, but the action your perform on your interrupt controller to extract the hwirq number and find out what corresponding Linux interrupt has fired.
> 
>>>
>>> I do not understand reverse lookup remark, where is it missing?
>>> Could you point me to an example for such reverse lookup? 
> 
>> See for example:
> 
>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/irqchip/irq-sun4i.c#n136
> 
>> This is the function (sun4i_handle_irq) that is executed almost immediately after the IRQ is asserted. The CPU reads the hwirq from the interrupt controller, and use handle_domain_irq() to call the corresponding handler (by doing a lookup in the domain).
> 
>> I couldn't find out in your platform code where you are doing that.
> 
> OK, this is seem much like exclusively ARM stuff.

No, this is not. Can you please stop looking at the surface of things
and start taking an interest in how things actually *work*? Almost
*nothing* in the interrupt handling code is architecture specific.

> Note that I am working with ARC (seem alike) here and we do not
> define CONFIG_HANDLE_DOMAIN_IRQ and do not implement
> set_handle_irq().
> 
> So for ARC this reverse mapping is something we can leave without
> (maybe because we are kind of a legacy domain).

Yeah, I just located the crap: arch_do_IRQ() happily takes a hwirq (the
vector number), and uses that as a Linux IRQ. This looks a lot like ARM
pre-DT, about 10 years ago.

Well, time to meet the 21st century. If you intend to use DT, please fix
your arch port. Otherwise, just hardcode everything in your platform and
don't pretend to support device tree.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From Alexey.Brodkin at synopsys.com  Fri Dec 18 11:28:51 2015
From: Alexey.Brodkin at synopsys.com (Alexey Brodkin)
Date: Fri, 18 Dec 2015 22:28:51 +0300
Subject: [PATCH] ARC: fix building for MMU v2
Message-ID: <1450466931-13355-1-git-send-email-abrodkin@synopsys.com>

ARC700 cores with MMU v2 don't have IC_PTAG AUX register and so we only
define ARC_REG_IC_PTAG for MMU versions >= 3.

But current implementation of cache_line_loop_vX() routines assumes
availability of all of them (v2, v3 and v4) simultaneously.

And given undefined ARC_REG_IC_PTAG if CONFIG_MMU_VER=2 we're seeing
compilation problem:
---------------------------------->8-------------------------------
  CC      arch/arc/mm/cache.o
arch/arc/mm/cache.c: In function '__cache_line_loop_v3':
arch/arc/mm/cache.c:270:13: error: 'ARC_REG_IC_PTAG' undeclared (first use in this function)
   aux_tag = ARC_REG_IC_PTAG;
             ^
arch/arc/mm/cache.c:270:13: note: each undeclared identifier is reported only once for each function it appears in
scripts/Makefile.build:258: recipe for target 'arch/arc/mm/cache.o' failed
---------------------------------->8-------------------------------

The simples fix is to have ARC_REG_IC_PTAG defined regardless MMU
version being used.

We don't use it in cache_line_loop_v2() anyways so who cares.

Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
Cc: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/cache.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index abf06e8..210ef3e 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -62,9 +62,7 @@ extern int ioc_exists;
 #define ARC_REG_IC_IVIC		0x10
 #define ARC_REG_IC_CTRL		0x11
 #define ARC_REG_IC_IVIL		0x19
-#if defined(CONFIG_ARC_MMU_V3) || defined(CONFIG_ARC_MMU_V4)
 #define ARC_REG_IC_PTAG		0x1E
-#endif
 #define ARC_REG_IC_PTAG_HI	0x1F
 
 /* Bit val in IC_CTRL */
-- 
2.4.3



From noamc at ezchip.com  Sat Dec 19 01:30:26 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sat, 19 Dec 2015 09:30:26 +0000
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <567434DF.2030201@arm.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
 <56712F50.6050404@arm.com>
 <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <5673EC2D.5040307@arm.com>
 <DB5PR02MB1141A1E0BE574A713957650BD6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <567434DF.2030201@arm.com>
Message-ID: <DB5PR02MB11415D584CC523B99476DEB1D6E20@DB5PR02MB1141.eurprd02.prod.outlook.com>

>From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
>Sent: Friday, December 18, 2015 6:31 PM

>> Note that I am working with ARC (seem alike) here and we do not define 
>> CONFIG_HANDLE_DOMAIN_IRQ and do not implement set_handle_irq().
>> 
>> So for ARC this reverse mapping is something we can leave without 
>> (maybe because we are kind of a legacy domain).

>Yeah, I just located the crap: arch_do_IRQ() happily takes a hwirq (the vector number), and uses that as a Linux IRQ. This looks a lot like ARM pre-DT, about 10 years ago.

>Well, time to meet the 21st century. If you intend to use DT, please fix your arch port. Otherwise, just hardcode everything in your platform and don't pretend to support device tree.

Thank you very much. 
I have the complete picture now.

Will discuss with ARC maintainer and see what best way to do this change. 

-Noam


From noreply at ellerman.id.au  Sun Dec 20 12:07:29 2015
From: noreply at ellerman.id.au (noreply at ellerman.id.au)
Date: Sun, 20 Dec 2015 20:07:29 -0000
Subject: kisskb: OK linus/axs101_defconfig/arcompact Mon Dec 21, 07:06
Message-ID: <20151220200729.1.11953@21ab0802fddb>

OK linus/axs101_defconfig/arcompact Mon Dec 21, 07:06

http://kisskb.ellerman.id.au/kisskb/buildresult/12573408/

Commit:   Merge tag 'rtc-4.4-3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
          9f7e43278605a0daf4edf7025c52c25e9ace6875
Compiler: arc-buildroot-linux-uclibc-gcc (Buildroot 2015.08.1) 4.8.4

Possible errors
---------------

      rtc: da9063: fix access ordering error during RTC interrupt at system power on
     harderr = icmp_err_convert[code].fatal;

Possible warnings (110)
----------------------

kernel/sched/core.c:3062:1: warning: control reaches end of non-void function [-Wreturn-type]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1892:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/kernel.h:724:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
ipc/shm.c:1219:2: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/rbtree.h:83:28: warning: 'rb_parent' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/rbtree.h:86:11: warning: 'rb_link' may be used uninitialized in this function [-Wmaybe-uninitialized]
mm/mmap.c:660:17: warning: 'prev' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:818:21: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:95:8: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:695:17: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:1268:13: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/namei.c:1759:10: warning: 'seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
block/cfq-iosched.c:3775:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/namei.c:3161:10: warning: 'seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
arch/arc/include/asm/elf.h:58:29: warning: integer overflow in expression [-Woverflow]
include/asm-generic/bug.h:74:48: warning: 'fn' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/base/regmap/regmap-mmio.c:86:1: warning: control reaches end of non-void function [-Wreturn-type]
include/linux/buffer_head.h:363:2: warning: 'blocknr' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/buffer_head.h:370:2: warning: 'blocknr' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/packet/af_packet.c:2098:33: warning: 'hdrlen' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
net/core/ethtool.c:260:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
net/xfrm/xfrm_policy.c:2876:17: warning: 'xfrm_dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<Uae40>.key[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<Uae40>.key[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:26: warning: 'saddr.<Uae40>.a4.vif' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<Uae40>.a4.addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.<Uae40>.a4.addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/tcp_metrics.c:1079:7: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<Uae40>.key[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<Uae40>.key[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_extents.h:224:8: warning: '*((void *)&zero_ex+8)' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_extents.h:225:12: warning: '*((void *)&zero_ex+6)' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:3113:2: warning: 'zero_ex.ee_block' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
net/unix/af_unix.c:1694:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1026:20: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/xfrm/xfrm_policy.c:1599:7: warning: 'dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1237:8: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1116:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/xfrm/xfrm_policy.c:1599:7: warning: 'dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:2306:14: warning: 'lblock' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:2305:14: warning: 'len' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1694:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/sunrpc/svc_xprt.h:174:1: warning: control reaches end of non-void function [-Wreturn-type]
net/ipv4/ping.c:559:37: warning: 'code' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:532:3: warning: 'type' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:513:48: warning: 'icmph' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:690:21: warning: 'type' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:476:63: warning: 'code' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcsock.c:779:6: warning: 'optname' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcsock.c:779:6: warning: 'level' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/neighbour.c:3180:10: warning: 'p_name' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcauth_unix.c:282:12: warning: 'sin6' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/fib_trie.c:911:11: warning: 'local_tp' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1153:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1144:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1153:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1144:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/tcp_input.c:4224:49: warning: array subscript is above array bounds [-Warray-bounds]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1207:12: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/usb/storage/transport.c:499:15: warning: 'partial' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/usb/storage/transport.c:473:40: warning: 'partial' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/tty/serial/8250/8250_core.c:250:10: warning: 'i' may be used uninitialized in this function [-Wmaybe-uninitialized]



From Vineet.Gupta1 at synopsys.com  Sun Dec 20 23:24:46 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Mon, 21 Dec 2015 12:54:46 +0530
Subject: [PATCH] ARC: Fix linking errors with CONFIG_MODULE +
 CONFIG_CC_OPTIMIZE_FOR_SIZE
Message-ID: <1450682686-837-1-git-send-email-vgupta@synopsys.com>

At -Os, ARC gcc generates millicode thunk for function prologue/epilogue,
which are served by libgcc.

Modules historically are NOT linked with libgcc to avoid code bloat, reducing
runtime relocation fixups etc. I even once tried doign that but got lost
in makefile intricacies.

However CONFIG_MODULE + CONFIG_CC_OPTIMIZE_FOR_SIZE causes link errors

| MODPOST 5 modules
| ERROR: "__ld_r13_to_r18" [crypto/sha256_generic.ko] undefined!
| ERROR: "__ld_r13_to_r18_ret" [crypto/sha256_generic.ko] undefined!
| ERROR: "__st_r13_to_r18" [crypto/sha256_generic.ko] undefined!
| ERROR: "__ld_r13_to_r17_ret" [crypto/sha256_generic.ko] undefined!
| ERROR: "__st_r13_to_r17" [crypto/sha256_generic.ko] undefined!
| ERROR: "__ld_r13_to_r16_ret" [crypto/sha256_generic.ko] undefined!
| ERROR: "__st_r13_to_r16" [crypto/sha256_generic.ko] undefined!
|....
|....

Workaround that by inhibiting millicode thunks for loadable modules

Fixes STAR 9000641864:
("Linux built with optimizations for size emits errors for modules")

Reported-by: Anton Kolesov <akolesov at synosys.com>
Cc: Michal Marek <mmarek at suse.cz>
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index cf0cf34eeb24..aeb19021099e 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -81,7 +81,7 @@ endif
 LIBGCC	:= $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
 
 # Modules with short calls might break for calls into builtin-kernel
-KBUILD_CFLAGS_MODULE	+= -mlong-calls
+KBUILD_CFLAGS_MODULE	+= -mlong-calls -mno-millicode
 
 # Finally dump eveything into kernel build system
 KBUILD_CFLAGS	+= $(cflags-y)
-- 
1.9.1



From Joao.Pinto at synopsys.com  Mon Dec 21 07:44:14 2015
From: Joao.Pinto at synopsys.com (Joao Pinto)
Date: Mon, 21 Dec 2015 15:44:14 +0000
Subject: [PATCH v3 0/2] adding PCI support to AXS10x
Message-ID: <cover.1450694884.git.jpinto@synopsys.com>

This patch set has the goal to add suppport for DesignWare PCIe RC in ARC
AXS10x. It includes the necessary tweaks to the ARC architecture, necessary
tweaks to the PCI subsystem and a new driver (pcie-snpsdev).
This new driver will be used extensively in the PCIe RC Prototyping Kit.

The patches were produced against Bjorn Helgaas' repository. It was properly
tested in an IP Prototyping Kit.

Joao Pinto (2):
  PCI support added to ARC
  add new platform driver for PCI RC

 .../devicetree/bindings/pci/pcie-snpsdev.txt       |  33 +++
 MAINTAINERS                                        |   7 +
 arch/arc/Kconfig                                   |  23 ++
 arch/arc/include/asm/dma.h                         |   5 +
 arch/arc/include/asm/io.h                          |  10 +
 arch/arc/include/asm/pci.h                         |  43 ++++
 arch/arc/kernel/Makefile                           |   1 +
 arch/arc/kernel/pcibios.c                          |  55 ++++
 arch/arc/mm/ioremap.c                              |  10 +-
 arch/arc/plat-axs10x/Kconfig                       |   1 +
 drivers/pci/Makefile                               |   1 +
 drivers/pci/host/Kconfig                           |   5 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pcie-designware.c                 |  11 +
 drivers/pci/host/pcie-designware.h                 |   1 +
 drivers/pci/host/pcie-snpsdev.c                    | 286 +++++++++++++++++++++
 16 files changed, 492 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
 create mode 100644 arch/arc/include/asm/pci.h
 create mode 100644 arch/arc/kernel/pcibios.c
 create mode 100644 drivers/pci/host/pcie-snpsdev.c

-- 
1.8.1.5



From Joao.Pinto at synopsys.com  Mon Dec 21 07:44:15 2015
From: Joao.Pinto at synopsys.com (Joao Pinto)
Date: Mon, 21 Dec 2015 15:44:15 +0000
Subject: [PATCH v3 1/2] PCI support added to ARC
In-Reply-To: <cover.1450694884.git.jpinto@synopsys.com>
References: <cover.1450694884.git.jpinto@synopsys.com>
Message-ID: <8f605456b30bf94a28cececab99d3f5c6d8e4f8b.1450694884.git.jpinto@synopsys.com>

This patch adds PCI support to ARC and updates drivers/pci Makefile enabling
the ARC arch to use the generic PCI setup functions.

Signed-off-by: Joao Pinto <jpinto at synopsys.com>
---
Change v2 -> v3 (Bjorn Helgaas):
- arch/arc/kernel/pcibios.c unused functions were removed and also the
arch/arc/include/asm/mach/pci.h was removed because was no longer necessary

Change v1 -> v2:
- In arch/arc/Kconfig, the new menu entry (Bus Configuration) was moved to the
slot between sourcing of drivers/Kconfig and fs/Kconfig (Vineet Gupta)
- In arch/arc/plat-axs10x/Kconfig the "select MIGHT_HAVE_PCI" option was placed
in order as suggested (Vineet Gupta)
- ioport_map() and ioport_unmap() were static inlined and included in
the io.h (Vineet Gupta)
- pcibios_min_io and pcibios_min_mem declaration moved to
pcibios.c (Vineet Gupta)
- pr_err() replaced by dev_err() in pcibios_enable_device() (Bjorn Helgaas)
- string simplified in pcibios_enable_device() (Vineet Gupta)
- pci_host_bridge_window structure was replaced by resource_entry structure, and
list_for_each_entry() for resource_list_for_each_entry() in pcibios.c

 arch/arc/Kconfig             | 23 ++++++++++++++++++
 arch/arc/include/asm/dma.h   |  5 ++++
 arch/arc/include/asm/io.h    | 10 ++++++++
 arch/arc/include/asm/pci.h   | 43 ++++++++++++++++++++++++++++++++++
 arch/arc/kernel/Makefile     |  1 +
 arch/arc/kernel/pcibios.c    | 55 ++++++++++++++++++++++++++++++++++++++++++++
 arch/arc/mm/ioremap.c        | 10 +++++++-
 arch/arc/plat-axs10x/Kconfig |  1 +
 drivers/pci/Makefile         |  1 +
 9 files changed, 148 insertions(+), 1 deletion(-)
 create mode 100644 arch/arc/include/asm/pci.h
 create mode 100644 arch/arc/kernel/pcibios.c

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..98b32c1 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -19,6 +19,7 @@ config ARC
 	select GENERIC_FIND_FIRST_BIT
 	# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
 	select GENERIC_IRQ_SHOW
+	select GENERIC_PCI_IOMAP
 	select GENERIC_PENDING_IRQ if SMP
 	select GENERIC_SMP_IDLE_THREAD
 	select HAVE_ARCH_KGDB
@@ -39,6 +40,9 @@ config ARC
 	select PERF_USE_VMALLOC
 	select HAVE_DEBUG_STACKOVERFLOW
 
+config MIGHT_HAVE_PCI
+	bool
+
 config TRACE_IRQFLAGS_SUPPORT
 	def_bool y
 
@@ -570,6 +574,25 @@ endmenu	 # "ARC Architecture Configuration"
 source "mm/Kconfig"
 source "net/Kconfig"
 source "drivers/Kconfig"
+
+menu "Bus Support"
+
+config PCI
+	bool "PCI support" if MIGHT_HAVE_PCI
+	help
+	  PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box.Find out if your board/platform have PCI.
+	  Note: PCIE support for Synopsys Device will be available only when
+	  HAPS DX is configured with PCIE RC bitmap. If you have PCI, say Y, otherwise N.
+
+config PCI_SYSCALL
+	def_bool PCI
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+
+endmenu
+
 source "fs/Kconfig"
 source "arch/arc/Kconfig.debug"
 source "security/Kconfig"
diff --git a/arch/arc/include/asm/dma.h b/arch/arc/include/asm/dma.h
index ca7c451..37942fa 100644
--- a/arch/arc/include/asm/dma.h
+++ b/arch/arc/include/asm/dma.h
@@ -10,5 +10,10 @@
 #define ASM_ARC_DMA_H
 
 #define MAX_DMA_ADDRESS 0xC0000000
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
 
 #endif
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 694ece8..2ec3cf4 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -16,7 +16,17 @@
 extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
 extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
 				  unsigned long flags);
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *)port;
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+}
+
 extern void iounmap(const void __iomem *addr);
+extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
 
 #define ioremap_nocache(phy, sz)	ioremap(phy, sz)
 #define ioremap_wc(phy, sz)		ioremap(phy, sz)
diff --git a/arch/arc/include/asm/pci.h b/arch/arc/include/asm/pci.h
new file mode 100644
index 0000000..a0a0fa5
--- /dev/null
+++ b/arch/arc/include/asm/pci.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015-2016 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 _ASM_ARC_PCI_H
+#define _ASM_ARC_PCI_H
+
+#ifdef __KERNEL__
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci-bridge.h>
+
+#include <linux/ioport.h>
+
+extern unsigned long pcibios_min_io;
+#define PCIBIOS_MIN_IO pcibios_min_io
+extern unsigned long pcibios_min_mem;
+#define PCIBIOS_MIN_MEM pcibios_min_mem
+
+#define pcibios_assign_all_busses()	1
+/*
+ * The PCI address space does equal the physical memory address space.
+ * The networking and block device layers use this boolean for bounce
+ * buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS     (1)
+
+/*
+ * Setup early fixed I/O mapping.
+ */
+#if defined(CONFIG_PCI)
+extern void pci_map_io_early(unsigned long pfn);
+#else
+static inline void pci_map_io_early(unsigned long pfn) {}
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_ARC_PCI_H */
+
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index e7f3625..1bc2036 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -12,6 +12,7 @@ obj-y	:= arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
 obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o
 obj-$(CONFIG_ISA_ARCOMPACT)		+= entry-compact.o intc-compact.o
 obj-$(CONFIG_ISA_ARCV2)			+= entry-arcv2.o intc-arcv2.o
+obj-$(CONFIG_PCI)  			+= pcibios.o
 
 obj-$(CONFIG_MODULES)			+= arcksyms.o module.o
 obj-$(CONFIG_SMP) 			+= smp.o
diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c
new file mode 100644
index 0000000..99ee329
--- /dev/null
+++ b/arch/arc/kernel/pcibios.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014-2015 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+
+#include <asm/pci.h>
+
+unsigned long pcibios_min_io = 0x100;
+EXPORT_SYMBOL(pcibios_min_io);
+
+unsigned long pcibios_min_mem = 0x100000;
+EXPORT_SYMBOL(pcibios_min_mem);
+
+/*
+ * We don't have to worry about legacy ISA devices, so nothing to do here
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
+{
+	return res->start;
+}
+
+/*
+ * If the bus contains any of these devices, then we must not turn on
+ * parity checking of any kind.  Currently this is CyberPro 20x0 only.
+ */
+static inline int pdev_bad_for_parity(struct pci_dev *dev)
+{
+	return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
+		 (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+		  dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
+		(dev->vendor == PCI_VENDOR_ID_ITE &&
+		 dev->device == PCI_DEVICE_ID_ITE_8152));
+
+}
+
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c
index 739e65f..fe807b0 100644
--- a/arch/arc/mm/ioremap.c
+++ b/arch/arc/mm/ioremap.c
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/cache.h>
+#include <linux/sizes.h>
 
 void __iomem *ioremap(unsigned long paddr, unsigned long size)
 {
@@ -80,7 +81,6 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size,
 }
 EXPORT_SYMBOL(ioremap_prot);
 
-
 void iounmap(const void __iomem *addr)
 {
 	if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE)
@@ -89,3 +89,11 @@ void iounmap(const void __iomem *addr)
 	vfree((void *)(PAGE_MASK & (unsigned long __force)addr));
 }
 EXPORT_SYMBOL(iounmap);
+
+#ifdef CONFIG_PCI
+int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
+{
+	return ioremap_nocache(phys_addr + offset,  SZ_64K);
+}
+EXPORT_SYMBOL_GPL(pci_ioremap_io);
+#endif
diff --git a/arch/arc/plat-axs10x/Kconfig b/arch/arc/plat-axs10x/Kconfig
index d475f9d..426ac4b 100644
--- a/arch/arc/plat-axs10x/Kconfig
+++ b/arch/arc/plat-axs10x/Kconfig
@@ -11,6 +11,7 @@ menuconfig ARC_PLAT_AXS10X
 	select DW_APB_ICTL
 	select GPIO_DWAPB
 	select OF_GPIO
+	select MIGHT_HAVE_PCI
 	select GENERIC_IRQ_CHIP
 	select ARCH_REQUIRE_GPIOLIB
 	help
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index be3f631..2154092 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
 # Some architectures use the generic PCI setup functions
 #
 obj-$(CONFIG_ALPHA) += setup-irq.o
+obj-$(CONFIG_ARC) += setup-irq.o
 obj-$(CONFIG_ARM) += setup-irq.o
 obj-$(CONFIG_ARM64) += setup-irq.o
 obj-$(CONFIG_UNICORE32) += setup-irq.o
-- 
1.8.1.5



From Joao.Pinto at synopsys.com  Mon Dec 21 07:44:16 2015
From: Joao.Pinto at synopsys.com (Joao Pinto)
Date: Mon, 21 Dec 2015 15:44:16 +0000
Subject: [PATCH v3 2/2] add new platform driver for PCI RC
In-Reply-To: <cover.1450694884.git.jpinto@synopsys.com>
References: <cover.1450694884.git.jpinto@synopsys.com>
Message-ID: <5d0ef02da7c69534420aac36a8a0a375873bae99.1450694884.git.jpinto@synopsys.com>

This patch adds a new driver that will be the reference platform driver for all
PCI RC IP Protoyping Kits based on ARC SDP. This patch is composed by:

-Changes to pcie-designware driver add a function that enables the feature of
starting the LTSSM (Link Train Status State) used by the new driver
-MAINTAINERS file was updated to include the new driver
-Documentation/devicetree/bindings/pci was updated to include the new driver
documentation
-New driver called pcie-snpsdev

Signed-off-by: Joao Pinto <jpinto at synopsys.com>
---
Changes v2 -> v3:
- link init stuff was moved to a snpsdev_pcie_establish_link() function in
pcie-snpsdev (Bjorn Helgaas)
- pcie-snpsdev driver declaration was changed to be more 
standard (Bjorn Helgaas)
- pcie-designware' dw_pcie_link_retrain() now use standard registers from
pci-regs.h (Bjorn Helgaas)
- pcie-snpsdev.txt was complemented with more info (Mark Rutland)

Changes v1 -> v2 (Bjorn Helgaas):
- Fixups snpsdev_pcie_fixup_bridge() and snpsdev_pcie_fixup_res() were removed
from the driver (these functions were for specific tests only and not usefull
in mainline)
- Driver' comments were reviewed (fix Typos and excessive comments removal)
- Removed unnecessary definitions in the driver source (PCIE_PHY_CTRL and
PCIE_PHY_STAT)

 .../devicetree/bindings/pci/pcie-snpsdev.txt       |  33 +++
 MAINTAINERS                                        |   7 +
 drivers/pci/host/Kconfig                           |   5 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pcie-designware.c                 |  11 +
 drivers/pci/host/pcie-designware.h                 |   1 +
 drivers/pci/host/pcie-snpsdev.c                    | 286 +++++++++++++++++++++
 7 files changed, 344 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
 create mode 100644 drivers/pci/host/pcie-snpsdev.c

diff --git a/Documentation/devicetree/bindings/pci/pcie-snpsdev.txt b/Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
new file mode 100644
index 0000000..cae548b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
@@ -0,0 +1,33 @@
+Synopsys PCI RC IP Prototyping Kit
+----------------------------------
+
+This is the reference platform driver to be used in the Synopsys PCI Root
+Complex IP Prototyping Kit.
+
+Required properties:
+- compatible: set to "snps,pcie-snpsdev";
+- reg: base address and length of the pcie controller registers.
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- device_type: set to "pci"
+- ranges: ranges for the PCI memory and I/O regions.
+- interrupts: one interrupt source for MSI interrupts, followed by interrupt
+	source for hardware related interrupts.
+- #interrupt-cells: set to <1>
+- num-lanes: set to <1>;
+
+Example configuration:
+
+	pcie: pcie at 0xdffff000 {
+		compatible = "snps,pcie-snpsdev";
+		reg = <0xdffff000 0x1000>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0xd0000000 0xd0000000 0 0x00002000>,
+			 <0x81000000 0 0x00000000 0xde000000 0 0x00010000>,
+			 <0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
+		interrupts = <25>, <24>;
+		#interrupt-cells = <1>;
+		num-lanes = <1>;
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index e9caa4b..d2e4506 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8230,6 +8230,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 F:	drivers/pci/host/pcie-hisi.c
 
+PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE
+M:	Joao Pinto <jpinto at synopsys.com>
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/pcie-snpsdev.txt
+F:	drivers/pci/host/pcie-snpsdev.c
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia at lists.infradead.org
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index f131ba9..a874b1e 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -172,4 +172,9 @@ config PCI_HISI
 	help
 	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
 
+config PCIE_SNPSDEV
+	bool "Platform Driver for Synopsys Device"
+	select PCIEPORTBUS
+	select PCIE_DW
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6..e422f65 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
 obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
 obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
+obj-$(CONFIG_PCIE_SNPSDEV) += pcie-snpsdev.o
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 540f077..99fad62 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -22,6 +22,8 @@
 #include <linux/pci_regs.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/sizes.h>
 
 #include "pcie-designware.h"
 
@@ -706,6 +708,15 @@ static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
+void dw_pcie_link_retrain(struct pcie_port *pp)
+{
+	u32 val = 0;
+
+	dw_pcie_readl_rc(pp, PCI_EXP_LNKCTL+0x70, &val);
+	val = val | PCI_EXP_LNKCTL_RL;
+	dw_pcie_writel_rc(pp, val, PCI_EXP_LNKCTL+0x70);
+}
+
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index 2356d29..249b631 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -79,5 +79,6 @@ void dw_pcie_msi_init(struct pcie_port *pp);
 int dw_pcie_link_up(struct pcie_port *pp);
 void dw_pcie_setup_rc(struct pcie_port *pp);
 int dw_pcie_host_init(struct pcie_port *pp);
+void dw_pcie_link_retrain(struct pcie_port *pp);
 
 #endif /* _PCIE_DESIGNWARE_H */
diff --git a/drivers/pci/host/pcie-snpsdev.c b/drivers/pci/host/pcie-snpsdev.c
new file mode 100644
index 0000000..4ca7ec5
--- /dev/null
+++ b/drivers/pci/host/pcie-snpsdev.c
@@ -0,0 +1,286 @@
+/*
+ * PCIe RC driver for Synopsys Designware Core
+ *
+ * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
+ *
+ * Authors: Manjunath Bettegowda <manjumb at synopsys.com>,
+ *	    Jie Deng <jiedeng at synopsys.com>
+ *	    Joao Pinto <jpinto at 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/signal.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+
+#define to_snpsdev_pcie(x)	container_of(x, struct snpsdev_pcie, pp)
+
+struct snpsdev_pcie {
+	void __iomem		*mem_base; /* Memory Base to access Core's [RC]
+					    * Config Space Layout
+					    */
+	struct pcie_port	pp;        /* RC Root Port specific structure -
+					    * DWC_PCIE_RC stuff
+					    */
+};
+
+#define PCI_EQUAL_CONTROL_PHY 0x00000707
+
+/* PCIe Port Logic registers (memory-mapped) */
+#define PLR_OFFSET 0x700
+#define PCIE_PHY_DEBUG_R0 (PLR_OFFSET + 0x28) /* 0x728 */
+#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c) /* 0x72c */
+
+/* This handler was created for future work */
+static irqreturn_t snpsdev_pcie_irq_handler(int irq, void *arg)
+{
+	return IRQ_NONE;
+}
+
+static irqreturn_t snpsdev_pcie_msi_irq_handler(int irq, void *arg)
+{
+	struct pcie_port *pp = arg;
+
+	dw_handle_msi_irq(pp);
+
+	return IRQ_HANDLED;
+}
+
+static void snpsdev_pcie_init_phy(struct pcie_port *pp)
+{
+	/* write Lane 0 Equalization Control fields register */
+	writel(PCI_EQUAL_CONTROL_PHY, pp->dbi_base + 0x154);
+}
+
+static int snpsdev_pcie_deassert_core_reset(struct pcie_port *pp)
+{
+	return 0;
+}
+
+static void snpsdev_pcie_establish_link(struct pcie_port *pp)
+{
+	int count = 0;
+
+	/* Initialize Phy (Reset/poweron/control-inputs ) */
+	snpsdev_pcie_init_phy(pp);
+
+	/* de-assert core reset */
+	snpsdev_pcie_deassert_core_reset(pp);
+
+	/* We expect the PCIe Link to be up by this time */
+	dw_pcie_setup_rc(pp);
+
+	/* Start LTSSM here */
+	dw_pcie_link_retrain(pp);
+
+	while (!dw_pcie_link_up(pp)) {
+		usleep_range(1000, 1100);
+		count++;
+		if (count == 20) {
+			dev_err(pp->dev, "phy link never came up\n");
+			dev_dbg(pp->dev,
+				"PL_DEBUG0: 0x%08x, DEBUG_R1: 0x%08x\n",
+				readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
+				readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
+			break;
+		}
+	}
+}
+
+/*
+ * snpsdev_pcie_host_init()
+ * Platform specific host/RC initialization
+ *	a. Assert the core reset
+ *	b. Assert and deassert phy reset and initialize the phy
+ *	c. De-Assert the core reset
+ *	d. Initializet the Root Port (BARs/Memory Or IO/ Interrupt/ Commnad Reg)
+ *	e. Initiate Link startup procedure
+ *
+ */
+static void snpsdev_pcie_host_init(struct pcie_port *pp)
+{
+	/* Establish link */
+	snpsdev_pcie_establish_link(pp);
+
+	if (IS_ENABLED(CONFIG_PCI_MSI))
+		dw_pcie_msi_init(pp);
+}
+
+static int snpsdev_pcie_link_up(struct pcie_port *pp)
+{
+	u32 status;
+
+	/* Bit number 36: reports LTSSM PHY Link UP; Available in bit 3 of
+	 * PCIE_PHY_DEBUG_R1
+	 */
+	status = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & (0x1 << 4);
+	if (status != 0)
+		return 1;
+
+	/* TODO:Now Link is in L0;Initiate GEN2/GEN3 migration if RC Supports*/
+	return 0;
+}
+
+/**
+ * This is RC operation structure
+ * snpsdev_pcie_link_up: the function which initiates the phy link up procedure
+ * snpsdev_pcie_host_init: the function which does the host/RC Root port
+ * initialization.
+ */
+static struct pcie_host_ops snpsdev_pcie_host_ops = {
+	.link_up = snpsdev_pcie_link_up,
+	.host_init = snpsdev_pcie_host_init,
+};
+
+/**
+ * snpsdev_add_pcie_port
+ * This function
+ * a. installs the interrupt handler
+ * b. registers host operations in the pcie_port structure
+ */
+static int snpsdev_add_pcie_port(struct pcie_port *pp,
+				 struct platform_device *pdev)
+{
+	int ret;
+
+	pp->irq = platform_get_irq(pdev, 1);
+
+	if (pp->irq < 0) {
+		if (pp->irq != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "cannot get irq\n");
+		return pp->irq;
+	}
+
+	ret = devm_request_irq(&pdev->dev, pp->irq, snpsdev_pcie_irq_handler,
+				IRQF_SHARED, "snpsdev-pcie", pp);
+
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		return ret;
+	}
+
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		pp->msi_irq = platform_get_irq(pdev, 0);
+
+		if (pp->msi_irq < 0) {
+			if (pp->msi_irq != -EPROBE_DEFER)
+				dev_err(&pdev->dev, "cannot get msi irq\n");
+			return pp->msi_irq;
+		}
+
+		ret = devm_request_irq(&pdev->dev, pp->msi_irq,
+					snpsdev_pcie_msi_irq_handler,
+					IRQF_SHARED, "snpsdev-pcie-msi", pp);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to request msi irq\n");
+			return ret;
+		}
+	}
+
+	pp->root_bus_nr = -1;
+	pp->ops = &snpsdev_pcie_host_ops;
+
+	/* Below function:
+	 * Checks for range property from DT
+	 * Gets the IO and MEMORY and CONFIG-Space ranges from DT
+	 * Does IOREMAPS on the physical addresses
+	 * Gets the num-lanes from DT
+	 * Gets MSI capability from DT
+	 * Calls the platform specific host initialization
+	 * Program the correct class, BAR0, Link width, in Config space
+	 * Then it calls pci common init routine
+	 * Then it calls function to assign "unassigned resources"
+	 */
+	ret = dw_pcie_host_init(pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize host\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * snpsdev_pcie_rc_probe()
+ * This function gets called as part of pcie registration. if the id matches
+ * the platform driver framework will call this function.
+ *
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Returns zero on success; Negative errorno on failure
+ */
+static int snpsdev_pcie_rc_probe(struct platform_device *pdev)
+{
+	struct snpsdev_pcie *snpsdev_pcie;
+	struct pcie_port *pp;
+	struct resource *dwc_pcie_rc_res;  /* Resource from DT */
+	int ret;
+
+	snpsdev_pcie = devm_kzalloc(&pdev->dev, sizeof(*snpsdev_pcie),
+					GFP_KERNEL);
+	if (!snpsdev_pcie)
+		return -ENOMEM;
+
+	pp = &snpsdev_pcie->pp;
+	pp->dev = &pdev->dev;
+
+	dwc_pcie_rc_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!dwc_pcie_rc_res)
+		return -ENODEV;
+
+	snpsdev_pcie->mem_base = devm_ioremap_resource(&pdev->dev,
+							dwc_pcie_rc_res);
+	if (IS_ERR(snpsdev_pcie->mem_base)) {
+		ret = PTR_ERR(snpsdev_pcie->mem_base);
+		return ret;
+	}
+	pp->dbi_base = snpsdev_pcie->mem_base;
+
+	ret = snpsdev_add_pcie_port(pp, pdev);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, snpsdev_pcie);
+
+	return 0;
+}
+
+static int snpsdev_pcie_rc_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id snpsdev_pcie_rc_of_match[] = {
+	{ .compatible = "snps,pcie-snpsdev", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, snpsdev_pcie_rc_of_match);
+
+static struct platform_driver snpsdev_pcie_rc_driver = {
+	.driver = {
+		.name	= "pcie-snpsdev",
+		.of_match_table = snpsdev_pcie_rc_of_match,
+	},
+	.probe = snpsdev_pcie_rc_probe,
+};
+
+module_platform_driver(snpsdev_pcie_rc_driver);
+
+MODULE_AUTHOR("Manjunath Bettegowda <manjumb at synopsys.com>");
+MODULE_DESCRIPTION("Platform Driver for Synopsys Device");
+MODULE_LICENSE("GPL v2");
-- 
1.8.1.5



From CARLOS.PALMINHA at synopsys.com  Mon Dec 21 10:30:09 2015
From: CARLOS.PALMINHA at synopsys.com (Carlos Palminha)
Date: Mon, 21 Dec 2015 18:30:09 +0000
Subject: ARC AXS101 problems with linux next-20151221
Message-ID: <56784531.1000007@synopsys.com>

Hi guys,

I just compiled the kernel for axs101_defconfig based on linux next tag 'next-20151221'.
I can't boot it due to the following errors causing strange stack traces after freeing unused kernel memory (check log below).

Any clue?
Do you more info to understand the issue?

Regards,
C.Palminha


Welcome to the ARC Software Development Platform
axs101 login: mmc0: card b368 removed
mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 400000Hz, actual 396825HZ div = 63)
mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 25000000Hz, actual 25000000HZ div = 1)
mmc0: new SD card at address b368
blk_queue_max_segment_size: set to minimum 8192
mmcblk0: mmc0:b368 SDC   1.83 GiB
 mmcblk0: p1


U-Boot 2015.10 (Nov 17 2015 - 19:28:48 +0100)

I2C:   ready
DRAM:  512 MiB
NAND:  512 MiB
MMC:   Synopsys Mobile storage: 0
In:    serial0 at e0022000
Out:   serial0 at e0022000
Err:   serial0 at e0022000
Net:   eth0: ethernet at e0018000
Hit any key to stop autoboot:  0
reading uImage
7285668 bytes read in 624 ms (11.1 MiB/s)
## Booting kernel from Legacy Image at 82000000 ...
   Image Name:   Linux-4.4.0-rc5-next-20151221
   Image Type:   ARC Linux Kernel Image (uncompressed)
   Data Size:    7285604 Bytes = 6.9 MiB
   Load Address: 80000000
   Entry Point:  800cc000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

Linux version 4.4.0-rc5-next-20151221 (palminha at palminha-vm) (gcc version 4.8.4 (Buildroot 2015.08.1) ) #2 PREEMPT Mon Dec 21 18:22:27 WET 2015
Memory @ 80000000 [512M]
Machine model: snps,axs101
earlycon: Early serial console at MMIO32 0xe0022000 (options '115200n8')
bootconsole [uart0] enabled
AXS: MainBoard v3 FPGA Date: 25-6-2015

IDENTITY        : ARCVER [0x34] ARCNUM [0x4] CHIPID [ 0x0]
processor [0]   : ARC 700 R4.10 (ARCompact ISA)
CPU speed       : 750.00 Mhz
Timers          : Timer0 Timer1
ISA Extn        : atomic
                : mpy norm barrel-shift swap minmax swape
BPU             : partial match, cache:512, Predict Table:512
MMU [v3]        : 8k PAGE, JTLB 512 (128x4), uDTLB 8, uITLB 4
I-Cache         : 32K, 2way/set, 32B Line, VIPT aliasing
D-Cache         : 32K, 4way/set, 32B Line, VIPT
Vector Table    : 0x80000000
Uncached Base   : 0xc0000000
FPU             : SP DP
DEBUG           : ActionPoint smaRT
OS ABI [v3]     : no-legacy-syscalls
CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65248
Kernel command line: earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0
PID hash table entries: 2048 (order: 0, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 5, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 4, 131072 bytes)
Memory: 514288K/524288K available (4521K kernel code, 132K rwdata, 816K rodata, 928K init, 266K bss, 10000K reserved, 0K cma-reserved)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Preemptible hierarchical RCU implementation.
        Build-time adjustment of leaf fanout to 32.
NR_IRQS:128
clocksource: ARC Timer1: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 2548347262 ns
Console: colour dummy device 80x25
console [tty0] enabled
Calibrating delay loop... 743.83 BogoMIPS (lpj=3719168)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 2048 (order: 0, 8192 bytes)
Mountpoint-cache hash table entries: 2048 (order: 0, 8192 bytes)
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
NET: Registered protocol family 16
irq: no irq domain found for /cpu_card/dw-apb-gpio at 0x2000/gpio-controller at 0 !
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
i2c_designware e001e000.i2c: Unknown Synopsys component type: 0x00000030
pps_core: LinuxPPS API ver. 1 registered
pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti at linux.it>
PTP clock support registered
clocksource: Switched to clocksource ARC Timer1
NET: Registered protocol family 2
TCP established hash table entries: 4096 (order: 1, 16384 bytes)
TCP bind hash table entries: 4096 (order: 1, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
UDP hash table entries: 512 (order: 0, 8192 bytes)
UDP-Lite hash table entries: 512 (order: 0, 8192 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
ARC perf        : 8 counters (48 bits), 199 conditions
futex hash table entries: 256 (order: -2, 3072 bytes)
ntfs: driver 2.1.32 [Flags: R/O].
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
f0005000.dw-apb-uart: ttyS0 at MMIO 0xf0005000 (irq = 60, base_baud = 2083312) is a 16550A
e0020000.uart: ttyS1 at MMIO 0xe0020000 (irq = 35, base_baud = 2083333) is a 16550A
e0021000.uart: ttyS2 at MMIO 0xe0021000 (irq = 36, base_baud = 2083333) is a 16550A
console [ttyS3] disabled
e0022000.uart: ttyS3 at MMIO 0xe0022000 (irq = 37, base_baud = 2083333) is a 16550A
console [ttyS3] enabled
console [ttyS3] enabled
bootconsole [uart0] disabled
bootconsole [uart0] disabled
stmmaceth e0018000.ethernet: no reset control found
stmmac - user ID: 0x10, Synopsys ID: 0x37
 Ring mode enabled
 DMA HW capability register supported
 Normal descriptors
 RX Checksum Offload Engine supported (type 2)
 TX Checksum insertion supported
 Enable RX Mitigation via HW Watchdog Timer
stmmaceth e0018000.ethernet eth0: NO MDIO subnode
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-platform: EHCI generic platform driver
ehci-platform e0040000.ehci: EHCI Host Controller
ehci-platform e0040000.ehci: new USB bus registered, assigned bus number 1
ehci-platform e0040000.ehci: irq 33, io mem 0xe0040000
ehci-platform e0040000.ehci: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-platform: OHCI generic platform driver
ohci-platform e0060000.ohci: Generic Platform OHCI controller
ohci-platform e0060000.ohci: new USB bus registered, assigned bus number 2
ohci-platform e0060000.ohci: irq 33, io mem 0xe0060000
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
usbcore: registered new interface driver usb-storage
mousedev: PS/2 mouse device common for all mice
usbcore: registered new interface driver synaptics_usb
i2c /dev entries driver
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
Synopsys Designware Multimedia Card Interface Driver
dw_mmc e0015000.mmc: IDMAC supports 32-bit address mode.
dw_mmc e0015000.mmc: Using internal DMA controller.
dw_mmc e0015000.mmc: Version ID is 270a
dw_mmc e0015000.mmc: DW MMC controller at irq 34,32 bit host data width,16 deep fifo
dw_mmc e0015000.mmc: 1 slots initialized
sdhci-pltfm: SDHCI platform and OF driver helper
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
NET: Registered protocol family 17
NET: Registered protocol family 15
ttyS3 - failed to request DMA
Freeing unused kernel memory: 928K (80002000 - 800ea000)
INFO: rcu_preempt self-detected stall on CPU
        0-...: (2100 ticks this GP) idle=011/140000000000001/0 softirq=92/92 fqs=0
         (t=2100 jiffies g=-261 c=-262 q=60)
rcu_preempt kthread starved for 2100 jiffies! g4294967035 c4294967034 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
rcu_preempt     S 8053879e     0     7      2 0x00000000

Stack Trace:
  __switch_to+0x0/0x94
  __schedule+0x1c2/0x724
  schedule+0x2a/0x74
  schedule_timeout+0x126/0x198
  rcu_gp_kthread+0x5fa/0xee8
  kthread+0xe2/0xf4
  ret_from_fork+0x18/0x1c
Task dump for CPU 0:
kworker/0:1     R running      0    19      2 0x00000008
Workqueue: events_freezable mmc_rescan

Stack Trace:
  __switch_to+0x0/0x94
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:1:19]
Modules linked in:
Path: (null)
CPU: 0 PID: 19 Comm: kworker/0:1 Not tainted 4.4.0-rc5-next-20151221 #2
Workqueue: events_freezable mmc_rescan
task: 9f0ce000 ti: 9f0d0000 task.ti: 9f0d0000

[ECR   ]: 0x0031abcd => Check Programmer's Manual
[EFA   ]: 0x00000000
[BLINK ]: arc_dma_map_sg+0x50/0xe4
[ERET  ]: arc_dma_map_page+0x5e/0x98
[STAT32]: 0x00000006 : K         E2 E1
BTA: 0x800f57c8  SP: 0x9f0d1d00  FP: 0x00000000
LPS: 0x80323e80 LPE: 0x80323e84 LPC: 0x00000000
r00: 0x9f04310c r01: 0x9ffeeda4 r02: 0x00001a40
r03: 0x00000040 r04: 0x00000002 r05: 0x9fdc0000
r06: 0x800f5794 r07: 0x00000000 r08: 0x23b345fc
r09: 0x00000000 r10: 0x00000007 r11: 0x00000000
r12: 0x00000000
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:1:19]
Modules linked in:
Path: (null)
CPU: 0 PID: 19 Comm: kworker/0:1 Tainted: G             L  4.4.0-rc5-next-20151221 #2
Workqueue: events_freezable mmc_rescan
task: 9f0ce000 ti: 9f0d0000 task.ti: 9f0d0000

[ECR   ]: 0x0031abcd => Check Programmer's Manual
[EFA   ]: 0x00000000
[BLINK ]: arc_dma_map_sg+0x50/0xe4
[ERET  ]: arc_dma_map_page+0x3c/0x98
[STAT32]: 0x00000006 : K         E2 E1
BTA: 0x800f57c8  SP: 0x9f0d1cfc  FP: 0x00000000
LPS: 0x80323e80 LPE: 0x80323e84 LPC: 0x00000000
r00: 0x9f04310c r01: 0x0008bb69 r02: 0x1f0c3a40
r03: 0x00000040 r04: 0x00000002 r05: 0x9fdc0000
r06: 0x800f5794 r07: 0x00000000 r08: 0x23b345fc
r09: 0x00000000 r10: 0x00000007 r11: 0x00000000
r12: 0x00000000
random: nonblocking pool is initialized
INFO: rcu_preempt self-detected stall on CPU
        0-...: (8386 ticks this GP) idle=011/140000000000001/0 softirq=92/92 fqs=0
         (t=8403 jiffies g=-261 c=-262 q=60)
rcu_preempt kthread starved for 8403 jiffies! g4294967035 c4294967034 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
rcu_preempt     S 8053879e     0     7      2 0x00000000

Stack Trace:
  __switch_to+0x0/0x94
  __schedule+0x1c2/0x724
  schedule+0x2a/0x74
  schedule_timeout+0x126/0x198
  rcu_gp_kthread+0x5fa/0xee8
  kthread+0xe2/0xf4
  ret_from_fork+0x18/0x1c
Task dump for CPU 0:
kworker/0:1     R running      0    19      2 0x00000008
Workqueue: events_freezable mmc_rescan

Stack Trace:
  __switch_to+0x0/0x94
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:1:19]
Modules linked in:
Path: (null)
CPU: 0 PID: 19 Comm: kworker/0:1 Tainted: G             L  4.4.0-rc5-next-20151221 #2
Workqueue: events_freezable mmc_rescan
task: 9f0ce000 ti: 9f0d0000 task.ti: 9f0d0000

[ECR   ]: 0x0031abcd => Check Programmer's Manual
[EFA   ]: 0x00000000
[BLINK ]: arc_dma_map_sg+0x50/0xe4
[ERET  ]: arc_dma_map_page+0x1c/0x98
[STAT32]: 0x00000006 : K         E2 E1
BTA: 0x800f5795  SP: 0x9f0d1d00  FP: 0x00000000
LPS: 0x80323e80 LPE: 0x80323e84 LPC: 0x00000000
r00: 0x9f04310c r01: 0x0008bb69 r02: 0x00001a40
r03: 0x00000040 r04: 0x00000002 r05: 0x9fdc0000
r06: 0x800f5794 r07: 0x00000000 r08: 0x23b345fc
r09: 0x00000000 r10: 0x00000007 r11: 0x00000000
r12: 0x00000000
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:1:19]
Modules linked in:
Path: (null)
CPU: 0 PID: 19 Comm: kworker/0:1 Tainted: G             L  4.4.0-rc5-next-20151221 #2
Workqueue: events_freezable mmc_rescan
task: 9f0ce000 ti: 9f0d0000 task.ti: 9f0d0000

[ECR   ]: 0x0031abcd => Check Programmer's Manual
[EFA   ]: 0x00000000
[BLINK ]: arc_dma_map_sg+0x50/0xe4
[ERET  ]: arc_dma_map_page+0x8/0x98
[STAT32]: 0x00000006 : K         E2 E1
BTA: 0x800f5795  SP: 0x9f0d1d10  FP: 0x00000000
LPS: 0x80323e80 LPE: 0x80323e84 LPC: 0x00000000
r00: 0x9f04310c r01: 0x9ffeeda4 r02: 0x00001a40
r03: 0x00000040 r04: 0x00000002 r05: 0x9fdc0000
r06: 0x800f5794 r07: 0x00000000 r08: 0x23b345fc
r09: 0x00000000 r10: 0x00000007 r11: 0x00000000
r12: 0x00000000
INFO: rcu_preempt self-detected stall on CPU
        0-...: (14672 ticks this GP) idle=011/140000000000001/0 softirq=92/92 fqs=0
         (t=14706 jiffies g=-261 c=-262 q=60)
rcu_preempt kthread starved for 14706 jiffies! g4294967035 c4294967034 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
rcu_preempt     S 8053879e     0     7      2 0x00000000

Stack Trace:
  __switch_to+0x0/0x94
  __schedule+0x1c2/0x724
  schedule+0x2a/0x74
  schedule_timeout+0x126/0x198
  rcu_gp_kthread+0x5fa/0xee8
  kthread+0xe2/0xf4
  ret_from_fork+0x18/0x1c
Task dump for CPU 0:
kworker/0:1     R running      0    19      2 0x00000008
Workqueue: events_freezable mmc_rescan

Stack Trace:
  __switch_to+0x0/0x94
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/0:1:19]
Modules linked in:
Path: (null)
CPU: 0 PID: 19 Comm: kworker/0:1 Tainted: G             L  4.4.0-rc5-next-20151221 #2
Workqueue: events_freezable mmc_rescan
task: 9f0ce000 ti: 9f0d0000 task.ti: 9f0d0000

[ECR   ]: 0x0031abcd => Check Programmer's Manual
[EFA   ]: 0x00000000
[BLINK ]: arc_dma_map_sg+0x50/0xe4
[ERET  ]: arc_dma_map_page+0x28/0x98
[STAT32]: 0x00000006 : K         E2 E1
BTA: 0x800f5795  SP: 0x9f0d1d00  FP: 0x00000000
LPS: 0x80323e80 LPE: 0x80323e84 LPC: 0x00000000
r00: 0x9f04310c r01: 0x0008bb69 r02: 0x00001a40
r03: 0x00000040 r04: 0x00000002 r05: 0x9fdc0000
r06: 0x800f5794 r07: 0x00000000 r08: 0x23b345fc
r09: 0x00000000 r10: 0x00000007 r11: 0x00000000
r12: 0x00000000
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/0:1:19]
Modules linked in:
Path: (null)
CPU: 0 PID: 19 Comm: kworker/0:1 Tainted: G             L  4.4.0-rc5-next-20151221 #2
Workqueue: events_freezable mmc_rescan
task: 9f0ce000 ti: 9f0d0000 task.ti: 9f0d0000

[ECR   ]: 0x0031abcd => Check Programmer's Manual
[EFA   ]: 0x00000000
[BLINK ]: arc_dma_map_sg+0x50/0xe4
[ERET  ]: arc_dma_map_page+0x4e/0x98
[STAT32]: 0x00000006 : K         E2 E1
BTA: 0x800f57c8  SP: 0x9f0d1d00  FP: 0x00000000
LPS: 0x80323e80 LPE: 0x80323e84 LPC: 0x00000000
r00: 0x9f04310c r01: 0x0008bb69 r02: 0x00001a40
r03: 0x00000040 r04: 0x00000002 r05: 0x9fdc0000
r06: 0x800f5794 r07: 0x00000000 r08: 0x23b345fc
r09: 0x00000000 r10: 0x00000007 r11: 0x00000000
r12: 0x00000000
INFO: rcu_preempt self-detected stall on CPU
        0-...: (20958 ticks this GP) idle=011/140000000000001/0 softirq=92/92 fqs=0
         (t=21009 jiffies g=-261 c=-262 q=60)
rcu_preempt kthread starved for 21009 jiffies! g4294967035 c4294967034 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
rcu_preempt     S 8053879e     0     7      2 0x00000000

Stack Trace:
  __switch_to+0x0/0x94
  __schedule+0x1c2/0x724
  schedule+0x2a/0x74
  schedule_timeout+0x126/0x198
  rcu_gp_kthread+0x5fa/0xee8
  kthread+0xe2/0xf4
  ret_from_fork+0x18/0x1c
Task dump for CPU 0:
kworker/0:1     R running      0    19      2 0x00000008
Workqueue: events_freezable mmc_rescan

Stack Trace:
  __switch_to+0x0/0x94


From lkp at intel.com  Mon Dec 21 11:45:47 2015
From: lkp at intel.com (kbuild test robot)
Date: Tue, 22 Dec 2015 03:45:47 +0800
Subject: [PATCH v3 2/2] add new platform driver for PCI RC
In-Reply-To: <5d0ef02da7c69534420aac36a8a0a375873bae99.1450694884.git.jpinto@synopsys.com>
Message-ID: <201512220321.CiZXINn9%fengguang.wu@intel.com>

Hi Joao,

[auto build test ERROR on arc/for-next]
[also build test ERROR on v4.4-rc6 next-20151221]

url:    https://github.com/0day-ci/linux/commits/Joao-Pinto/adding-PCI-support-to-AXS10x/20151221-234734
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next
config: i386-allmodconfig (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/pci/host/pcie-designware.c: In function 'dw_pcie_host_init':
>> drivers/pci/host/pcie-designware.c:556:7: error: implicit declaration of function 'pci_has_flag' [-Werror=implicit-function-declaration]
     if (!pci_has_flag(PCI_PROBE_ONLY)) {
          ^
>> drivers/pci/host/pcie-designware.c:556:20: error: 'PCI_PROBE_ONLY' undeclared (first use in this function)
     if (!pci_has_flag(PCI_PROBE_ONLY)) {
                       ^
   drivers/pci/host/pcie-designware.c:556:20: note: each undeclared identifier is reported only once for each function it appears in
   cc1: some warnings being treated as errors

vim +/pci_has_flag +556 drivers/pci/host/pcie-designware.c

cbce7900 Zhou Wang   2015-10-29  550  
cbce7900 Zhou Wang   2015-10-29  551  #ifdef CONFIG_ARM
cbce7900 Zhou Wang   2015-10-29  552  	/* support old dtbs that incorrectly describe IRQs */
cbce7900 Zhou Wang   2015-10-29  553  	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
0815f957 Yijing Wang 2014-11-11  554  #endif
0815f957 Yijing Wang 2014-11-11  555  
cbce7900 Zhou Wang   2015-10-29 @556  	if (!pci_has_flag(PCI_PROBE_ONLY)) {
cbce7900 Zhou Wang   2015-10-29  557  		pci_bus_size_bridges(bus);
cbce7900 Zhou Wang   2015-10-29  558  		pci_bus_assign_resources(bus);
4b1ced84 Jingoo Han  2013-07-31  559  

:::::: The code at line 556 was first introduced by commit
:::::: cbce7900598c26a12652f8ca9c41c5b29034c38d PCI: designware: Make driver arch-agnostic

:::::: TO: Zhou Wang <wangzhou1 at hisilicon.com>
:::::: CC: Bjorn Helgaas <bhelgaas at google.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/octet-stream
Size: 52582 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-snps-arc/attachments/20151222/f7add423/attachment-0001.obj>

From noreply at ellerman.id.au  Tue Dec 22 20:42:10 2015
From: noreply at ellerman.id.au (noreply at ellerman.id.au)
Date: Wed, 23 Dec 2015 04:42:10 -0000
Subject: kisskb: OK linux-next/axs103_smp_defconfig/arcv2 Wed Dec 23, 15:41
Message-ID: <20151223044210.1.76972@21ab0802fddb>

OK linux-next/axs103_smp_defconfig/arcv2 Wed Dec 23, 15:41

http://kisskb.ellerman.id.au/kisskb/buildresult/12574750/

Commit:   Add linux-next specific files for 20151223
          80c75a0f1d81922bf322c0634d1e1a15825a89e6
Compiler: arc-buildroot-linux-uclibc-gcc (Buildroot 2015.08.1) 4.8.4

Possible errors
---------------

     harderr = icmp_err_convert[code].fatal;

Possible warnings (111)
----------------------

kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sched/core.c:3162:1: warning: control reaches end of non-void function [-Wreturn-type]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/sysctl.c:1914:12: warning: 'kbuf' may be used uninitialized in this function [-Wmaybe-uninitialized]
ipc/shm.c:1219:2: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:818:21: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:95:8: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:695:17: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized]
kernel/time/posix-cpu-timers.c:1268:13: warning: 'now' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/rbtree.h:83:28: warning: 'rb_parent' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/rbtree.h:86:11: warning: 'rb_link' may be used uninitialized in this function [-Wmaybe-uninitialized]
mm/mmap.c:672:17: warning: 'prev' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/kernel.h:752:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
drivers/gpio/gpiolib.c:193:20: warning: 'iterator' may be used uninitialized in this function [-Wmaybe-uninitialized]
block/cfq-iosched.c:3775:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/namei.c:1767:10: warning: 'seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/datagram.c:99:5: warning: 'last' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/datagram.c:99:5: warning: 'last' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/namei.c:3237:10: warning: 'seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
lib/cpumask.c:178:1: warning: control reaches end of non-void function [-Wreturn-type]
net/core/ethtool.c:260:1: warning: control reaches end of non-void function [-Wreturn-type]
drivers/base/regmap/regmap-mmio.c:113:1: warning: control reaches end of non-void function [-Wreturn-type]
net/packet/af_packet.c:2098:33: warning: 'hdrlen' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/core/neighbour.c:3180:10: warning: 'p_name' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
net/unix/af_unix.c:1116:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1026:20: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/unix/af_unix.c:1237:8: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/xfrm/xfrm_policy.c:1599:7: warning: 'dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]
arch/arc/include/asm/elf.h:58:29: warning: integer overflow in expression [-Woverflow]
net/unix/af_unix.c:1694:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
net/unix/af_unix.c:1694:9: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/xfrm/xfrm_policy.c:1599:7: warning: 'dst_ops' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/inode.c:559:5: warning: 'retval' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
include/linux/buffer_head.h:363:2: warning: 'blocknr' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
include/linux/buffer_head.h:370:2: warning: 'blocknr' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_extents.h:224:8: warning: '*((void *)&zero_ex+8)' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_extents.h:225:12: warning: '*((void *)&zero_ex+6)' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:3113:2: warning: 'zero_ex.ee_block' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/ext4_jbd2.h:409:1: warning: control reaches end of non-void function [-Wreturn-type]
fs/ext4/extents.c:2306:14: warning: 'lblock' may be used uninitialized in this function [-Wmaybe-uninitialized]
fs/ext4/extents.c:2305:14: warning: 'len' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U 4c0>.key[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U 4c0>.key[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:26: warning: 'saddr.<U 4c0>.a4.vif' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U 4c0>.a4.addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/tty/serial/8250/8250_core.c:163:19: warning: 'i' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.<U 4c0>.a4.addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/tcp_metrics.c:1079:7: warning: 'hash' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U 4c0>.key[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'saddr.<U 4c0>.key[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[3]' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/net/inetpeer.h:141:6: warning: 'daddr.in6_u.u6_addr32[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/usb/storage/transport.c:473:40: warning: 'partial' may be used uninitialized in this function [-Wmaybe-uninitialized]
include/linux/sunrpc/svc_xprt.h:175:1: warning: control reaches end of non-void function [-Wreturn-type]
drivers/usb/storage/transport.c:499:15: warning: 'partial' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/tcp_input.c:4224:49: warning: array subscript is above array bounds [-Warray-bounds]
net/sunrpc/svcsock.c:779:6: warning: 'optname' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcsock.c:779:6: warning: 'level' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:559:37: warning: 'code' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:532:3: warning: 'type' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:513:48: warning: 'icmph' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:690:21: warning: 'type' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/ping.c:476:63: warning: 'code' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/ipv4/fib_trie.c:909:11: warning: 'local_tp' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/svcauth_unix.c:282:12: warning: 'sin6' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1153:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1144:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1153:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1149:17: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1144:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1207:12: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1122:8: warning: 'subbuf.tail[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.page_base' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1118:19: warning: 'subbuf.pages' may be used uninitialized in this function [-Wmaybe-uninitialized]
net/sunrpc/xdr.c:1113:8: warning: 'subbuf.head[0].iov_base' may be used uninitialized in this function [-Wmaybe-uninitialized]



From Vineet.Gupta1 at synopsys.com  Wed Dec 23 03:14:46 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 23 Dec 2015 16:44:46 +0530
Subject: ARC AXS101 problems with linux next-20151221
In-Reply-To: <56784531.1000007@synopsys.com>
References: <56784531.1000007@synopsys.com>
Message-ID: <567A8226.80308@synopsys.com>

Hi Christoph, Andrew

> On Tuesday 22 December 2015 12:00 AM, Carlos Palminha wrote:
> Hi guys,
> 
> I just compiled the kernel for axs101_defconfig based on linux next tag 'next-20151221'.
> I can't boot it due to the following errors causing strange stack traces after freeing unused kernel memory (check log below).
> 
> Any clue?
> Do you more info to understand the issue?

....[snip]

> dw_mmc e0015000.mmc: IDMAC supports 32-bit address mode.
> dw_mmc e0015000.mmc: Using internal DMA controller.
> dw_mmc e0015000.mmc: Version ID is 270a
> dw_mmc e0015000.mmc: DW MMC controller at irq 34,32 bit host data width,16 deep fifo
> dw_mmc e0015000.mmc: 1 slots initialized
> sdhci-pltfm: SDHCI platform and OF driver helper
> usbcore: registered new interface driver usbhid
> usbhid: USB HID core driver
> NET: Registered protocol family 17
> NET: Registered protocol family 15
> ttyS3 - failed to request DMA
> Freeing unused kernel memory: 928K (80002000 - 800ea000)
> INFO: rcu_preempt self-detected stall on CPU
>         0-...: (2100 ticks this GP) idle=011/140000000000001/0 softirq=92/92 fqs=0
>          (t=2100 jiffies g=-261 c=-262 q=60)
> rcu_preempt kthread starved for 2100 jiffies! g4294967035 c4294967034 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
> rcu_preempt     S 8053879e     0     7      2 0x00000000
> 
> Stack Trace:
>   __switch_to+0x0/0x94
>   __schedule+0x1c2/0x724
>   schedule+0x2a/0x74
>   schedule_timeout+0x126/0x198
>   rcu_gp_kthread+0x5fa/0xee8
>   kthread+0xe2/0xf4
>   ret_from_fork+0x18/0x1c
> Task dump for CPU 0:
> kworker/0:1     R running      0    19      2 0x00000008
> Workqueue: events_freezable mmc_rescan

[snip]

It seems the dma ops rework for ARC makes kernel belly up.

Patch below fixes it.

------------->
>From 96b44b39dc39542894a1081e683bd21f56cae1d1 Mon Sep 17 00:00:00 2001
From: Vineet Gupta <vgupta at synopsys.com>
Date: Wed, 23 Dec 2015 15:41:20 +0530
Subject: [PATCH] ARC: dma mapping fixes #2

Carlos Palminha reported linux-next boot broken for ARC.

(1) dma_map_single() would recursively call itself

| #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
| dma_map_single_attrs
|   ops->map_page
|     arc_dma_map_page
|        dma_map_single

(2) arc_dma_free() to iounmap if memory is coherent

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

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 695029f41a48..01eaf88bf821 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -72,8 +72,8 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
 static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
 		dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
-	if (!(is_isa_arcv2() && ioc_exists) ||
-	    dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
+	if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) &&
+	    !(is_isa_arcv2() && ioc_exists))
 		iounmap((void __force __iomem *)vaddr);

 	free_pages_exact((void *)dma_handle, size);
@@ -107,7 +107,8 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct
page *page,
 		struct dma_attrs *attrs)
 {
 	unsigned long paddr = page_to_phys(page) + offset;
-	return dma_map_single(dev, (void *)paddr, size, dir);
+	_dma_cache_sync(paddr, size, dir);
+	return (dma_addr_t)paddr;
 }

 static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg,
-- 
1.9.1



From Vineet.Gupta1 at synopsys.com  Fri Dec 25 23:01:22 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Sat, 26 Dec 2015 07:01:22 +0000
Subject: [GIT PULL] ARC fixes for 4.4-rc7
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075F4E82F2C@us01wembx1.internal.synopsys.com>

Hi Linus,

Sorry for this late pull request, but these are all important fixes for code
introduced/updated in this release which we will otherwise end up back porting.

Please pull and wish you happy holidays !

Thx,
-Vineet
--------------->
The following changes since commit 4ef7675344d687a0ef5b0d7c0cee12da005870c0:

  Linux 4.4-rc6 (2015-12-20 16:06:09 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git/ tags/arc-4.4-rc7-fixes

for you to fetch changes up to 6b538db7c6b091960c57b23feae5431fc82286e7:

  ARC: dw2 unwind: Catch Dwarf SNAFUs early (2015-12-21 14:01:49 +0530)

----------------------------------------------------------------
ARC fixes for
 - Unwinder rework (A revert followed by better fix)
 - Build errors: MMUv2, modules with -Os
 - highmem section mismatch build splat

----------------------------------------------------------------
Alexey Brodkin (1):
      ARC: mm: fix building for MMU v2

Vineet Gupta (5):
      ARC: mm: HIGHMEM: Fix section mismatch splat
      ARC: Fix linking errors with CONFIG_MODULE + CONFIG_CC_OPTIMIZE_FOR_SIZE
      Revert "ARC: dw2 unwind: Ignore CIE version !=1 gracefully instead of bailing"
      ARC: dw2 unwind: Don't bail for CIE.version != 1
      ARC: dw2 unwind: Catch Dwarf SNAFUs early

 arch/arc/Makefile            |  2 +-
 arch/arc/include/asm/cache.h |  2 --
 arch/arc/kernel/unwind.c     | 28 +++++++++++-----------------
 arch/arc/mm/highmem.c        |  4 ++--
 4 files changed, 14 insertions(+), 22 deletions(-)


From noamc at ezchip.com  Sun Dec 27 05:23:19 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:19 +0200
Subject: [PATCH v5 00/20] Adding plat-eznps to ARC
Message-ID: <1451222619-3610-1-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

v5:
1) irqchip -- work with handle_domain_irq(), and remove use of irq_set_default_host()
2) clocksource -- initialize clockevents as well by parsing interrupts node of DT
3) Do not use IPI with irq generic infrastructure

v4:
1) irqchip -- use irq_domain_add_linear()
2) clocksource -- use of_clk_get()
3) New header at include/soc use by platform and drivers
4) update DTS file for above fixed drivers

v3:
1)	irqchip: use MACROS instead of structures to decribe
	registers.
2)	clocksource: use 32bit counter and avoid 2 halfs read
	of 64bit dance.

v2:
1)	Remove out of tree platform include path
2)	Move atomic/bitop/cmpxchg for platform to end.
	Remove macro duplication.
	Fix some bad implementation.
3)	define cpu_relax_lowlatency() for platform.
4)	rename init_irq_cpu() to init_per_cpu()
	reorder call to init_per_cpu() for secondary
	use it instead of init_cpu_smp().
5)	set res_service to call stext
6)	fix build failure for CTOP_AUX_BASE at assembly code
7)	Use ilog2 for mtm_init_nat()
8)	Add CLKSRC_NPS option to Kconfig
	change nps_clksrc_read() to be more readable.

General summay:
This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threads. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (19):
  Documentation: Add EZchip vendor to binding list
  soc: Support for EZchip SoC
  ARC: [plat-eznps] define IPI_IRQ
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: Mark secondary cpu online only after all HW setup is done
  ARC: IRQ: use device tree to get timer device configuration
  ARC: IRQ: do not use hwirq directly at arch_do_IRQ()
  ARC: IPI: do not use generic IRQ domain
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (1):
  ARC: [plat-eznps] Use dedicated cpu_relax()

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   17 ++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |   10 +
 arch/arc/Makefile                                  |    5 +
 arch/arc/boot/dts/eznps.dts                        |   94 +++++++++
 arch/arc/configs/nps_defconfig                     |   85 +++++++++
 arch/arc/include/asm/Kbuild                        |    1 -
 arch/arc/include/asm/atomic.h                      |   79 ++++++++-
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   54 ++++++
 arch/arc/include/asm/cmpxchg.h                     |   87 +++++++--
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/hardirq.h                     |   22 +++
 arch/arc/include/asm/irq.h                         |    9 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   36 +++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    6 +
 arch/arc/include/asm/spinlock.h                    |   14 ++
 arch/arc/kernel/ctx_sw.c                           |   13 ++
 arch/arc/kernel/irq.c                              |   25 +++
 arch/arc/kernel/setup.c                            |    1 -
 arch/arc/kernel/smp.c                              |   39 ++++-
 arch/arc/kernel/time.c                             |    8 +
 arch/arc/mm/tlb.c                                  |   12 ++
 arch/arc/plat-eznps/Kconfig                        |   34 ++++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   70 +++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  198 +++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 ++++++
 arch/arc/plat-eznps/include/plat/smp.h             |   26 +++
 arch/arc/plat-eznps/mtm.c                          |  133 +++++++++++++
 arch/arc/plat-eznps/platform.c                     |  102 ++++++++++
 arch/arc/plat-eznps/smp.c                          |  154 +++++++++++++++
 drivers/clocksource/Kconfig                        |    7 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |  199 ++++++++++++++++++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  139 ++++++++++++++
 include/soc/nps/common.h                           |  123 ++++++++++++
 43 files changed, 1893 insertions(+), 31 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/include/asm/hardirq.h
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c
 create mode 100644 include/soc/nps/common.h



From noamc at ezchip.com  Sun Dec 27 05:23:20 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:20 +0200
Subject: [PATCH v5 01/20] Documentation: Add EZchip vendor to binding list
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-2-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..1aa50c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Processor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d4..d7bff8a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -82,6 +82,7 @@ eukrea  Eukr??a Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 focaltech	FocalTech Systems Co.,Ltd
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:21 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:21 +0200
Subject: [PATCH v5 02/20] soc: Support for EZchip SoC
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-3-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This header file is for NPS400 SoC.
It includes macros for accessing memory mapped registers.
These are functional registers that core can use to configure SoC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 include/soc/nps/common.h |  123 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 123 insertions(+), 0 deletions(-)
 create mode 100644 include/soc/nps/common.h

diff --git a/include/soc/nps/common.h b/include/soc/nps/common.h
new file mode 100644
index 0000000..3bc30a8
--- /dev/null
+++ b/include/soc/nps/common.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef SOC_NPS_COMMON_H
+#define SOC_NPS_COMMON_H
+
+#define NPS_HOST_REG_BASE			0xF6000000
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5B60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+
+#ifndef __ASSEMBLY__
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physically,
+ * and not like the id's physically came with each cluster.
+ * Below table is 4x4 mesh of core clusters as it layout on chip.
+ * Cluster ids are in format: logical (physical)
+ *
+ *    -----------------   ------------------
+ * 3 |  5 (3)   7 (7)  | | 13 (11)   15 (15)|
+ *
+ * 2 |  4 (2)   6 (6)  | | 12 (10)   14 (14)|
+ *    -----------------   ------------------
+ * 1 |  1 (1)   3 (5)  | |  9  (9)   11 (13)|
+ *
+ * 0 |  0 (0)   2 (4)  | |  8  (8)   10 (12)|
+ *    -----------------   ------------------
+ *       0       1            2        3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	 __asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32 base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+#endif /* __ASSEMBLY__ */
+
+#endif /* SOC_NPS_COMMON_H */
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:22 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:22 +0200
Subject: [PATCH v5 03/20] ARC: [plat-eznps] define IPI_IRQ
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-4-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:23 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:23 +0200
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-5-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: John Stultz <john.stultz at linaro.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   17 ++
 drivers/clocksource/Kconfig                        |    7 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |  199 ++++++++++++++++++++
 4 files changed, 224 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..eeb26d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,17 @@
+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
+- interrupts : The interrupt of the first timer
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer";
+	clocks = <&sysclk>;
+	interrupts = <3>;
+};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 2eb5f0e..859e83d 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -132,6 +132,13 @@ config CLKSRC_TI_32K
 	  This option enables support for Texas Instruments 32.768 Hz clocksource
 	  available on many OMAP-like platforms.
 
+config CLKSRC_NPS
+	bool "NPS400 clocksource driver" if COMPILE_TEST
+	select CLKSRC_OF if OF
+	help
+	  NPS400 clocksource support.
+	  Got 64 bit counter with update rate up to 1000MHz.
+
 config CLKSRC_STM32
 	bool "Clocksource for STM32 SoCs" if !ARCH_STM32
 	depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 56bd16e..056cffd 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
 obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
+obj-$(CONFIG_CLKSRC_NPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..b3fc9ba
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/cpu.h>
+#include <soc/nps/common.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+/* 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 TIMER_CTRL_IE           (1 << 0) /* Interupt when Count reachs limit */
+#define TIMER_CTRL_NH           (1 << 1) /* Count only when CPU NOT halted */
+
+/* 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 int nps_timer_irq;
+
+static cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
+
+	return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(32),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void nps_timer_event_setup(unsigned int cycles)
+{
+	write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
+	write_aux_reg(ARC_REG_TIMER0_CNT, 0);   /* start from 0 */
+
+	write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
+}
+
+static int nps_clkevent_set_next_event(unsigned long delta,
+				       struct clock_event_device *dev)
+{
+	nps_timer_event_setup(delta);
+	return 0;
+}
+
+static int nps_clkevent_set_periodic(struct clock_event_device *dev)
+{
+	/*
+	 * At X Hz, 1 sec = 1000ms -> X cycles;
+	 *                    10ms -> X / 100 cycles
+	 */
+	nps_timer_event_setup(nps_timer_rate / HZ);
+	return 0;
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
+	.name			= "nps_sys_timer",
+	.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,
+};
+
+static int nps_timer_cpu_notify(struct notifier_block *self,
+				unsigned long action, void *hcpu)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+
+	evt->irq = nps_timer_irq;
+	evt->cpumask = cpumask_of(smp_processor_id());
+
+	/*
+	 * Grab cpu pointer in each case to avoid spurious
+	 * preemptible warnings
+	 */
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_STARTING:
+		enable_percpu_irq(nps_timer_irq, 0);
+		clockevents_config_and_register(evt, nps_timer_rate,
+						0, ULONG_MAX);
+		break;
+	case CPU_DYING:
+		disable_percpu_irq(nps_timer_irq);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block nps_timer_cpu_nb = {
+	.notifier_call = nps_timer_cpu_notify,
+};
+
+static irqreturn_t nps_timer_irq_handler(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+	int irq_reenable = clockevent_state_periodic(evt);
+
+	/*
+	 * Any write to CTRL reg ACks the interrupt, we rewrite the
+	 * Count when [N]ot [H]alted bit.
+	 * And re-arm it if perioid by [I]nterrupt [E]nable bit
+	 */
+	write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static void __init nps_setup_clocksource(struct device_node *node,
+					 struct clk *clk, int irq)
+{
+	struct clocksource *clksrc = &nps_counter;
+	int ret, cluster;
+
+	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");
+
+	nps_timer_rate = clk_get_rate(clk);
+
+	ret = clocksource_register_hz(clksrc, nps_timer_rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+static void __init nps_setup_clockevents(struct device_node *node,
+					 struct clk *clk, int irq)
+{
+	struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+	int ret;
+
+	register_cpu_notifier(&nps_timer_cpu_nb);
+
+	evt->irq = irq;
+	evt->cpumask = cpumask_of(smp_processor_id());
+
+	clockevents_config_and_register(evt, nps_timer_rate, 0, ULONG_MAX);
+
+	enable_percpu_irq(irq, 0);
+
+	ret = request_percpu_irq(irq, nps_timer_irq_handler,
+				 "timer", evt);
+	if (ret)
+		pr_err("Unable to register interrupt\n");
+}
+
+static void __init nps_timer_init(struct device_node *node)
+{
+	struct clk *clk;
+
+	nps_timer_irq = irq_of_parse_and_map(node, 0);
+	if (nps_timer_irq <= 0)
+		panic("Can't parse IRQ");
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk))
+		panic("Can't get timer clock");
+
+	nps_setup_clocksource(node, clk, nps_timer_irq);
+	nps_setup_clockevents(node, clk, nps_timer_irq);
+}
+
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
+		       nps_timer_init);
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:24 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:24 +0200
Subject: [PATCH v5 05/20] irqchip: add nps Internal and external irqchips
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-6-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 +++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  139 ++++++++++++++++++++
 3 files changed, 157 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 177f78f..b95b954 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..5a5d649
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+
+/*
+ * NPS400 core includes an Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ *
+ * NOTE: AUX_IENABLE and CTOP_AUX_IACK are auxiliary registers
+ * with private HW copy per CPU.
+ */
+
+static void nps400_irq_mask(struct irq_data *irqd)
+{
+	unsigned int ienb;
+	unsigned int irq = irqd_to_hwirq(irqd);
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *irqd)
+{
+	unsigned int ienb;
+	unsigned int irq = irqd_to_hwirq(irqd);
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+
+	write_aux_reg(CTOP_AUX_IACK, 1 << irq);
+
+	/* Don't ack before all device access attempts are done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+
+	write_aux_reg(CTOP_AUX_IACK, 1 << irq);
+}
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
+			  irq_hw_number_t hw)
+{
+	switch (hw) {
+	case TIMER0_IRQ:
+		irq_set_percpu_devid(virq);
+		irq_set_chip_and_handler(virq, &nps400_irq_chip_percpu,
+					 handle_percpu_devid_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(virq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static void nps400_handle_irq(unsigned int hwirq, struct pt_regs *regs)
+{
+	handle_domain_irq(nps400_root_domain, hwirq, regs);
+}
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	set_handle_irq(nps400_handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:25 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:25 +0200
Subject: [PATCH v5 06/20] ARC: Set vmalloc size from configuration
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-7-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

This introduce build error since PGDIR_SIZE() cannot use "1UL"
ibecause it is called from mm/tlbex.S by VMALLOC_START.
Using _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/pgtable.h   |    2 +-
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 6312f60..7be1020 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -469,6 +469,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 1d694c1..8a77ccd 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -109,18 +109,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index daf2bf5..843e1a5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:26 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:26 +0200
Subject: [PATCH v5 07/20] ARC: rwlock: disable interrupts in !LLSC variant
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-8-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

If we hold rwlock and interrupt occures we may
end up spinning on it for ever during softirq.
Note that this lock is an internal lock
and since the lock is free to be used from any context,
the lock needs to be IRQ-safe.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:27 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:27 +0200
Subject: [PATCH v5 08/20] ARC: Mark secondary cpu online only after all HW
 setup is done
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-9-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up().
For ARC it returns as soon as new cpu's status becomes online,
However secondary may still do HW initializing,
machine or platform hook level.

So turn secondary online only after all HW setup is done.
Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/smp.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index ef6e9e1..2cfe135 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,11 +126,6 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
-	notify_cpu_starting(cpu);
-	set_cpu_online(cpu, true);
-
-	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
-
 	/* Some SMP H/w setup - for each cpu */
 	if (plat_smp_ops.init_per_cpu)
 		plat_smp_ops.init_per_cpu(cpu);
@@ -138,6 +133,11 @@ void start_kernel_secondary(void)
 	if (machine_desc->init_per_cpu)
 		machine_desc->init_per_cpu(cpu);
 
+	notify_cpu_starting(cpu);
+	set_cpu_online(cpu, true);
+
+	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
+
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:28 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:28 +0200
Subject: [PATCH v5 09/20] ARC: IRQ: use device tree to get timer device
 configuration
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-10-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We've designated:
TIMER0 for events (clockevents)
TIMER1 for free running (clocksource)

Till now timer configuration was done on arch/arc/kernel/time.c
with constant values.

This commit add device tree support so we can do this work
at dedicated clocksource driver which parse the DT blob.

Such driver will get clocksource rate as well as interrupt line
from DT and use them for setting clocksourcse and clockevents.

Note that lately called of_clk_init() is moved before we call
clocksource_probe() since at that time device from DT
need a "provider" (clocks) which will be available only after
we call to of_clk_init().

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/setup.c |    1 -
 arch/arc/kernel/smp.c   |    2 ++
 arch/arc/kernel/time.c  |    8 ++++++++
 3 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index e1b8744..4681e9c 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -433,7 +433,6 @@ void __init setup_arch(char **cmdline_p)
 
 static int __init customize_machine(void)
 {
-	of_clk_init(NULL);
 	/*
 	 * Traverses flattened DeviceTree - registering platform devices
 	 * (if any) complete with their resources
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 2cfe135..ec6a5c1 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -138,7 +138,9 @@ void start_kernel_secondary(void)
 
 	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
+#ifndef CONFIG_CLKSRC_OF
 	arc_local_timer_setup();
+#endif
 
 	local_irq_enable();
 	preempt_disable();
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..be6dd9e 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -38,6 +38,7 @@
 #include <linux/init.h>
 #include <linux/timex.h>
 #include <linux/profile.h>
+#include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <asm/irq.h>
@@ -283,6 +284,13 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_COMMON_CLK
+	of_clk_init(NULL);
+#endif
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_probe();
+#else
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
+#endif
 }
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:29 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:29 +0200
Subject: [PATCH v5 10/20] ARC: IRQ: do not use hwirq directly at arch_do_IRQ()
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-11-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

ARC uses hwirq at arch_do_IRQ() to pass into generic_handle_irq().
This is wrong since we need first to reverse map it into virq.

Happily, if we use handle_domain_irq() we get all we need.

Just like ARM I created a pointer to handler that should be filled
by an interrupt controller driver from driver/irqchip/

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/Kconfig           |    1 +
 arch/arc/include/asm/irq.h |    5 +++++
 arch/arc/kernel/irq.c      |   14 ++++++++++++++
 3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 7be1020..079946e 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -32,6 +32,7 @@ config ARC
 	select HAVE_OPROFILE
 	select HAVE_PERF_EVENTS
 	select IRQ_DOMAIN
+	select HANDLE_DOMAIN_IRQ if ARC_PLAT_EZNPS
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
 	select OF
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index c5f8f0f..64226c9 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -36,4 +36,9 @@ void arc_request_percpu_irq(int irq, int cpu,
                             irqreturn_t (*isr)(int irq, void *dev),
                             const char *irq_nm, void *percpu_dev);
 
+#ifdef CONFIG_HANDLE_DOMAIN_IRQ
+extern void set_handle_irq(void (*handle_irq)(unsigned int hwirq,
+					      struct pt_regs *));
+#endif
+
 #endif
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index ba17f85..7ae5411 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -41,6 +41,7 @@ void __init init_IRQ(void)
  * "C" Entry point for any ARC ISR, called from low level vector handler
  * @irq is the vector number read from ICAUSE reg of on-chip intc
  */
+#ifndef CONFIG_HANDLE_DOMAIN_IRQ
 void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
@@ -50,6 +51,19 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
 	irq_exit();
 	set_irq_regs(old_regs);
 }
+#else
+void (*handle_arch_irq)(unsigned int hwirq, struct pt_regs *) = NULL;
+void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+	handle_arch_irq(irq, regs);
+}
+
+void __init set_handle_irq(void (*handle_irq)(unsigned int hwirq,
+					      struct pt_regs *))
+{
+	handle_arch_irq = handle_irq;
+}
+#endif
 
 /*
  * API called for requesting percpu interrupts - called by each CPU
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:30 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:30 +0200
Subject: [PATCH v5 11/20] ARC: IPI: do not use generic IRQ domain
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-12-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This behaviour is the desired one as been seen on other arch's.

We do not use generic irq domain and hence hwirq number is used
directly by our code without any mapping to virq.
In order to add IPI status to /proc/interrupts we use
hardirq macros also we define arch_show_interrupts().

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/Kbuild    |    1 -
 arch/arc/include/asm/hardirq.h |   22 ++++++++++++++++++++++
 arch/arc/include/asm/smp.h     |    6 ++++++
 arch/arc/kernel/irq.c          |   13 ++++++++++++-
 arch/arc/kernel/smp.c          |   27 +++++++++++++++++++++++++++
 5 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 arch/arc/include/asm/hardirq.h

diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 0b10ef2..bbc3e4a 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -10,7 +10,6 @@ generic-y += errno.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += ftrace.h
-generic-y += hardirq.h
 generic-y += hw_irq.h
 generic-y += ioctl.h
 generic-y += ioctls.h
diff --git a/arch/arc/include/asm/hardirq.h b/arch/arc/include/asm/hardirq.h
new file mode 100644
index 0000000..e83aa88
--- /dev/null
+++ b/arch/arc/include/asm/hardirq.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_ARC_HARDIRQ_H
+#define __ASM_ARC_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+#ifdef CONFIG_SMP
+	unsigned int ipi_irqs;
+#endif
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+#include <linux/irq.h>
+
+static inline void ack_bad_irq(unsigned int irq)
+{
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+#endif /* __ASM_ARC_HARDIRQ_H */
diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 9913804..9e4ec48 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -14,12 +14,16 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/threads.h>
+#include <asm/ptrace.h>
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
 /* including cpumask.h leads to cyclic deps hence this Forward declaration */
 struct cpumask;
 
+/* including seq_file.h leads to cyclic deps hence this Forward declaration */
+struct seq_file;
+
 /*
  * APIs provided by arch SMP code to generic code
  */
@@ -32,6 +36,8 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 extern void __init smp_init_cpus(void);
 extern void first_lines_of_secondary(void);
 extern const char *arc_platform_smp_cpuinfo(void);
+extern void arch_do_IPI(unsigned int irq, struct pt_regs *regs);
+extern void show_ipi_list(struct seq_file *, int);
 
 /*
  * API expected BY platform smp code (FROM arch smp code)
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 7ae5411..c8d3c3d 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -55,7 +55,10 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
 void (*handle_arch_irq)(unsigned int hwirq, struct pt_regs *) = NULL;
 void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-	handle_arch_irq(irq, regs);
+	if (irq == IPI_IRQ)
+		arch_do_IPI(irq, regs);
+	else
+		handle_arch_irq(irq, regs);
 }
 
 void __init set_handle_irq(void (*handle_irq)(unsigned int hwirq,
@@ -65,6 +68,14 @@ void __init set_handle_irq(void (*handle_irq)(unsigned int hwirq,
 }
 #endif
 
+int arch_show_interrupts(struct seq_file *p, int prec)
+{
+#ifdef CONFIG_SMP
+	show_ipi_list(p, prec);
+#endif
+	return 0;
+}
+
 /*
  * API called for requesting percpu interrupts - called by each CPU
  *  - For boot CPU, actually request the IRQ with genirq core + enables
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index ec6a5c1..8d37906 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -22,6 +22,7 @@
 #include <linux/atomic.h>
 #include <linux/cpumask.h>
 #include <linux/reboot.h>
+#include <linux/seq_file.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
 #include <asm/mach_desc.h>
@@ -349,6 +350,32 @@ irqreturn_t do_IPI(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+void arch_do_IPI(unsigned int irq, struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+	unsigned int cpu = smp_processor_id();
+
+	__IRQ_STAT(cpu, ipi_irqs)++;
+
+	irq_enter();
+	do_IPI(irq, NULL);
+	irq_exit();
+
+	set_irq_regs(old_regs);
+}
+
+void show_ipi_list(struct seq_file *p, int prec)
+{
+	unsigned int cpu;
+
+	seq_printf(p, "%*s: ", prec - 1, "IPI");
+
+	for_each_online_cpu(cpu)
+		seq_printf(p, "%10u ", __IRQ_STAT(cpu, ipi_irqs));
+
+	seq_printf(p, " %s\n", "IPI");
+}
+
 /*
  * API called by platform code to hookup arch-common ISR to their IPI IRQ
  */
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:31 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:31 +0200
Subject: [PATCH v5 12/20] ARC: [plat-eznps] Add eznps board defconfig and dts
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-13-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   94 ++++++++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..2434948
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,94 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	aliases {
+		ethernet0 = &gmac0;
+		pll = &sysclk;
+	};
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;	/* 512M */
+	};
+
+	clocks {
+		sysclk: sysclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <83333333>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+			clocks = <&sysclk>;
+			clock-names="sysclk";
+			interrupts = <3>;
+		};
+
+		uart at f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clocks = <&sysclk>;
+			clock-names="baudclk";
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		gmac0: ethernet at f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			/* Filled in by U-Boot */
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:32 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:32 +0200
Subject: [PATCH v5 13/20] ARC: [plat-eznps] Add eznps platform
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-14-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   70 +++++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  198 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   26 ++++
 arch/arc/plat-eznps/mtm.c               |  133 +++++++++++++++++++++
 arch/arc/plat-eznps/platform.c          |  102 ++++++++++++++++
 arch/arc/plat-eznps/smp.c               |  154 ++++++++++++++++++++++++
 10 files changed, 790 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 233f834..004e70e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4260,6 +4260,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc at ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare at suse.com>
 L:	lm-sensors at lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..051fdca
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_NPS
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..328261c
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,70 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .init.text, "ax", at progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; There is no work for HW thread id != 0
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; With no cache coherency mechanism D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..5844913
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#include <soc/nps/common.h>
+
+/* core auxiliary registers */
+#ifdef __ASSEMBLY__
+#define CTOP_AUX_BASE				(-0x800)
+#else
+#define CTOP_AUX_BASE				0xFFFFF800
+#endif
+
+#define CTOP_AUX_GLOBAL_ID			(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID			(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID			(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID			(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID		(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID		(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID			(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL			(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY			(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC				(CTOP_AUX_BASE + 0x030)
+#define CTOP_AUX_EFLAGS				(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK				(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1				(CTOP_AUX_BASE + 0x08C)
+#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		0x3E6F7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3E6F7103
+#define CTOP_INST_SCHD_RW			0x3E6F7004
+#define CTOP_INST_SCHD_RD			0x3E6F7084
+#define CTOP_INST_ASRI_0_R3			0x3B56003E
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4A664C00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4A664C01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4A664C02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4A664C04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4A664C05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4A664C06
+#define CTOP_INST_RSPI_GIC_0_R12		0x3C56117E
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED		_BITUL(28)
+
+#define NPS_MSU_BLKID				0x018
+#define NPS_MSU_EN_CFG				0x80
+#define NPS_CRG_BLKID				0x480
+#define NPS_CRG_SYNC_BIT			_BITUL(0)
+#define NPS_GIM_BLKID				0x5C0
+
+/* GIM registers and fields*/
+#define NPS_GIM_UART_LINE			_BITUL(7)
+#define NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE	_BITUL(10)
+#define NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE	_BITUL(11)
+#define NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE	_BITUL(25)
+#define NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE	_BITUL(26)
+
+#ifndef __ASSEMBLY__
+/* Functional registers definition */
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_msu_en_cfg {
+	union {
+		struct {
+			u32     __reserved1:11,
+			rtc_en:1, ipc_en:1, gim_1_en:1,
+			gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
+			buff_e_alc_bmuw:1, buff_i_rls_bmuw:1, buff_i_alc_bmuw:1,
+			buff_e_rls_bmue:1, buff_e_alc_bmue:1, buff_i_rls_bmue:1,
+			buff_i_alc_bmue:1, __reserved2:1, buff_e_pre_en:1,
+			buff_i_pre_en:1, pmuw_ja_en:1, pmue_ja_en:1,
+			pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_gim_p_int_dst {
+	union {
+		struct {
+			u32 int_out_en:1, __reserved1:4,
+			is:1, intm:2, __reserved2:4,
+			nid:4, __reserved3:4, cid:4,
+			 __reserved4:4, tid:4;
+		};
+		u32 value;
+	};
+};
+
+/* AUX registers definition */
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			st_cnt:8, __reserved:8,
+			hs_cnt:8, __reserved1:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+/* CRG registers */
+#define REG_GEN_PURP_0          nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+/* GIM registers */
+#define REG_GIM_P_INT_EN_0      nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
+#define REG_GIM_P_INT_POL_0     nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
+#define REG_GIM_P_INT_SENS_0    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
+#define REG_GIM_P_INT_BLK_0     nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
+#define REG_GIM_P_INT_DST_10    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
+#define REG_GIM_P_INT_DST_11    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
+#define REG_GIM_P_INT_DST_25    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x149)
+#define REG_GIM_P_INT_DST_26    nps_host_reg_non_cl(NPS_GIM_BLKID, 0x14A)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..06b59bd
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern void res_service(void);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..aaaaffd
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	log_nat = ilog2(nat);
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..7ad6d2b
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/mach_desc.h>
+#include <plat/mtm.h>
+
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
+
+	msu_en_cfg.msu_en = 1;
+	msu_en_cfg.ipi_en = 1;
+	msu_en_cfg.gim_0_en = 1;
+	msu_en_cfg.gim_1_en = 1;
+
+	/* enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(msu_en_cfg.value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_value;
+	u32 gim_int_lines;
+	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
+
+	gim_int_lines = NPS_GIM_UART_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE;
+
+	/*
+	 * IRQ polarity
+	 * low or high level
+	 * negative or positive edge
+	 */
+	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
+	reg_value &= ~gim_int_lines;
+	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
+
+	/* IRQ type level or edge */
+	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
+	reg_value |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE;
+	reg_value |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE;
+	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
+
+	/*
+	 * GIM interrupt select type for
+	 * dbg_lan TX and RX interrupts
+	 * should be type 1
+	 * type 0 = IRQ line 6
+	 * type 1 = IRQ line 7
+	 */
+	gim_p_int_dst.is = 1;
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_25);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_26);
+
+	/*
+	 * CTOP IRQ lines should be defined
+	 * as blocking in GIM
+	*/
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
+
+	/* enable CTOP IRQ lines in GIM */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
+}
+
+static void __init eznps_early_init(void)
+{
+	eznps_configure_msu();
+	eznps_configure_gim();
+}
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+	.init_early	= eznps_early_init,
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..8f2d6af
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = (u32)res_service;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+static void eznps_init_per_cpu(int cpu)
+{
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+static void eznps_ipi_clear(int irq)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << irq);
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+	.init_per_cpu	= eznps_init_per_cpu,
+	.ipi_clear	= eznps_ipi_clear,
+};
+
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:33 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:33 +0200
Subject: [PATCH v5 14/20] ARC: [plat-eznps] Use dedicated user stack top
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-15-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 8a77ccd..41142ab 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -122,7 +122,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 843e1a5..01f85e5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:34 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:34 +0200
Subject: [PATCH v5 15/20] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-16-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

We need our own implementaions since we lack LLSC support.
Our extended ISA provided with optimized solution for all 32bit
operations we see in these three headers.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/atomic.h  |   79 +++++++++++++++++++++++++++++++++++-
 arch/arc/include/asm/bitops.h  |   54 +++++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h |   87 +++++++++++++++++++++++++++++++++-------
 3 files changed, 202 insertions(+), 18 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index 7730d30..a626996 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #define atomic_read(v)  READ_ONCE((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -180,12 +181,84 @@ ATOMIC_OP(andnot, &= ~, bic)
 ATOMIC_OP(or, |=, or)
 ATOMIC_OP(xor, ^=, xor)
 
-#undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
-#undef ATOMIC_OP
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	temp c_op i;							\
+									\
+	return temp;							\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..5a29185 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,7 @@
 #include <asm/smp.h>
 #endif
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +156,53 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#else /* CONFIG_ARC_PLAT_EZNPS */
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	nr = old = (1UL << (nr & 0x1f));				\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	return (old & nr) != 0;					\
+}
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +244,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#else
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..6d320d3 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -66,21 +67,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
 
 #endif /* CONFIG_ARC_HAS_LLSC */
 
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
-				(unsigned long)(o), (unsigned long)(n)))
-
-/*
- * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
- * just to gaurantee semantics.
- * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
- * which also happens to be atomic_ops_lock.
- *
- * Thus despite semantically being different, implementation of atomic_cmpxchg()
- * is same as cmpxchg().
- */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-
-
 /*
  * xchg (reg with memory) based on "Native atomic" EX insn
  */
@@ -143,6 +129,63 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
 
 #endif
 
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	/*
+	 * Explicit full memory barrier needed before/after
+	 */
+	smp_mb();
+
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	smp_mb();
+
+	return new;
+}
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		/*
+		 * Explicit full memory barrier needed before/after
+		 */
+		smp_mb();
+
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		smp_mb();
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 /*
  * "atomic" variant of xchg()
  * REQ: It needs to follow the same serialization rules as other atomic_xxx()
@@ -158,4 +201,18 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+
+/*
+ * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
+ * just to gaurantee semantics.
+ * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
+ * which also happens to be atomic_ops_lock.
+ *
+ * Thus despite semantically being different, implementation of atomic_cmpxchg()
+ * is same as cmpxchg().
+ */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
 #endif
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:35 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:35 +0200
Subject: [PATCH v5 16/20] ARC: [plat-eznps] Use dedicated SMP barriers
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-17-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..a559732 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,7 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +42,13 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:36 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:36 +0200
Subject: [PATCH v5 17/20] ARC: [plat-eznps] Use dedicated identity auxiliary
 register.
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-18-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 5d446df..6f4cb0d 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -67,9 +70,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -107,6 +117,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:37 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:37 +0200
Subject: [PATCH v5 18/20] ARC: [plat-eznps] Use dedicated cpu_relax()
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-19-git-send-email-noamc@ezchip.com>

From: Tal Zilcer <talz at ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Implementing cpu_relax_lowlatency() with barrier()
Since with current semantics of cpu_relax() it may take a
while till yielded CPU will get back.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 41142ab..974b878 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,9 +57,18 @@ struct task_struct;
  * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
  * get optimised away by gcc
  */
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
+#else
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#endif
 
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax_lowlatency() cpu_relax()
+#else
+#define cpu_relax_lowlatency() barrier()
+#endif
 
 #define copy_segments(tsk, mm)      do { } while (0)
 #define release_segments(mm)        do { } while (0)
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:38 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:38 +0200
Subject: [PATCH v5 19/20] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-20-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 05:23:39 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 15:23:39 +0200
Subject: [PATCH v5 20/20] ARC: Add eznps platform to Kconfig and Makefile
In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
Message-ID: <1451222619-3610-21-git-send-email-noamc@ezchip.com>

From: Noam Camus <noamc at ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 079946e..9d828a3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -92,6 +92,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index aeb1902..6212fea 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,11 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1



From noamc at ezchip.com  Sun Dec 27 13:41:05 2015
From: noamc at ezchip.com (Noam Camus)
Date: Sun, 27 Dec 2015 21:41:05 +0000
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <201512272200.4NfpC6DB%fengguang.wu@intel.com>
References: <1451222619-3610-5-git-send-email-noamc@ezchip.com>,
 <201512272200.4NfpC6DB%fengguang.wu@intel.com>
Message-ID: <HE1PR02MB13872391DF4E87BD2A7B7EC6D6FA0@HE1PR02MB1387.eurprd02.prod.outlook.com>

>From: kbuild test robot <lkp at intel.com>
>Sent: Sunday, December 27, 2015 4:55 PM

>[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
>Hi Noam,

>[auto build test ERROR on arc/for-next]
>[also build test ERROR on v4.4-rc6 next-20151223]

>url:    https://github.com/0day-ci/linux/commits/Noam-Camus/Adding-plat-eznps-to-ARC/20151227-220433
>base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next
>config: i386-allmodconfig (attached as .config)
>reproduce:
>       # save the attached .config to linux build tree
>      make ARCH=i386

This is meant for ARC only (not i386), I will add to the Kconfig file a dependency on my platform. 

-Noam

From daniel.lezcano at linaro.org  Mon Dec 28 01:00:04 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 28 Dec 2015 10:00:04 +0100
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <HE1PR02MB13872391DF4E87BD2A7B7EC6D6FA0@HE1PR02MB1387.eurprd02.prod.outlook.com>
References: <1451222619-3610-5-git-send-email-noamc@ezchip.com>
 <201512272200.4NfpC6DB%fengguang.wu@intel.com>
 <HE1PR02MB13872391DF4E87BD2A7B7EC6D6FA0@HE1PR02MB1387.eurprd02.prod.outlook.com>
Message-ID: <5680FA14.4010107@linaro.org>

On 12/27/2015 10:41 PM, Noam Camus wrote:
>> From: kbuild test robot <lkp at intel.com>
>> Sent: Sunday, December 27, 2015 4:55 PM
>
>> [if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
>> Hi Noam,
>
>> [auto build test ERROR on arc/for-next]
>> [also build test ERROR on v4.4-rc6 next-20151223]
>
>> url:    https://github.com/0day-ci/linux/commits/Noam-Camus/Adding-plat-eznps-to-ARC/20151227-220433
>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next
>> config: i386-allmodconfig (attached as .config)
>> reproduce:
>>        # save the attached .config to linux build tree
>>       make ARCH=i386
>
> This is meant for ARC only (not i386), I will add to the Kconfig file a dependency on my platform.

Hi Noam,

for compilation test coverage it would be nice to not restrict the to 
ARC only but change the write_aux_reg to a common name across the 
different arch if possible.

   -- Daniel


-- 
  <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



From lkp at intel.com  Sun Dec 27 06:55:23 2015
From: lkp at intel.com (kbuild test robot)
Date: Sun, 27 Dec 2015 22:55:23 +0800
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <1451222619-3610-5-git-send-email-noamc@ezchip.com>
Message-ID: <201512272200.4NfpC6DB%fengguang.wu@intel.com>

[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
Hi Noam,

[auto build test ERROR on arc/for-next]
[also build test ERROR on v4.4-rc6 next-20151223]

url:    https://github.com/0day-ci/linux/commits/Noam-Camus/Adding-plat-eznps-to-ARC/20151227-220433
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next
config: i386-allmodconfig (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/clocksource/timer-nps.c: In function 'nps_timer_event_setup':
>> drivers/clocksource/timer-nps.c:60:2: error: implicit declaration of function 'write_aux_reg' [-Werror=implicit-function-declaration]
     write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
     ^
   drivers/clocksource/timer-nps.c: In function 'nps_timer_cpu_notify':
>> drivers/clocksource/timer-nps.c:106:3: error: implicit declaration of function 'enable_percpu_irq' [-Werror=implicit-function-declaration]
      enable_percpu_irq(nps_timer_irq, 0);
      ^
>> drivers/clocksource/timer-nps.c:111:3: error: implicit declaration of function 'disable_percpu_irq' [-Werror=implicit-function-declaration]
      disable_percpu_irq(nps_timer_irq);
      ^
   drivers/clocksource/timer-nps.c: In function 'nps_setup_clocksource':
   drivers/clocksource/timer-nps.c:148:6: error: 'NPS_MSU_BLKID' undeclared (first use in this function)
         NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
         ^
   drivers/clocksource/timer-nps.c:148:6: note: each undeclared identifier is reported only once for each function it appears in
   drivers/clocksource/timer-nps.c: In function 'nps_setup_clockevents':
>> drivers/clocksource/timer-nps.c:176:8: error: implicit declaration of function 'request_percpu_irq' [-Werror=implicit-function-declaration]
     ret = request_percpu_irq(irq, nps_timer_irq_handler,
           ^
   cc1: some warnings being treated as errors

vim +/write_aux_reg +60 drivers/clocksource/timer-nps.c

    54		.mask   = CLOCKSOURCE_MASK(32),
    55		.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
    56	};
    57	
    58	static void nps_timer_event_setup(unsigned int cycles)
    59	{
  > 60		write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
    61		write_aux_reg(ARC_REG_TIMER0_CNT, 0);   /* start from 0 */
    62	
    63		write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
    64	}
    65	
    66	static int nps_clkevent_set_next_event(unsigned long delta,
    67					       struct clock_event_device *dev)
    68	{
    69		nps_timer_event_setup(delta);
    70		return 0;
    71	}
    72	
    73	static int nps_clkevent_set_periodic(struct clock_event_device *dev)
    74	{
    75		/*
    76		 * At X Hz, 1 sec = 1000ms -> X cycles;
    77		 *                    10ms -> X / 100 cycles
    78		 */
    79		nps_timer_event_setup(nps_timer_rate / HZ);
    80		return 0;
    81	}
    82	
    83	static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
    84		.name			= "nps_sys_timer",
    85		.features               = CLOCK_EVT_FEAT_ONESHOT |
    86					  CLOCK_EVT_FEAT_PERIODIC,
    87		.rating                 = 300,
    88		.set_next_event         = nps_clkevent_set_next_event,
    89		.set_state_periodic     = nps_clkevent_set_periodic,
    90	};
    91	
    92	static int nps_timer_cpu_notify(struct notifier_block *self,
    93					unsigned long action, void *hcpu)
    94	{
    95		struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
    96	
    97		evt->irq = nps_timer_irq;
    98		evt->cpumask = cpumask_of(smp_processor_id());
    99	
   100		/*
   101		 * Grab cpu pointer in each case to avoid spurious
   102		 * preemptible warnings
   103		 */
   104		switch (action & ~CPU_TASKS_FROZEN) {
   105		case CPU_STARTING:
 > 106			enable_percpu_irq(nps_timer_irq, 0);
   107			clockevents_config_and_register(evt, nps_timer_rate,
   108							0, ULONG_MAX);
   109			break;
   110		case CPU_DYING:
 > 111			disable_percpu_irq(nps_timer_irq);
   112			break;
   113		}
   114	
   115		return NOTIFY_OK;
   116	}
   117	
   118	static struct notifier_block nps_timer_cpu_nb = {
   119		.notifier_call = nps_timer_cpu_notify,
   120	};
   121	
   122	static irqreturn_t nps_timer_irq_handler(int irq, void *dev_id)
   123	{
   124		struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
   125		int irq_reenable = clockevent_state_periodic(evt);
   126	
   127		/*
   128		 * Any write to CTRL reg ACks the interrupt, we rewrite the
   129		 * Count when [N]ot [H]alted bit.
   130		 * And re-arm it if perioid by [I]nterrupt [E]nable bit
   131		 */
   132		write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH);
   133	
   134		evt->event_handler(evt);
   135	
   136		return IRQ_HANDLED;
   137	}
   138	
   139	static void __init nps_setup_clocksource(struct device_node *node,
   140						 struct clk *clk, int irq)
   141	{
   142		struct clocksource *clksrc = &nps_counter;
   143		int ret, cluster;
   144	
   145		for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
   146			nps_msu_reg_low_addr[cluster] =
   147				nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
   148					 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
   149	
   150		ret = clk_prepare_enable(clk);
   151		if (ret)
   152			pr_err("Couldn't enable parent clock\n");
   153	
   154		nps_timer_rate = clk_get_rate(clk);
   155	
   156		ret = clocksource_register_hz(clksrc, nps_timer_rate);
   157		if (ret)
   158			pr_err("Couldn't register clock source.\n");
   159	}
   160	
   161	static void __init nps_setup_clockevents(struct device_node *node,
   162						 struct clk *clk, int irq)
   163	{
   164		struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
   165		int ret;
   166	
   167		register_cpu_notifier(&nps_timer_cpu_nb);
   168	
   169		evt->irq = irq;
   170		evt->cpumask = cpumask_of(smp_processor_id());
   171	
   172		clockevents_config_and_register(evt, nps_timer_rate, 0, ULONG_MAX);
   173	
   174		enable_percpu_irq(irq, 0);
   175	
 > 176		ret = request_percpu_irq(irq, nps_timer_irq_handler,
   177					 "timer", evt);
   178		if (ret)
   179			pr_err("Unable to register interrupt\n");

---
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/octet-stream
Size: 52554 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-snps-arc/attachments/20151227/e70423e8/attachment-0001.obj>

From Vineet.Gupta1 at synopsys.com  Mon Dec 28 02:35:32 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Mon, 28 Dec 2015 16:05:32 +0530
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <5680FA14.4010107@linaro.org>
References: <1451222619-3610-5-git-send-email-noamc@ezchip.com>
 <201512272200.4NfpC6DB%fengguang.wu@intel.com>
 <HE1PR02MB13872391DF4E87BD2A7B7EC6D6FA0@HE1PR02MB1387.eurprd02.prod.outlook.com>
 <5680FA14.4010107@linaro.org>
Message-ID: <56811074.9020102@synopsys.com>

On Monday 28 December 2015 02:30 PM, Daniel Lezcano wrote:
>>> reproduce:
>>>        # save the attached .config to linux build tree
>>>       make ARCH=i386
>>
>> This is meant for ARC only (not i386), I will add to the Kconfig file a
>> dependency on my platform.
> 
> Hi Noam,
> 
> for compilation test coverage it would be nice to not restrict the to ARC only but
> change the write_aux_reg to a common name across the different arch if possible.
> 
>   -- Daniel

Hi Daniel,

AUX registers is a ARC specific mechanism used to access some of the core
functionality (intc, caches, ....) which other arches likely do via MMIO. I don't
think a generic abstraction exists. And IMHO it doesn't make sense to invent one
given this may not map directly to other arches.

This was one of the key reasons arc intc/timers were not added to drivers/* in
first place.

I do agree with compilation test coverage aspect though.
Maybe we add a *hack* to include/soc/nps/common.h

#ifndef __ARC__
#define  write_aux_reg(r, v)
#define  read_aux_reg(r) 0
#endif

What say you ?

-Vineet


From daniel.lezcano at linaro.org  Mon Dec 28 02:55:44 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 28 Dec 2015 11:55:44 +0100
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <56811074.9020102@synopsys.com>
References: <1451222619-3610-5-git-send-email-noamc@ezchip.com>
 <201512272200.4NfpC6DB%fengguang.wu@intel.com>
 <HE1PR02MB13872391DF4E87BD2A7B7EC6D6FA0@HE1PR02MB1387.eurprd02.prod.outlook.com>
 <5680FA14.4010107@linaro.org> <56811074.9020102@synopsys.com>
Message-ID: <56811530.7070504@linaro.org>

On 12/28/2015 11:35 AM, Vineet Gupta wrote:
> On Monday 28 December 2015 02:30 PM, Daniel Lezcano wrote:
>>>> reproduce:
>>>>         # save the attached .config to linux build tree
>>>>        make ARCH=i386
>>>
>>> This is meant for ARC only (not i386), I will add to the Kconfig file a
>>> dependency on my platform.
>>
>> Hi Noam,
>>
>> for compilation test coverage it would be nice to not restrict the to ARC only but
>> change the write_aux_reg to a common name across the different arch if possible.
>>
>>    -- Daniel
>
> Hi Daniel,
>
> AUX registers is a ARC specific mechanism used to access some of the core
> functionality (intc, caches, ....) which other arches likely do via MMIO. I don't
> think a generic abstraction exists. And IMHO it doesn't make sense to invent one
> given this may not map directly to other arches.
>
> This was one of the key reasons arc intc/timers were not added to drivers/* in
> first place.
>
> I do agree with compilation test coverage aspect though.
> Maybe we add a *hack* to include/soc/nps/common.h
>
> #ifndef __ARC__
> #define  write_aux_reg(r, v)
> #define  read_aux_reg(r) 0
> #endif
>
> What say you ?

Yes that's an alternative.

Perhaps instead of the __ARC__:

/*
  * Define dummy macros to let different architectures to
  * compile test some drivers, eg. the timer.
  */
#ifndef write_aux_reg
#define write_aux_reg(r, v)
#endif

#ifndef read_aux_reg
#define read_aux_reg(r) 0
#endif

Now that header must be included always *after* asm/arcregs.h.

Not sure this kind of implicit ordering is not prone to bug.

-- 
  <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



From Vineet.Gupta1 at synopsys.com  Mon Dec 28 03:11:14 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Mon, 28 Dec 2015 16:41:14 +0530
Subject: [PATCH v5 04/20] clocksource: Add NPS400 timers driver
In-Reply-To: <56811530.7070504@linaro.org>
References: <1451222619-3610-5-git-send-email-noamc@ezchip.com>
 <201512272200.4NfpC6DB%fengguang.wu@intel.com>
 <HE1PR02MB13872391DF4E87BD2A7B7EC6D6FA0@HE1PR02MB1387.eurprd02.prod.outlook.com>
 <5680FA14.4010107@linaro.org> <56811074.9020102@synopsys.com>
 <56811530.7070504@linaro.org>
Message-ID: <568118D2.9060709@synopsys.com>

On Monday 28 December 2015 04:25 PM, Daniel Lezcano wrote:
> On 12/28/2015 11:35 AM, Vineet Gupta wrote:
>> On Monday 28 December 2015 02:30 PM, Daniel Lezcano wrote:
>>>>> reproduce:
>>>>>         # save the attached .config to linux build tree
>>>>>        make ARCH=i386
>>>>
>>>> This is meant for ARC only (not i386), I will add to the Kconfig file a
>>>> dependency on my platform.
>>>
>>> Hi Noam,
>>>
>>> for compilation test coverage it would be nice to not restrict the to ARC only but
>>> change the write_aux_reg to a common name across the different arch if possible.
>>>
>>>    -- Daniel
>>
>> Hi Daniel,
>>
>> AUX registers is a ARC specific mechanism used to access some of the core
>> functionality (intc, caches, ....) which other arches likely do via MMIO. I don't
>> think a generic abstraction exists. And IMHO it doesn't make sense to invent one
>> given this may not map directly to other arches.
>>
>> This was one of the key reasons arc intc/timers were not added to drivers/* in
>> first place.
>>
>> I do agree with compilation test coverage aspect though.
>> Maybe we add a *hack* to include/soc/nps/common.h
>>
>> #ifndef __ARC__
>> #define  write_aux_reg(r, v)
>> #define  read_aux_reg(r) 0
>> #endif
>>
>> What say you ?
> 
> Yes that's an alternative.
> 
> Perhaps instead of the __ARC__:
> 
> /*
>  * Define dummy macros to let different architectures to
>  * compile test some drivers, eg. the timer.
>  */
> #ifndef write_aux_reg
> #define write_aux_reg(r, v)
> #endif
> 
> #ifndef read_aux_reg
> #define read_aux_reg(r) 0
> #endif
> 
> Now that header must be included always *after* asm/arcregs.h.
> 
> Not sure this kind of implicit ordering is not prone to bug.

Indeed, this all seems too fragile. The main point here is to allow building of
this code on !ARC and that can simply be done with my original proposal, w/o
adding any other ordering rules/dependencies for ARC builds !

-Vineet




From Vineet.Gupta1 at synopsys.com  Mon Dec 28 03:42:55 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Mon, 28 Dec 2015 17:12:55 +0530
Subject: [PATCH v5 09/20] ARC: IRQ: use device tree to get timer device
 configuration
In-Reply-To: <1451222619-3610-10-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-10-git-send-email-noamc@ezchip.com>
Message-ID: <5681203F.1010907@synopsys.com>

On Sunday 27 December 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> We've designated:
> TIMER0 for events (clockevents)
> TIMER1 for free running (clocksource)
> 
> Till now timer configuration was done on arch/arc/kernel/time.c
> with constant values.
> 
> This commit add device tree support so we can do this work
> at dedicated clocksource driver which parse the DT blob.
> 
> Such driver will get clocksource rate as well as interrupt line
> from DT and use them for setting clocksourcse and clockevents.
> 
> Note that lately called of_clk_init() is moved before we call
> clocksource_probe() since at that time device from DT
> need a "provider" (clocks) which will be available only after
> we call to of_clk_init().
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Acked-by: Vineet Gupta <vgupta at synopsys.com>

For patches which change semantically, ACK should not be copied over from prev
version. I do have some reservation with this patch.

I think we should just fix ARC once and for all by removing the legacy
registration. This would be a flag day change but I think we should be fine !
No point in keeping 2 implementations !

@Noam let me take a stab at it - OK !

-Vineet





From Vineet.Gupta1 at synopsys.com  Wed Dec 30 02:08:24 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 30 Dec 2015 15:38:24 +0530
Subject: [PATCH v5 05/20] irqchip: add nps Internal and external irqchips
In-Reply-To: <1451222619-3610-6-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-6-git-send-email-noamc@ezchip.com>
Message-ID: <5683AD18.7090603@synopsys.com>

On Sunday 27 December 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>

[snip..]

> +
> +static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
> +			  irq_hw_number_t hw)
> +{
> +	switch (hw) {
> +	case TIMER0_IRQ:
> +		irq_set_percpu_devid(virq);
> +		irq_set_chip_and_handler(virq, &nps400_irq_chip_percpu,
> +					 handle_percpu_devid_irq);
> +	break;
> +	default:
> +		irq_set_chip_and_handler(virq, &nps400_irq_chip_fasteoi,
> +					 handle_fasteoi_irq);
> +	break;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops nps400_irq_ops = {
> +	.xlate = irq_domain_xlate_onecell,
> +	.map = nps400_irq_map,
> +};
> +
> +static struct irq_domain *nps400_root_domain;
> +
> +static void nps400_handle_irq(unsigned int hwirq, struct pt_regs *regs)
> +{
> +	handle_domain_irq(nps400_root_domain, hwirq, regs);
> +}
> +
> +static int __init nps400_of_init(struct device_node *node,
> +				 struct device_node *parent)
> +{
> +	if (parent)
> +		panic("DeviceTree incore ic not a root irq controller\n");
> +
> +	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
> +						   &nps400_irq_ops, NULL);
> +
> +	if (!nps400_root_domain)
> +		panic("nps400 root irq domain not avail\n");
> +
> +	set_handle_irq(nps400_handle_irq);


Your series is NOT bisectable - u introduce this call later in series.
But do you need this song and dance anyways. Will handle_domain_irq() NOT work for
ARC in general for the core intc which are instantiated in legacy domain !

I'm ok with extra cost per int handling - given it is the right thing to do which
we've been missing so far !


> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
> 



From Vineet.Gupta1 at synopsys.com  Wed Dec 30 02:10:38 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 30 Dec 2015 15:40:38 +0530
Subject: [PATCH v5 10/20] ARC: IRQ: do not use hwirq directly at
 arch_do_IRQ()
In-Reply-To: <1451222619-3610-11-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-11-git-send-email-noamc@ezchip.com>
Message-ID: <5683AD9E.10501@synopsys.com>

On Sunday 27 December 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> ARC uses hwirq at arch_do_IRQ() to pass into generic_handle_irq().
> This is wrong since we need first to reverse map it into virq.
> 
> Happily, if we use handle_domain_irq() we get all we need.
> 
> Just like ARM I created a pointer to handler that should be filled
> by an interrupt controller driver from driver/irqchip/
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/Kconfig           |    1 +
>  arch/arc/include/asm/irq.h |    5 +++++
>  arch/arc/kernel/irq.c      |   14 ++++++++++++++
>  3 files changed, 20 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
> index 7be1020..079946e 100644
> --- a/arch/arc/Kconfig
> +++ b/arch/arc/Kconfig
> @@ -32,6 +32,7 @@ config ARC
>  	select HAVE_OPROFILE
>  	select HAVE_PERF_EVENTS
>  	select IRQ_DOMAIN
> +	select HANDLE_DOMAIN_IRQ if ARC_PLAT_EZNPS

On same lines as prev comment - just do this unconditionally for ARC port -
assuming this works with legacy domain as well.


>  	select MODULES_USE_ELF_RELA
>  	select NO_BOOTMEM
>  	select OF
> diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
> index c5f8f0f..64226c9 100644
> --- a/arch/arc/include/asm/irq.h
> +++ b/arch/arc/include/asm/irq.h
> @@ -36,4 +36,9 @@ void arc_request_percpu_irq(int irq, int cpu,
>                              irqreturn_t (*isr)(int irq, void *dev),
>                              const char *irq_nm, void *percpu_dev);
>  
> +#ifdef CONFIG_HANDLE_DOMAIN_IRQ
> +extern void set_handle_irq(void (*handle_irq)(unsigned int hwirq,
> +					      struct pt_regs *));
> +#endif

Not needed !

> +
>  #endif
> diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
> index ba17f85..7ae5411 100644
> --- a/arch/arc/kernel/irq.c
> +++ b/arch/arc/kernel/irq.c
> @@ -41,6 +41,7 @@ void __init init_IRQ(void)
>   * "C" Entry point for any ARC ISR, called from low level vector handler
>   * @irq is the vector number read from ICAUSE reg of on-chip intc
>   */
> +#ifndef CONFIG_HANDLE_DOMAIN_IRQ
>  void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
>  {
>  	struct pt_regs *old_regs = set_irq_regs(regs);
> @@ -50,6 +51,19 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
>  	irq_exit();
>  	set_irq_regs(old_regs);
>  }
> +#else
> +void (*handle_arch_irq)(unsigned int hwirq, struct pt_regs *) = NULL;
> +void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
> +{
> +	handle_arch_irq(irq, regs);
> +}
> +
> +void __init set_handle_irq(void (*handle_irq)(unsigned int hwirq,
> +					      struct pt_regs *))
> +{
> +	handle_arch_irq = handle_irq;
> +}
> +#endif
>  
>  /*
>   * API called for requesting percpu interrupts - called by each CPU
> 



From Vineet.Gupta1 at synopsys.com  Wed Dec 30 02:13:15 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 30 Dec 2015 15:43:15 +0530
Subject: [PATCH v5 11/20] ARC: IPI: do not use generic IRQ domain
In-Reply-To: <1451222619-3610-12-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-12-git-send-email-noamc@ezchip.com>
Message-ID: <5683AE3B.900@synopsys.com>

On Sunday 27 December 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> This behaviour is the desired one as been seen on other arch's.
> 
> We do not use generic irq domain and hence hwirq number is used
> directly by our code without any mapping to virq.
> In order to add IPI status to /proc/interrupts we use
> hardirq macros also we define arch_show_interrupts().
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/include/asm/Kbuild    |    1 -
>  arch/arc/include/asm/hardirq.h |   22 ++++++++++++++++++++++
>  arch/arc/include/asm/smp.h     |    6 ++++++
>  arch/arc/kernel/irq.c          |   13 ++++++++++++-
>  arch/arc/kernel/smp.c          |   27 +++++++++++++++++++++++++++
>  5 files changed, 67 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arc/include/asm/hardirq.h
> 
> diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
> index 0b10ef2..bbc3e4a 100644
> --- a/arch/arc/include/asm/Kbuild
> +++ b/arch/arc/include/asm/Kbuild
> @@ -10,7 +10,6 @@ generic-y += errno.h
>  generic-y += fb.h
>  generic-y += fcntl.h
>  generic-y += ftrace.h
> -generic-y += hardirq.h

So this is going backwards - copy/paste generic code into arch header
I don't understand why you need this !


>  generic-y += hw_irq.h
>  generic-y += ioctl.h
>  generic-y += ioctls.h
> diff --git a/arch/arc/include/asm/hardirq.h b/arch/arc/include/asm/hardirq.h
> new file mode 100644
> index 0000000..e83aa88
> --- /dev/null
> +++ b/arch/arc/include/asm/hardirq.h
> @@ -0,0 +1,22 @@
> +#ifndef __ASM_ARC_HARDIRQ_H
> +#define __ASM_ARC_HARDIRQ_H
> +
> +#include <linux/cache.h>
> +#include <linux/threads.h>
> +
> +typedef struct {
> +	unsigned int __softirq_pending;
> +#ifdef CONFIG_SMP
> +	unsigned int ipi_irqs;
> +#endif
> +} ____cacheline_aligned irq_cpustat_t;
> +
> +#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
> +#include <linux/irq.h>
> +
> +static inline void ack_bad_irq(unsigned int irq)
> +{
> +	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
> +}
> +
> +#endif /* __ASM_ARC_HARDIRQ_H */
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 9913804..9e4ec48 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -14,12 +14,16 @@
>  #include <linux/types.h>
>  #include <linux/init.h>
>  #include <linux/threads.h>
> +#include <asm/ptrace.h>
>  
>  #define raw_smp_processor_id() (current_thread_info()->cpu)
>  
>  /* including cpumask.h leads to cyclic deps hence this Forward declaration */
>  struct cpumask;
>  
> +/* including seq_file.h leads to cyclic deps hence this Forward declaration */
> +struct seq_file;
> +
>  /*
>   * APIs provided by arch SMP code to generic code
>   */
> @@ -32,6 +36,8 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
>  extern void __init smp_init_cpus(void);
>  extern void first_lines_of_secondary(void);
>  extern const char *arc_platform_smp_cpuinfo(void);
> +extern void arch_do_IPI(unsigned int irq, struct pt_regs *regs);
> +extern void show_ipi_list(struct seq_file *, int);
>  
>  /*
>   * API expected BY platform smp code (FROM arch smp code)
> diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
> index 7ae5411..c8d3c3d 100644
> --- a/arch/arc/kernel/irq.c
> +++ b/arch/arc/kernel/irq.c
> @@ -55,7 +55,10 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
>  void (*handle_arch_irq)(unsigned int hwirq, struct pt_regs *) = NULL;
>  void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
>  {
> -	handle_arch_irq(irq, regs);
> +	if (irq == IPI_IRQ)
> +		arch_do_IPI(irq, regs);
> +	else
> +		handle_arch_irq(irq, regs);
>  }
>  
>  void __init set_handle_irq(void (*handle_irq)(unsigned int hwirq,
> @@ -65,6 +68,14 @@ void __init set_handle_irq(void (*handle_irq)(unsigned int hwirq,
>  }
>  #endif
>  
> +int arch_show_interrupts(struct seq_file *p, int prec)
> +{
> +#ifdef CONFIG_SMP
> +	show_ipi_list(p, prec);
> +#endif
> +	return 0;
> +}
> +
>  /*
>   * API called for requesting percpu interrupts - called by each CPU
>   *  - For boot CPU, actually request the IRQ with genirq core + enables
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index ec6a5c1..8d37906 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -22,6 +22,7 @@
>  #include <linux/atomic.h>
>  #include <linux/cpumask.h>
>  #include <linux/reboot.h>
> +#include <linux/seq_file.h>
>  #include <asm/processor.h>
>  #include <asm/setup.h>
>  #include <asm/mach_desc.h>
> @@ -349,6 +350,32 @@ irqreturn_t do_IPI(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +void arch_do_IPI(unsigned int irq, struct pt_regs *regs)
> +{
> +	struct pt_regs *old_regs = set_irq_regs(regs);
> +	unsigned int cpu = smp_processor_id();
> +
> +	__IRQ_STAT(cpu, ipi_irqs)++;
> +
> +	irq_enter();
> +	do_IPI(irq, NULL);
> +	irq_exit();
> +
> +	set_irq_regs(old_regs);
> +}

WHY ?


> +
> +void show_ipi_list(struct seq_file *p, int prec)
> +{
> +	unsigned int cpu;
> +
> +	seq_printf(p, "%*s: ", prec - 1, "IPI");
> +
> +	for_each_online_cpu(cpu)
> +		seq_printf(p, "%10u ", __IRQ_STAT(cpu, ipi_irqs));
> +
> +	seq_printf(p, " %s\n", "IPI");
> +}
> +
>  /*
>   * API called by platform code to hookup arch-common ISR to their IPI IRQ
>   */
> 



From Vineet.Gupta1 at synopsys.com  Wed Dec 30 02:41:40 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 30 Dec 2015 16:11:40 +0530
Subject: [PATCH v5 05/20] irqchip: add nps Internal and external irqchips
In-Reply-To: <1451222619-3610-6-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-6-git-send-email-noamc@ezchip.com>
Message-ID: <5683B4E4.40101@synopsys.com>

On Sunday 27 December 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>

...

> +static struct irq_domain *nps400_root_domain;

This can simply be a local var now !

> +static void nps400_handle_irq(unsigned int hwirq, struct pt_regs *regs)
> +{
> +	handle_domain_irq(nps400_root_domain, hwirq, regs);
> +}
> +
> +static int __init nps400_of_init(struct device_node *node,
> +				 struct device_node *parent)
> +{
> +	if (parent)
> +		panic("DeviceTree incore ic not a root irq controller\n");
> +
> +	nps400_root_domain = irq_domain_add_linear(node, NR_CPU_IRQS,
> +						   &nps400_irq_ops, NULL);
> +
> +	if (!nps400_root_domain)
> +		panic("nps400 root irq domain not avail\n");
> +
> +	set_handle_irq(nps400_handle_irq);
> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
> 



From Vineet.Gupta1 at synopsys.com  Wed Dec 30 03:20:08 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 30 Dec 2015 16:50:08 +0530
Subject: [PATCH v5 09/20] ARC: IRQ: use device tree to get timer device
 configuration
In-Reply-To: <1451222619-3610-10-git-send-email-noamc@ezchip.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-10-git-send-email-noamc@ezchip.com>
Message-ID: <5683BDE8.4010200@synopsys.com>

On Sunday 27 December 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> We've designated:
> TIMER0 for events (clockevents)
> TIMER1 for free running (clocksource)
> 
> Till now timer configuration was done on arch/arc/kernel/time.c
> with constant values.
> 
> This commit add device tree support so we can do this work
> at dedicated clocksource driver which parse the DT blob.
> 
> Such driver will get clocksource rate as well as interrupt line
> from DT and use them for setting clocksourcse and clockevents.

Rephrase above part please...

Enable DT based clocksources/clockevents to be probed on ARC. Both clk and IRQ are
furnished by DT.

> 
> Note that lately called of_clk_init() is moved before we call
> clocksource_probe() since at that time device from DT
> need a "provider" (clocks) which will be available only after
> we call to of_clk_init().

Rephrase...

Also move of_clk_init() from a late'ish arch_initcall into time_init() to ensure
clocksource_probe() gets the "provide" clocks.


> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Acked-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  arch/arc/kernel/setup.c |    1 -
>  arch/arc/kernel/smp.c   |    2 ++
>  arch/arc/kernel/time.c  |    8 ++++++++
>  3 files changed, 10 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
> index e1b8744..4681e9c 100644
> --- a/arch/arc/kernel/setup.c
> +++ b/arch/arc/kernel/setup.c
> @@ -433,7 +433,6 @@ void __init setup_arch(char **cmdline_p)
>  
>  static int __init customize_machine(void)
>  {
> -	of_clk_init(NULL);
>  	/*
>  	 * Traverses flattened DeviceTree - registering platform devices
>  	 * (if any) complete with their resources
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 2cfe135..ec6a5c1 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -138,7 +138,9 @@ void start_kernel_secondary(void)
>  
>  	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
>  
> +#ifndef CONFIG_CLKSRC_OF
>  	arc_local_timer_setup();
> +#endif
>  
>  	local_irq_enable();
>  	preempt_disable();
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index dfad287..be6dd9e 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -38,6 +38,7 @@
>  #include <linux/init.h>
>  #include <linux/timex.h>
>  #include <linux/profile.h>
> +#include <linux/clk-provider.h>
>  #include <linux/clocksource.h>
>  #include <linux/clockchips.h>
>  #include <asm/irq.h>
> @@ -283,6 +284,13 @@ void __init time_init(void)
>  		 */
>  		clocksource_register_hz(&arc_counter, arc_get_core_freq());
>  
> +#ifdef CONFIG_COMMON_CLK
> +	of_clk_init(NULL);
> +#endif
> +#ifdef CONFIG_CLKSRC_OF
> +	clocksource_probe();
> +#else

You don't need the #ifdef for both as stub versions already exist.

>  	/* sets up the periodic event timer */
>  	arc_local_timer_setup();

simply do #ifndef CONFIG_CLKSRC_OF just as you do above.

I wanted to remove arc_local_timer_setup from ARC altogether and just switch over
to DT, but it seems I first need to figure out how the timer clk will work with
existing *hack* in plat-axs where we change the clk value for SMP / QUAD configs.

Perhaps needs a clk driver !


> +#endif
>  }
> 


From Vineet.Gupta1 at synopsys.com  Wed Dec 30 03:35:20 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Wed, 30 Dec 2015 17:05:20 +0530
Subject: [PATCH v4 05/19] irqchip: add nps Internal and external irqchips
In-Reply-To: <567434DF.2030201@arm.com>
References: <1450228238-4499-1-git-send-email-noamc@ezchip.com>
 <1450228238-4499-6-git-send-email-noamc@ezchip.com>
 <56712F50.6050404@arm.com>
 <DB5PR02MB1141324364E0253DAA030DF1D6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <5673EC2D.5040307@arm.com>
 <DB5PR02MB1141A1E0BE574A713957650BD6E10@DB5PR02MB1141.eurprd02.prod.outlook.com>
 <567434DF.2030201@arm.com>
Message-ID: <5683C178.7080706@synopsys.com>

On Friday 18 December 2015 10:01 PM, Marc Zyngier wrote:
> On 18/12/15 14:29, Noam Camus wrote:
>>> From: Marc Zyngier [mailto:marc.zyngier at arm.com] 
>>> Sent: Friday, December 18, 2015 1:21 PM
>>
>>>> I need this for my per CPU irqs such timer and IPI which do not come 
>>>> from some external device but from CPUs. For these IRQs I am calling 
>>>> to irq_create_mapping() from my platform at arch/arc and at that point 
>>>> I got no irqdomain and using irq_find_host() is not good since I got 
>>>> no device_node (at most I can have DT root).
>>
>>> That's a problem. You should never do that for your timer (doing a request_irq will do the right thing, and that's what your timer driver already does).
>>
>> Please be more specific, from all that I wrote what is the problem?
> 
> Calling irq_create_mapping out of the blue like you do it here:
> 
> +static void eznps_init_per_cpu(int cpu)
> +{
> +	/* Create mapping for all per cpu IRQs */
> +	if (cpu == 0) {
> +		irq_create_mapping(NULL, TIMER0_IRQ);
> +		irq_create_mapping(NULL, IPI_IRQ);
> +	}
> 
> is simply not acceptable.
> 
>> When I use request_irq() it fail without the mapping and mapping fail without a domain.
> 
> Grmbl...
> 
> That's not completely surprising:
> 
> +		timer {
> +			compatible = "ezchip,nps400-timer";
> +			clocks = <&sysclk>;
> +			clock-names="sysclk";
> +		};
> 
> Where is the interrupt?
> 
>> Never do what?
>> What should I do then?
> 
> Maybe you should start by looking how the other architectures have
> solved that exact problem at least half a dozen time.
> 
>>
>>> As for initializing your IPIs, they are usually outside of the IRQ
>>> space, so you should handle them separately (and get your irqchip
>>> to initialize them).
>> I am handling all my IRQs within same irqchip, which is the only one 
>> I have. So I am not sure what you expect here. Please be more 
>> elaborate.
> 
> Do not create a mapping for IPIs. Full stop. Handle them independently
> from your normal IRQs.
> 
>>>>
>>>> Another thing I'm not seeing here is where is the interrupt actually taken. This code only contains the EOI part, but not the ACK side, as well as the reverse lookup hwirq -> irq). Where is that code?
>>>>
>>>> ACK is an optional handler and is not needed by my platform.
>>>> I will add comment that since my IRQs are EOI based I do not need an ACK.
>>
>>> What I'm talking about is not the irq_ack method that the irqchip can provide, but the action your perform on your interrupt controller to extract the hwirq number and find out what corresponding Linux interrupt has fired.
>>
>>>>
>>>> I do not understand reverse lookup remark, where is it missing?
>>>> Could you point me to an example for such reverse lookup? 
>>
>>> See for example:
>>
>>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/irqchip/irq-sun4i.c#n136
>>
>>> This is the function (sun4i_handle_irq) that is executed almost immediately after the IRQ is asserted. The CPU reads the hwirq from the interrupt controller, and use handle_domain_irq() to call the corresponding handler (by doing a lookup in the domain).
>>
>>> I couldn't find out in your platform code where you are doing that.
>>
>> OK, this is seem much like exclusively ARM stuff.
> 
> No, this is not. Can you please stop looking at the surface of things
> and start taking an interest in how things actually *work*? Almost
> *nothing* in the interrupt handling code is architecture specific.
> 
>> Note that I am working with ARC (seem alike) here and we do not
>> define CONFIG_HANDLE_DOMAIN_IRQ and do not implement
>> set_handle_irq().
>>
>> So for ARC this reverse mapping is something we can leave without
>> (maybe because we are kind of a legacy domain).
> 
> Yeah, I just located the crap: arch_do_IRQ() happily takes a hwirq (the
> vector number), and uses that as a Linux IRQ. This looks a lot like ARM
> pre-DT, about 10 years ago.
> 
> Well, time to meet the 21st century. If you intend to use DT, please fix
> your arch port. Otherwise, just hardcode everything in your platform and
> don't pretend to support device tree.

Hi Marc,

Taking your rant in a positive stride and I'm all up for making this as
nice/modern as possible. I don't have issues with enabling
CONFIG_HANDLE_DOMAIN_IRQ for ARC (although it might add a few cycles o/h to each ISR)

However currently (4.4-rcX) it is only enabled for arm/arm64/openrisc and from the
looks of it in drivers/irqchip, only ARM based SoCs use the handle_domain_irq()
calls by plugging into ARM top level handler.

Why is that not a problem for other arches like PPC/MIPS which also use DT
heavily. Or perhaps they are also subtly broken as ARC is !

What am I missing ?

Thx,
-Vineet


From noamc at ezchip.com  Wed Dec 30 21:14:34 2015
From: noamc at ezchip.com (Noam Camus)
Date: Thu, 31 Dec 2015 05:14:34 +0000
Subject: [PATCH v5 11/20] ARC: IPI: do not use generic IRQ domain
In-Reply-To: <5683AE3B.900@synopsys.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-12-git-send-email-noamc@ezchip.com>,
 <5683AE3B.900@synopsys.com>
Message-ID: <HE1PR02MB1387ACCF6EA0EADEE8DE9817D6FE0@HE1PR02MB1387.eurprd02.prod.outlook.com>

>From: Vineet Gupta <Vineet.Gupta1 at synopsys.com>
>Sent: Wednesday, December 30, 2015 12:13 PM

>>  generic-y += fb.h
>>  generic-y += fcntl.h
>>  generic-y += ftrace.h
>> -generic-y += hardirq.h

>So this is going backwards - copy/paste generic code into arch header
I don't understand why you need this !

I need an extra field (ipi_irqs) at struct irq_cpustat_t and I cannot do this at asm-generic.

See below that how I use it to save and show status for each cpu

>> +void arch_do_IPI(unsigned int irq, struct pt_regs *regs)
>> +{
>> +     struct pt_regs *old_regs = set_irq_regs(regs);
>> +     unsigned int cpu = smp_processor_id();
>> +
>> +     __IRQ_STAT(cpu, ipi_irqs)++;
>> +
>> +     irq_enter();
>> +     do_IPI(irq, NULL);
>> +     irq_exit();
>> +
>> +     set_irq_regs(old_regs);
>> +}

>WHY ?

Please explain


From noamc at ezchip.com  Wed Dec 30 21:21:26 2015
From: noamc at ezchip.com (Noam Camus)
Date: Thu, 31 Dec 2015 05:21:26 +0000
Subject: [PATCH v5 10/20] ARC: IRQ: do not use hwirq directly at
 arch_do_IRQ()
In-Reply-To: <5683AD9E.10501@synopsys.com>
References: <1451222619-3610-1-git-send-email-noamc@ezchip.com>
 <1451222619-3610-11-git-send-email-noamc@ezchip.com>,
 <5683AD9E.10501@synopsys.com>
Message-ID: <HE1PR02MB138766FD1F3455F09AC8FD1BD6FE0@HE1PR02MB1387.eurprd02.prod.outlook.com>

>From: Vineet Gupta <Vineet.Gupta1 at synopsys.com>
>Sent: Wednesday, December 30, 2015 12:10 PM

>> --- a/arch/arc/Kconfig
>> +++ b/arch/arc/Kconfig
>> @@ -32,6 +32,7 @@ config ARC
>>       select HAVE_OPROFILE
>>       select HAVE_PERF_EVENTS
>>       select IRQ_DOMAIN
>> +     select HANDLE_DOMAIN_IRQ if ARC_PLAT_EZNPS

>On same lines as prev comment - just do this unconditionally for ARC port -
assuming this works with legacy domain as well.

Yes it should work for legacy domain.
On the other hand I can select it at the driver Kconfig itself and remove this line altogether.


>>
>> +#ifdef CONFIG_HANDLE_DOMAIN_IRQ
>> +extern void set_handle_irq(void (*handle_irq)(unsigned int hwirq,
>> +                                           struct pt_regs *));
>> +#endif

>Not needed !

I need to have it since we do not know at arch/arc/kernel/irq.c what is the domain allocated by the timer driver



