Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull ARC updates from Vineet Gupta:

- support for Edge Triggered IRQs in ARC IDU intc

- other fixes here and there

* tag 'arc-5.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
arc: prefer __section from compiler_attributes.h
dt-bindings: IDU-intc: Add support for edge-triggered interrupts
dt-bindings: IDU-intc: Clean up documentation
ARCv2: IDU-intc: Add support for edge-triggered interrupts
ARC: unwind: Mark expected switch fall-throughs
ARC: [plat-hsdk]: allow to switch between AXI DMAC port configurations
ARC: fix typo in setup_dma_ops log message
ARCv2: entry: early return from exception need not clear U & DE bits

+170 -36
+18 -8
Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
··· 1 1 * ARC-HS Interrupt Distribution Unit 2 2 3 - This optional 2nd level interrupt controller can be used in SMP configurations for 4 - dynamic IRQ routing, load balancing of common/external IRQs towards core intc. 3 + This optional 2nd level interrupt controller can be used in SMP configurations 4 + for dynamic IRQ routing, load balancing of common/external IRQs towards core 5 + intc. 5 6 6 7 Properties: 7 8 8 9 - compatible: "snps,archs-idu-intc" 9 10 - interrupt-controller: This is an interrupt controller. 10 - - #interrupt-cells: Must be <1>. 11 + - #interrupt-cells: Must be <1> or <2>. 11 12 12 - Value of the cell specifies the "common" IRQ from peripheral to IDU. Number N 13 - of the particular interrupt line of IDU corresponds to the line N+24 of the 14 - core interrupt controller. 13 + Value of the first cell specifies the "common" IRQ from peripheral to IDU. 14 + Number N of the particular interrupt line of IDU corresponds to the line N+24 15 + of the core interrupt controller. 15 16 16 - intc accessed via the special ARC AUX register interface, hence "reg" property 17 - is not specified. 17 + The (optional) second cell specifies any of the following flags: 18 + - bits[3:0] trigger type and level flags 19 + 1 = low-to-high edge triggered 20 + 2 = NOT SUPPORTED (high-to-low edge triggered) 21 + 4 = active high level-sensitive <<< DEFAULT 22 + 8 = NOT SUPPORTED (active low level-sensitive) 23 + When no second cell is specified, the interrupt is assumed to be level 24 + sensitive. 25 + 26 + The interrupt controller is accessed via the special ARC AUX register 27 + interface, hence "reg" property is not specified. 18 28 19 29 Example: 20 30 core_intc: core-interrupt-controller {
+3
arch/arc/boot/dts/Makefile
··· 12 12 # for CONFIG_OF_ALL_DTBS test 13 13 dtstree := $(srctree)/$(src) 14 14 dtb- := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) 15 + 16 + # board-specific dtc flags 17 + DTC_FLAGS_hsdk += --pad 20
+1 -1
arch/arc/include/asm/entry-arcv2.h
··· 256 256 257 257 .macro FAKE_RET_FROM_EXCPN 258 258 lr r9, [status32] 259 - bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK) 259 + bic r9, r9, STATUS_AE_MASK 260 260 or r9, r9, STATUS_IE_MASK 261 261 kflag r9 262 262 .endm
+4 -4
arch/arc/include/asm/linkage.h
··· 62 62 #else /* !__ASSEMBLY__ */ 63 63 64 64 #ifdef CONFIG_ARC_HAS_ICCM 65 - #define __arcfp_code __attribute__((__section__(".text.arcfp"))) 65 + #define __arcfp_code __section(.text.arcfp) 66 66 #else 67 - #define __arcfp_code __attribute__((__section__(".text"))) 67 + #define __arcfp_code __section(.text) 68 68 #endif 69 69 70 70 #ifdef CONFIG_ARC_HAS_DCCM 71 - #define __arcfp_data __attribute__((__section__(".data.arcfp"))) 71 + #define __arcfp_data __section(.data.arcfp) 72 72 #else 73 - #define __arcfp_data __attribute__((__section__(".data"))) 73 + #define __arcfp_data __section(.data) 74 74 #endif 75 75 76 76 #endif /* __ASSEMBLY__ */
+1 -2
arch/arc/include/asm/mach_desc.h
··· 53 53 */ 54 54 #define MACHINE_START(_type, _name) \ 55 55 static const struct machine_desc __mach_desc_##_type \ 56 - __used \ 57 - __attribute__((__section__(".arch.info.init"))) = { \ 56 + __used __section(.arch.info.init) = { \ 58 57 .name = _name, 59 58 60 59 #define MACHINE_END \
+54 -6
arch/arc/kernel/mcip.c
··· 202 202 __mcip_cmd_data(CMD_IDU_SET_DEST, cmn_irq, cpu_mask); 203 203 } 204 204 205 - static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl, 206 - unsigned int distr) 205 + static void idu_set_mode(unsigned int cmn_irq, bool set_lvl, unsigned int lvl, 206 + bool set_distr, unsigned int distr) 207 207 { 208 208 union { 209 209 unsigned int word; ··· 212 212 }; 213 213 } data; 214 214 215 - data.distr = distr; 216 - data.lvl = lvl; 215 + data.word = __mcip_cmd_read(CMD_IDU_READ_MODE, cmn_irq); 216 + if (set_distr) 217 + data.distr = distr; 218 + if (set_lvl) 219 + data.lvl = lvl; 217 220 __mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word); 218 221 } 219 222 ··· 243 240 raw_spin_unlock_irqrestore(&mcip_lock, flags); 244 241 } 245 242 243 + static void idu_irq_ack(struct irq_data *data) 244 + { 245 + unsigned long flags; 246 + 247 + raw_spin_lock_irqsave(&mcip_lock, flags); 248 + __mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq); 249 + raw_spin_unlock_irqrestore(&mcip_lock, flags); 250 + } 251 + 252 + static void idu_irq_mask_ack(struct irq_data *data) 253 + { 254 + unsigned long flags; 255 + 256 + raw_spin_lock_irqsave(&mcip_lock, flags); 257 + __mcip_cmd_data(CMD_IDU_SET_MASK, data->hwirq, 1); 258 + __mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq); 259 + raw_spin_unlock_irqrestore(&mcip_lock, flags); 260 + } 261 + 246 262 static int 247 263 idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, 248 264 bool force) ··· 285 263 else 286 264 distribution_mode = IDU_M_DISTRI_RR; 287 265 288 - idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode); 266 + idu_set_mode(data->hwirq, false, 0, true, distribution_mode); 289 267 290 268 raw_spin_unlock_irqrestore(&mcip_lock, flags); 291 269 292 270 return IRQ_SET_MASK_OK; 271 + } 272 + 273 + static int idu_irq_set_type(struct irq_data *data, u32 type) 274 + { 275 + unsigned long flags; 276 + 277 + /* 278 + * ARCv2 IDU HW does not support inverse polarity, so these are the 279 + * only interrupt types supported. 280 + */ 281 + if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) 282 + return -EINVAL; 283 + 284 + raw_spin_lock_irqsave(&mcip_lock, flags); 285 + 286 + idu_set_mode(data->hwirq, true, 287 + type & IRQ_TYPE_EDGE_RISING ? IDU_M_TRIG_EDGE : 288 + IDU_M_TRIG_LEVEL, 289 + false, 0); 290 + 291 + raw_spin_unlock_irqrestore(&mcip_lock, flags); 292 + 293 + return 0; 293 294 } 294 295 295 296 static void idu_irq_enable(struct irq_data *data) ··· 334 289 .name = "MCIP IDU Intc", 335 290 .irq_mask = idu_irq_mask, 336 291 .irq_unmask = idu_irq_unmask, 292 + .irq_ack = idu_irq_ack, 293 + .irq_mask_ack = idu_irq_mask_ack, 337 294 .irq_enable = idu_irq_enable, 295 + .irq_set_type = idu_irq_set_type, 338 296 #ifdef CONFIG_SMP 339 297 .irq_set_affinity = idu_irq_set_affinity, 340 298 #endif ··· 365 317 } 366 318 367 319 static const struct irq_domain_ops idu_irq_ops = { 368 - .xlate = irq_domain_xlate_onecell, 320 + .xlate = irq_domain_xlate_onetwocell, 369 321 .map = idu_irq_map, 370 322 }; 371 323
+2 -2
arch/arc/kernel/unwind.c
··· 826 826 case DW_CFA_def_cfa: 827 827 state->cfa.reg = get_uleb128(&ptr.p8, end); 828 828 unw_debug("cfa_def_cfa: r%lu ", state->cfa.reg); 829 - /*nobreak*/ 829 + /* fall through */ 830 830 case DW_CFA_def_cfa_offset: 831 831 state->cfa.offs = get_uleb128(&ptr.p8, end); 832 832 unw_debug("cfa_def_cfa_offset: 0x%lx ", ··· 834 834 break; 835 835 case DW_CFA_def_cfa_sf: 836 836 state->cfa.reg = get_uleb128(&ptr.p8, end); 837 - /*nobreak */ 837 + /* fall through */ 838 838 case DW_CFA_def_cfa_offset_sf: 839 839 state->cfa.offs = get_sleb128(&ptr.p8, end) 840 840 * state->dataAlign;
+1 -1
arch/arc/mm/dma.c
··· 101 101 if (is_isa_arcv2() && ioc_enable && coherent) 102 102 dev->dma_coherent = true; 103 103 104 - dev_info(dev, "use %sncoherent DMA ops\n", 104 + dev_info(dev, "use %scoherent DMA ops\n", 105 105 dev->dma_coherent ? "" : "non"); 106 106 } 107 107
+75 -12
arch/arc/plat-hsdk/platform.c
··· 6 6 */ 7 7 8 8 #include <linux/init.h> 9 + #include <linux/of_fdt.h> 10 + #include <linux/libfdt.h> 9 11 #include <linux/smp.h> 10 12 #include <asm/arcregs.h> 11 13 #include <asm/io.h> 12 14 #include <asm/mach_desc.h> 15 + 16 + int arc_hsdk_axi_dmac_coherent __section(.data) = 0; 13 17 14 18 #define ARC_CCM_UNUSED_ADDR 0x60000000 15 19 ··· 101 97 iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN); 102 98 } 103 99 100 + static int __init hsdk_tweak_node_coherency(const char *path, bool coherent) 101 + { 102 + void *fdt = initial_boot_params; 103 + const void *prop; 104 + int node, ret; 105 + bool dt_coh_set; 106 + 107 + node = fdt_path_offset(fdt, path); 108 + if (node < 0) 109 + goto tweak_fail; 110 + 111 + prop = fdt_getprop(fdt, node, "dma-coherent", &ret); 112 + if (!prop && ret != -FDT_ERR_NOTFOUND) 113 + goto tweak_fail; 114 + 115 + dt_coh_set = ret != -FDT_ERR_NOTFOUND; 116 + ret = 0; 117 + 118 + /* need to remove "dma-coherent" property */ 119 + if (dt_coh_set && !coherent) 120 + ret = fdt_delprop(fdt, node, "dma-coherent"); 121 + 122 + /* need to set "dma-coherent" property */ 123 + if (!dt_coh_set && coherent) 124 + ret = fdt_setprop(fdt, node, "dma-coherent", NULL, 0); 125 + 126 + if (ret < 0) 127 + goto tweak_fail; 128 + 129 + return 0; 130 + 131 + tweak_fail: 132 + pr_err("failed to tweak %s to %scoherent\n", path, coherent ? "" : "non"); 133 + return -EFAULT; 134 + } 135 + 104 136 enum hsdk_axi_masters { 105 137 M_HS_CORE = 0, 106 138 M_HS_RTT, ··· 201 161 202 162 #define CREG_PAE ((void __iomem *)(CREG_BASE + 0x180)) 203 163 #define CREG_PAE_UPDT ((void __iomem *)(CREG_BASE + 0x194)) 164 + 165 + static void __init hsdk_init_memory_bridge_axi_dmac(void) 166 + { 167 + bool coherent = !!arc_hsdk_axi_dmac_coherent; 168 + u32 axi_m_slv1, axi_m_oft1; 169 + 170 + /* 171 + * Don't tweak memory bridge configuration if we failed to tweak DTB 172 + * as we will end up in a inconsistent state. 173 + */ 174 + if (hsdk_tweak_node_coherency("/soc/dmac@80000", coherent)) 175 + return; 176 + 177 + if (coherent) { 178 + axi_m_slv1 = 0x77999999; 179 + axi_m_oft1 = 0x76DCBA98; 180 + } else { 181 + axi_m_slv1 = 0x77777777; 182 + axi_m_oft1 = 0x76543210; 183 + } 184 + 185 + writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0)); 186 + writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0)); 187 + writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_0)); 188 + writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_0)); 189 + writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0)); 190 + 191 + writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1)); 192 + writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1)); 193 + writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_1)); 194 + writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_1)); 195 + writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1)); 196 + } 204 197 205 198 static void __init hsdk_init_memory_bridge(void) 206 199 { ··· 300 227 writel(0x76543210, CREG_AXI_M_OFT1(M_GPU)); 301 228 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU)); 302 229 303 - writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0)); 304 - writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_0)); 305 - writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0)); 306 - writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_0)); 307 - writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0)); 308 - 309 - writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1)); 310 - writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_1)); 311 - writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1)); 312 - writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_1)); 313 - writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1)); 314 - 315 230 writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS)); 316 231 writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS)); 317 232 writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS)); 318 233 writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS)); 319 234 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS)); 235 + 236 + hsdk_init_memory_bridge_axi_dmac(); 320 237 321 238 /* 322 239 * PAE remapping for DMA clients does not work due to an RTL bug, so
+11
include/soc/arc/mcip.h
··· 46 46 #define CMD_IDU_ENABLE 0x71 47 47 #define CMD_IDU_DISABLE 0x72 48 48 #define CMD_IDU_SET_MODE 0x74 49 + #define CMD_IDU_READ_MODE 0x75 49 50 #define CMD_IDU_SET_DEST 0x76 51 + #define CMD_IDU_ACK_CIRQ 0x79 50 52 #define CMD_IDU_SET_MASK 0x7C 51 53 52 54 #define IDU_M_TRIG_LEVEL 0x0 ··· 119 117 write_aux_reg(ARC_REG_MCIP_WDATA, data); 120 118 121 119 __mcip_cmd(cmd, param); 120 + } 121 + 122 + /* 123 + * Read MCIP register 124 + */ 125 + static inline unsigned int __mcip_cmd_read(unsigned int cmd, unsigned int param) 126 + { 127 + __mcip_cmd(cmd, param); 128 + return read_aux_reg(ARC_REG_MCIP_READBACK); 122 129 } 123 130 124 131 #endif