Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
@ 2017-08-13  4:36 Paul Burton
  2017-08-13  4:36 ` Paul Burton
                   ` (40 more replies)
  0 siblings, 41 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

This series cleans up the MIPS Global Interrupt Controller (GIC) driver
somewhat. It moves us towards using a header in a similar vein to the
ones we have for the MIPS Coherence Manager (CM) & Cluster Power
Controller (CPC) which allows us to access the GIC outside of the
irqchip driver - something beneficial already for the clocksource &
clock event driver, and which will be beneficial for further drivers
(eg. one for the GIC watchdog timer) and for multi-cluster work. Using
this header is also beneficial for consistency & code-sharing.

In addition to cleanups the series also optimises the driver in various
ways, including by using a per-CPU variable for pcpu_masks & removing
the need to read the GIC_SH_MASK_* registers when decoding interrupts in
gic_handle_shared_int().

This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
support" series to be applied first.


James Hogan (1):
  irqchip: mips-gic: SYNC after enabling GIC region

Paul Burton (37):
  MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  clocksource: mips-gic-timer: Use new GIC accessor functions
  irqchip: mips-gic: Remove counter access functions
  MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver
  irqchip: mips-gic: Remove gic_read_local_vp_id()
  lib/iomap_copy.c: Add __ioread64_copy
  irqchip: mips-gic: Simplify shared interrupt pending/mask reads
  irqchip: mips-gic: Simplify gic_local_irq_domain_map()
  irqchip: mips-gic: Drop gic_(re)set_mask() functions
  irqchip: mips-gic: Remove gic_set_polarity()
  irqchip: mips-gic: Remove gic_set_trigger()
  irqchip: mips-gic: Remove gic_set_dual_edge()
  irqchip: mips-gic: Remove gic_map_to_pin()
  irqchip: mips-gic: Remove gic_map_to_vpe()
  irqchip: mips-gic: Convert remaining shared reg access to new
    accessors
  irqchip: mips-gic: Convert local int mask access to new accessors
  irqchip: mips-gic: Convert remaining local reg access to new accessors
  MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h
  irqchip: mips-gic: Remove GIC_CPU_INT* macros
  irqchip: mips-gic: Move various definitions to the driver
  MIPS: VDSO: Drop gic_get_usm_range() usage
  irqchip: mips-gic: Remove gic_get_usm_range()
  irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration
  irqchip: mips-gic: Remove gic_init()
  MIPS: Use mips_gic_present() in place of gic_present
  irqchip: mips-gic: Remove gic_present
  irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h
  MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h
  MIPS: Remove unnecessary inclusions of linux/irqchip/mips-gic.h
  irqchip: mips-gic: Remove linux/irqchip/mips-gic.h
  irqchip: mips-gic: Inline __gic_init()
  irqchip: mips-gic: Inline gic_basic_init()
  irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling
  irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  irqchip: mips-gic: Let the core set struct irq_common_data affinity

 arch/mips/generic/irq.c                      |   8 +-
 arch/mips/include/asm/mips-boards/maltaint.h |   5 -
 arch/mips/include/asm/mips-cps.h             |   1 +
 arch/mips/include/asm/mips-gic.h             | 347 +++++++++++++++
 arch/mips/kernel/smp-cmp.c                   |   1 -
 arch/mips/kernel/smp-cps.c                   |   3 +-
 arch/mips/kernel/smp-mt.c                    |   6 +-
 arch/mips/kernel/vdso.c                      |  15 +-
 arch/mips/lantiq/irq.c                       |   4 -
 arch/mips/mti-malta/malta-int.c              |   4 +-
 arch/mips/mti-malta/malta-time.c             |  20 +-
 arch/mips/pistachio/irq.c                    |   1 -
 arch/mips/pistachio/time.c                   |   2 +-
 arch/mips/ralink/irq-gic.c                   |   2 +-
 arch/mips/vdso/gettimeofday.c                |   7 +-
 drivers/clocksource/mips-gic-timer.c         |  37 +-
 drivers/irqchip/irq-mips-gic.c               | 604 ++++++++-------------------
 include/linux/io.h                           |   1 +
 include/linux/irqchip/mips-gic.h             | 297 -------------
 lib/iomap_copy.c                             |  25 ++
 20 files changed, 609 insertions(+), 781 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-gic.h
 delete mode 100644 include/linux/irqchip/mips-gic.h

-- 
2.14.0

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

* [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36 ` [PATCH 01/38] irqchip: mips-gic: SYNC after enabling GIC region Paul Burton
                   ` (39 subsequent siblings)
  40 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

This series cleans up the MIPS Global Interrupt Controller (GIC) driver
somewhat. It moves us towards using a header in a similar vein to the
ones we have for the MIPS Coherence Manager (CM) & Cluster Power
Controller (CPC) which allows us to access the GIC outside of the
irqchip driver - something beneficial already for the clocksource &
clock event driver, and which will be beneficial for further drivers
(eg. one for the GIC watchdog timer) and for multi-cluster work. Using
this header is also beneficial for consistency & code-sharing.

In addition to cleanups the series also optimises the driver in various
ways, including by using a per-CPU variable for pcpu_masks & removing
the need to read the GIC_SH_MASK_* registers when decoding interrupts in
gic_handle_shared_int().

This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
support" series to be applied first.


James Hogan (1):
  irqchip: mips-gic: SYNC after enabling GIC region

Paul Burton (37):
  MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  clocksource: mips-gic-timer: Use new GIC accessor functions
  irqchip: mips-gic: Remove counter access functions
  MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver
  irqchip: mips-gic: Remove gic_read_local_vp_id()
  lib/iomap_copy.c: Add __ioread64_copy
  irqchip: mips-gic: Simplify shared interrupt pending/mask reads
  irqchip: mips-gic: Simplify gic_local_irq_domain_map()
  irqchip: mips-gic: Drop gic_(re)set_mask() functions
  irqchip: mips-gic: Remove gic_set_polarity()
  irqchip: mips-gic: Remove gic_set_trigger()
  irqchip: mips-gic: Remove gic_set_dual_edge()
  irqchip: mips-gic: Remove gic_map_to_pin()
  irqchip: mips-gic: Remove gic_map_to_vpe()
  irqchip: mips-gic: Convert remaining shared reg access to new
    accessors
  irqchip: mips-gic: Convert local int mask access to new accessors
  irqchip: mips-gic: Convert remaining local reg access to new accessors
  MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h
  irqchip: mips-gic: Remove GIC_CPU_INT* macros
  irqchip: mips-gic: Move various definitions to the driver
  MIPS: VDSO: Drop gic_get_usm_range() usage
  irqchip: mips-gic: Remove gic_get_usm_range()
  irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration
  irqchip: mips-gic: Remove gic_init()
  MIPS: Use mips_gic_present() in place of gic_present
  irqchip: mips-gic: Remove gic_present
  irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h
  MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h
  MIPS: Remove unnecessary inclusions of linux/irqchip/mips-gic.h
  irqchip: mips-gic: Remove linux/irqchip/mips-gic.h
  irqchip: mips-gic: Inline __gic_init()
  irqchip: mips-gic: Inline gic_basic_init()
  irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling
  irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  irqchip: mips-gic: Let the core set struct irq_common_data affinity

 arch/mips/generic/irq.c                      |   8 +-
 arch/mips/include/asm/mips-boards/maltaint.h |   5 -
 arch/mips/include/asm/mips-cps.h             |   1 +
 arch/mips/include/asm/mips-gic.h             | 347 +++++++++++++++
 arch/mips/kernel/smp-cmp.c                   |   1 -
 arch/mips/kernel/smp-cps.c                   |   3 +-
 arch/mips/kernel/smp-mt.c                    |   6 +-
 arch/mips/kernel/vdso.c                      |  15 +-
 arch/mips/lantiq/irq.c                       |   4 -
 arch/mips/mti-malta/malta-int.c              |   4 +-
 arch/mips/mti-malta/malta-time.c             |  20 +-
 arch/mips/pistachio/irq.c                    |   1 -
 arch/mips/pistachio/time.c                   |   2 +-
 arch/mips/ralink/irq-gic.c                   |   2 +-
 arch/mips/vdso/gettimeofday.c                |   7 +-
 drivers/clocksource/mips-gic-timer.c         |  37 +-
 drivers/irqchip/irq-mips-gic.c               | 604 ++++++++-------------------
 include/linux/io.h                           |   1 +
 include/linux/irqchip/mips-gic.h             | 297 -------------
 lib/iomap_copy.c                             |  25 ++
 20 files changed, 609 insertions(+), 781 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-gic.h
 delete mode 100644 include/linux/irqchip/mips-gic.h

-- 
2.14.0

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

* [PATCH 01/38] irqchip: mips-gic: SYNC after enabling GIC region
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
  2017-08-13  4:36 ` Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions Paul Burton
                   ` (38 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, James Hogan, Paul Burton, linux-kernel, stable

From: James Hogan <james.hogan@imgtec.com>

A SYNC is required between enabling the GIC region and actually trying
to use it, even if the first access is a read, otherwise its possible
depending on the timing (and in my case depending on the precise
alignment of certain kernel code) to hit CM bus errors on that first
access.

Add the SYNC straight after setting the GIC base.

[paul.burton@imgtec.com:
  Changes later in this series increase our likelihood of hitting this
  by reducing the amount of code that runs between enabling the GIC &
  accessing it.]

Fixes: a7057270c280 ("irqchip: mips-gic: Add device-tree support")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: <stable@vger.kernel.org> # 3.19.x-
---

 drivers/irqchip/irq-mips-gic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 9e984cefdca0..6841bd79c7c2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -1022,6 +1022,9 @@ static int __init gic_of_init(struct device_node *node,
 
 	if (mips_cm_present())
 		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
+		/* Ensure GIC region is enabled before trying to access it */
+		__sync();
+	}
 	gic_present = true;
 
 	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
-- 
2.14.0

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

* [PATCH 01/38] irqchip: mips-gic: SYNC after enabling GIC region
  2017-08-13  4:36 ` [PATCH 01/38] irqchip: mips-gic: SYNC after enabling GIC region Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, James Hogan, Paul Burton, linux-kernel, stable

From: James Hogan <james.hogan@imgtec.com>

A SYNC is required between enabling the GIC region and actually trying
to use it, even if the first access is a read, otherwise its possible
depending on the timing (and in my case depending on the precise
alignment of certain kernel code) to hit CM bus errors on that first
access.

Add the SYNC straight after setting the GIC base.

[paul.burton@imgtec.com:
  Changes later in this series increase our likelihood of hitting this
  by reducing the amount of code that runs between enabling the GIC &
  accessing it.]

Fixes: a7057270c280 ("irqchip: mips-gic: Add device-tree support")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: <stable@vger.kernel.org> # 3.19.x-
---

 drivers/irqchip/irq-mips-gic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 9e984cefdca0..6841bd79c7c2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -1022,6 +1022,9 @@ static int __init gic_of_init(struct device_node *node,
 
 	if (mips_cm_present())
 		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
+		/* Ensure GIC region is enabled before trying to access it */
+		__sync();
+	}
 	gic_present = true;
 
 	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
-- 
2.14.0

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

* [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
  2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36 ` [PATCH 01/38] irqchip: mips-gic: SYNC after enabling GIC region Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-18 11:10   ` Marc Zyngier
  2017-08-13  4:36 ` [PATCH 03/38] clocksource: mips-gic-timer: Use new GIC " Paul Burton
                   ` (37 subsequent siblings)
  40 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton, linux-kernel

This patch introduces a new header providing accessor functions for the
MIPS Global Interrupt Controller (GIC) mirroring those provided for the
other 2 components of the MIPS Coherent Processing System (CPS) - the
Coherence Manager (CM) & Cluster Power Controller (CPC).

This header makes use of the new standardised CPS accessor macros where
possible, but does require some custom accessors for cases where we have
either a bit or a register per interrupt.

A major advantage of this over the existing
include/linux/irqchip/mips-gic.h definitions is that code performing
accesses can become much simpler, for example this:

  gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
                  GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
                  (unsigned long)trig << GIC_INTR_BIT(intr));

...can become simply:

  change_gic_trig(intr, trig);

The accessors handle 32 vs 64 bit in the same way as for CM & CPC code,
which means that GIC code will also not need to worry about the access
size in most cases. They are also accessible outside of
drivers/irqchip/irq-mips-gic.c which will allow for simplification in
the use of the non-interrupt portions of the GIC (eg. counters) which
currently require the interrupt controller driver to expose helper
functions for access.

This patch doesn't change any existing code over to use the new
accessors yet, since a wholesale change would be invasive & difficult to
review. Instead follow-on patches will convert code piecemeal to use
this new header. The one change to existing code is to rename gic_base
to mips_gic_base & make it global, in order to fit in with the naming
expected by the standardised CPS accessor macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cps.h |   1 +
 arch/mips/include/asm/mips-gic.h | 293 +++++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-mips-gic.c   |  13 +-
 3 files changed, 300 insertions(+), 7 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-gic.h

diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 2dd737d803e1..bf02b5070a98 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -107,6 +107,7 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
 
 #include <asm/mips-cm.h>
 #include <asm/mips-cpc.h>
+#include <asm/mips-gic.h>
 
 /**
  * mips_cps_numclusters - return the number of clusters present in the system
diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
new file mode 100644
index 000000000000..8cf4bdc1a059
--- /dev/null
+++ b/arch/mips/include/asm/mips-gic.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+# error Please include asm/mips-cps.h rather than asm/mips-gic.h
+#endif
+
+#ifndef __MIPS_ASM_MIPS_GIC_H__
+#define __MIPS_ASM_MIPS_GIC_H__
+
+#include <linux/bitops.h>
+
+/* The base address of the GIC registers */
+extern void __iomem *mips_gic_base;
+
+/* Offsets from the GIC base address to various control blocks */
+#define MIPS_GIC_SHARED_OFS	0x00000
+#define MIPS_GIC_SHARED_SZ	0x08000
+#define MIPS_GIC_LOCAL_OFS	0x08000
+#define MIPS_GIC_LOCAL_SZ	0x04000
+#define MIPS_GIC_REDIR_OFS	0x0c000
+#define MIPS_GIC_REDIR_SZ	0x04000
+#define MIPS_GIC_USER_OFS	0x10000
+#define MIPS_GIC_USER_SZ	0x10000
+
+/* For read-only shared registers */
+#define GIC_ACCESSOR_RO(sz, off, name)					\
+	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
+
+/* For read-write shared registers */
+#define GIC_ACCESSOR_RW(sz, off, name)					\
+	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
+
+/* For read-only local registers */
+#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
+	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
+	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
+
+/* For read-write local registers */
+#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
+	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
+	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
+
+/* For read-only shared per-interrupt registers */
+#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
+static inline void __iomem *addr_gic_##name(unsigned int intr)		\
+{									\
+	return mips_gic_base + (off) + (intr * (stride));		\
+}									\
+									\
+static inline unsigned int read_gic_##name(unsigned int intr)		\
+{									\
+	BUILD_BUG_ON(sz != 32);						\
+	return __raw_readl(addr_gic_##name(intr));			\
+}
+
+/* For read-write shared per-interrupt registers */
+#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
+	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
+									\
+static inline void write_gic_##name(unsigned int intr,			\
+				    unsigned int val)			\
+{									\
+	BUILD_BUG_ON(sz != 32);						\
+	__raw_writel(val, addr_gic_##name(intr));			\
+}
+
+/* For read-only local per-interrupt registers */
+#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
+	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 stride, vl_##name)			\
+	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 stride, vo_##name)
+
+/* For read-write local per-interrupt registers */
+#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
+	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 stride, vl_##name)			\
+	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 stride, vo_##name)
+
+/* For read-only shared bit-per-interrupt registers */
+#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
+static inline void __iomem *addr_gic_##name(void)			\
+{									\
+	return mips_gic_base + (off);					\
+}									\
+									\
+static inline unsigned int read_gic_##name(unsigned int intr)		\
+{									\
+	void __iomem *addr = addr_gic_##name();				\
+	unsigned int val;						\
+									\
+	if (mips_cm_is64) {						\
+		addr += (intr / 64) * sizeof(uint64_t);			\
+		val = __raw_readq(addr) >> intr % 64;			\
+	} else {							\
+		addr += (intr / 32) * sizeof(uint32_t);			\
+		val = __raw_readl(addr) >> intr % 32;			\
+	}								\
+									\
+	return val & 0x1;						\
+}
+
+/* For read-write shared bit-per-interrupt registers */
+#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
+	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
+									\
+static inline void write_gic_##name(unsigned int intr)			\
+{									\
+	void __iomem *addr = addr_gic_##name();				\
+									\
+	if (mips_cm_is64) {						\
+		addr += (intr / 64) * sizeof(uint64_t);			\
+		__raw_writeq(BIT(intr % 64), addr);			\
+	} else {							\
+		addr += (intr / 32) * sizeof(uint32_t);			\
+		__raw_writel(BIT(intr % 32), addr);			\
+	}								\
+}									\
+									\
+static inline void change_gic_##name(unsigned int intr,			\
+				     unsigned int val)			\
+{									\
+	void __iomem *addr = addr_gic_##name();				\
+									\
+	if (mips_cm_is64) {						\
+		uint64_t _val;						\
+									\
+		addr += (intr / 64) * sizeof(uint64_t);			\
+		_val = __raw_readq(addr);				\
+		_val &= ~BIT_ULL(intr % 64);				\
+		_val |= (uint64_t)val << (intr % 64);			\
+		__raw_writeq(_val, addr);				\
+	} else {							\
+		uint32_t _val;						\
+									\
+		addr += (intr / 32) * sizeof(uint32_t);			\
+		_val = __raw_readl(addr);				\
+		_val &= ~BIT(intr % 32);				\
+		_val |= val << (intr % 32);				\
+		__raw_writel(_val, addr);				\
+	}								\
+}
+
+/* For read-only local bit-per-interrupt registers */
+#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name)			\
+	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 vl_##name)				\
+	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 vo_##name)
+
+/* For read-write local bit-per-interrupt registers */
+#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name)			\
+	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 vl_##name)				\
+	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 vo_##name)
+
+/* GIC_SH_CONFIG - Information about the GIC configuration */
+GIC_ACCESSOR_RW(32, 0x000, config)
+#define GIC_CONFIG_COUNTSTOP		BIT(28)
+#define GIC_CONFIG_COUNTBITS		GENMASK(27, 24)
+#define GIC_CONFIG_NUMINTERRUPTS	GENMASK(23, 16)
+#define GIC_CONFIG_PVPS			GENMASK(6, 0)
+
+/* GIC_SH_COUNTER - Shared global counter value */
+GIC_ACCESSOR_RW(64, 0x010, counter)
+GIC_ACCESSOR_RW(32, 0x010, counter_32l)
+GIC_ACCESSOR_RW(32, 0x014, counter_32h)
+
+/* GIC_SH_POL_* - Configures interrupt polarity */
+GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
+#define GIC_POL_ACTIVE_LOW		0	/* when level triggered */
+#define GIC_POL_ACTIVE_HIGH		1	/* when level triggered */
+#define GIC_POL_FALLING_EDGE		0	/* when single-edge triggered */
+#define GIC_POL_RISING_EDGE		1	/* when single-edge triggered */
+
+/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
+GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
+#define GIC_TRIG_LEVEL			0
+#define GIC_TRIG_EDGE			1
+
+/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
+GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
+#define GIC_DUAL_SINGLE			0	/* when edge-triggered */
+#define GIC_DUAL_DUAL			1	/* when edge-triggered */
+
+/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
+GIC_ACCESSOR_RW(32, 0x280, wedge)
+#define GIC_WEDGE_RW			BIT(31)
+#define GIC_WEDGE_INTR			GENMASK(7, 0)
+
+/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
+GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
+
+/* GIC_SH_SMASK_* - Set shared interrupt mask bits */
+GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
+
+/* GIC_SH_MASK_* - Read the current shared interrupt mask */
+GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
+
+/* GIC_SH_PEND_* - Read currently pending shared interrupts */
+GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
+
+/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
+GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
+#define GIC_MAP_PIN_MAP_TO_PIN		BIT(31)
+#define GIC_MAP_PIN_MAP_TO_NMI		BIT(30)
+#define GIC_MAP_PIN_MAP			GENMASK(5, 0)
+
+/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
+GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
+
+/* GIC_Vx_CTL - VP-level interrupt control */
+GIC_VX_ACCESSOR_RW(32, 0x000, ctl)
+#define GIC_VX_CTL_FDC_ROUTABLE		BIT(4)
+#define GIC_VX_CTL_SWINT_ROUTABLE	BIT(3)
+#define GIC_VX_CTL_PERFCNT_ROUTABLE	BIT(2)
+#define GIC_VX_CTL_TIMER_ROUTABLE	BIT(1)
+#define GIC_VX_CTL_EIC			BIT(0)
+
+/* GIC_Vx_PEND - Read currently pending local interrupts */
+GIC_VX_ACCESSOR_RO(32, 0x004, pend)
+
+/* GIC_Vx_MASK - Read the current local interrupt mask */
+GIC_VX_ACCESSOR_RO(32, 0x008, mask)
+
+/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
+GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
+
+/* GIC_Vx_SMASK - Set local interrupt mask bits */
+GIC_VX_ACCESSOR_RW(32, 0x010, smask)
+
+/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
+GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
+
+/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
+
+/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
+
+/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
+
+/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
+
+/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
+
+/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
+GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
+
+/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
+GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
+
+/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
+GIC_VX_ACCESSOR_RW(32, 0x080, other)
+#define GIC_VX_OTHER_VPNUM		GENMASK(5, 0)
+
+/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
+GIC_VX_ACCESSOR_RO(32, 0x088, ident)
+#define GIC_VX_IDENT_VPNUM		GENMASK(5, 0)
+
+/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
+GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
+
+/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
+GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
+
+/**
+ * mips_gic_present() - Determine whether a GIC is present
+ *
+ * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
+ * the system that the kernel is running on.
+ *
+ * Return true if a GIC is present, else false.
+ */
+static inline bool mips_gic_present(void)
+{
+	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
+}
+
+#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6841bd79c7c2..aaa4c046ccfe 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -24,14 +24,13 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 
 unsigned int gic_present;
+void __iomem *mips_gic_base;
 
 struct gic_pcpu_mask {
 	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
 };
 
 static unsigned long __gic_base_addr;
-
-static void __iomem *gic_base;
 static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
@@ -48,12 +47,12 @@ static void __gic_irq_dispatch(void);
 
 static inline u32 gic_read32(unsigned int reg)
 {
-	return __raw_readl(gic_base + reg);
+	return __raw_readl(mips_gic_base + reg);
 }
 
 static inline u64 gic_read64(unsigned int reg)
 {
-	return __raw_readq(gic_base + reg);
+	return __raw_readq(mips_gic_base + reg);
 }
 
 static inline unsigned long gic_read(unsigned int reg)
@@ -66,12 +65,12 @@ static inline unsigned long gic_read(unsigned int reg)
 
 static inline void gic_write32(unsigned int reg, u32 val)
 {
-	return __raw_writel(val, gic_base + reg);
+	return __raw_writel(val, mips_gic_base + reg);
 }
 
 static inline void gic_write64(unsigned int reg, u64 val)
 {
-	return __raw_writeq(val, gic_base + reg);
+	return __raw_writeq(val, mips_gic_base + reg);
 }
 
 static inline void gic_write(unsigned int reg, unsigned long val)
@@ -891,7 +890,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
 
 	__gic_base_addr = gic_base_addr;
 
-	gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
+	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
 	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
 	gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
-- 
2.14.0

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

* [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  2017-08-13  4:36 ` [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  2017-08-18 11:10   ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton, linux-kernel

This patch introduces a new header providing accessor functions for the
MIPS Global Interrupt Controller (GIC) mirroring those provided for the
other 2 components of the MIPS Coherent Processing System (CPS) - the
Coherence Manager (CM) & Cluster Power Controller (CPC).

This header makes use of the new standardised CPS accessor macros where
possible, but does require some custom accessors for cases where we have
either a bit or a register per interrupt.

A major advantage of this over the existing
include/linux/irqchip/mips-gic.h definitions is that code performing
accesses can become much simpler, for example this:

  gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
                  GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
                  (unsigned long)trig << GIC_INTR_BIT(intr));

...can become simply:

  change_gic_trig(intr, trig);

The accessors handle 32 vs 64 bit in the same way as for CM & CPC code,
which means that GIC code will also not need to worry about the access
size in most cases. They are also accessible outside of
drivers/irqchip/irq-mips-gic.c which will allow for simplification in
the use of the non-interrupt portions of the GIC (eg. counters) which
currently require the interrupt controller driver to expose helper
functions for access.

This patch doesn't change any existing code over to use the new
accessors yet, since a wholesale change would be invasive & difficult to
review. Instead follow-on patches will convert code piecemeal to use
this new header. The one change to existing code is to rename gic_base
to mips_gic_base & make it global, in order to fit in with the naming
expected by the standardised CPS accessor macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cps.h |   1 +
 arch/mips/include/asm/mips-gic.h | 293 +++++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-mips-gic.c   |  13 +-
 3 files changed, 300 insertions(+), 7 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-gic.h

diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 2dd737d803e1..bf02b5070a98 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -107,6 +107,7 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
 
 #include <asm/mips-cm.h>
 #include <asm/mips-cpc.h>
+#include <asm/mips-gic.h>
 
 /**
  * mips_cps_numclusters - return the number of clusters present in the system
diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
new file mode 100644
index 000000000000..8cf4bdc1a059
--- /dev/null
+++ b/arch/mips/include/asm/mips-gic.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+# error Please include asm/mips-cps.h rather than asm/mips-gic.h
+#endif
+
+#ifndef __MIPS_ASM_MIPS_GIC_H__
+#define __MIPS_ASM_MIPS_GIC_H__
+
+#include <linux/bitops.h>
+
+/* The base address of the GIC registers */
+extern void __iomem *mips_gic_base;
+
+/* Offsets from the GIC base address to various control blocks */
+#define MIPS_GIC_SHARED_OFS	0x00000
+#define MIPS_GIC_SHARED_SZ	0x08000
+#define MIPS_GIC_LOCAL_OFS	0x08000
+#define MIPS_GIC_LOCAL_SZ	0x04000
+#define MIPS_GIC_REDIR_OFS	0x0c000
+#define MIPS_GIC_REDIR_SZ	0x04000
+#define MIPS_GIC_USER_OFS	0x10000
+#define MIPS_GIC_USER_SZ	0x10000
+
+/* For read-only shared registers */
+#define GIC_ACCESSOR_RO(sz, off, name)					\
+	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
+
+/* For read-write shared registers */
+#define GIC_ACCESSOR_RW(sz, off, name)					\
+	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
+
+/* For read-only local registers */
+#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
+	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
+	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
+
+/* For read-write local registers */
+#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
+	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
+	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
+
+/* For read-only shared per-interrupt registers */
+#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
+static inline void __iomem *addr_gic_##name(unsigned int intr)		\
+{									\
+	return mips_gic_base + (off) + (intr * (stride));		\
+}									\
+									\
+static inline unsigned int read_gic_##name(unsigned int intr)		\
+{									\
+	BUILD_BUG_ON(sz != 32);						\
+	return __raw_readl(addr_gic_##name(intr));			\
+}
+
+/* For read-write shared per-interrupt registers */
+#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
+	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
+									\
+static inline void write_gic_##name(unsigned int intr,			\
+				    unsigned int val)			\
+{									\
+	BUILD_BUG_ON(sz != 32);						\
+	__raw_writel(val, addr_gic_##name(intr));			\
+}
+
+/* For read-only local per-interrupt registers */
+#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
+	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 stride, vl_##name)			\
+	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 stride, vo_##name)
+
+/* For read-write local per-interrupt registers */
+#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
+	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 stride, vl_##name)			\
+	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 stride, vo_##name)
+
+/* For read-only shared bit-per-interrupt registers */
+#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
+static inline void __iomem *addr_gic_##name(void)			\
+{									\
+	return mips_gic_base + (off);					\
+}									\
+									\
+static inline unsigned int read_gic_##name(unsigned int intr)		\
+{									\
+	void __iomem *addr = addr_gic_##name();				\
+	unsigned int val;						\
+									\
+	if (mips_cm_is64) {						\
+		addr += (intr / 64) * sizeof(uint64_t);			\
+		val = __raw_readq(addr) >> intr % 64;			\
+	} else {							\
+		addr += (intr / 32) * sizeof(uint32_t);			\
+		val = __raw_readl(addr) >> intr % 32;			\
+	}								\
+									\
+	return val & 0x1;						\
+}
+
+/* For read-write shared bit-per-interrupt registers */
+#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
+	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
+									\
+static inline void write_gic_##name(unsigned int intr)			\
+{									\
+	void __iomem *addr = addr_gic_##name();				\
+									\
+	if (mips_cm_is64) {						\
+		addr += (intr / 64) * sizeof(uint64_t);			\
+		__raw_writeq(BIT(intr % 64), addr);			\
+	} else {							\
+		addr += (intr / 32) * sizeof(uint32_t);			\
+		__raw_writel(BIT(intr % 32), addr);			\
+	}								\
+}									\
+									\
+static inline void change_gic_##name(unsigned int intr,			\
+				     unsigned int val)			\
+{									\
+	void __iomem *addr = addr_gic_##name();				\
+									\
+	if (mips_cm_is64) {						\
+		uint64_t _val;						\
+									\
+		addr += (intr / 64) * sizeof(uint64_t);			\
+		_val = __raw_readq(addr);				\
+		_val &= ~BIT_ULL(intr % 64);				\
+		_val |= (uint64_t)val << (intr % 64);			\
+		__raw_writeq(_val, addr);				\
+	} else {							\
+		uint32_t _val;						\
+									\
+		addr += (intr / 32) * sizeof(uint32_t);			\
+		_val = __raw_readl(addr);				\
+		_val &= ~BIT(intr % 32);				\
+		_val |= val << (intr % 32);				\
+		__raw_writel(_val, addr);				\
+	}								\
+}
+
+/* For read-only local bit-per-interrupt registers */
+#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name)			\
+	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 vl_##name)				\
+	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 vo_##name)
+
+/* For read-write local bit-per-interrupt registers */
+#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name)			\
+	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
+				 vl_##name)				\
+	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
+				 vo_##name)
+
+/* GIC_SH_CONFIG - Information about the GIC configuration */
+GIC_ACCESSOR_RW(32, 0x000, config)
+#define GIC_CONFIG_COUNTSTOP		BIT(28)
+#define GIC_CONFIG_COUNTBITS		GENMASK(27, 24)
+#define GIC_CONFIG_NUMINTERRUPTS	GENMASK(23, 16)
+#define GIC_CONFIG_PVPS			GENMASK(6, 0)
+
+/* GIC_SH_COUNTER - Shared global counter value */
+GIC_ACCESSOR_RW(64, 0x010, counter)
+GIC_ACCESSOR_RW(32, 0x010, counter_32l)
+GIC_ACCESSOR_RW(32, 0x014, counter_32h)
+
+/* GIC_SH_POL_* - Configures interrupt polarity */
+GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
+#define GIC_POL_ACTIVE_LOW		0	/* when level triggered */
+#define GIC_POL_ACTIVE_HIGH		1	/* when level triggered */
+#define GIC_POL_FALLING_EDGE		0	/* when single-edge triggered */
+#define GIC_POL_RISING_EDGE		1	/* when single-edge triggered */
+
+/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
+GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
+#define GIC_TRIG_LEVEL			0
+#define GIC_TRIG_EDGE			1
+
+/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
+GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
+#define GIC_DUAL_SINGLE			0	/* when edge-triggered */
+#define GIC_DUAL_DUAL			1	/* when edge-triggered */
+
+/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
+GIC_ACCESSOR_RW(32, 0x280, wedge)
+#define GIC_WEDGE_RW			BIT(31)
+#define GIC_WEDGE_INTR			GENMASK(7, 0)
+
+/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
+GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
+
+/* GIC_SH_SMASK_* - Set shared interrupt mask bits */
+GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
+
+/* GIC_SH_MASK_* - Read the current shared interrupt mask */
+GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
+
+/* GIC_SH_PEND_* - Read currently pending shared interrupts */
+GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
+
+/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
+GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
+#define GIC_MAP_PIN_MAP_TO_PIN		BIT(31)
+#define GIC_MAP_PIN_MAP_TO_NMI		BIT(30)
+#define GIC_MAP_PIN_MAP			GENMASK(5, 0)
+
+/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
+GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
+
+/* GIC_Vx_CTL - VP-level interrupt control */
+GIC_VX_ACCESSOR_RW(32, 0x000, ctl)
+#define GIC_VX_CTL_FDC_ROUTABLE		BIT(4)
+#define GIC_VX_CTL_SWINT_ROUTABLE	BIT(3)
+#define GIC_VX_CTL_PERFCNT_ROUTABLE	BIT(2)
+#define GIC_VX_CTL_TIMER_ROUTABLE	BIT(1)
+#define GIC_VX_CTL_EIC			BIT(0)
+
+/* GIC_Vx_PEND - Read currently pending local interrupts */
+GIC_VX_ACCESSOR_RO(32, 0x004, pend)
+
+/* GIC_Vx_MASK - Read the current local interrupt mask */
+GIC_VX_ACCESSOR_RO(32, 0x008, mask)
+
+/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
+GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
+
+/* GIC_Vx_SMASK - Set local interrupt mask bits */
+GIC_VX_ACCESSOR_RW(32, 0x010, smask)
+
+/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
+GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
+
+/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
+
+/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
+
+/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
+
+/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
+
+/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
+GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
+
+/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
+GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
+
+/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
+GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
+
+/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
+GIC_VX_ACCESSOR_RW(32, 0x080, other)
+#define GIC_VX_OTHER_VPNUM		GENMASK(5, 0)
+
+/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
+GIC_VX_ACCESSOR_RO(32, 0x088, ident)
+#define GIC_VX_IDENT_VPNUM		GENMASK(5, 0)
+
+/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
+GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
+
+/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
+GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
+
+/**
+ * mips_gic_present() - Determine whether a GIC is present
+ *
+ * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
+ * the system that the kernel is running on.
+ *
+ * Return true if a GIC is present, else false.
+ */
+static inline bool mips_gic_present(void)
+{
+	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
+}
+
+#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6841bd79c7c2..aaa4c046ccfe 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -24,14 +24,13 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 
 unsigned int gic_present;
+void __iomem *mips_gic_base;
 
 struct gic_pcpu_mask {
 	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
 };
 
 static unsigned long __gic_base_addr;
-
-static void __iomem *gic_base;
 static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
@@ -48,12 +47,12 @@ static void __gic_irq_dispatch(void);
 
 static inline u32 gic_read32(unsigned int reg)
 {
-	return __raw_readl(gic_base + reg);
+	return __raw_readl(mips_gic_base + reg);
 }
 
 static inline u64 gic_read64(unsigned int reg)
 {
-	return __raw_readq(gic_base + reg);
+	return __raw_readq(mips_gic_base + reg);
 }
 
 static inline unsigned long gic_read(unsigned int reg)
@@ -66,12 +65,12 @@ static inline unsigned long gic_read(unsigned int reg)
 
 static inline void gic_write32(unsigned int reg, u32 val)
 {
-	return __raw_writel(val, gic_base + reg);
+	return __raw_writel(val, mips_gic_base + reg);
 }
 
 static inline void gic_write64(unsigned int reg, u64 val)
 {
-	return __raw_writeq(val, gic_base + reg);
+	return __raw_writeq(val, mips_gic_base + reg);
 }
 
 static inline void gic_write(unsigned int reg, unsigned long val)
@@ -891,7 +890,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
 
 	__gic_base_addr = gic_base_addr;
 
-	gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
+	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
 	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
 	gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
-- 
2.14.0

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

* [PATCH 03/38] clocksource: mips-gic-timer: Use new GIC accessor functions
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (2 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 04/38] irqchip: mips-gic: Remove counter access functions Paul Burton
                   ` (36 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton, Daniel Lezcano

Switch from calling functions exported by the GIC interrupt controller
to using new accessors provided by asm/mips-gic.h. This will allow the
counter-handling functionality to be removed from the interrupt
controller driver, where it doesn't really belong, and also allow for
inlining of the accesses to the GIC.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/clocksource/mips-gic-timer.c | 37 ++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 17b861ea2626..ae3167c28b12 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -10,25 +10,45 @@
 #include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/notifier.h>
 #include <linux/of_irq.h>
 #include <linux/percpu.h>
 #include <linux/smp.h>
 #include <linux/time.h>
+#include <asm/mips-cps.h>
 
 static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
 static int gic_timer_irq;
 static unsigned int gic_frequency;
 
+static u64 notrace gic_read_count(void)
+{
+	unsigned int hi, hi2, lo;
+
+	if (mips_cm_is64)
+		return read_gic_counter();
+
+	do {
+		hi = read_gic_counter_32h();
+		lo = read_gic_counter_32l();
+		hi2 = read_gic_counter_32h();
+	} while (hi2 != hi);
+
+	return (((u64) hi) << 32) + lo;
+}
+
 static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
 {
+	unsigned long flags;
 	u64 cnt;
 	int res;
 
 	cnt = gic_read_count();
 	cnt += (u64)delta;
-	gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
+	local_irq_save(flags);
+	write_gic_vl_other(mips_cm_vp_id(cpumask_first(evt->cpumask)));
+	write_gic_vo_compare(cnt);
+	local_irq_restore(flags);
 	res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
 	return res;
 }
@@ -37,7 +57,7 @@ static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *cd = dev_id;
 
-	gic_write_compare(gic_read_compare());
+	write_gic_vl_compare(read_gic_vl_compare());
 	cd->event_handler(cd);
 	return IRQ_HANDLED;
 }
@@ -139,10 +159,15 @@ static struct clocksource gic_clocksource = {
 
 static int __init __gic_clocksource_init(void)
 {
+	unsigned int count_width;
 	int ret;
 
 	/* Set clocksource mask. */
-	gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());
+	count_width = read_gic_config() & GIC_CONFIG_COUNTBITS;
+	count_width >>= __fls(GIC_CONFIG_COUNTBITS);
+	count_width *= 4;
+	count_width += 32;
+	gic_clocksource.mask = CLOCKSOURCE_MASK(count_width);
 
 	/* Calculate a somewhat reasonable rating value. */
 	gic_clocksource.rating = 200 + gic_frequency / 10000000;
@@ -159,7 +184,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
 	struct clk *clk;
 	int ret;
 
-	if (!gic_present || !node->parent ||
+	if (!mips_gic_present() || !node->parent ||
 	    !of_device_is_compatible(node->parent, "mti,gic")) {
 		pr_warn("No DT definition for the mips gic driver\n");
 		return -ENXIO;
@@ -197,7 +222,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
 	}
 
 	/* And finally start the counter */
-	gic_start_count();
+	clear_gic_config(GIC_CONFIG_COUNTSTOP);
 
 	return 0;
 }
-- 
2.14.0

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

* [PATCH 03/38] clocksource: mips-gic-timer: Use new GIC accessor functions
  2017-08-13  4:36 ` [PATCH 03/38] clocksource: mips-gic-timer: Use new GIC " Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton, Daniel Lezcano

Switch from calling functions exported by the GIC interrupt controller
to using new accessors provided by asm/mips-gic.h. This will allow the
counter-handling functionality to be removed from the interrupt
controller driver, where it doesn't really belong, and also allow for
inlining of the accesses to the GIC.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/clocksource/mips-gic-timer.c | 37 ++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 17b861ea2626..ae3167c28b12 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -10,25 +10,45 @@
 #include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/notifier.h>
 #include <linux/of_irq.h>
 #include <linux/percpu.h>
 #include <linux/smp.h>
 #include <linux/time.h>
+#include <asm/mips-cps.h>
 
 static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
 static int gic_timer_irq;
 static unsigned int gic_frequency;
 
+static u64 notrace gic_read_count(void)
+{
+	unsigned int hi, hi2, lo;
+
+	if (mips_cm_is64)
+		return read_gic_counter();
+
+	do {
+		hi = read_gic_counter_32h();
+		lo = read_gic_counter_32l();
+		hi2 = read_gic_counter_32h();
+	} while (hi2 != hi);
+
+	return (((u64) hi) << 32) + lo;
+}
+
 static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
 {
+	unsigned long flags;
 	u64 cnt;
 	int res;
 
 	cnt = gic_read_count();
 	cnt += (u64)delta;
-	gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
+	local_irq_save(flags);
+	write_gic_vl_other(mips_cm_vp_id(cpumask_first(evt->cpumask)));
+	write_gic_vo_compare(cnt);
+	local_irq_restore(flags);
 	res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
 	return res;
 }
@@ -37,7 +57,7 @@ static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *cd = dev_id;
 
-	gic_write_compare(gic_read_compare());
+	write_gic_vl_compare(read_gic_vl_compare());
 	cd->event_handler(cd);
 	return IRQ_HANDLED;
 }
@@ -139,10 +159,15 @@ static struct clocksource gic_clocksource = {
 
 static int __init __gic_clocksource_init(void)
 {
+	unsigned int count_width;
 	int ret;
 
 	/* Set clocksource mask. */
-	gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());
+	count_width = read_gic_config() & GIC_CONFIG_COUNTBITS;
+	count_width >>= __fls(GIC_CONFIG_COUNTBITS);
+	count_width *= 4;
+	count_width += 32;
+	gic_clocksource.mask = CLOCKSOURCE_MASK(count_width);
 
 	/* Calculate a somewhat reasonable rating value. */
 	gic_clocksource.rating = 200 + gic_frequency / 10000000;
@@ -159,7 +184,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
 	struct clk *clk;
 	int ret;
 
-	if (!gic_present || !node->parent ||
+	if (!mips_gic_present() || !node->parent ||
 	    !of_device_is_compatible(node->parent, "mti,gic")) {
 		pr_warn("No DT definition for the mips gic driver\n");
 		return -ENXIO;
@@ -197,7 +222,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
 	}
 
 	/* And finally start the counter */
-	gic_start_count();
+	clear_gic_config(GIC_CONFIG_COUNTSTOP);
 
 	return 0;
 }
-- 
2.14.0

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

* [PATCH 04/38] irqchip: mips-gic: Remove counter access functions
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (3 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 03/38] clocksource: mips-gic-timer: Use new GIC " Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 05/38] MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver Paul Burton
                   ` (35 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The MIPS GIC clocksource driver is no longer using the accessor
functions provided by the irqchip driver, so remove them.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 95 ----------------------------------------
 include/linux/irqchip/mips-gic.h | 22 ----------
 2 files changed, 117 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index aaa4c046ccfe..e49d48438626 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -138,101 +138,6 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 		  GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
 }
 
-#ifdef CONFIG_CLKSRC_MIPS_GIC
-u64 notrace gic_read_count(void)
-{
-	unsigned int hi, hi2, lo;
-
-	if (mips_cm_is64)
-		return (u64)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
-
-	do {
-		hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
-		lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
-		hi2 = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
-	} while (hi2 != hi);
-
-	return (((u64) hi) << 32) + lo;
-}
-
-unsigned int gic_get_count_width(void)
-{
-	unsigned int bits, config;
-
-	config = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
-			 GIC_SH_CONFIG_COUNTBITS_SHF);
-
-	return bits;
-}
-
-void notrace gic_write_compare(u64 cnt)
-{
-	if (mips_cm_is64) {
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
-	} else {
-		gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
-					(int)(cnt >> 32));
-		gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
-					(int)(cnt & 0xffffffff));
-	}
-}
-
-void notrace gic_write_cpu_compare(u64 cnt, int cpu)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), mips_cm_vp_id(cpu));
-
-	if (mips_cm_is64) {
-		gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt);
-	} else {
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
-					(int)(cnt >> 32));
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
-					(int)(cnt & 0xffffffff));
-	}
-
-	local_irq_restore(flags);
-}
-
-u64 gic_read_compare(void)
-{
-	unsigned int hi, lo;
-
-	if (mips_cm_is64)
-		return (u64)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
-
-	hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
-	lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
-
-	return (((u64) hi) << 32) + lo;
-}
-
-void gic_start_count(void)
-{
-	u32 gicconfig;
-
-	/* Start the counter */
-	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	gicconfig &= ~(1 << GIC_SH_CONFIG_COUNTSTOP_SHF);
-	gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
-}
-
-void gic_stop_count(void)
-{
-	u32 gicconfig;
-
-	/* Stop the counter */
-	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	gicconfig |= 1 << GIC_SH_CONFIG_COUNTSTOP_SHF;
-	gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
-}
-
-#endif
-
 unsigned gic_read_local_vp_id(void)
 {
 	unsigned long ident;
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 2b0e56619e53..c9e1c993cf5b 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -40,11 +40,6 @@
 
 #define GIC_SH_CONFIG_OFS		0x0000
 
-/* Shared Global Counter */
-#define GIC_SH_COUNTER_31_00_OFS	0x0010
-/* 64-bit counter register for CM3 */
-#define GIC_SH_COUNTER_OFS		GIC_SH_COUNTER_31_00_OFS
-#define GIC_SH_COUNTER_63_32_OFS	0x0014
 #define GIC_SH_REVISIONID_OFS		0x0020
 
 /* Convert an interrupt number to a byte offset/bit for multi-word registers */
@@ -107,10 +102,6 @@
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
 #define GIC_VPE_WD_INITIAL0_OFS		0x0098
-#define GIC_VPE_COMPARE_LO_OFS		0x00a0
-/* 64-bit Compare register on CM3 */
-#define GIC_VPE_COMPARE_OFS		GIC_VPE_COMPARE_LO_OFS
-#define GIC_VPE_COMPARE_HI_OFS		0x00a4
 
 #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS	0x0100
 #define GIC_VPE_EIC_SS(intr)		(4 * (intr))
@@ -128,12 +119,6 @@
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
 /* Masks */
-#define GIC_SH_CONFIG_COUNTSTOP_SHF	28
-#define GIC_SH_CONFIG_COUNTSTOP_MSK	(MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
-
-#define GIC_SH_CONFIG_COUNTBITS_SHF	24
-#define GIC_SH_CONFIG_COUNTBITS_MSK	(MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
-
 #define GIC_SH_CONFIG_NUMINTRS_SHF	16
 #define GIC_SH_CONFIG_NUMINTRS_MSK	(MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
 
@@ -258,13 +243,6 @@ extern unsigned int gic_present;
 extern void gic_init(unsigned long gic_base_addr,
 	unsigned long gic_addrspace_size, unsigned int cpu_vec,
 	unsigned int irqbase);
-extern u64 gic_read_count(void);
-extern unsigned int gic_get_count_width(void);
-extern u64 gic_read_compare(void);
-extern void gic_write_compare(u64 cnt);
-extern void gic_write_cpu_compare(u64 cnt, int cpu);
-extern void gic_start_count(void);
-extern void gic_stop_count(void);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
-- 
2.14.0

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

* [PATCH 04/38] irqchip: mips-gic: Remove counter access functions
  2017-08-13  4:36 ` [PATCH 04/38] irqchip: mips-gic: Remove counter access functions Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The MIPS GIC clocksource driver is no longer using the accessor
functions provided by the irqchip driver, so remove them.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 95 ----------------------------------------
 include/linux/irqchip/mips-gic.h | 22 ----------
 2 files changed, 117 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index aaa4c046ccfe..e49d48438626 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -138,101 +138,6 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 		  GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
 }
 
-#ifdef CONFIG_CLKSRC_MIPS_GIC
-u64 notrace gic_read_count(void)
-{
-	unsigned int hi, hi2, lo;
-
-	if (mips_cm_is64)
-		return (u64)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
-
-	do {
-		hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
-		lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
-		hi2 = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
-	} while (hi2 != hi);
-
-	return (((u64) hi) << 32) + lo;
-}
-
-unsigned int gic_get_count_width(void)
-{
-	unsigned int bits, config;
-
-	config = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
-			 GIC_SH_CONFIG_COUNTBITS_SHF);
-
-	return bits;
-}
-
-void notrace gic_write_compare(u64 cnt)
-{
-	if (mips_cm_is64) {
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
-	} else {
-		gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
-					(int)(cnt >> 32));
-		gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
-					(int)(cnt & 0xffffffff));
-	}
-}
-
-void notrace gic_write_cpu_compare(u64 cnt, int cpu)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), mips_cm_vp_id(cpu));
-
-	if (mips_cm_is64) {
-		gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt);
-	} else {
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
-					(int)(cnt >> 32));
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
-					(int)(cnt & 0xffffffff));
-	}
-
-	local_irq_restore(flags);
-}
-
-u64 gic_read_compare(void)
-{
-	unsigned int hi, lo;
-
-	if (mips_cm_is64)
-		return (u64)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
-
-	hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
-	lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
-
-	return (((u64) hi) << 32) + lo;
-}
-
-void gic_start_count(void)
-{
-	u32 gicconfig;
-
-	/* Start the counter */
-	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	gicconfig &= ~(1 << GIC_SH_CONFIG_COUNTSTOP_SHF);
-	gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
-}
-
-void gic_stop_count(void)
-{
-	u32 gicconfig;
-
-	/* Stop the counter */
-	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	gicconfig |= 1 << GIC_SH_CONFIG_COUNTSTOP_SHF;
-	gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
-}
-
-#endif
-
 unsigned gic_read_local_vp_id(void)
 {
 	unsigned long ident;
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 2b0e56619e53..c9e1c993cf5b 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -40,11 +40,6 @@
 
 #define GIC_SH_CONFIG_OFS		0x0000
 
-/* Shared Global Counter */
-#define GIC_SH_COUNTER_31_00_OFS	0x0010
-/* 64-bit counter register for CM3 */
-#define GIC_SH_COUNTER_OFS		GIC_SH_COUNTER_31_00_OFS
-#define GIC_SH_COUNTER_63_32_OFS	0x0014
 #define GIC_SH_REVISIONID_OFS		0x0020
 
 /* Convert an interrupt number to a byte offset/bit for multi-word registers */
@@ -107,10 +102,6 @@
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
 #define GIC_VPE_WD_INITIAL0_OFS		0x0098
-#define GIC_VPE_COMPARE_LO_OFS		0x00a0
-/* 64-bit Compare register on CM3 */
-#define GIC_VPE_COMPARE_OFS		GIC_VPE_COMPARE_LO_OFS
-#define GIC_VPE_COMPARE_HI_OFS		0x00a4
 
 #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS	0x0100
 #define GIC_VPE_EIC_SS(intr)		(4 * (intr))
@@ -128,12 +119,6 @@
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
 /* Masks */
-#define GIC_SH_CONFIG_COUNTSTOP_SHF	28
-#define GIC_SH_CONFIG_COUNTSTOP_MSK	(MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
-
-#define GIC_SH_CONFIG_COUNTBITS_SHF	24
-#define GIC_SH_CONFIG_COUNTBITS_MSK	(MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
-
 #define GIC_SH_CONFIG_NUMINTRS_SHF	16
 #define GIC_SH_CONFIG_NUMINTRS_MSK	(MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
 
@@ -258,13 +243,6 @@ extern unsigned int gic_present;
 extern void gic_init(unsigned long gic_base_addr,
 	unsigned long gic_addrspace_size, unsigned int cpu_vec,
 	unsigned int irqbase);
-extern u64 gic_read_count(void);
-extern unsigned int gic_get_count_width(void);
-extern u64 gic_read_compare(void);
-extern void gic_write_compare(u64 cnt);
-extern void gic_write_cpu_compare(u64 cnt, int cpu);
-extern void gic_start_count(void);
-extern void gic_stop_count(void);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
-- 
2.14.0

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

* [PATCH 05/38] MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (4 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 04/38] irqchip: mips-gic: Remove counter access functions Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 06/38] irqchip: mips-gic: Remove gic_read_local_vp_id() Paul Burton
                   ` (34 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Rather than calling the gic_read_local_vp_id() function from the GIC
irqchip driver, call read_gic_vl_ident() to read the GIC_VL_IDENT
register directly. This will allow us to remove gic_read_local_vp_id()
from the irqchip driver in a further patch, since that driver doesn't
actually care about the register's value.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/smp-cps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 0d9cda6a77de..c316a0f9e6fb 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -368,7 +368,7 @@ static void cps_init_secondary(void)
 		dmt();
 
 	if (mips_cm_revision() >= CM_REV_CM3) {
-		unsigned ident = gic_read_local_vp_id();
+		unsigned int ident = read_gic_vl_ident();
 
 		/*
 		 * Ensure that our calculation of the VP ID matches up with
-- 
2.14.0

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

* [PATCH 05/38] MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver
  2017-08-13  4:36 ` [PATCH 05/38] MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Rather than calling the gic_read_local_vp_id() function from the GIC
irqchip driver, call read_gic_vl_ident() to read the GIC_VL_IDENT
register directly. This will allow us to remove gic_read_local_vp_id()
from the irqchip driver in a further patch, since that driver doesn't
actually care about the register's value.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/smp-cps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 0d9cda6a77de..c316a0f9e6fb 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -368,7 +368,7 @@ static void cps_init_secondary(void)
 		dmt();
 
 	if (mips_cm_revision() >= CM_REV_CM3) {
-		unsigned ident = gic_read_local_vp_id();
+		unsigned int ident = read_gic_vl_ident();
 
 		/*
 		 * Ensure that our calculation of the VP ID matches up with
-- 
2.14.0

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

* [PATCH 06/38] irqchip: mips-gic: Remove gic_read_local_vp_id()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (5 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 05/38] MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 07/38] lib/iomap_copy.c: Add __ioread64_copy Paul Burton
                   ` (33 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Nothing needs gic_read_local_vp_id() any longer, so remove the dead
code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   |  8 --------
 include/linux/irqchip/mips-gic.h | 17 -----------------
 2 files changed, 25 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index e49d48438626..1a572a6511cf 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -138,14 +138,6 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 		  GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
 }
 
-unsigned gic_read_local_vp_id(void)
-{
-	unsigned long ident;
-
-	ident = gic_read(GIC_REG(VPE_LOCAL, GIC_VP_IDENT));
-	return ident & GIC_VP_IDENT_VCNUM_MSK;
-}
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index c9e1c993cf5b..29453bdc06e2 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -98,7 +98,6 @@
 #define GIC_VPE_SWINT0_MAP_OFS		0x0054
 #define GIC_VPE_SWINT1_MAP_OFS		0x0058
 #define GIC_VPE_OTHER_ADDR_OFS		0x0080
-#define GIC_VP_IDENT_OFS		0x0088
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
 #define GIC_VPE_WD_INITIAL0_OFS		0x0098
@@ -197,10 +196,6 @@
 #define GIC_VPE_SMASK_FDC_SHF		6
 #define GIC_VPE_SMASK_FDC_MSK		(MSK(1) << GIC_VPE_SMASK_FDC_SHF)
 
-/* GIC_VP_IDENT fields */
-#define GIC_VP_IDENT_VCNUM_SHF		0
-#define GIC_VP_IDENT_VCNUM_MSK		(MSK(6) << GIC_VP_IDENT_VCNUM_SHF)
-
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0		0 /* Core Interrupt 2 */
 #define GIC_CPU_INT1		1 /* .		      */
@@ -260,16 +255,4 @@ static inline int gic_get_usm_range(struct resource *gic_usm_res)
 
 #endif /* CONFIG_MIPS_GIC */
 
-/**
- * gic_read_local_vp_id() - read the local VPs VCNUM
- *
- * Read the VCNUM of the local VP from the GIC_VP_IDENT register and
- * return it to the caller. This ID should be used to refer to the VP
- * via the GICs VP-other region, or when calculating an offset to a
- * bit representing the VP in interrupt masks.
- *
- * Return: The VCNUM value for the local VP.
- */
-extern unsigned gic_read_local_vp_id(void);
-
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 06/38] irqchip: mips-gic: Remove gic_read_local_vp_id()
  2017-08-13  4:36 ` [PATCH 06/38] irqchip: mips-gic: Remove gic_read_local_vp_id() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Nothing needs gic_read_local_vp_id() any longer, so remove the dead
code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   |  8 --------
 include/linux/irqchip/mips-gic.h | 17 -----------------
 2 files changed, 25 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index e49d48438626..1a572a6511cf 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -138,14 +138,6 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 		  GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
 }
 
-unsigned gic_read_local_vp_id(void)
-{
-	unsigned long ident;
-
-	ident = gic_read(GIC_REG(VPE_LOCAL, GIC_VP_IDENT));
-	return ident & GIC_VP_IDENT_VCNUM_MSK;
-}
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index c9e1c993cf5b..29453bdc06e2 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -98,7 +98,6 @@
 #define GIC_VPE_SWINT0_MAP_OFS		0x0054
 #define GIC_VPE_SWINT1_MAP_OFS		0x0058
 #define GIC_VPE_OTHER_ADDR_OFS		0x0080
-#define GIC_VP_IDENT_OFS		0x0088
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
 #define GIC_VPE_WD_INITIAL0_OFS		0x0098
@@ -197,10 +196,6 @@
 #define GIC_VPE_SMASK_FDC_SHF		6
 #define GIC_VPE_SMASK_FDC_MSK		(MSK(1) << GIC_VPE_SMASK_FDC_SHF)
 
-/* GIC_VP_IDENT fields */
-#define GIC_VP_IDENT_VCNUM_SHF		0
-#define GIC_VP_IDENT_VCNUM_MSK		(MSK(6) << GIC_VP_IDENT_VCNUM_SHF)
-
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0		0 /* Core Interrupt 2 */
 #define GIC_CPU_INT1		1 /* .		      */
@@ -260,16 +255,4 @@ static inline int gic_get_usm_range(struct resource *gic_usm_res)
 
 #endif /* CONFIG_MIPS_GIC */
 
-/**
- * gic_read_local_vp_id() - read the local VPs VCNUM
- *
- * Read the VCNUM of the local VP from the GIC_VP_IDENT register and
- * return it to the caller. This ID should be used to refer to the VP
- * via the GICs VP-other region, or when calculating an offset to a
- * bit representing the VP in interrupt masks.
- *
- * Return: The VCNUM value for the local VP.
- */
-extern unsigned gic_read_local_vp_id(void);
-
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 07/38] lib/iomap_copy.c: Add __ioread64_copy
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (6 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 06/38] irqchip: mips-gic: Remove gic_read_local_vp_id() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 08/38] irqchip: mips-gic: Simplify shared interrupt pending/mask reads Paul Burton
                   ` (32 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

We currently have __ioread32_copy, __iowrite32_copy & __iowrite64_copy
helpers in lib/iomap_copy.c. This patch adds __ioread64_copy to round
out the set, allowing copies from I/O memory using 32 or 64 bit reads.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 include/linux/io.h |  1 +
 lib/iomap_copy.c   | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/io.h b/include/linux/io.h
index 2195d9ea4aaa..29a602a6ee0a 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -31,6 +31,7 @@ struct resource;
 __visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
 void __ioread32_copy(void *to, const void __iomem *from, size_t count);
 void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
+void __ioread64_copy(void *to, const void __iomem *from, size_t count);
 
 #ifdef CONFIG_MMU
 int ioremap_page_range(unsigned long addr, unsigned long end,
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
index b8f1d6cbb200..2efdf4baf9d4 100644
--- a/lib/iomap_copy.c
+++ b/lib/iomap_copy.c
@@ -89,3 +89,28 @@ void __attribute__((weak)) __iowrite64_copy(void __iomem *to,
 }
 
 EXPORT_SYMBOL_GPL(__iowrite64_copy);
+
+/**
+ * __ioread64_copy - copy data from MMIO space, in 64-bit units
+ * @to: destination (must be 64-bit aligned)
+ * @from: source, in MMIO space (must be 64-bit aligned)
+ * @count: number of 64-bit quantities to copy
+ *
+ * Copy data from MMIO space to kernel space, in units of 32 or 64 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void __ioread64_copy(void *to, const void __iomem *from, size_t count)
+{
+#ifdef CONFIG_64BIT
+	u64 *dst = to;
+	const u64 __iomem *src = from;
+	const u64 __iomem *end = src + count;
+
+	while (src < end)
+		*dst++ = __raw_readq(src++);
+#else
+	__ioread32_copy(to, from, count * 2);
+#endif
+}
+EXPORT_SYMBOL_GPL(__ioread64_copy);
-- 
2.14.0

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

* [PATCH 07/38] lib/iomap_copy.c: Add __ioread64_copy
  2017-08-13  4:36 ` [PATCH 07/38] lib/iomap_copy.c: Add __ioread64_copy Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

We currently have __ioread32_copy, __iowrite32_copy & __iowrite64_copy
helpers in lib/iomap_copy.c. This patch adds __ioread64_copy to round
out the set, allowing copies from I/O memory using 32 or 64 bit reads.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 include/linux/io.h |  1 +
 lib/iomap_copy.c   | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/io.h b/include/linux/io.h
index 2195d9ea4aaa..29a602a6ee0a 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -31,6 +31,7 @@ struct resource;
 __visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
 void __ioread32_copy(void *to, const void __iomem *from, size_t count);
 void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
+void __ioread64_copy(void *to, const void __iomem *from, size_t count);
 
 #ifdef CONFIG_MMU
 int ioremap_page_range(unsigned long addr, unsigned long end,
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
index b8f1d6cbb200..2efdf4baf9d4 100644
--- a/lib/iomap_copy.c
+++ b/lib/iomap_copy.c
@@ -89,3 +89,28 @@ void __attribute__((weak)) __iowrite64_copy(void __iomem *to,
 }
 
 EXPORT_SYMBOL_GPL(__iowrite64_copy);
+
+/**
+ * __ioread64_copy - copy data from MMIO space, in 64-bit units
+ * @to: destination (must be 64-bit aligned)
+ * @from: source, in MMIO space (must be 64-bit aligned)
+ * @count: number of 64-bit quantities to copy
+ *
+ * Copy data from MMIO space to kernel space, in units of 32 or 64 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void __ioread64_copy(void *to, const void __iomem *from, size_t count)
+{
+#ifdef CONFIG_64BIT
+	u64 *dst = to;
+	const u64 __iomem *src = from;
+	const u64 __iomem *end = src + count;
+
+	while (src < end)
+		*dst++ = __raw_readq(src++);
+#else
+	__ioread32_copy(to, from, count * 2);
+#endif
+}
+EXPORT_SYMBOL_GPL(__ioread64_copy);
-- 
2.14.0

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

* [PATCH 08/38] irqchip: mips-gic: Simplify shared interrupt pending/mask reads
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (7 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 07/38] lib/iomap_copy.c: Add __ioread64_copy Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 09/38] irqchip: mips-gic: Simplify gic_local_irq_domain_map() Paul Burton
                   ` (31 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Simplify the reads of the bitmaps indicating pending & masked interrupts
in gic_handle_shared_int() using the __ioread32_copy() &
__ioread64_copy() helper functions.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 29 +++++++++++------------------
 include/linux/irqchip/mips-gic.h |  6 ------
 2 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 1a572a6511cf..01ab6fbdb700 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -225,31 +225,24 @@ int gic_get_usm_range(struct resource *gic_usm_res)
 
 static void gic_handle_shared_int(bool chained)
 {
-	unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4;
+	unsigned int intr, virq;
 	unsigned long *pcpu_mask;
-	unsigned long pending_reg, intrmask_reg;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
 	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
 	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
 
-	pending_reg = GIC_REG(SHARED, GIC_SH_PEND);
-	intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK);
-
-	for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {
-		pending[i] = gic_read(pending_reg);
-		intrmask[i] = gic_read(intrmask_reg);
-		pending_reg += gic_reg_step;
-		intrmask_reg += gic_reg_step;
-
-		if (!IS_ENABLED(CONFIG_64BIT) || mips_cm_is64)
-			continue;
-
-		pending[i] |= (u64)gic_read(pending_reg) << 32;
-		intrmask[i] |= (u64)gic_read(intrmask_reg) << 32;
-		pending_reg += gic_reg_step;
-		intrmask_reg += gic_reg_step;
+	if (mips_cm_is64) {
+		__ioread64_copy(pending, addr_gic_pend(),
+				DIV_ROUND_UP(gic_shared_intrs, 64));
+		__ioread64_copy(intrmask, addr_gic_mask(),
+				DIV_ROUND_UP(gic_shared_intrs, 64));
+	} else {
+		__ioread32_copy(pending, addr_gic_pend(),
+				DIV_ROUND_UP(gic_shared_intrs, 32));
+		__ioread32_copy(intrmask, addr_gic_mask(),
+				DIV_ROUND_UP(gic_shared_intrs, 32));
 	}
 
 	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 29453bdc06e2..835e25506660 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -68,12 +68,6 @@
 #define GIC_SH_RMASK_OFS		0x0300
 #define GIC_SH_SMASK_OFS		0x0380
 
-/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
-#define GIC_SH_MASK_OFS			0x0400
-
-/* Pending Global Interrupts (RO) */
-#define GIC_SH_PEND_OFS			0x0480
-
 /* Maps Interrupt X to a Pin */
 #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
 #define GIC_SH_MAP_TO_PIN(intr)		(4 * (intr))
-- 
2.14.0

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

* [PATCH 08/38] irqchip: mips-gic: Simplify shared interrupt pending/mask reads
  2017-08-13  4:36 ` [PATCH 08/38] irqchip: mips-gic: Simplify shared interrupt pending/mask reads Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Simplify the reads of the bitmaps indicating pending & masked interrupts
in gic_handle_shared_int() using the __ioread32_copy() &
__ioread64_copy() helper functions.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 29 +++++++++++------------------
 include/linux/irqchip/mips-gic.h |  6 ------
 2 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 1a572a6511cf..01ab6fbdb700 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -225,31 +225,24 @@ int gic_get_usm_range(struct resource *gic_usm_res)
 
 static void gic_handle_shared_int(bool chained)
 {
-	unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4;
+	unsigned int intr, virq;
 	unsigned long *pcpu_mask;
-	unsigned long pending_reg, intrmask_reg;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
 	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
 	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
 
-	pending_reg = GIC_REG(SHARED, GIC_SH_PEND);
-	intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK);
-
-	for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {
-		pending[i] = gic_read(pending_reg);
-		intrmask[i] = gic_read(intrmask_reg);
-		pending_reg += gic_reg_step;
-		intrmask_reg += gic_reg_step;
-
-		if (!IS_ENABLED(CONFIG_64BIT) || mips_cm_is64)
-			continue;
-
-		pending[i] |= (u64)gic_read(pending_reg) << 32;
-		intrmask[i] |= (u64)gic_read(intrmask_reg) << 32;
-		pending_reg += gic_reg_step;
-		intrmask_reg += gic_reg_step;
+	if (mips_cm_is64) {
+		__ioread64_copy(pending, addr_gic_pend(),
+				DIV_ROUND_UP(gic_shared_intrs, 64));
+		__ioread64_copy(intrmask, addr_gic_mask(),
+				DIV_ROUND_UP(gic_shared_intrs, 64));
+	} else {
+		__ioread32_copy(pending, addr_gic_pend(),
+				DIV_ROUND_UP(gic_shared_intrs, 32));
+		__ioread32_copy(intrmask, addr_gic_mask(),
+				DIV_ROUND_UP(gic_shared_intrs, 32));
 	}
 
 	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 29453bdc06e2..835e25506660 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -68,12 +68,6 @@
 #define GIC_SH_RMASK_OFS		0x0300
 #define GIC_SH_SMASK_OFS		0x0380
 
-/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
-#define GIC_SH_MASK_OFS			0x0400
-
-/* Pending Global Interrupts (RO) */
-#define GIC_SH_PEND_OFS			0x0480
-
 /* Maps Interrupt X to a Pin */
 #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
 #define GIC_SH_MAP_TO_PIN(intr)		(4 * (intr))
-- 
2.14.0

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

* [PATCH 09/38] irqchip: mips-gic: Simplify gic_local_irq_domain_map()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (8 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 08/38] irqchip: mips-gic: Simplify shared interrupt pending/mask reads Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 10/38] irqchip: mips-gic: Drop gic_(re)set_mask() functions Paul Burton
                   ` (30 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Simplify gic_local_irq_domain_map() by:

- Moving the check for invalid IRQs outside of the loop.

- Moving the decision about whether to use gic_cpu_pin or timer_cpu_pin
  outside of the loop.

- Using the new write_gic_vo_map() accessor function to avoid the need
  to handle each map register separately.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 57 +++++++++++-----------------------------
 include/linux/irqchip/mips-gic.h |  6 -----
 2 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 01ab6fbdb700..8ed4a997554d 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -498,58 +498,33 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 				    irq_hw_number_t hw)
 {
 	int intr = GIC_HWIRQ_TO_LOCAL(hw);
-	int ret = 0;
 	int i;
 	unsigned long flags;
+	u32 val;
 
 	if (!gic_local_irq_is_routable(intr))
 		return -EPERM;
 
-	spin_lock_irqsave(&gic_lock, flags);
-	for (i = 0; i < gic_vpes; i++) {
-		u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin;
+	if (intr > GIC_LOCAL_INT_FDC) {
+		pr_err("Invalid local IRQ %d\n", intr);
+		return -EINVAL;
+	}
 
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+	if (intr == GIC_LOCAL_INT_TIMER) {
+		/* CONFIG_MIPS_CMP workaround (see __gic_init) */
+		val = GIC_MAP_PIN_MAP_TO_PIN | timer_cpu_pin;
+	} else {
+		val = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
+	}
 
-		switch (intr) {
-		case GIC_LOCAL_INT_WD:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
-			break;
-		case GIC_LOCAL_INT_COMPARE:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_TIMER:
-			/* CONFIG_MIPS_CMP workaround (see __gic_init) */
-			val = GIC_MAP_TO_PIN_MSK | timer_cpu_pin;
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_PERFCTR:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_SWINT0:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_SWINT1:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_FDC:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
-			break;
-		default:
-			pr_err("Invalid local IRQ %d\n", intr);
-			ret = -EINVAL;
-			break;
-		}
+	spin_lock_irqsave(&gic_lock, flags);
+	for (i = 0; i < gic_vpes; i++) {
+		write_gic_vl_other(mips_cm_vp_id(i));
+		write_gic_vo_map(intr, val);
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
 
-	return ret;
+	return 0;
 }
 
 static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 835e25506660..1342b17b6812 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -84,13 +84,7 @@
 #define GIC_VPE_MASK_OFS		0x0008
 #define GIC_VPE_RMASK_OFS		0x000c
 #define GIC_VPE_SMASK_OFS		0x0010
-#define GIC_VPE_WD_MAP_OFS		0x0040
-#define GIC_VPE_COMPARE_MAP_OFS		0x0044
 #define GIC_VPE_TIMER_MAP_OFS		0x0048
-#define GIC_VPE_FDC_MAP_OFS		0x004c
-#define GIC_VPE_PERFCTR_MAP_OFS		0x0050
-#define GIC_VPE_SWINT0_MAP_OFS		0x0054
-#define GIC_VPE_SWINT1_MAP_OFS		0x0058
 #define GIC_VPE_OTHER_ADDR_OFS		0x0080
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
-- 
2.14.0

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

* [PATCH 09/38] irqchip: mips-gic: Simplify gic_local_irq_domain_map()
  2017-08-13  4:36 ` [PATCH 09/38] irqchip: mips-gic: Simplify gic_local_irq_domain_map() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Simplify gic_local_irq_domain_map() by:

- Moving the check for invalid IRQs outside of the loop.

- Moving the decision about whether to use gic_cpu_pin or timer_cpu_pin
  outside of the loop.

- Using the new write_gic_vo_map() accessor function to avoid the need
  to handle each map register separately.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 57 +++++++++++-----------------------------
 include/linux/irqchip/mips-gic.h |  6 -----
 2 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 01ab6fbdb700..8ed4a997554d 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -498,58 +498,33 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 				    irq_hw_number_t hw)
 {
 	int intr = GIC_HWIRQ_TO_LOCAL(hw);
-	int ret = 0;
 	int i;
 	unsigned long flags;
+	u32 val;
 
 	if (!gic_local_irq_is_routable(intr))
 		return -EPERM;
 
-	spin_lock_irqsave(&gic_lock, flags);
-	for (i = 0; i < gic_vpes; i++) {
-		u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin;
+	if (intr > GIC_LOCAL_INT_FDC) {
+		pr_err("Invalid local IRQ %d\n", intr);
+		return -EINVAL;
+	}
 
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+	if (intr == GIC_LOCAL_INT_TIMER) {
+		/* CONFIG_MIPS_CMP workaround (see __gic_init) */
+		val = GIC_MAP_PIN_MAP_TO_PIN | timer_cpu_pin;
+	} else {
+		val = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
+	}
 
-		switch (intr) {
-		case GIC_LOCAL_INT_WD:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
-			break;
-		case GIC_LOCAL_INT_COMPARE:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_TIMER:
-			/* CONFIG_MIPS_CMP workaround (see __gic_init) */
-			val = GIC_MAP_TO_PIN_MSK | timer_cpu_pin;
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_PERFCTR:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_SWINT0:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_SWINT1:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP),
-				    val);
-			break;
-		case GIC_LOCAL_INT_FDC:
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
-			break;
-		default:
-			pr_err("Invalid local IRQ %d\n", intr);
-			ret = -EINVAL;
-			break;
-		}
+	spin_lock_irqsave(&gic_lock, flags);
+	for (i = 0; i < gic_vpes; i++) {
+		write_gic_vl_other(mips_cm_vp_id(i));
+		write_gic_vo_map(intr, val);
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
 
-	return ret;
+	return 0;
 }
 
 static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 835e25506660..1342b17b6812 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -84,13 +84,7 @@
 #define GIC_VPE_MASK_OFS		0x0008
 #define GIC_VPE_RMASK_OFS		0x000c
 #define GIC_VPE_SMASK_OFS		0x0010
-#define GIC_VPE_WD_MAP_OFS		0x0040
-#define GIC_VPE_COMPARE_MAP_OFS		0x0044
 #define GIC_VPE_TIMER_MAP_OFS		0x0048
-#define GIC_VPE_FDC_MAP_OFS		0x004c
-#define GIC_VPE_PERFCTR_MAP_OFS		0x0050
-#define GIC_VPE_SWINT0_MAP_OFS		0x0054
-#define GIC_VPE_SWINT1_MAP_OFS		0x0058
 #define GIC_VPE_OTHER_ADDR_OFS		0x0080
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
-- 
2.14.0

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

* [PATCH 10/38] irqchip: mips-gic: Drop gic_(re)set_mask() functions
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (9 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 09/38] irqchip: mips-gic: Simplify gic_local_irq_domain_map() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 11/38] irqchip: mips-gic: Remove gic_set_polarity() Paul Burton
                   ` (29 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The gic_set_mask() & gic_reset_mask() functions are now no more
convenient to call than the write_gic_smask() or write_gic_rmask()
accessor functions. Remove the layer of abstraction.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 18 +++---------------
 include/linux/irqchip/mips-gic.h |  4 ----
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 8ed4a997554d..f3fd32c8aa1e 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -92,18 +92,6 @@ static inline void gic_update_bits(unsigned int reg, unsigned long mask,
 	gic_write(reg, regval);
 }
 
-static inline void gic_reset_mask(unsigned int intr)
-{
-	gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr),
-		  1ul << GIC_INTR_BIT(intr));
-}
-
-static inline void gic_set_mask(unsigned int intr)
-{
-	gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr),
-		  1ul << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
 {
 	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
@@ -260,12 +248,12 @@ static void gic_handle_shared_int(bool chained)
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	gic_reset_mask(GIC_HWIRQ_TO_SHARED(d->hwirq));
+	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	gic_set_mask(GIC_HWIRQ_TO_SHARED(d->hwirq));
+	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
 }
 
 static void gic_ack_irq(struct irq_data *d)
@@ -478,7 +466,7 @@ static void __init gic_basic_init(void)
 	for (i = 0; i < gic_shared_intrs; i++) {
 		gic_set_polarity(i, GIC_POL_POS);
 		gic_set_trigger(i, GIC_TRIG_LEVEL);
-		gic_reset_mask(i);
+		write_gic_rmask(BIT(i));
 	}
 
 	for (i = 0; i < gic_vpes; i++) {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 1342b17b6812..8160cc8b677d 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -64,10 +64,6 @@
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-/* Mask manipulation */
-#define GIC_SH_RMASK_OFS		0x0300
-#define GIC_SH_SMASK_OFS		0x0380
-
 /* Maps Interrupt X to a Pin */
 #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
 #define GIC_SH_MAP_TO_PIN(intr)		(4 * (intr))
-- 
2.14.0

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

* [PATCH 10/38] irqchip: mips-gic: Drop gic_(re)set_mask() functions
  2017-08-13  4:36 ` [PATCH 10/38] irqchip: mips-gic: Drop gic_(re)set_mask() functions Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The gic_set_mask() & gic_reset_mask() functions are now no more
convenient to call than the write_gic_smask() or write_gic_rmask()
accessor functions. Remove the layer of abstraction.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 18 +++---------------
 include/linux/irqchip/mips-gic.h |  4 ----
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 8ed4a997554d..f3fd32c8aa1e 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -92,18 +92,6 @@ static inline void gic_update_bits(unsigned int reg, unsigned long mask,
 	gic_write(reg, regval);
 }
 
-static inline void gic_reset_mask(unsigned int intr)
-{
-	gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr),
-		  1ul << GIC_INTR_BIT(intr));
-}
-
-static inline void gic_set_mask(unsigned int intr)
-{
-	gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr),
-		  1ul << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
 {
 	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
@@ -260,12 +248,12 @@ static void gic_handle_shared_int(bool chained)
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	gic_reset_mask(GIC_HWIRQ_TO_SHARED(d->hwirq));
+	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	gic_set_mask(GIC_HWIRQ_TO_SHARED(d->hwirq));
+	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
 }
 
 static void gic_ack_irq(struct irq_data *d)
@@ -478,7 +466,7 @@ static void __init gic_basic_init(void)
 	for (i = 0; i < gic_shared_intrs; i++) {
 		gic_set_polarity(i, GIC_POL_POS);
 		gic_set_trigger(i, GIC_TRIG_LEVEL);
-		gic_reset_mask(i);
+		write_gic_rmask(BIT(i));
 	}
 
 	for (i = 0; i < gic_vpes; i++) {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 1342b17b6812..8160cc8b677d 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -64,10 +64,6 @@
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-/* Mask manipulation */
-#define GIC_SH_RMASK_OFS		0x0300
-#define GIC_SH_SMASK_OFS		0x0380
-
 /* Maps Interrupt X to a Pin */
 #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
 #define GIC_SH_MAP_TO_PIN(intr)		(4 * (intr))
-- 
2.14.0

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

* [PATCH 11/38] irqchip: mips-gic: Remove gic_set_polarity()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (10 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 10/38] irqchip: mips-gic: Drop gic_(re)set_mask() functions Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 12/38] irqchip: mips-gic: Remove gic_set_trigger() Paul Burton
                   ` (28 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_set_polarity() function in favour of using the new
change_gic_pol() accessor function which provides equivalent
functionality.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 17 +++++------------
 include/linux/irqchip/mips-gic.h |  5 -----
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index f3fd32c8aa1e..3d9f264dcda0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -92,13 +92,6 @@ static inline void gic_update_bits(unsigned int reg, unsigned long mask,
 	gic_write(reg, regval);
 }
 
-static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
-{
-	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
-			GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
-			(unsigned long)pol << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
 {
 	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
@@ -272,13 +265,13 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	spin_lock_irqsave(&gic_lock, flags);
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_FALLING:
-		gic_set_polarity(irq, GIC_POL_NEG);
+		change_gic_pol(irq, GIC_POL_FALLING_EDGE);
 		gic_set_trigger(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		gic_set_polarity(irq, GIC_POL_POS);
+		change_gic_pol(irq, GIC_POL_RISING_EDGE);
 		gic_set_trigger(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
@@ -290,14 +283,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 		is_edge = true;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
-		gic_set_polarity(irq, GIC_POL_NEG);
+		change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
 		gic_set_trigger(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
 	default:
-		gic_set_polarity(irq, GIC_POL_POS);
+		change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
 		gic_set_trigger(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
@@ -464,7 +457,7 @@ static void __init gic_basic_init(void)
 
 	/* Setup defaults */
 	for (i = 0; i < gic_shared_intrs; i++) {
-		gic_set_polarity(i, GIC_POL_POS);
+		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
 		gic_set_trigger(i, GIC_TRIG_LEVEL);
 		write_gic_rmask(BIT(i));
 	}
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 8160cc8b677d..960e49a64e7a 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -14,8 +14,6 @@
 #define GIC_MAX_INTRS			256
 
 /* Constants */
-#define GIC_POL_POS			1
-#define GIC_POL_NEG			0
 #define GIC_TRIG_EDGE			1
 #define GIC_TRIG_LEVEL			0
 #define GIC_TRIG_DUAL_ENABLE		1
@@ -52,9 +50,6 @@
 })
 #define GIC_INTR_BIT(intr)		((intr) % (mips_cm_is64 ? 64 : 32))
 
-/* Polarity : Reset Value is always 0 */
-#define GIC_SH_SET_POLARITY_OFS		0x0100
-
 /* Triggering : Reset Value is always 0 */
 #define GIC_SH_SET_TRIGGER_OFS		0x0180
 
-- 
2.14.0

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

* [PATCH 11/38] irqchip: mips-gic: Remove gic_set_polarity()
  2017-08-13  4:36 ` [PATCH 11/38] irqchip: mips-gic: Remove gic_set_polarity() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_set_polarity() function in favour of using the new
change_gic_pol() accessor function which provides equivalent
functionality.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 17 +++++------------
 include/linux/irqchip/mips-gic.h |  5 -----
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index f3fd32c8aa1e..3d9f264dcda0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -92,13 +92,6 @@ static inline void gic_update_bits(unsigned int reg, unsigned long mask,
 	gic_write(reg, regval);
 }
 
-static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
-{
-	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
-			GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
-			(unsigned long)pol << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
 {
 	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
@@ -272,13 +265,13 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	spin_lock_irqsave(&gic_lock, flags);
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_FALLING:
-		gic_set_polarity(irq, GIC_POL_NEG);
+		change_gic_pol(irq, GIC_POL_FALLING_EDGE);
 		gic_set_trigger(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		gic_set_polarity(irq, GIC_POL_POS);
+		change_gic_pol(irq, GIC_POL_RISING_EDGE);
 		gic_set_trigger(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
@@ -290,14 +283,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 		is_edge = true;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
-		gic_set_polarity(irq, GIC_POL_NEG);
+		change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
 		gic_set_trigger(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
 	default:
-		gic_set_polarity(irq, GIC_POL_POS);
+		change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
 		gic_set_trigger(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
@@ -464,7 +457,7 @@ static void __init gic_basic_init(void)
 
 	/* Setup defaults */
 	for (i = 0; i < gic_shared_intrs; i++) {
-		gic_set_polarity(i, GIC_POL_POS);
+		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
 		gic_set_trigger(i, GIC_TRIG_LEVEL);
 		write_gic_rmask(BIT(i));
 	}
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 8160cc8b677d..960e49a64e7a 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -14,8 +14,6 @@
 #define GIC_MAX_INTRS			256
 
 /* Constants */
-#define GIC_POL_POS			1
-#define GIC_POL_NEG			0
 #define GIC_TRIG_EDGE			1
 #define GIC_TRIG_LEVEL			0
 #define GIC_TRIG_DUAL_ENABLE		1
@@ -52,9 +50,6 @@
 })
 #define GIC_INTR_BIT(intr)		((intr) % (mips_cm_is64 ? 64 : 32))
 
-/* Polarity : Reset Value is always 0 */
-#define GIC_SH_SET_POLARITY_OFS		0x0100
-
 /* Triggering : Reset Value is always 0 */
 #define GIC_SH_SET_TRIGGER_OFS		0x0180
 
-- 
2.14.0

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

* [PATCH 12/38] irqchip: mips-gic: Remove gic_set_trigger()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (11 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 11/38] irqchip: mips-gic: Remove gic_set_polarity() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 13/38] irqchip: mips-gic: Remove gic_set_dual_edge() Paul Burton
                   ` (27 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_set_trigger() function in favour of using the new
change_gic_trig() accessor function which provides equivalent
functionality.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 19 ++++++-------------
 include/linux/irqchip/mips-gic.h |  5 -----
 2 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 3d9f264dcda0..960d393ca8d1 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -92,13 +92,6 @@ static inline void gic_update_bits(unsigned int reg, unsigned long mask,
 	gic_write(reg, regval);
 }
 
-static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
-{
-	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
-			GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
-			(unsigned long)trig << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
 {
 	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
@@ -266,32 +259,32 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_FALLING:
 		change_gic_pol(irq, GIC_POL_FALLING_EDGE);
-		gic_set_trigger(irq, GIC_TRIG_EDGE);
+		change_gic_trig(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
 		change_gic_pol(irq, GIC_POL_RISING_EDGE);
-		gic_set_trigger(irq, GIC_TRIG_EDGE);
+		change_gic_trig(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
 		/* polarity is irrelevant in this case */
-		gic_set_trigger(irq, GIC_TRIG_EDGE);
+		change_gic_trig(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
-		gic_set_trigger(irq, GIC_TRIG_LEVEL);
+		change_gic_trig(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
 	default:
 		change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
-		gic_set_trigger(irq, GIC_TRIG_LEVEL);
+		change_gic_trig(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
 		break;
@@ -458,7 +451,7 @@ static void __init gic_basic_init(void)
 	/* Setup defaults */
 	for (i = 0; i < gic_shared_intrs; i++) {
 		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
-		gic_set_trigger(i, GIC_TRIG_LEVEL);
+		change_gic_trig(i, GIC_TRIG_LEVEL);
 		write_gic_rmask(BIT(i));
 	}
 
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 960e49a64e7a..2e9f0c43d425 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -14,8 +14,6 @@
 #define GIC_MAX_INTRS			256
 
 /* Constants */
-#define GIC_TRIG_EDGE			1
-#define GIC_TRIG_LEVEL			0
 #define GIC_TRIG_DUAL_ENABLE		1
 #define GIC_TRIG_DUAL_DISABLE		0
 
@@ -50,9 +48,6 @@
 })
 #define GIC_INTR_BIT(intr)		((intr) % (mips_cm_is64 ? 64 : 32))
 
-/* Triggering : Reset Value is always 0 */
-#define GIC_SH_SET_TRIGGER_OFS		0x0180
-
 /* Dual edge triggering : Reset Value is always 0 */
 #define GIC_SH_SET_DUAL_OFS		0x0200
 
-- 
2.14.0

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

* [PATCH 12/38] irqchip: mips-gic: Remove gic_set_trigger()
  2017-08-13  4:36 ` [PATCH 12/38] irqchip: mips-gic: Remove gic_set_trigger() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_set_trigger() function in favour of using the new
change_gic_trig() accessor function which provides equivalent
functionality.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 19 ++++++-------------
 include/linux/irqchip/mips-gic.h |  5 -----
 2 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 3d9f264dcda0..960d393ca8d1 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -92,13 +92,6 @@ static inline void gic_update_bits(unsigned int reg, unsigned long mask,
 	gic_write(reg, regval);
 }
 
-static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
-{
-	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
-			GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
-			(unsigned long)trig << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
 {
 	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
@@ -266,32 +259,32 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_FALLING:
 		change_gic_pol(irq, GIC_POL_FALLING_EDGE);
-		gic_set_trigger(irq, GIC_TRIG_EDGE);
+		change_gic_trig(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
 		change_gic_pol(irq, GIC_POL_RISING_EDGE);
-		gic_set_trigger(irq, GIC_TRIG_EDGE);
+		change_gic_trig(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
 		/* polarity is irrelevant in this case */
-		gic_set_trigger(irq, GIC_TRIG_EDGE);
+		change_gic_trig(irq, GIC_TRIG_EDGE);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
-		gic_set_trigger(irq, GIC_TRIG_LEVEL);
+		change_gic_trig(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
 	default:
 		change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
-		gic_set_trigger(irq, GIC_TRIG_LEVEL);
+		change_gic_trig(irq, GIC_TRIG_LEVEL);
 		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
 		is_edge = false;
 		break;
@@ -458,7 +451,7 @@ static void __init gic_basic_init(void)
 	/* Setup defaults */
 	for (i = 0; i < gic_shared_intrs; i++) {
 		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
-		gic_set_trigger(i, GIC_TRIG_LEVEL);
+		change_gic_trig(i, GIC_TRIG_LEVEL);
 		write_gic_rmask(BIT(i));
 	}
 
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 960e49a64e7a..2e9f0c43d425 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -14,8 +14,6 @@
 #define GIC_MAX_INTRS			256
 
 /* Constants */
-#define GIC_TRIG_EDGE			1
-#define GIC_TRIG_LEVEL			0
 #define GIC_TRIG_DUAL_ENABLE		1
 #define GIC_TRIG_DUAL_DISABLE		0
 
@@ -50,9 +48,6 @@
 })
 #define GIC_INTR_BIT(intr)		((intr) % (mips_cm_is64 ? 64 : 32))
 
-/* Triggering : Reset Value is always 0 */
-#define GIC_SH_SET_TRIGGER_OFS		0x0180
-
 /* Dual edge triggering : Reset Value is always 0 */
 #define GIC_SH_SET_DUAL_OFS		0x0200
 
-- 
2.14.0

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

* [PATCH 13/38] irqchip: mips-gic: Remove gic_set_dual_edge()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (12 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 12/38] irqchip: mips-gic: Remove gic_set_trigger() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 14/38] irqchip: mips-gic: Remove gic_map_to_pin() Paul Burton
                   ` (26 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_set_dual_edge() function in favour of using the new
change_gic_dual() accessor function which provides equivalent
functionality. This also allows us to remove the gic_update_bits()
function which gic_set_dual_edge() was the last user of, along with the
GIC_INTR_OFS() & GIC_INTR_BIT() macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 28 +++++-----------------------
 include/linux/irqchip/mips-gic.h | 17 -----------------
 2 files changed, 5 insertions(+), 40 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 960d393ca8d1..cd5d46b1c372 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -81,24 +81,6 @@ static inline void gic_write(unsigned int reg, unsigned long val)
 		return gic_write64(reg, (u64)val);
 }
 
-static inline void gic_update_bits(unsigned int reg, unsigned long mask,
-				   unsigned long val)
-{
-	unsigned long regval;
-
-	regval = gic_read(reg);
-	regval &= ~mask;
-	regval |= val;
-	gic_write(reg, regval);
-}
-
-static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
-{
-	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
-			1ul << GIC_INTR_BIT(intr),
-			(unsigned long)dual << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
 {
 	gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
@@ -260,32 +242,32 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	case IRQ_TYPE_EDGE_FALLING:
 		change_gic_pol(irq, GIC_POL_FALLING_EDGE);
 		change_gic_trig(irq, GIC_TRIG_EDGE);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
 		change_gic_pol(irq, GIC_POL_RISING_EDGE);
 		change_gic_trig(irq, GIC_TRIG_EDGE);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
 		/* polarity is irrelevant in this case */
 		change_gic_trig(irq, GIC_TRIG_EDGE);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE);
+		change_gic_dual(irq, GIC_DUAL_DUAL);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
 		change_gic_trig(irq, GIC_TRIG_LEVEL);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = false;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
 	default:
 		change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
 		change_gic_trig(irq, GIC_TRIG_LEVEL);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = false;
 		break;
 	}
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 2e9f0c43d425..bd348fc9db18 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -13,10 +13,6 @@
 
 #define GIC_MAX_INTRS			256
 
-/* Constants */
-#define GIC_TRIG_DUAL_ENABLE		1
-#define GIC_TRIG_DUAL_DISABLE		0
-
 #define MSK(n) ((1 << (n)) - 1)
 
 /* Accessors */
@@ -38,19 +34,6 @@
 
 #define GIC_SH_REVISIONID_OFS		0x0020
 
-/* Convert an interrupt number to a byte offset/bit for multi-word registers */
-#define GIC_INTR_OFS(intr) ({				\
-	unsigned bits = mips_cm_is64 ? 64 : 32;		\
-	unsigned reg_idx = (intr) / bits;		\
-	unsigned reg_width = bits / 8;			\
-							\
-	reg_idx * reg_width;				\
-})
-#define GIC_INTR_BIT(intr)		((intr) % (mips_cm_is64 ? 64 : 32))
-
-/* Dual edge triggering : Reset Value is always 0 */
-#define GIC_SH_SET_DUAL_OFS		0x0200
-
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-- 
2.14.0

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

* [PATCH 13/38] irqchip: mips-gic: Remove gic_set_dual_edge()
  2017-08-13  4:36 ` [PATCH 13/38] irqchip: mips-gic: Remove gic_set_dual_edge() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_set_dual_edge() function in favour of using the new
change_gic_dual() accessor function which provides equivalent
functionality. This also allows us to remove the gic_update_bits()
function which gic_set_dual_edge() was the last user of, along with the
GIC_INTR_OFS() & GIC_INTR_BIT() macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 28 +++++-----------------------
 include/linux/irqchip/mips-gic.h | 17 -----------------
 2 files changed, 5 insertions(+), 40 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 960d393ca8d1..cd5d46b1c372 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -81,24 +81,6 @@ static inline void gic_write(unsigned int reg, unsigned long val)
 		return gic_write64(reg, (u64)val);
 }
 
-static inline void gic_update_bits(unsigned int reg, unsigned long mask,
-				   unsigned long val)
-{
-	unsigned long regval;
-
-	regval = gic_read(reg);
-	regval &= ~mask;
-	regval |= val;
-	gic_write(reg, regval);
-}
-
-static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
-{
-	gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
-			1ul << GIC_INTR_BIT(intr),
-			(unsigned long)dual << GIC_INTR_BIT(intr));
-}
-
 static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
 {
 	gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
@@ -260,32 +242,32 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	case IRQ_TYPE_EDGE_FALLING:
 		change_gic_pol(irq, GIC_POL_FALLING_EDGE);
 		change_gic_trig(irq, GIC_TRIG_EDGE);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
 		change_gic_pol(irq, GIC_POL_RISING_EDGE);
 		change_gic_trig(irq, GIC_TRIG_EDGE);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
 		/* polarity is irrelevant in this case */
 		change_gic_trig(irq, GIC_TRIG_EDGE);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE);
+		change_gic_dual(irq, GIC_DUAL_DUAL);
 		is_edge = true;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
 		change_gic_trig(irq, GIC_TRIG_LEVEL);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = false;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
 	default:
 		change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
 		change_gic_trig(irq, GIC_TRIG_LEVEL);
-		gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
+		change_gic_dual(irq, GIC_DUAL_SINGLE);
 		is_edge = false;
 		break;
 	}
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 2e9f0c43d425..bd348fc9db18 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -13,10 +13,6 @@
 
 #define GIC_MAX_INTRS			256
 
-/* Constants */
-#define GIC_TRIG_DUAL_ENABLE		1
-#define GIC_TRIG_DUAL_DISABLE		0
-
 #define MSK(n) ((1 << (n)) - 1)
 
 /* Accessors */
@@ -38,19 +34,6 @@
 
 #define GIC_SH_REVISIONID_OFS		0x0020
 
-/* Convert an interrupt number to a byte offset/bit for multi-word registers */
-#define GIC_INTR_OFS(intr) ({				\
-	unsigned bits = mips_cm_is64 ? 64 : 32;		\
-	unsigned reg_idx = (intr) / bits;		\
-	unsigned reg_width = bits / 8;			\
-							\
-	reg_idx * reg_width;				\
-})
-#define GIC_INTR_BIT(intr)		((intr) % (mips_cm_is64 ? 64 : 32))
-
-/* Dual edge triggering : Reset Value is always 0 */
-#define GIC_SH_SET_DUAL_OFS		0x0200
-
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-- 
2.14.0

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

* [PATCH 14/38] irqchip: mips-gic: Remove gic_map_to_pin()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (13 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 13/38] irqchip: mips-gic: Remove gic_set_dual_edge() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 15/38] irqchip: mips-gic: Remove gic_map_to_vpe() Paul Burton
                   ` (25 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_map_to_pin() function in favour of using the new
write_gic_map_pin() accessor function which isn't any more complex to
use & allows us to drop a level of abstraction.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   |  8 +-------
 include/linux/irqchip/mips-gic.h | 10 ----------
 2 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index cd5d46b1c372..b97c7afef61d 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -81,12 +81,6 @@ static inline void gic_write(unsigned int reg, unsigned long val)
 		return gic_write64(reg, (u64)val);
 }
 
-static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
-{
-	gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
-		    GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);
-}
-
 static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 {
 	gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) +
@@ -491,7 +485,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
 	int i;
 
 	spin_lock_irqsave(&gic_lock, flags);
-	gic_map_to_pin(intr, gic_cpu_pin);
+	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
 	gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
 		clear_bit(intr, pcpu_masks[i].pcpu_mask);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index bd348fc9db18..dea79a7a54cc 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -37,10 +37,6 @@
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-/* Maps Interrupt X to a Pin */
-#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
-#define GIC_SH_MAP_TO_PIN(intr)		(4 * (intr))
-
 /* Maps Interrupt X to a VPE */
 #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
 #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
@@ -84,12 +80,6 @@
 #define GIC_SH_WEDGE_SET(intr)		((intr) | (0x1 << 31))
 #define GIC_SH_WEDGE_CLR(intr)		((intr) & ~(0x1 << 31))
 
-#define GIC_MAP_TO_PIN_SHF		31
-#define GIC_MAP_TO_PIN_MSK		(MSK(1) << GIC_MAP_TO_PIN_SHF)
-#define GIC_MAP_TO_NMI_SHF		30
-#define GIC_MAP_TO_NMI_MSK		(MSK(1) << GIC_MAP_TO_NMI_SHF)
-#define GIC_MAP_TO_YQ_SHF		29
-#define GIC_MAP_TO_YQ_MSK		(MSK(1) << GIC_MAP_TO_YQ_SHF)
 #define GIC_MAP_SHF			0
 #define GIC_MAP_MSK			(MSK(6) << GIC_MAP_SHF)
 
-- 
2.14.0

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

* [PATCH 14/38] irqchip: mips-gic: Remove gic_map_to_pin()
  2017-08-13  4:36 ` [PATCH 14/38] irqchip: mips-gic: Remove gic_map_to_pin() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_map_to_pin() function in favour of using the new
write_gic_map_pin() accessor function which isn't any more complex to
use & allows us to drop a level of abstraction.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   |  8 +-------
 include/linux/irqchip/mips-gic.h | 10 ----------
 2 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index cd5d46b1c372..b97c7afef61d 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -81,12 +81,6 @@ static inline void gic_write(unsigned int reg, unsigned long val)
 		return gic_write64(reg, (u64)val);
 }
 
-static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
-{
-	gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
-		    GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);
-}
-
 static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 {
 	gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) +
@@ -491,7 +485,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
 	int i;
 
 	spin_lock_irqsave(&gic_lock, flags);
-	gic_map_to_pin(intr, gic_cpu_pin);
+	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
 	gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
 		clear_bit(intr, pcpu_masks[i].pcpu_mask);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index bd348fc9db18..dea79a7a54cc 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -37,10 +37,6 @@
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-/* Maps Interrupt X to a Pin */
-#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
-#define GIC_SH_MAP_TO_PIN(intr)		(4 * (intr))
-
 /* Maps Interrupt X to a VPE */
 #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
 #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
@@ -84,12 +80,6 @@
 #define GIC_SH_WEDGE_SET(intr)		((intr) | (0x1 << 31))
 #define GIC_SH_WEDGE_CLR(intr)		((intr) & ~(0x1 << 31))
 
-#define GIC_MAP_TO_PIN_SHF		31
-#define GIC_MAP_TO_PIN_MSK		(MSK(1) << GIC_MAP_TO_PIN_SHF)
-#define GIC_MAP_TO_NMI_SHF		30
-#define GIC_MAP_TO_NMI_MSK		(MSK(1) << GIC_MAP_TO_NMI_SHF)
-#define GIC_MAP_TO_YQ_SHF		29
-#define GIC_MAP_TO_YQ_MSK		(MSK(1) << GIC_MAP_TO_YQ_SHF)
 #define GIC_MAP_SHF			0
 #define GIC_MAP_MSK			(MSK(6) << GIC_MAP_SHF)
 
-- 
2.14.0

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

* [PATCH 15/38] irqchip: mips-gic: Remove gic_map_to_vpe()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (14 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 14/38] irqchip: mips-gic: Remove gic_map_to_pin() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 16/38] irqchip: mips-gic: Convert remaining shared reg access to new accessors Paul Burton
                   ` (24 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_map_to_vpe() function in favour of using the new
write_gic_map_vp() accessor function which isn't any more complex to
use & allows us to drop a level of abstraction.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 11 ++---------
 include/linux/irqchip/mips-gic.h |  6 ------
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index b97c7afef61d..bc7a4e320f89 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -81,13 +81,6 @@ static inline void gic_write(unsigned int reg, unsigned long val)
 		return gic_write64(reg, (u64)val);
 }
 
-static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
-{
-	gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) +
-		  GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe),
-		  GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
-}
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -294,7 +287,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
-	gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first(&tmp)));
+	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
 
 	/* Update the pcpu_masks */
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
@@ -486,7 +479,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
 
 	spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
-	gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
+	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
 		clear_bit(intr, pcpu_masks[i].pcpu_mask);
 	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index dea79a7a54cc..ad8b216b6056 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -37,12 +37,6 @@
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-/* Maps Interrupt X to a VPE */
-#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
-#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
-	((32 * (intr)) + (((vpe) / 32) * 4))
-#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe)	(1 << ((vpe) % 32))
-
 /* Register Map for Local Section */
 #define GIC_VPE_CTL_OFS			0x0000
 #define GIC_VPE_PEND_OFS		0x0004
-- 
2.14.0

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

* [PATCH 15/38] irqchip: mips-gic: Remove gic_map_to_vpe()
  2017-08-13  4:36 ` [PATCH 15/38] irqchip: mips-gic: Remove gic_map_to_vpe() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Remove the gic_map_to_vpe() function in favour of using the new
write_gic_map_vp() accessor function which isn't any more complex to
use & allows us to drop a level of abstraction.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 11 ++---------
 include/linux/irqchip/mips-gic.h |  6 ------
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index b97c7afef61d..bc7a4e320f89 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -81,13 +81,6 @@ static inline void gic_write(unsigned int reg, unsigned long val)
 		return gic_write64(reg, (u64)val);
 }
 
-static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
-{
-	gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) +
-		  GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe),
-		  GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
-}
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -294,7 +287,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
-	gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first(&tmp)));
+	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
 
 	/* Update the pcpu_masks */
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
@@ -486,7 +479,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
 
 	spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
-	gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
+	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
 		clear_bit(intr, pcpu_masks[i].pcpu_mask);
 	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index dea79a7a54cc..ad8b216b6056 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -37,12 +37,6 @@
 /* Set/Clear corresponding bit in Edge Detect Register */
 #define GIC_SH_WEDGE_OFS		0x0280
 
-/* Maps Interrupt X to a VPE */
-#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
-#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
-	((32 * (intr)) + (((vpe) / 32) * 4))
-#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe)	(1 << ((vpe) % 32))
-
 /* Register Map for Local Section */
 #define GIC_VPE_CTL_OFS			0x0000
 #define GIC_VPE_PEND_OFS		0x0004
-- 
2.14.0

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

* [PATCH 16/38] irqchip: mips-gic: Convert remaining shared reg access to new accessors
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (15 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 15/38] irqchip: mips-gic: Remove gic_map_to_vpe() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 17/38] irqchip: mips-gic: Convert local int mask " Paul Burton
                   ` (23 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Convert the remaining accesses to registers in the GIC shared register
block to use the new accessor functions provided by asm/mips-gic.h,
resulting in code which is often shorter & easier to read.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 16 ++++++++--------
 include/linux/irqchip/mips-gic.h | 20 --------------------
 2 files changed, 8 insertions(+), 28 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index bc7a4e320f89..90b8644e1264 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -119,7 +119,7 @@ static void gic_send_ipi(struct irq_data *d, unsigned int cpu)
 {
 	irq_hw_number_t hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(d));
 
-	gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(hwirq));
+	write_gic_wedge(GIC_WEDGE_RW | hwirq);
 }
 
 int gic_get_c0_compare_int(void)
@@ -215,7 +215,7 @@ static void gic_ack_irq(struct irq_data *d)
 {
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 
-	gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(irq));
+	write_gic_wedge(irq);
 }
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -700,13 +700,13 @@ static void __init __gic_init(unsigned long gic_base_addr,
 
 	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
-	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
-		   GIC_SH_CONFIG_NUMINTRS_SHF;
-	gic_shared_intrs = ((gic_shared_intrs + 1) * 8);
+	gicconfig = read_gic_config();
+	gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
+	gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS);
+	gic_shared_intrs = (gic_shared_intrs + 1) * 8;
 
-	gic_vpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
-		  GIC_SH_CONFIG_NUMVPES_SHF;
+	gic_vpes = gicconfig & GIC_CONFIG_PVPS;
+	gic_vpes >>= __fls(GIC_CONFIG_PVPS);
 	gic_vpes = gic_vpes + 1;
 
 	if (cpu_has_veic) {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index ad8b216b6056..f0a60770d775 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -19,8 +19,6 @@
 #define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS)
 
 /* GIC Address Space */
-#define SHARED_SECTION_OFS		0x0000
-#define SHARED_SECTION_SIZE		0x8000
 #define VPE_LOCAL_SECTION_OFS		0x8000
 #define VPE_LOCAL_SECTION_SIZE		0x4000
 #define VPE_OTHER_SECTION_OFS		0xc000
@@ -28,15 +26,6 @@
 #define USM_VISIBLE_SECTION_OFS		0x10000
 #define USM_VISIBLE_SECTION_SIZE	0x10000
 
-/* Register Map for Shared Section */
-
-#define GIC_SH_CONFIG_OFS		0x0000
-
-#define GIC_SH_REVISIONID_OFS		0x0020
-
-/* Set/Clear corresponding bit in Edge Detect Register */
-#define GIC_SH_WEDGE_OFS		0x0280
-
 /* Register Map for Local Section */
 #define GIC_VPE_CTL_OFS			0x0000
 #define GIC_VPE_PEND_OFS		0x0004
@@ -65,15 +54,6 @@
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
 /* Masks */
-#define GIC_SH_CONFIG_NUMINTRS_SHF	16
-#define GIC_SH_CONFIG_NUMINTRS_MSK	(MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
-
-#define GIC_SH_CONFIG_NUMVPES_SHF	0
-#define GIC_SH_CONFIG_NUMVPES_MSK	(MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF)
-
-#define GIC_SH_WEDGE_SET(intr)		((intr) | (0x1 << 31))
-#define GIC_SH_WEDGE_CLR(intr)		((intr) & ~(0x1 << 31))
-
 #define GIC_MAP_SHF			0
 #define GIC_MAP_MSK			(MSK(6) << GIC_MAP_SHF)
 
-- 
2.14.0

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

* [PATCH 16/38] irqchip: mips-gic: Convert remaining shared reg access to new accessors
  2017-08-13  4:36 ` [PATCH 16/38] irqchip: mips-gic: Convert remaining shared reg access to new accessors Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Convert the remaining accesses to registers in the GIC shared register
block to use the new accessor functions provided by asm/mips-gic.h,
resulting in code which is often shorter & easier to read.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 16 ++++++++--------
 include/linux/irqchip/mips-gic.h | 20 --------------------
 2 files changed, 8 insertions(+), 28 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index bc7a4e320f89..90b8644e1264 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -119,7 +119,7 @@ static void gic_send_ipi(struct irq_data *d, unsigned int cpu)
 {
 	irq_hw_number_t hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(d));
 
-	gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(hwirq));
+	write_gic_wedge(GIC_WEDGE_RW | hwirq);
 }
 
 int gic_get_c0_compare_int(void)
@@ -215,7 +215,7 @@ static void gic_ack_irq(struct irq_data *d)
 {
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 
-	gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(irq));
+	write_gic_wedge(irq);
 }
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -700,13 +700,13 @@ static void __init __gic_init(unsigned long gic_base_addr,
 
 	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
-	gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
-	gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
-		   GIC_SH_CONFIG_NUMINTRS_SHF;
-	gic_shared_intrs = ((gic_shared_intrs + 1) * 8);
+	gicconfig = read_gic_config();
+	gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
+	gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS);
+	gic_shared_intrs = (gic_shared_intrs + 1) * 8;
 
-	gic_vpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
-		  GIC_SH_CONFIG_NUMVPES_SHF;
+	gic_vpes = gicconfig & GIC_CONFIG_PVPS;
+	gic_vpes >>= __fls(GIC_CONFIG_PVPS);
 	gic_vpes = gic_vpes + 1;
 
 	if (cpu_has_veic) {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index ad8b216b6056..f0a60770d775 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -19,8 +19,6 @@
 #define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS)
 
 /* GIC Address Space */
-#define SHARED_SECTION_OFS		0x0000
-#define SHARED_SECTION_SIZE		0x8000
 #define VPE_LOCAL_SECTION_OFS		0x8000
 #define VPE_LOCAL_SECTION_SIZE		0x4000
 #define VPE_OTHER_SECTION_OFS		0xc000
@@ -28,15 +26,6 @@
 #define USM_VISIBLE_SECTION_OFS		0x10000
 #define USM_VISIBLE_SECTION_SIZE	0x10000
 
-/* Register Map for Shared Section */
-
-#define GIC_SH_CONFIG_OFS		0x0000
-
-#define GIC_SH_REVISIONID_OFS		0x0020
-
-/* Set/Clear corresponding bit in Edge Detect Register */
-#define GIC_SH_WEDGE_OFS		0x0280
-
 /* Register Map for Local Section */
 #define GIC_VPE_CTL_OFS			0x0000
 #define GIC_VPE_PEND_OFS		0x0004
@@ -65,15 +54,6 @@
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
 /* Masks */
-#define GIC_SH_CONFIG_NUMINTRS_SHF	16
-#define GIC_SH_CONFIG_NUMINTRS_MSK	(MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
-
-#define GIC_SH_CONFIG_NUMVPES_SHF	0
-#define GIC_SH_CONFIG_NUMVPES_MSK	(MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF)
-
-#define GIC_SH_WEDGE_SET(intr)		((intr) | (0x1 << 31))
-#define GIC_SH_WEDGE_CLR(intr)		((intr) & ~(0x1 << 31))
-
 #define GIC_MAP_SHF			0
 #define GIC_MAP_MSK			(MSK(6) << GIC_MAP_SHF)
 
-- 
2.14.0

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

* [PATCH 17/38] irqchip: mips-gic: Convert local int mask access to new accessors
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (16 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 16/38] irqchip: mips-gic: Convert remaining shared reg access to new accessors Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 18/38] irqchip: mips-gic: Convert remaining local reg " Paul Burton
                   ` (22 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Use the new accessor functions provided by asm/mips-gic.h to access
masks controlling local interrupts, resulting in code which is often
shorter & easier to read.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 14 +++++------
 include/linux/irqchip/mips-gic.h | 52 ----------------------------------------
 2 files changed, 7 insertions(+), 59 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 90b8644e1264..ac4ba4f7c2d6 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -328,8 +328,8 @@ static void gic_handle_local_int(bool chained)
 	unsigned long pending, masked;
 	unsigned int intr, virq;
 
-	pending = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
-	masked = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));
+	pending = read_gic_vl_pend();
+	masked = read_gic_vl_mask();
 
 	bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
 
@@ -347,14 +347,14 @@ static void gic_mask_local_irq(struct irq_data *d)
 {
 	int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
 
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
+	write_gic_vl_rmask(BIT(intr));
 }
 
 static void gic_unmask_local_irq(struct irq_data *d)
 {
 	int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
 
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
+	write_gic_vl_smask(BIT(intr));
 }
 
 static struct irq_chip gic_local_irq_controller = {
@@ -373,7 +373,7 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
 	for (i = 0; i < gic_vpes; i++) {
 		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
 			  mips_cm_vp_id(i));
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
+		write_gic_vo_rmask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
 }
@@ -388,7 +388,7 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
 	for (i = 0; i < gic_vpes; i++) {
 		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
 			  mips_cm_vp_id(i));
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
+		write_gic_vo_smask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
 }
@@ -432,7 +432,7 @@ static void __init gic_basic_init(void)
 		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
 			if (!gic_local_irq_is_routable(j))
 				continue;
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
+			write_gic_vo_rmask(BIT(j));
 		}
 	}
 }
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index f0a60770d775..011698962a8d 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -28,10 +28,6 @@
 
 /* Register Map for Local Section */
 #define GIC_VPE_CTL_OFS			0x0000
-#define GIC_VPE_PEND_OFS		0x0004
-#define GIC_VPE_MASK_OFS		0x0008
-#define GIC_VPE_RMASK_OFS		0x000c
-#define GIC_VPE_SMASK_OFS		0x0010
 #define GIC_VPE_TIMER_MAP_OFS		0x0048
 #define GIC_VPE_OTHER_ADDR_OFS		0x0080
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
@@ -69,54 +65,6 @@
 #define GIC_VPE_CTL_EIC_MODE_SHF	0
 #define GIC_VPE_CTL_EIC_MODE_MSK	(MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
 
-/* GIC_VPE_PEND Masks */
-#define GIC_VPE_PEND_WD_SHF		0
-#define GIC_VPE_PEND_WD_MSK		(MSK(1) << GIC_VPE_PEND_WD_SHF)
-#define GIC_VPE_PEND_CMP_SHF		1
-#define GIC_VPE_PEND_CMP_MSK		(MSK(1) << GIC_VPE_PEND_CMP_SHF)
-#define GIC_VPE_PEND_TIMER_SHF		2
-#define GIC_VPE_PEND_TIMER_MSK		(MSK(1) << GIC_VPE_PEND_TIMER_SHF)
-#define GIC_VPE_PEND_PERFCOUNT_SHF	3
-#define GIC_VPE_PEND_PERFCOUNT_MSK	(MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF)
-#define GIC_VPE_PEND_SWINT0_SHF		4
-#define GIC_VPE_PEND_SWINT0_MSK		(MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
-#define GIC_VPE_PEND_SWINT1_SHF		5
-#define GIC_VPE_PEND_SWINT1_MSK		(MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
-#define GIC_VPE_PEND_FDC_SHF		6
-#define GIC_VPE_PEND_FDC_MSK		(MSK(1) << GIC_VPE_PEND_FDC_SHF)
-
-/* GIC_VPE_RMASK Masks */
-#define GIC_VPE_RMASK_WD_SHF		0
-#define GIC_VPE_RMASK_WD_MSK		(MSK(1) << GIC_VPE_RMASK_WD_SHF)
-#define GIC_VPE_RMASK_CMP_SHF		1
-#define GIC_VPE_RMASK_CMP_MSK		(MSK(1) << GIC_VPE_RMASK_CMP_SHF)
-#define GIC_VPE_RMASK_TIMER_SHF		2
-#define GIC_VPE_RMASK_TIMER_MSK		(MSK(1) << GIC_VPE_RMASK_TIMER_SHF)
-#define GIC_VPE_RMASK_PERFCNT_SHF	3
-#define GIC_VPE_RMASK_PERFCNT_MSK	(MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF)
-#define GIC_VPE_RMASK_SWINT0_SHF	4
-#define GIC_VPE_RMASK_SWINT0_MSK	(MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
-#define GIC_VPE_RMASK_SWINT1_SHF	5
-#define GIC_VPE_RMASK_SWINT1_MSK	(MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
-#define GIC_VPE_RMASK_FDC_SHF		6
-#define GIC_VPE_RMASK_FDC_MSK		(MSK(1) << GIC_VPE_RMASK_FDC_SHF)
-
-/* GIC_VPE_SMASK Masks */
-#define GIC_VPE_SMASK_WD_SHF		0
-#define GIC_VPE_SMASK_WD_MSK		(MSK(1) << GIC_VPE_SMASK_WD_SHF)
-#define GIC_VPE_SMASK_CMP_SHF		1
-#define GIC_VPE_SMASK_CMP_MSK		(MSK(1) << GIC_VPE_SMASK_CMP_SHF)
-#define GIC_VPE_SMASK_TIMER_SHF		2
-#define GIC_VPE_SMASK_TIMER_MSK		(MSK(1) << GIC_VPE_SMASK_TIMER_SHF)
-#define GIC_VPE_SMASK_PERFCNT_SHF	3
-#define GIC_VPE_SMASK_PERFCNT_MSK	(MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF)
-#define GIC_VPE_SMASK_SWINT0_SHF	4
-#define GIC_VPE_SMASK_SWINT0_MSK	(MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
-#define GIC_VPE_SMASK_SWINT1_SHF	5
-#define GIC_VPE_SMASK_SWINT1_MSK	(MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
-#define GIC_VPE_SMASK_FDC_SHF		6
-#define GIC_VPE_SMASK_FDC_MSK		(MSK(1) << GIC_VPE_SMASK_FDC_SHF)
-
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0		0 /* Core Interrupt 2 */
 #define GIC_CPU_INT1		1 /* .		      */
-- 
2.14.0

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

* [PATCH 17/38] irqchip: mips-gic: Convert local int mask access to new accessors
  2017-08-13  4:36 ` [PATCH 17/38] irqchip: mips-gic: Convert local int mask " Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Use the new accessor functions provided by asm/mips-gic.h to access
masks controlling local interrupts, resulting in code which is often
shorter & easier to read.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 14 +++++------
 include/linux/irqchip/mips-gic.h | 52 ----------------------------------------
 2 files changed, 7 insertions(+), 59 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 90b8644e1264..ac4ba4f7c2d6 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -328,8 +328,8 @@ static void gic_handle_local_int(bool chained)
 	unsigned long pending, masked;
 	unsigned int intr, virq;
 
-	pending = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
-	masked = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));
+	pending = read_gic_vl_pend();
+	masked = read_gic_vl_mask();
 
 	bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
 
@@ -347,14 +347,14 @@ static void gic_mask_local_irq(struct irq_data *d)
 {
 	int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
 
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
+	write_gic_vl_rmask(BIT(intr));
 }
 
 static void gic_unmask_local_irq(struct irq_data *d)
 {
 	int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
 
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
+	write_gic_vl_smask(BIT(intr));
 }
 
 static struct irq_chip gic_local_irq_controller = {
@@ -373,7 +373,7 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
 	for (i = 0; i < gic_vpes; i++) {
 		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
 			  mips_cm_vp_id(i));
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
+		write_gic_vo_rmask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
 }
@@ -388,7 +388,7 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
 	for (i = 0; i < gic_vpes; i++) {
 		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
 			  mips_cm_vp_id(i));
-		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
+		write_gic_vo_smask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
 }
@@ -432,7 +432,7 @@ static void __init gic_basic_init(void)
 		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
 			if (!gic_local_irq_is_routable(j))
 				continue;
-			gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
+			write_gic_vo_rmask(BIT(j));
 		}
 	}
 }
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index f0a60770d775..011698962a8d 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -28,10 +28,6 @@
 
 /* Register Map for Local Section */
 #define GIC_VPE_CTL_OFS			0x0000
-#define GIC_VPE_PEND_OFS		0x0004
-#define GIC_VPE_MASK_OFS		0x0008
-#define GIC_VPE_RMASK_OFS		0x000c
-#define GIC_VPE_SMASK_OFS		0x0010
 #define GIC_VPE_TIMER_MAP_OFS		0x0048
 #define GIC_VPE_OTHER_ADDR_OFS		0x0080
 #define GIC_VPE_WD_CONFIG0_OFS		0x0090
@@ -69,54 +65,6 @@
 #define GIC_VPE_CTL_EIC_MODE_SHF	0
 #define GIC_VPE_CTL_EIC_MODE_MSK	(MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
 
-/* GIC_VPE_PEND Masks */
-#define GIC_VPE_PEND_WD_SHF		0
-#define GIC_VPE_PEND_WD_MSK		(MSK(1) << GIC_VPE_PEND_WD_SHF)
-#define GIC_VPE_PEND_CMP_SHF		1
-#define GIC_VPE_PEND_CMP_MSK		(MSK(1) << GIC_VPE_PEND_CMP_SHF)
-#define GIC_VPE_PEND_TIMER_SHF		2
-#define GIC_VPE_PEND_TIMER_MSK		(MSK(1) << GIC_VPE_PEND_TIMER_SHF)
-#define GIC_VPE_PEND_PERFCOUNT_SHF	3
-#define GIC_VPE_PEND_PERFCOUNT_MSK	(MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF)
-#define GIC_VPE_PEND_SWINT0_SHF		4
-#define GIC_VPE_PEND_SWINT0_MSK		(MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
-#define GIC_VPE_PEND_SWINT1_SHF		5
-#define GIC_VPE_PEND_SWINT1_MSK		(MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
-#define GIC_VPE_PEND_FDC_SHF		6
-#define GIC_VPE_PEND_FDC_MSK		(MSK(1) << GIC_VPE_PEND_FDC_SHF)
-
-/* GIC_VPE_RMASK Masks */
-#define GIC_VPE_RMASK_WD_SHF		0
-#define GIC_VPE_RMASK_WD_MSK		(MSK(1) << GIC_VPE_RMASK_WD_SHF)
-#define GIC_VPE_RMASK_CMP_SHF		1
-#define GIC_VPE_RMASK_CMP_MSK		(MSK(1) << GIC_VPE_RMASK_CMP_SHF)
-#define GIC_VPE_RMASK_TIMER_SHF		2
-#define GIC_VPE_RMASK_TIMER_MSK		(MSK(1) << GIC_VPE_RMASK_TIMER_SHF)
-#define GIC_VPE_RMASK_PERFCNT_SHF	3
-#define GIC_VPE_RMASK_PERFCNT_MSK	(MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF)
-#define GIC_VPE_RMASK_SWINT0_SHF	4
-#define GIC_VPE_RMASK_SWINT0_MSK	(MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
-#define GIC_VPE_RMASK_SWINT1_SHF	5
-#define GIC_VPE_RMASK_SWINT1_MSK	(MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
-#define GIC_VPE_RMASK_FDC_SHF		6
-#define GIC_VPE_RMASK_FDC_MSK		(MSK(1) << GIC_VPE_RMASK_FDC_SHF)
-
-/* GIC_VPE_SMASK Masks */
-#define GIC_VPE_SMASK_WD_SHF		0
-#define GIC_VPE_SMASK_WD_MSK		(MSK(1) << GIC_VPE_SMASK_WD_SHF)
-#define GIC_VPE_SMASK_CMP_SHF		1
-#define GIC_VPE_SMASK_CMP_MSK		(MSK(1) << GIC_VPE_SMASK_CMP_SHF)
-#define GIC_VPE_SMASK_TIMER_SHF		2
-#define GIC_VPE_SMASK_TIMER_MSK		(MSK(1) << GIC_VPE_SMASK_TIMER_SHF)
-#define GIC_VPE_SMASK_PERFCNT_SHF	3
-#define GIC_VPE_SMASK_PERFCNT_MSK	(MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF)
-#define GIC_VPE_SMASK_SWINT0_SHF	4
-#define GIC_VPE_SMASK_SWINT0_MSK	(MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
-#define GIC_VPE_SMASK_SWINT1_SHF	5
-#define GIC_VPE_SMASK_SWINT1_MSK	(MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
-#define GIC_VPE_SMASK_FDC_SHF		6
-#define GIC_VPE_SMASK_FDC_MSK		(MSK(1) << GIC_VPE_SMASK_FDC_SHF)
-
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0		0 /* Core Interrupt 2 */
 #define GIC_CPU_INT1		1 /* .		      */
-- 
2.14.0

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

* [PATCH 18/38] irqchip: mips-gic: Convert remaining local reg access to new accessors
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (17 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 17/38] irqchip: mips-gic: Convert local int mask " Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 19/38] MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h Paul Burton
                   ` (21 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Convert the remaining accesses to registers in the GIC VP-local &
VP-other register blocks to use the new accessor functions provided by
asm/mips-gic.h, resulting in code which is often shorter & easier to
read.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 68 +++++++---------------------------------
 include/linux/irqchip/mips-gic.h | 44 --------------------------
 2 files changed, 12 insertions(+), 100 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index ac4ba4f7c2d6..5b282a7fd7e0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -45,42 +45,6 @@ DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
 static void __gic_irq_dispatch(void);
 
-static inline u32 gic_read32(unsigned int reg)
-{
-	return __raw_readl(mips_gic_base + reg);
-}
-
-static inline u64 gic_read64(unsigned int reg)
-{
-	return __raw_readq(mips_gic_base + reg);
-}
-
-static inline unsigned long gic_read(unsigned int reg)
-{
-	if (!mips_cm_is64)
-		return gic_read32(reg);
-	else
-		return gic_read64(reg);
-}
-
-static inline void gic_write32(unsigned int reg, u32 val)
-{
-	return __raw_writel(val, mips_gic_base + reg);
-}
-
-static inline void gic_write64(unsigned int reg, u64 val)
-{
-	return __raw_writeq(val, mips_gic_base + reg);
-}
-
-static inline void gic_write(unsigned int reg, unsigned long val)
-{
-	if (!mips_cm_is64)
-		return gic_write32(reg, (u32)val);
-	else
-		return gic_write64(reg, (u64)val);
-}
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -89,17 +53,17 @@ static bool gic_local_irq_is_routable(int intr)
 	if (cpu_has_veic)
 		return true;
 
-	vpe_ctl = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));
+	vpe_ctl = read_gic_vl_ctl();
 	switch (intr) {
 	case GIC_LOCAL_INT_TIMER:
-		return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_TIMER_ROUTABLE;
 	case GIC_LOCAL_INT_PERFCTR:
-		return vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_PERFCNT_ROUTABLE;
 	case GIC_LOCAL_INT_FDC:
-		return vpe_ctl & GIC_VPE_CTL_FDC_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_FDC_ROUTABLE;
 	case GIC_LOCAL_INT_SWINT0:
 	case GIC_LOCAL_INT_SWINT1:
-		return vpe_ctl & GIC_VPE_CTL_SWINT_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_SWINT_ROUTABLE;
 	default:
 		return true;
 	}
@@ -111,8 +75,7 @@ static void gic_bind_eic_interrupt(int irq, int set)
 	irq -= GIC_PIN_TO_VEC_OFFSET;
 
 	/* Set irq to use shadow set */
-	gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_EIC_SHADOW_SET_BASE) +
-		  GIC_VPE_EIC_SS(irq), set);
+	write_gic_vl_eic_shadow_set(irq, set);
 }
 
 static void gic_send_ipi(struct irq_data *d, unsigned int cpu)
@@ -371,8 +334,7 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
 
 	spin_lock_irqsave(&gic_lock, flags);
 	for (i = 0; i < gic_vpes; i++) {
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+		write_gic_vl_other(mips_cm_vp_id(i));
 		write_gic_vo_rmask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -386,8 +348,7 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
 
 	spin_lock_irqsave(&gic_lock, flags);
 	for (i = 0; i < gic_vpes; i++) {
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+		write_gic_vl_other(mips_cm_vp_id(i));
 		write_gic_vo_smask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -427,8 +388,7 @@ static void __init gic_basic_init(void)
 	for (i = 0; i < gic_vpes; i++) {
 		unsigned int j;
 
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+		write_gic_vl_other(mips_cm_vp_id(i));
 		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
 			if (!gic_local_irq_is_routable(j))
 				continue;
@@ -712,10 +672,8 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	if (cpu_has_veic) {
 		/* Set EIC mode for all VPEs */
 		for_each_present_cpu(cpu) {
-			gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-				  mips_cm_vp_id(cpu));
-			gic_write(GIC_REG(VPE_OTHER, GIC_VPE_CTL),
-				  GIC_VPE_CTL_EIC_MODE_MSK);
+			write_gic_vl_other(mips_cm_vp_id(cpu));
+			write_gic_vo_ctl(GIC_VX_CTL_EIC);
 		}
 
 		/* Always use vector 1 in EIC mode */
@@ -740,9 +698,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
 		 */
 		if (IS_ENABLED(CONFIG_MIPS_CMP) &&
 		    gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) {
-			timer_cpu_pin = gic_read32(GIC_REG(VPE_LOCAL,
-							 GIC_VPE_TIMER_MAP)) &
-					GIC_MAP_MSK;
+			timer_cpu_pin = read_gic_vl_timer_map() & GIC_MAP_PIN_MAP;
 			irq_set_chained_handler(MIPS_CPU_IRQ_BASE +
 						GIC_CPU_PIN_OFFSET +
 						timer_cpu_pin,
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 011698962a8d..b7a3ce1da9a7 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -13,58 +13,14 @@
 
 #define GIC_MAX_INTRS			256
 
-#define MSK(n) ((1 << (n)) - 1)
-
-/* Accessors */
-#define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS)
-
 /* GIC Address Space */
-#define VPE_LOCAL_SECTION_OFS		0x8000
-#define VPE_LOCAL_SECTION_SIZE		0x4000
-#define VPE_OTHER_SECTION_OFS		0xc000
-#define VPE_OTHER_SECTION_SIZE		0x4000
 #define USM_VISIBLE_SECTION_OFS		0x10000
 #define USM_VISIBLE_SECTION_SIZE	0x10000
 
-/* Register Map for Local Section */
-#define GIC_VPE_CTL_OFS			0x0000
-#define GIC_VPE_TIMER_MAP_OFS		0x0048
-#define GIC_VPE_OTHER_ADDR_OFS		0x0080
-#define GIC_VPE_WD_CONFIG0_OFS		0x0090
-#define GIC_VPE_WD_COUNT0_OFS		0x0094
-#define GIC_VPE_WD_INITIAL0_OFS		0x0098
-
-#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS	0x0100
-#define GIC_VPE_EIC_SS(intr)		(4 * (intr))
-
-#define GIC_VPE_EIC_VEC_BASE_OFS	0x0800
-#define GIC_VPE_EIC_VEC(intr)		(4 * (intr))
-
-#define GIC_VPE_TENABLE_NMI_OFS		0x1000
-#define GIC_VPE_TENABLE_YQ_OFS		0x1004
-#define GIC_VPE_TENABLE_INT_31_0_OFS	0x1080
-#define GIC_VPE_TENABLE_INT_63_32_OFS	0x1084
-
 /* User Mode Visible Section Register Map */
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-/* Masks */
-#define GIC_MAP_SHF			0
-#define GIC_MAP_MSK			(MSK(6) << GIC_MAP_SHF)
-
-/* GIC_VPE_CTL Masks */
-#define GIC_VPE_CTL_FDC_RTBL_SHF	4
-#define GIC_VPE_CTL_FDC_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_FDC_RTBL_SHF)
-#define GIC_VPE_CTL_SWINT_RTBL_SHF	3
-#define GIC_VPE_CTL_SWINT_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_SWINT_RTBL_SHF)
-#define GIC_VPE_CTL_PERFCNT_RTBL_SHF	2
-#define GIC_VPE_CTL_PERFCNT_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF)
-#define GIC_VPE_CTL_TIMER_RTBL_SHF	1
-#define GIC_VPE_CTL_TIMER_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF)
-#define GIC_VPE_CTL_EIC_MODE_SHF	0
-#define GIC_VPE_CTL_EIC_MODE_MSK	(MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
-
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0		0 /* Core Interrupt 2 */
 #define GIC_CPU_INT1		1 /* .		      */
-- 
2.14.0

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

* [PATCH 18/38] irqchip: mips-gic: Convert remaining local reg access to new accessors
  2017-08-13  4:36 ` [PATCH 18/38] irqchip: mips-gic: Convert remaining local reg " Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Convert the remaining accesses to registers in the GIC VP-local &
VP-other register blocks to use the new accessor functions provided by
asm/mips-gic.h, resulting in code which is often shorter & easier to
read.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 68 +++++++---------------------------------
 include/linux/irqchip/mips-gic.h | 44 --------------------------
 2 files changed, 12 insertions(+), 100 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index ac4ba4f7c2d6..5b282a7fd7e0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -45,42 +45,6 @@ DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
 static void __gic_irq_dispatch(void);
 
-static inline u32 gic_read32(unsigned int reg)
-{
-	return __raw_readl(mips_gic_base + reg);
-}
-
-static inline u64 gic_read64(unsigned int reg)
-{
-	return __raw_readq(mips_gic_base + reg);
-}
-
-static inline unsigned long gic_read(unsigned int reg)
-{
-	if (!mips_cm_is64)
-		return gic_read32(reg);
-	else
-		return gic_read64(reg);
-}
-
-static inline void gic_write32(unsigned int reg, u32 val)
-{
-	return __raw_writel(val, mips_gic_base + reg);
-}
-
-static inline void gic_write64(unsigned int reg, u64 val)
-{
-	return __raw_writeq(val, mips_gic_base + reg);
-}
-
-static inline void gic_write(unsigned int reg, unsigned long val)
-{
-	if (!mips_cm_is64)
-		return gic_write32(reg, (u32)val);
-	else
-		return gic_write64(reg, (u64)val);
-}
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -89,17 +53,17 @@ static bool gic_local_irq_is_routable(int intr)
 	if (cpu_has_veic)
 		return true;
 
-	vpe_ctl = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));
+	vpe_ctl = read_gic_vl_ctl();
 	switch (intr) {
 	case GIC_LOCAL_INT_TIMER:
-		return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_TIMER_ROUTABLE;
 	case GIC_LOCAL_INT_PERFCTR:
-		return vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_PERFCNT_ROUTABLE;
 	case GIC_LOCAL_INT_FDC:
-		return vpe_ctl & GIC_VPE_CTL_FDC_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_FDC_ROUTABLE;
 	case GIC_LOCAL_INT_SWINT0:
 	case GIC_LOCAL_INT_SWINT1:
-		return vpe_ctl & GIC_VPE_CTL_SWINT_RTBL_MSK;
+		return vpe_ctl & GIC_VX_CTL_SWINT_ROUTABLE;
 	default:
 		return true;
 	}
@@ -111,8 +75,7 @@ static void gic_bind_eic_interrupt(int irq, int set)
 	irq -= GIC_PIN_TO_VEC_OFFSET;
 
 	/* Set irq to use shadow set */
-	gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_EIC_SHADOW_SET_BASE) +
-		  GIC_VPE_EIC_SS(irq), set);
+	write_gic_vl_eic_shadow_set(irq, set);
 }
 
 static void gic_send_ipi(struct irq_data *d, unsigned int cpu)
@@ -371,8 +334,7 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
 
 	spin_lock_irqsave(&gic_lock, flags);
 	for (i = 0; i < gic_vpes; i++) {
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+		write_gic_vl_other(mips_cm_vp_id(i));
 		write_gic_vo_rmask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -386,8 +348,7 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
 
 	spin_lock_irqsave(&gic_lock, flags);
 	for (i = 0; i < gic_vpes; i++) {
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+		write_gic_vl_other(mips_cm_vp_id(i));
 		write_gic_vo_smask(BIT(intr));
 	}
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -427,8 +388,7 @@ static void __init gic_basic_init(void)
 	for (i = 0; i < gic_vpes; i++) {
 		unsigned int j;
 
-		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-			  mips_cm_vp_id(i));
+		write_gic_vl_other(mips_cm_vp_id(i));
 		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
 			if (!gic_local_irq_is_routable(j))
 				continue;
@@ -712,10 +672,8 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	if (cpu_has_veic) {
 		/* Set EIC mode for all VPEs */
 		for_each_present_cpu(cpu) {
-			gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
-				  mips_cm_vp_id(cpu));
-			gic_write(GIC_REG(VPE_OTHER, GIC_VPE_CTL),
-				  GIC_VPE_CTL_EIC_MODE_MSK);
+			write_gic_vl_other(mips_cm_vp_id(cpu));
+			write_gic_vo_ctl(GIC_VX_CTL_EIC);
 		}
 
 		/* Always use vector 1 in EIC mode */
@@ -740,9 +698,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
 		 */
 		if (IS_ENABLED(CONFIG_MIPS_CMP) &&
 		    gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) {
-			timer_cpu_pin = gic_read32(GIC_REG(VPE_LOCAL,
-							 GIC_VPE_TIMER_MAP)) &
-					GIC_MAP_MSK;
+			timer_cpu_pin = read_gic_vl_timer_map() & GIC_MAP_PIN_MAP;
 			irq_set_chained_handler(MIPS_CPU_IRQ_BASE +
 						GIC_CPU_PIN_OFFSET +
 						timer_cpu_pin,
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 011698962a8d..b7a3ce1da9a7 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -13,58 +13,14 @@
 
 #define GIC_MAX_INTRS			256
 
-#define MSK(n) ((1 << (n)) - 1)
-
-/* Accessors */
-#define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS)
-
 /* GIC Address Space */
-#define VPE_LOCAL_SECTION_OFS		0x8000
-#define VPE_LOCAL_SECTION_SIZE		0x4000
-#define VPE_OTHER_SECTION_OFS		0xc000
-#define VPE_OTHER_SECTION_SIZE		0x4000
 #define USM_VISIBLE_SECTION_OFS		0x10000
 #define USM_VISIBLE_SECTION_SIZE	0x10000
 
-/* Register Map for Local Section */
-#define GIC_VPE_CTL_OFS			0x0000
-#define GIC_VPE_TIMER_MAP_OFS		0x0048
-#define GIC_VPE_OTHER_ADDR_OFS		0x0080
-#define GIC_VPE_WD_CONFIG0_OFS		0x0090
-#define GIC_VPE_WD_COUNT0_OFS		0x0094
-#define GIC_VPE_WD_INITIAL0_OFS		0x0098
-
-#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS	0x0100
-#define GIC_VPE_EIC_SS(intr)		(4 * (intr))
-
-#define GIC_VPE_EIC_VEC_BASE_OFS	0x0800
-#define GIC_VPE_EIC_VEC(intr)		(4 * (intr))
-
-#define GIC_VPE_TENABLE_NMI_OFS		0x1000
-#define GIC_VPE_TENABLE_YQ_OFS		0x1004
-#define GIC_VPE_TENABLE_INT_31_0_OFS	0x1080
-#define GIC_VPE_TENABLE_INT_63_32_OFS	0x1084
-
 /* User Mode Visible Section Register Map */
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-/* Masks */
-#define GIC_MAP_SHF			0
-#define GIC_MAP_MSK			(MSK(6) << GIC_MAP_SHF)
-
-/* GIC_VPE_CTL Masks */
-#define GIC_VPE_CTL_FDC_RTBL_SHF	4
-#define GIC_VPE_CTL_FDC_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_FDC_RTBL_SHF)
-#define GIC_VPE_CTL_SWINT_RTBL_SHF	3
-#define GIC_VPE_CTL_SWINT_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_SWINT_RTBL_SHF)
-#define GIC_VPE_CTL_PERFCNT_RTBL_SHF	2
-#define GIC_VPE_CTL_PERFCNT_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF)
-#define GIC_VPE_CTL_TIMER_RTBL_SHF	1
-#define GIC_VPE_CTL_TIMER_RTBL_MSK	(MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF)
-#define GIC_VPE_CTL_EIC_MODE_SHF	0
-#define GIC_VPE_CTL_EIC_MODE_MSK	(MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
-
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0		0 /* Core Interrupt 2 */
 #define GIC_CPU_INT1		1 /* .		      */
-- 
2.14.0

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

* [PATCH 19/38] MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (18 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 18/38] irqchip: mips-gic: Convert remaining local reg " Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 20/38] irqchip: mips-gic: Remove GIC_CPU_INT* macros Paul Burton
                   ` (20 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Move the definition of VP-local interrupts provided by the MIPS Global
Interrupt Controller to the new asm/mips-gic.h header to be alongside
the new accessor functions. Whilst at it, convert to an enum which lends
itself more easily to expansion & documentation.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-gic.h | 24 ++++++++++++++++++++++++
 include/linux/irqchip/mips-gic.h | 10 ----------
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
index 8cf4bdc1a059..27736d7f4aba 100644
--- a/arch/mips/include/asm/mips-gic.h
+++ b/arch/mips/include/asm/mips-gic.h
@@ -277,6 +277,30 @@ GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
 /* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
 GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
 
+/**
+ * enum mips_gic_local_interrupt - GIC local interrupts
+ * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
+ * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
+ * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
+ * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
+ * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
+ * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
+ * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
+ * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
+ *
+ * Enumerates interrupts provided by the GIC that are local to a VP.
+ */
+enum mips_gic_local_interrupt {
+	GIC_LOCAL_INT_WD,
+	GIC_LOCAL_INT_COMPARE,
+	GIC_LOCAL_INT_TIMER,
+	GIC_LOCAL_INT_PERFCTR,
+	GIC_LOCAL_INT_SWINT0,
+	GIC_LOCAL_INT_SWINT1,
+	GIC_LOCAL_INT_FDC,
+	GIC_NUM_LOCAL_INTRS
+};
+
 /**
  * mips_gic_present() - Determine whether a GIC is present
  *
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index b7a3ce1da9a7..9546947d1842 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -38,16 +38,6 @@
 /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
 #define GIC_PIN_TO_VEC_OFFSET	1
 
-/* Local GIC interrupts. */
-#define GIC_LOCAL_INT_WD	0 /* GIC watchdog */
-#define GIC_LOCAL_INT_COMPARE	1 /* GIC count and compare timer */
-#define GIC_LOCAL_INT_TIMER	2 /* CPU timer interrupt */
-#define GIC_LOCAL_INT_PERFCTR	3 /* CPU performance counter */
-#define GIC_LOCAL_INT_SWINT0	4 /* CPU software interrupt 0 */
-#define GIC_LOCAL_INT_SWINT1	5 /* CPU software interrupt 1 */
-#define GIC_LOCAL_INT_FDC	6 /* CPU fast debug channel */
-#define GIC_NUM_LOCAL_INTRS	7
-
 /* Convert between local/shared IRQ number and GIC HW IRQ number. */
 #define GIC_LOCAL_HWIRQ_BASE	0
 #define GIC_LOCAL_TO_HWIRQ(x)	(GIC_LOCAL_HWIRQ_BASE + (x))
-- 
2.14.0

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

* [PATCH 19/38] MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h
  2017-08-13  4:36 ` [PATCH 19/38] MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Move the definition of VP-local interrupts provided by the MIPS Global
Interrupt Controller to the new asm/mips-gic.h header to be alongside
the new accessor functions. Whilst at it, convert to an enum which lends
itself more easily to expansion & documentation.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-gic.h | 24 ++++++++++++++++++++++++
 include/linux/irqchip/mips-gic.h | 10 ----------
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
index 8cf4bdc1a059..27736d7f4aba 100644
--- a/arch/mips/include/asm/mips-gic.h
+++ b/arch/mips/include/asm/mips-gic.h
@@ -277,6 +277,30 @@ GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
 /* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
 GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
 
+/**
+ * enum mips_gic_local_interrupt - GIC local interrupts
+ * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
+ * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
+ * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
+ * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
+ * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
+ * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
+ * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
+ * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
+ *
+ * Enumerates interrupts provided by the GIC that are local to a VP.
+ */
+enum mips_gic_local_interrupt {
+	GIC_LOCAL_INT_WD,
+	GIC_LOCAL_INT_COMPARE,
+	GIC_LOCAL_INT_TIMER,
+	GIC_LOCAL_INT_PERFCTR,
+	GIC_LOCAL_INT_SWINT0,
+	GIC_LOCAL_INT_SWINT1,
+	GIC_LOCAL_INT_FDC,
+	GIC_NUM_LOCAL_INTRS
+};
+
 /**
  * mips_gic_present() - Determine whether a GIC is present
  *
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index b7a3ce1da9a7..9546947d1842 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -38,16 +38,6 @@
 /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
 #define GIC_PIN_TO_VEC_OFFSET	1
 
-/* Local GIC interrupts. */
-#define GIC_LOCAL_INT_WD	0 /* GIC watchdog */
-#define GIC_LOCAL_INT_COMPARE	1 /* GIC count and compare timer */
-#define GIC_LOCAL_INT_TIMER	2 /* CPU timer interrupt */
-#define GIC_LOCAL_INT_PERFCTR	3 /* CPU performance counter */
-#define GIC_LOCAL_INT_SWINT0	4 /* CPU software interrupt 0 */
-#define GIC_LOCAL_INT_SWINT1	5 /* CPU software interrupt 1 */
-#define GIC_LOCAL_INT_FDC	6 /* CPU fast debug channel */
-#define GIC_NUM_LOCAL_INTRS	7
-
 /* Convert between local/shared IRQ number and GIC HW IRQ number. */
 #define GIC_LOCAL_HWIRQ_BASE	0
 #define GIC_LOCAL_TO_HWIRQ(x)	(GIC_LOCAL_HWIRQ_BASE + (x))
-- 
2.14.0

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

* [PATCH 20/38] irqchip: mips-gic: Remove GIC_CPU_INT* macros
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (19 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 19/38] MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 21/38] irqchip: mips-gic: Move various definitions to the driver Paul Burton
                   ` (19 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The GIC_CPU_INT* macros are never used. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 include/linux/irqchip/mips-gic.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 9546947d1842..e93aaf529baa 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -21,14 +21,6 @@
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-/* GIC nomenclature for Core Interrupt Pins. */
-#define GIC_CPU_INT0		0 /* Core Interrupt 2 */
-#define GIC_CPU_INT1		1 /* .		      */
-#define GIC_CPU_INT2		2 /* .		      */
-#define GIC_CPU_INT3		3 /* .		      */
-#define GIC_CPU_INT4		4 /* .		      */
-#define GIC_CPU_INT5		5 /* Core Interrupt 7 */
-
 /* Add 2 to convert GIC CPU pin to core interrupt */
 #define GIC_CPU_PIN_OFFSET	2
 
-- 
2.14.0

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

* [PATCH 20/38] irqchip: mips-gic: Remove GIC_CPU_INT* macros
  2017-08-13  4:36 ` [PATCH 20/38] irqchip: mips-gic: Remove GIC_CPU_INT* macros Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The GIC_CPU_INT* macros are never used. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 include/linux/irqchip/mips-gic.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 9546947d1842..e93aaf529baa 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -21,14 +21,6 @@
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-/* GIC nomenclature for Core Interrupt Pins. */
-#define GIC_CPU_INT0		0 /* Core Interrupt 2 */
-#define GIC_CPU_INT1		1 /* .		      */
-#define GIC_CPU_INT2		2 /* .		      */
-#define GIC_CPU_INT3		3 /* .		      */
-#define GIC_CPU_INT4		4 /* .		      */
-#define GIC_CPU_INT5		5 /* Core Interrupt 7 */
-
 /* Add 2 to convert GIC CPU pin to core interrupt */
 #define GIC_CPU_PIN_OFFSET	2
 
-- 
2.14.0

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

* [PATCH 21/38] irqchip: mips-gic: Move various definitions to the driver
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (20 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 20/38] irqchip: mips-gic: Remove GIC_CPU_INT* macros Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage Paul Burton
                   ` (18 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Move the definitions of macros used to convert between hardware IRQ
numbers & shared or local interrupt numbers into the irqchip driver,
which is all that should ever need to care about them.

Remove GIC_CPU_TO_VEC_OFFSET() in the process since it's never used.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-boards/maltaint.h |  5 -----
 drivers/irqchip/irq-mips-gic.c               | 16 ++++++++++++++++
 include/linux/irqchip/mips-gic.h             | 19 -------------------
 3 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index 987ff580466b..817698abf2eb 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -10,8 +10,6 @@
 #ifndef _MIPS_MALTAINT_H
 #define _MIPS_MALTAINT_H
 
-#include <linux/irqchip/mips-gic.h>
-
 /*
  * Interrupts 0..15 are used for Malta ISA compatible interrupts
  */
@@ -62,7 +60,4 @@
 #define MSC01E_INT_PERFCTR	10
 #define MSC01E_INT_CPUCTR	11
 
-/* GIC external interrupts */
-#define GIC_INT_I8259A		GIC_SHARED_TO_HWIRQ(3)
-
 #endif /* !(_MIPS_MALTAINT_H) */
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 5b282a7fd7e0..d6fbc5d6e8e2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -23,6 +23,22 @@
 
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 
+#define GIC_MAX_INTRS		256
+
+/* Add 2 to convert GIC CPU pin to core interrupt */
+#define GIC_CPU_PIN_OFFSET	2
+
+/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
+#define GIC_PIN_TO_VEC_OFFSET	1
+
+/* Convert between local/shared IRQ number and GIC HW IRQ number. */
+#define GIC_LOCAL_HWIRQ_BASE	0
+#define GIC_LOCAL_TO_HWIRQ(x)	(GIC_LOCAL_HWIRQ_BASE + (x))
+#define GIC_HWIRQ_TO_LOCAL(x)	((x) - GIC_LOCAL_HWIRQ_BASE)
+#define GIC_SHARED_HWIRQ_BASE	GIC_NUM_LOCAL_INTRS
+#define GIC_SHARED_TO_HWIRQ(x)	(GIC_SHARED_HWIRQ_BASE + (x))
+#define GIC_HWIRQ_TO_SHARED(x)	((x) - GIC_SHARED_HWIRQ_BASE)
+
 unsigned int gic_present;
 void __iomem *mips_gic_base;
 
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index e93aaf529baa..da02a146b292 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -11,8 +11,6 @@
 #include <linux/clocksource.h>
 #include <linux/ioport.h>
 
-#define GIC_MAX_INTRS			256
-
 /* GIC Address Space */
 #define USM_VISIBLE_SECTION_OFS		0x10000
 #define USM_VISIBLE_SECTION_SIZE	0x10000
@@ -21,23 +19,6 @@
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-/* Add 2 to convert GIC CPU pin to core interrupt */
-#define GIC_CPU_PIN_OFFSET	2
-
-/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
-#define GIC_CPU_TO_VEC_OFFSET	2
-
-/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
-#define GIC_PIN_TO_VEC_OFFSET	1
-
-/* Convert between local/shared IRQ number and GIC HW IRQ number. */
-#define GIC_LOCAL_HWIRQ_BASE	0
-#define GIC_LOCAL_TO_HWIRQ(x)	(GIC_LOCAL_HWIRQ_BASE + (x))
-#define GIC_HWIRQ_TO_LOCAL(x)	((x) - GIC_LOCAL_HWIRQ_BASE)
-#define GIC_SHARED_HWIRQ_BASE	GIC_NUM_LOCAL_INTRS
-#define GIC_SHARED_TO_HWIRQ(x)	(GIC_SHARED_HWIRQ_BASE + (x))
-#define GIC_HWIRQ_TO_SHARED(x)	((x) - GIC_SHARED_HWIRQ_BASE)
-
 #ifdef CONFIG_MIPS_GIC
 
 extern unsigned int gic_present;
-- 
2.14.0

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

* [PATCH 21/38] irqchip: mips-gic: Move various definitions to the driver
  2017-08-13  4:36 ` [PATCH 21/38] irqchip: mips-gic: Move various definitions to the driver Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Move the definitions of macros used to convert between hardware IRQ
numbers & shared or local interrupt numbers into the irqchip driver,
which is all that should ever need to care about them.

Remove GIC_CPU_TO_VEC_OFFSET() in the process since it's never used.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-boards/maltaint.h |  5 -----
 drivers/irqchip/irq-mips-gic.c               | 16 ++++++++++++++++
 include/linux/irqchip/mips-gic.h             | 19 -------------------
 3 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index 987ff580466b..817698abf2eb 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -10,8 +10,6 @@
 #ifndef _MIPS_MALTAINT_H
 #define _MIPS_MALTAINT_H
 
-#include <linux/irqchip/mips-gic.h>
-
 /*
  * Interrupts 0..15 are used for Malta ISA compatible interrupts
  */
@@ -62,7 +60,4 @@
 #define MSC01E_INT_PERFCTR	10
 #define MSC01E_INT_CPUCTR	11
 
-/* GIC external interrupts */
-#define GIC_INT_I8259A		GIC_SHARED_TO_HWIRQ(3)
-
 #endif /* !(_MIPS_MALTAINT_H) */
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 5b282a7fd7e0..d6fbc5d6e8e2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -23,6 +23,22 @@
 
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 
+#define GIC_MAX_INTRS		256
+
+/* Add 2 to convert GIC CPU pin to core interrupt */
+#define GIC_CPU_PIN_OFFSET	2
+
+/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
+#define GIC_PIN_TO_VEC_OFFSET	1
+
+/* Convert between local/shared IRQ number and GIC HW IRQ number. */
+#define GIC_LOCAL_HWIRQ_BASE	0
+#define GIC_LOCAL_TO_HWIRQ(x)	(GIC_LOCAL_HWIRQ_BASE + (x))
+#define GIC_HWIRQ_TO_LOCAL(x)	((x) - GIC_LOCAL_HWIRQ_BASE)
+#define GIC_SHARED_HWIRQ_BASE	GIC_NUM_LOCAL_INTRS
+#define GIC_SHARED_TO_HWIRQ(x)	(GIC_SHARED_HWIRQ_BASE + (x))
+#define GIC_HWIRQ_TO_SHARED(x)	((x) - GIC_SHARED_HWIRQ_BASE)
+
 unsigned int gic_present;
 void __iomem *mips_gic_base;
 
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index e93aaf529baa..da02a146b292 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -11,8 +11,6 @@
 #include <linux/clocksource.h>
 #include <linux/ioport.h>
 
-#define GIC_MAX_INTRS			256
-
 /* GIC Address Space */
 #define USM_VISIBLE_SECTION_OFS		0x10000
 #define USM_VISIBLE_SECTION_SIZE	0x10000
@@ -21,23 +19,6 @@
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-/* Add 2 to convert GIC CPU pin to core interrupt */
-#define GIC_CPU_PIN_OFFSET	2
-
-/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
-#define GIC_CPU_TO_VEC_OFFSET	2
-
-/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
-#define GIC_PIN_TO_VEC_OFFSET	1
-
-/* Convert between local/shared IRQ number and GIC HW IRQ number. */
-#define GIC_LOCAL_HWIRQ_BASE	0
-#define GIC_LOCAL_TO_HWIRQ(x)	(GIC_LOCAL_HWIRQ_BASE + (x))
-#define GIC_HWIRQ_TO_LOCAL(x)	((x) - GIC_LOCAL_HWIRQ_BASE)
-#define GIC_SHARED_HWIRQ_BASE	GIC_NUM_LOCAL_INTRS
-#define GIC_SHARED_TO_HWIRQ(x)	(GIC_SHARED_HWIRQ_BASE + (x))
-#define GIC_HWIRQ_TO_SHARED(x)	((x) - GIC_SHARED_HWIRQ_BASE)
-
 #ifdef CONFIG_MIPS_GIC
 
 extern unsigned int gic_present;
-- 
2.14.0

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

* [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (21 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 21/38] irqchip: mips-gic: Move various definitions to the driver Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-18 11:38   ` Marc Zyngier
  2017-08-13  4:36 ` [PATCH 23/38] irqchip: mips-gic: Remove gic_get_usm_range() Paul Burton
                   ` (17 subsequent siblings)
  40 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

We don't really need gic_get_usm_range() to abstract discovery of the
address of the GIC user-visible section now that we have access to its
base address globally.

Switch to calculating it ourselves, which will allow us to stop
requiring the irqchip driver to care about a counter exposed to userland
for use via the VDSO.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/vdso.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 093517e85a6c..019035d7225c 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -13,13 +13,13 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/timekeeper_internal.h>
 
 #include <asm/abi.h>
+#include <asm/mips-cps.h>
 #include <asm/vdso.h>
 
 /* Kernel-provided data used by the VDSO. */
@@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mips_vdso_image *image = current->thread.abi->vdso;
 	struct mm_struct *mm = current->mm;
-	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
+	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn;
 	struct vm_area_struct *vma;
-	struct resource gic_res;
 	int ret;
 
 	if (down_write_killable(&mm->mmap_sem))
@@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	 * only map a page even though the total area is 64K, as we only need
 	 * the counter registers at the start.
 	 */
-	gic_size = gic_present ? PAGE_SIZE : 0;
+	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
 	vvar_size = gic_size + PAGE_SIZE;
 	size = vvar_size + image->size;
 
@@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
 	/* Map GIC user page. */
 	if (gic_size) {
-		ret = gic_get_usm_range(&gic_res);
-		if (ret)
-			goto out;
+		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT;
 
-		ret = io_remap_pfn_range(vma, base,
-					 gic_res.start >> PAGE_SHIFT,
-					 gic_size,
+		ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
 					 pgprot_noncached(PAGE_READONLY));
 		if (ret)
 			goto out;
-- 
2.14.0

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

* [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage
  2017-08-13  4:36 ` [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  2017-08-18 11:38   ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

We don't really need gic_get_usm_range() to abstract discovery of the
address of the GIC user-visible section now that we have access to its
base address globally.

Switch to calculating it ourselves, which will allow us to stop
requiring the irqchip driver to care about a counter exposed to userland
for use via the VDSO.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/vdso.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 093517e85a6c..019035d7225c 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -13,13 +13,13 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/timekeeper_internal.h>
 
 #include <asm/abi.h>
+#include <asm/mips-cps.h>
 #include <asm/vdso.h>
 
 /* Kernel-provided data used by the VDSO. */
@@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mips_vdso_image *image = current->thread.abi->vdso;
 	struct mm_struct *mm = current->mm;
-	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
+	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn;
 	struct vm_area_struct *vma;
-	struct resource gic_res;
 	int ret;
 
 	if (down_write_killable(&mm->mmap_sem))
@@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	 * only map a page even though the total area is 64K, as we only need
 	 * the counter registers at the start.
 	 */
-	gic_size = gic_present ? PAGE_SIZE : 0;
+	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
 	vvar_size = gic_size + PAGE_SIZE;
 	size = vvar_size + image->size;
 
@@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
 	/* Map GIC user page. */
 	if (gic_size) {
-		ret = gic_get_usm_range(&gic_res);
-		if (ret)
-			goto out;
+		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT;
 
-		ret = io_remap_pfn_range(vma, base,
-					 gic_res.start >> PAGE_SHIFT,
-					 gic_size,
+		ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
 					 pgprot_noncached(PAGE_READONLY));
 		if (ret)
 			goto out;
-- 
2.14.0

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

* [PATCH 23/38] irqchip: mips-gic: Remove gic_get_usm_range()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (22 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 24/38] irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration Paul Burton
                   ` (16 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The MIPS VDSO code is no longer reliant upon the irqchip driver to
provide the address of the GIC's user-visible section via
gic_get_usm_range(). Remove the now-dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 14 --------------
 include/linux/irqchip/mips-gic.h | 11 -----------
 2 files changed, 25 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index d6fbc5d6e8e2..6086747f02bf 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -46,7 +46,6 @@ struct gic_pcpu_mask {
 	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
 };
 
-static unsigned long __gic_base_addr;
 static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
@@ -134,17 +133,6 @@ int gic_get_c0_fdc_int(void)
 				  GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
 }
 
-int gic_get_usm_range(struct resource *gic_usm_res)
-{
-	if (!gic_present)
-		return -1;
-
-	gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS;
-	gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1);
-
-	return 0;
-}
-
 static void gic_handle_shared_int(bool chained)
 {
 	unsigned int intr, virq;
@@ -672,8 +660,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	unsigned int gicconfig, cpu;
 	unsigned int v[2];
 
-	__gic_base_addr = gic_base_addr;
-
 	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
 	gicconfig = read_gic_config();
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index da02a146b292..843e1bb49767 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -11,10 +11,6 @@
 #include <linux/clocksource.h>
 #include <linux/ioport.h>
 
-/* GIC Address Space */
-#define USM_VISIBLE_SECTION_OFS		0x10000
-#define USM_VISIBLE_SECTION_SIZE	0x10000
-
 /* User Mode Visible Section Register Map */
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
@@ -29,18 +25,11 @@ extern void gic_init(unsigned long gic_base_addr,
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
-extern int gic_get_usm_range(struct resource *gic_usm_res);
 
 #else /* CONFIG_MIPS_GIC */
 
 #define gic_present	0
 
-static inline int gic_get_usm_range(struct resource *gic_usm_res)
-{
-	/* Shouldn't be called. */
-	return -1;
-}
-
 #endif /* CONFIG_MIPS_GIC */
 
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 23/38] irqchip: mips-gic: Remove gic_get_usm_range()
  2017-08-13  4:36 ` [PATCH 23/38] irqchip: mips-gic: Remove gic_get_usm_range() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The MIPS VDSO code is no longer reliant upon the irqchip driver to
provide the address of the GIC's user-visible section via
gic_get_usm_range(). Remove the now-dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 14 --------------
 include/linux/irqchip/mips-gic.h | 11 -----------
 2 files changed, 25 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index d6fbc5d6e8e2..6086747f02bf 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -46,7 +46,6 @@ struct gic_pcpu_mask {
 	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
 };
 
-static unsigned long __gic_base_addr;
 static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
@@ -134,17 +133,6 @@ int gic_get_c0_fdc_int(void)
 				  GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
 }
 
-int gic_get_usm_range(struct resource *gic_usm_res)
-{
-	if (!gic_present)
-		return -1;
-
-	gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS;
-	gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1);
-
-	return 0;
-}
-
 static void gic_handle_shared_int(bool chained)
 {
 	unsigned int intr, virq;
@@ -672,8 +660,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	unsigned int gicconfig, cpu;
 	unsigned int v[2];
 
-	__gic_base_addr = gic_base_addr;
-
 	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
 	gicconfig = read_gic_config();
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index da02a146b292..843e1bb49767 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -11,10 +11,6 @@
 #include <linux/clocksource.h>
 #include <linux/ioport.h>
 
-/* GIC Address Space */
-#define USM_VISIBLE_SECTION_OFS		0x10000
-#define USM_VISIBLE_SECTION_SIZE	0x10000
-
 /* User Mode Visible Section Register Map */
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
@@ -29,18 +25,11 @@ extern void gic_init(unsigned long gic_base_addr,
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
-extern int gic_get_usm_range(struct resource *gic_usm_res);
 
 #else /* CONFIG_MIPS_GIC */
 
 #define gic_present	0
 
-static inline int gic_get_usm_range(struct resource *gic_usm_res)
-{
-	/* Shouldn't be called. */
-	return -1;
-}
-
 #endif /* CONFIG_MIPS_GIC */
 
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 24/38] irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (23 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 23/38] irqchip: mips-gic: Remove gic_get_usm_range() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 25/38] irqchip: mips-gic: Remove gic_init() Paul Burton
                   ` (15 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

We provide a forward declaration of the __gic_irq_dispatch() function
for no apparent reason. Remove it.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6086747f02bf..ce5b2f59c3fb 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -58,8 +58,6 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
 DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
-static void __gic_irq_dispatch(void);
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
-- 
2.14.0

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

* [PATCH 24/38] irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration
  2017-08-13  4:36 ` [PATCH 24/38] irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

We provide a forward declaration of the __gic_irq_dispatch() function
for no apparent reason. Remove it.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6086747f02bf..ce5b2f59c3fb 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -58,8 +58,6 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
 DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
-static void __gic_irq_dispatch(void);
-
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
-- 
2.14.0

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

* [PATCH 25/38] irqchip: mips-gic: Remove gic_init()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (24 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 24/38] irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 26/38] MIPS: Use mips_gic_present() in place of gic_present Paul Burton
                   ` (14 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

All in-tree platforms now probe the GIC driver using device tree, and as
such nothing calls gic_init() any longer. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 7 -------
 include/linux/irqchip/mips-gic.h | 3 ---
 2 files changed, 10 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index ce5b2f59c3fb..75877c793c4f 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -737,13 +737,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	gic_basic_init();
 }
 
-void __init gic_init(unsigned long gic_base_addr,
-		     unsigned long gic_addrspace_size,
-		     unsigned int cpu_vec, unsigned int irqbase)
-{
-	__gic_init(gic_base_addr, gic_addrspace_size, cpu_vec, irqbase, NULL);
-}
-
 static int __init gic_of_init(struct device_node *node,
 			      struct device_node *parent)
 {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 843e1bb49767..63c5f87034c9 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -19,9 +19,6 @@
 
 extern unsigned int gic_present;
 
-extern void gic_init(unsigned long gic_base_addr,
-	unsigned long gic_addrspace_size, unsigned int cpu_vec,
-	unsigned int irqbase);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
-- 
2.14.0

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

* [PATCH 25/38] irqchip: mips-gic: Remove gic_init()
  2017-08-13  4:36 ` [PATCH 25/38] irqchip: mips-gic: Remove gic_init() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

All in-tree platforms now probe the GIC driver using device tree, and as
such nothing calls gic_init() any longer. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 7 -------
 include/linux/irqchip/mips-gic.h | 3 ---
 2 files changed, 10 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index ce5b2f59c3fb..75877c793c4f 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -737,13 +737,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	gic_basic_init();
 }
 
-void __init gic_init(unsigned long gic_base_addr,
-		     unsigned long gic_addrspace_size,
-		     unsigned int cpu_vec, unsigned int irqbase)
-{
-	__gic_init(gic_base_addr, gic_addrspace_size, cpu_vec, irqbase, NULL);
-}
-
 static int __init gic_of_init(struct device_node *node,
 			      struct device_node *parent)
 {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 843e1bb49767..63c5f87034c9 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -19,9 +19,6 @@
 
 extern unsigned int gic_present;
 
-extern void gic_init(unsigned long gic_base_addr,
-	unsigned long gic_addrspace_size, unsigned int cpu_vec,
-	unsigned int irqbase);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
-- 
2.14.0

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

* [PATCH 26/38] MIPS: Use mips_gic_present() in place of gic_present
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (25 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 25/38] irqchip: mips-gic: Remove gic_init() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 27/38] irqchip: mips-gic: Remove gic_present Paul Burton
                   ` (13 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

In preparation for removing the gic_present global variable, switch to
using the mips_gic_present() function instead. For the most part this is
a straightforward substitution. In cases which previously wrapped the
GIC case in an #ifdef CONFIG_MIPS_GIC that #ifdef has been removed,
since mips_gic_present() will return a compile-time constant false
allowing the affected code to be optimised out anyway.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/generic/irq.c          |  7 ++++---
 arch/mips/kernel/smp-mt.c        |  6 ++----
 arch/mips/lantiq/irq.c           |  4 ----
 arch/mips/mti-malta/malta-int.c  |  4 ++--
 arch/mips/mti-malta/malta-time.c | 19 +++++++++----------
 5 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index 14064bdd91dd..a05fcb328e2e 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 
 #include <asm/irq.h>
+#include <asm/mips-cps.h>
 
 int get_c0_fdc_int(void)
 {
@@ -23,7 +24,7 @@ int get_c0_fdc_int(void)
 
 	if (cpu_has_veic)
 		panic("Unimplemented!");
-	else if (gic_present)
+	else if (mips_gic_present())
 		mips_cpu_fdc_irq = gic_get_c0_fdc_int();
 	else if (cp0_fdc_irq >= 0)
 		mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
@@ -39,7 +40,7 @@ int get_c0_perfcount_int(void)
 
 	if (cpu_has_veic)
 		panic("Unimplemented!");
-	else if (gic_present)
+	else if (mips_gic_present())
 		mips_cpu_perf_irq = gic_get_c0_perfcount_int();
 	else if (cp0_perfcount_irq >= 0)
 		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -55,7 +56,7 @@ unsigned int get_c0_compare_int(void)
 
 	if (cpu_has_veic)
 		panic("Unimplemented!");
-	else if (gic_present)
+	else if (mips_gic_present())
 		mips_cpu_timer_irq = gic_get_c0_compare_int();
 	else
 		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 30415a74f312..94ab3276b48c 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/interrupt.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/compiler.h>
 #include <linux/sched/task_stack.h>
 #include <linux/smp.h>
@@ -36,6 +35,7 @@
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/mips_mt.h>
+#include <asm/mips-cps.h>
 
 static void __init smvp_copy_vpe_config(void)
 {
@@ -118,14 +118,12 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
 
 static void vsmp_init_secondary(void)
 {
-#ifdef CONFIG_MIPS_GIC
 	/* This is Malta specific: IPI,performance and timer interrupts */
-	if (gic_present)
+	if (mips_gic_present())
 		change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 |
 					 STATUSF_IP4 | STATUSF_IP5 |
 					 STATUSF_IP6 | STATUSF_IP7);
 	else
-#endif
 		change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
 					 STATUSF_IP6 | STATUSF_IP7);
 }
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 33728b7af426..f0bc3312ed11 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -61,10 +61,6 @@
 /* we have a cascade of 8 irqs */
 #define MIPS_CPU_IRQ_CASCADE		8
 
-#ifdef CONFIG_MIPS_MT_SMP
-int gic_present;
-#endif
-
 static int exin_avail;
 static u32 ltq_eiu_irq[MAX_EIU];
 static void __iomem *ltq_icu_membase[MAX_IM];
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 2e831f4abfb3..a840e0c1642c 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -19,7 +19,6 @@
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/of_irq.h>
 #include <linux/kernel_stat.h>
 #include <linux/kernel.h>
@@ -31,6 +30,7 @@
 #include <asm/irq_regs.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
+#include <asm/mips-cps.h>
 #include <asm/gt64120.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/msc01_pci.h>
@@ -214,7 +214,7 @@ void __init arch_init_irq(void)
 					msc_nr_irqs);
 	}
 
-	if (gic_present) {
+	if (mips_gic_present()) {
 		corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
 	} else if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index cea4ec909806..7db872be01c0 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -40,6 +40,7 @@
 #include <asm/time.h>
 #include <asm/mc146818-time.h>
 #include <asm/msc01_ic.h>
+#include <asm/mips-cps.h>
 
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/maltaint.h>
@@ -85,7 +86,7 @@ static void __init estimate_frequencies(void)
 
 	local_irq_save(flags);
 
-	if (gic_present)
+	if (mips_gic_present())
 		gic_start_count();
 
 	/*
@@ -95,7 +96,7 @@ static void __init estimate_frequencies(void)
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 	start = read_c0_count();
-	if (gic_present)
+	if (mips_gic_present())
 		gicstart = gic_read_count();
 
 	/* Wait for falling edge before reading RTC. */
@@ -105,7 +106,7 @@ static void __init estimate_frequencies(void)
 	/* Read counters again exactly on rising edge of update flag. */
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 	count = read_c0_count();
-	if (gic_present)
+	if (mips_gic_present())
 		giccount = gic_read_count();
 
 	/* Wait for falling edge before reading RTC again. */
@@ -128,7 +129,7 @@ static void __init estimate_frequencies(void)
 	count /= secs;
 	mips_hpt_frequency = count;
 
-	if (gic_present) {
+	if (mips_gic_present()) {
 		giccount = div_u64(giccount - gicstart, secs);
 		gic_frequency = giccount;
 	}
@@ -154,7 +155,7 @@ int get_c0_fdc_int(void)
 
 	if (cpu_has_veic)
 		return -1;
-	else if (gic_present)
+	else if (mips_gic_present())
 		return gic_get_c0_fdc_int();
 	else if (cp0_fdc_irq >= 0)
 		return MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
@@ -167,7 +168,7 @@ int get_c0_perfcount_int(void)
 	if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
 		mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
-	} else if (gic_present) {
+	} else if (mips_gic_present()) {
 		mips_cpu_perf_irq = gic_get_c0_perfcount_int();
 	} else if (cp0_perfcount_irq >= 0) {
 		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -184,7 +185,7 @@ unsigned int get_c0_compare_int(void)
 	if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
 		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-	} else if (gic_present) {
+	} else if (mips_gic_present()) {
 		mips_cpu_timer_irq = gic_get_c0_compare_int();
 	} else {
 		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
@@ -258,8 +259,7 @@ void __init plat_time_init(void)
 	setup_pit_timer();
 #endif
 
-#ifdef CONFIG_MIPS_GIC
-	if (gic_present) {
+	if (mips_gic_present()) {
 		freq = freqround(gic_frequency, 5000);
 		printk("GIC frequency %d.%02d MHz\n", freq/1000000,
 		       (freq%1000000)*100/1000000);
@@ -268,5 +268,4 @@ void __init plat_time_init(void)
 		timer_probe();
 #endif
 	}
-#endif
 }
-- 
2.14.0

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

* [PATCH 26/38] MIPS: Use mips_gic_present() in place of gic_present
  2017-08-13  4:36 ` [PATCH 26/38] MIPS: Use mips_gic_present() in place of gic_present Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

In preparation for removing the gic_present global variable, switch to
using the mips_gic_present() function instead. For the most part this is
a straightforward substitution. In cases which previously wrapped the
GIC case in an #ifdef CONFIG_MIPS_GIC that #ifdef has been removed,
since mips_gic_present() will return a compile-time constant false
allowing the affected code to be optimised out anyway.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/generic/irq.c          |  7 ++++---
 arch/mips/kernel/smp-mt.c        |  6 ++----
 arch/mips/lantiq/irq.c           |  4 ----
 arch/mips/mti-malta/malta-int.c  |  4 ++--
 arch/mips/mti-malta/malta-time.c | 19 +++++++++----------
 5 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index 14064bdd91dd..a05fcb328e2e 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 
 #include <asm/irq.h>
+#include <asm/mips-cps.h>
 
 int get_c0_fdc_int(void)
 {
@@ -23,7 +24,7 @@ int get_c0_fdc_int(void)
 
 	if (cpu_has_veic)
 		panic("Unimplemented!");
-	else if (gic_present)
+	else if (mips_gic_present())
 		mips_cpu_fdc_irq = gic_get_c0_fdc_int();
 	else if (cp0_fdc_irq >= 0)
 		mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
@@ -39,7 +40,7 @@ int get_c0_perfcount_int(void)
 
 	if (cpu_has_veic)
 		panic("Unimplemented!");
-	else if (gic_present)
+	else if (mips_gic_present())
 		mips_cpu_perf_irq = gic_get_c0_perfcount_int();
 	else if (cp0_perfcount_irq >= 0)
 		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -55,7 +56,7 @@ unsigned int get_c0_compare_int(void)
 
 	if (cpu_has_veic)
 		panic("Unimplemented!");
-	else if (gic_present)
+	else if (mips_gic_present())
 		mips_cpu_timer_irq = gic_get_c0_compare_int();
 	else
 		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 30415a74f312..94ab3276b48c 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/interrupt.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/compiler.h>
 #include <linux/sched/task_stack.h>
 #include <linux/smp.h>
@@ -36,6 +35,7 @@
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/mips_mt.h>
+#include <asm/mips-cps.h>
 
 static void __init smvp_copy_vpe_config(void)
 {
@@ -118,14 +118,12 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
 
 static void vsmp_init_secondary(void)
 {
-#ifdef CONFIG_MIPS_GIC
 	/* This is Malta specific: IPI,performance and timer interrupts */
-	if (gic_present)
+	if (mips_gic_present())
 		change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 |
 					 STATUSF_IP4 | STATUSF_IP5 |
 					 STATUSF_IP6 | STATUSF_IP7);
 	else
-#endif
 		change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
 					 STATUSF_IP6 | STATUSF_IP7);
 }
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 33728b7af426..f0bc3312ed11 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -61,10 +61,6 @@
 /* we have a cascade of 8 irqs */
 #define MIPS_CPU_IRQ_CASCADE		8
 
-#ifdef CONFIG_MIPS_MT_SMP
-int gic_present;
-#endif
-
 static int exin_avail;
 static u32 ltq_eiu_irq[MAX_EIU];
 static void __iomem *ltq_icu_membase[MAX_IM];
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 2e831f4abfb3..a840e0c1642c 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -19,7 +19,6 @@
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/of_irq.h>
 #include <linux/kernel_stat.h>
 #include <linux/kernel.h>
@@ -31,6 +30,7 @@
 #include <asm/irq_regs.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
+#include <asm/mips-cps.h>
 #include <asm/gt64120.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/msc01_pci.h>
@@ -214,7 +214,7 @@ void __init arch_init_irq(void)
 					msc_nr_irqs);
 	}
 
-	if (gic_present) {
+	if (mips_gic_present()) {
 		corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
 	} else if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index cea4ec909806..7db872be01c0 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -40,6 +40,7 @@
 #include <asm/time.h>
 #include <asm/mc146818-time.h>
 #include <asm/msc01_ic.h>
+#include <asm/mips-cps.h>
 
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/maltaint.h>
@@ -85,7 +86,7 @@ static void __init estimate_frequencies(void)
 
 	local_irq_save(flags);
 
-	if (gic_present)
+	if (mips_gic_present())
 		gic_start_count();
 
 	/*
@@ -95,7 +96,7 @@ static void __init estimate_frequencies(void)
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 	start = read_c0_count();
-	if (gic_present)
+	if (mips_gic_present())
 		gicstart = gic_read_count();
 
 	/* Wait for falling edge before reading RTC. */
@@ -105,7 +106,7 @@ static void __init estimate_frequencies(void)
 	/* Read counters again exactly on rising edge of update flag. */
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 	count = read_c0_count();
-	if (gic_present)
+	if (mips_gic_present())
 		giccount = gic_read_count();
 
 	/* Wait for falling edge before reading RTC again. */
@@ -128,7 +129,7 @@ static void __init estimate_frequencies(void)
 	count /= secs;
 	mips_hpt_frequency = count;
 
-	if (gic_present) {
+	if (mips_gic_present()) {
 		giccount = div_u64(giccount - gicstart, secs);
 		gic_frequency = giccount;
 	}
@@ -154,7 +155,7 @@ int get_c0_fdc_int(void)
 
 	if (cpu_has_veic)
 		return -1;
-	else if (gic_present)
+	else if (mips_gic_present())
 		return gic_get_c0_fdc_int();
 	else if (cp0_fdc_irq >= 0)
 		return MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
@@ -167,7 +168,7 @@ int get_c0_perfcount_int(void)
 	if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
 		mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
-	} else if (gic_present) {
+	} else if (mips_gic_present()) {
 		mips_cpu_perf_irq = gic_get_c0_perfcount_int();
 	} else if (cp0_perfcount_irq >= 0) {
 		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -184,7 +185,7 @@ unsigned int get_c0_compare_int(void)
 	if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
 		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-	} else if (gic_present) {
+	} else if (mips_gic_present()) {
 		mips_cpu_timer_irq = gic_get_c0_compare_int();
 	} else {
 		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
@@ -258,8 +259,7 @@ void __init plat_time_init(void)
 	setup_pit_timer();
 #endif
 
-#ifdef CONFIG_MIPS_GIC
-	if (gic_present) {
+	if (mips_gic_present()) {
 		freq = freqround(gic_frequency, 5000);
 		printk("GIC frequency %d.%02d MHz\n", freq/1000000,
 		       (freq%1000000)*100/1000000);
@@ -268,5 +268,4 @@ void __init plat_time_init(void)
 		timer_probe();
 #endif
 	}
-#endif
 }
-- 
2.14.0

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

* [PATCH 27/38] irqchip: mips-gic: Remove gic_present
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (26 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 26/38] MIPS: Use mips_gic_present() in place of gic_present Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 28/38] irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h Paul Burton
                   ` (12 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Nothing uses the global gic_present variable anymore; mips_gic_present()
should be used instead. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 2 --
 include/linux/irqchip/mips-gic.h | 6 ------
 2 files changed, 8 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 75877c793c4f..5e1966777ab7 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -39,7 +39,6 @@
 #define GIC_SHARED_TO_HWIRQ(x)	(GIC_SHARED_HWIRQ_BASE + (x))
 #define GIC_HWIRQ_TO_SHARED(x)	((x) - GIC_SHARED_HWIRQ_BASE)
 
-unsigned int gic_present;
 void __iomem *mips_gic_base;
 
 struct gic_pcpu_mask {
@@ -781,7 +780,6 @@ static int __init gic_of_init(struct device_node *node,
 		/* Ensure GIC region is enabled before trying to access it */
 		__sync();
 	}
-	gic_present = true;
 
 	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
 
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 63c5f87034c9..113010c8dd8b 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -17,16 +17,10 @@
 
 #ifdef CONFIG_MIPS_GIC
 
-extern unsigned int gic_present;
-
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
 
-#else /* CONFIG_MIPS_GIC */
-
-#define gic_present	0
-
 #endif /* CONFIG_MIPS_GIC */
 
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 27/38] irqchip: mips-gic: Remove gic_present
  2017-08-13  4:36 ` [PATCH 27/38] irqchip: mips-gic: Remove gic_present Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Nothing uses the global gic_present variable anymore; mips_gic_present()
should be used instead. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c   | 2 --
 include/linux/irqchip/mips-gic.h | 6 ------
 2 files changed, 8 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 75877c793c4f..5e1966777ab7 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -39,7 +39,6 @@
 #define GIC_SHARED_TO_HWIRQ(x)	(GIC_SHARED_HWIRQ_BASE + (x))
 #define GIC_HWIRQ_TO_SHARED(x)	((x) - GIC_SHARED_HWIRQ_BASE)
 
-unsigned int gic_present;
 void __iomem *mips_gic_base;
 
 struct gic_pcpu_mask {
@@ -781,7 +780,6 @@ static int __init gic_of_init(struct device_node *node,
 		/* Ensure GIC region is enabled before trying to access it */
 		__sync();
 	}
-	gic_present = true;
 
 	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
 
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 63c5f87034c9..113010c8dd8b 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -17,16 +17,10 @@
 
 #ifdef CONFIG_MIPS_GIC
 
-extern unsigned int gic_present;
-
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
 
-#else /* CONFIG_MIPS_GIC */
-
-#define gic_present	0
-
 #endif /* CONFIG_MIPS_GIC */
 
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 28/38] irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (27 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 27/38] irqchip: mips-gic: Remove gic_present Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 29/38] MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h Paul Burton
                   ` (11 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The linux/irqchip/mips-gic.h header is now almost empty. Move the
declarations of gic_get_c0_compare_int(), gic_get_c0_perfcount_int() &
gic_get_c0_fdc_int() to asm/mips-gic.h in order to close in on being
able to delete the former header.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/generic/irq.c          |  1 -
 arch/mips/include/asm/mips-gic.h | 30 ++++++++++++++++++++++++++++++
 arch/mips/mti-malta/malta-time.c |  1 -
 arch/mips/pistachio/time.c       |  2 +-
 arch/mips/ralink/irq-gic.c       |  2 +-
 drivers/irqchip/irq-mips-gic.c   |  1 -
 include/linux/irqchip/mips-gic.h |  8 --------
 7 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index a05fcb328e2e..b193fbf4a6eb 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -12,7 +12,6 @@
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/init.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/types.h>
 
 #include <asm/irq.h>
diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
index 27736d7f4aba..a2badf572632 100644
--- a/arch/mips/include/asm/mips-gic.h
+++ b/arch/mips/include/asm/mips-gic.h
@@ -314,4 +314,34 @@ static inline bool mips_gic_present(void)
 	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
 }
 
+/**
+ * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
+ *
+ * Determine the virq number to use for the coprocessor 0 count/compare
+ * interrupt, which may be routed via the GIC.
+ *
+ * Returns the virq number or a negative error number.
+ */
+extern int gic_get_c0_compare_int(void);
+
+/**
+ * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
+ *
+ * Determine the virq number to use for CPU performance counter interrupts,
+ * which may be routed via the GIC.
+ *
+ * Returns the virq number or a negative error number.
+ */
+extern int gic_get_c0_perfcount_int(void);
+
+/**
+ * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
+ *
+ * Determine the virq number to use for fast debug channel (FDC) interrupts,
+ * which may be routed via the GIC.
+ *
+ * Returns the virq number or a negative error number.
+ */
+extern int gic_get_c0_fdc_int(void);
+
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 7db872be01c0..59fb3ce17c71 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -26,7 +26,6 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/timex.h>
 #include <linux/mc146818rtc.h>
 
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
index 17a0f1dec05b..8a6af9b76202 100644
--- a/arch/mips/pistachio/time.c
+++ b/arch/mips/pistachio/time.c
@@ -12,9 +12,9 @@
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/init.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/of.h>
 
+#include <asm/mips-cps.h>
 #include <asm/time.h>
 
 unsigned int get_c0_compare_int(void)
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c
index 2058280450b5..bda576f2cad8 100644
--- a/arch/mips/ralink/irq-gic.c
+++ b/arch/mips/ralink/irq-gic.c
@@ -11,7 +11,7 @@
 
 #include <linux/of.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/mips-gic.h>
+#include <asm/mips-cps.h>
 
 int get_c0_perfcount_int(void)
 {
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 5e1966777ab7..e77e194740a9 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -12,7 +12,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/of_address.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 113010c8dd8b..277d5be03a57 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -15,12 +15,4 @@
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-#ifdef CONFIG_MIPS_GIC
-
-extern int gic_get_c0_compare_int(void);
-extern int gic_get_c0_perfcount_int(void);
-extern int gic_get_c0_fdc_int(void);
-
-#endif /* CONFIG_MIPS_GIC */
-
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 28/38] irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h
  2017-08-13  4:36 ` [PATCH 28/38] irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The linux/irqchip/mips-gic.h header is now almost empty. Move the
declarations of gic_get_c0_compare_int(), gic_get_c0_perfcount_int() &
gic_get_c0_fdc_int() to asm/mips-gic.h in order to close in on being
able to delete the former header.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/generic/irq.c          |  1 -
 arch/mips/include/asm/mips-gic.h | 30 ++++++++++++++++++++++++++++++
 arch/mips/mti-malta/malta-time.c |  1 -
 arch/mips/pistachio/time.c       |  2 +-
 arch/mips/ralink/irq-gic.c       |  2 +-
 drivers/irqchip/irq-mips-gic.c   |  1 -
 include/linux/irqchip/mips-gic.h |  8 --------
 7 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index a05fcb328e2e..b193fbf4a6eb 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -12,7 +12,6 @@
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/init.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/types.h>
 
 #include <asm/irq.h>
diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
index 27736d7f4aba..a2badf572632 100644
--- a/arch/mips/include/asm/mips-gic.h
+++ b/arch/mips/include/asm/mips-gic.h
@@ -314,4 +314,34 @@ static inline bool mips_gic_present(void)
 	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
 }
 
+/**
+ * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
+ *
+ * Determine the virq number to use for the coprocessor 0 count/compare
+ * interrupt, which may be routed via the GIC.
+ *
+ * Returns the virq number or a negative error number.
+ */
+extern int gic_get_c0_compare_int(void);
+
+/**
+ * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
+ *
+ * Determine the virq number to use for CPU performance counter interrupts,
+ * which may be routed via the GIC.
+ *
+ * Returns the virq number or a negative error number.
+ */
+extern int gic_get_c0_perfcount_int(void);
+
+/**
+ * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
+ *
+ * Determine the virq number to use for fast debug channel (FDC) interrupts,
+ * which may be routed via the GIC.
+ *
+ * Returns the virq number or a negative error number.
+ */
+extern int gic_get_c0_fdc_int(void);
+
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 7db872be01c0..59fb3ce17c71 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -26,7 +26,6 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/timex.h>
 #include <linux/mc146818rtc.h>
 
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
index 17a0f1dec05b..8a6af9b76202 100644
--- a/arch/mips/pistachio/time.c
+++ b/arch/mips/pistachio/time.c
@@ -12,9 +12,9 @@
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/init.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/of.h>
 
+#include <asm/mips-cps.h>
 #include <asm/time.h>
 
 unsigned int get_c0_compare_int(void)
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c
index 2058280450b5..bda576f2cad8 100644
--- a/arch/mips/ralink/irq-gic.c
+++ b/arch/mips/ralink/irq-gic.c
@@ -11,7 +11,7 @@
 
 #include <linux/of.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/mips-gic.h>
+#include <asm/mips-cps.h>
 
 int get_c0_perfcount_int(void)
 {
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 5e1966777ab7..e77e194740a9 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -12,7 +12,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/of_address.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 113010c8dd8b..277d5be03a57 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -15,12 +15,4 @@
 #define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
 #define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
 
-#ifdef CONFIG_MIPS_GIC
-
-extern int gic_get_c0_compare_int(void);
-extern int gic_get_c0_perfcount_int(void);
-extern int gic_get_c0_fdc_int(void);
-
-#endif /* CONFIG_MIPS_GIC */
-
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 29/38] MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (28 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 28/38] irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 30/38] MIPS: Remove unnecessary inclusions " Paul Burton
                   ` (10 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Our VDSO code makes use of macros from linux/irqchip/mips-gic.h to
provide offsets to register values, but these are trivial offsets to the
two 32 bit halves of a 64 bit value. Replace use of the macros with zero
(ie. omit adding an offset) and the size of the low 32 bit of the value.
This removes our need for linux/irqchip/mips-gic.h & prepares us for it
to be removed.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/vdso/gettimeofday.c    | 7 +++----
 include/linux/irqchip/mips-gic.h | 4 ----
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
index fec7835b9de7..e22b422f282c 100644
--- a/arch/mips/vdso/gettimeofday.c
+++ b/arch/mips/vdso/gettimeofday.c
@@ -11,7 +11,6 @@
 #include "vdso.h"
 
 #include <linux/compiler.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/time.h>
 
 #include <asm/clocksource.h>
@@ -125,9 +124,9 @@ static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
 	u32 hi, hi2, lo;
 
 	do {
-		hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
-		lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS);
-		hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
+		hi = __raw_readl(gic + sizeof(lo));
+		lo = __raw_readl(gic);
+		hi2 = __raw_readl(gic + sizeof(lo));
 	} while (hi2 != hi);
 
 	return (((u64)hi) << 32) + lo;
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 277d5be03a57..6e6c9adea049 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -11,8 +11,4 @@
 #include <linux/clocksource.h>
 #include <linux/ioport.h>
 
-/* User Mode Visible Section Register Map */
-#define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
-#define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
-
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 29/38] MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h
  2017-08-13  4:36 ` [PATCH 29/38] MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Our VDSO code makes use of macros from linux/irqchip/mips-gic.h to
provide offsets to register values, but these are trivial offsets to the
two 32 bit halves of a 64 bit value. Replace use of the macros with zero
(ie. omit adding an offset) and the size of the low 32 bit of the value.
This removes our need for linux/irqchip/mips-gic.h & prepares us for it
to be removed.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 arch/mips/vdso/gettimeofday.c    | 7 +++----
 include/linux/irqchip/mips-gic.h | 4 ----
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
index fec7835b9de7..e22b422f282c 100644
--- a/arch/mips/vdso/gettimeofday.c
+++ b/arch/mips/vdso/gettimeofday.c
@@ -11,7 +11,6 @@
 #include "vdso.h"
 
 #include <linux/compiler.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/time.h>
 
 #include <asm/clocksource.h>
@@ -125,9 +124,9 @@ static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
 	u32 hi, hi2, lo;
 
 	do {
-		hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
-		lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS);
-		hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
+		hi = __raw_readl(gic + sizeof(lo));
+		lo = __raw_readl(gic);
+		hi2 = __raw_readl(gic + sizeof(lo));
 	} while (hi2 != hi);
 
 	return (((u64)hi) << 32) + lo;
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 277d5be03a57..6e6c9adea049 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -11,8 +11,4 @@
 #include <linux/clocksource.h>
 #include <linux/ioport.h>
 
-/* User Mode Visible Section Register Map */
-#define GIC_UMV_SH_COUNTER_31_00_OFS	0x0000
-#define GIC_UMV_SH_COUNTER_63_32_OFS	0x0004
-
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 30/38] MIPS: Remove unnecessary inclusions of linux/irqchip/mips-gic.h
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (29 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 29/38] MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 31/38] irqchip: mips-gic: Remove linux/irqchip/mips-gic.h Paul Burton
                   ` (9 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

linux/irqchip/mips-gic.h is included in a few files that don't actually
use it at all. Remove these unnecessary inclusions in preparation for
removing the header.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/smp-cmp.c | 1 -
 arch/mips/kernel/smp-cps.c | 1 -
 arch/mips/pistachio/irq.c  | 1 -
 3 files changed, 3 deletions(-)

diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index 04b21deea4f2..05295a4909f1 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -24,7 +24,6 @@
 #include <linux/cpumask.h>
 #include <linux/interrupt.h>
 #include <linux/compiler.h>
-#include <linux/irqchip/mips-gic.h>
 
 #include <linux/atomic.h>
 #include <asm/cacheflush.h>
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index c316a0f9e6fb..0063122c85da 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -11,7 +11,6 @@
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/sched/task_stack.h>
 #include <linux/sched/hotplug.h>
 #include <linux/slab.h>
diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c
index 0a6b24c24652..709a8219073a 100644
--- a/arch/mips/pistachio/irq.c
+++ b/arch/mips/pistachio/irq.c
@@ -10,7 +10,6 @@
 
 #include <linux/init.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/kernel.h>
 
 #include <asm/cpu-features.h>
-- 
2.14.0

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

* [PATCH 30/38] MIPS: Remove unnecessary inclusions of linux/irqchip/mips-gic.h
  2017-08-13  4:36 ` [PATCH 30/38] MIPS: Remove unnecessary inclusions " Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

linux/irqchip/mips-gic.h is included in a few files that don't actually
use it at all. Remove these unnecessary inclusions in preparation for
removing the header.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/smp-cmp.c | 1 -
 arch/mips/kernel/smp-cps.c | 1 -
 arch/mips/pistachio/irq.c  | 1 -
 3 files changed, 3 deletions(-)

diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index 04b21deea4f2..05295a4909f1 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -24,7 +24,6 @@
 #include <linux/cpumask.h>
 #include <linux/interrupt.h>
 #include <linux/compiler.h>
-#include <linux/irqchip/mips-gic.h>
 
 #include <linux/atomic.h>
 #include <asm/cacheflush.h>
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index c316a0f9e6fb..0063122c85da 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -11,7 +11,6 @@
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/sched/task_stack.h>
 #include <linux/sched/hotplug.h>
 #include <linux/slab.h>
diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c
index 0a6b24c24652..709a8219073a 100644
--- a/arch/mips/pistachio/irq.c
+++ b/arch/mips/pistachio/irq.c
@@ -10,7 +10,6 @@
 
 #include <linux/init.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/mips-gic.h>
 #include <linux/kernel.h>
 
 #include <asm/cpu-features.h>
-- 
2.14.0

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

* [PATCH 31/38] irqchip: mips-gic: Remove linux/irqchip/mips-gic.h
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (30 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 30/38] MIPS: Remove unnecessary inclusions " Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 32/38] irqchip: mips-gic: Inline __gic_init() Paul Burton
                   ` (8 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The linux/irqchip/mips-gic.h header is no longer used. Remove it.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 include/linux/irqchip/mips-gic.h | 14 --------------
 1 file changed, 14 deletions(-)
 delete mode 100644 include/linux/irqchip/mips-gic.h

diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
deleted file mode 100644
index 6e6c9adea049..000000000000
--- a/include/linux/irqchip/mips-gic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000, 07 MIPS Technologies, Inc.
- */
-#ifndef __LINUX_IRQCHIP_MIPS_GIC_H
-#define __LINUX_IRQCHIP_MIPS_GIC_H
-
-#include <linux/clocksource.h>
-#include <linux/ioport.h>
-
-#endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 31/38] irqchip: mips-gic: Remove linux/irqchip/mips-gic.h
  2017-08-13  4:36 ` [PATCH 31/38] irqchip: mips-gic: Remove linux/irqchip/mips-gic.h Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The linux/irqchip/mips-gic.h header is no longer used. Remove it.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 include/linux/irqchip/mips-gic.h | 14 --------------
 1 file changed, 14 deletions(-)
 delete mode 100644 include/linux/irqchip/mips-gic.h

diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
deleted file mode 100644
index 6e6c9adea049..000000000000
--- a/include/linux/irqchip/mips-gic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000, 07 MIPS Technologies, Inc.
- */
-#ifndef __LINUX_IRQCHIP_MIPS_GIC_H
-#define __LINUX_IRQCHIP_MIPS_GIC_H
-
-#include <linux/clocksource.h>
-#include <linux/ioport.h>
-
-#endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
-- 
2.14.0

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

* [PATCH 32/38] irqchip: mips-gic: Inline __gic_init()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (31 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 31/38] irqchip: mips-gic: Remove linux/irqchip/mips-gic.h Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 33/38] irqchip: mips-gic: Inline gic_basic_init() Paul Burton
                   ` (7 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The __gic_init() function is only called from gic_of_init() now that the
non-DT path has been removed. In order to simplify the code & aid
readability, fold __gic_init() into gic_of_init().

This provides us with the ability to return an error code, which
__gic_init() was previously unable to do. As such the irq_domain_add_*()
error paths are modified to print & return an error rather than panic().

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 116 +++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 61 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index e77e194740a9..a4a22bcb1a38 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -648,15 +648,54 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
 	.match = gic_ipi_domain_match,
 };
 
-static void __init __gic_init(unsigned long gic_base_addr,
-			      unsigned long gic_addrspace_size,
-			      unsigned int cpu_vec, unsigned int irqbase,
-			      struct device_node *node)
+
+static int __init gic_of_init(struct device_node *node,
+			      struct device_node *parent)
 {
-	unsigned int gicconfig, cpu;
-	unsigned int v[2];
+	unsigned int cpu_vec, i, reserved, gicconfig, cpu, v[2];
+	phys_addr_t gic_base;
+	struct resource res;
+	size_t gic_len;
 
-	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
+	/* Find the first available CPU vector. */
+	i = reserved = 0;
+	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
+					   i++, &cpu_vec))
+		reserved |= BIT(cpu_vec);
+	for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) {
+		if (!(reserved & BIT(cpu_vec)))
+			break;
+	}
+	if (cpu_vec == 8) {
+		pr_err("No CPU vectors available for GIC\n");
+		return -ENODEV;
+	}
+
+	if (of_address_to_resource(node, 0, &res)) {
+		/*
+		 * Probe the CM for the GIC base address if not specified
+		 * in the device-tree.
+		 */
+		if (mips_cm_present()) {
+			gic_base = read_gcr_gic_base() &
+				~CM_GCR_GIC_BASE_GICEN;
+			gic_len = 0x20000;
+		} else {
+			pr_err("Failed to get GIC memory range\n");
+			return -ENODEV;
+		}
+	} else {
+		gic_base = res.start;
+		gic_len = resource_size(&res);
+	}
+
+	if (mips_cm_present()) {
+		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
+		/* Ensure GIC region is enabled before trying to access it */
+		__sync();
+	}
+
+	mips_gic_base = ioremap_nocache(gic_base, gic_len);
 
 	gicconfig = read_gic_config();
 	gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
@@ -707,17 +746,21 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	}
 
 	gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS +
-					       gic_shared_intrs, irqbase,
+					       gic_shared_intrs, 0,
 					       &gic_irq_domain_ops, NULL);
-	if (!gic_irq_domain)
-		panic("Failed to add GIC IRQ domain");
+	if (!gic_irq_domain) {
+		pr_err("Failed to add GIC IRQ domain");
+		return -ENXIO;
+	}
 
 	gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
 						  IRQ_DOMAIN_FLAG_IPI_PER_CPU,
 						  GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
 						  node, &gic_ipi_domain_ops, NULL);
-	if (!gic_ipi_domain)
-		panic("Failed to add GIC IPI domain");
+	if (!gic_ipi_domain) {
+		pr_err("Failed to add GIC IPI domain");
+		return -ENXIO;
+	}
 
 	irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
 
@@ -733,55 +776,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
 
 	bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
 	gic_basic_init();
-}
-
-static int __init gic_of_init(struct device_node *node,
-			      struct device_node *parent)
-{
-	struct resource res;
-	unsigned int cpu_vec, i = 0, reserved = 0;
-	phys_addr_t gic_base;
-	size_t gic_len;
-
-	/* Find the first available CPU vector. */
-	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
-					   i++, &cpu_vec))
-		reserved |= BIT(cpu_vec);
-	for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) {
-		if (!(reserved & BIT(cpu_vec)))
-			break;
-	}
-	if (cpu_vec == 8) {
-		pr_err("No CPU vectors available for GIC\n");
-		return -ENODEV;
-	}
-
-	if (of_address_to_resource(node, 0, &res)) {
-		/*
-		 * Probe the CM for the GIC base address if not specified
-		 * in the device-tree.
-		 */
-		if (mips_cm_present()) {
-			gic_base = read_gcr_gic_base() &
-				~CM_GCR_GIC_BASE_GICEN;
-			gic_len = 0x20000;
-		} else {
-			pr_err("Failed to get GIC memory range\n");
-			return -ENODEV;
-		}
-	} else {
-		gic_base = res.start;
-		gic_len = resource_size(&res);
-	}
-
-	if (mips_cm_present())
-		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
-		/* Ensure GIC region is enabled before trying to access it */
-		__sync();
-	}
-
-	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
-
 	return 0;
 }
 IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init);
-- 
2.14.0

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

* [PATCH 32/38] irqchip: mips-gic: Inline __gic_init()
  2017-08-13  4:36 ` [PATCH 32/38] irqchip: mips-gic: Inline __gic_init() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

The __gic_init() function is only called from gic_of_init() now that the
non-DT path has been removed. In order to simplify the code & aid
readability, fold __gic_init() into gic_of_init().

This provides us with the ability to return an error code, which
__gic_init() was previously unable to do. As such the irq_domain_add_*()
error paths are modified to print & return an error rather than panic().

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 116 +++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 61 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index e77e194740a9..a4a22bcb1a38 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -648,15 +648,54 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
 	.match = gic_ipi_domain_match,
 };
 
-static void __init __gic_init(unsigned long gic_base_addr,
-			      unsigned long gic_addrspace_size,
-			      unsigned int cpu_vec, unsigned int irqbase,
-			      struct device_node *node)
+
+static int __init gic_of_init(struct device_node *node,
+			      struct device_node *parent)
 {
-	unsigned int gicconfig, cpu;
-	unsigned int v[2];
+	unsigned int cpu_vec, i, reserved, gicconfig, cpu, v[2];
+	phys_addr_t gic_base;
+	struct resource res;
+	size_t gic_len;
 
-	mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
+	/* Find the first available CPU vector. */
+	i = reserved = 0;
+	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
+					   i++, &cpu_vec))
+		reserved |= BIT(cpu_vec);
+	for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) {
+		if (!(reserved & BIT(cpu_vec)))
+			break;
+	}
+	if (cpu_vec == 8) {
+		pr_err("No CPU vectors available for GIC\n");
+		return -ENODEV;
+	}
+
+	if (of_address_to_resource(node, 0, &res)) {
+		/*
+		 * Probe the CM for the GIC base address if not specified
+		 * in the device-tree.
+		 */
+		if (mips_cm_present()) {
+			gic_base = read_gcr_gic_base() &
+				~CM_GCR_GIC_BASE_GICEN;
+			gic_len = 0x20000;
+		} else {
+			pr_err("Failed to get GIC memory range\n");
+			return -ENODEV;
+		}
+	} else {
+		gic_base = res.start;
+		gic_len = resource_size(&res);
+	}
+
+	if (mips_cm_present()) {
+		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
+		/* Ensure GIC region is enabled before trying to access it */
+		__sync();
+	}
+
+	mips_gic_base = ioremap_nocache(gic_base, gic_len);
 
 	gicconfig = read_gic_config();
 	gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
@@ -707,17 +746,21 @@ static void __init __gic_init(unsigned long gic_base_addr,
 	}
 
 	gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS +
-					       gic_shared_intrs, irqbase,
+					       gic_shared_intrs, 0,
 					       &gic_irq_domain_ops, NULL);
-	if (!gic_irq_domain)
-		panic("Failed to add GIC IRQ domain");
+	if (!gic_irq_domain) {
+		pr_err("Failed to add GIC IRQ domain");
+		return -ENXIO;
+	}
 
 	gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
 						  IRQ_DOMAIN_FLAG_IPI_PER_CPU,
 						  GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
 						  node, &gic_ipi_domain_ops, NULL);
-	if (!gic_ipi_domain)
-		panic("Failed to add GIC IPI domain");
+	if (!gic_ipi_domain) {
+		pr_err("Failed to add GIC IPI domain");
+		return -ENXIO;
+	}
 
 	irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
 
@@ -733,55 +776,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
 
 	bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
 	gic_basic_init();
-}
-
-static int __init gic_of_init(struct device_node *node,
-			      struct device_node *parent)
-{
-	struct resource res;
-	unsigned int cpu_vec, i = 0, reserved = 0;
-	phys_addr_t gic_base;
-	size_t gic_len;
-
-	/* Find the first available CPU vector. */
-	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
-					   i++, &cpu_vec))
-		reserved |= BIT(cpu_vec);
-	for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) {
-		if (!(reserved & BIT(cpu_vec)))
-			break;
-	}
-	if (cpu_vec == 8) {
-		pr_err("No CPU vectors available for GIC\n");
-		return -ENODEV;
-	}
-
-	if (of_address_to_resource(node, 0, &res)) {
-		/*
-		 * Probe the CM for the GIC base address if not specified
-		 * in the device-tree.
-		 */
-		if (mips_cm_present()) {
-			gic_base = read_gcr_gic_base() &
-				~CM_GCR_GIC_BASE_GICEN;
-			gic_len = 0x20000;
-		} else {
-			pr_err("Failed to get GIC memory range\n");
-			return -ENODEV;
-		}
-	} else {
-		gic_base = res.start;
-		gic_len = resource_size(&res);
-	}
-
-	if (mips_cm_present())
-		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
-		/* Ensure GIC region is enabled before trying to access it */
-		__sync();
-	}
-
-	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
-
 	return 0;
 }
 IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init);
-- 
2.14.0

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

* [PATCH 33/38] irqchip: mips-gic: Inline gic_basic_init()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (32 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 32/38] irqchip: mips-gic: Inline __gic_init() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable Paul Burton
                   ` (6 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

gic_basic_init() is now a fairly short function that is only called in
one place. Inline it into gic_of_init() to help readability.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 47 ++++++++++++++++++------------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index a4a22bcb1a38..feff4bf97577 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -372,31 +372,6 @@ static void gic_irq_dispatch(struct irq_desc *desc)
 	gic_handle_shared_int(true);
 }
 
-static void __init gic_basic_init(void)
-{
-	unsigned int i;
-
-	board_bind_eic_interrupt = &gic_bind_eic_interrupt;
-
-	/* Setup defaults */
-	for (i = 0; i < gic_shared_intrs; i++) {
-		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
-		change_gic_trig(i, GIC_TRIG_LEVEL);
-		write_gic_rmask(BIT(i));
-	}
-
-	for (i = 0; i < gic_vpes; i++) {
-		unsigned int j;
-
-		write_gic_vl_other(mips_cm_vp_id(i));
-		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
-			if (!gic_local_irq_is_routable(j))
-				continue;
-			write_gic_vo_rmask(BIT(j));
-		}
-	}
-}
-
 static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 				    irq_hw_number_t hw)
 {
@@ -652,7 +627,7 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
 static int __init gic_of_init(struct device_node *node,
 			      struct device_node *parent)
 {
-	unsigned int cpu_vec, i, reserved, gicconfig, cpu, v[2];
+	unsigned int cpu_vec, i, j, reserved, gicconfig, cpu, v[2];
 	phys_addr_t gic_base;
 	struct resource res;
 	size_t gic_len;
@@ -775,7 +750,25 @@ static int __init gic_of_init(struct device_node *node,
 	}
 
 	bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
-	gic_basic_init();
+
+	board_bind_eic_interrupt = &gic_bind_eic_interrupt;
+
+	/* Setup defaults */
+	for (i = 0; i < gic_shared_intrs; i++) {
+		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
+		change_gic_trig(i, GIC_TRIG_LEVEL);
+		write_gic_rmask(BIT(i));
+	}
+
+	for (i = 0; i < gic_vpes; i++) {
+		write_gic_vl_other(mips_cm_vp_id(i));
+		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
+			if (!gic_local_irq_is_routable(j))
+				continue;
+			write_gic_vo_rmask(BIT(j));
+		}
+	}
+
 	return 0;
 }
 IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init);
-- 
2.14.0

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

* [PATCH 33/38] irqchip: mips-gic: Inline gic_basic_init()
  2017-08-13  4:36 ` [PATCH 33/38] irqchip: mips-gic: Inline gic_basic_init() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

gic_basic_init() is now a fairly short function that is only called in
one place. Inline it into gic_of_init() to help readability.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 47 ++++++++++++++++++------------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index a4a22bcb1a38..feff4bf97577 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -372,31 +372,6 @@ static void gic_irq_dispatch(struct irq_desc *desc)
 	gic_handle_shared_int(true);
 }
 
-static void __init gic_basic_init(void)
-{
-	unsigned int i;
-
-	board_bind_eic_interrupt = &gic_bind_eic_interrupt;
-
-	/* Setup defaults */
-	for (i = 0; i < gic_shared_intrs; i++) {
-		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
-		change_gic_trig(i, GIC_TRIG_LEVEL);
-		write_gic_rmask(BIT(i));
-	}
-
-	for (i = 0; i < gic_vpes; i++) {
-		unsigned int j;
-
-		write_gic_vl_other(mips_cm_vp_id(i));
-		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
-			if (!gic_local_irq_is_routable(j))
-				continue;
-			write_gic_vo_rmask(BIT(j));
-		}
-	}
-}
-
 static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 				    irq_hw_number_t hw)
 {
@@ -652,7 +627,7 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
 static int __init gic_of_init(struct device_node *node,
 			      struct device_node *parent)
 {
-	unsigned int cpu_vec, i, reserved, gicconfig, cpu, v[2];
+	unsigned int cpu_vec, i, j, reserved, gicconfig, cpu, v[2];
 	phys_addr_t gic_base;
 	struct resource res;
 	size_t gic_len;
@@ -775,7 +750,25 @@ static int __init gic_of_init(struct device_node *node,
 	}
 
 	bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
-	gic_basic_init();
+
+	board_bind_eic_interrupt = &gic_bind_eic_interrupt;
+
+	/* Setup defaults */
+	for (i = 0; i < gic_shared_intrs; i++) {
+		change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
+		change_gic_trig(i, GIC_TRIG_LEVEL);
+		write_gic_rmask(BIT(i));
+	}
+
+	for (i = 0; i < gic_vpes; i++) {
+		write_gic_vl_other(mips_cm_vp_id(i));
+		for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
+			if (!gic_local_irq_is_routable(j))
+				continue;
+			write_gic_vo_rmask(BIT(j));
+		}
+	}
+
 	return 0;
 }
 IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init);
-- 
2.14.0

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

* [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (33 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 33/38] irqchip: mips-gic: Inline gic_basic_init() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-18 15:37   ` Marc Zyngier
  2017-08-13  4:36 ` [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK* Paul Burton
                   ` (5 subsequent siblings)
  40 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Define the pcpu_masks variable using the kernel's standard per-cpu
variable support, rather than an open-coded array of structs containing
bitmaps.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index feff4bf97577..00153231376a 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -13,6 +13,7 @@
 #include <linux/irq.h>
 #include <linux/irqchip.h>
 #include <linux/of_address.h>
+#include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 
@@ -23,6 +24,7 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 
 #define GIC_MAX_INTRS		256
+#define GIC_MAX_LONGS		BITS_TO_LONGS(GIC_MAX_INTRS)
 
 /* Add 2 to convert GIC CPU pin to core interrupt */
 #define GIC_CPU_PIN_OFFSET	2
@@ -40,11 +42,8 @@
 
 void __iomem *mips_gic_base;
 
-struct gic_pcpu_mask {
-	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
-};
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
 
-static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
 static struct irq_domain *gic_ipi_domain;
@@ -137,7 +136,7 @@ static void gic_handle_shared_int(bool chained)
 	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
-	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
+	pcpu_mask = this_cpu_ptr(pcpu_masks);
 
 	if (mips_cm_is64) {
 		__ioread64_copy(pending, addr_gic_pend(),
@@ -254,8 +253,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 
 	/* Update the pcpu_masks */
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(irq, pcpu_masks[i].pcpu_mask);
-	set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);
+		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
+	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -416,8 +415,8 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
 	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(intr, pcpu_masks[i].pcpu_mask);
-	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
+		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
+	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
-- 
2.14.0

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

* [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  2017-08-13  4:36 ` [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  2017-08-18 15:37   ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Define the pcpu_masks variable using the kernel's standard per-cpu
variable support, rather than an open-coded array of structs containing
bitmaps.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index feff4bf97577..00153231376a 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -13,6 +13,7 @@
 #include <linux/irq.h>
 #include <linux/irqchip.h>
 #include <linux/of_address.h>
+#include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 
@@ -23,6 +24,7 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 
 #define GIC_MAX_INTRS		256
+#define GIC_MAX_LONGS		BITS_TO_LONGS(GIC_MAX_INTRS)
 
 /* Add 2 to convert GIC CPU pin to core interrupt */
 #define GIC_CPU_PIN_OFFSET	2
@@ -40,11 +42,8 @@
 
 void __iomem *mips_gic_base;
 
-struct gic_pcpu_mask {
-	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
-};
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
 
-static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
 static struct irq_domain *gic_ipi_domain;
@@ -137,7 +136,7 @@ static void gic_handle_shared_int(bool chained)
 	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
-	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
+	pcpu_mask = this_cpu_ptr(pcpu_masks);
 
 	if (mips_cm_is64) {
 		__ioread64_copy(pending, addr_gic_pend(),
@@ -254,8 +253,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 
 	/* Update the pcpu_masks */
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(irq, pcpu_masks[i].pcpu_mask);
-	set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);
+		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
+	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -416,8 +415,8 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
 	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(intr, pcpu_masks[i].pcpu_mask);
-	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
+		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
+	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
-- 
2.14.0

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

* [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (34 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-18 15:44   ` Marc Zyngier
  2017-08-13  4:36 ` [PATCH 36/38] irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling Paul Burton
                   ` (4 subsequent siblings)
  40 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

This patch avoids the need to read the GIC_SH_MASK* registers when
decoding shared interrupts by setting & clearing the interrupt's bit in
the appropriate CPU's pcpu_masks entry when masking or unmasking the
interrupt.

This effectively means that whilst an interrupt is masked we clear its
bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
on all CPUs without needing to check GIC_SH_MASK*.

In essence, we add a little overhead to masking or unmasking interrupts
but in return reduce the overhead of the far more common task of
decoding interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 49 ++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 00153231376a..7a42f0b3822f 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -55,6 +55,19 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
 DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
+static void gic_setup_pcpu_mask(unsigned int intr, unsigned int cpu)
+{
+	unsigned int i;
+
+	/* Clear the interrupt's bit in all pcpu_masks */
+	for_each_possible_cpu(i)
+		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
+
+	/* Set the interrupt's bit in the appropriate CPU's mask */
+	if (cpu < NR_CPUS)
+		set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
+}
+
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -133,24 +146,17 @@ static void gic_handle_shared_int(bool chained)
 	unsigned int intr, virq;
 	unsigned long *pcpu_mask;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
-	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
 	pcpu_mask = this_cpu_ptr(pcpu_masks);
 
-	if (mips_cm_is64) {
+	if (mips_cm_is64)
 		__ioread64_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 64));
-		__ioread64_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 64));
-	} else {
+	else
 		__ioread32_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 32));
-		__ioread32_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 32));
-	}
 
-	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
 	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
 
 	for_each_set_bit(intr, pending, gic_shared_intrs) {
@@ -165,12 +171,19 @@ static void gic_handle_shared_int(bool chained)
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+
+	write_gic_rmask(BIT(intr));
+	gic_setup_pcpu_mask(intr, NR_CPUS);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	struct cpumask *affinity = irq_data_get_affinity_mask(d);
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+
+	write_gic_smask(BIT(intr));
+	gic_setup_pcpu_mask(intr, cpumask_first_and(affinity, cpu_online_mask));
 }
 
 static void gic_ack_irq(struct irq_data *d)
@@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
-	int		i;
 
 	cpumask_and(&tmp, cpumask, cpu_online_mask);
 	if (cpumask_empty(&tmp))
@@ -252,9 +264,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
 
 	/* Update the pcpu_masks */
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
-	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
+	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) : NR_CPUS);
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -405,18 +415,15 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 }
 
 static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
-				     irq_hw_number_t hw, unsigned int vpe)
+				     irq_hw_number_t hw, unsigned int cpu)
 {
 	int intr = GIC_HWIRQ_TO_SHARED(hw);
 	unsigned long flags;
-	int i;
 
 	spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
-	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
-	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
+	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
+	gic_setup_pcpu_mask(intr, cpu);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
-- 
2.14.0

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

* [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-13  4:36 ` [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK* Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  2017-08-18 15:44   ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

This patch avoids the need to read the GIC_SH_MASK* registers when
decoding shared interrupts by setting & clearing the interrupt's bit in
the appropriate CPU's pcpu_masks entry when masking or unmasking the
interrupt.

This effectively means that whilst an interrupt is masked we clear its
bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
on all CPUs without needing to check GIC_SH_MASK*.

In essence, we add a little overhead to masking or unmasking interrupts
but in return reduce the overhead of the far more common task of
decoding interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 49 ++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 00153231376a..7a42f0b3822f 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -55,6 +55,19 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
 DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
+static void gic_setup_pcpu_mask(unsigned int intr, unsigned int cpu)
+{
+	unsigned int i;
+
+	/* Clear the interrupt's bit in all pcpu_masks */
+	for_each_possible_cpu(i)
+		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
+
+	/* Set the interrupt's bit in the appropriate CPU's mask */
+	if (cpu < NR_CPUS)
+		set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
+}
+
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -133,24 +146,17 @@ static void gic_handle_shared_int(bool chained)
 	unsigned int intr, virq;
 	unsigned long *pcpu_mask;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
-	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
 	pcpu_mask = this_cpu_ptr(pcpu_masks);
 
-	if (mips_cm_is64) {
+	if (mips_cm_is64)
 		__ioread64_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 64));
-		__ioread64_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 64));
-	} else {
+	else
 		__ioread32_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 32));
-		__ioread32_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 32));
-	}
 
-	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
 	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
 
 	for_each_set_bit(intr, pending, gic_shared_intrs) {
@@ -165,12 +171,19 @@ static void gic_handle_shared_int(bool chained)
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+
+	write_gic_rmask(BIT(intr));
+	gic_setup_pcpu_mask(intr, NR_CPUS);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	struct cpumask *affinity = irq_data_get_affinity_mask(d);
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+
+	write_gic_smask(BIT(intr));
+	gic_setup_pcpu_mask(intr, cpumask_first_and(affinity, cpu_online_mask));
 }
 
 static void gic_ack_irq(struct irq_data *d)
@@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
-	int		i;
 
 	cpumask_and(&tmp, cpumask, cpu_online_mask);
 	if (cpumask_empty(&tmp))
@@ -252,9 +264,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
 
 	/* Update the pcpu_masks */
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
-	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
+	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) : NR_CPUS);
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -405,18 +415,15 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 }
 
 static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
-				     irq_hw_number_t hw, unsigned int vpe)
+				     irq_hw_number_t hw, unsigned int cpu)
 {
 	int intr = GIC_HWIRQ_TO_SHARED(hw);
 	unsigned long flags;
-	int i;
 
 	spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
-	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
-	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
+	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
+	gic_setup_pcpu_mask(intr, cpu);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
-- 
2.14.0

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

* [PATCH 36/38] irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (35 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK* Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  4:36 ` [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity() Paul Burton
                   ` (3 subsequent siblings)
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

When parsing mti,reserved-cpu-vectors we generate a mask of all bits
that have been declared reserved, the loop through starting from bit 2
to find one that isn't reserved (ie. is zero).

This patch accomplishes the same task more simply by:

  - Inititialising the reserved mask to 0x3 (ie. the 2 software
    interrupts). This means we don't need to skip them later as the loop
    previously has.

  - Replacing the loop checking for zero bits with find_first_zero_bit,
    which fits our needs now that the 2 software interrupts are marked
    reserved. This requires that the type of reserved is changed to
    unsigned long so that it's suitable for use with bitmap functions.

  - Replacing the magic number 8 with the hamming weight of the ST0_IM
    field - ie. the number of bits that a MIPS CPU has for interrupt
    inputs. This is still a compile-time constant 8, but makes it
    clearer why it's 8.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 7a42f0b3822f..e4ab65c7056d 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -633,21 +633,21 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
 static int __init gic_of_init(struct device_node *node,
 			      struct device_node *parent)
 {
-	unsigned int cpu_vec, i, j, reserved, gicconfig, cpu, v[2];
+	unsigned int cpu_vec, i, j, gicconfig, cpu, v[2];
+	unsigned long reserved;
 	phys_addr_t gic_base;
 	struct resource res;
 	size_t gic_len;
 
 	/* Find the first available CPU vector. */
-	i = reserved = 0;
+	i = 0;
+	reserved = (C_SW0 | C_SW1) >> __fls(C_SW0);
 	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
 					   i++, &cpu_vec))
 		reserved |= BIT(cpu_vec);
-	for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) {
-		if (!(reserved & BIT(cpu_vec)))
-			break;
-	}
-	if (cpu_vec == 8) {
+
+	cpu_vec = find_first_zero_bit(&reserved, hweight_long(ST0_IM));
+	if (cpu_vec == hweight_long(ST0_IM)) {
 		pr_err("No CPU vectors available for GIC\n");
 		return -ENODEV;
 	}
-- 
2.14.0

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

* [PATCH 36/38] irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling
  2017-08-13  4:36 ` [PATCH 36/38] irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

When parsing mti,reserved-cpu-vectors we generate a mask of all bits
that have been declared reserved, the loop through starting from bit 2
to find one that isn't reserved (ie. is zero).

This patch accomplishes the same task more simply by:

  - Inititialising the reserved mask to 0x3 (ie. the 2 software
    interrupts). This means we don't need to skip them later as the loop
    previously has.

  - Replacing the loop checking for zero bits with find_first_zero_bit,
    which fits our needs now that the 2 software interrupts are marked
    reserved. This requires that the type of reserved is changed to
    unsigned long so that it's suitable for use with bitmap functions.

  - Replacing the magic number 8 with the hamming weight of the ST0_IM
    field - ie. the number of bits that a MIPS CPU has for interrupt
    inputs. This is still a compile-time constant 8, but makes it
    clearer why it's 8.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 7a42f0b3822f..e4ab65c7056d 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -633,21 +633,21 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
 static int __init gic_of_init(struct device_node *node,
 			      struct device_node *parent)
 {
-	unsigned int cpu_vec, i, j, reserved, gicconfig, cpu, v[2];
+	unsigned int cpu_vec, i, j, gicconfig, cpu, v[2];
+	unsigned long reserved;
 	phys_addr_t gic_base;
 	struct resource res;
 	size_t gic_len;
 
 	/* Find the first available CPU vector. */
-	i = reserved = 0;
+	i = 0;
+	reserved = (C_SW0 | C_SW1) >> __fls(C_SW0);
 	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
 					   i++, &cpu_vec))
 		reserved |= BIT(cpu_vec);
-	for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) {
-		if (!(reserved & BIT(cpu_vec)))
-			break;
-	}
-	if (cpu_vec == 8) {
+
+	cpu_vec = find_first_zero_bit(&reserved, hweight_long(ST0_IM));
+	if (cpu_vec == hweight_long(ST0_IM)) {
 		pr_err("No CPU vectors available for GIC\n");
 		return -ENODEV;
 	}
-- 
2.14.0

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

* [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (36 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 36/38] irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
                     ` (2 more replies)
  2017-08-13  4:36 ` [PATCH 38/38] irqchip: mips-gic: Let the core set struct irq_common_data affinity Paul Burton
                   ` (2 subsequent siblings)
  40 siblings, 3 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Currently in gic_set_affinity() we calculate a temporary cpumask holding
the intersection of the provided cpumask & the CPUs that are online,
then we call cpumask_first twice on it to find the first such CPU. Since
we don't need to temporary cpumask for anything else & we only care
about the first CPU that's both online & in the provided cpumask, we can
instead use cpumask_first_and to find that CPU & drop the temporary
mask.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index e4ab65c7056d..cd9cbda1f263 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -250,21 +250,21 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 			    bool force)
 {
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
-	cpumask_t	tmp = CPU_MASK_NONE;
-	unsigned long	flags;
+	unsigned long flags;
+	unsigned int cpu;
 
-	cpumask_and(&tmp, cpumask, cpu_online_mask);
-	if (cpumask_empty(&tmp))
+	cpu = cpumask_first_and(cpumask, cpu_online_mask);
+	if (cpu >= NR_CPUS)
 		return -EINVAL;
 
 	/* Assumption : cpumask refers to a single CPU */
 	spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
-	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
+	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
 
 	/* Update the pcpu_masks */
-	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) : NR_CPUS);
+	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpu : NR_CPUS);
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
-- 
2.14.0

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

* [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-13  4:36 ` [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity() Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  2017-08-13  9:08   ` Sergei Shtylyov
  2017-08-18 21:04   ` [PATCH v2 " Paul Burton
  2 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

Currently in gic_set_affinity() we calculate a temporary cpumask holding
the intersection of the provided cpumask & the CPUs that are online,
then we call cpumask_first twice on it to find the first such CPU. Since
we don't need to temporary cpumask for anything else & we only care
about the first CPU that's both online & in the provided cpumask, we can
instead use cpumask_first_and to find that CPU & drop the temporary
mask.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
---

 drivers/irqchip/irq-mips-gic.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index e4ab65c7056d..cd9cbda1f263 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -250,21 +250,21 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 			    bool force)
 {
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
-	cpumask_t	tmp = CPU_MASK_NONE;
-	unsigned long	flags;
+	unsigned long flags;
+	unsigned int cpu;
 
-	cpumask_and(&tmp, cpumask, cpu_online_mask);
-	if (cpumask_empty(&tmp))
+	cpu = cpumask_first_and(cpumask, cpu_online_mask);
+	if (cpu >= NR_CPUS)
 		return -EINVAL;
 
 	/* Assumption : cpumask refers to a single CPU */
 	spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
-	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
+	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
 
 	/* Update the pcpu_masks */
-	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) : NR_CPUS);
+	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpu : NR_CPUS);
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
-- 
2.14.0

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

* [PATCH 38/38] irqchip: mips-gic: Let the core set struct irq_common_data affinity
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (37 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity() Paul Burton
@ 2017-08-13  4:36 ` Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-15 10:13 ` [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Marc Zyngier
  2017-08-18 17:28 ` Marc Zyngier
  40 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

gic_set_affinity() manually copies the provided cpumask to the struct
irq_common_data affinity field, returning IRQ_SET_MASK_OK_NOCOPY in
order to prevent the core code from doing that.

We can instead simply let the core code do it for us, by returning
IRQ_SET_MASK_OK instead of IRQ_SET_MASK_OK_NOCOPY & doing the copy
ourselves.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org

---

 drivers/irqchip/irq-mips-gic.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index cd9cbda1f263..11bab55e18bd 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -266,10 +266,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	/* Update the pcpu_masks */
 	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpu : NR_CPUS);
 
-	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
-	return IRQ_SET_MASK_OK_NOCOPY;
+	return IRQ_SET_MASK_OK;
 }
 #endif
 
-- 
2.14.0

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

* [PATCH 38/38] irqchip: mips-gic: Let the core set struct irq_common_data affinity
  2017-08-13  4:36 ` [PATCH 38/38] irqchip: mips-gic: Let the core set struct irq_common_data affinity Paul Burton
@ 2017-08-13  4:36   ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-13  4:36 UTC (permalink / raw)
  To: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Ralf Baechle, Paul Burton

gic_set_affinity() manually copies the provided cpumask to the struct
irq_common_data affinity field, returning IRQ_SET_MASK_OK_NOCOPY in
order to prevent the core code from doing that.

We can instead simply let the core code do it for us, by returning
IRQ_SET_MASK_OK instead of IRQ_SET_MASK_OK_NOCOPY & doing the copy
ourselves.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org

---

 drivers/irqchip/irq-mips-gic.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index cd9cbda1f263..11bab55e18bd 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -266,10 +266,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	/* Update the pcpu_masks */
 	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpu : NR_CPUS);
 
-	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
-	return IRQ_SET_MASK_OK_NOCOPY;
+	return IRQ_SET_MASK_OK;
 }
 #endif
 
-- 
2.14.0

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

* Re: [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-13  4:36 ` [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity() Paul Burton
  2017-08-13  4:36   ` Paul Burton
@ 2017-08-13  9:08   ` Sergei Shtylyov
  2017-08-14 16:18     ` Paul Burton
  2017-08-18 21:04   ` [PATCH v2 " Paul Burton
  2 siblings, 1 reply; 111+ messages in thread
From: Sergei Shtylyov @ 2017-08-13  9:08 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Marc Zyngier,
	Thomas Gleixner
  Cc: Ralf Baechle

Hello!

On 8/13/2017 7:36 AM, Paul Burton wrote:

> Currently in gic_set_affinity() we calculate a temporary cpumask holding
> the intersection of the provided cpumask & the CPUs that are online,
> then we call cpumask_first twice on it to find the first such CPU. Since
> we don't need to temporary cpumask for anything else & we only care

    s/to/the/?

> about the first CPU that's both online & in the provided cpumask, we can
> instead use cpumask_first_and to find that CPU & drop the temporary
> mask.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mips@linux-mips.org
[...]

MBR, Serge

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

* Re: [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-13  9:08   ` Sergei Shtylyov
@ 2017-08-14 16:18     ` Paul Burton
  2017-08-14 16:18       ` Paul Burton
  2017-08-14 16:48       ` Sergei Shtylyov
  0 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-14 16:18 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner,
	Ralf Baechle

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

Hi Sergei,

On Sunday, 13 August 2017 02:08:50 PDT Sergei Shtylyov wrote:
> Hello!
> 
> On 8/13/2017 7:36 AM, Paul Burton wrote:
> > Currently in gic_set_affinity() we calculate a temporary cpumask holding
> > the intersection of the provided cpumask & the CPUs that are online,
> > then we call cpumask_first twice on it to find the first such CPU. Since
> > we don't need to temporary cpumask for anything else & we only care
> 
>     s/to/the/?

Indeed - nice to know someone is reading a 38 patch series :)

I'll fix up but leave submitting a v2 until someone asks me to.

Thanks,
    Paul

> 
> > about the first CPU that's both online & in the provided cpumask, we can
> > instead use cpumask_first_and to find that CPU & drop the temporary
> > mask.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> 
> [...]
> 
> MBR, Serge


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-14 16:18     ` Paul Burton
@ 2017-08-14 16:18       ` Paul Burton
  2017-08-14 16:48       ` Sergei Shtylyov
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-14 16:18 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner,
	Ralf Baechle

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

Hi Sergei,

On Sunday, 13 August 2017 02:08:50 PDT Sergei Shtylyov wrote:
> Hello!
> 
> On 8/13/2017 7:36 AM, Paul Burton wrote:
> > Currently in gic_set_affinity() we calculate a temporary cpumask holding
> > the intersection of the provided cpumask & the CPUs that are online,
> > then we call cpumask_first twice on it to find the first such CPU. Since
> > we don't need to temporary cpumask for anything else & we only care
> 
>     s/to/the/?

Indeed - nice to know someone is reading a 38 patch series :)

I'll fix up but leave submitting a v2 until someone asks me to.

Thanks,
    Paul

> 
> > about the first CPU that's both online & in the provided cpumask, we can
> > instead use cpumask_first_and to find that CPU & drop the temporary
> > mask.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> 
> [...]
> 
> MBR, Serge


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-14 16:18     ` Paul Burton
  2017-08-14 16:18       ` Paul Burton
@ 2017-08-14 16:48       ` Sergei Shtylyov
  1 sibling, 0 replies; 111+ messages in thread
From: Sergei Shtylyov @ 2017-08-14 16:48 UTC (permalink / raw)
  To: Paul Burton
  Cc: linux-mips, Jason Cooper, Marc Zyngier, Thomas Gleixner,
	Ralf Baechle

On 08/14/2017 07:18 PM, Paul Burton wrote:

>> On 8/13/2017 7:36 AM, Paul Burton wrote:
>>> Currently in gic_set_affinity() we calculate a temporary cpumask holding
>>> the intersection of the provided cpumask & the CPUs that are online,
>>> then we call cpumask_first twice on it to find the first such CPU. Since
>>> we don't need to temporary cpumask for anything else & we only care
>>
>>      s/to/the/?
> 
> Indeed - nice to know someone is reading a 38 patch series :)

    I can't say I've read all of them, only the smaller ones... :-)

> I'll fix up but leave submitting a v2 until someone asks me to.

    It's OK.

> Thanks,
>      Paul
> 
>>
>>> about the first CPU that's both online & in the provided cpumask, we can
>>> instead use cpumask_first_and to find that CPU & drop the temporary
>>> mask.
>>>
>>> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
>>> Cc: Jason Cooper <jason@lakedaemon.net>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: linux-mips@linux-mips.org
>>
>> [...]

MBR, Sergei

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (38 preceding siblings ...)
  2017-08-13  4:36 ` [PATCH 38/38] irqchip: mips-gic: Let the core set struct irq_common_data affinity Paul Burton
@ 2017-08-15 10:13 ` Marc Zyngier
  2017-08-15 16:16   ` Paul Burton
  2017-08-18 17:28 ` Marc Zyngier
  40 siblings, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-15 10:13 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Thomas Gleixner; +Cc: Ralf Baechle

Hi Paul,

On 13/08/17 05:36, Paul Burton wrote:
> This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> somewhat. It moves us towards using a header in a similar vein to the
> ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> Controller (CPC) which allows us to access the GIC outside of the
> irqchip driver - something beneficial already for the clocksource &
> clock event driver, and which will be beneficial for further drivers
> (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> this header is also beneficial for consistency & code-sharing.
> 
> In addition to cleanups the series also optimises the driver in various
> ways, including by using a per-CPU variable for pcpu_masks & removing
> the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> gic_handle_shared_int().
> 
> This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> support" series to be applied first.

I'm not on Cc on this one, so it is a bit hard to see what's going on.
But overall, it is incredibly difficult to follow what is going on here.
Everything seems to move around, and while I'm sure that you have
something in mind, the mix of fixes+optimizations+new features is a bit
hard to swallow (not to mention the VDSO stuff in the middle of what is
supposed to be an irqchip series).

Is there any chance you could rework this to have a more logical
ordering? Something like fixes first, new features next, and
optimizations in the end, organized by domains (arch stuff first, then
irqchip, then timer, then userspace)? Because at the moment, this is a
bit overwhelming...

Thanks,

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

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-15 10:13 ` [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Marc Zyngier
@ 2017-08-15 16:16   ` Paul Burton
  2017-08-15 16:16     ` Paul Burton
  2017-08-15 16:49     ` Marc Zyngier
  0 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-15 16:16 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Tuesday, 15 August 2017 03:13:03 PDT Marc Zyngier wrote:
> Hi Paul,
> 
> On 13/08/17 05:36, Paul Burton wrote:
> > This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> > somewhat. It moves us towards using a header in a similar vein to the
> > ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> > Controller (CPC) which allows us to access the GIC outside of the
> > irqchip driver - something beneficial already for the clocksource &
> > clock event driver, and which will be beneficial for further drivers
> > (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> > this header is also beneficial for consistency & code-sharing.
> > 
> > In addition to cleanups the series also optimises the driver in various
> > ways, including by using a per-CPU variable for pcpu_masks & removing
> > the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> > gic_handle_shared_int().
> > 
> > This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> > support" series to be applied first.
> 
> I'm not on Cc on this one, so it is a bit hard to see what's going on.

That other series is only really related insomuch as it adds asm/mips-cps.h 
which this series makes use of, and changes a couple of lines in irq-mips-
gic.c which would cause conflicts if this series is applied without the other 
first.

> But overall, it is incredibly difficult to follow what is going on here.
> Everything seems to move around, and while I'm sure that you have
> something in mind, the mix of fixes+optimizations+new features is a bit
> hard to swallow (not to mention the VDSO stuff in the middle of what is
> supposed to be an irqchip series).

In general the non-irqchip patches preceed the irqchip patch that they enable. 
For example, the VDSO patch you mention (presumably patch 22 "MIPS: VDSO: Drop 
git_get_usm_range() usage") is followed immediately by the removal of that 
function in patch 23 "irqchip: mips-gic: Remove gic_get_usm_range()".

The issue is that the MIPS GIC irqchip driver currently provides a bunch of 
functions which have nothing to do with interrupts, and so probably ought to 
be elsewhere. Moving that code elsewhere involves both adjusting the callers 
of those functions & then removing them from the irqchip driver, hence the 
non-irqchip patches followed by the related irqchip patches.

In general the only things that move are:

 - The GIC register definitions, to asm/mips-gic.h for reasons described in 
patch 2.

 - Functions as I mentioned in the previous paragraph which have nothing to do 
with the irqchip driver & don't need to be there once we have access to GIC 
registers elsewhere through asm/mips-gic.h.

 - A few other bits from linux/irqchip/mips-gic.h just so we can drop that 
header.

> Is there any chance you could rework this to have a more logical
> ordering? Something like fixes first, new features next, and
> optimizations in the end, organized by domains (arch stuff first, then
> irqchip, then timer, then userspace)?

It's already almost grouped like that. We have:

- Patch 1 is a fix.

- Patches 2 through 34 are cleanup, though a couple could probably be 
secondarily considered optimisations too.

- Patch 35 is an optimisation.

- Patches 36 through 38 could be considered optimisation or cleanup depending 
upon the tint of your glasses.

So I'm not sure what you're asking me to do here - to group them better I 
could perhaps move patch 35 to the end, but I'm not sure I see how that would 
make review any easier.

I didn't group by domain like you suggest for the reason I mention before - 
the non-irqchip patches are purely there to enable the following irqchip patch 
so it made sense to me to group those together. If you really want I could 
move all the non-irqchip patches to the start & all the irqchip patches to the 
end, but again I'm not sure I see how that helps - it would just mean that 
tightly related patches no longer follow one another.

> Because at the moment, this is a bit overwhelming...

My intent in splitting this into so many patches, and in grouping together the 
related non-irqchip & irqchip patches, was to reduce that overwhelming-ness by 
making each patch pretty readable by itself & perhaps taking into account only 
a patch or two before it. I guess that didn't work though.. :)

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-15 16:16   ` Paul Burton
@ 2017-08-15 16:16     ` Paul Burton
  2017-08-15 16:49     ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-15 16:16 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Tuesday, 15 August 2017 03:13:03 PDT Marc Zyngier wrote:
> Hi Paul,
> 
> On 13/08/17 05:36, Paul Burton wrote:
> > This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> > somewhat. It moves us towards using a header in a similar vein to the
> > ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> > Controller (CPC) which allows us to access the GIC outside of the
> > irqchip driver - something beneficial already for the clocksource &
> > clock event driver, and which will be beneficial for further drivers
> > (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> > this header is also beneficial for consistency & code-sharing.
> > 
> > In addition to cleanups the series also optimises the driver in various
> > ways, including by using a per-CPU variable for pcpu_masks & removing
> > the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> > gic_handle_shared_int().
> > 
> > This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> > support" series to be applied first.
> 
> I'm not on Cc on this one, so it is a bit hard to see what's going on.

That other series is only really related insomuch as it adds asm/mips-cps.h 
which this series makes use of, and changes a couple of lines in irq-mips-
gic.c which would cause conflicts if this series is applied without the other 
first.

> But overall, it is incredibly difficult to follow what is going on here.
> Everything seems to move around, and while I'm sure that you have
> something in mind, the mix of fixes+optimizations+new features is a bit
> hard to swallow (not to mention the VDSO stuff in the middle of what is
> supposed to be an irqchip series).

In general the non-irqchip patches preceed the irqchip patch that they enable. 
For example, the VDSO patch you mention (presumably patch 22 "MIPS: VDSO: Drop 
git_get_usm_range() usage") is followed immediately by the removal of that 
function in patch 23 "irqchip: mips-gic: Remove gic_get_usm_range()".

The issue is that the MIPS GIC irqchip driver currently provides a bunch of 
functions which have nothing to do with interrupts, and so probably ought to 
be elsewhere. Moving that code elsewhere involves both adjusting the callers 
of those functions & then removing them from the irqchip driver, hence the 
non-irqchip patches followed by the related irqchip patches.

In general the only things that move are:

 - The GIC register definitions, to asm/mips-gic.h for reasons described in 
patch 2.

 - Functions as I mentioned in the previous paragraph which have nothing to do 
with the irqchip driver & don't need to be there once we have access to GIC 
registers elsewhere through asm/mips-gic.h.

 - A few other bits from linux/irqchip/mips-gic.h just so we can drop that 
header.

> Is there any chance you could rework this to have a more logical
> ordering? Something like fixes first, new features next, and
> optimizations in the end, organized by domains (arch stuff first, then
> irqchip, then timer, then userspace)?

It's already almost grouped like that. We have:

- Patch 1 is a fix.

- Patches 2 through 34 are cleanup, though a couple could probably be 
secondarily considered optimisations too.

- Patch 35 is an optimisation.

- Patches 36 through 38 could be considered optimisation or cleanup depending 
upon the tint of your glasses.

So I'm not sure what you're asking me to do here - to group them better I 
could perhaps move patch 35 to the end, but I'm not sure I see how that would 
make review any easier.

I didn't group by domain like you suggest for the reason I mention before - 
the non-irqchip patches are purely there to enable the following irqchip patch 
so it made sense to me to group those together. If you really want I could 
move all the non-irqchip patches to the start & all the irqchip patches to the 
end, but again I'm not sure I see how that helps - it would just mean that 
tightly related patches no longer follow one another.

> Because at the moment, this is a bit overwhelming...

My intent in splitting this into so many patches, and in grouping together the 
related non-irqchip & irqchip patches, was to reduce that overwhelming-ness by 
making each patch pretty readable by itself & perhaps taking into account only 
a patch or two before it. I guess that didn't work though.. :)

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-15 16:16   ` Paul Burton
  2017-08-15 16:16     ` Paul Burton
@ 2017-08-15 16:49     ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Marc Zyngier @ 2017-08-15 16:49 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

On 15/08/17 17:16, Paul Burton wrote:
> Hi Marc,
> 
> On Tuesday, 15 August 2017 03:13:03 PDT Marc Zyngier wrote:
>> Hi Paul,
>>
>> On 13/08/17 05:36, Paul Burton wrote:
>>> This series cleans up the MIPS Global Interrupt Controller (GIC) driver
>>> somewhat. It moves us towards using a header in a similar vein to the
>>> ones we have for the MIPS Coherence Manager (CM) & Cluster Power
>>> Controller (CPC) which allows us to access the GIC outside of the
>>> irqchip driver - something beneficial already for the clocksource &
>>> clock event driver, and which will be beneficial for further drivers
>>> (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
>>> this header is also beneficial for consistency & code-sharing.
>>>
>>> In addition to cleanups the series also optimises the driver in various
>>> ways, including by using a per-CPU variable for pcpu_masks & removing
>>> the need to read the GIC_SH_MASK_* registers when decoding interrupts in
>>> gic_handle_shared_int().
>>>
>>> This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
>>> support" series to be applied first.
>>
>> I'm not on Cc on this one, so it is a bit hard to see what's going on.
> 
> That other series is only really related insomuch as it adds asm/mips-cps.h 
> which this series makes use of, and changes a couple of lines in irq-mips-
> gic.c which would cause conflicts if this series is applied without the other 
> first.
> 
>> But overall, it is incredibly difficult to follow what is going on here.
>> Everything seems to move around, and while I'm sure that you have
>> something in mind, the mix of fixes+optimizations+new features is a bit
>> hard to swallow (not to mention the VDSO stuff in the middle of what is
>> supposed to be an irqchip series).
> 
> In general the non-irqchip patches preceed the irqchip patch that they enable. 
> For example, the VDSO patch you mention (presumably patch 22 "MIPS: VDSO: Drop 
> git_get_usm_range() usage") is followed immediately by the removal of that 
> function in patch 23 "irqchip: mips-gic: Remove gic_get_usm_range()".
> 
> The issue is that the MIPS GIC irqchip driver currently provides a bunch of 
> functions which have nothing to do with interrupts, and so probably ought to 
> be elsewhere. Moving that code elsewhere involves both adjusting the callers 
> of those functions & then removing them from the irqchip driver, hence the 
> non-irqchip patches followed by the related irqchip patches.
> 
> In general the only things that move are:
> 
>  - The GIC register definitions, to asm/mips-gic.h for reasons described in 
> patch 2.
> 
>  - Functions as I mentioned in the previous paragraph which have nothing to do 
> with the irqchip driver & don't need to be there once we have access to GIC 
> registers elsewhere through asm/mips-gic.h.
> 
>  - A few other bits from linux/irqchip/mips-gic.h just so we can drop that 
> header.
> 
>> Is there any chance you could rework this to have a more logical
>> ordering? Something like fixes first, new features next, and
>> optimizations in the end, organized by domains (arch stuff first, then
>> irqchip, then timer, then userspace)?
> 
> It's already almost grouped like that. We have:
> 
> - Patch 1 is a fix.
> 
> - Patches 2 through 34 are cleanup, though a couple could probably be 
> secondarily considered optimisations too.
> 
> - Patch 35 is an optimisation.
> 
> - Patches 36 through 38 could be considered optimisation or cleanup depending 
> upon the tint of your glasses.
> 
> So I'm not sure what you're asking me to do here - to group them better I 
> could perhaps move patch 35 to the end, but I'm not sure I see how that would 
> make review any easier.

This classification on its own is quite useful. In the future, please
add this kind of thing to the cover letter, it definitely helps.

> 
> I didn't group by domain like you suggest for the reason I mention before - 
> the non-irqchip patches are purely there to enable the following irqchip patch 
> so it made sense to me to group those together. If you really want I could 
> move all the non-irqchip patches to the start & all the irqchip patches to the 
> end, but again I'm not sure I see how that helps - it would just mean that 
> tightly related patches no longer follow one another.
> 
>> Because at the moment, this is a bit overwhelming...
> 
> My intent in splitting this into so many patches, and in grouping together the 
> related non-irqchip & irqchip patches, was to reduce that overwhelming-ness by 
> making each patch pretty readable by itself & perhaps taking into account only 
> a patch or two before it. I guess that didn't work though.. :)
I'll try and review the series with the above in mind. It will hopefully
make things easier.

Thanks,

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

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

* Re: [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  2017-08-13  4:36 ` [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions Paul Burton
  2017-08-13  4:36   ` Paul Burton
@ 2017-08-18 11:10   ` Marc Zyngier
  2017-08-18 16:43     ` Paul Burton
  1 sibling, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 11:10 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Thomas Gleixner
  Cc: Ralf Baechle, linux-kernel

On 13/08/17 05:36, Paul Burton wrote:
> This patch introduces a new header providing accessor functions for the
> MIPS Global Interrupt Controller (GIC) mirroring those provided for the
> other 2 components of the MIPS Coherent Processing System (CPS) - the
> Coherence Manager (CM) & Cluster Power Controller (CPC).
> 
> This header makes use of the new standardised CPS accessor macros where
> possible, but does require some custom accessors for cases where we have
> either a bit or a register per interrupt.
> 
> A major advantage of this over the existing
> include/linux/irqchip/mips-gic.h definitions is that code performing
> accesses can become much simpler, for example this:
> 
>   gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
>                   GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
>                   (unsigned long)trig << GIC_INTR_BIT(intr));
> 
> ...can become simply:
> 
>   change_gic_trig(intr, trig);
> 
> The accessors handle 32 vs 64 bit in the same way as for CM & CPC code,
> which means that GIC code will also not need to worry about the access
> size in most cases. They are also accessible outside of
> drivers/irqchip/irq-mips-gic.c which will allow for simplification in
> the use of the non-interrupt portions of the GIC (eg. counters) which
> currently require the interrupt controller driver to expose helper
> functions for access.
> 
> This patch doesn't change any existing code over to use the new
> accessors yet, since a wholesale change would be invasive & difficult to
> review. Instead follow-on patches will convert code piecemeal to use
> this new header. The one change to existing code is to rename gic_base
> to mips_gic_base & make it global, in order to fit in with the naming
> expected by the standardised CPS accessor macros.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-mips@linux-mips.org
> ---
> 
>  arch/mips/include/asm/mips-cps.h |   1 +
>  arch/mips/include/asm/mips-gic.h | 293 +++++++++++++++++++++++++++++++++++++++
>  drivers/irqchip/irq-mips-gic.c   |  13 +-
>  3 files changed, 300 insertions(+), 7 deletions(-)
>  create mode 100644 arch/mips/include/asm/mips-gic.h
> 
> diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
> index 2dd737d803e1..bf02b5070a98 100644
> --- a/arch/mips/include/asm/mips-cps.h
> +++ b/arch/mips/include/asm/mips-cps.h
> @@ -107,6 +107,7 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
>  
>  #include <asm/mips-cm.h>
>  #include <asm/mips-cpc.h>
> +#include <asm/mips-gic.h>
>  
>  /**
>   * mips_cps_numclusters - return the number of clusters present in the system
> diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
> new file mode 100644
> index 000000000000..8cf4bdc1a059
> --- /dev/null
> +++ b/arch/mips/include/asm/mips-gic.h
> @@ -0,0 +1,293 @@
> +/*
> + * Copyright (C) 2017 Imagination Technologies
> + * Author: Paul Burton <paul.burton@imgtec.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#ifndef __MIPS_ASM_MIPS_CPS_H__
> +# error Please include asm/mips-cps.h rather than asm/mips-gic.h
> +#endif
> +
> +#ifndef __MIPS_ASM_MIPS_GIC_H__
> +#define __MIPS_ASM_MIPS_GIC_H__
> +
> +#include <linux/bitops.h>
> +
> +/* The base address of the GIC registers */
> +extern void __iomem *mips_gic_base;
> +
> +/* Offsets from the GIC base address to various control blocks */
> +#define MIPS_GIC_SHARED_OFS	0x00000
> +#define MIPS_GIC_SHARED_SZ	0x08000
> +#define MIPS_GIC_LOCAL_OFS	0x08000
> +#define MIPS_GIC_LOCAL_SZ	0x04000
> +#define MIPS_GIC_REDIR_OFS	0x0c000
> +#define MIPS_GIC_REDIR_SZ	0x04000
> +#define MIPS_GIC_USER_OFS	0x10000
> +#define MIPS_GIC_USER_SZ	0x10000
> +
> +/* For read-only shared registers */
> +#define GIC_ACCESSOR_RO(sz, off, name)					\
> +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
> +
> +/* For read-write shared registers */
> +#define GIC_ACCESSOR_RW(sz, off, name)					\
> +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
> +
> +/* For read-only local registers */
> +#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
> +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
> +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
> +
> +/* For read-write local registers */
> +#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
> +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
> +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
> +
> +/* For read-only shared per-interrupt registers */
> +#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
> +static inline void __iomem *addr_gic_##name(unsigned int intr)		\
> +{									\
> +	return mips_gic_base + (off) + (intr * (stride));		\
> +}									\
> +									\
> +static inline unsigned int read_gic_##name(unsigned int intr)		\
> +{									\
> +	BUILD_BUG_ON(sz != 32);						\
> +	return __raw_readl(addr_gic_##name(intr));			\
> +}
> +
> +/* For read-write shared per-interrupt registers */
> +#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
> +	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
> +									\
> +static inline void write_gic_##name(unsigned int intr,			\
> +				    unsigned int val)			\
> +{									\
> +	BUILD_BUG_ON(sz != 32);						\
> +	__raw_writel(val, addr_gic_##name(intr));			\
> +}
> +
> +/* For read-only local per-interrupt registers */
> +#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
> +	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
> +				 stride, vl_##name)			\
> +	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
> +				 stride, vo_##name)
> +
> +/* For read-write local per-interrupt registers */
> +#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
> +	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
> +				 stride, vl_##name)			\
> +	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
> +				 stride, vo_##name)
> +
> +/* For read-only shared bit-per-interrupt registers */
> +#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
> +static inline void __iomem *addr_gic_##name(void)			\
> +{									\
> +	return mips_gic_base + (off);					\
> +}									\
> +									\
> +static inline unsigned int read_gic_##name(unsigned int intr)		\
> +{									\
> +	void __iomem *addr = addr_gic_##name();				\
> +	unsigned int val;						\
> +									\
> +	if (mips_cm_is64) {						\
> +		addr += (intr / 64) * sizeof(uint64_t);			\
> +		val = __raw_readq(addr) >> intr % 64;			\
> +	} else {							\
> +		addr += (intr / 32) * sizeof(uint32_t);			\
> +		val = __raw_readl(addr) >> intr % 32;			\
> +	}								\
> +									\
> +	return val & 0x1;						\
> +}
> +
> +/* For read-write shared bit-per-interrupt registers */
> +#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
> +	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
> +									\
> +static inline void write_gic_##name(unsigned int intr)			\
> +{									\
> +	void __iomem *addr = addr_gic_##name();				\
> +									\
> +	if (mips_cm_is64) {						\

Given that you now refer to this symbol, wouldn't it be best to include
asm/mips-cm.h here? It is probably included via some other path, but
it'd make this file standalone.

Thanks,

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

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

* Re: [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage
  2017-08-13  4:36 ` [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage Paul Burton
  2017-08-13  4:36   ` Paul Burton
@ 2017-08-18 11:38   ` Marc Zyngier
  2017-08-18 16:47     ` Paul Burton
  1 sibling, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 11:38 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Thomas Gleixner; +Cc: Ralf Baechle

On 13/08/17 05:36, Paul Burton wrote:
> We don't really need gic_get_usm_range() to abstract discovery of the
> address of the GIC user-visible section now that we have access to its
> base address globally.
> 
> Switch to calculating it ourselves, which will allow us to stop
> requiring the irqchip driver to care about a counter exposed to userland
> for use via the VDSO.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mips@linux-mips.org
> ---
> 
>  arch/mips/kernel/vdso.c | 15 +++++----------
>  1 file changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
> index 093517e85a6c..019035d7225c 100644
> --- a/arch/mips/kernel/vdso.c
> +++ b/arch/mips/kernel/vdso.c
> @@ -13,13 +13,13 @@
>  #include <linux/err.h>
>  #include <linux/init.h>
>  #include <linux/ioport.h>
> -#include <linux/irqchip/mips-gic.h>
>  #include <linux/mm.h>
>  #include <linux/sched.h>
>  #include <linux/slab.h>
>  #include <linux/timekeeper_internal.h>
>  
>  #include <asm/abi.h>
> +#include <asm/mips-cps.h>
>  #include <asm/vdso.h>
>  
>  /* Kernel-provided data used by the VDSO. */
> @@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  {
>  	struct mips_vdso_image *image = current->thread.abi->vdso;
>  	struct mm_struct *mm = current->mm;
> -	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
> +	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn;
>  	struct vm_area_struct *vma;
> -	struct resource gic_res;
>  	int ret;
>  
>  	if (down_write_killable(&mm->mmap_sem))
> @@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  	 * only map a page even though the total area is 64K, as we only need
>  	 * the counter registers at the start.
>  	 */
> -	gic_size = gic_present ? PAGE_SIZE : 0;
> +	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
>  	vvar_size = gic_size + PAGE_SIZE;
>  	size = vvar_size + image->size;
>  
> @@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  
>  	/* Map GIC user page. */
>  	if (gic_size) {
> -		ret = gic_get_usm_range(&gic_res);
> -		if (ret)
> -			goto out;
> +		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT;

virt_to_pfn() instead?

>  
> -		ret = io_remap_pfn_range(vma, base,
> -					 gic_res.start >> PAGE_SHIFT,
> -					 gic_size,
> +		ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
>  					 pgprot_noncached(PAGE_READONLY));
>  		if (ret)
>  			goto out;
> 

Thanks,

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

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

* Re: [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  2017-08-13  4:36 ` [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable Paul Burton
  2017-08-13  4:36   ` Paul Burton
@ 2017-08-18 15:37   ` Marc Zyngier
  2017-08-18 17:02     ` Paul Burton
  1 sibling, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 15:37 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Thomas Gleixner; +Cc: Ralf Baechle

On 13/08/17 05:36, Paul Burton wrote:
> Define the pcpu_masks variable using the kernel's standard per-cpu
> variable support, rather than an open-coded array of structs containing
> bitmaps.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mips@linux-mips.org
> ---
> 
>  drivers/irqchip/irq-mips-gic.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
> index feff4bf97577..00153231376a 100644
> --- a/drivers/irqchip/irq-mips-gic.c
> +++ b/drivers/irqchip/irq-mips-gic.c
> @@ -13,6 +13,7 @@
>  #include <linux/irq.h>
>  #include <linux/irqchip.h>
>  #include <linux/of_address.h>
> +#include <linux/percpu.h>
>  #include <linux/sched.h>
>  #include <linux/smp.h>
>  
> @@ -23,6 +24,7 @@
>  #include <dt-bindings/interrupt-controller/mips-gic.h>
>  
>  #define GIC_MAX_INTRS		256
> +#define GIC_MAX_LONGS		BITS_TO_LONGS(GIC_MAX_INTRS)
>  
>  /* Add 2 to convert GIC CPU pin to core interrupt */
>  #define GIC_CPU_PIN_OFFSET	2
> @@ -40,11 +42,8 @@
>  
>  void __iomem *mips_gic_base;
>  
> -struct gic_pcpu_mask {
> -	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
> -};
> +DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
>  
> -static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
>  static DEFINE_SPINLOCK(gic_lock);
>  static struct irq_domain *gic_irq_domain;
>  static struct irq_domain *gic_ipi_domain;
> @@ -137,7 +136,7 @@ static void gic_handle_shared_int(bool chained)
>  	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
>  
>  	/* Get per-cpu bitmaps */
> -	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
> +	pcpu_mask = this_cpu_ptr(pcpu_masks);
>  
>  	if (mips_cm_is64) {
>  		__ioread64_copy(pending, addr_gic_pend(),
> @@ -254,8 +253,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
>  
>  	/* Update the pcpu_masks */
>  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)

Is there any case where gic_vpes is not equal to nr_cpus?

> -		clear_bit(irq, pcpu_masks[i].pcpu_mask);
> -	set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);
> +		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
> +	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
>  
>  	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
>  	spin_unlock_irqrestore(&gic_lock, flags);
> @@ -416,8 +415,8 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
>  	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
>  	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
>  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> -		clear_bit(intr, pcpu_masks[i].pcpu_mask);
> -	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
> +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> +	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
>  	spin_unlock_irqrestore(&gic_lock, flags);
>  
>  	return 0;
> 

Thanks,

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

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

* Re: [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-13  4:36 ` [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK* Paul Burton
  2017-08-13  4:36   ` Paul Burton
@ 2017-08-18 15:44   ` Marc Zyngier
  2017-08-18 17:11     ` Paul Burton
  1 sibling, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 15:44 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Thomas Gleixner; +Cc: Ralf Baechle

On 13/08/17 05:36, Paul Burton wrote:
> This patch avoids the need to read the GIC_SH_MASK* registers when
> decoding shared interrupts by setting & clearing the interrupt's bit in
> the appropriate CPU's pcpu_masks entry when masking or unmasking the
> interrupt.
> 
> This effectively means that whilst an interrupt is masked we clear its
> bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
> on all CPUs without needing to check GIC_SH_MASK*.
> 
> In essence, we add a little overhead to masking or unmasking interrupts
> but in return reduce the overhead of the far more common task of
> decoding interrupts.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mips@linux-mips.org
> ---
> 
>  drivers/irqchip/irq-mips-gic.c | 49 ++++++++++++++++++++++++------------------
>  1 file changed, 28 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
> index 00153231376a..7a42f0b3822f 100644
> --- a/drivers/irqchip/irq-mips-gic.c
> +++ b/drivers/irqchip/irq-mips-gic.c
> @@ -55,6 +55,19 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
>  DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
>  DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
>  
> +static void gic_setup_pcpu_mask(unsigned int intr, unsigned int cpu)
> +{
> +	unsigned int i;
> +
> +	/* Clear the interrupt's bit in all pcpu_masks */
> +	for_each_possible_cpu(i)
> +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));

This iterates from 0 to nr_cpu_ids-1...

> +
> +	/* Set the interrupt's bit in the appropriate CPU's mask */
> +	if (cpu < NR_CPUS)

and here you're using NR_CPUS. I'm a bit worried that you're not quite
using the same thing (nr_cpu_ids <= NR_CPUS).

> +		set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
> +}
> +
>  static bool gic_local_irq_is_routable(int intr)
>  {
>  	u32 vpe_ctl;
> @@ -133,24 +146,17 @@ static void gic_handle_shared_int(bool chained)
>  	unsigned int intr, virq;
>  	unsigned long *pcpu_mask;
>  	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
> -	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
>  
>  	/* Get per-cpu bitmaps */
>  	pcpu_mask = this_cpu_ptr(pcpu_masks);
>  
> -	if (mips_cm_is64) {
> +	if (mips_cm_is64)
>  		__ioread64_copy(pending, addr_gic_pend(),
>  				DIV_ROUND_UP(gic_shared_intrs, 64));
> -		__ioread64_copy(intrmask, addr_gic_mask(),
> -				DIV_ROUND_UP(gic_shared_intrs, 64));
> -	} else {
> +	else
>  		__ioread32_copy(pending, addr_gic_pend(),
>  				DIV_ROUND_UP(gic_shared_intrs, 32));
> -		__ioread32_copy(intrmask, addr_gic_mask(),
> -				DIV_ROUND_UP(gic_shared_intrs, 32));
> -	}
>  
> -	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
>  	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
>  
>  	for_each_set_bit(intr, pending, gic_shared_intrs) {
> @@ -165,12 +171,19 @@ static void gic_handle_shared_int(bool chained)
>  
>  static void gic_mask_irq(struct irq_data *d)
>  {
> -	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
> +	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
> +
> +	write_gic_rmask(BIT(intr));
> +	gic_setup_pcpu_mask(intr, NR_CPUS);
>  }
>  
>  static void gic_unmask_irq(struct irq_data *d)
>  {
> -	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
> +	struct cpumask *affinity = irq_data_get_affinity_mask(d);
> +	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
> +
> +	write_gic_smask(BIT(intr));
> +	gic_setup_pcpu_mask(intr, cpumask_first_and(affinity, cpu_online_mask));
>  }
>  
>  static void gic_ack_irq(struct irq_data *d)
> @@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
>  	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
>  	cpumask_t	tmp = CPU_MASK_NONE;
>  	unsigned long	flags;
> -	int		i;
>  
>  	cpumask_and(&tmp, cpumask, cpu_online_mask);
>  	if (cpumask_empty(&tmp))
> @@ -252,9 +264,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
>  	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
>  
>  	/* Update the pcpu_masks */
> -	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> -		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
> -	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
> +	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) : NR_CPUS);
>  
>  	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
>  	spin_unlock_irqrestore(&gic_lock, flags);
> @@ -405,18 +415,15 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
>  }
>  
>  static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
> -				     irq_hw_number_t hw, unsigned int vpe)
> +				     irq_hw_number_t hw, unsigned int cpu)
>  {
>  	int intr = GIC_HWIRQ_TO_SHARED(hw);
>  	unsigned long flags;
> -	int i;
>  
>  	spin_lock_irqsave(&gic_lock, flags);
>  	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
> -	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
> -	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> -		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> -	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
> +	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
> +	gic_setup_pcpu_mask(intr, cpu);
>  	spin_unlock_irqrestore(&gic_lock, flags);
>  
>  	return 0;
> 

Thanks,

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

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

* Re: [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  2017-08-18 11:10   ` Marc Zyngier
@ 2017-08-18 16:43     ` Paul Burton
  2017-08-18 16:43       ` Paul Burton
  0 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-18 16:43 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle,
	linux-kernel

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

Hi Marc,

On Friday, 18 August 2017 04:10:20 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > This patch introduces a new header providing accessor functions for the
> > MIPS Global Interrupt Controller (GIC) mirroring those provided for the
> > other 2 components of the MIPS Coherent Processing System (CPS) - the
> > Coherence Manager (CM) & Cluster Power Controller (CPC).
> > 
> > This header makes use of the new standardised CPS accessor macros where
> > possible, but does require some custom accessors for cases where we have
> > either a bit or a register per interrupt.
> > 
> > A major advantage of this over the existing
> > include/linux/irqchip/mips-gic.h definitions is that code performing
> > 
> > accesses can become much simpler, for example this:
> >   gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
> >   
> >                   GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
> >                   (unsigned long)trig << GIC_INTR_BIT(intr));
> > 
> > ...can become simply:
> >   change_gic_trig(intr, trig);
> > 
> > The accessors handle 32 vs 64 bit in the same way as for CM & CPC code,
> > which means that GIC code will also not need to worry about the access
> > size in most cases. They are also accessible outside of
> > drivers/irqchip/irq-mips-gic.c which will allow for simplification in
> > the use of the non-interrupt portions of the GIC (eg. counters) which
> > currently require the interrupt controller driver to expose helper
> > functions for access.
> > 
> > This patch doesn't change any existing code over to use the new
> > accessors yet, since a wholesale change would be invasive & difficult to
> > review. Instead follow-on patches will convert code piecemeal to use
> > this new header. The one change to existing code is to rename gic_base
> > to mips_gic_base & make it global, in order to fit in with the naming
> > expected by the standardised CPS accessor macros.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-kernel@vger.kernel.org
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  arch/mips/include/asm/mips-cps.h |   1 +
> >  arch/mips/include/asm/mips-gic.h | 293
> >  +++++++++++++++++++++++++++++++++++++++ drivers/irqchip/irq-mips-gic.c  
> >  |  13 +-
> >  3 files changed, 300 insertions(+), 7 deletions(-)
> >  create mode 100644 arch/mips/include/asm/mips-gic.h
> > 
> > diff --git a/arch/mips/include/asm/mips-cps.h
> > b/arch/mips/include/asm/mips-cps.h index 2dd737d803e1..bf02b5070a98
> > 100644
> > --- a/arch/mips/include/asm/mips-cps.h
> > +++ b/arch/mips/include/asm/mips-cps.h
> > @@ -107,6 +107,7 @@ static inline void clear_##unit##_##name(uint##sz##_t
> > val)		\> 
> >  #include <asm/mips-cm.h>
> >  #include <asm/mips-cpc.h>
> > 
> > +#include <asm/mips-gic.h>
> > 
> >  /**
> >  
> >   * mips_cps_numclusters - return the number of clusters present in the
> >   system> 
> > diff --git a/arch/mips/include/asm/mips-gic.h
> > b/arch/mips/include/asm/mips-gic.h new file mode 100644
> > index 000000000000..8cf4bdc1a059
> > --- /dev/null
> > +++ b/arch/mips/include/asm/mips-gic.h
> > @@ -0,0 +1,293 @@
> > +/*
> > + * Copyright (C) 2017 Imagination Technologies
> > + * Author: Paul Burton <paul.burton@imgtec.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > it
> > + * under the terms of the GNU General Public License as published by the
> > + * Free Software Foundation;  either version 2 of the  License, or (at
> > your + * option) any later version.
> > + */
> > +
> > +#ifndef __MIPS_ASM_MIPS_CPS_H__
> > +# error Please include asm/mips-cps.h rather than asm/mips-gic.h
> > +#endif
> > +
> > +#ifndef __MIPS_ASM_MIPS_GIC_H__
> > +#define __MIPS_ASM_MIPS_GIC_H__
> > +
> > +#include <linux/bitops.h>
> > +
> > +/* The base address of the GIC registers */
> > +extern void __iomem *mips_gic_base;
> > +
> > +/* Offsets from the GIC base address to various control blocks */
> > +#define MIPS_GIC_SHARED_OFS	0x00000
> > +#define MIPS_GIC_SHARED_SZ	0x08000
> > +#define MIPS_GIC_LOCAL_OFS	0x08000
> > +#define MIPS_GIC_LOCAL_SZ	0x04000
> > +#define MIPS_GIC_REDIR_OFS	0x0c000
> > +#define MIPS_GIC_REDIR_SZ	0x04000
> > +#define MIPS_GIC_USER_OFS	0x10000
> > +#define MIPS_GIC_USER_SZ	0x10000
> > +
> > +/* For read-only shared registers */
> > +#define GIC_ACCESSOR_RO(sz, off, name)					\
> > +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
> > +
> > +/* For read-write shared registers */
> > +#define GIC_ACCESSOR_RW(sz, off, name)					\
> > +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
> > +
> > +/* For read-only local registers */
> > +#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
> > +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
> > +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
> > +
> > +/* For read-write local registers */
> > +#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
> > +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
> > +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
> > +
> > +/* For read-only shared per-interrupt registers */
> > +#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
> > +static inline void __iomem *addr_gic_##name(unsigned int intr)		\
> > +{									\
> > +	return mips_gic_base + (off) + (intr * (stride));		\
> > +}									\
> > +									\
> > +static inline unsigned int read_gic_##name(unsigned int intr)		\
> > +{									\
> > +	BUILD_BUG_ON(sz != 32);						\
> > +	return __raw_readl(addr_gic_##name(intr));			\
> > +}
> > +
> > +/* For read-write shared per-interrupt registers */
> > +#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
> > +	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
> > +									\
> > +static inline void write_gic_##name(unsigned int intr,			\
> > +				    unsigned int val)			\
> > +{									\
> > +	BUILD_BUG_ON(sz != 32);						\
> > +	__raw_writel(val, addr_gic_##name(intr));			\
> > +}
> > +
> > +/* For read-only local per-interrupt registers */
> > +#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
> > +	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
> > +				 stride, vl_##name)			\
> > +	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
> > +				 stride, vo_##name)
> > +
> > +/* For read-write local per-interrupt registers */
> > +#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
> > +	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
> > +				 stride, vl_##name)			\
> > +	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
> > +				 stride, vo_##name)
> > +
> > +/* For read-only shared bit-per-interrupt registers */
> > +#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
> > +static inline void __iomem *addr_gic_##name(void)			\
> > +{									\
> > +	return mips_gic_base + (off);					\
> > +}									\
> > +									\
> > +static inline unsigned int read_gic_##name(unsigned int intr)		\
> > +{									\
> > +	void __iomem *addr = addr_gic_##name();				\
> > +	unsigned int val;						\
> > +									\
> > +	if (mips_cm_is64) {						\
> > +		addr += (intr / 64) * sizeof(uint64_t);			\
> > +		val = __raw_readq(addr) >> intr % 64;			\
> > +	} else {							\
> > +		addr += (intr / 32) * sizeof(uint32_t);			\
> > +		val = __raw_readl(addr) >> intr % 32;			\
> > +	}								\
> > +									\
> > +	return val & 0x1;						\
> > +}
> > +
> > +/* For read-write shared bit-per-interrupt registers */
> > +#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
> > +	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
> > +									\
> > +static inline void write_gic_##name(unsigned int intr)			\
> > +{									\
> > +	void __iomem *addr = addr_gic_##name();				\
> > +									\
> > +	if (mips_cm_is64) {						\
> 
> Given that you now refer to this symbol, wouldn't it be best to include
> asm/mips-cm.h here? It is probably included via some other path, but
> it'd make this file standalone.
> 
> Thanks,
> 
> 	M.

The inclusion is actually sort of the other way right now - asm/mips-cps.h 
includes each of asm/mips-cm.h, asm/mips-cpc.h & asm/mips-gic.h. This allows 
us to have code in asm/mips-cps.h which makes use of combinations of those 3 
blocks (CM, CPC & GIC) that form the MIPS Coherent Processing System.

Right now, well once the "MIPS: Initial multi-cluster support" series gets 
merged, the code in asm/mips-cps.h only really requires the CM & CPC headers 
but it seemed good to be consistent & include the GIC one in the same way.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions
  2017-08-18 16:43     ` Paul Burton
@ 2017-08-18 16:43       ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 16:43 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle,
	linux-kernel

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

Hi Marc,

On Friday, 18 August 2017 04:10:20 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > This patch introduces a new header providing accessor functions for the
> > MIPS Global Interrupt Controller (GIC) mirroring those provided for the
> > other 2 components of the MIPS Coherent Processing System (CPS) - the
> > Coherence Manager (CM) & Cluster Power Controller (CPC).
> > 
> > This header makes use of the new standardised CPS accessor macros where
> > possible, but does require some custom accessors for cases where we have
> > either a bit or a register per interrupt.
> > 
> > A major advantage of this over the existing
> > include/linux/irqchip/mips-gic.h definitions is that code performing
> > 
> > accesses can become much simpler, for example this:
> >   gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
> >   
> >                   GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
> >                   (unsigned long)trig << GIC_INTR_BIT(intr));
> > 
> > ...can become simply:
> >   change_gic_trig(intr, trig);
> > 
> > The accessors handle 32 vs 64 bit in the same way as for CM & CPC code,
> > which means that GIC code will also not need to worry about the access
> > size in most cases. They are also accessible outside of
> > drivers/irqchip/irq-mips-gic.c which will allow for simplification in
> > the use of the non-interrupt portions of the GIC (eg. counters) which
> > currently require the interrupt controller driver to expose helper
> > functions for access.
> > 
> > This patch doesn't change any existing code over to use the new
> > accessors yet, since a wholesale change would be invasive & difficult to
> > review. Instead follow-on patches will convert code piecemeal to use
> > this new header. The one change to existing code is to rename gic_base
> > to mips_gic_base & make it global, in order to fit in with the naming
> > expected by the standardised CPS accessor macros.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-kernel@vger.kernel.org
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  arch/mips/include/asm/mips-cps.h |   1 +
> >  arch/mips/include/asm/mips-gic.h | 293
> >  +++++++++++++++++++++++++++++++++++++++ drivers/irqchip/irq-mips-gic.c  
> >  |  13 +-
> >  3 files changed, 300 insertions(+), 7 deletions(-)
> >  create mode 100644 arch/mips/include/asm/mips-gic.h
> > 
> > diff --git a/arch/mips/include/asm/mips-cps.h
> > b/arch/mips/include/asm/mips-cps.h index 2dd737d803e1..bf02b5070a98
> > 100644
> > --- a/arch/mips/include/asm/mips-cps.h
> > +++ b/arch/mips/include/asm/mips-cps.h
> > @@ -107,6 +107,7 @@ static inline void clear_##unit##_##name(uint##sz##_t
> > val)		\> 
> >  #include <asm/mips-cm.h>
> >  #include <asm/mips-cpc.h>
> > 
> > +#include <asm/mips-gic.h>
> > 
> >  /**
> >  
> >   * mips_cps_numclusters - return the number of clusters present in the
> >   system> 
> > diff --git a/arch/mips/include/asm/mips-gic.h
> > b/arch/mips/include/asm/mips-gic.h new file mode 100644
> > index 000000000000..8cf4bdc1a059
> > --- /dev/null
> > +++ b/arch/mips/include/asm/mips-gic.h
> > @@ -0,0 +1,293 @@
> > +/*
> > + * Copyright (C) 2017 Imagination Technologies
> > + * Author: Paul Burton <paul.burton@imgtec.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > it
> > + * under the terms of the GNU General Public License as published by the
> > + * Free Software Foundation;  either version 2 of the  License, or (at
> > your + * option) any later version.
> > + */
> > +
> > +#ifndef __MIPS_ASM_MIPS_CPS_H__
> > +# error Please include asm/mips-cps.h rather than asm/mips-gic.h
> > +#endif
> > +
> > +#ifndef __MIPS_ASM_MIPS_GIC_H__
> > +#define __MIPS_ASM_MIPS_GIC_H__
> > +
> > +#include <linux/bitops.h>
> > +
> > +/* The base address of the GIC registers */
> > +extern void __iomem *mips_gic_base;
> > +
> > +/* Offsets from the GIC base address to various control blocks */
> > +#define MIPS_GIC_SHARED_OFS	0x00000
> > +#define MIPS_GIC_SHARED_SZ	0x08000
> > +#define MIPS_GIC_LOCAL_OFS	0x08000
> > +#define MIPS_GIC_LOCAL_SZ	0x04000
> > +#define MIPS_GIC_REDIR_OFS	0x0c000
> > +#define MIPS_GIC_REDIR_SZ	0x04000
> > +#define MIPS_GIC_USER_OFS	0x10000
> > +#define MIPS_GIC_USER_SZ	0x10000
> > +
> > +/* For read-only shared registers */
> > +#define GIC_ACCESSOR_RO(sz, off, name)					\
> > +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
> > +
> > +/* For read-write shared registers */
> > +#define GIC_ACCESSOR_RW(sz, off, name)					\
> > +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
> > +
> > +/* For read-only local registers */
> > +#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
> > +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
> > +	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
> > +
> > +/* For read-write local registers */
> > +#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
> > +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
> > +	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
> > +
> > +/* For read-only shared per-interrupt registers */
> > +#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
> > +static inline void __iomem *addr_gic_##name(unsigned int intr)		\
> > +{									\
> > +	return mips_gic_base + (off) + (intr * (stride));		\
> > +}									\
> > +									\
> > +static inline unsigned int read_gic_##name(unsigned int intr)		\
> > +{									\
> > +	BUILD_BUG_ON(sz != 32);						\
> > +	return __raw_readl(addr_gic_##name(intr));			\
> > +}
> > +
> > +/* For read-write shared per-interrupt registers */
> > +#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
> > +	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
> > +									\
> > +static inline void write_gic_##name(unsigned int intr,			\
> > +				    unsigned int val)			\
> > +{									\
> > +	BUILD_BUG_ON(sz != 32);						\
> > +	__raw_writel(val, addr_gic_##name(intr));			\
> > +}
> > +
> > +/* For read-only local per-interrupt registers */
> > +#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
> > +	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
> > +				 stride, vl_##name)			\
> > +	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
> > +				 stride, vo_##name)
> > +
> > +/* For read-write local per-interrupt registers */
> > +#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
> > +	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
> > +				 stride, vl_##name)			\
> > +	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
> > +				 stride, vo_##name)
> > +
> > +/* For read-only shared bit-per-interrupt registers */
> > +#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
> > +static inline void __iomem *addr_gic_##name(void)			\
> > +{									\
> > +	return mips_gic_base + (off);					\
> > +}									\
> > +									\
> > +static inline unsigned int read_gic_##name(unsigned int intr)		\
> > +{									\
> > +	void __iomem *addr = addr_gic_##name();				\
> > +	unsigned int val;						\
> > +									\
> > +	if (mips_cm_is64) {						\
> > +		addr += (intr / 64) * sizeof(uint64_t);			\
> > +		val = __raw_readq(addr) >> intr % 64;			\
> > +	} else {							\
> > +		addr += (intr / 32) * sizeof(uint32_t);			\
> > +		val = __raw_readl(addr) >> intr % 32;			\
> > +	}								\
> > +									\
> > +	return val & 0x1;						\
> > +}
> > +
> > +/* For read-write shared bit-per-interrupt registers */
> > +#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
> > +	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
> > +									\
> > +static inline void write_gic_##name(unsigned int intr)			\
> > +{									\
> > +	void __iomem *addr = addr_gic_##name();				\
> > +									\
> > +	if (mips_cm_is64) {						\
> 
> Given that you now refer to this symbol, wouldn't it be best to include
> asm/mips-cm.h here? It is probably included via some other path, but
> it'd make this file standalone.
> 
> Thanks,
> 
> 	M.

The inclusion is actually sort of the other way right now - asm/mips-cps.h 
includes each of asm/mips-cm.h, asm/mips-cpc.h & asm/mips-gic.h. This allows 
us to have code in asm/mips-cps.h which makes use of combinations of those 3 
blocks (CM, CPC & GIC) that form the MIPS Coherent Processing System.

Right now, well once the "MIPS: Initial multi-cluster support" series gets 
merged, the code in asm/mips-cps.h only really requires the CM & CPC headers 
but it seemed good to be consistent & include the GIC one in the same way.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage
  2017-08-18 11:38   ` Marc Zyngier
@ 2017-08-18 16:47     ` Paul Burton
  2017-08-18 16:47       ` Paul Burton
  2017-08-18 16:52       ` Marc Zyngier
  0 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 16:47 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Friday, 18 August 2017 04:38:50 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > We don't really need gic_get_usm_range() to abstract discovery of the
> > address of the GIC user-visible section now that we have access to its
> > base address globally.
> > 
> > Switch to calculating it ourselves, which will allow us to stop
> > requiring the irqchip driver to care about a counter exposed to userland
> > for use via the VDSO.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  arch/mips/kernel/vdso.c | 15 +++++----------
> >  1 file changed, 5 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
> > index 093517e85a6c..019035d7225c 100644
> > --- a/arch/mips/kernel/vdso.c
> > +++ b/arch/mips/kernel/vdso.c
> > @@ -13,13 +13,13 @@
> > 
> >  #include <linux/err.h>
> >  #include <linux/init.h>
> >  #include <linux/ioport.h>
> > 
> > -#include <linux/irqchip/mips-gic.h>
> > 
> >  #include <linux/mm.h>
> >  #include <linux/sched.h>
> >  #include <linux/slab.h>
> >  #include <linux/timekeeper_internal.h>
> >  
> >  #include <asm/abi.h>
> > 
> > +#include <asm/mips-cps.h>
> > 
> >  #include <asm/vdso.h>
> >  
> >  /* Kernel-provided data used by the VDSO. */
> > 
> > @@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm
> > *bprm, int uses_interp)> 
> >  {
> >  
> >  	struct mips_vdso_image *image = current->thread.abi->vdso;
> >  	struct mm_struct *mm = current->mm;
> > 
> > -	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
> > +	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr,
> > gic_pfn;> 
> >  	struct vm_area_struct *vma;
> > 
> > -	struct resource gic_res;
> > 
> >  	int ret;
> >  	
> >  	if (down_write_killable(&mm->mmap_sem))
> > 
> > @@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm
> > *bprm, int uses_interp)> 
> >  	 * only map a page even though the total area is 64K, as we only need
> >  	 * the counter registers at the start.
> >  	 */
> > 
> > -	gic_size = gic_present ? PAGE_SIZE : 0;
> > +	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
> > 
> >  	vvar_size = gic_size + PAGE_SIZE;
> >  	size = vvar_size + image->size;
> > 
> > @@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm
> > *bprm, int uses_interp)> 
> >  	/* Map GIC user page. */
> >  	if (gic_size) {
> > 
> > -		ret = gic_get_usm_range(&gic_res);
> > -		if (ret)
> > -			goto out;
> > +		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >>
> > PAGE_SHIFT;
> 
> virt_to_pfn() instead?

We don't seem to have virt_to_pfn() on MIPS, but I'd be happy to add it & tidy 
up a few places that could use it. Would you mind if that cleanup came 
separately though?

> 
> > -		ret = io_remap_pfn_range(vma, base,
> > -					 gic_res.start >> PAGE_SHIFT,
> > -					 gic_size,
> > +		ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
> > 
> >  					 pgprot_noncached(PAGE_READONLY));
> >  		
> >  		if (ret)
> >  		
> >  			goto out;
> 
> Thanks,
> 
> 	M.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage
  2017-08-18 16:47     ` Paul Burton
@ 2017-08-18 16:47       ` Paul Burton
  2017-08-18 16:52       ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 16:47 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Friday, 18 August 2017 04:38:50 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > We don't really need gic_get_usm_range() to abstract discovery of the
> > address of the GIC user-visible section now that we have access to its
> > base address globally.
> > 
> > Switch to calculating it ourselves, which will allow us to stop
> > requiring the irqchip driver to care about a counter exposed to userland
> > for use via the VDSO.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  arch/mips/kernel/vdso.c | 15 +++++----------
> >  1 file changed, 5 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
> > index 093517e85a6c..019035d7225c 100644
> > --- a/arch/mips/kernel/vdso.c
> > +++ b/arch/mips/kernel/vdso.c
> > @@ -13,13 +13,13 @@
> > 
> >  #include <linux/err.h>
> >  #include <linux/init.h>
> >  #include <linux/ioport.h>
> > 
> > -#include <linux/irqchip/mips-gic.h>
> > 
> >  #include <linux/mm.h>
> >  #include <linux/sched.h>
> >  #include <linux/slab.h>
> >  #include <linux/timekeeper_internal.h>
> >  
> >  #include <asm/abi.h>
> > 
> > +#include <asm/mips-cps.h>
> > 
> >  #include <asm/vdso.h>
> >  
> >  /* Kernel-provided data used by the VDSO. */
> > 
> > @@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm
> > *bprm, int uses_interp)> 
> >  {
> >  
> >  	struct mips_vdso_image *image = current->thread.abi->vdso;
> >  	struct mm_struct *mm = current->mm;
> > 
> > -	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
> > +	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr,
> > gic_pfn;> 
> >  	struct vm_area_struct *vma;
> > 
> > -	struct resource gic_res;
> > 
> >  	int ret;
> >  	
> >  	if (down_write_killable(&mm->mmap_sem))
> > 
> > @@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm
> > *bprm, int uses_interp)> 
> >  	 * only map a page even though the total area is 64K, as we only need
> >  	 * the counter registers at the start.
> >  	 */
> > 
> > -	gic_size = gic_present ? PAGE_SIZE : 0;
> > +	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
> > 
> >  	vvar_size = gic_size + PAGE_SIZE;
> >  	size = vvar_size + image->size;
> > 
> > @@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm
> > *bprm, int uses_interp)> 
> >  	/* Map GIC user page. */
> >  	if (gic_size) {
> > 
> > -		ret = gic_get_usm_range(&gic_res);
> > -		if (ret)
> > -			goto out;
> > +		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >>
> > PAGE_SHIFT;
> 
> virt_to_pfn() instead?

We don't seem to have virt_to_pfn() on MIPS, but I'd be happy to add it & tidy 
up a few places that could use it. Would you mind if that cleanup came 
separately though?

> 
> > -		ret = io_remap_pfn_range(vma, base,
> > -					 gic_res.start >> PAGE_SHIFT,
> > -					 gic_size,
> > +		ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
> > 
> >  					 pgprot_noncached(PAGE_READONLY));
> >  		
> >  		if (ret)
> >  		
> >  			goto out;
> 
> Thanks,
> 
> 	M.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage
  2017-08-18 16:47     ` Paul Burton
  2017-08-18 16:47       ` Paul Burton
@ 2017-08-18 16:52       ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 16:52 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

On 18/08/17 17:47, Paul Burton wrote:
> Hi Marc,
> 
> On Friday, 18 August 2017 04:38:50 PDT Marc Zyngier wrote:
>> On 13/08/17 05:36, Paul Burton wrote:
>>> We don't really need gic_get_usm_range() to abstract discovery of the
>>> address of the GIC user-visible section now that we have access to its
>>> base address globally.
>>>
>>> Switch to calculating it ourselves, which will allow us to stop
>>> requiring the irqchip driver to care about a counter exposed to userland
>>> for use via the VDSO.
>>>
>>> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
>>> Cc: Jason Cooper <jason@lakedaemon.net>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: linux-mips@linux-mips.org
>>> ---
>>>
>>>  arch/mips/kernel/vdso.c | 15 +++++----------
>>>  1 file changed, 5 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
>>> index 093517e85a6c..019035d7225c 100644
>>> --- a/arch/mips/kernel/vdso.c
>>> +++ b/arch/mips/kernel/vdso.c
>>> @@ -13,13 +13,13 @@
>>>
>>>  #include <linux/err.h>
>>>  #include <linux/init.h>
>>>  #include <linux/ioport.h>
>>>
>>> -#include <linux/irqchip/mips-gic.h>
>>>
>>>  #include <linux/mm.h>
>>>  #include <linux/sched.h>
>>>  #include <linux/slab.h>
>>>  #include <linux/timekeeper_internal.h>
>>>  
>>>  #include <asm/abi.h>
>>>
>>> +#include <asm/mips-cps.h>
>>>
>>>  #include <asm/vdso.h>
>>>  
>>>  /* Kernel-provided data used by the VDSO. */
>>>
>>> @@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm
>>> *bprm, int uses_interp)> 
>>>  {
>>>  
>>>  	struct mips_vdso_image *image = current->thread.abi->vdso;
>>>  	struct mm_struct *mm = current->mm;
>>>
>>> -	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
>>> +	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr,
>>> gic_pfn;> 
>>>  	struct vm_area_struct *vma;
>>>
>>> -	struct resource gic_res;
>>>
>>>  	int ret;
>>>  	
>>>  	if (down_write_killable(&mm->mmap_sem))
>>>
>>> @@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm
>>> *bprm, int uses_interp)> 
>>>  	 * only map a page even though the total area is 64K, as we only need
>>>  	 * the counter registers at the start.
>>>  	 */
>>>
>>> -	gic_size = gic_present ? PAGE_SIZE : 0;
>>> +	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
>>>
>>>  	vvar_size = gic_size + PAGE_SIZE;
>>>  	size = vvar_size + image->size;
>>>
>>> @@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm
>>> *bprm, int uses_interp)> 
>>>  	/* Map GIC user page. */
>>>  	if (gic_size) {
>>>
>>> -		ret = gic_get_usm_range(&gic_res);
>>> -		if (ret)
>>> -			goto out;
>>> +		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >>
>>> PAGE_SHIFT;
>>
>> virt_to_pfn() instead?
> 
> We don't seem to have virt_to_pfn() on MIPS, but I'd be happy to add it & tidy 
> up a few places that could use it. Would you mind if that cleanup came 
> separately though?

I don't mind either way. This is a fairly common shortcut, but no need
to introduce it (and add more dependencies) on this account.

Thanks,

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

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

* Re: [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  2017-08-18 15:37   ` Marc Zyngier
@ 2017-08-18 17:02     ` Paul Burton
  2017-08-18 17:02       ` Paul Burton
  2017-08-18 17:18       ` Marc Zyngier
  0 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 17:02 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Friday, 18 August 2017 08:37:03 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > Define the pcpu_masks variable using the kernel's standard per-cpu
> > variable support, rather than an open-coded array of structs containing
> > bitmaps.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  drivers/irqchip/irq-mips-gic.c | 17 ++++++++---------
> >  1 file changed, 8 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/irqchip/irq-mips-gic.c
> > b/drivers/irqchip/irq-mips-gic.c index feff4bf97577..00153231376a 100644
> > --- a/drivers/irqchip/irq-mips-gic.c
> > +++ b/drivers/irqchip/irq-mips-gic.c
> > @@ -13,6 +13,7 @@
> > 
> >  #include <linux/irq.h>
> >  #include <linux/irqchip.h>
> >  #include <linux/of_address.h>
> > 
> > +#include <linux/percpu.h>
> > 
> >  #include <linux/sched.h>
> >  #include <linux/smp.h>
> > 
> > @@ -23,6 +24,7 @@
> > 
> >  #include <dt-bindings/interrupt-controller/mips-gic.h>
> >  
> >  #define GIC_MAX_INTRS		256
> > 
> > +#define GIC_MAX_LONGS		BITS_TO_LONGS(GIC_MAX_INTRS)
> > 
> >  /* Add 2 to convert GIC CPU pin to core interrupt */
> >  #define GIC_CPU_PIN_OFFSET	2
> > 
> > @@ -40,11 +42,8 @@
> > 
> >  void __iomem *mips_gic_base;
> > 
> > -struct gic_pcpu_mask {
> > -	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
> > -};
> > +DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
> > 
> > -static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
> > 
> >  static DEFINE_SPINLOCK(gic_lock);
> >  static struct irq_domain *gic_irq_domain;
> >  static struct irq_domain *gic_ipi_domain;
> > 
> > @@ -137,7 +136,7 @@ static void gic_handle_shared_int(bool chained)
> > 
> >  	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
> >  	
> >  	/* Get per-cpu bitmaps */
> > 
> > -	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
> > +	pcpu_mask = this_cpu_ptr(pcpu_masks);
> > 
> >  	if (mips_cm_is64) {
> >  	
> >  		__ioread64_copy(pending, addr_gic_pend(),
> > 
> > @@ -254,8 +253,8 @@ static int gic_set_affinity(struct irq_data *d, const
> > struct cpumask *cpumask,> 
> >  	/* Update the pcpu_masks */
> >  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> 
> Is there any case where gic_vpes is not equal to nr_cpus?

Yes - if the kernel is built with CONFIG_NR_CPUS set to something other than 
the actual number of VPs (Virtual Processors, ie. hardware threads) in the 
system. (VPE, or Virtual Processing Element, is a roughly equivalent term used 
in older revisions of the MIPS architecture).

To be honest I suspect gic_vpes should go away, and for example in this case 
we should juse use for_each_possible_cpu(). The use of gic_vpes here was added 
by commit 2a0787051182 ("irqchip/mips-gic: Use gic_vpes instead of NR_CPUS") 
but it doesn't really do a good job of explaining why - I suspect Qais felt it 
was an optimisation, but that's debatable.

This code will need adjusting to add multi-cluster support, which is my 
ultimate goal here, anyway. So that'll be one of the next things for me to 
tackle.

Thanks,
    Paul

> 
> > -		clear_bit(irq, pcpu_masks[i].pcpu_mask);
> > -	set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);
> > +		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
> > +	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
> > 
> >  	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> > 
> > @@ -416,8 +415,8 @@ static int gic_shared_irq_domain_map(struct irq_domain
> > *d, unsigned int virq,> 
> >  	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
> >  	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
> >  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> > 
> > -		clear_bit(intr, pcpu_masks[i].pcpu_mask);
> > -	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
> > +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> > +	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
> > 
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> >  	
> >  	return 0;
> 
> Thanks,
> 
> 	M.


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  2017-08-18 17:02     ` Paul Burton
@ 2017-08-18 17:02       ` Paul Burton
  2017-08-18 17:18       ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 17:02 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Friday, 18 August 2017 08:37:03 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > Define the pcpu_masks variable using the kernel's standard per-cpu
> > variable support, rather than an open-coded array of structs containing
> > bitmaps.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  drivers/irqchip/irq-mips-gic.c | 17 ++++++++---------
> >  1 file changed, 8 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/irqchip/irq-mips-gic.c
> > b/drivers/irqchip/irq-mips-gic.c index feff4bf97577..00153231376a 100644
> > --- a/drivers/irqchip/irq-mips-gic.c
> > +++ b/drivers/irqchip/irq-mips-gic.c
> > @@ -13,6 +13,7 @@
> > 
> >  #include <linux/irq.h>
> >  #include <linux/irqchip.h>
> >  #include <linux/of_address.h>
> > 
> > +#include <linux/percpu.h>
> > 
> >  #include <linux/sched.h>
> >  #include <linux/smp.h>
> > 
> > @@ -23,6 +24,7 @@
> > 
> >  #include <dt-bindings/interrupt-controller/mips-gic.h>
> >  
> >  #define GIC_MAX_INTRS		256
> > 
> > +#define GIC_MAX_LONGS		BITS_TO_LONGS(GIC_MAX_INTRS)
> > 
> >  /* Add 2 to convert GIC CPU pin to core interrupt */
> >  #define GIC_CPU_PIN_OFFSET	2
> > 
> > @@ -40,11 +42,8 @@
> > 
> >  void __iomem *mips_gic_base;
> > 
> > -struct gic_pcpu_mask {
> > -	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
> > -};
> > +DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
> > 
> > -static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
> > 
> >  static DEFINE_SPINLOCK(gic_lock);
> >  static struct irq_domain *gic_irq_domain;
> >  static struct irq_domain *gic_ipi_domain;
> > 
> > @@ -137,7 +136,7 @@ static void gic_handle_shared_int(bool chained)
> > 
> >  	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
> >  	
> >  	/* Get per-cpu bitmaps */
> > 
> > -	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
> > +	pcpu_mask = this_cpu_ptr(pcpu_masks);
> > 
> >  	if (mips_cm_is64) {
> >  	
> >  		__ioread64_copy(pending, addr_gic_pend(),
> > 
> > @@ -254,8 +253,8 @@ static int gic_set_affinity(struct irq_data *d, const
> > struct cpumask *cpumask,> 
> >  	/* Update the pcpu_masks */
> >  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> 
> Is there any case where gic_vpes is not equal to nr_cpus?

Yes - if the kernel is built with CONFIG_NR_CPUS set to something other than 
the actual number of VPs (Virtual Processors, ie. hardware threads) in the 
system. (VPE, or Virtual Processing Element, is a roughly equivalent term used 
in older revisions of the MIPS architecture).

To be honest I suspect gic_vpes should go away, and for example in this case 
we should juse use for_each_possible_cpu(). The use of gic_vpes here was added 
by commit 2a0787051182 ("irqchip/mips-gic: Use gic_vpes instead of NR_CPUS") 
but it doesn't really do a good job of explaining why - I suspect Qais felt it 
was an optimisation, but that's debatable.

This code will need adjusting to add multi-cluster support, which is my 
ultimate goal here, anyway. So that'll be one of the next things for me to 
tackle.

Thanks,
    Paul

> 
> > -		clear_bit(irq, pcpu_masks[i].pcpu_mask);
> > -	set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);
> > +		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
> > +	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
> > 
> >  	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> > 
> > @@ -416,8 +415,8 @@ static int gic_shared_irq_domain_map(struct irq_domain
> > *d, unsigned int virq,> 
> >  	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
> >  	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
> >  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> > 
> > -		clear_bit(intr, pcpu_masks[i].pcpu_mask);
> > -	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
> > +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> > +	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
> > 
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> >  	
> >  	return 0;
> 
> Thanks,
> 
> 	M.


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-18 15:44   ` Marc Zyngier
@ 2017-08-18 17:11     ` Paul Burton
  2017-08-18 17:11       ` Paul Burton
  2017-08-18 17:25       ` Marc Zyngier
  0 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 17:11 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Friday, 18 August 2017 08:44:15 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > This patch avoids the need to read the GIC_SH_MASK* registers when
> > decoding shared interrupts by setting & clearing the interrupt's bit in
> > the appropriate CPU's pcpu_masks entry when masking or unmasking the
> > interrupt.
> > 
> > This effectively means that whilst an interrupt is masked we clear its
> > bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
> > on all CPUs without needing to check GIC_SH_MASK*.
> > 
> > In essence, we add a little overhead to masking or unmasking interrupts
> > but in return reduce the overhead of the far more common task of
> > decoding interrupts.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  drivers/irqchip/irq-mips-gic.c | 49
> >  ++++++++++++++++++++++++------------------ 1 file changed, 28
> >  insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/irqchip/irq-mips-gic.c
> > b/drivers/irqchip/irq-mips-gic.c index 00153231376a..7a42f0b3822f 100644
> > --- a/drivers/irqchip/irq-mips-gic.c
> > +++ b/drivers/irqchip/irq-mips-gic.c
> > @@ -55,6 +55,19 @@ static struct irq_chip gic_level_irq_controller,
> > gic_edge_irq_controller;> 
> >  DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
> >  DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
> > 
> > +static void gic_setup_pcpu_mask(unsigned int intr, unsigned int cpu)
> > +{
> > +	unsigned int i;
> > +
> > +	/* Clear the interrupt's bit in all pcpu_masks */
> > +	for_each_possible_cpu(i)
> > +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> 
> This iterates from 0 to nr_cpu_ids-1...
> 
> > +
> > +	/* Set the interrupt's bit in the appropriate CPU's mask */
> > +	if (cpu < NR_CPUS)
> 
> and here you're using NR_CPUS. I'm a bit worried that you're not quite
> using the same thing (nr_cpu_ids <= NR_CPUS).

I think that would be fine - if nr_cpu_ids is less than NR_CPUS then all we 
risk is leaving bits set in the mask for CPUs that aren't in cpu_possible_mask 
(which is where nr_cpu_ids comes from). Since those CPUs don't exist & thus 
can't take interrupts they'll never check the bits in their mask.

The NR_CPUS check here is basically just to allow the interrupt to be set in 
none of the masks when called by gic_mask_irq() - NR_CPUS is just some 
constant value that we know will never be the ID of a CPU that an interrupt's 
affinity is set to.

Perhaps it'd be clearer to instead split gic_setup_pcpu_mask() into 2 
functions - one to just clear all the masks, and one to set the interrupt's 
bit in the appropriate one? Possibly just inline that second one. That way we 
wouldn't be using NR_CPUS at all here which might be clearer. How does that 
sound?

Thanks,
    Paul

> 
> > +		set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
> > +}
> > +
> > 
> >  static bool gic_local_irq_is_routable(int intr)
> >  {
> >  
> >  	u32 vpe_ctl;
> > 
> > @@ -133,24 +146,17 @@ static void gic_handle_shared_int(bool chained)
> > 
> >  	unsigned int intr, virq;
> >  	unsigned long *pcpu_mask;
> >  	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
> > 
> > -	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
> > 
> >  	/* Get per-cpu bitmaps */
> >  	pcpu_mask = this_cpu_ptr(pcpu_masks);
> > 
> > -	if (mips_cm_is64) {
> > +	if (mips_cm_is64)
> > 
> >  		__ioread64_copy(pending, addr_gic_pend(),
> >  		
> >  				DIV_ROUND_UP(gic_shared_intrs, 64));
> > 
> > -		__ioread64_copy(intrmask, addr_gic_mask(),
> > -				DIV_ROUND_UP(gic_shared_intrs, 64));
> > -	} else {
> > +	else
> > 
> >  		__ioread32_copy(pending, addr_gic_pend(),
> >  		
> >  				DIV_ROUND_UP(gic_shared_intrs, 32));
> > 
> > -		__ioread32_copy(intrmask, addr_gic_mask(),
> > -				DIV_ROUND_UP(gic_shared_intrs, 32));
> > -	}
> > 
> > -	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
> > 
> >  	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
> >  	
> >  	for_each_set_bit(intr, pending, gic_shared_intrs) {
> > 
> > @@ -165,12 +171,19 @@ static void gic_handle_shared_int(bool chained)
> > 
> >  static void gic_mask_irq(struct irq_data *d)
> >  {
> > 
> > -	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
> > +	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
> > +
> > +	write_gic_rmask(BIT(intr));
> > +	gic_setup_pcpu_mask(intr, NR_CPUS);
> > 
> >  }
> >  
> >  static void gic_unmask_irq(struct irq_data *d)
> >  {
> > 
> > -	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
> > +	struct cpumask *affinity = irq_data_get_affinity_mask(d);
> > +	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
> > +
> > +	write_gic_smask(BIT(intr));
> > +	gic_setup_pcpu_mask(intr, cpumask_first_and(affinity, 
cpu_online_mask));
> > 
> >  }
> >  
> >  static void gic_ack_irq(struct irq_data *d)
> > 
> > @@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const
> > struct cpumask *cpumask,> 
> >  	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
> >  	cpumask_t	tmp = CPU_MASK_NONE;
> >  	unsigned long	flags;
> > 
> > -	int		i;
> > 
> >  	cpumask_and(&tmp, cpumask, cpu_online_mask);
> >  	if (cpumask_empty(&tmp))
> > 
> > @@ -252,9 +264,7 @@ static int gic_set_affinity(struct irq_data *d, const
> > struct cpumask *cpumask,> 
> >  	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
> >  	
> >  	/* Update the pcpu_masks */
> > 
> > -	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> > -		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
> > -	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
> > +	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) :
> > NR_CPUS);> 
> >  	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> > 
> > @@ -405,18 +415,15 @@ static int gic_local_irq_domain_map(struct
> > irq_domain *d, unsigned int virq,> 
> >  }
> >  
> >  static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int
> >  virq,> 
> > -				     irq_hw_number_t hw, unsigned int vpe)
> > +				     irq_hw_number_t hw, unsigned int cpu)
> > 
> >  {
> >  
> >  	int intr = GIC_HWIRQ_TO_SHARED(hw);
> >  	unsigned long flags;
> > 
> > -	int i;
> > 
> >  	spin_lock_irqsave(&gic_lock, flags);
> >  	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
> > 
> > -	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
> > -	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> > -		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> > -	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
> > +	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
> > +	gic_setup_pcpu_mask(intr, cpu);
> > 
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> >  	
> >  	return 0;
> 
> Thanks,
> 
> 	M.


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-18 17:11     ` Paul Burton
@ 2017-08-18 17:11       ` Paul Burton
  2017-08-18 17:25       ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 17:11 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

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

Hi Marc,

On Friday, 18 August 2017 08:44:15 PDT Marc Zyngier wrote:
> On 13/08/17 05:36, Paul Burton wrote:
> > This patch avoids the need to read the GIC_SH_MASK* registers when
> > decoding shared interrupts by setting & clearing the interrupt's bit in
> > the appropriate CPU's pcpu_masks entry when masking or unmasking the
> > interrupt.
> > 
> > This effectively means that whilst an interrupt is masked we clear its
> > bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
> > on all CPUs without needing to check GIC_SH_MASK*.
> > 
> > In essence, we add a little overhead to masking or unmasking interrupts
> > but in return reduce the overhead of the far more common task of
> > decoding interrupts.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  drivers/irqchip/irq-mips-gic.c | 49
> >  ++++++++++++++++++++++++------------------ 1 file changed, 28
> >  insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/irqchip/irq-mips-gic.c
> > b/drivers/irqchip/irq-mips-gic.c index 00153231376a..7a42f0b3822f 100644
> > --- a/drivers/irqchip/irq-mips-gic.c
> > +++ b/drivers/irqchip/irq-mips-gic.c
> > @@ -55,6 +55,19 @@ static struct irq_chip gic_level_irq_controller,
> > gic_edge_irq_controller;> 
> >  DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
> >  DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
> > 
> > +static void gic_setup_pcpu_mask(unsigned int intr, unsigned int cpu)
> > +{
> > +	unsigned int i;
> > +
> > +	/* Clear the interrupt's bit in all pcpu_masks */
> > +	for_each_possible_cpu(i)
> > +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> 
> This iterates from 0 to nr_cpu_ids-1...
> 
> > +
> > +	/* Set the interrupt's bit in the appropriate CPU's mask */
> > +	if (cpu < NR_CPUS)
> 
> and here you're using NR_CPUS. I'm a bit worried that you're not quite
> using the same thing (nr_cpu_ids <= NR_CPUS).

I think that would be fine - if nr_cpu_ids is less than NR_CPUS then all we 
risk is leaving bits set in the mask for CPUs that aren't in cpu_possible_mask 
(which is where nr_cpu_ids comes from). Since those CPUs don't exist & thus 
can't take interrupts they'll never check the bits in their mask.

The NR_CPUS check here is basically just to allow the interrupt to be set in 
none of the masks when called by gic_mask_irq() - NR_CPUS is just some 
constant value that we know will never be the ID of a CPU that an interrupt's 
affinity is set to.

Perhaps it'd be clearer to instead split gic_setup_pcpu_mask() into 2 
functions - one to just clear all the masks, and one to set the interrupt's 
bit in the appropriate one? Possibly just inline that second one. That way we 
wouldn't be using NR_CPUS at all here which might be clearer. How does that 
sound?

Thanks,
    Paul

> 
> > +		set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
> > +}
> > +
> > 
> >  static bool gic_local_irq_is_routable(int intr)
> >  {
> >  
> >  	u32 vpe_ctl;
> > 
> > @@ -133,24 +146,17 @@ static void gic_handle_shared_int(bool chained)
> > 
> >  	unsigned int intr, virq;
> >  	unsigned long *pcpu_mask;
> >  	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
> > 
> > -	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
> > 
> >  	/* Get per-cpu bitmaps */
> >  	pcpu_mask = this_cpu_ptr(pcpu_masks);
> > 
> > -	if (mips_cm_is64) {
> > +	if (mips_cm_is64)
> > 
> >  		__ioread64_copy(pending, addr_gic_pend(),
> >  		
> >  				DIV_ROUND_UP(gic_shared_intrs, 64));
> > 
> > -		__ioread64_copy(intrmask, addr_gic_mask(),
> > -				DIV_ROUND_UP(gic_shared_intrs, 64));
> > -	} else {
> > +	else
> > 
> >  		__ioread32_copy(pending, addr_gic_pend(),
> >  		
> >  				DIV_ROUND_UP(gic_shared_intrs, 32));
> > 
> > -		__ioread32_copy(intrmask, addr_gic_mask(),
> > -				DIV_ROUND_UP(gic_shared_intrs, 32));
> > -	}
> > 
> > -	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
> > 
> >  	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
> >  	
> >  	for_each_set_bit(intr, pending, gic_shared_intrs) {
> > 
> > @@ -165,12 +171,19 @@ static void gic_handle_shared_int(bool chained)
> > 
> >  static void gic_mask_irq(struct irq_data *d)
> >  {
> > 
> > -	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
> > +	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
> > +
> > +	write_gic_rmask(BIT(intr));
> > +	gic_setup_pcpu_mask(intr, NR_CPUS);
> > 
> >  }
> >  
> >  static void gic_unmask_irq(struct irq_data *d)
> >  {
> > 
> > -	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
> > +	struct cpumask *affinity = irq_data_get_affinity_mask(d);
> > +	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
> > +
> > +	write_gic_smask(BIT(intr));
> > +	gic_setup_pcpu_mask(intr, cpumask_first_and(affinity, 
cpu_online_mask));
> > 
> >  }
> >  
> >  static void gic_ack_irq(struct irq_data *d)
> > 
> > @@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const
> > struct cpumask *cpumask,> 
> >  	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
> >  	cpumask_t	tmp = CPU_MASK_NONE;
> >  	unsigned long	flags;
> > 
> > -	int		i;
> > 
> >  	cpumask_and(&tmp, cpumask, cpu_online_mask);
> >  	if (cpumask_empty(&tmp))
> > 
> > @@ -252,9 +264,7 @@ static int gic_set_affinity(struct irq_data *d, const
> > struct cpumask *cpumask,> 
> >  	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
> >  	
> >  	/* Update the pcpu_masks */
> > 
> > -	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> > -		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
> > -	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
> > +	gic_setup_pcpu_mask(irq, read_gic_mask(irq) ? cpumask_first(&tmp) :
> > NR_CPUS);> 
> >  	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> > 
> > @@ -405,18 +415,15 @@ static int gic_local_irq_domain_map(struct
> > irq_domain *d, unsigned int virq,> 
> >  }
> >  
> >  static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int
> >  virq,> 
> > -				     irq_hw_number_t hw, unsigned int vpe)
> > +				     irq_hw_number_t hw, unsigned int cpu)
> > 
> >  {
> >  
> >  	int intr = GIC_HWIRQ_TO_SHARED(hw);
> >  	unsigned long flags;
> > 
> > -	int i;
> > 
> >  	spin_lock_irqsave(&gic_lock, flags);
> >  	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
> > 
> > -	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
> > -	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
> > -		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
> > -	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
> > +	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
> > +	gic_setup_pcpu_mask(intr, cpu);
> > 
> >  	spin_unlock_irqrestore(&gic_lock, flags);
> >  	
> >  	return 0;
> 
> Thanks,
> 
> 	M.


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable
  2017-08-18 17:02     ` Paul Burton
  2017-08-18 17:02       ` Paul Burton
@ 2017-08-18 17:18       ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 17:18 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

On 18/08/17 18:02, Paul Burton wrote:
> Hi Marc,
> 
> On Friday, 18 August 2017 08:37:03 PDT Marc Zyngier wrote:
>> On 13/08/17 05:36, Paul Burton wrote:
>>> Define the pcpu_masks variable using the kernel's standard per-cpu
>>> variable support, rather than an open-coded array of structs containing
>>> bitmaps.
>>>
>>> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
>>> Cc: Jason Cooper <jason@lakedaemon.net>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: linux-mips@linux-mips.org
>>> ---
>>>
>>>  drivers/irqchip/irq-mips-gic.c | 17 ++++++++---------
>>>  1 file changed, 8 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mips-gic.c
>>> b/drivers/irqchip/irq-mips-gic.c index feff4bf97577..00153231376a 100644
>>> --- a/drivers/irqchip/irq-mips-gic.c
>>> +++ b/drivers/irqchip/irq-mips-gic.c
>>> @@ -13,6 +13,7 @@
>>>
>>>  #include <linux/irq.h>
>>>  #include <linux/irqchip.h>
>>>  #include <linux/of_address.h>
>>>
>>> +#include <linux/percpu.h>
>>>
>>>  #include <linux/sched.h>
>>>  #include <linux/smp.h>
>>>
>>> @@ -23,6 +24,7 @@
>>>
>>>  #include <dt-bindings/interrupt-controller/mips-gic.h>
>>>  
>>>  #define GIC_MAX_INTRS		256
>>>
>>> +#define GIC_MAX_LONGS		BITS_TO_LONGS(GIC_MAX_INTRS)
>>>
>>>  /* Add 2 to convert GIC CPU pin to core interrupt */
>>>  #define GIC_CPU_PIN_OFFSET	2
>>>
>>> @@ -40,11 +42,8 @@
>>>
>>>  void __iomem *mips_gic_base;
>>>
>>> -struct gic_pcpu_mask {
>>> -	DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
>>> -};
>>> +DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
>>>
>>> -static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
>>>
>>>  static DEFINE_SPINLOCK(gic_lock);
>>>  static struct irq_domain *gic_irq_domain;
>>>  static struct irq_domain *gic_ipi_domain;
>>>
>>> @@ -137,7 +136,7 @@ static void gic_handle_shared_int(bool chained)
>>>
>>>  	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
>>>  	
>>>  	/* Get per-cpu bitmaps */
>>>
>>> -	pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
>>> +	pcpu_mask = this_cpu_ptr(pcpu_masks);
>>>
>>>  	if (mips_cm_is64) {
>>>  	
>>>  		__ioread64_copy(pending, addr_gic_pend(),
>>>
>>> @@ -254,8 +253,8 @@ static int gic_set_affinity(struct irq_data *d, const
>>> struct cpumask *cpumask,> 
>>>  	/* Update the pcpu_masks */
>>>  	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
>>
>> Is there any case where gic_vpes is not equal to nr_cpus?
> 
> Yes - if the kernel is built with CONFIG_NR_CPUS set to something other than 
> the actual number of VPs (Virtual Processors, ie. hardware threads) in the 
> system. (VPE, or Virtual Processing Element, is a roughly equivalent term used 
> in older revisions of the MIPS architecture).
> 
> To be honest I suspect gic_vpes should go away, and for example in this case 
> we should juse use for_each_possible_cpu(). 

That's exactly where I was implicitly aiming to. Either NR_CPUS is set
to something bigger than the physical number of CPU/threads, and
nr_cpus_ids is then the right thing, or NR_CPUS is smaller than that
number, and nr_cpu_ids == NR_CPUS.

So for_each_possible_cpus should always do the right thing.

> The use of gic_vpes here was added 
> by commit 2a0787051182 ("irqchip/mips-gic: Use gic_vpes instead of NR_CPUS") 
> but it doesn't really do a good job of explaining why - I suspect Qais felt it 
> was an optimisation, but that's debatable.

Quite.

> This code will need adjusting to add multi-cluster support, which is my 
> ultimate goal here, anyway. So that'll be one of the next things for me to 
> tackle.
Sounds good to me.

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

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

* Re: [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-18 17:11     ` Paul Burton
  2017-08-18 17:11       ` Paul Burton
@ 2017-08-18 17:25       ` Marc Zyngier
  2017-08-18 21:02         ` [PATCH v2 " Paul Burton
  1 sibling, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 17:25 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Jason Cooper, Thomas Gleixner, Ralf Baechle

On 18/08/17 18:11, Paul Burton wrote:
> Hi Marc,
> 
> On Friday, 18 August 2017 08:44:15 PDT Marc Zyngier wrote:
>> On 13/08/17 05:36, Paul Burton wrote:
>>> This patch avoids the need to read the GIC_SH_MASK* registers when
>>> decoding shared interrupts by setting & clearing the interrupt's bit in
>>> the appropriate CPU's pcpu_masks entry when masking or unmasking the
>>> interrupt.
>>>
>>> This effectively means that whilst an interrupt is masked we clear its
>>> bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
>>> on all CPUs without needing to check GIC_SH_MASK*.
>>>
>>> In essence, we add a little overhead to masking or unmasking interrupts
>>> but in return reduce the overhead of the far more common task of
>>> decoding interrupts.
>>>
>>> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
>>> Cc: Jason Cooper <jason@lakedaemon.net>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: linux-mips@linux-mips.org
>>> ---
>>>
>>>  drivers/irqchip/irq-mips-gic.c | 49
>>>  ++++++++++++++++++++++++------------------ 1 file changed, 28
>>>  insertions(+), 21 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mips-gic.c
>>> b/drivers/irqchip/irq-mips-gic.c index 00153231376a..7a42f0b3822f 100644
>>> --- a/drivers/irqchip/irq-mips-gic.c
>>> +++ b/drivers/irqchip/irq-mips-gic.c
>>> @@ -55,6 +55,19 @@ static struct irq_chip gic_level_irq_controller,
>>> gic_edge_irq_controller;> 
>>>  DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
>>>  DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
>>>
>>> +static void gic_setup_pcpu_mask(unsigned int intr, unsigned int cpu)
>>> +{
>>> +	unsigned int i;
>>> +
>>> +	/* Clear the interrupt's bit in all pcpu_masks */
>>> +	for_each_possible_cpu(i)
>>> +		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
>>
>> This iterates from 0 to nr_cpu_ids-1...
>>
>>> +
>>> +	/* Set the interrupt's bit in the appropriate CPU's mask */
>>> +	if (cpu < NR_CPUS)
>>
>> and here you're using NR_CPUS. I'm a bit worried that you're not quite
>> using the same thing (nr_cpu_ids <= NR_CPUS).
> 
> I think that would be fine - if nr_cpu_ids is less than NR_CPUS then all we 
> risk is leaving bits set in the mask for CPUs that aren't in cpu_possible_mask 
> (which is where nr_cpu_ids comes from). Since those CPUs don't exist & thus 
> can't take interrupts they'll never check the bits in their mask.
> 
> The NR_CPUS check here is basically just to allow the interrupt to be set in 
> none of the masks when called by gic_mask_irq() - NR_CPUS is just some 
> constant value that we know will never be the ID of a CPU that an interrupt's 
> affinity is set to.
> 
> Perhaps it'd be clearer to instead split gic_setup_pcpu_mask() into 2 
> functions - one to just clear all the masks, and one to set the interrupt's 
> bit in the appropriate one? Possibly just inline that second one. That way we 
> wouldn't be using NR_CPUS at all here which might be clearer. How does that 
> sound?

That'd probably be best, even if that's a couple extra lines here and
there. This NR_CPUS is just confusing.

Thanks,

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

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
                   ` (39 preceding siblings ...)
  2017-08-15 10:13 ` [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Marc Zyngier
@ 2017-08-18 17:28 ` Marc Zyngier
  2017-08-18 17:44   ` Paul Burton
  40 siblings, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 17:28 UTC (permalink / raw)
  To: Paul Burton, linux-mips, Jason Cooper, Thomas Gleixner; +Cc: Ralf Baechle

Hi Paul,

On 13/08/17 05:36, Paul Burton wrote:
> This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> somewhat. It moves us towards using a header in a similar vein to the
> ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> Controller (CPC) which allows us to access the GIC outside of the
> irqchip driver - something beneficial already for the clocksource &
> clock event driver, and which will be beneficial for further drivers
> (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> this header is also beneficial for consistency & code-sharing.
> 
> In addition to cleanups the series also optimises the driver in various
> ways, including by using a per-CPU variable for pcpu_masks & removing
> the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> gic_handle_shared_int().
> 
> This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> support" series to be applied first.
I went through the whole series, and didn't spot anything bad (the
couple of nits I raised can either be fixed at a later time or as a
fixup on top of what you have).

Given that this has a number of dependencies (your multicluster series),
how do you want to get this merged?

Thanks,

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

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-18 17:28 ` Marc Zyngier
@ 2017-08-18 17:44   ` Paul Burton
  2017-08-18 17:44     ` Paul Burton
  2017-08-18 17:49     ` Marc Zyngier
  0 siblings, 2 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 17:44 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Ralf Baechle; +Cc: linux-mips, Jason Cooper

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

Hi Marc,

On Friday, 18 August 2017 10:28:01 PDT Marc Zyngier wrote:
> Hi Paul,
> 
> On 13/08/17 05:36, Paul Burton wrote:
> > This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> > somewhat. It moves us towards using a header in a similar vein to the
> > ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> > Controller (CPC) which allows us to access the GIC outside of the
> > irqchip driver - something beneficial already for the clocksource &
> > clock event driver, and which will be beneficial for further drivers
> > (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> > this header is also beneficial for consistency & code-sharing.
> > 
> > In addition to cleanups the series also optimises the driver in various
> > ways, including by using a per-CPU variable for pcpu_masks & removing
> > the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> > gic_handle_shared_int().
> > 
> > This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> > support" series to be applied first.
> 
> I went through the whole series, and didn't spot anything bad (the
> couple of nits I raised can either be fixed at a later time or as a
> fixup on top of what you have).

Thanks :) I appreciate your review. So shall I take that as you'd prefer that 
I submit separate fixup patches rather than submit a v2?

> Given that this has a number of dependencies (your multicluster series),
> how do you want to get this merged?
> 
> Thanks,
> 
> 	M.

Ralf mentioned in a meeting yesterday that he was going to speak to Thomas 
about that, and suggested that perhaps it'd be easiest for him to take it 
through the MIPS tree. I'm happy either way.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-18 17:44   ` Paul Burton
@ 2017-08-18 17:44     ` Paul Burton
  2017-08-18 17:49     ` Marc Zyngier
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 17:44 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Ralf Baechle; +Cc: linux-mips, Jason Cooper

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

Hi Marc,

On Friday, 18 August 2017 10:28:01 PDT Marc Zyngier wrote:
> Hi Paul,
> 
> On 13/08/17 05:36, Paul Burton wrote:
> > This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> > somewhat. It moves us towards using a header in a similar vein to the
> > ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> > Controller (CPC) which allows us to access the GIC outside of the
> > irqchip driver - something beneficial already for the clocksource &
> > clock event driver, and which will be beneficial for further drivers
> > (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> > this header is also beneficial for consistency & code-sharing.
> > 
> > In addition to cleanups the series also optimises the driver in various
> > ways, including by using a per-CPU variable for pcpu_masks & removing
> > the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> > gic_handle_shared_int().
> > 
> > This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> > support" series to be applied first.
> 
> I went through the whole series, and didn't spot anything bad (the
> couple of nits I raised can either be fixed at a later time or as a
> fixup on top of what you have).

Thanks :) I appreciate your review. So shall I take that as you'd prefer that 
I submit separate fixup patches rather than submit a v2?

> Given that this has a number of dependencies (your multicluster series),
> how do you want to get this merged?
> 
> Thanks,
> 
> 	M.

Ralf mentioned in a meeting yesterday that he was going to speak to Thomas 
about that, and suggested that perhaps it'd be easiest for him to take it 
through the MIPS tree. I'm happy either way.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-18 17:44   ` Paul Burton
  2017-08-18 17:44     ` Paul Burton
@ 2017-08-18 17:49     ` Marc Zyngier
  2017-08-18 21:09       ` Paul Burton
  1 sibling, 1 reply; 111+ messages in thread
From: Marc Zyngier @ 2017-08-18 17:49 UTC (permalink / raw)
  To: Paul Burton, Thomas Gleixner, Ralf Baechle; +Cc: linux-mips, Jason Cooper

On 18/08/17 18:44, Paul Burton wrote:
> Hi Marc,
> 
> On Friday, 18 August 2017 10:28:01 PDT Marc Zyngier wrote:
>> Hi Paul,
>>
>> On 13/08/17 05:36, Paul Burton wrote:
>>> This series cleans up the MIPS Global Interrupt Controller (GIC) driver
>>> somewhat. It moves us towards using a header in a similar vein to the
>>> ones we have for the MIPS Coherence Manager (CM) & Cluster Power
>>> Controller (CPC) which allows us to access the GIC outside of the
>>> irqchip driver - something beneficial already for the clocksource &
>>> clock event driver, and which will be beneficial for further drivers
>>> (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
>>> this header is also beneficial for consistency & code-sharing.
>>>
>>> In addition to cleanups the series also optimises the driver in various
>>> ways, including by using a per-CPU variable for pcpu_masks & removing
>>> the need to read the GIC_SH_MASK_* registers when decoding interrupts in
>>> gic_handle_shared_int().
>>>
>>> This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
>>> support" series to be applied first.
>>
>> I went through the whole series, and didn't spot anything bad (the
>> couple of nits I raised can either be fixed at a later time or as a
>> fixup on top of what you have).
> 
> Thanks :) I appreciate your review. So shall I take that as you'd prefer that 
> I submit separate fixup patches rather than submit a v2?

Just post the fixups on top. Nobody wants a new 38 series in their
Inbox! ;-)

>> Given that this has a number of dependencies (your multicluster series),
>> how do you want to get this merged?
>>
>> Thanks,
>>
>> 	M.
> 
> Ralf mentioned in a meeting yesterday that he was going to speak to Thomas 
> about that, and suggested that perhaps it'd be easiest for him to take it 
> through the MIPS tree. I'm happy either way.
Works for me. In that case, please stick my:

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

on these patches.

Thanks,

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

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

* [PATCH v2 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-18 17:25       ` Marc Zyngier
@ 2017-08-18 21:02         ` Paul Burton
  2017-08-18 21:02           ` Paul Burton
  0 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-18 21:02 UTC (permalink / raw)
  To: Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Paul Burton, Ralf Baechle, linux-mips

This patch avoids the need to read the GIC_SH_MASK* registers when
decoding shared interrupts by setting & clearing the interrupt's bit in
the appropriate CPU's pcpu_masks entry when masking or unmasking the
interrupt.

This effectively means that whilst an interrupt is masked we clear its
bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
on all CPUs without needing to check GIC_SH_MASK*.

In essence, we add a little overhead to masking or unmasking interrupts
but in return reduce the overhead of the far more common task of
decoding interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org

---

Changes in v2:
- Split pcpu_masks bit setting out of gic_setup_pcpu_masks() & rename to
  gic_clear_pcpu_masks(), avoiding confusing use of NR_CPUS.

 drivers/irqchip/irq-mips-gic.c | 52 +++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 00153231376a..e2ab0cee9ff2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -55,6 +55,15 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
 DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
+static void gic_clear_pcpu_masks(unsigned int intr)
+{
+	unsigned int i;
+
+	/* Clear the interrupt's bit in all pcpu_masks */
+	for_each_possible_cpu(i)
+		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
+}
+
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -133,24 +142,17 @@ static void gic_handle_shared_int(bool chained)
 	unsigned int intr, virq;
 	unsigned long *pcpu_mask;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
-	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
 	pcpu_mask = this_cpu_ptr(pcpu_masks);
 
-	if (mips_cm_is64) {
+	if (mips_cm_is64)
 		__ioread64_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 64));
-		__ioread64_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 64));
-	} else {
+	else
 		__ioread32_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 32));
-		__ioread32_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 32));
-	}
 
-	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
 	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
 
 	for_each_set_bit(intr, pending, gic_shared_intrs) {
@@ -165,12 +167,23 @@ static void gic_handle_shared_int(bool chained)
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+
+	write_gic_rmask(BIT(intr));
+	gic_clear_pcpu_masks(intr);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	struct cpumask *affinity = irq_data_get_affinity_mask(d);
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+	unsigned int cpu;
+
+	write_gic_smask(BIT(intr));
+
+	gic_clear_pcpu_masks(intr);
+	cpu = cpumask_first_and(affinity, cpu_online_mask);
+	set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
 }
 
 static void gic_ack_irq(struct irq_data *d)
@@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
-	int		i;
 
 	cpumask_and(&tmp, cpumask, cpu_online_mask);
 	if (cpumask_empty(&tmp))
@@ -252,9 +264,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
 
 	/* Update the pcpu_masks */
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
-	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
+	gic_clear_pcpu_masks(irq);
+	if (read_gic_mask(irq))
+		set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -405,18 +417,16 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 }
 
 static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
-				     irq_hw_number_t hw, unsigned int vpe)
+				     irq_hw_number_t hw, unsigned int cpu)
 {
 	int intr = GIC_HWIRQ_TO_SHARED(hw);
 	unsigned long flags;
-	int i;
 
 	spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
-	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
-	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
+	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
+	gic_clear_pcpu_masks(intr);
+	set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
-- 
2.14.1

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

* [PATCH v2 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*
  2017-08-18 21:02         ` [PATCH v2 " Paul Burton
@ 2017-08-18 21:02           ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 21:02 UTC (permalink / raw)
  To: Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Paul Burton, Ralf Baechle, linux-mips

This patch avoids the need to read the GIC_SH_MASK* registers when
decoding shared interrupts by setting & clearing the interrupt's bit in
the appropriate CPU's pcpu_masks entry when masking or unmasking the
interrupt.

This effectively means that whilst an interrupt is masked we clear its
bit in all pcpu_masks, which causes gic_handle_shared_int() to ignore it
on all CPUs without needing to check GIC_SH_MASK*.

In essence, we add a little overhead to masking or unmasking interrupts
but in return reduce the overhead of the far more common task of
decoding interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org

---

Changes in v2:
- Split pcpu_masks bit setting out of gic_setup_pcpu_masks() & rename to
  gic_clear_pcpu_masks(), avoiding confusing use of NR_CPUS.

 drivers/irqchip/irq-mips-gic.c | 52 +++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 00153231376a..e2ab0cee9ff2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -55,6 +55,15 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
 DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
 DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
 
+static void gic_clear_pcpu_masks(unsigned int intr)
+{
+	unsigned int i;
+
+	/* Clear the interrupt's bit in all pcpu_masks */
+	for_each_possible_cpu(i)
+		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
+}
+
 static bool gic_local_irq_is_routable(int intr)
 {
 	u32 vpe_ctl;
@@ -133,24 +142,17 @@ static void gic_handle_shared_int(bool chained)
 	unsigned int intr, virq;
 	unsigned long *pcpu_mask;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
-	DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
 
 	/* Get per-cpu bitmaps */
 	pcpu_mask = this_cpu_ptr(pcpu_masks);
 
-	if (mips_cm_is64) {
+	if (mips_cm_is64)
 		__ioread64_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 64));
-		__ioread64_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 64));
-	} else {
+	else
 		__ioread32_copy(pending, addr_gic_pend(),
 				DIV_ROUND_UP(gic_shared_intrs, 32));
-		__ioread32_copy(intrmask, addr_gic_mask(),
-				DIV_ROUND_UP(gic_shared_intrs, 32));
-	}
 
-	bitmap_and(pending, pending, intrmask, gic_shared_intrs);
 	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
 
 	for_each_set_bit(intr, pending, gic_shared_intrs) {
@@ -165,12 +167,23 @@ static void gic_handle_shared_int(bool chained)
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	write_gic_rmask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+
+	write_gic_rmask(BIT(intr));
+	gic_clear_pcpu_masks(intr);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	write_gic_smask(BIT(GIC_HWIRQ_TO_SHARED(d->hwirq)));
+	struct cpumask *affinity = irq_data_get_affinity_mask(d);
+	unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
+	unsigned int cpu;
+
+	write_gic_smask(BIT(intr));
+
+	gic_clear_pcpu_masks(intr);
+	cpu = cpumask_first_and(affinity, cpu_online_mask);
+	set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
 }
 
 static void gic_ack_irq(struct irq_data *d)
@@ -239,7 +252,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
-	int		i;
 
 	cpumask_and(&tmp, cpumask, cpu_online_mask);
 	if (cpumask_empty(&tmp))
@@ -252,9 +264,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
 
 	/* Update the pcpu_masks */
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(irq, per_cpu_ptr(pcpu_masks, i));
-	set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
+	gic_clear_pcpu_masks(irq);
+	if (read_gic_mask(irq))
+		set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
@@ -405,18 +417,16 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
 }
 
 static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
-				     irq_hw_number_t hw, unsigned int vpe)
+				     irq_hw_number_t hw, unsigned int cpu)
 {
 	int intr = GIC_HWIRQ_TO_SHARED(hw);
 	unsigned long flags;
-	int i;
 
 	spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
-	write_gic_map_vp(intr, BIT(mips_cm_vp_id(vpe)));
-	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
-		clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
-	set_bit(intr, per_cpu_ptr(pcpu_masks, vpe));
+	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
+	gic_clear_pcpu_masks(intr);
+	set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
-- 
2.14.1

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

* [PATCH v2 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-13  4:36 ` [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity() Paul Burton
  2017-08-13  4:36   ` Paul Burton
  2017-08-13  9:08   ` Sergei Shtylyov
@ 2017-08-18 21:04   ` Paul Burton
  2017-08-18 21:04     ` Paul Burton
  2 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-18 21:04 UTC (permalink / raw)
  To: Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Paul Burton, Ralf Baechle, linux-mips

Currently in gic_set_affinity() we calculate a temporary cpumask holding
the intersection of the provided cpumask & the CPUs that are online,
then we call cpumask_first twice on it to find the first such CPU. Since
we don't need the temporary cpumask for anything else & we only care
about the first CPU that's both online & in the provided cpumask, we can
instead use cpumask_first_and to find that CPU & drop the temporary
mask.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org

---

Changes in v2:
- Rebase atop changes to patch 35 "irqchip: mips-gic: Use pcpu_masks to
  avoid reading GIC_SH_MASK*".
- Fixup typo in commit message (s/to/the/).

 drivers/irqchip/irq-mips-gic.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 183c225b84de..8f64ac824d20 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -250,23 +250,23 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 			    bool force)
 {
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
-	cpumask_t	tmp = CPU_MASK_NONE;
-	unsigned long	flags;
+	unsigned long flags;
+	unsigned int cpu;
 
-	cpumask_and(&tmp, cpumask, cpu_online_mask);
-	if (cpumask_empty(&tmp))
+	cpu = cpumask_first_and(cpumask, cpu_online_mask);
+	if (cpu >= NR_CPUS)
 		return -EINVAL;
 
 	/* Assumption : cpumask refers to a single CPU */
 	spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
-	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
+	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
 
 	/* Update the pcpu_masks */
 	gic_clear_pcpu_masks(irq);
 	if (read_gic_mask(irq))
-		set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
+		set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
-- 
2.14.1

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

* [PATCH v2 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity()
  2017-08-18 21:04   ` [PATCH v2 " Paul Burton
@ 2017-08-18 21:04     ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 21:04 UTC (permalink / raw)
  To: Jason Cooper, Marc Zyngier, Thomas Gleixner
  Cc: Paul Burton, Ralf Baechle, linux-mips

Currently in gic_set_affinity() we calculate a temporary cpumask holding
the intersection of the provided cpumask & the CPUs that are online,
then we call cpumask_first twice on it to find the first such CPU. Since
we don't need the temporary cpumask for anything else & we only care
about the first CPU that's both online & in the provided cpumask, we can
instead use cpumask_first_and to find that CPU & drop the temporary
mask.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org

---

Changes in v2:
- Rebase atop changes to patch 35 "irqchip: mips-gic: Use pcpu_masks to
  avoid reading GIC_SH_MASK*".
- Fixup typo in commit message (s/to/the/).

 drivers/irqchip/irq-mips-gic.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 183c225b84de..8f64ac824d20 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -250,23 +250,23 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 			    bool force)
 {
 	unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
-	cpumask_t	tmp = CPU_MASK_NONE;
-	unsigned long	flags;
+	unsigned long flags;
+	unsigned int cpu;
 
-	cpumask_and(&tmp, cpumask, cpu_online_mask);
-	if (cpumask_empty(&tmp))
+	cpu = cpumask_first_and(cpumask, cpu_online_mask);
+	if (cpu >= NR_CPUS)
 		return -EINVAL;
 
 	/* Assumption : cpumask refers to a single CPU */
 	spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
-	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpumask_first(&tmp))));
+	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
 
 	/* Update the pcpu_masks */
 	gic_clear_pcpu_masks(irq);
 	if (read_gic_mask(irq))
-		set_bit(irq, per_cpu_ptr(pcpu_masks, cpumask_first(&tmp)));
+		set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
 
 	cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
-- 
2.14.1

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-18 17:49     ` Marc Zyngier
@ 2017-08-18 21:09       ` Paul Burton
  2017-08-18 21:09         ` Paul Burton
  0 siblings, 1 reply; 111+ messages in thread
From: Paul Burton @ 2017-08-18 21:09 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: Thomas Gleixner, Ralf Baechle, linux-mips, Jason Cooper

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

Hi Marc,

On Friday, 18 August 2017 10:49:27 PDT Marc Zyngier wrote:
> On 18/08/17 18:44, Paul Burton wrote:
> > Hi Marc,
> > 
> > On Friday, 18 August 2017 10:28:01 PDT Marc Zyngier wrote:
> >> Hi Paul,
> >> 
> >> On 13/08/17 05:36, Paul Burton wrote:
> >>> This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> >>> somewhat. It moves us towards using a header in a similar vein to the
> >>> ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> >>> Controller (CPC) which allows us to access the GIC outside of the
> >>> irqchip driver - something beneficial already for the clocksource &
> >>> clock event driver, and which will be beneficial for further drivers
> >>> (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> >>> this header is also beneficial for consistency & code-sharing.
> >>> 
> >>> In addition to cleanups the series also optimises the driver in various
> >>> ways, including by using a per-CPU variable for pcpu_masks & removing
> >>> the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> >>> gic_handle_shared_int().
> >>> 
> >>> This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> >>> support" series to be applied first.
> >> 
> >> I went through the whole series, and didn't spot anything bad (the
> >> couple of nits I raised can either be fixed at a later time or as a
> >> fixup on top of what you have).
> > 
> > Thanks :) I appreciate your review. So shall I take that as you'd prefer
> > that I submit separate fixup patches rather than submit a v2?
> 
> Just post the fixups on top. Nobody wants a new 38 series in their
> Inbox! ;-)

The changes to patch 35 wound up causing conflicts with patch 37 if you go 
squash the fixup commit, so I instead submitted a v2 of just those 2 patches.

I've also updated a bundle on the linux-mips patchwork which is hopefully 
convenient for whomever merges the series:

https://patchwork.linux-mips.org/bundle/paulburton/4.14-gic/

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation
  2017-08-18 21:09       ` Paul Burton
@ 2017-08-18 21:09         ` Paul Burton
  0 siblings, 0 replies; 111+ messages in thread
From: Paul Burton @ 2017-08-18 21:09 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: Thomas Gleixner, Ralf Baechle, linux-mips, Jason Cooper

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

Hi Marc,

On Friday, 18 August 2017 10:49:27 PDT Marc Zyngier wrote:
> On 18/08/17 18:44, Paul Burton wrote:
> > Hi Marc,
> > 
> > On Friday, 18 August 2017 10:28:01 PDT Marc Zyngier wrote:
> >> Hi Paul,
> >> 
> >> On 13/08/17 05:36, Paul Burton wrote:
> >>> This series cleans up the MIPS Global Interrupt Controller (GIC) driver
> >>> somewhat. It moves us towards using a header in a similar vein to the
> >>> ones we have for the MIPS Coherence Manager (CM) & Cluster Power
> >>> Controller (CPC) which allows us to access the GIC outside of the
> >>> irqchip driver - something beneficial already for the clocksource &
> >>> clock event driver, and which will be beneficial for further drivers
> >>> (eg. one for the GIC watchdog timer) and for multi-cluster work. Using
> >>> this header is also beneficial for consistency & code-sharing.
> >>> 
> >>> In addition to cleanups the series also optimises the driver in various
> >>> ways, including by using a per-CPU variable for pcpu_masks & removing
> >>> the need to read the GIC_SH_MASK_* registers when decoding interrupts in
> >>> gic_handle_shared_int().
> >>> 
> >>> This series requires my "[PATCH 00/19] MIPS: Initial multi-cluster
> >>> support" series to be applied first.
> >> 
> >> I went through the whole series, and didn't spot anything bad (the
> >> couple of nits I raised can either be fixed at a later time or as a
> >> fixup on top of what you have).
> > 
> > Thanks :) I appreciate your review. So shall I take that as you'd prefer
> > that I submit separate fixup patches rather than submit a v2?
> 
> Just post the fixups on top. Nobody wants a new 38 series in their
> Inbox! ;-)

The changes to patch 35 wound up causing conflicts with patch 37 if you go 
squash the fixup commit, so I instead submitted a v2 of just those 2 patches.

I've also updated a bundle on the linux-mips patchwork which is hopefully 
convenient for whomever merges the series:

https://patchwork.linux-mips.org/bundle/paulburton/4.14-gic/

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

end of thread, other threads:[~2017-08-18 21:10 UTC | newest]

Thread overview: 111+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-13  4:36 [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Paul Burton
2017-08-13  4:36 ` Paul Burton
2017-08-13  4:36 ` [PATCH 01/38] irqchip: mips-gic: SYNC after enabling GIC region Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 02/38] MIPS: GIC: Introduce asm/mips-gic.h with accessor functions Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-18 11:10   ` Marc Zyngier
2017-08-18 16:43     ` Paul Burton
2017-08-18 16:43       ` Paul Burton
2017-08-13  4:36 ` [PATCH 03/38] clocksource: mips-gic-timer: Use new GIC " Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 04/38] irqchip: mips-gic: Remove counter access functions Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 05/38] MIPS: CPS: Read GIC_VL_IDENT directly, not via irqchip driver Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 06/38] irqchip: mips-gic: Remove gic_read_local_vp_id() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 07/38] lib/iomap_copy.c: Add __ioread64_copy Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 08/38] irqchip: mips-gic: Simplify shared interrupt pending/mask reads Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 09/38] irqchip: mips-gic: Simplify gic_local_irq_domain_map() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 10/38] irqchip: mips-gic: Drop gic_(re)set_mask() functions Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 11/38] irqchip: mips-gic: Remove gic_set_polarity() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 12/38] irqchip: mips-gic: Remove gic_set_trigger() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 13/38] irqchip: mips-gic: Remove gic_set_dual_edge() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 14/38] irqchip: mips-gic: Remove gic_map_to_pin() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 15/38] irqchip: mips-gic: Remove gic_map_to_vpe() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 16/38] irqchip: mips-gic: Convert remaining shared reg access to new accessors Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 17/38] irqchip: mips-gic: Convert local int mask " Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 18/38] irqchip: mips-gic: Convert remaining local reg " Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 19/38] MIPS: GIC: Move GIC_LOCAL_INT_* to asm/mips-gic.h Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 20/38] irqchip: mips-gic: Remove GIC_CPU_INT* macros Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 21/38] irqchip: mips-gic: Move various definitions to the driver Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 22/38] MIPS: VDSO: Drop gic_get_usm_range() usage Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-18 11:38   ` Marc Zyngier
2017-08-18 16:47     ` Paul Burton
2017-08-18 16:47       ` Paul Burton
2017-08-18 16:52       ` Marc Zyngier
2017-08-13  4:36 ` [PATCH 23/38] irqchip: mips-gic: Remove gic_get_usm_range() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 24/38] irqchip: mips-gic: Remove __gic_irq_dispatch() forward declaration Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 25/38] irqchip: mips-gic: Remove gic_init() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 26/38] MIPS: Use mips_gic_present() in place of gic_present Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 27/38] irqchip: mips-gic: Remove gic_present Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 28/38] irqchip: mips-gic: Move gic_get_c0_*_int() to asm/mips-gic.h Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 29/38] MIPS: VDSO: Avoid use of linux/irqchip/mips-gic.h Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 30/38] MIPS: Remove unnecessary inclusions " Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 31/38] irqchip: mips-gic: Remove linux/irqchip/mips-gic.h Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 32/38] irqchip: mips-gic: Inline __gic_init() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 33/38] irqchip: mips-gic: Inline gic_basic_init() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 34/38] irqchip: mips-gic: Make pcpu_masks a per-cpu variable Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-18 15:37   ` Marc Zyngier
2017-08-18 17:02     ` Paul Burton
2017-08-18 17:02       ` Paul Burton
2017-08-18 17:18       ` Marc Zyngier
2017-08-13  4:36 ` [PATCH 35/38] irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK* Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-18 15:44   ` Marc Zyngier
2017-08-18 17:11     ` Paul Burton
2017-08-18 17:11       ` Paul Burton
2017-08-18 17:25       ` Marc Zyngier
2017-08-18 21:02         ` [PATCH v2 " Paul Burton
2017-08-18 21:02           ` Paul Burton
2017-08-13  4:36 ` [PATCH 36/38] irqchip: mips-gic: Clean up mti,reserved-cpu-vectors handling Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  4:36 ` [PATCH 37/38] irqchip: mips-gic: Use cpumask_first_and() in gic_set_affinity() Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-13  9:08   ` Sergei Shtylyov
2017-08-14 16:18     ` Paul Burton
2017-08-14 16:18       ` Paul Burton
2017-08-14 16:48       ` Sergei Shtylyov
2017-08-18 21:04   ` [PATCH v2 " Paul Burton
2017-08-18 21:04     ` Paul Burton
2017-08-13  4:36 ` [PATCH 38/38] irqchip: mips-gic: Let the core set struct irq_common_data affinity Paul Burton
2017-08-13  4:36   ` Paul Burton
2017-08-15 10:13 ` [PATCH 00/38] irqchip: mips-gic: Cleanup & optimisation Marc Zyngier
2017-08-15 16:16   ` Paul Burton
2017-08-15 16:16     ` Paul Burton
2017-08-15 16:49     ` Marc Zyngier
2017-08-18 17:28 ` Marc Zyngier
2017-08-18 17:44   ` Paul Burton
2017-08-18 17:44     ` Paul Burton
2017-08-18 17:49     ` Marc Zyngier
2017-08-18 21:09       ` Paul Burton
2017-08-18 21:09         ` Paul Burton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox