Commit a4ee7bac authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arc-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull ARC updates from Vineet Gupta:

 - Intc imporvements [Yuriy]

 - VDK platform updates [Alexey]

* tag 'arc-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARC: [plat-*] ARC_HAS_COH_CACHES no longer relevant
  ARCv2: intc: Delete useless comments in Device Trees
  ARCv2: IDU-intc: Delete deprecated parameters in Device Trees
  ARCv2: IDU-intc: mask all common interrupts by default
  ARCv2: IDU-intc: Use build registers for getting numbers of interrupts
  ARCv2: intc: Set default priority for all core interrupts
  ARCv2: intc: Use runtime value of irq count for setting up intc
  ARCv2: intc: Rework the build time irq count information
  ARC: [intc-*]: confine NR_CPU_IRQS to intc code
  ARCv2: intc: Use ARC_REG_STATUS32 for addressing STATUS32 reg
  arc: vdk: Add support of UIO
  arc: vdk: Add support of MMC controller
  arc: vdk: Disable halt on reset
parents 38705613 8ba605b6
...@@ -8,15 +8,11 @@ Properties: ...@@ -8,15 +8,11 @@ Properties:
- compatible: "snps,archs-idu-intc" - compatible: "snps,archs-idu-intc"
- interrupt-controller: This is an interrupt controller. - interrupt-controller: This is an interrupt controller.
- interrupt-parent: <reference to parent core intc> - interrupt-parent: <reference to parent core intc>
- #interrupt-cells: Must be <2>. - #interrupt-cells: Must be <1>.
- interrupts: <...> specifies the upstream core irqs
First cell specifies the "common" IRQ from peripheral to IDU Value of the cell specifies the "common" IRQ from peripheral to IDU. Number N
Second cell specifies the irq distribution mode to cores of the particular interrupt line of IDU corresponds to the line N+24 of the
0=Round Robin; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 core interrupt controller.
The second cell in interrupts property is deprecated and may be ignored by
the kernel.
intc accessed via the special ARC AUX register interface, hence "reg" property intc accessed via the special ARC AUX register interface, hence "reg" property
is not specified. is not specified.
...@@ -32,18 +28,10 @@ Example: ...@@ -32,18 +28,10 @@ Example:
compatible = "snps,archs-idu-intc"; compatible = "snps,archs-idu-intc";
interrupt-controller; interrupt-controller;
interrupt-parent = <&core_intc>; interrupt-parent = <&core_intc>;
#interrupt-cells = <1>;
/*
* <hwirq distribution>
* distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3
*/
#interrupt-cells = <2>;
/* upstream core irqs: downstream these are "COMMON" irq 0,1.. */
interrupts = <24 25 26 27 28 29 30 31>;
}; };
some_device: serial@c0fc1000 { some_device: serial@c0fc1000 {
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <0 0>; /* upstream idu IRQ #24, Round Robin */ interrupts = <0>; /* upstream idu IRQ #24 */
}; };
...@@ -180,16 +180,12 @@ config CPU_BIG_ENDIAN ...@@ -180,16 +180,12 @@ config CPU_BIG_ENDIAN
config SMP config SMP
bool "Symmetric Multi-Processing" bool "Symmetric Multi-Processing"
default n default n
select ARC_HAS_COH_CACHES if ISA_ARCV2
select ARC_MCIP if ISA_ARCV2 select ARC_MCIP if ISA_ARCV2
help help
This enables support for systems with more than one CPU. This enables support for systems with more than one CPU.
if SMP if SMP
config ARC_HAS_COH_CACHES
def_bool n
config NR_CPUS config NR_CPUS
int "Maximum number of CPUs (2-4096)" int "Maximum number of CPUs (2-4096)"
range 2 4096 range 2 4096
...@@ -219,8 +215,6 @@ config ARC_MCIP ...@@ -219,8 +215,6 @@ config ARC_MCIP
menuconfig ARC_CACHE menuconfig ARC_CACHE
bool "Enable Cache Support" bool "Enable Cache Support"
default y default y
# if SMP, cache enabled ONLY if ARC implementation has cache coherency
depends on !SMP || ARC_HAS_COH_CACHES
if ARC_CACHE if ARC_CACHE
...@@ -412,17 +406,6 @@ config ARC_HAS_DIV_REM ...@@ -412,17 +406,6 @@ config ARC_HAS_DIV_REM
bool "Insn: div, divu, rem, remu" bool "Insn: div, divu, rem, remu"
default y default y
config ARC_NUMBER_OF_INTERRUPTS
int "Number of interrupts"
range 8 240
default 32
help
This defines the number of interrupts on the ARCv2HS core.
It affects the size of vector table.
The initial 8 IRQs are fixed (Timer, ICI etc) and although configurable
in hardware, it keep things simple for Linux to assume they are always
present.
endif # ISA_ARCV2 endif # ISA_ARCV2
endmenu # "ARC CPU Configuration" endmenu # "ARC CPU Configuration"
......
...@@ -40,18 +40,7 @@ idu_intc: idu-interrupt-controller { ...@@ -40,18 +40,7 @@ idu_intc: idu-interrupt-controller {
compatible = "snps,archs-idu-intc"; compatible = "snps,archs-idu-intc";
interrupt-controller; interrupt-controller;
interrupt-parent = <&core_intc>; interrupt-parent = <&core_intc>;
#interrupt-cells = <1>;
/*
* <hwirq distribution>
* distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3
*/
#interrupt-cells = <2>;
/*
* upstream irqs to core intc - downstream these are
* "COMMON" irq 0,1..
*/
interrupts = <24 25>;
}; };
/* /*
...@@ -73,12 +62,7 @@ ictl_intc: gpio-controller@0 { ...@@ -73,12 +62,7 @@ ictl_intc: gpio-controller@0 {
interrupt-controller; interrupt-controller;
#interrupt-cells = <2>; #interrupt-cells = <2>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <1>;
/*
* cmn irq 1 -> cpu irq 25
* Distribute to cpu0 only
*/
interrupts = <1 1>;
}; };
}; };
...@@ -119,8 +103,7 @@ mb_intc: dw-apb-ictl@0xe0012000 { ...@@ -119,8 +103,7 @@ mb_intc: dw-apb-ictl@0xe0012000 {
reg = < 0xe0012000 0x200 >; reg = < 0xe0012000 0x200 >;
interrupt-controller; interrupt-controller;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <0 1>; /* cmn irq 0 -> cpu irq 24 interrupts = <0>;
distribute to cpu0 only */
}; };
memory { memory {
......
...@@ -47,18 +47,13 @@ core_intc: interrupt-controller { ...@@ -47,18 +47,13 @@ core_intc: interrupt-controller {
compatible = "snps,archs-intc"; compatible = "snps,archs-intc";
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
/* interrupts = <16 17 18 19 20 21 22 23 24 25>; */
}; };
idu_intc: idu-interrupt-controller { idu_intc: idu-interrupt-controller {
compatible = "snps,archs-idu-intc"; compatible = "snps,archs-idu-intc";
interrupt-controller; interrupt-controller;
interrupt-parent = <&core_intc>; interrupt-parent = <&core_intc>;
/* <hwirq distribution> #interrupt-cells = <1>;
distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 */
#interrupt-cells = <2>;
interrupts = <24 25 26 27 28 29 30 31>;
}; };
uart0: serial@f0000000 { uart0: serial@f0000000 {
...@@ -66,9 +61,7 @@ uart0: serial@f0000000 { ...@@ -66,9 +61,7 @@ uart0: serial@f0000000 {
compatible = "ns16550a"; compatible = "ns16550a";
reg = <0xf0000000 0x2000>; reg = <0xf0000000 0x2000>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
/* interrupts = <0 1>; DEST=1*/ interrupts = <0>;
/* interrupts = <0 2>; DEST=2*/
interrupts = <0 0>; /* RR*/
clock-frequency = <50000000>; clock-frequency = <50000000>;
baud = <115200>; baud = <115200>;
reg-shift = <2>; reg-shift = <2>;
......
...@@ -46,25 +46,14 @@ idu_intc: idu-interrupt-controller { ...@@ -46,25 +46,14 @@ idu_intc: idu-interrupt-controller {
compatible = "snps,archs-idu-intc"; compatible = "snps,archs-idu-intc";
interrupt-controller; interrupt-controller;
interrupt-parent = <&core_intc>; interrupt-parent = <&core_intc>;
#interrupt-cells = <1>;
/*
* <hwirq distribution>
* distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3
*/
#interrupt-cells = <2>;
/*
* upstream irqs to core intc - downstream these are
* "COMMON" irq 0,1..
*/
interrupts = <24 25 26 27 28 29 30 31>;
}; };
arcuart0: serial@c0fc1000 { arcuart0: serial@c0fc1000 {
compatible = "snps,arc-uart"; compatible = "snps,arc-uart";
reg = <0xc0fc1000 0x100>; reg = <0xc0fc1000 0x100>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <0 0>; interrupts = <0>;
clock-frequency = <80000000>; clock-frequency = <80000000>;
current-speed = <115200>; current-speed = <115200>;
status = "okay"; status = "okay";
......
...@@ -43,33 +43,20 @@ core_intc: core-interrupt-controller { ...@@ -43,33 +43,20 @@ core_intc: core-interrupt-controller {
compatible = "snps,archs-intc"; compatible = "snps,archs-intc";
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
/* interrupts = <16 17 18 19 20 21 22 23 24 25>; */
}; };
idu_intc: idu-interrupt-controller { idu_intc: idu-interrupt-controller {
compatible = "snps,archs-idu-intc"; compatible = "snps,archs-idu-intc";
interrupt-controller; interrupt-controller;
interrupt-parent = <&core_intc>; interrupt-parent = <&core_intc>;
#interrupt-cells = <1>;
/*
* <hwirq distribution>
* distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3
*/
#interrupt-cells = <2>;
/*
* upstream irqs to core intc - downstream these are
* "COMMON" irq 0,1..
*/
interrupts = <24 25 26 27 28 29 30 31>;
}; };
uart0: serial@f0000000 { uart0: serial@f0000000 {
compatible = "ns8250"; compatible = "ns8250";
reg = <0xf0000000 0x2000>; reg = <0xf0000000 0x2000>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <0 0>; /* cmn irq 0 -> cpu irq 24 interrupts = <0>;
RR distribute to all cpus */
clock-frequency = <3686400>; clock-frequency = <3686400>;
baud = <115200>; baud = <115200>;
reg-shift = <2>; reg-shift = <2>;
...@@ -93,7 +80,7 @@ pgu@f9000000 { ...@@ -93,7 +80,7 @@ pgu@f9000000 {
ps2: ps2@f9001000 { ps2: ps2@f9001000 {
compatible = "snps,arc_ps2"; compatible = "snps,arc_ps2";
reg = <0xf9000400 0x14>; reg = <0xf9000400 0x14>;
interrupts = <3 0>; interrupts = <3>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupt-names = "arc_ps2_irq"; interrupt-names = "arc_ps2_irq";
}; };
...@@ -102,7 +89,7 @@ eth0: ethernet@f0003000 { ...@@ -102,7 +89,7 @@ eth0: ethernet@f0003000 {
compatible = "ezchip,nps-mgt-enet"; compatible = "ezchip,nps-mgt-enet";
reg = <0xf0003000 0x44>; reg = <0xf0003000 0x44>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <1 2>; interrupts = <1>;
}; };
arcpct0: pct { arcpct0: pct {
......
...@@ -41,14 +41,7 @@ idu_intc: idu-interrupt-controller { ...@@ -41,14 +41,7 @@ idu_intc: idu-interrupt-controller {
compatible = "snps,archs-idu-intc"; compatible = "snps,archs-idu-intc";
interrupt-controller; interrupt-controller;
interrupt-parent = <&core_intc>; interrupt-parent = <&core_intc>;
#interrupt-cells = <1>;
/*
* <hwirq distribution>
* distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3
*/
#interrupt-cells = <2>;
interrupts = <24 25 26 27>;
}; };
debug_uart: dw-apb-uart@0x5000 { debug_uart: dw-apb-uart@0x5000 {
...@@ -56,7 +49,7 @@ debug_uart: dw-apb-uart@0x5000 { ...@@ -56,7 +49,7 @@ debug_uart: dw-apb-uart@0x5000 {
reg = <0x5000 0x100>; reg = <0x5000 0x100>;
clock-frequency = <2403200>; clock-frequency = <2403200>;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = <2 0>; interrupts = <2>;
baud = <115200>; baud = <115200>;
reg-shift = <2>; reg-shift = <2>;
reg-io-width = <4>; reg-io-width = <4>;
...@@ -70,7 +63,7 @@ mb_intc: dw-apb-ictl@0xe0012000 { ...@@ -70,7 +63,7 @@ mb_intc: dw-apb-ictl@0xe0012000 {
reg = < 0xe0012000 0x200 >; reg = < 0xe0012000 0x200 >;
interrupt-controller; interrupt-controller;
interrupt-parent = <&idu_intc>; interrupt-parent = <&idu_intc>;
interrupts = < 0 0 >; interrupts = <0>;
}; };
memory { memory {
......
...@@ -23,6 +23,12 @@ apbclk: apbclk { ...@@ -23,6 +23,12 @@ apbclk: apbclk {
#clock-cells = <0>; #clock-cells = <0>;
}; };
mmcclk: mmcclk {
compatible = "fixed-clock";
clock-frequency = <50000000>;
#clock-cells = <0>;
};
pguclk: pguclk { pguclk: pguclk {
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock"; compatible = "fixed-clock";
...@@ -94,5 +100,25 @@ ps2: ps2@e0017400 { ...@@ -94,5 +100,25 @@ ps2: ps2@e0017400 {
interrupts = <5>; interrupts = <5>;
interrupt-names = "arc_ps2_irq"; interrupt-names = "arc_ps2_irq";
}; };
mmc@0x15000 {
compatible = "snps,dw-mshc";
reg = <0x15000 0x400>;
num-slots = <1>;
fifo-depth = <1024>;
card-detect-delay = <200>;
clocks = <&apbclk>, <&mmcclk>;
clock-names = "biu", "ciu";
interrupts = <7>;
bus-width = <4>;
};
/* Embedded Vision subsystem UIO mappings; only relevant for EV VDK */
uio_ev: uio@0xD0000000 {
compatible = "generic-uio";
reg = <0xD0000000 0x2000 0xD1000000 0x2000 0x90000000 0x10000000 0xC0000000 0x10000000>;
reg-names = "ev_gsa", "ev_ctrl", "ev_shared_mem", "ev_code_mem";
interrupts = <23>;
};
}; };
}; };
...@@ -16,6 +16,7 @@ CONFIG_AXS103=y ...@@ -16,6 +16,7 @@ CONFIG_AXS103=y
CONFIG_ISA_ARCV2=y CONFIG_ISA_ARCV2=y
CONFIG_SMP=y CONFIG_SMP=y
# CONFIG_ARC_TIMERS_64BIT is not set # CONFIG_ARC_TIMERS_64BIT is not set
# CONFIG_ARC_SMP_HALT_ON_RESET is not set
CONFIG_ARC_UBOOT_SUPPORT=y CONFIG_ARC_UBOOT_SUPPORT=y
CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp" CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
...@@ -56,7 +57,6 @@ CONFIG_NATIONAL_PHY=y ...@@ -56,7 +57,6 @@ CONFIG_NATIONAL_PHY=y
CONFIG_MOUSE_PS2_TOUCHKIT=y CONFIG_MOUSE_PS2_TOUCHKIT=y
CONFIG_SERIO_ARC_PS2=y CONFIG_SERIO_ARC_PS2=y
# CONFIG_LEGACY_PTYS is not set # CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_DW=y
...@@ -78,9 +78,14 @@ CONFIG_USB_OHCI_HCD=y ...@@ -78,9 +78,14 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE=y
CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_DW=y
CONFIG_UIO=y
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_IOMMU_SUPPORT is not set # CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT3_FS=y CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y CONFIG_NTFS_FS=y
......
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
#define ARC_REG_CLUSTER_BCR 0xcf #define ARC_REG_CLUSTER_BCR 0xcf
#define ARC_REG_AUX_ICCM 0x208 /* ICCM Base Addr (ARCv2) */ #define ARC_REG_AUX_ICCM 0x208 /* ICCM Base Addr (ARCv2) */
/* Common for ARCompact and ARCv2 status register */
#define ARC_REG_STATUS32 0x0A
/* status32 Bits Positions */ /* status32 Bits Positions */
#define STATUS_AE_BIT 5 /* Exception active */ #define STATUS_AE_BIT 5 /* Exception active */
#define STATUS_DE_BIT 6 /* PC is in delay slot */ #define STATUS_DE_BIT 6 /* PC is in delay slot */
......
...@@ -9,13 +9,19 @@ ...@@ -9,13 +9,19 @@
#ifndef __ASM_ARC_IRQ_H #ifndef __ASM_ARC_IRQ_H
#define __ASM_ARC_IRQ_H #define __ASM_ARC_IRQ_H
#define NR_CPU_IRQS 32 /* number of interrupt lines of ARC770 CPU */ /*
#define NR_IRQS 128 /* allow some CPU external IRQ handling */ * ARCv2 can support 240 interrupts in the core interrupts controllers and
* 128 interrupts in IDU. Thus 512 virtual IRQs must be enough for most
* configurations of boards.
* This doesnt affect ARCompact, but we change it to same value
*/
#define NR_IRQS 512
/* Platform Independent IRQs */ /* Platform Independent IRQs */
#ifdef CONFIG_ISA_ARCV2 #ifdef CONFIG_ISA_ARCV2
#define IPI_IRQ 19 #define IPI_IRQ 19
#define SOFTIRQ_IRQ 21 #define SOFTIRQ_IRQ 21
#define FIRST_EXT_IRQ 24
#endif #endif
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
#include <asm/arcregs.h> #include <asm/arcregs.h>
#include <asm/irqflags.h> #include <asm/irqflags.h>
; A maximum number of supported interrupts in the core interrupt controller.
; This number is not equal to the maximum interrupt number (256) because
; first 16 lines are reserved for exceptions and are not configurable.
#define NR_CPU_IRQS 240
.cpu HS .cpu HS
#define VECTOR .word #define VECTOR .word
...@@ -52,7 +57,7 @@ VECTOR handle_interrupt ; unused ...@@ -52,7 +57,7 @@ VECTOR handle_interrupt ; unused
VECTOR handle_interrupt ; (23) unused VECTOR handle_interrupt ; (23) unused
# End of fixed IRQs # End of fixed IRQs
.rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8 .rept NR_CPU_IRQS - 8
VECTOR handle_interrupt VECTOR handle_interrupt
.endr .endr
......
...@@ -14,6 +14,16 @@ ...@@ -14,6 +14,16 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <asm/irq.h> #include <asm/irq.h>
#define NR_EXCEPTIONS 16
struct bcr_irq_arcv2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:3, firq:1, prio:4, exts:8, irqs:8, ver:8;
#else
unsigned int ver:8, irqs:8, exts:8, prio:4, firq:1, pad:3;
#endif
};
/* /*
* Early Hardware specific Interrupt setup * Early Hardware specific Interrupt setup
* -Called very early (start_kernel -> setup_arch -> setup_processor) * -Called very early (start_kernel -> setup_arch -> setup_processor)
...@@ -22,15 +32,8 @@ ...@@ -22,15 +32,8 @@
*/ */
void arc_init_IRQ(void) void arc_init_IRQ(void)
{ {
unsigned int tmp, irq_prio; unsigned int tmp, irq_prio, i;
struct bcr_irq_arcv2 irq_bcr;
struct irq_build {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:3, firq:1, prio:4, exts:8, irqs:8, ver:8;
#else
unsigned int ver:8, irqs:8, exts:8, prio:4, firq:1, pad:3;
#endif
} irq_bcr;
struct aux_irq_ctrl { struct aux_irq_ctrl {
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
...@@ -68,8 +71,18 @@ void arc_init_IRQ(void) ...@@ -68,8 +71,18 @@ void arc_init_IRQ(void)
irq_prio + 1, ARCV2_IRQ_DEF_PRIO, irq_prio + 1, ARCV2_IRQ_DEF_PRIO,
irq_bcr.firq ? " FIRQ (not used)":""); irq_bcr.firq ? " FIRQ (not used)":"");
/*
* Set a default priority for all available interrupts to prevent
* switching of register banks if Fast IRQ and multiple register banks
* are supported by CPU.
*/
for (i = NR_EXCEPTIONS; i < irq_bcr.irqs + NR_EXCEPTIONS; i++) {
write_aux_reg(AUX_IRQ_SELECT, i);
write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO);
}
/* setup status32, don't enable intr yet as kernel doesn't want */ /* setup status32, don't enable intr yet as kernel doesn't want */
tmp = read_aux_reg(0xa); tmp = read_aux_reg(ARC_REG_STATUS32);
tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1); tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1);
tmp &= ~STATUS_IE_MASK; tmp &= ~STATUS_IE_MASK;
asm volatile("kflag %0 \n"::"r"(tmp)); asm volatile("kflag %0 \n"::"r"(tmp));
...@@ -115,7 +128,7 @@ static int arcv2_irq_map(struct irq_domain *d, unsigned int irq, ...@@ -115,7 +128,7 @@ static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
* core intc IRQs [16, 23]: * core intc IRQs [16, 23]:
* Statically assigned always private-per-core (Timers, WDT, IPI, PCT) * Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
*/ */
if (hw < 24) { if (hw < FIRST_EXT_IRQ) {
/* /*
* A subsequent request_percpu_irq() fails if percpu_devid is * A subsequent request_percpu_irq() fails if percpu_devid is
* not set. That in turns sets NOAUTOEN, meaning each core needs * not set. That in turns sets NOAUTOEN, meaning each core needs
...@@ -140,11 +153,16 @@ static int __init ...@@ -140,11 +153,16 @@ static int __init
init_onchip_IRQ(struct device_node *intc, struct device_node *parent) init_onchip_IRQ(struct device_node *intc, struct device_node *parent)
{ {
struct irq_domain *root_domain; struct irq_domain *root_domain;
struct bcr_irq_arcv2 irq_bcr;
unsigned int nr_cpu_irqs;
READ_BCR(ARC_REG_IRQ_BCR, irq_bcr);
nr_cpu_irqs = irq_bcr.irqs + NR_EXCEPTIONS;
if (parent) if (parent)
panic("DeviceTree incore intc not a root irq controller\n"); panic("DeviceTree incore intc not a root irq controller\n");
root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, &arcv2_irq_ops, NULL); root_domain = irq_domain_add_linear(intc, nr_cpu_irqs, &arcv2_irq_ops, NULL);
if (!root_domain) if (!root_domain)
panic("root irq domain not avail\n"); panic("root irq domain not avail\n");
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <asm/irq.h> #include <asm/irq.h>
#define NR_CPU_IRQS 32 /* number of irq lines coming in */
#define TIMER0_IRQ 3 /* Fixed by ISA */ #define TIMER0_IRQ 3 /* Fixed by ISA */
/* /*
......
...@@ -156,15 +156,20 @@ static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl, ...@@ -156,15 +156,20 @@ static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl,
__mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word); __mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word);
} }
static void idu_irq_mask(struct irq_data *data) static void idu_irq_mask_raw(irq_hw_number_t hwirq)
{ {
unsigned long flags; unsigned long flags;
raw_spin_lock_irqsave(&mcip_lock, flags); raw_spin_lock_irqsave(&mcip_lock, flags);
__mcip_cmd_data(CMD_IDU_SET_MASK, data->hwirq, 1); __mcip_cmd_data(CMD_IDU_SET_MASK, hwirq, 1);
raw_spin_unlock_irqrestore(&mcip_lock, flags); raw_spin_unlock_irqrestore(&mcip_lock, flags);
} }
static void idu_irq_mask(struct irq_data *data)
{
idu_irq_mask_raw(data->hwirq);
}
static void idu_irq_unmask(struct irq_data *data) static void idu_irq_unmask(struct irq_data *data)
{ {
unsigned long flags; unsigned long flags;
...@@ -230,14 +235,12 @@ static struct irq_chip idu_irq_chip = { ...@@ -230,14 +235,12 @@ static struct irq_chip idu_irq_chip = {
}; };
static irq_hw_number_t idu_first_hwirq;
static void idu_cascade_isr(struct irq_desc *desc) static void idu_cascade_isr(struct irq_desc *desc)
{ {
struct irq_domain *idu_domain = irq_desc_get_handler_data(desc); struct irq_domain *idu_domain = irq_desc_get_handler_data(desc);
struct irq_chip *core_chip = irq_desc_get_chip(desc); struct irq_chip *core_chip = irq_desc_get_chip(desc);
irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc)); irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc));
irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq; irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ;
chained_irq_enter(core_chip, desc); chained_irq_enter(core_chip, desc);
generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
...@@ -252,23 +255,8 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t ...@@ -252,23 +255,8 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t
return 0; return 0;
} }
static int idu_irq_xlate(struct irq_domain *d, struct device_node *n,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type)
{
/*
* Ignore value of interrupt distribution mode for common interrupts in
* IDU which resides in intspec[1] since setting an affinity using value
* from Device Tree is deprecated in ARC.
*/
*out_hwirq = intspec[0];
*out_type = IRQ_TYPE_NONE;
return 0;
}
static const struct irq_domain_ops idu_irq_ops = { static const struct irq_domain_ops idu_irq_ops = {
.xlate = idu_irq_xlate, .xlate = irq_domain_xlate_onecell,
.map = idu_irq_map, .map = idu_irq_map,
}; };
...@@ -283,33 +271,37 @@ static int __init ...@@ -283,33 +271,37 @@ static int __init
idu_of_init(struct device_node *intc, struct device_node *parent) idu_of_init(struct device_node *intc, struct device_node *parent)
{ {
struct irq_domain *domain; struct irq_domain *domain;
/* Read IDU BCR to confirm nr_irqs */ int nr_irqs;
int nr_irqs = of_irq_count(intc);
int i, virq; int i, virq;
struct mcip_bcr mp; struct mcip_bcr mp;
struct mcip_idu_bcr idu_bcr;
READ_BCR(ARC_REG_MCIP_BCR, mp); READ_BCR(ARC_REG_MCIP_BCR, mp);
if (!mp.idu) if (!mp.idu)
panic("IDU not detected, but DeviceTree using it"); panic("IDU not detected, but DeviceTree using it");
pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs); READ_BCR(ARC_REG_MCIP_IDU_BCR, idu_bcr);
nr_irqs = mcip_idu_bcr_to_nr_irqs(idu_bcr);
pr_info("MCIP: IDU supports %u common irqs\n", nr_irqs);
domain = irq_domain_add_linear(intc, nr_irqs, &idu_irq_ops, NULL); domain = irq_domain_add_linear(intc, nr_irqs, &idu_irq_ops, NULL);
/* Parent interrupts (core-intc) are already mapped */ /* Parent interrupts (core-intc) are already mapped */
for (i = 0; i < nr_irqs; i++) { for (i = 0; i < nr_irqs; i++) {
/* Mask all common interrupts by default */
idu_irq_mask_raw(i);
/* /*
* Return parent uplink IRQs (towards core intc) 24,25,..... * Return parent uplink IRQs (towards core intc) 24,25,.....
* this step has been done before already * this step has been done before already
* however we need it to get the parent virq and set IDU handler * however we need it to get the parent virq and set IDU handler
* as first level isr * as first level isr
*/ */
virq = irq_of_parse_and_map(intc, i); virq = irq_create_mapping(NULL, i + FIRST_EXT_IRQ);
if (!i) BUG_ON(!virq);
idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq));
irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain); irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain);
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
menuconfig ARC_PLAT_EZNPS menuconfig ARC_PLAT_EZNPS
bool "\"EZchip\" ARC dev platform" bool "\"EZchip\" ARC dev platform"
select ARC_HAS_COH_CACHES if SMP
select CPU_BIG_ENDIAN select CPU_BIG_ENDIAN
select CLKSRC_NPS select CLKSRC_NPS
select EZNPS_GIC select EZNPS_GIC
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
menuconfig ARC_PLAT_SIM menuconfig ARC_PLAT_SIM
bool "ARC nSIM based simulation virtual platforms" bool "ARC nSIM based simulation virtual platforms"
select ARC_HAS_COH_CACHES if SMP
help help
Support for nSIM based ARC simulation platforms Support for nSIM based ARC simulation platforms
This includes the standalone nSIM (uart only) vs. System C OSCI VP This includes the standalone nSIM (uart only) vs. System C OSCI VP
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <soc/arc/aux.h> #include <soc/arc/aux.h>
#define ARC_REG_MCIP_BCR 0x0d0 #define ARC_REG_MCIP_BCR 0x0d0
#define ARC_REG_MCIP_IDU_BCR 0x0D5
#define ARC_REG_MCIP_CMD 0x600 #define ARC_REG_MCIP_CMD 0x600
#define ARC_REG_MCIP_WDATA 0x601 #define ARC_REG_MCIP_WDATA 0x601
#define ARC_REG_MCIP_READBACK 0x602 #define ARC_REG_MCIP_READBACK 0x602
...@@ -69,6 +70,22 @@ struct mcip_bcr { ...@@ -69,6 +70,22 @@ struct mcip_bcr {
#endif #endif
}; };
struct mcip_idu_bcr {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:21, cirqnum:3, ver:8;
#else
unsigned int ver:8, cirqnum:3, pad:21;
#endif
};
/*
* Build register for IDU contains not an actual number of supported common
* interrupts but an exponent of 2 which must be multiplied by 4 to
* get a number of supported common interrupts.
*/
#define mcip_idu_bcr_to_nr_irqs(bcr) (4 * (1 << (bcr).cirqnum))
/* /*
* MCIP programming model * MCIP programming model
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment