Skip to content

Commit

Permalink
Merge tag 'irqchip-4.10' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/maz/arm-platforms into irq/core

Pull irqchip updates for 4.10 from Marc Zyngier:

- xylinx interrupt controller made architecture agnostic
  (microblaze, ppc, mips)
- GICv3 ITS now supported on 32bit ARM (mostly useful
  for virtual machines)
- Some arm64 GICv3 cleanups
  • Loading branch information
Thomas Gleixner committed Nov 29, 2016
2 parents 4e20156 + 8328255 commit 2cae3a1
Show file tree
Hide file tree
Showing 19 changed files with 376 additions and 489 deletions.
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ config ARCH_VIRT
select ARM_GIC
select ARM_GIC_V2M if PCI
select ARM_GIC_V3
select ARM_GIC_V3_ITS if PCI
select ARM_PSCI
select HAVE_ARM_ARCH_TIMER

Expand Down
54 changes: 47 additions & 7 deletions arch/arm/include/asm/arch_gicv3.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <linux/io.h>
#include <asm/barrier.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>

#define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)
Expand Down Expand Up @@ -230,19 +231,14 @@ static inline void gic_write_bpr1(u32 val)
* AArch32, since the syndrome register doesn't provide any information for
* them.
* Consequently, the following IO helpers use 32bit accesses.
*
* There are only two registers that need 64bit accesses in this driver:
* - GICD_IROUTERn, contain the affinity values associated to each interrupt.
* The upper-word (aff3) will always be 0, so there is no need for a lock.
* - GICR_TYPER is an ID register and doesn't need atomicity.
*/
static inline void gic_write_irouter(u64 val, volatile void __iomem *addr)
static inline void __gic_writeq_nonatomic(u64 val, volatile void __iomem *addr)
{
writel_relaxed((u32)val, addr);
writel_relaxed((u32)(val >> 32), addr + 4);
}

static inline u64 gic_read_typer(const volatile void __iomem *addr)
static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
{
u64 val;

Expand All @@ -251,5 +247,49 @@ static inline u64 gic_read_typer(const volatile void __iomem *addr)
return val;
}

#define gic_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l))

/*
* GICD_IROUTERn, contain the affinity values associated to each interrupt.
* The upper-word (aff3) will always be 0, so there is no need for a lock.
*/
#define gic_write_irouter(v, c) __gic_writeq_nonatomic(v, c)

/*
* GICR_TYPER is an ID register and doesn't need atomicity.
*/
#define gic_read_typer(c) __gic_readq_nonatomic(c)

/*
* GITS_BASER - hi and lo bits may be accessed independently.
*/
#define gits_read_baser(c) __gic_readq_nonatomic(c)
#define gits_write_baser(v, c) __gic_writeq_nonatomic(v, c)

/*
* GICR_PENDBASER and GICR_PROPBASE are changed with LPIs disabled, so they
* won't be being used during any updates and can be changed non-atomically
*/
#define gicr_read_propbaser(c) __gic_readq_nonatomic(c)
#define gicr_write_propbaser(v, c) __gic_writeq_nonatomic(v, c)
#define gicr_read_pendbaser(c) __gic_readq_nonatomic(c)
#define gicr_write_pendbaser(v, c) __gic_writeq_nonatomic(v, c)

/*
* GITS_TYPER is an ID register and doesn't need atomicity.
*/
#define gits_read_typer(c) __gic_readq_nonatomic(c)

/*
* GITS_CBASER - hi and lo bits may be accessed independently.
*/
#define gits_read_cbaser(c) __gic_readq_nonatomic(c)
#define gits_write_cbaser(v, c) __gic_writeq_nonatomic(v, c)

/*
* GITS_CWRITER - hi and lo bits may be accessed independently.
*/
#define gits_write_cwriter(v, c) __gic_writeq_nonatomic(v, c)

#endif /* !__ASSEMBLY__ */
#endif /* !__ASM_ARCH_GICV3_H */
61 changes: 31 additions & 30 deletions arch/arm64/include/asm/arch_gicv3.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,10 @@

#include <linux/stringify.h>
#include <asm/barrier.h>
#include <asm/cacheflush.h>

#define read_gicreg(r) \
({ \
u64 reg; \
asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
reg; \
})

#define write_gicreg(v,r) \
do { \
u64 __val = (v); \
asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
} while (0)
#define read_gicreg read_sysreg_s
#define write_gicreg write_sysreg_s

/*
* Low-level accessors
Expand All @@ -102,21 +93,21 @@

static inline void gic_write_eoir(u32 irq)
{
asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" ((u64)irq));
write_sysreg_s(irq, ICC_EOIR1_EL1);
isb();
}

static inline void gic_write_dir(u32 irq)
{
asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" ((u64)irq));
write_sysreg_s(irq, ICC_DIR_EL1);
isb();
}

static inline u64 gic_read_iar_common(void)
{
u64 irqstat;

asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
irqstat = read_sysreg_s(ICC_IAR1_EL1);
dsb(sy);
return irqstat;
}
Expand All @@ -132,50 +123,44 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
{
u64 irqstat;

asm volatile(
"nop;nop;nop;nop\n\t"
"nop;nop;nop;nop\n\t"
"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
"nop;nop;nop;nop"
: "=r" (irqstat));
nops(8);
irqstat = read_sysreg_s(ICC_IAR1_EL1);
nops(4);
mb();

return irqstat;
}

static inline void gic_write_pmr(u32 val)
{
asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" ((u64)val));
write_sysreg_s(val, ICC_PMR_EL1);
}

static inline void gic_write_ctlr(u32 val)
{
asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" ((u64)val));
write_sysreg_s(val, ICC_CTLR_EL1);
isb();
}

static inline void gic_write_grpen1(u32 val)
{
asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" ((u64)val));
write_sysreg_s(val, ICC_GRPEN1_EL1);
isb();
}

static inline void gic_write_sgi1r(u64 val)
{
asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
write_sysreg_s(val, ICC_SGI1R_EL1);
}

static inline u32 gic_read_sre(void)
{
u64 val;

asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
return val;
return read_sysreg_s(ICC_SRE_EL1);
}

static inline void gic_write_sre(u32 val)
{
asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" ((u64)val));
write_sysreg_s(val, ICC_SRE_EL1);
isb();
}

Expand All @@ -187,5 +172,21 @@ static inline void gic_write_bpr1(u32 val)
#define gic_read_typer(c) readq_relaxed(c)
#define gic_write_irouter(v, c) writeq_relaxed(v, c)

#define gic_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l))

#define gits_read_baser(c) readq_relaxed(c)
#define gits_write_baser(v, c) writeq_relaxed(v, c)

#define gits_read_cbaser(c) readq_relaxed(c)
#define gits_write_cbaser(v, c) writeq_relaxed(v, c)

#define gits_write_cwriter(v, c) writeq_relaxed(v, c)

#define gicr_read_propbaser(c) readq_relaxed(c)
#define gicr_write_propbaser(v, c) writeq_relaxed(v, c)

#define gicr_write_pendbaser(v, c) writeq_relaxed(v, c)
#define gicr_read_pendbaser(c) readq_relaxed(c)

#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARCH_GICV3_H */
1 change: 1 addition & 0 deletions arch/microblaze/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ config MICROBLAZE
select HAVE_MEMBLOCK_NODE_MAP
select HAVE_OPROFILE
select IRQ_DOMAIN
select XILINX_INTC
select MODULES_USE_ELF_RELA
select OF
select OF_EARLY_FLATTREE
Expand Down
2 changes: 1 addition & 1 deletion arch/microblaze/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ struct pt_regs;
extern void do_IRQ(struct pt_regs *regs);

/* should be defined in each interrupt controller driver */
extern unsigned int get_irq(void);
extern unsigned int xintc_get_irq(void);

#endif /* _ASM_MICROBLAZE_IRQ_H */
2 changes: 1 addition & 1 deletion arch/microblaze/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ endif
extra-y := head.o vmlinux.lds

obj-y += dma.o exceptions.o \
hw_exception_handler.o intc.o irq.o \
hw_exception_handler.o irq.o \
platform.o process.o prom.o ptrace.o \
reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o

Expand Down
Loading

0 comments on commit 2cae3a1

Please sign in to comment.