From 91447ec9b4d0c5ad6eaa66400f3fd7cb4baff7df Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 1 Feb 2017 19:42:51 +0300 Subject: [PATCH 01/13] arc: vdk: Disable halt on reset In recent VDKs ARC cores are configured as "run on reset" which made existing kernel configuration outdated to effect that slave cores never start execution of the code keeping only master online. With that fix we're again in sync with VDK platform. And while at it we regenerate defconfig via savedefconfig so default options are now excluded. Signed-off-by: Alexey Brodkin Signed-off-by: Vineet Gupta --- arch/arc/configs/vdk_hs38_smp_defconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index 573028f19de7..f84714e76483 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -16,6 +16,7 @@ CONFIG_AXS103=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y # CONFIG_ARC_TIMERS_64BIT is not set +# CONFIG_ARC_SMP_HALT_ON_RESET is not set CONFIG_ARC_UBOOT_SUPPORT=y CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp" CONFIG_PREEMPT=y @@ -56,7 +57,6 @@ CONFIG_NATIONAL_PHY=y CONFIG_MOUSE_PS2_TOUCHKIT=y CONFIG_SERIO_ARC_PS2=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DW=y @@ -80,7 +80,6 @@ CONFIG_USB_STORAGE=y CONFIG_USB_SERIAL=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT3_FS=y -CONFIG_EXT4_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_NTFS_FS=y From d9174e722debd070efe57323de60610cf54b0049 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 1 Feb 2017 19:42:52 +0300 Subject: [PATCH 02/13] arc: vdk: Add support of MMC controller ARC VDK virtual platform emulates host MMC controller (DW Mobile Storage) and moreover rootfs is situated on that virtual card. Signed-off-by: Alexey Brodkin Signed-off-by: Vineet Gupta --- arch/arc/boot/dts/vdk_axs10x_mb.dtsi | 18 ++++++++++++++++++ arch/arc/configs/vdk_hs38_smp_defconfig | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi index 99498a4b4216..1953914b9f4f 100644 --- a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi +++ b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi @@ -23,6 +23,12 @@ #clock-cells = <0>; }; + mmcclk: mmcclk { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + #clock-cells = <0>; + }; + pguclk: pguclk { #clock-cells = <0>; compatible = "fixed-clock"; @@ -94,5 +100,17 @@ interrupts = <5>; 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>; + }; }; }; diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index f84714e76483..f06c7fca500c 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -78,6 +78,10 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y CONFIG_USB_SERIAL=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_DW=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT3_FS=y CONFIG_MSDOS_FS=y From cf16bf7779a68bc572c57ab0cb40054e1754223a Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 1 Feb 2017 19:42:53 +0300 Subject: [PATCH 03/13] arc: vdk: Add support of UIO ARC VDK for EVSS uses UIO for communication with Embedded Vision Subsystem. Signed-off-by: Alexey Brodkin Signed-off-by: Vineet Gupta --- arch/arc/boot/dts/vdk_axs10x_mb.dtsi | 8 ++++++++ arch/arc/configs/vdk_hs38_smp_defconfig | 2 ++ 2 files changed, 10 insertions(+) diff --git a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi index 1953914b9f4f..f0df59b23e21 100644 --- a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi +++ b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi @@ -112,5 +112,13 @@ 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>; + }; }; }; diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index f06c7fca500c..5c0971787acf 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -82,6 +82,8 @@ 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_EXT3_FS=y CONFIG_MSDOS_FS=y From e98a7bf0b094dea1ceed3a4d52584dcd59af0980 Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Tue, 31 Jan 2017 14:45:21 +0300 Subject: [PATCH 04/13] ARCv2: intc: Use ARC_REG_STATUS32 for addressing STATUS32 reg It is better to use it instead of magic numbers. Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta --- arch/arc/include/asm/arcregs.h | 3 +++ arch/arc/kernel/intc-arcv2.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index f659942744de..ba8e802dba80 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -38,6 +38,9 @@ #define ARC_REG_CLUSTER_BCR 0xcf #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 */ #define STATUS_AE_BIT 5 /* Exception active */ #define STATUS_DE_BIT 6 /* PC is in delay slot */ diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index ecef0fb0b66c..6ba2a84ab709 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -69,7 +69,7 @@ void arc_init_IRQ(void) irq_bcr.firq ? " FIRQ (not used)":""); /* 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_IE_MASK; asm volatile("kflag %0 \n"::"r"(tmp)); From fe7b10994618c846481fbcf9212d296df47bc1dc Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 1 Feb 2017 10:14:11 -0800 Subject: [PATCH 05/13] ARC: [intc-*]: confine NR_CPU_IRQS to intc code And even this willl change in subsequent patches where we resort to using run time info instead... Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irq.h | 1 - arch/arc/kernel/intc-arcv2.c | 2 ++ arch/arc/kernel/intc-compact.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index c0fa0d2de400..19deab06b07a 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -9,7 +9,6 @@ #ifndef __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 */ /* Platform Independent IRQs */ diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 6ba2a84ab709..5c5769dd8f5d 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -14,6 +14,8 @@ #include #include +#define NR_CPU_IRQS 32 /* number of irq lines coming in */ + /* * Early Hardware specific Interrupt setup * -Called very early (start_kernel -> setup_arch -> setup_processor) diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 8c1fd5c00782..7e608c6b0a01 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -14,6 +14,7 @@ #include #include +#define NR_CPU_IRQS 32 /* number of irq lines coming in */ #define TIMER0_IRQ 3 /* Fixed by ISA */ /* From f33b8cddc8ad8ce83cd3214406bcf68ec6c4d8ec Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Tue, 31 Jan 2017 14:45:22 +0300 Subject: [PATCH 06/13] ARCv2: intc: Rework the build time irq count information Currently Kconfig knob ARC_NUMBER_OF_INTERRUPTS is used as indicator of hard irq count. But it is flawed that it doesn't affect - NR_IRQS : for number of virtual interrupts - NR_CPU_IRQS : for number of hardware interrupts Moreover the actual hardware irq count might still not be same as ARC_NUMBER_OF_INTERRUPTS. So use the information availble in the Build Configuration Registers and get rid of the Kconfig option. We still need "some" build time info about irq count to set up sufficient number of vector table entries. This is done with a sufficiently large NR_CPU_IRQS which will eventually be used soley for that purpose (subsequent patches will remove its usage elsewhere) So to summarize what this patch does: * NR_CPU_IRQS defines a maximum number of hardware interrupts. * Remove ARC_NUMBER_OF_INTERRUPTS option and create interrupts table for all possible hardware interrupts. * Increase a maximum number of virtual IRQs to 512. 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 patch leads to NR_CPU_IRQS in 2 places, to reduce the overall churn. The next patch will remove the 2nd definition anyways. Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta [vgupta: reworked the changelog a bit] --- arch/arc/Kconfig | 11 ----------- arch/arc/include/asm/irq.h | 8 +++++++- arch/arc/kernel/entry-arcv2.S | 7 ++++++- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 283099c9560a..ba15cb8f60fb 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -412,17 +412,6 @@ config ARC_HAS_DIV_REM bool "Insn: div, divu, rem, remu" 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 endmenu # "ARC CPU Configuration" diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index 19deab06b07a..a3880b423925 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -9,7 +9,13 @@ #ifndef __ASM_ARC_IRQ_H #define __ASM_ARC_IRQ_H -#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 */ #ifdef CONFIG_ISA_ARCV2 diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index 0b6388a5f0b8..2585632eaa68 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -14,6 +14,11 @@ #include #include +; 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 #define VECTOR .word @@ -52,7 +57,7 @@ VECTOR handle_interrupt ; unused VECTOR handle_interrupt ; (23) unused # End of fixed IRQs -.rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8 +.rept NR_CPU_IRQS - 8 VECTOR handle_interrupt .endr From 179cf194e6d153fb6daeca811253502d5c84e4c8 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 1 Feb 2017 09:44:33 -0800 Subject: [PATCH 07/13] ARCv2: intc: Use runtime value of irq count for setting up intc Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irq.h | 1 + arch/arc/kernel/intc-arcv2.c | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index a3880b423925..0618b1ce707c 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -21,6 +21,7 @@ #ifdef CONFIG_ISA_ARCV2 #define IPI_IRQ 19 #define SOFTIRQ_IRQ 21 +#define FIRST_EXT_IRQ 24 #endif #include diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 5c5769dd8f5d..4d3166f9bbc9 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -14,7 +14,15 @@ #include #include -#define NR_CPU_IRQS 32 /* number of irq lines coming in */ +#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 @@ -25,14 +33,7 @@ void arc_init_IRQ(void) { unsigned int tmp, irq_prio; - - 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 bcr_irq_arcv2 irq_bcr; struct aux_irq_ctrl { #ifdef CONFIG_CPU_BIG_ENDIAN @@ -117,7 +118,7 @@ static int arcv2_irq_map(struct irq_domain *d, unsigned int irq, * core intc IRQs [16, 23]: * 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 * not set. That in turns sets NOAUTOEN, meaning each core needs @@ -142,11 +143,16 @@ static int __init init_onchip_IRQ(struct device_node *intc, struct device_node *parent) { 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) 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) panic("root irq domain not avail\n"); From be568e78dbb35383fdfd0563fd0cfbbff1bc42d0 Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Tue, 31 Jan 2017 14:45:24 +0300 Subject: [PATCH 08/13] ARCv2: intc: Set default priority for all core interrupts After reset all interrupts in the core interrupt controller has the highest priority P0. If the platform supports Fast IRQs and has more than 1 banks of registers then CPU automatically switch banks of registers when P0 interrupt comes. The problem is that the kernel expects that by default switching of banks is not used by all interrupts. It is necessary to set a default nonzero priority for all available interrupts to avoid undefined behaviour. Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta --- arch/arc/kernel/intc-arcv2.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 4d3166f9bbc9..f928795fd07a 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -32,7 +32,7 @@ struct bcr_irq_arcv2 { */ void arc_init_IRQ(void) { - unsigned int tmp, irq_prio; + unsigned int tmp, irq_prio, i; struct bcr_irq_arcv2 irq_bcr; struct aux_irq_ctrl { @@ -71,6 +71,16 @@ void arc_init_IRQ(void) irq_prio + 1, ARCV2_IRQ_DEF_PRIO, 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 */ tmp = read_aux_reg(ARC_REG_STATUS32); tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1); From 6f0310a126f1a46cac366327751bb7eb8941bdde Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Tue, 31 Jan 2017 14:45:23 +0300 Subject: [PATCH 09/13] ARCv2: IDU-intc: Use build registers for getting numbers of interrupts This enhancement is needed to allow masking all available common interrupts in IDU interrupt controller in boot time since the kernel can discover a number of them from the build register. Also now there is no need to specify in device tree a list of used core interrupts by IDU. E.g. before: idu_intc: idu-interrupt-controller { compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; #interrupt-cells = <2>; interrupts = <24 25 26 27 28 29 30 31>; }; and after: idu_intc: idu-interrupt-controller { compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; #interrupt-cells = <2>; }; Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta --- arch/arc/kernel/mcip.c | 19 +++++++++---------- include/soc/arc/mcip.h | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 9f6b68fd4f3b..21dc89704113 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -230,14 +230,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) { struct irq_domain *idu_domain = irq_desc_get_handler_data(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 idu_hwirq = core_hwirq - idu_first_hwirq; + irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ; chained_irq_enter(core_chip, desc); generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); @@ -283,17 +281,20 @@ static int __init idu_of_init(struct device_node *intc, struct device_node *parent) { struct irq_domain *domain; - /* Read IDU BCR to confirm nr_irqs */ - int nr_irqs = of_irq_count(intc); + int nr_irqs; int i, virq; struct mcip_bcr mp; + struct mcip_idu_bcr idu_bcr; READ_BCR(ARC_REG_MCIP_BCR, mp); if (!mp.idu) 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); @@ -306,10 +307,8 @@ idu_of_init(struct device_node *intc, struct device_node *parent) * however we need it to get the parent virq and set IDU handler * as first level isr */ - virq = irq_of_parse_and_map(intc, i); - if (!i) - idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq)); - + virq = irq_create_mapping(NULL, i + FIRST_EXT_IRQ); + BUG_ON(!virq); irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain); } diff --git a/include/soc/arc/mcip.h b/include/soc/arc/mcip.h index 4b6b489a8d7c..c2d1b15da136 100644 --- a/include/soc/arc/mcip.h +++ b/include/soc/arc/mcip.h @@ -14,6 +14,7 @@ #include #define ARC_REG_MCIP_BCR 0x0d0 +#define ARC_REG_MCIP_IDU_BCR 0x0D5 #define ARC_REG_MCIP_CMD 0x600 #define ARC_REG_MCIP_WDATA 0x601 #define ARC_REG_MCIP_READBACK 0x602 @@ -69,6 +70,22 @@ struct mcip_bcr { #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 * From fc73965ed0aa360d1c1813fcdb078533cbab03e3 Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Wed, 1 Feb 2017 11:00:30 -0800 Subject: [PATCH 10/13] ARCv2: IDU-intc: mask all common interrupts by default Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta [vgupta: broken off from a bigger patch] --- arch/arc/kernel/mcip.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 21dc89704113..b91d833ea6bb 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -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); } -static void idu_irq_mask(struct irq_data *data) +static void idu_irq_mask_raw(irq_hw_number_t hwirq) { unsigned long 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); } +static void idu_irq_mask(struct irq_data *data) +{ + idu_irq_mask_raw(data->hwirq); +} + static void idu_irq_unmask(struct irq_data *data) { unsigned long flags; @@ -301,6 +306,9 @@ idu_of_init(struct device_node *intc, struct device_node *parent) /* Parent interrupts (core-intc) are already mapped */ 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,..... * this step has been done before already From ec69b269d87c123a66bbcdc31cd5918db4ce442a Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Thu, 2 Feb 2017 03:13:32 +0300 Subject: [PATCH 11/13] ARCv2: IDU-intc: Delete deprecated parameters in Device Trees No need for specifying a list of interrupts in the declaration of IDU interrupt controller anymore since the kernel can obtain a number of supported interrupts from the build register. Also delete support of the second parameter for devices which are connected to IDU because it is not used anywhere. Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta --- .../snps,archs-idu-intc.txt | 24 +++++-------------- arch/arc/boot/dts/axc003_idu.dtsi | 23 +++--------------- arch/arc/boot/dts/haps_hs_idu.dts | 10 ++------ arch/arc/boot/dts/nsim_hs_idu.dts | 15 ++---------- arch/arc/boot/dts/nsimosci_hs_idu.dts | 20 ++++------------ arch/arc/boot/dts/vdk_axc003_idu.dtsi | 13 +++------- arch/arc/kernel/mcip.c | 17 +------------ 7 files changed, 21 insertions(+), 101 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt index 944657684d73..8b46a34e05f1 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt @@ -8,15 +8,11 @@ Properties: - compatible: "snps,archs-idu-intc" - interrupt-controller: This is an interrupt controller. - interrupt-parent: -- #interrupt-cells: Must be <2>. -- interrupts: <...> specifies the upstream core irqs +- #interrupt-cells: Must be <1>. - First cell specifies the "common" IRQ from peripheral to IDU - Second cell specifies the irq distribution mode to cores - 0=Round Robin; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 - - The second cell in interrupts property is deprecated and may be ignored by - the kernel. + Value of the cell specifies the "common" IRQ from peripheral to IDU. Number N + of the particular interrupt line of IDU corresponds to the line N+24 of the + core interrupt controller. intc accessed via the special ARC AUX register interface, hence "reg" property is not specified. @@ -32,18 +28,10 @@ Example: compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * - * 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>; + #interrupt-cells = <1>; }; some_device: serial@c0fc1000 { interrupt-parent = <&idu_intc>; - interrupts = <0 0>; /* upstream idu IRQ #24, Round Robin */ + interrupts = <0>; /* upstream idu IRQ #24 */ }; diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi index 3d6cfa32bf51..695f9fa1996b 100644 --- a/arch/arc/boot/dts/axc003_idu.dtsi +++ b/arch/arc/boot/dts/axc003_idu.dtsi @@ -40,18 +40,7 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * - * 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>; + #interrupt-cells = <1>; }; /* @@ -73,12 +62,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupt-parent = <&idu_intc>; - - /* - * cmn irq 1 -> cpu irq 25 - * Distribute to cpu0 only - */ - interrupts = <1 1>; + interrupts = <1>; }; }; @@ -119,8 +103,7 @@ reg = < 0xe0012000 0x200 >; interrupt-controller; interrupt-parent = <&idu_intc>; - interrupts = <0 1>; /* cmn irq 0 -> cpu irq 24 - distribute to cpu0 only */ + interrupts = <0>; }; memory { diff --git a/arch/arc/boot/dts/haps_hs_idu.dts b/arch/arc/boot/dts/haps_hs_idu.dts index 65204b4c0f13..0a857fa73190 100644 --- a/arch/arc/boot/dts/haps_hs_idu.dts +++ b/arch/arc/boot/dts/haps_hs_idu.dts @@ -54,11 +54,7 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - /* - distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 */ - #interrupt-cells = <2>; - interrupts = <24 25 26 27 28 29 30 31>; - + #interrupt-cells = <1>; }; uart0: serial@f0000000 { @@ -66,9 +62,7 @@ compatible = "ns16550a"; reg = <0xf0000000 0x2000>; interrupt-parent = <&idu_intc>; - /* interrupts = <0 1>; DEST=1*/ - /* interrupts = <0 2>; DEST=2*/ - interrupts = <0 0>; /* RR*/ + interrupts = <0>; clock-frequency = <50000000>; baud = <115200>; reg-shift = <2>; diff --git a/arch/arc/boot/dts/nsim_hs_idu.dts b/arch/arc/boot/dts/nsim_hs_idu.dts index 48434d7c4498..4f98ebf71fd8 100644 --- a/arch/arc/boot/dts/nsim_hs_idu.dts +++ b/arch/arc/boot/dts/nsim_hs_idu.dts @@ -46,25 +46,14 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * - * 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>; + #interrupt-cells = <1>; }; arcuart0: serial@c0fc1000 { compatible = "snps,arc-uart"; reg = <0xc0fc1000 0x100>; interrupt-parent = <&idu_intc>; - interrupts = <0 0>; + interrupts = <0>; clock-frequency = <80000000>; current-speed = <115200>; status = "okay"; diff --git a/arch/arc/boot/dts/nsimosci_hs_idu.dts b/arch/arc/boot/dts/nsimosci_hs_idu.dts index cbf65b6cc7c6..37be2bb8dd39 100644 --- a/arch/arc/boot/dts/nsimosci_hs_idu.dts +++ b/arch/arc/boot/dts/nsimosci_hs_idu.dts @@ -50,26 +50,14 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * - * 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>; + #interrupt-cells = <1>; }; uart0: serial@f0000000 { compatible = "ns8250"; reg = <0xf0000000 0x2000>; interrupt-parent = <&idu_intc>; - interrupts = <0 0>; /* cmn irq 0 -> cpu irq 24 - RR distribute to all cpus */ + interrupts = <0>; clock-frequency = <3686400>; baud = <115200>; reg-shift = <2>; @@ -93,7 +81,7 @@ ps2: ps2@f9001000 { compatible = "snps,arc_ps2"; reg = <0xf9000400 0x14>; - interrupts = <3 0>; + interrupts = <3>; interrupt-parent = <&idu_intc>; interrupt-names = "arc_ps2_irq"; }; @@ -102,7 +90,7 @@ compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; interrupt-parent = <&idu_intc>; - interrupts = <1 2>; + interrupts = <1>; }; arcpct0: pct { diff --git a/arch/arc/boot/dts/vdk_axc003_idu.dtsi b/arch/arc/boot/dts/vdk_axc003_idu.dtsi index 82214cd7ba0c..28956f9a9f3d 100644 --- a/arch/arc/boot/dts/vdk_axc003_idu.dtsi +++ b/arch/arc/boot/dts/vdk_axc003_idu.dtsi @@ -41,14 +41,7 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * - * distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 - */ - #interrupt-cells = <2>; - - interrupts = <24 25 26 27>; + #interrupt-cells = <1>; }; debug_uart: dw-apb-uart@0x5000 { @@ -56,7 +49,7 @@ reg = <0x5000 0x100>; clock-frequency = <2403200>; interrupt-parent = <&idu_intc>; - interrupts = <2 0>; + interrupts = <2>; baud = <115200>; reg-shift = <2>; reg-io-width = <4>; @@ -70,7 +63,7 @@ reg = < 0xe0012000 0x200 >; interrupt-controller; interrupt-parent = <&idu_intc>; - interrupts = < 0 0 >; + interrupts = <0>; }; memory { diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index b91d833ea6bb..f61a52b01625 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -255,23 +255,8 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t 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 = { - .xlate = idu_irq_xlate, + .xlate = irq_domain_xlate_onecell, .map = idu_irq_map, }; From b48fba057ca850d69cd8fde5adbbdf927206514b Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Thu, 2 Feb 2017 03:13:33 +0300 Subject: [PATCH 12/13] ARCv2: intc: Delete useless comments in Device Trees Signed-off-by: Yuriy Kolerov Signed-off-by: Vineet Gupta --- arch/arc/boot/dts/haps_hs_idu.dts | 1 - arch/arc/boot/dts/nsimosci_hs_idu.dts | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arc/boot/dts/haps_hs_idu.dts b/arch/arc/boot/dts/haps_hs_idu.dts index 0a857fa73190..215cddd0b63b 100644 --- a/arch/arc/boot/dts/haps_hs_idu.dts +++ b/arch/arc/boot/dts/haps_hs_idu.dts @@ -47,7 +47,6 @@ compatible = "snps,archs-intc"; interrupt-controller; #interrupt-cells = <1>; -/* interrupts = <16 17 18 19 20 21 22 23 24 25>; */ }; idu_intc: idu-interrupt-controller { diff --git a/arch/arc/boot/dts/nsimosci_hs_idu.dts b/arch/arc/boot/dts/nsimosci_hs_idu.dts index 37be2bb8dd39..5052917d4a99 100644 --- a/arch/arc/boot/dts/nsimosci_hs_idu.dts +++ b/arch/arc/boot/dts/nsimosci_hs_idu.dts @@ -43,7 +43,6 @@ compatible = "snps,archs-intc"; interrupt-controller; #interrupt-cells = <1>; -/* interrupts = <16 17 18 19 20 21 22 23 24 25>; */ }; idu_intc: idu-interrupt-controller { From 8ba605b607b7278548c1092b2ac36381627f0839 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 2 Feb 2017 09:09:50 -0800 Subject: [PATCH 13/13] ARC: [plat-*] ARC_HAS_COH_CACHES no longer relevant A typical SMP system expects cache coherency. Initial NPS platform support was slated to be SMP w/o cache coherency. However it seems the platform now selects that option, so there is no point in keeping it around. Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 6 ------ arch/arc/plat-eznps/Kconfig | 1 - arch/arc/plat-sim/Kconfig | 1 - 3 files changed, 8 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index ba15cb8f60fb..c9f30f4763ab 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -180,16 +180,12 @@ config CPU_BIG_ENDIAN config SMP bool "Symmetric Multi-Processing" default n - select ARC_HAS_COH_CACHES if ISA_ARCV2 select ARC_MCIP if ISA_ARCV2 help This enables support for systems with more than one CPU. if SMP -config ARC_HAS_COH_CACHES - def_bool n - config NR_CPUS int "Maximum number of CPUs (2-4096)" range 2 4096 @@ -219,8 +215,6 @@ config ARC_MCIP menuconfig ARC_CACHE bool "Enable Cache Support" default y - # if SMP, cache enabled ONLY if ARC implementation has cache coherency - depends on !SMP || ARC_HAS_COH_CACHES if ARC_CACHE diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig index 1d175cc6ad6d..1595a38e50cd 100644 --- a/arch/arc/plat-eznps/Kconfig +++ b/arch/arc/plat-eznps/Kconfig @@ -5,7 +5,6 @@ menuconfig ARC_PLAT_EZNPS bool "\"EZchip\" ARC dev platform" - select ARC_HAS_COH_CACHES if SMP select CPU_BIG_ENDIAN select CLKSRC_NPS select EZNPS_GIC diff --git a/arch/arc/plat-sim/Kconfig b/arch/arc/plat-sim/Kconfig index 18e39fcc488a..ac6af96a82f3 100644 --- a/arch/arc/plat-sim/Kconfig +++ b/arch/arc/plat-sim/Kconfig @@ -8,7 +8,6 @@ menuconfig ARC_PLAT_SIM bool "ARC nSIM based simulation virtual platforms" - select ARC_HAS_COH_CACHES if SMP help Support for nSIM based ARC simulation platforms This includes the standalone nSIM (uart only) vs. System C OSCI VP