Discussion:
[PATCH 00/19] MIPS GIC cleanup, part 2
Andrew Bresticker
2014-10-20 19:03:47 UTC
Permalink
Second round of cleanups for the MIPS GIC drivers:
- Patches 1 through 5 get rid of the ugly REG() macros and instead use
proper iomem accessors.
- Patches 6 and 7 move the GIC header to linux/irqchip/ and clean it up.
- Patches 8 through 10 are misc. GIC irqchip cleanups.
- Patches 11 and 12 combine the GIC clocksource and clockevent drivers and
move them to drivers/clocksource/.
- Patches 13 through 19 are various cleanups for the GIC clocksource driver.

Boot tested on Malta and (with additional out-of-tree patches) a platform
based on the IMG Pistachio SoC. Build tested for SEAD-3.

Based on 3.18-rc1 + part 1 of my GIC cleanup series [0]. A tree with both
series is available at:
https://github.com/abrestic/linux/commits/mips-gic-cleanup-pt2-v1

[0] https://lkml.org/lkml/2014/9/18/487

Andrew Bresticker (19):
MIPS: Malta: Use gic_read_count() to read GIC timer
irqchip: mips-gic: Export function to read counter width
MIPS: sead3: Stop using GIC REG macros
MIPS: Malta: Stop using GIC REG macros
irqchip: mips-gic: Use proper iomem accessors
MIPS: Move gic.h to include/linux/irqchip/mips-gic.h
irqchip: mips-gic: Clean up header file
irqchip: mips-gic: Clean up #includes
irqchip: mips-gic: Remove gic_{pending,itrmask}_regs
irqchip: mips-gic: Use GIC_SH_WEDGE_{SET,CLR} macros
MIPS: Move GIC clocksource driver to drivers/clocksource/
clocksource: mips-gic: Combine with GIC clockevent driver
clocksource: mips-gic: Staticize local symbols
clocksource: mips-gic: Move gic_frequency to clocksource driver
clocksource: mips-gic: Remove gic_event_handler
clocksource: mips-gic: Use percpu_dev_id
clocksource: mips-gic: Use CPU notifiers to setup the timer
clocksource: mips-gic: Use clockevents_config_and_register
clocksource: mips-gic: Bump up rating of GIC timer

arch/mips/Kconfig | 21 +-
arch/mips/include/asm/mips-boards/maltaint.h | 2 +-
arch/mips/include/asm/mips-boards/sead3int.h | 2 +-
arch/mips/include/asm/time.h | 5 +-
arch/mips/kernel/Makefile | 2 -
arch/mips/kernel/cevt-gic.c | 103 ---------
arch/mips/kernel/cevt-r4k.c | 2 +-
arch/mips/kernel/csrc-gic.c | 40 ----
arch/mips/kernel/smp-cmp.c | 2 +-
arch/mips/kernel/smp-cps.c | 2 +-
arch/mips/kernel/smp-gic.c | 2 +-
arch/mips/kernel/smp-mt.c | 2 +-
arch/mips/mti-malta/malta-int.c | 15 +-
arch/mips/mti-malta/malta-time.c | 20 +-
arch/mips/mti-sead3/sead3-ehci.c | 2 +-
arch/mips/mti-sead3/sead3-int.c | 9 +-
arch/mips/mti-sead3/sead3-net.c | 2 +-
arch/mips/mti-sead3/sead3-platform.c | 2 +-
arch/mips/mti-sead3/sead3-time.c | 2 +-
drivers/clocksource/Kconfig | 4 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/mips-gic-timer.c | 139 ++++++++++++
drivers/irqchip/irq-mips-gic.c | 243 +++++++++++++--------
.../asm/gic.h => include/linux/irqchip/mips-gic.h | 203 +++--------------
24 files changed, 363 insertions(+), 464 deletions(-)
delete mode 100644 arch/mips/kernel/cevt-gic.c
delete mode 100644 arch/mips/kernel/csrc-gic.c
create mode 100644 drivers/clocksource/mips-gic-timer.c
rename arch/mips/include/asm/gic.h => include/linux/irqchip/mips-gic.h (61%)
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:48 UTC
Permalink
Instead of reading the GIC registers directly, use the interface the GIC
driver already exposes for reading the global timer. Also get rid of
the unnecessary #ifdefs.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/mti-malta/malta-time.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index f6ca8ea..39f3902 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -70,9 +70,7 @@ static void __init estimate_frequencies(void)
{
unsigned long flags;
unsigned int count, start;
-#ifdef CONFIG_MIPS_GIC
- unsigned int giccount = 0, gicstart = 0;
-#endif
+ cycle_t giccount = 0, gicstart = 0;

#if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ
mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000;
@@ -87,32 +85,26 @@ static void __init estimate_frequencies(void)

/* Initialize counters. */
start = read_c0_count();
-#ifdef CONFIG_MIPS_GIC
if (gic_present)
- GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart);
-#endif
+ gicstart = gic_read_count();

/* Read counter exactly on falling edge of update flag. */
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));

count = read_c0_count();
-#ifdef CONFIG_MIPS_GIC
if (gic_present)
- GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount);
-#endif
+ giccount = gic_read_count();

local_irq_restore(flags);

count -= start;
mips_hpt_frequency = count;

-#ifdef CONFIG_MIPS_GIC
if (gic_present) {
giccount -= gicstart;
gic_frequency = giccount;
}
-#endif
}

void read_persistent_clock(struct timespec *ts)
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:04:00 UTC
Permalink
There are a number of variables and functions which are unnecessarily
global. Mark them static.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/clocksource/mips-gic-timer.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 3cf5912..2603f50 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -15,8 +15,8 @@

#include <asm/time.h>

-DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
-int gic_timer_irq_installed;
+static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
+static int gic_timer_irq_installed;

static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
{
@@ -30,13 +30,13 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
return res;
}

-void gic_set_clock_mode(enum clock_event_mode mode,
+static void gic_set_clock_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
/* Nothing to do ... */
}

-irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
+static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd;
int cpu = smp_processor_id();
@@ -53,7 +53,7 @@ struct irqaction gic_compare_irqaction = {
.name = "timer",
};

-void gic_event_handler(struct clock_event_device *dev)
+static void gic_event_handler(struct clock_event_device *dev)
{
}
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:59 UTC
Permalink
Combine the GIC clocksource driver with the GIC clockevent driver from
arch/mips/kernel/cevt-gic.c and remove the clockevent driver's separate
Kconfig symbol.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/Kconfig | 13 -----
arch/mips/include/asm/time.h | 2 +-
arch/mips/kernel/Makefile | 1 -
arch/mips/kernel/cevt-gic.c | 103 -----------------------------------
drivers/clocksource/mips-gic-timer.c | 90 ++++++++++++++++++++++++++++++
drivers/irqchip/irq-mips-gic.c | 2 +-
6 files changed, 92 insertions(+), 119 deletions(-)
delete mode 100644 arch/mips/kernel/cevt-gic.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5b1d44b..88ef7f4 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -907,10 +907,6 @@ config CEVT_GT641XX
config CEVT_R4K
bool

-config CEVT_GIC
- select MIPS_CM
- bool
-
config CEVT_SB1250
bool

@@ -1880,15 +1876,6 @@ config FORCE_MAX_ZONEORDER
The page size is not necessarily 4KB. Keep this in mind
when choosing a value for this option.

-config CEVT_GIC
- bool "Use GIC global counter for clock events"
- depends on MIPS_GIC && !MIPS_SEAD3
- help
- Use the GIC global counter for the clock events. The R4K clock
- event driver is always present, so if the platform ends up not
- detecting a GIC, it will fall back to the R4K timer for the
- generation of clock events.
-
config BOARD_SCACHE
bool

diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index 7969933..5f30aab 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -57,7 +57,7 @@ extern int gic_clockevent_init(void);

static inline int mips_clockevent_init(void)
{
-#if defined(CONFIG_CEVT_GIC)
+#if defined(CONFIG_CLKSRC_MIPS_GIC)
return (gic_clockevent_init() | r4k_clockevent_init());
#elif defined(CONFIG_CEVT_R4K)
return r4k_clockevent_init();
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 3d1ea51..e64fe1d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -18,7 +18,6 @@ endif
obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
-obj-$(CONFIG_CEVT_GIC) += cevt-gic.o
obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c
deleted file mode 100644
index 9caa68a..0000000
--- a/arch/mips/kernel/cevt-gic.c
+++ /dev/null
@@ -1,103 +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) 2013 Imagination Technologies Ltd.
- */
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/percpu.h>
-#include <linux/smp.h>
-#include <linux/irq.h>
-#include <linux/irqchip/mips-gic.h>
-
-#include <asm/time.h>
-#include <asm/mips-boards/maltaint.h>
-
-DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
-int gic_timer_irq_installed;
-
-
-static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
-{
- u64 cnt;
- int res;
-
- cnt = gic_read_count();
- cnt += (u64)delta;
- gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
- res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
- return res;
-}
-
-void gic_set_clock_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- /* Nothing to do ... */
-}
-
-irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *cd;
- int cpu = smp_processor_id();
-
- gic_write_compare(gic_read_compare());
- cd = &per_cpu(gic_clockevent_device, cpu);
- cd->event_handler(cd);
- return IRQ_HANDLED;
-}
-
-struct irqaction gic_compare_irqaction = {
- .handler = gic_compare_interrupt,
- .flags = IRQF_PERCPU | IRQF_TIMER,
- .name = "timer",
-};
-
-
-void gic_event_handler(struct clock_event_device *dev)
-{
-}
-
-int gic_clockevent_init(void)
-{
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *cd;
- unsigned int irq;
-
- if (!cpu_has_counter || !gic_frequency)
- return -ENXIO;
-
- irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
-
- cd = &per_cpu(gic_clockevent_device, cpu);
-
- cd->name = "MIPS GIC";
- cd->features = CLOCK_EVT_FEAT_ONESHOT |
- CLOCK_EVT_FEAT_C3STOP;
-
- clockevent_set_clock(cd, gic_frequency);
-
- /* Calculate the min / max delta */
- cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
- cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
-
- cd->rating = 300;
- cd->irq = irq;
- cd->cpumask = cpumask_of(cpu);
- cd->set_next_event = gic_next_event;
- cd->set_mode = gic_set_clock_mode;
- cd->event_handler = gic_event_handler;
-
- clockevents_register_device(cd);
-
- if (!gic_timer_irq_installed) {
- setup_percpu_irq(irq, &gic_compare_irqaction);
- gic_timer_irq_installed = 1;
- }
-
- enable_percpu_irq(irq, IRQ_TYPE_NONE);
-
-
- return 0;
-}
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 0bf28e6..3cf5912 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -5,10 +5,100 @@
*
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/
+#include <linux/clockchips.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/irqchip/mips-gic.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
#include <linux/time.h>

+#include <asm/time.h>
+
+DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
+int gic_timer_irq_installed;
+
+static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+ u64 cnt;
+ int res;
+
+ cnt = gic_read_count();
+ cnt += (u64)delta;
+ gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
+ res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
+ return res;
+}
+
+void gic_set_clock_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd;
+ int cpu = smp_processor_id();
+
+ gic_write_compare(gic_read_compare());
+ cd = &per_cpu(gic_clockevent_device, cpu);
+ cd->event_handler(cd);
+ return IRQ_HANDLED;
+}
+
+struct irqaction gic_compare_irqaction = {
+ .handler = gic_compare_interrupt,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
+ .name = "timer",
+};
+
+void gic_event_handler(struct clock_event_device *dev)
+{
+}
+
+int gic_clockevent_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+ unsigned int irq;
+
+ if (!cpu_has_counter || !gic_frequency)
+ return -ENXIO;
+
+ irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
+
+ cd = &per_cpu(gic_clockevent_device, cpu);
+
+ cd->name = "MIPS GIC";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_C3STOP;
+
+ clockevent_set_clock(cd, gic_frequency);
+
+ /* Calculate the min / max delta */
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+
+ cd->rating = 300;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_next_event = gic_next_event;
+ cd->set_mode = gic_set_clock_mode;
+ cd->event_handler = gic_event_handler;
+
+ clockevents_register_device(cd);
+
+ if (!gic_timer_irq_installed) {
+ setup_percpu_irq(irq, &gic_compare_irqaction);
+ gic_timer_irq_installed = 1;
+ }
+
+ enable_percpu_irq(irq, IRQ_TYPE_NONE);
+
+ return 0;
+}
+
static cycle_t gic_hpt_read(struct clocksource *cs)
{
return gic_read_count();
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 99687ed..5c856e6 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -103,7 +103,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
}

-#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC)
+#ifdef CONFIG_CLKSRC_MIPS_GIC
cycle_t gic_read_count(void)
{
unsigned int hi, hi2, lo;
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:04:06 UTC
Permalink
Bump up the rating of the GIC timer so that it gets prioritized
over the CP0 timer.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/clocksource/mips-gic-timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 84fbb7a..a749c81 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -61,7 +61,7 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd)
cd->features = CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_C3STOP;

- cd->rating = 300;
+ cd->rating = 350;
cd->irq = gic_timer_irq;
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = gic_next_event;
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:04:05 UTC
Permalink
Use clockevents_config_and_register to setup the clock_event_device
based on frequency and min/max ticks instead of doing it ourselves.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/clocksource/mips-gic-timer.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 3ce992b..84fbb7a 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -15,8 +15,6 @@
#include <linux/smp.h>
#include <linux/time.h>

-#include <asm/time.h>
-
static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
static int gic_timer_irq;
static unsigned int gic_frequency;
@@ -63,19 +61,13 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd)
cd->features = CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_C3STOP;

- clockevent_set_clock(cd, gic_frequency);
-
- /* Calculate the min / max delta */
- cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
- cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
-
cd->rating = 300;
cd->irq = gic_timer_irq;
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = gic_next_event;
cd->set_mode = gic_set_clock_mode;

- clockevents_register_device(cd);
+ clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff);

enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE);
}
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:49 UTC
Permalink
Export the function gic_get_count_width to read the width of
the GIC global counter from GIC_SH_CONFIG. Update the GIC
clocksource driver to use this new function.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/include/asm/gic.h | 1 +
arch/mips/kernel/csrc-gic.c | 9 +--------
drivers/irqchip/irq-mips-gic.c | 11 +++++++++++
3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index 727b7bf..c88e1fa 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -370,6 +370,7 @@ extern void gic_init(unsigned long gic_base_addr,
unsigned int irqbase);
extern void gic_clocksource_init(unsigned int);
extern cycle_t gic_read_count(void);
+extern unsigned int gic_get_count_width(void);
extern cycle_t gic_read_compare(void);
extern void gic_write_compare(cycle_t cnt);
extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c
index e026209..ab615c6 100644
--- a/arch/mips/kernel/csrc-gic.c
+++ b/arch/mips/kernel/csrc-gic.c
@@ -23,15 +23,8 @@ static struct clocksource gic_clocksource = {

void __init gic_clocksource_init(unsigned int frequency)
{
- unsigned int config, bits;
-
- /* Calculate the clocksource mask. */
- GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
- bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
- (GIC_SH_CONFIG_COUNTBITS_SHF - 2));
-
/* Set clocksource mask. */
- gic_clocksource.mask = CLOCKSOURCE_MASK(bits);
+ gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());

/* Calculate a somewhat reasonable rating value. */
gic_clocksource.rating = 200 + frequency / 10000000;
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 02c7d2a..83dde6f 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -63,6 +63,17 @@ cycle_t gic_read_count(void)
return (((cycle_t) hi) << 32) + lo;
}

+unsigned int gic_get_count_width(void)
+{
+ unsigned int bits, config;
+
+ GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
+ bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
+ GIC_SH_CONFIG_COUNTBITS_SHF);
+
+ return bits;
+}
+
void gic_write_compare(cycle_t cnt)
{
GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:50 UTC
Permalink
Stop using the REG macros from gic.h and instead use proper iomem
accessors.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/mti-sead3/sead3-int.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
index 69ae185..995c401 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -20,16 +20,15 @@
#define SEAD_CONFIG_BASE 0x1b100110
#define SEAD_CONFIG_SIZE 4

-static unsigned long sead3_config_reg;
+static void __iomem *sead3_config_reg;

void __init arch_init_irq(void)
{
if (!cpu_has_veic)
mips_cpu_irq_init();

- sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE,
- SEAD_CONFIG_SIZE);
- gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
+ sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE);
+ gic_present = (readl(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
SEAD_CONFIG_GIC_PRESENT_SHF;
pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
pr_info("EIC: %s\n",
--
2.1.0.rc2.206.gedb03e5
Qais Yousef
2014-10-22 09:33:44 UTC
Permalink
Post by Andrew Bresticker
Stop using the REG macros from gic.h and instead use proper iomem
accessors.
---
arch/mips/mti-sead3/sead3-int.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
index 69ae185..995c401 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -20,16 +20,15 @@
#define SEAD_CONFIG_BASE 0x1b100110
#define SEAD_CONFIG_SIZE 4
-static unsigned long sead3_config_reg;
+static void __iomem *sead3_config_reg;
void __init arch_init_irq(void)
{
if (!cpu_has_veic)
mips_cpu_irq_init();
- sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE,
- SEAD_CONFIG_SIZE);
- gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
+ sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE);
+ gic_present = (readl(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
SEAD_CONFIG_GIC_PRESENT_SHF;
pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
pr_info("EIC: %s\n",
I think you need to use the __raw_readl() variant here and for all other
similar changes.

Qais
Andrew Bresticker
2014-10-22 18:01:15 UTC
Permalink
Post by Qais Yousef
Post by Andrew Bresticker
Stop using the REG macros from gic.h and instead use proper iomem
accessors.
---
arch/mips/mti-sead3/sead3-int.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/mips/mti-sead3/sead3-int.c
b/arch/mips/mti-sead3/sead3-int.c
index 69ae185..995c401 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -20,16 +20,15 @@
#define SEAD_CONFIG_BASE 0x1b100110
#define SEAD_CONFIG_SIZE 4
-static unsigned long sead3_config_reg;
+static void __iomem *sead3_config_reg;
void __init arch_init_irq(void)
{
if (!cpu_has_veic)
mips_cpu_irq_init();
- sead3_config_reg = (unsigned
long)ioremap_nocache(SEAD_CONFIG_BASE,
- SEAD_CONFIG_SIZE);
- gic_present = (REG32(sead3_config_reg) &
SEAD_CONFIG_GIC_PRESENT_MSK) >>
+ sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE,
SEAD_CONFIG_SIZE);
+ gic_present = (readl(sead3_config_reg) &
SEAD_CONFIG_GIC_PRESENT_MSK) >>
SEAD_CONFIG_GIC_PRESENT_SHF;
pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
pr_info("EIC: %s\n",
I think you need to use the __raw_readl() variant here and for all other
similar changes.
Thanks, will do.

-Andrew

Andrew Bresticker
2014-10-20 19:04:04 UTC
Permalink
Instead of requiring an explicit call to gic_clockevent_init in the SMP
startup path, use CPU notifiers to register and enable the GIC timer on
CPU startup.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/include/asm/time.h | 5 +--
drivers/clocksource/mips-gic-timer.c | 60 ++++++++++++++++++++++++++----------
2 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index 5f30aab..8ab2874 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -53,13 +53,10 @@ extern int __weak get_c0_perfcount_int(void);
*/
extern unsigned int __weak get_c0_compare_int(void);
extern int r4k_clockevent_init(void);
-extern int gic_clockevent_init(void);

static inline int mips_clockevent_init(void)
{
-#if defined(CONFIG_CLKSRC_MIPS_GIC)
- return (gic_clockevent_init() | r4k_clockevent_init());
-#elif defined(CONFIG_CEVT_R4K)
+#ifdef CONFIG_CEVT_R4K
return r4k_clockevent_init();
#else
return -ENXIO;
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 05bdfe1..3ce992b 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -6,9 +6,11 @@
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/
#include <linux/clockchips.h>
+#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irqchip/mips-gic.h>
+#include <linux/notifier.h>
#include <linux/percpu.h>
#include <linux/smp.h>
#include <linux/time.h>
@@ -16,7 +18,7 @@
#include <asm/time.h>

static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
-static int gic_timer_irq_installed;
+static int gic_timer_irq;
static unsigned int gic_frequency;

static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
@@ -53,18 +55,9 @@ struct irqaction gic_compare_irqaction = {
.name = "timer",
};

-int gic_clockevent_init(void)
+static void gic_clockevent_cpu_init(struct clock_event_device *cd)
{
unsigned int cpu = smp_processor_id();
- struct clock_event_device *cd;
- unsigned int irq;
-
- if (!cpu_has_counter || !gic_frequency)
- return -ENXIO;
-
- irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
-
- cd = &per_cpu(gic_clockevent_device, cpu);

cd->name = "MIPS GIC";
cd->features = CLOCK_EVT_FEAT_ONESHOT |
@@ -77,19 +70,52 @@ int gic_clockevent_init(void)
cd->min_delta_ns = clockevent_delta2ns(0x300, cd);

cd->rating = 300;
- cd->irq = irq;
+ cd->irq = gic_timer_irq;
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = gic_next_event;
cd->set_mode = gic_set_clock_mode;

clockevents_register_device(cd);

- if (!gic_timer_irq_installed) {
- setup_percpu_irq(irq, &gic_compare_irqaction);
- gic_timer_irq_installed = 1;
+ enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE);
+}
+
+static void gic_clockevent_cpu_exit(struct clock_event_device *cd)
+{
+ disable_percpu_irq(gic_timer_irq);
+}
+
+static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device));
+ break;
+ case CPU_DYING:
+ gic_clockevent_cpu_exit(this_cpu_ptr(&gic_clockevent_device));
+ break;
}

- enable_percpu_irq(irq, IRQ_TYPE_NONE);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block gic_cpu_nb = {
+ .notifier_call = gic_cpu_notifier,
+};
+
+static int gic_clockevent_init(void)
+{
+ if (!cpu_has_counter || !gic_frequency)
+ return -ENXIO;
+
+ gic_timer_irq = MIPS_GIC_IRQ_BASE +
+ GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
+ setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction);
+
+ register_cpu_notifier(&gic_cpu_nb);
+
+ gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device));

return 0;
}
@@ -116,4 +142,6 @@ void __init gic_clocksource_init(unsigned int frequency)
gic_clocksource.rating = 200 + frequency / 10000000;

clocksource_register_hz(&gic_clocksource, frequency);
+
+ gic_clockevent_init();
}
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:04:03 UTC
Permalink
Since the GIC timer IRQ is a percpu IRQ, we can use percpu_dev_id
to pass the IRQ handler the correct clock_event_device.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/clocksource/mips-gic-timer.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 763aa1c..05bdfe1 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -39,17 +39,16 @@ static void gic_set_clock_mode(enum clock_event_mode mode,

static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *cd;
- int cpu = smp_processor_id();
+ struct clock_event_device *cd = dev_id;

gic_write_compare(gic_read_compare());
- cd = &per_cpu(gic_clockevent_device, cpu);
cd->event_handler(cd);
return IRQ_HANDLED;
}

struct irqaction gic_compare_irqaction = {
.handler = gic_compare_interrupt,
+ .percpu_dev_id = &gic_clockevent_device,
.flags = IRQF_PERCPU | IRQF_TIMER,
.name = "timer",
};
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:04:02 UTC
Permalink
Remove gic_event_handler since it is completely unnecessary.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/clocksource/mips-gic-timer.c | 5 -----
1 file changed, 5 deletions(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index bced17d..763aa1c 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -54,10 +54,6 @@ struct irqaction gic_compare_irqaction = {
.name = "timer",
};

-static void gic_event_handler(struct clock_event_device *dev)
-{
-}
-
int gic_clockevent_init(void)
{
unsigned int cpu = smp_processor_id();
@@ -86,7 +82,6 @@ int gic_clockevent_init(void)
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = gic_next_event;
cd->set_mode = gic_set_clock_mode;
- cd->event_handler = gic_event_handler;

clockevents_register_device(cd);
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:04:01 UTC
Permalink
There's no reason for gic_frequency to be global any more and it
certainly doesn't belong in the GIC irqchip driver, so move it to
the GIC clocksource driver.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/mti-malta/malta-time.c | 2 ++
drivers/clocksource/mips-gic-timer.c | 3 +++
drivers/irqchip/irq-mips-gic.c | 1 -
include/linux/irqchip/mips-gic.h | 1 -
4 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 028fae0..ce02dbd 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -46,6 +46,8 @@ static int mips_cpu_timer_irq;
static int mips_cpu_perf_irq;
extern int cp0_perfcount_irq;

+static unsigned int gic_frequency;
+
static void mips_timer_dispatch(void)
{
do_IRQ(mips_cpu_timer_irq);
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 2603f50..bced17d 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -17,6 +17,7 @@

static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
static int gic_timer_irq_installed;
+static unsigned int gic_frequency;

static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
{
@@ -112,6 +113,8 @@ static struct clocksource gic_clocksource = {

void __init gic_clocksource_init(unsigned int frequency)
{
+ gic_frequency = frequency;
+
/* Set clocksource mask. */
gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 5c856e6..2949a9c 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -18,7 +18,6 @@
#include <asm/setup.h>
#include <asm/traps.h>

-unsigned int gic_frequency;
unsigned int gic_present;

struct gic_pcpu_mask {
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 0350eff..420f77b 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -230,7 +230,6 @@
#define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)

extern unsigned int gic_present;
-extern unsigned int gic_frequency;

extern void gic_init(unsigned long gic_base_addr,
unsigned long gic_addrspace_size, unsigned int cpu_vec,
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:51 UTC
Permalink
Stop using the REG macros from gic.h and instead use proper iomem
accessors.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/mti-malta/malta-int.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index bcab0b1..864d482 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -37,7 +37,7 @@
#include <asm/setup.h>
#include <asm/rtlx.h>

-static unsigned long _msc01_biu_base;
+static void __iomem *_msc01_biu_base;

static DEFINE_RAW_SPINLOCK(mips_irq_lock);

@@ -293,10 +293,9 @@ void __init arch_init_irq(void)
gic_present = 1;
} else {
if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) {
- _msc01_biu_base = (unsigned long)
- ioremap_nocache(MSC01_BIU_REG_BASE,
+ _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE,
MSC01_BIU_ADDRSPACE_SZ);
- gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) &
+ gic_present = (readl(_msc01_biu_base + MSC01_SC_CFG_OFS) &
MSC01_SC_CFG_GICPRES_MSK) >>
MSC01_SC_CFG_GICPRES_SHF;
}
@@ -336,9 +335,9 @@ void __init arch_init_irq(void)
MIPS_GIC_IRQ_BASE);
if (!mips_cm_present()) {
/* Enable the GIC */
- i = REG(_msc01_biu_base, MSC01_SC_CFG);
- REG(_msc01_biu_base, MSC01_SC_CFG) =
- (i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
+ i = readl(_msc01_biu_base + MSC01_SC_CFG_OFS);
+ writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF),
+ _msc01_biu_base + MSC01_SC_CFG_OFS);
pr_debug("GIC Enabled\n");
}
i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A;
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:52 UTC
Permalink
Get rid of the ugly GICREAD/GICWRITE/GICBIS macros and use proper
iomem accessors instead. Since the GIC registers are not directly
accessed outside of the GIC driver any more, make gic_base static
and move all the GIC register manipulation macros out of gic.h,
converting them to static inline functions.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/include/asm/gic.h | 72 ++------------
drivers/irqchip/irq-mips-gic.c | 206 +++++++++++++++++++++++++++--------------
2 files changed, 142 insertions(+), 136 deletions(-)

diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index c88e1fa..285944c 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -16,8 +16,6 @@

#include <irq.h>

-#undef GICISBYTELITTLEENDIAN
-
#define GIC_MAX_INTRS 256

/* Constants */
@@ -29,36 +27,9 @@
#define GIC_TRIG_DUAL_DISABLE 0

#define MSK(n) ((1 << (n)) - 1)
-#define REG32(addr) (*(volatile unsigned int *) (addr))
-#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS)
-#define REGP(base, phys) REG32((unsigned long)(base) + (phys))

/* Accessors */
-#define GIC_REG(segment, offset) \
- REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
-#define GIC_REG_ADDR(segment, offset) \
- REG32(_gic_base + segment##_##SECTION_OFS + offset)
-
-#define GIC_ABS_REG(segment, offset) \
- (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
-#define GIC_REG_ABS_ADDR(segment, offset) \
- (_gic_base + segment##_##SECTION_OFS + offset)
-
-#ifdef GICISBYTELITTLEENDIAN
-#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
-#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data))
-#else
-#define GICREAD(reg, data) ((data) = (reg))
-#define GICWRITE(reg, data) ((reg) = (data))
-#endif
-#define GICBIS(reg, mask, bits) \
- do { u32 data; \
- GICREAD(reg, data); \
- data &= ~(mask); \
- data |= ((bits) & (mask)); \
- GICWRITE((reg), data); \
- } while (0)
-
+#define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS)

/* GIC Address Space */
#define SHARED_SECTION_OFS 0x0000
@@ -155,14 +126,13 @@
#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500

/* Maps Interrupt X to a Pin */
-#define GIC_SH_MAP_TO_PIN(intr) \
- (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr))
+#define GIC_SH_MAP_TO_PIN(intr) (4 * (intr))

#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000

/* Maps Interrupt X to a VPE */
#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
- (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4))
+ ((32 * (intr)) + (((vpe) / 32) * 4))
#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))

/* Convert an interrupt number to a byte offset/bit for multi-word registers */
@@ -171,34 +141,16 @@

/* Polarity : Reset Value is always 0 */
#define GIC_SH_SET_POLARITY_OFS 0x0100
-#define GIC_SET_POLARITY(intr, pol) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
- GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
- (pol) << GIC_INTR_BIT(intr))

/* Triggering : Reset Value is always 0 */
#define GIC_SH_SET_TRIGGER_OFS 0x0180
-#define GIC_SET_TRIGGER(intr, trig) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
- GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
- (trig) << GIC_INTR_BIT(intr))

/* Dual edge triggering : Reset Value is always 0 */
#define GIC_SH_SET_DUAL_OFS 0x0200
-#define GIC_SET_DUAL(intr, dual) \
- GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_DUAL_OFS + \
- GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
- (dual) << GIC_INTR_BIT(intr))

/* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380
-#define GIC_SET_INTR_MASK(intr) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \
- GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
#define GIC_SH_RMASK_OFS 0x0300
-#define GIC_CLR_INTR_MASK(intr) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \
- GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))

/* Register Map for Local Section */
#define GIC_VPE_CTL_OFS 0x0000
@@ -220,13 +172,11 @@
#define GIC_VPE_COMPARE_LO_OFS 0x00a0
#define GIC_VPE_COMPARE_HI_OFS 0x00a4

-#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
-#define GIC_VPE_EIC_SS(intr) \
- (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr))
+#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100
+#define GIC_VPE_EIC_SS(intr) (4 * (intr))

-#define GIC_VPE_EIC_VEC_BASE 0x0800
-#define GIC_VPE_EIC_VEC(intr) \
- (GIC_VPE_EIC_VEC_BASE + (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
@@ -316,13 +266,6 @@
#define GIC_VPE_SMASK_SWINT1_SHF 5
#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)

-/*
- * Set the Mapping of Interrupt X to a VPE.
- */
-#define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \
- GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
-
/* GIC nomenclature for Core Interrupt Pins. */
#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
#define GIC_CPU_INT1 1 /* . */
@@ -363,7 +306,6 @@

extern unsigned int gic_present;
extern unsigned int gic_frequency;
-extern unsigned long _gic_base;

extern void gic_init(unsigned long gic_base_addr,
unsigned long gic_addrspace_size, unsigned int cpu_vec,
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 83dde6f..afa3663 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -23,7 +23,6 @@

unsigned int gic_frequency;
unsigned int gic_present;
-unsigned long _gic_base;

struct gic_pcpu_mask {
DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
@@ -37,6 +36,7 @@ struct gic_intrmask_regs {
DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
};

+static void __iomem *gic_base;
static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
@@ -49,15 +49,82 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;

static void __gic_irq_dispatch(void);

+static inline unsigned int gic_read(unsigned int reg)
+{
+ return readl(gic_base + reg);
+}
+
+static inline void gic_write(unsigned int reg, unsigned int val)
+{
+ writel(val, gic_base + reg);
+}
+
+static inline void gic_update_bits(unsigned int reg, unsigned int mask,
+ unsigned int val)
+{
+ unsigned int regval;
+
+ regval = gic_read(reg);
+ regval &= ~mask;
+ regval |= val;
+ 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),
+ 1 << 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),
+ 1 << 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) +
+ GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr),
+ 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) +
+ GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr),
+ 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),
+ 1 << GIC_INTR_BIT(intr),
+ dual << GIC_INTR_BIT(intr));
+}
+
+static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
+{
+ gic_write(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) +
+ GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe),
+ GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
+}
+
#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC)
cycle_t gic_read_count(void)
{
unsigned int hi, hi2, lo;

do {
- GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
- GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
- GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
+ hi = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
+ lo = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
+ hi2 = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
} while (hi2 != hi);

return (((cycle_t) hi) << 32) + lo;
@@ -67,7 +134,7 @@ unsigned int gic_get_count_width(void)
{
unsigned int bits, config;

- GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
+ config = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
GIC_SH_CONFIG_COUNTBITS_SHF);

@@ -76,9 +143,9 @@ unsigned int gic_get_count_width(void)

void gic_write_compare(cycle_t cnt)
{
- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
(int)(cnt >> 32));
- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
(int)(cnt & 0xffffffff));
}

@@ -88,10 +155,10 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu)

local_irq_save(flags);

- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
(int)(cnt >> 32));
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
(int)(cnt & 0xffffffff));

local_irq_restore(flags);
@@ -101,8 +168,8 @@ cycle_t gic_read_compare(void)
{
unsigned int hi, lo;

- GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi);
- GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo);
+ hi = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
+ lo = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));

return (((cycle_t) hi) << 32) + lo;
}
@@ -116,7 +183,7 @@ static bool gic_local_irq_is_routable(int intr)
if (cpu_has_veic)
return true;

- GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_CTL), vpe_ctl);
+ vpe_ctl = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));
switch (intr) {
case GIC_LOCAL_INT_TIMER:
return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK;
@@ -136,7 +203,7 @@ unsigned int gic_get_timer_pending(void)
{
unsigned int vpe_pending;

- GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), vpe_pending);
+ vpe_pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
return (vpe_pending & GIC_VPE_PEND_TIMER_MSK);
}

@@ -146,12 +213,13 @@ static void gic_bind_eic_interrupt(int irq, int set)
irq -= GIC_PIN_TO_VEC_OFFSET;

/* Set irq to use shadow set */
- GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_EIC_SHADOW_SET_BASE) +
+ GIC_VPE_EIC_SS(irq), set);
}

void gic_send_ipi(unsigned int intr)
{
- GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
+ gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
}

int gic_get_c0_compare_int(void)
@@ -178,23 +246,21 @@ static unsigned int gic_get_int(void)
{
unsigned int i;
unsigned long *pending, *intrmask, *pcpu_mask;
- unsigned long *pending_abs, *intrmask_abs;
+ unsigned long pending_reg, intrmask_reg;

/* Get per-cpu bitmaps */
pending = pending_regs[smp_processor_id()].pending;
intrmask = intrmask_regs[smp_processor_id()].intrmask;
pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;

- pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
- GIC_SH_PEND_31_0_OFS);
- intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
- GIC_SH_MASK_31_0_OFS);
+ pending_reg = GIC_REG(SHARED, GIC_SH_PEND_31_0);
+ intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK_31_0);

for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {
- GICREAD(*pending_abs, pending[i]);
- GICREAD(*intrmask_abs, intrmask[i]);
- pending_abs++;
- intrmask_abs++;
+ pending[i] = gic_read(pending_reg);
+ intrmask[i] = gic_read(intrmask_reg);
+ pending_reg += 0x4;
+ intrmask_reg += 0x4;
}

bitmap_and(pending, pending, intrmask, gic_shared_intrs);
@@ -205,19 +271,19 @@ static unsigned int gic_get_int(void)

static void gic_mask_irq(struct irq_data *d)
{
- GIC_CLR_INTR_MASK(GIC_HWIRQ_TO_SHARED(d->hwirq));
+ gic_reset_mask(GIC_HWIRQ_TO_SHARED(d->hwirq));
}

static void gic_unmask_irq(struct irq_data *d)
{
- GIC_SET_INTR_MASK(GIC_HWIRQ_TO_SHARED(d->hwirq));
+ gic_set_mask(GIC_HWIRQ_TO_SHARED(d->hwirq));
}

static void gic_ack_irq(struct irq_data *d)
{
unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);

- GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+ gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
}

static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -229,34 +295,34 @@ 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);
- GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE);
- GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE);
+ gic_set_polarity(irq, GIC_POL_NEG);
+ 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);
- GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE);
- GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE);
+ gic_set_polarity(irq, GIC_POL_POS);
+ gic_set_trigger(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);
- GIC_SET_DUAL(irq, GIC_TRIG_DUAL_ENABLE);
+ gic_set_trigger(irq, GIC_TRIG_EDGE);
+ gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE);
is_edge = true;
break;
case IRQ_TYPE_LEVEL_LOW:
- GIC_SET_POLARITY(irq, GIC_POL_NEG);
- GIC_SET_TRIGGER(irq, GIC_TRIG_LEVEL);
- GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE);
+ gic_set_polarity(irq, GIC_POL_NEG);
+ 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);
- GIC_SET_TRIGGER(irq, GIC_TRIG_LEVEL);
- GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE);
+ gic_set_polarity(irq, GIC_POL_POS);
+ gic_set_trigger(irq, GIC_TRIG_LEVEL);
+ gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE);
is_edge = false;
break;
}
@@ -292,7 +358,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_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
+ gic_map_to_vpe(irq, first_cpu(tmp));

/* Update the pcpu_masks */
for (i = 0; i < NR_CPUS; i++)
@@ -331,8 +397,8 @@ static unsigned int gic_get_local_int(void)
{
unsigned long pending, masked;

- GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending);
- GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_MASK), masked);
+ pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
+ masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));

bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);

@@ -343,14 +409,14 @@ static void gic_mask_local_irq(struct irq_data *d)
{
int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);

- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
}

static void gic_unmask_local_irq(struct irq_data *d)
{
int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);

- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
}

static struct irq_chip gic_local_irq_controller = {
@@ -367,8 +433,8 @@ 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++) {
- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
}
spin_unlock_irqrestore(&gic_lock, flags);
}
@@ -381,8 +447,8 @@ 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++) {
- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
}
spin_unlock_irqrestore(&gic_lock, flags);
}
@@ -462,7 +528,7 @@ static __init void gic_ipi_init_one(unsigned int intr, int cpu,
GIC_SHARED_TO_HWIRQ(intr));
int i;

- GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
+ gic_map_to_vpe(intr, cpu);
for (i = 0; i < NR_CPUS; i++)
clear_bit(intr, pcpu_masks[i].pcpu_mask);
set_bit(intr, pcpu_masks[cpu].pcpu_mask);
@@ -500,19 +566,19 @@ static void __init gic_basic_init(void)

/* Setup defaults */
for (i = 0; i < gic_shared_intrs; i++) {
- GIC_SET_POLARITY(i, GIC_POL_POS);
- GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
- GIC_CLR_INTR_MASK(i);
+ gic_set_polarity(i, GIC_POL_POS);
+ gic_set_trigger(i, GIC_TRIG_LEVEL);
+ gic_reset_mask(i);
}

for (i = 0; i < gic_vpes; i++) {
unsigned int j;

- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
if (!gic_local_irq_is_routable(j))
continue;
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
}
}
}
@@ -548,29 +614,29 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
for (i = 0; i < gic_vpes; i++) {
u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin;

- GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);

switch (intr) {
case GIC_LOCAL_INT_WD:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
break;
case GIC_LOCAL_INT_COMPARE:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val);
break;
case GIC_LOCAL_INT_TIMER:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val);
break;
case GIC_LOCAL_INT_PERFCTR:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val);
break;
case GIC_LOCAL_INT_SWINT0:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val);
break;
case GIC_LOCAL_INT_SWINT1:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val);
break;
case GIC_LOCAL_INT_FDC:
- GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
break;
default:
pr_err("Invalid local IRQ %d\n", intr);
@@ -593,10 +659,9 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
handle_level_irq);

spin_lock_irqsave(&gic_lock, flags);
- GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
- GIC_MAP_TO_PIN_MSK | gic_cpu_pin);
+ gic_map_to_pin(intr, gic_cpu_pin);
/* Map to VPE 0 by default */
- GIC_SH_MAP_TO_VPE_SMASK(intr, 0);
+ gic_map_to_vpe(intr, 0);
set_bit(intr, pcpu_masks[0].pcpu_mask);
spin_unlock_irqrestore(&gic_lock, flags);

@@ -622,10 +687,9 @@ void __init gic_init(unsigned long gic_base_addr,
{
unsigned int gicconfig;

- _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
- gic_addrspace_size);
+ gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);

- GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
+ 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);
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:54 UTC
Permalink
Remove duplicate #defines and unnecessary #includes, fix parenthesization,
and re-order register definitions in ascending order.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/irqchip/irq-mips-gic.c | 4 +-
include/linux/irqchip/mips-gic.h | 129 ++++++++-------------------------------
2 files changed, 29 insertions(+), 104 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 64a9729..adcb9b2 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -253,8 +253,8 @@ static unsigned int gic_get_int(void)
intrmask = intrmask_regs[smp_processor_id()].intrmask;
pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;

- pending_reg = GIC_REG(SHARED, GIC_SH_PEND_31_0);
- intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK_31_0);
+ 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);
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index 285944c..0350eff 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -4,17 +4,11 @@
* for more details.
*
* Copyright (C) 2000, 07 MIPS Technologies, Inc.
- *
- * GIC Register Definitions
- *
*/
-#ifndef _ASM_GICREGS_H
-#define _ASM_GICREGS_H
-
-#include <linux/bitmap.h>
-#include <linux/threads.h>
+#ifndef __LINUX_IRQCHIP_MIPS_GIC_H
+#define __LINUX_IRQCHIP_MIPS_GIC_H

-#include <irq.h>
+#include <linux/clocksource.h>

#define GIC_MAX_INTRS 256

@@ -50,108 +44,42 @@
#define GIC_SH_COUNTER_63_32_OFS 0x0014
#define GIC_SH_REVISIONID_OFS 0x0020

-/* Interrupt Polarity */
-#define GIC_SH_POL_31_0_OFS 0x0100
-#define GIC_SH_POL_63_32_OFS 0x0104
-#define GIC_SH_POL_95_64_OFS 0x0108
-#define GIC_SH_POL_127_96_OFS 0x010c
-#define GIC_SH_POL_159_128_OFS 0x0110
-#define GIC_SH_POL_191_160_OFS 0x0114
-#define GIC_SH_POL_223_192_OFS 0x0118
-#define GIC_SH_POL_255_224_OFS 0x011c
-
-/* Edge/Level Triggering */
-#define GIC_SH_TRIG_31_0_OFS 0x0180
-#define GIC_SH_TRIG_63_32_OFS 0x0184
-#define GIC_SH_TRIG_95_64_OFS 0x0188
-#define GIC_SH_TRIG_127_96_OFS 0x018c
-#define GIC_SH_TRIG_159_128_OFS 0x0190
-#define GIC_SH_TRIG_191_160_OFS 0x0194
-#define GIC_SH_TRIG_223_192_OFS 0x0198
-#define GIC_SH_TRIG_255_224_OFS 0x019c
-
-/* Dual Edge Triggering */
-#define GIC_SH_DUAL_31_0_OFS 0x0200
-#define GIC_SH_DUAL_63_32_OFS 0x0204
-#define GIC_SH_DUAL_95_64_OFS 0x0208
-#define GIC_SH_DUAL_127_96_OFS 0x020c
-#define GIC_SH_DUAL_159_128_OFS 0x0210
-#define GIC_SH_DUAL_191_160_OFS 0x0214
-#define GIC_SH_DUAL_223_192_OFS 0x0218
-#define GIC_SH_DUAL_255_224_OFS 0x021c
+/* Convert an interrupt number to a byte offset/bit for multi-word registers */
+#define GIC_INTR_OFS(intr) (((intr) / 32) * 4)
+#define GIC_INTR_BIT(intr) ((intr) % 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
+
+/* 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

-/* Reset Mask - Disables Interrupt */
-#define GIC_SH_RMASK_31_0_OFS 0x0300
-#define GIC_SH_RMASK_63_32_OFS 0x0304
-#define GIC_SH_RMASK_95_64_OFS 0x0308
-#define GIC_SH_RMASK_127_96_OFS 0x030c
-#define GIC_SH_RMASK_159_128_OFS 0x0310
-#define GIC_SH_RMASK_191_160_OFS 0x0314
-#define GIC_SH_RMASK_223_192_OFS 0x0318
-#define GIC_SH_RMASK_255_224_OFS 0x031c
-
-/* Set Mask (WO) - Enables Interrupt */
-#define GIC_SH_SMASK_31_0_OFS 0x0380
-#define GIC_SH_SMASK_63_32_OFS 0x0384
-#define GIC_SH_SMASK_95_64_OFS 0x0388
-#define GIC_SH_SMASK_127_96_OFS 0x038c
-#define GIC_SH_SMASK_159_128_OFS 0x0390
-#define GIC_SH_SMASK_191_160_OFS 0x0394
-#define GIC_SH_SMASK_223_192_OFS 0x0398
-#define GIC_SH_SMASK_255_224_OFS 0x039c
+/* Mask manipulation */
+#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_31_0_OFS 0x0400
-#define GIC_SH_MASK_63_32_OFS 0x0404
-#define GIC_SH_MASK_95_64_OFS 0x0408
-#define GIC_SH_MASK_127_96_OFS 0x040c
-#define GIC_SH_MASK_159_128_OFS 0x0410
-#define GIC_SH_MASK_191_160_OFS 0x0414
-#define GIC_SH_MASK_223_192_OFS 0x0418
-#define GIC_SH_MASK_255_224_OFS 0x041c
+#define GIC_SH_MASK_OFS 0x0400

/* Pending Global Interrupts (RO) */
-#define GIC_SH_PEND_31_0_OFS 0x0480
-#define GIC_SH_PEND_63_32_OFS 0x0484
-#define GIC_SH_PEND_95_64_OFS 0x0488
-#define GIC_SH_PEND_127_96_OFS 0x048c
-#define GIC_SH_PEND_159_128_OFS 0x0490
-#define GIC_SH_PEND_191_160_OFS 0x0494
-#define GIC_SH_PEND_223_192_OFS 0x0498
-#define GIC_SH_PEND_255_224_OFS 0x049c
-
-#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
+#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))

-#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
-
/* 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))

-/* Convert an interrupt number to a byte offset/bit for multi-word registers */
-#define GIC_INTR_OFS(intr) (((intr) / 32)*4)
-#define GIC_INTR_BIT(intr) ((intr) % 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
-
-/* Dual edge triggering : Reset Value is always 0 */
-#define GIC_SH_SET_DUAL_OFS 0x0200
-
-/* Mask manipulation */
-#define GIC_SH_SMASK_OFS 0x0380
-#define GIC_SH_RMASK_OFS 0x0300
-
/* Register Map for Local Section */
#define GIC_VPE_CTL_OFS 0x0000
#define GIC_VPE_PEND_OFS 0x0004
@@ -200,8 +128,8 @@
#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_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)
@@ -278,10 +206,10 @@
#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)
+#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)
+#define GIC_PIN_TO_VEC_OFFSET 1

/* Local GIC interrupts. */
#define GIC_LOCAL_INT_WD 0 /* GIC watchdog */
@@ -301,9 +229,6 @@
#define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x))
#define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)

-#include <linux/clocksource.h>
-#include <linux/irq.h>
-
extern unsigned int gic_present;
extern unsigned int gic_frequency;

@@ -322,4 +247,4 @@ extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
extern unsigned int gic_get_timer_pending(void);
extern int gic_get_c0_compare_int(void);
extern int gic_get_c0_perfcount_int(void);
-#endif /* _ASM_GICREGS_H */
+#endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:53 UTC
Permalink
Now that the MIPS GIC irqchip lives in drivers/irqchip/, move
its header over to include/linux/irqchip/.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/include/asm/mips-boards/maltaint.h | 2 +-
arch/mips/include/asm/mips-boards/sead3int.h | 2 +-
arch/mips/kernel/cevt-gic.c | 2 +-
arch/mips/kernel/cevt-r4k.c | 2 +-
arch/mips/kernel/csrc-gic.c | 3 +--
arch/mips/kernel/smp-cmp.c | 2 +-
arch/mips/kernel/smp-cps.c | 2 +-
arch/mips/kernel/smp-gic.c | 2 +-
arch/mips/kernel/smp-mt.c | 2 +-
arch/mips/mti-malta/malta-int.c | 2 +-
arch/mips/mti-malta/malta-time.c | 2 +-
arch/mips/mti-sead3/sead3-ehci.c | 2 +-
arch/mips/mti-sead3/sead3-int.c | 2 +-
arch/mips/mti-sead3/sead3-net.c | 2 +-
arch/mips/mti-sead3/sead3-platform.c | 2 +-
arch/mips/mti-sead3/sead3-time.c | 2 +-
drivers/irqchip/irq-mips-gic.c | 2 +-
arch/mips/include/asm/gic.h => include/linux/irqchip/mips-gic.h | 0
18 files changed, 17 insertions(+), 18 deletions(-)
rename arch/mips/include/asm/gic.h => include/linux/irqchip/mips-gic.h (100%)

diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index 38b06a0..987ff58 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -10,7 +10,7 @@
#ifndef _MIPS_MALTAINT_H
#define _MIPS_MALTAINT_H

-#include <asm/gic.h>
+#include <linux/irqchip/mips-gic.h>

/*
* Interrupts 0..15 are used for Malta ISA compatible interrupts
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h
index 59d6c32..8932c7d 100644
--- a/arch/mips/include/asm/mips-boards/sead3int.h
+++ b/arch/mips/include/asm/mips-boards/sead3int.h
@@ -10,7 +10,7 @@
#ifndef _MIPS_SEAD3INT_H
#define _MIPS_SEAD3INT_H

-#include <asm/gic.h>
+#include <linux/irqchip/mips-gic.h>

/* SEAD-3 GIC address space definitions. */
#define GIC_BASE_ADDR 0x1b1c0000
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c
index 4f9262a..9caa68a 100644
--- a/arch/mips/kernel/cevt-gic.c
+++ b/arch/mips/kernel/cevt-gic.c
@@ -10,9 +10,9 @@
#include <linux/percpu.h>
#include <linux/smp.h>
#include <linux/irq.h>
+#include <linux/irqchip/mips-gic.h>

#include <asm/time.h>
-#include <asm/gic.h>
#include <asm/mips-boards/maltaint.h>

DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index fd0ef8d..6acaad0 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -11,10 +11,10 @@
#include <linux/percpu.h>
#include <linux/smp.h>
#include <linux/irq.h>
+#include <linux/irqchip/mips-gic.h>

#include <asm/time.h>
#include <asm/cevt-r4k.h>
-#include <asm/gic.h>

static int mips_next_event(unsigned long delta,
struct clock_event_device *evt)
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c
index ab615c6..0bf28e6 100644
--- a/arch/mips/kernel/csrc-gic.c
+++ b/arch/mips/kernel/csrc-gic.c
@@ -6,10 +6,9 @@
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/
#include <linux/init.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/time.h>

-#include <asm/gic.h>
-
static cycle_t gic_hpt_read(struct clocksource *cs)
{
return gic_read_count();
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index fc8a515..1e0a93c 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -24,6 +24,7 @@
#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>
@@ -37,7 +38,6 @@
#include <asm/mipsmtregs.h>
#include <asm/mips_mt.h>
#include <asm/amon.h>
-#include <asm/gic.h>

static void cmp_init_secondary(void)
{
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index cd20aca..bed7590 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -9,13 +9,13 @@
*/

#include <linux/io.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/types.h>

#include <asm/bcache.h>
-#include <asm/gic.h>
#include <asm/mips-cm.h>
#include <asm/mips-cpc.h>
#include <asm/mips_mt.h>
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c
index 3b21a96..5f0ab5b 100644
--- a/arch/mips/kernel/smp-gic.c
+++ b/arch/mips/kernel/smp-gic.c
@@ -12,9 +12,9 @@
* option) any later version.
*/

+#include <linux/irqchip/mips-gic.h>
#include <linux/printk.h>

-#include <asm/gic.h>
#include <asm/mips-cpc.h>
#include <asm/smp-ops.h>

diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index d60475f..ad86951 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/compiler.h>
#include <linux/smp.h>

@@ -34,7 +35,6 @@
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/mips_mt.h>
-#include <asm/gic.h>

static void __init smvp_copy_vpe_config(void)
{
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 864d482..6ea4033 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/kernel_stat.h>
#include <linux/kernel.h>
#include <linux/random.h>
@@ -33,7 +34,6 @@
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/msc01_pci.h>
#include <asm/msc01_ic.h>
-#include <asm/gic.h>
#include <asm/setup.h>
#include <asm/rtlx.h>

diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 39f3902..608655f 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -24,6 +24,7 @@
#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>

@@ -37,7 +38,6 @@
#include <asm/time.h>
#include <asm/mc146818-time.h>
#include <asm/msc01_ic.h>
-#include <asm/gic.h>

#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/maltaint.h>
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
index 4ddaa0f..014dd7b 100644
--- a/arch/mips/mti-sead3/sead3-ehci.c
+++ b/arch/mips/mti-sead3/sead3-ehci.c
@@ -9,8 +9,8 @@
#include <linux/irq.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/irqchip/mips-gic.h>

-#include <asm/gic.h>
#include <asm/mips-boards/sead3int.h>

struct resource ehci_resources[] = {
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
index 995c401..5c6b949 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -7,9 +7,9 @@
*/
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/io.h>

-#include <asm/gic.h>
#include <asm/irq_cpu.h>
#include <asm/setup.h>

diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
index c9f728a..46176b8 100644
--- a/arch/mips/mti-sead3/sead3-net.c
+++ b/arch/mips/mti-sead3/sead3-net.c
@@ -7,10 +7,10 @@
*/
#include <linux/module.h>
#include <linux/irq.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>

-#include <asm/gic.h>
#include <asm/mips-boards/sead3int.h>

static struct smsc911x_platform_config sead3_smsc911x_data = {
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c
index d9661eb..53ee6f1 100644
--- a/arch/mips/mti-sead3/sead3-platform.c
+++ b/arch/mips/mti-sead3/sead3-platform.c
@@ -7,9 +7,9 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/serial_8250.h>

-#include <asm/gic.h>
#include <asm/mips-boards/sead3int.h>

#define UART(base) \
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c
index fd40de3..ec1dd24 100644
--- a/arch/mips/mti-sead3/sead3-time.c
+++ b/arch/mips/mti-sead3/sead3-time.c
@@ -6,9 +6,9 @@
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/
#include <linux/init.h>
+#include <linux/irqchip/mips-gic.h>

#include <asm/cpu.h>
-#include <asm/gic.h>
#include <asm/setup.h>
#include <asm/time.h>
#include <asm/irq.h>
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index afa3663..64a9729 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -9,13 +9,13 @@
#include <linux/bitmap.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irqchip/mips-gic.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/clocksource.h>

#include <asm/io.h>
-#include <asm/gic.h>
#include <asm/setup.h>
#include <asm/traps.h>
#include <linux/hardirq.h>
diff --git a/arch/mips/include/asm/gic.h b/include/linux/irqchip/mips-gic.h
similarity index 100%
rename from arch/mips/include/asm/gic.h
rename to include/linux/irqchip/mips-gic.h
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:57 UTC
Permalink
Use the GIC_SH_WEDGE_{SET,CLR} macros provided by mips-gic.h.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/irqchip/irq-mips-gic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 188760c..165cf1e 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -206,7 +206,7 @@ static void gic_bind_eic_interrupt(int irq, int set)

void gic_send_ipi(unsigned int intr)
{
- gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
+ gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(intr));
}

int gic_get_c0_compare_int(void)
@@ -270,7 +270,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), irq);
+ gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(irq));
}

static int gic_set_type(struct irq_data *d, unsigned int type)
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:58 UTC
Permalink
Move the GIC clocksource driver to drivers/clocksource/mips-gic-timer.c.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
arch/mips/Kconfig | 8 ++------
arch/mips/kernel/Makefile | 1 -
arch/mips/mti-malta/malta-time.c | 2 +-
drivers/clocksource/Kconfig | 4 ++++
drivers/clocksource/Makefile | 1 +
.../kernel/csrc-gic.c => drivers/clocksource/mips-gic-timer.c | 0
drivers/irqchip/irq-mips-gic.c | 2 +-
7 files changed, 9 insertions(+), 9 deletions(-)
rename arch/mips/kernel/csrc-gic.c => drivers/clocksource/mips-gic-timer.c (100%)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4195267..5b1d44b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -315,7 +315,7 @@ config MIPS_MALTA
select BOOT_RAW
select CEVT_R4K
select CSRC_R4K
- select CSRC_GIC
+ select CLKSRC_MIPS_GIC
select DMA_MAYBE_COHERENT
select GENERIC_ISA_DMA
select HAVE_PCSPKR_PLATFORM
@@ -357,7 +357,7 @@ config MIPS_SEAD3
select BUILTIN_DTB
select CEVT_R4K
select CSRC_R4K
- select CSRC_GIC
+ select CLKSRC_MIPS_GIC
select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI
select DMA_NONCOHERENT
@@ -926,10 +926,6 @@ config CSRC_IOASIC
config CSRC_R4K
bool

-config CSRC_GIC
- select MIPS_CM
- bool
-
config CSRC_SB1250
bool

diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 3982e51..3d1ea51 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -23,7 +23,6 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
-obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 608655f..028fae0 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -183,7 +183,7 @@ void __init plat_time_init(void)
freq = freqround(gic_frequency, 5000);
printk("GIC frequency %d.%02d MHz\n", freq/1000000,
(freq%1000000)*100/1000000);
-#ifdef CONFIG_CSRC_GIC
+#ifdef CONFIG_CLKSRC_MIPS_GIC
gic_clocksource_init(gic_frequency);
#endif
}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9042060..cb7e7f4 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -223,4 +223,8 @@ config CLKSRC_VERSATILE
ARM Versatile, RealView and Versatile Express reference
platforms.

+config CLKSRC_MIPS_GIC
+ bool
+ depends on MIPS_GIC
+
endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 756f6f1..e23fc2d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -46,3 +46,4 @@ obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o
+obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
diff --git a/arch/mips/kernel/csrc-gic.c b/drivers/clocksource/mips-gic-timer.c
similarity index 100%
rename from arch/mips/kernel/csrc-gic.c
rename to drivers/clocksource/mips-gic-timer.c
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 165cf1e..99687ed 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -103,7 +103,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
}

-#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC)
+#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC)
cycle_t gic_read_count(void)
{
unsigned int hi, hi2, lo;
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:55 UTC
Permalink
Sort the #includes and remove those which are unnecessary.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/irqchip/irq-mips-gic.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index adcb9b2..a1ccde6 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -7,19 +7,16 @@
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/
#include <linux/bitmap.h>
+#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/irqchip/mips-gic.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/irq.h>
-#include <linux/clocksource.h>

-#include <asm/io.h>
#include <asm/setup.h>
#include <asm/traps.h>
-#include <linux/hardirq.h>
-#include <asm-generic/bitops/find.h>

unsigned int gic_frequency;
unsigned int gic_present;
--
2.1.0.rc2.206.gedb03e5
Andrew Bresticker
2014-10-20 19:03:56 UTC
Permalink
There's no reason for the pending and masked interrupt bitmasks
to be global. Just declare them on the stack in gic_get_int()
since they only consume (256*2)/8 = 64 bytes.

Signed-off-by: Andrew Bresticker <***@chromium.org>
---
drivers/irqchip/irq-mips-gic.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index a1ccde6..188760c 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -25,18 +25,8 @@ struct gic_pcpu_mask {
DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
};

-struct gic_pending_regs {
- DECLARE_BITMAP(pending, GIC_MAX_INTRS);
-};
-
-struct gic_intrmask_regs {
- DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
-};
-
static void __iomem *gic_base;
static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
-static struct gic_pending_regs pending_regs[NR_CPUS];
-static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
static DEFINE_SPINLOCK(gic_lock);
static struct irq_domain *gic_irq_domain;
static int gic_shared_intrs;
@@ -242,12 +232,12 @@ int gic_get_c0_perfcount_int(void)
static unsigned int gic_get_int(void)
{
unsigned int i;
- unsigned long *pending, *intrmask, *pcpu_mask;
+ 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 */
- pending = pending_regs[smp_processor_id()].pending;
- intrmask = intrmask_regs[smp_processor_id()].intrmask;
pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;

pending_reg = GIC_REG(SHARED, GIC_SH_PEND);
--
2.1.0.rc2.206.gedb03e5
Qais Yousef
2014-10-22 11:03:16 UTC
Permalink
Post by Andrew Bresticker
- Patches 1 through 5 get rid of the ugly REG() macros and instead use
proper iomem accessors.
- Patches 6 and 7 move the GIC header to linux/irqchip/ and clean it up.
- Patches 8 through 10 are misc. GIC irqchip cleanups.
- Patches 11 and 12 combine the GIC clocksource and clockevent drivers and
move them to drivers/clocksource/.
- Patches 13 through 19 are various cleanups for the GIC clocksource driver.
Boot tested on Malta and (with additional out-of-tree patches) a platform
based on the IMG Pistachio SoC. Build tested for SEAD-3.
I used your github tree to boot test this on sead3 and it worked fine.

Except for the one comment I had, feel free to add my
tested-and-reviewed by.

Nice work :)

Qais
Post by Andrew Bresticker
Based on 3.18-rc1 + part 1 of my GIC cleanup series [0]. A tree with both
https://github.com/abrestic/linux/commits/mips-gic-cleanup-pt2-v1
[0] https://lkml.org/lkml/2014/9/18/487
MIPS: Malta: Use gic_read_count() to read GIC timer
irqchip: mips-gic: Export function to read counter width
MIPS: sead3: Stop using GIC REG macros
MIPS: Malta: Stop using GIC REG macros
irqchip: mips-gic: Use proper iomem accessors
MIPS: Move gic.h to include/linux/irqchip/mips-gic.h
irqchip: mips-gic: Clean up header file
irqchip: mips-gic: Clean up #includes
irqchip: mips-gic: Remove gic_{pending,itrmask}_regs
irqchip: mips-gic: Use GIC_SH_WEDGE_{SET,CLR} macros
MIPS: Move GIC clocksource driver to drivers/clocksource/
clocksource: mips-gic: Combine with GIC clockevent driver
clocksource: mips-gic: Staticize local symbols
clocksource: mips-gic: Move gic_frequency to clocksource driver
clocksource: mips-gic: Remove gic_event_handler
clocksource: mips-gic: Use percpu_dev_id
clocksource: mips-gic: Use CPU notifiers to setup the timer
clocksource: mips-gic: Use clockevents_config_and_register
clocksource: mips-gic: Bump up rating of GIC timer
arch/mips/Kconfig | 21 +-
arch/mips/include/asm/mips-boards/maltaint.h | 2 +-
arch/mips/include/asm/mips-boards/sead3int.h | 2 +-
arch/mips/include/asm/time.h | 5 +-
arch/mips/kernel/Makefile | 2 -
arch/mips/kernel/cevt-gic.c | 103 ---------
arch/mips/kernel/cevt-r4k.c | 2 +-
arch/mips/kernel/csrc-gic.c | 40 ----
arch/mips/kernel/smp-cmp.c | 2 +-
arch/mips/kernel/smp-cps.c | 2 +-
arch/mips/kernel/smp-gic.c | 2 +-
arch/mips/kernel/smp-mt.c | 2 +-
arch/mips/mti-malta/malta-int.c | 15 +-
arch/mips/mti-malta/malta-time.c | 20 +-
arch/mips/mti-sead3/sead3-ehci.c | 2 +-
arch/mips/mti-sead3/sead3-int.c | 9 +-
arch/mips/mti-sead3/sead3-net.c | 2 +-
arch/mips/mti-sead3/sead3-platform.c | 2 +-
arch/mips/mti-sead3/sead3-time.c | 2 +-
drivers/clocksource/Kconfig | 4 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/mips-gic-timer.c | 139 ++++++++++++
drivers/irqchip/irq-mips-gic.c | 243 +++++++++++++--------
.../asm/gic.h => include/linux/irqchip/mips-gic.h | 203 +++--------------
24 files changed, 363 insertions(+), 464 deletions(-)
delete mode 100644 arch/mips/kernel/cevt-gic.c
delete mode 100644 arch/mips/kernel/csrc-gic.c
create mode 100644 drivers/clocksource/mips-gic-timer.c
rename arch/mips/include/asm/gic.h => include/linux/irqchip/mips-gic.h (61%)
Loading...