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

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

Pull ARC updates from Vineet Gupta:
"These are mostly timer/clocksource driver updates which were
Reviewed/Acked by Daniel but had to be merged via ARC tree due to
dependencies.

I will follow up with another pull request with actual ARC changes
early next week !

Summary:

- Moving ARC timer driver into drivers/clocksource

- EZChip timer driver updates [Noam]

- ARC AXS103 and HAPS platform updates [Alexey]"

* tag 'arc-4.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
ARC: axs10x: really enable ARC PGU
ARC: rename Zebu platform support to HAPS
clocksource: nps: avoid maybe-uninitialized warning
clocksource: Add clockevent support to NPS400 driver
clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
soc: Support for NPS HW scheduling
clocksource: import ARC timer driver
ARC: breakout timer include code into separate header ...
ARC: move mcip.h into include/soc and adjust the includes
ARC: breakout aux handling into a separate header
ARC: time: move time_init() out of the driver
ARC: timer: gfrc, rtc: build under same option (64-bit timers)
ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ...
ARC: timer: gfrc, rtc: deuglify big endian code

+483 -236
+3 -3
Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
··· 2 2 3 3 Required properties: 4 4 5 - - compatible : should be "ezchip,nps400-timer" 5 + - compatible : should be "ezchip,nps400-timer1" 6 6 7 - Clocks required for compatible = "ezchip,nps400-timer": 7 + Clocks required for compatible = "ezchip,nps400-timer1": 8 8 - clocks : Must contain a single entry describing the clock input 9 9 10 10 Example: 11 11 12 12 timer { 13 - compatible = "ezchip,nps400-timer"; 13 + compatible = "ezchip,nps400-timer1"; 14 14 clocks = <&sysclk>; 15 15 };
+17
Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
··· 1 + NPS Network Processor 2 + 3 + Required properties: 4 + 5 + - compatible : should be "ezchip,nps400-timer0" 6 + 7 + Clocks required for compatible = "ezchip,nps400-timer0": 8 + - interrupts : The interrupt of the first timer 9 + - clocks : Must contain a single entry describing the clock input 10 + 11 + Example: 12 + 13 + timer { 14 + compatible = "ezchip,nps400-timer0"; 15 + interrupts = <3>; 16 + clocks = <&sysclk>; 17 + };
+1
MAINTAINERS
··· 11827 11827 F: arch/arc/ 11828 11828 F: Documentation/devicetree/bindings/arc/* 11829 11829 F: Documentation/devicetree/bindings/interrupt-controller/snps,arc* 11830 + F: drivers/clocksource/arc_timer.c 11830 11831 F: drivers/tty/serial/arc_uart.c 11831 11832 T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git 11832 11833
+2 -11
arch/arc/Kconfig
··· 8 8 9 9 config ARC 10 10 def_bool y 11 + select ARC_TIMERS 11 12 select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC 12 13 select BUILDTIME_EXTABLE_SORT 13 - select CLKSRC_OF 14 14 select CLONE_BACKWARDS 15 15 select COMMON_CLK 16 16 select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC) ··· 115 115 116 116 config ISA_ARCV2 117 117 bool "ARC ISA v2" 118 + select ARC_TIMERS_64BIT 118 119 help 119 120 ISA for the Next Generation ARC-HS cores 120 121 ··· 410 409 config ARC_HAS_DIV_REM 411 410 bool "Insn: div, divu, rem, remu" 412 411 default y 413 - 414 - config ARC_HAS_RTC 415 - bool "Local 64-bit r/o cycle counter" 416 - default n 417 - depends on !SMP 418 - 419 - config ARC_HAS_GFRC 420 - bool "SMP synchronized 64-bit cycle counter" 421 - default y 422 - depends on SMP 423 412 424 413 config ARC_NUMBER_OF_INTERRUPTS 425 414 int "Number of interrupts"
+1 -1
arch/arc/boot/dts/axs101.dts
··· 17 17 compatible = "snps,axs101", "snps,arc-sdp"; 18 18 19 19 chosen { 20 - bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0"; 20 + bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 video=1280x720@60"; 21 21 }; 22 22 };
+1 -1
arch/arc/boot/dts/axs103_idu.dts
··· 20 20 compatible = "snps,axs103", "snps,arc-sdp"; 21 21 22 22 chosen { 23 - bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=ttyS3,115200n8 debug print-fatal-signals=1"; 23 + bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 print-fatal-signals=1 consoleblank=0 video=1280x720@60"; 24 24 }; 25 25 };
arch/arc/boot/dts/zebu_hs.dts arch/arc/boot/dts/haps_hs.dts
arch/arc/boot/dts/zebu_hs_idu.dts arch/arc/boot/dts/haps_hs_idu.dts
+3 -1
arch/arc/configs/axs101_defconfig
··· 75 75 CONFIG_I2C_CHARDEV=y 76 76 CONFIG_I2C_DESIGNWARE_PLATFORM=y 77 77 # CONFIG_HWMON is not set 78 + CONFIG_DRM=m 79 + CONFIG_DRM_I2C_ADV7511=m 80 + CONFIG_DRM_ARCPGU=m 78 81 CONFIG_FB=y 79 82 CONFIG_FRAMEBUFFER_CONSOLE=y 80 - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y 81 83 CONFIG_LOGO=y 82 84 # CONFIG_LOGO_LINUX_MONO is not set 83 85 # CONFIG_LOGO_LINUX_VGA16 is not set
+3 -1
arch/arc/configs/axs103_smp_defconfig
··· 77 77 CONFIG_I2C_CHARDEV=y 78 78 CONFIG_I2C_DESIGNWARE_PLATFORM=y 79 79 # CONFIG_HWMON is not set 80 + CONFIG_DRM=m 81 + CONFIG_DRM_I2C_ADV7511=m 82 + CONFIG_DRM_ARCPGU=m 80 83 CONFIG_FB=y 81 84 CONFIG_FRAMEBUFFER_CONSOLE=y 82 - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y 83 85 CONFIG_LOGO=y 84 86 # CONFIG_LOGO_LINUX_MONO is not set 85 87 # CONFIG_LOGO_LINUX_VGA16 is not set
+1 -1
arch/arc/configs/nsimosci_hs_smp_defconfig
··· 21 21 CONFIG_ARC_PLAT_SIM=y 22 22 CONFIG_ISA_ARCV2=y 23 23 CONFIG_SMP=y 24 - # CONFIG_ARC_HAS_GFRC is not set 24 + # CONFIG_ARC_TIMERS_64BIT is not set 25 25 CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu" 26 26 CONFIG_PREEMPT=y 27 27 # CONFIG_COMPACTION is not set
+1 -1
arch/arc/configs/vdk_hs38_smp_defconfig
··· 15 15 CONFIG_AXS103=y 16 16 CONFIG_ISA_ARCV2=y 17 17 CONFIG_SMP=y 18 - # CONFIG_ARC_HAS_GFRC is not set 18 + # CONFIG_ARC_TIMERS_64BIT is not set 19 19 CONFIG_ARC_UBOOT_SUPPORT=y 20 20 CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp" 21 21 CONFIG_PREEMPT=y
+6 -3
arch/arc/configs/zebu_hs_defconfig arch/arc/configs/haps_hs_smp_defconfig
··· 12 12 # CONFIG_PID_NS is not set 13 13 CONFIG_BLK_DEV_INITRD=y 14 14 CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/" 15 - CONFIG_EXPERT=y 15 + CONFIG_EMBEDDED=y 16 16 CONFIG_PERF_EVENTS=y 17 + # CONFIG_VM_EVENT_COUNTERS is not set 17 18 # CONFIG_COMPAT_BRK is not set 18 19 CONFIG_SLAB=y 20 + CONFIG_KPROBES=y 19 21 CONFIG_MODULES=y 20 22 # CONFIG_LBDAF is not set 21 23 # CONFIG_BLK_DEV_BSG is not set ··· 25 23 # CONFIG_IOSCHED_CFQ is not set 26 24 CONFIG_ARC_PLAT_SIM=y 27 25 CONFIG_ISA_ARCV2=y 28 - CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs" 26 + CONFIG_SMP=y 27 + CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu" 29 28 CONFIG_PREEMPT=y 30 29 # CONFIG_COMPACTION is not set 31 30 CONFIG_NET=y ··· 85 82 CONFIG_NFS_FS=y 86 83 # CONFIG_ENABLE_WARN_DEPRECATED is not set 87 84 # CONFIG_ENABLE_MUST_CHECK is not set 88 - CONFIG_DEBUG_MEMORY_INIT=y 85 + CONFIG_LOCKUP_DETECTOR=y 89 86 # CONFIG_DEBUG_PREEMPT is not set
+3 -6
arch/arc/configs/zebu_hs_smp_defconfig arch/arc/configs/haps_hs_defconfig
··· 12 12 # CONFIG_PID_NS is not set 13 13 CONFIG_BLK_DEV_INITRD=y 14 14 CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/" 15 - CONFIG_EMBEDDED=y 15 + CONFIG_EXPERT=y 16 16 CONFIG_PERF_EVENTS=y 17 - # CONFIG_VM_EVENT_COUNTERS is not set 18 17 # CONFIG_COMPAT_BRK is not set 19 18 CONFIG_SLAB=y 20 - CONFIG_KPROBES=y 21 19 CONFIG_MODULES=y 22 20 # CONFIG_LBDAF is not set 23 21 # CONFIG_BLK_DEV_BSG is not set ··· 23 25 # CONFIG_IOSCHED_CFQ is not set 24 26 CONFIG_ARC_PLAT_SIM=y 25 27 CONFIG_ISA_ARCV2=y 26 - CONFIG_SMP=y 27 - CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs_idu" 28 + CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs" 28 29 CONFIG_PREEMPT=y 29 30 # CONFIG_COMPACTION is not set 30 31 CONFIG_NET=y ··· 82 85 CONFIG_NFS_FS=y 83 86 # CONFIG_ENABLE_WARN_DEPRECATED is not set 84 87 # CONFIG_ENABLE_MUST_CHECK is not set 85 - CONFIG_LOCKUP_DETECTOR=y 88 + CONFIG_DEBUG_MEMORY_INIT=y 86 89 # CONFIG_DEBUG_PREEMPT is not set
+2 -92
arch/arc/include/asm/arcregs.h
··· 20 20 #define ARC_REG_FP_V2_BCR 0xc8 /* ARCv2 FPU */ 21 21 #define ARC_REG_SLC_BCR 0xce 22 22 #define ARC_REG_DCCM_BUILD 0x74 /* DCCM size (common) */ 23 - #define ARC_REG_TIMERS_BCR 0x75 24 23 #define ARC_REG_AP_BCR 0x76 25 24 #define ARC_REG_ICCM_BUILD 0x78 /* ICCM size (common) */ 26 25 #define ARC_REG_XY_MEM_BCR 0x79 ··· 111 112 112 113 #ifndef __ASSEMBLY__ 113 114 114 - /* 115 - ****************************************************************** 116 - * Inline ASM macros to read/write AUX Regs 117 - * Essentially invocation of lr/sr insns from "C" 118 - */ 119 - 120 - #if 1 121 - 122 - #define read_aux_reg(reg) __builtin_arc_lr(reg) 123 - 124 - /* gcc builtin sr needs reg param to be long immediate */ 125 - #define write_aux_reg(reg_immed, val) \ 126 - __builtin_arc_sr((unsigned int)(val), reg_immed) 127 - 128 - #else 129 - 130 - #define read_aux_reg(reg) \ 131 - ({ \ 132 - unsigned int __ret; \ 133 - __asm__ __volatile__( \ 134 - " lr %0, [%1]" \ 135 - : "=r"(__ret) \ 136 - : "i"(reg)); \ 137 - __ret; \ 138 - }) 139 - 140 - /* 141 - * Aux Reg address is specified as long immediate by caller 142 - * e.g. 143 - * write_aux_reg(0x69, some_val); 144 - * This generates tightest code. 145 - */ 146 - #define write_aux_reg(reg_imm, val) \ 147 - ({ \ 148 - __asm__ __volatile__( \ 149 - " sr %0, [%1] \n" \ 150 - : \ 151 - : "ir"(val), "i"(reg_imm)); \ 152 - }) 153 - 154 - /* 155 - * Aux Reg address is specified in a variable 156 - * * e.g. 157 - * reg_num = 0x69 158 - * write_aux_reg2(reg_num, some_val); 159 - * This has to generate glue code to load the reg num from 160 - * memory to a reg hence not recommended. 161 - */ 162 - #define write_aux_reg2(reg_in_var, val) \ 163 - ({ \ 164 - unsigned int tmp; \ 165 - \ 166 - __asm__ __volatile__( \ 167 - " ld %0, [%2] \n\t" \ 168 - " sr %1, [%0] \n\t" \ 169 - : "=&r"(tmp) \ 170 - : "r"(val), "memory"(&reg_in_var)); \ 171 - }) 172 - 173 - #endif 174 - 175 - #define READ_BCR(reg, into) \ 176 - { \ 177 - unsigned int tmp; \ 178 - tmp = read_aux_reg(reg); \ 179 - if (sizeof(tmp) == sizeof(into)) { \ 180 - into = *((typeof(into) *)&tmp); \ 181 - } else { \ 182 - extern void bogus_undefined(void); \ 183 - bogus_undefined(); \ 184 - } \ 185 - } 186 - 187 - #define WRITE_AUX(reg, into) \ 188 - { \ 189 - unsigned int tmp; \ 190 - if (sizeof(tmp) == sizeof(into)) { \ 191 - tmp = (*(unsigned int *)&(into)); \ 192 - write_aux_reg(reg, tmp); \ 193 - } else { \ 194 - extern void bogus_undefined(void); \ 195 - bogus_undefined(); \ 196 - } \ 197 - } 115 + #include <soc/arc/aux.h> 198 116 199 117 /* Helpers */ 200 118 #define TO_KB(bytes) ((bytes) >> 10) ··· 207 291 #endif 208 292 }; 209 293 210 - struct bcr_timer { 211 - #ifdef CONFIG_CPU_BIG_ENDIAN 212 - unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8; 213 - #else 214 - unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15; 215 - #endif 216 - }; 294 + #include <soc/arc/timers.h> 217 295 218 296 struct bcr_bpu_arcompact { 219 297 #ifdef CONFIG_CPU_BIG_ENDIAN
+3 -7
arch/arc/include/asm/mcip.h include/soc/arc/mcip.h
··· 8 8 * published by the Free Software Foundation. 9 9 */ 10 10 11 - #ifndef __ASM_MCIP_H 12 - #define __ASM_MCIP_H 11 + #ifndef __SOC_ARC_MCIP_H 12 + #define __SOC_ARC_MCIP_H 13 13 14 - #ifdef CONFIG_ISA_ARCV2 15 - 16 - #include <asm/arcregs.h> 14 + #include <soc/arc/aux.h> 17 15 18 16 #define ARC_REG_MCIP_BCR 0x0d0 19 17 #define ARC_REG_MCIP_CMD 0x600 ··· 99 101 100 102 __mcip_cmd(cmd, param); 101 103 } 102 - 103 - #endif 104 104 105 105 #endif
+1 -1
arch/arc/kernel/Makefile
··· 8 8 # Pass UTS_MACHINE for user_regset definition 9 9 CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' 10 10 11 - obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o 11 + obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o 12 12 obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o 13 13 obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o 14 14 obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
+1 -1
arch/arc/kernel/mcip.c
··· 11 11 #include <linux/smp.h> 12 12 #include <linux/irq.h> 13 13 #include <linux/spinlock.h> 14 + #include <soc/arc/mcip.h> 14 15 #include <asm/irqflags-arcv2.h> 15 - #include <asm/mcip.h> 16 16 #include <asm/setup.h> 17 17 18 18 static DEFINE_RAW_SPINLOCK(mcip_lock);
+14 -3
arch/arc/kernel/setup.c
··· 10 10 #include <linux/fs.h> 11 11 #include <linux/delay.h> 12 12 #include <linux/root_dev.h> 13 + #include <linux/clk-provider.h> 14 + #include <linux/clocksource.h> 13 15 #include <linux/console.h> 14 16 #include <linux/module.h> 15 17 #include <linux/cpu.h> ··· 236 234 is_isa_arcompact() ? "ARCompact" : "ARCv2", 237 235 IS_AVAIL1(cpu->isa.be, "[Big-Endian]")); 238 236 239 - n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", 237 + n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ", 240 238 IS_AVAIL1(cpu->extn.timer0, "Timer0 "), 241 239 IS_AVAIL1(cpu->extn.timer1, "Timer1 "), 242 - IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ", 243 - CONFIG_ARC_HAS_RTC)); 240 + IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), 241 + IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT)); 244 242 245 243 n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s", 246 244 IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), ··· 449 447 #endif 450 448 451 449 arc_unwind_init(); 450 + } 451 + 452 + /* 453 + * Called from start_kernel() - boot CPU only 454 + */ 455 + void __init time_init(void) 456 + { 457 + of_clk_init(NULL); 458 + clocksource_probe(); 452 459 } 453 460 454 461 static int __init customize_machine(void)
+32 -78
arch/arc/kernel/time.c drivers/clocksource/arc_timer.c
··· 1 1 /* 2 + * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com) 2 3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 4 * 4 5 * This program is free software; you can redistribute it and/or modify 5 6 * it under the terms of the GNU General Public License version 2 as 6 7 * published by the Free Software Foundation. 7 - * 8 - * vineetg: Jan 1011 9 - * -sched_clock( ) no longer jiffies based. Uses the same clocksource 10 - * as gtod 11 - * 12 - * Rajeshwarr/Vineetg: Mar 2008 13 - * -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code) 14 - * for arch independent gettimeofday() 15 - * -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers 16 - * 17 - * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c 18 8 */ 19 9 20 - /* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1 21 - * Each can programmed to go from @count to @limit and optionally 22 - * interrupt when that happens. 23 - * A write to Control Register clears the Interrupt 10 + /* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be 11 + * programmed to go from @count to @limit and optionally interrupt. 12 + * We've designated TIMER0 for clockevents and TIMER1 for clocksource 24 13 * 25 - * We've designated TIMER0 for events (clockevents) 26 - * while TIMER1 for free running (clocksource) 27 - * 28 - * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1 29 - * which however is currently broken 14 + * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP) 15 + * which are suitable for UP and SMP based clocksources respectively 30 16 */ 31 17 32 18 #include <linux/interrupt.h> ··· 23 37 #include <linux/cpu.h> 24 38 #include <linux/of.h> 25 39 #include <linux/of_irq.h> 26 - #include <asm/irq.h> 27 - #include <asm/arcregs.h> 28 40 29 - #include <asm/mcip.h> 41 + #include <soc/arc/timers.h> 42 + #include <soc/arc/mcip.h> 30 43 31 - /* Timer related Aux registers */ 32 - #define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */ 33 - #define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */ 34 - #define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */ 35 - #define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */ 36 - #define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */ 37 - #define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */ 38 - 39 - #define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ 40 - #define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ 41 - 42 - #define ARC_TIMER_MAX 0xFFFFFFFF 43 44 44 45 static unsigned long arc_timer_freq; 45 46 ··· 54 81 55 82 /********** Clock Source Device *********/ 56 83 57 - #ifdef CONFIG_ARC_HAS_GFRC 84 + #ifdef CONFIG_ARC_TIMERS_64BIT 58 85 59 86 static cycle_t arc_read_gfrc(struct clocksource *cs) 60 87 { 61 88 unsigned long flags; 62 - union { 63 - #ifdef CONFIG_CPU_BIG_ENDIAN 64 - struct { u32 h, l; }; 65 - #else 66 - struct { u32 l, h; }; 67 - #endif 68 - cycle_t full; 69 - } stamp; 89 + u32 l, h; 70 90 71 91 local_irq_save(flags); 72 92 73 93 __mcip_cmd(CMD_GFRC_READ_LO, 0); 74 - stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK); 94 + l = read_aux_reg(ARC_REG_MCIP_READBACK); 75 95 76 96 __mcip_cmd(CMD_GFRC_READ_HI, 0); 77 - stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK); 97 + h = read_aux_reg(ARC_REG_MCIP_READBACK); 78 98 79 99 local_irq_restore(flags); 80 100 81 - return stamp.full; 101 + return (((cycle_t)h) << 32) | l; 82 102 } 83 103 84 104 static struct clocksource arc_counter_gfrc = { ··· 84 118 85 119 static int __init arc_cs_setup_gfrc(struct device_node *node) 86 120 { 87 - int exists = cpuinfo_arc700[0].extn.gfrc; 121 + struct mcip_bcr mp; 88 122 int ret; 89 123 90 - if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) 124 + READ_BCR(ARC_REG_MCIP_BCR, mp); 125 + if (!mp.gfrc) { 126 + pr_warn("Global-64-bit-Ctr clocksource not detected"); 91 127 return -ENXIO; 128 + } 92 129 93 130 ret = arc_get_timer_clk(node); 94 131 if (ret) ··· 101 132 } 102 133 CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); 103 134 104 - #endif 105 - 106 - #ifdef CONFIG_ARC_HAS_RTC 107 - 108 135 #define AUX_RTC_CTRL 0x103 109 136 #define AUX_RTC_LOW 0x104 110 137 #define AUX_RTC_HIGH 0x105 ··· 108 143 static cycle_t arc_read_rtc(struct clocksource *cs) 109 144 { 110 145 unsigned long status; 111 - union { 112 - #ifdef CONFIG_CPU_BIG_ENDIAN 113 - struct { u32 high, low; }; 114 - #else 115 - struct { u32 low, high; }; 116 - #endif 117 - cycle_t full; 118 - } stamp; 146 + u32 l, h; 119 147 120 148 /* 121 149 * hardware has an internal state machine which tracks readout of ··· 117 159 * - high increments after low has been read 118 160 */ 119 161 do { 120 - stamp.low = read_aux_reg(AUX_RTC_LOW); 121 - stamp.high = read_aux_reg(AUX_RTC_HIGH); 162 + l = read_aux_reg(AUX_RTC_LOW); 163 + h = read_aux_reg(AUX_RTC_HIGH); 122 164 status = read_aux_reg(AUX_RTC_CTRL); 123 165 } while (!(status & _BITUL(31))); 124 166 125 - return stamp.full; 167 + return (((cycle_t)h) << 32) | l; 126 168 } 127 169 128 170 static struct clocksource arc_counter_rtc = { ··· 135 177 136 178 static int __init arc_cs_setup_rtc(struct device_node *node) 137 179 { 138 - int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; 180 + struct bcr_timer timer; 139 181 int ret; 140 182 141 - if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) 183 + READ_BCR(ARC_REG_TIMERS_BCR, timer); 184 + if (!timer.rtc) { 185 + pr_warn("Local-64-bit-Ctr clocksource not detected"); 142 186 return -ENXIO; 187 + } 143 188 144 189 /* Local to CPU hence not usable in SMP */ 145 - if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) 190 + if (IS_ENABLED(CONFIG_SMP)) { 191 + pr_warn("Local-64-bit-Ctr not usable in SMP"); 146 192 return -EINVAL; 193 + } 147 194 148 195 ret = arc_get_timer_clk(node); 149 196 if (ret) ··· 191 228 if (ret) 192 229 return ret; 193 230 194 - write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); 231 + write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX); 195 232 write_aux_reg(ARC_REG_TIMER1_CNT, 0); 196 233 write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); 197 234 ··· 269 306 270 307 evt->cpumask = cpumask_of(smp_processor_id()); 271 308 272 - clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX); 309 + clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMERN_MAX); 273 310 enable_percpu_irq(arc_timer_irq, 0); 274 311 return 0; 275 312 } ··· 334 371 return ret; 335 372 } 336 373 CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); 337 - 338 - /* 339 - * Called from start_kernel() - boot CPU only 340 - */ 341 - void __init time_init(void) 342 - { 343 - of_clk_init(NULL); 344 - clocksource_probe(); 345 - }
+1 -1
arch/arc/plat-axs10x/axs10x.c
··· 21 21 #include <asm/asm-offsets.h> 22 22 #include <asm/io.h> 23 23 #include <asm/mach_desc.h> 24 - #include <asm/mcip.h> 24 + #include <soc/arc/mcip.h> 25 25 26 26 #define AXS_MB_CGU 0xE0010000 27 27 #define AXS_MB_CREG 0xE0011000
-2
arch/arc/plat-eznps/include/plat/ctop.h
··· 46 46 #define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300) 47 47 48 48 /* EZchip core instructions */ 49 - #define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF 50 49 #define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF 51 - #define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3 52 50 #define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103 53 51 #define CTOP_INST_SCHD_RW 0x3E6F7004 54 52 #define CTOP_INST_SCHD_RD 0x3E6F7084
+20
drivers/clocksource/Kconfig
··· 282 282 select CLKSRC_MMIO 283 283 select CLKSRC_OF 284 284 285 + config ARC_TIMERS 286 + bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST 287 + depends on GENERIC_CLOCKEVENTS 288 + select CLKSRC_OF 289 + help 290 + These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores 291 + (ARC700 as well as ARC HS38). 292 + TIMER0 serves as clockevent while TIMER1 provides clocksource 293 + 294 + config ARC_TIMERS_64BIT 295 + bool "Support for 64-bit counters in ARC HS38 cores" if COMPILE_TEST 296 + depends on GENERIC_CLOCKEVENTS 297 + depends on ARC_TIMERS 298 + select CLKSRC_OF 299 + help 300 + This enables 2 different 64-bit timers: RTC (for UP) and GFRC (for SMP) 301 + RTC is implemented inside the core, while GFRC sits outside the core in 302 + ARConnect IP block. Driver automatically picks one of them for clocksource 303 + as appropriate. 304 + 285 305 config ARM_ARCH_TIMER 286 306 bool 287 307 select CLKSRC_OF if OF
+1
drivers/clocksource/Makefile
··· 51 51 obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o 52 52 obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o 53 53 54 + obj-$(CONFIG_ARC_TIMERS) += arc_timer.o 54 55 obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 55 56 obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o 56 57 obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o
+206 -22
drivers/clocksource/timer-nps.c
··· 46 46 /* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */ 47 47 static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly; 48 48 49 - static unsigned long nps_timer_rate; 49 + static int __init nps_get_timer_clk(struct device_node *node, 50 + unsigned long *timer_freq, 51 + struct clk **clk) 52 + { 53 + int ret; 54 + 55 + *clk = of_clk_get(node, 0); 56 + ret = PTR_ERR_OR_ZERO(*clk); 57 + if (ret) { 58 + pr_err("timer missing clk"); 59 + return ret; 60 + } 61 + 62 + ret = clk_prepare_enable(*clk); 63 + if (ret) { 64 + pr_err("Couldn't enable parent clk\n"); 65 + clk_put(*clk); 66 + return ret; 67 + } 68 + 69 + *timer_freq = clk_get_rate(*clk); 70 + if (!(*timer_freq)) { 71 + pr_err("Couldn't get clk rate\n"); 72 + clk_disable_unprepare(*clk); 73 + clk_put(*clk); 74 + return -EINVAL; 75 + } 76 + 77 + return 0; 78 + } 50 79 51 80 static cycle_t nps_clksrc_read(struct clocksource *clksrc) 52 81 { ··· 84 55 return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]); 85 56 } 86 57 87 - static int __init nps_setup_clocksource(struct device_node *node, 88 - struct clk *clk) 58 + static int __init nps_setup_clocksource(struct device_node *node) 89 59 { 90 60 int ret, cluster; 61 + struct clk *clk; 62 + unsigned long nps_timer1_freq; 63 + 91 64 92 65 for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++) 93 66 nps_msu_reg_low_addr[cluster] = 94 67 nps_host_reg((cluster << NPS_CLUSTER_OFFSET), 95 - NPS_MSU_BLKID, NPS_MSU_TICK_LOW); 68 + NPS_MSU_BLKID, NPS_MSU_TICK_LOW); 96 69 97 - ret = clk_prepare_enable(clk); 98 - if (ret) { 99 - pr_err("Couldn't enable parent clock\n"); 70 + ret = nps_get_timer_clk(node, &nps_timer1_freq, &clk); 71 + if (ret) 100 72 return ret; 101 - } 102 73 103 - nps_timer_rate = clk_get_rate(clk); 104 - 105 - ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick", 106 - nps_timer_rate, 301, 32, nps_clksrc_read); 74 + ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick", 75 + nps_timer1_freq, 300, 32, nps_clksrc_read); 107 76 if (ret) { 108 77 pr_err("Couldn't register clock source.\n"); 109 78 clk_disable_unprepare(clk); ··· 110 83 return ret; 111 84 } 112 85 113 - static int __init nps_timer_init(struct device_node *node) 86 + CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer", 87 + nps_setup_clocksource); 88 + CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clk_src, "ezchip,nps400-timer1", 89 + nps_setup_clocksource); 90 + 91 + #ifdef CONFIG_EZNPS_MTM_EXT 92 + #include <soc/nps/mtm.h> 93 + 94 + /* Timer related Aux registers */ 95 + #define NPS_REG_TIMER0_TSI 0xFFFFF850 96 + #define NPS_REG_TIMER0_LIMIT 0x23 97 + #define NPS_REG_TIMER0_CTRL 0x22 98 + #define NPS_REG_TIMER0_CNT 0x21 99 + 100 + /* 101 + * Interrupt Enabled (IE) - re-arm the timer 102 + * Not Halted (NH) - is cleared when working with JTAG (for debug) 103 + */ 104 + #define TIMER0_CTRL_IE BIT(0) 105 + #define TIMER0_CTRL_NH BIT(1) 106 + 107 + static unsigned long nps_timer0_freq; 108 + static unsigned long nps_timer0_irq; 109 + 110 + static void nps_clkevent_rm_thread(void) 114 111 { 115 - struct clk *clk; 112 + int thread; 113 + unsigned int cflags, enabled_threads; 116 114 117 - clk = of_clk_get(node, 0); 118 - if (IS_ERR(clk)) { 119 - pr_err("Can't get timer clock.\n"); 120 - return PTR_ERR(clk); 121 - } 115 + hw_schd_save(&cflags); 122 116 123 - return nps_setup_clocksource(node, clk); 117 + enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI); 118 + 119 + /* remove thread from TSI1 */ 120 + thread = read_aux_reg(CTOP_AUX_THREAD_ID); 121 + enabled_threads &= ~(1 << thread); 122 + write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads); 123 + 124 + /* Acknowledge and if needed re-arm the timer */ 125 + if (!enabled_threads) 126 + write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH); 127 + else 128 + write_aux_reg(NPS_REG_TIMER0_CTRL, 129 + TIMER0_CTRL_IE | TIMER0_CTRL_NH); 130 + 131 + hw_schd_restore(cflags); 124 132 } 125 133 126 - CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer", 127 - nps_timer_init); 134 + static void nps_clkevent_add_thread(unsigned long delta) 135 + { 136 + int thread; 137 + unsigned int cflags, enabled_threads; 138 + 139 + hw_schd_save(&cflags); 140 + 141 + /* add thread to TSI1 */ 142 + thread = read_aux_reg(CTOP_AUX_THREAD_ID); 143 + enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI); 144 + enabled_threads |= (1 << thread); 145 + write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads); 146 + 147 + /* set next timer event */ 148 + write_aux_reg(NPS_REG_TIMER0_LIMIT, delta); 149 + write_aux_reg(NPS_REG_TIMER0_CNT, 0); 150 + write_aux_reg(NPS_REG_TIMER0_CTRL, 151 + TIMER0_CTRL_IE | TIMER0_CTRL_NH); 152 + 153 + hw_schd_restore(cflags); 154 + } 155 + 156 + /* 157 + * Whenever anyone tries to change modes, we just mask interrupts 158 + * and wait for the next event to get set. 159 + */ 160 + static int nps_clkevent_set_state(struct clock_event_device *dev) 161 + { 162 + nps_clkevent_rm_thread(); 163 + disable_percpu_irq(nps_timer0_irq); 164 + 165 + return 0; 166 + } 167 + 168 + static int nps_clkevent_set_next_event(unsigned long delta, 169 + struct clock_event_device *dev) 170 + { 171 + nps_clkevent_add_thread(delta); 172 + enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE); 173 + 174 + return 0; 175 + } 176 + 177 + static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = { 178 + .name = "NPS Timer0", 179 + .features = CLOCK_EVT_FEAT_ONESHOT, 180 + .rating = 300, 181 + .set_next_event = nps_clkevent_set_next_event, 182 + .set_state_oneshot = nps_clkevent_set_state, 183 + .set_state_oneshot_stopped = nps_clkevent_set_state, 184 + .set_state_shutdown = nps_clkevent_set_state, 185 + .tick_resume = nps_clkevent_set_state, 186 + }; 187 + 188 + static irqreturn_t timer_irq_handler(int irq, void *dev_id) 189 + { 190 + struct clock_event_device *evt = dev_id; 191 + 192 + nps_clkevent_rm_thread(); 193 + evt->event_handler(evt); 194 + 195 + return IRQ_HANDLED; 196 + } 197 + 198 + static int nps_timer_starting_cpu(unsigned int cpu) 199 + { 200 + struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device); 201 + 202 + evt->cpumask = cpumask_of(smp_processor_id()); 203 + 204 + clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX); 205 + enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE); 206 + 207 + return 0; 208 + } 209 + 210 + static int nps_timer_dying_cpu(unsigned int cpu) 211 + { 212 + disable_percpu_irq(nps_timer0_irq); 213 + return 0; 214 + } 215 + 216 + static int __init nps_setup_clockevent(struct device_node *node) 217 + { 218 + struct clk *clk; 219 + int ret; 220 + 221 + nps_timer0_irq = irq_of_parse_and_map(node, 0); 222 + if (nps_timer0_irq <= 0) { 223 + pr_err("clockevent: missing irq"); 224 + return -EINVAL; 225 + } 226 + 227 + ret = nps_get_timer_clk(node, &nps_timer0_freq, &clk); 228 + if (ret) 229 + return ret; 230 + 231 + /* Needs apriori irq_set_percpu_devid() done in intc map function */ 232 + ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler, 233 + "Timer0 (per-cpu-tick)", 234 + &nps_clockevent_device); 235 + if (ret) { 236 + pr_err("Couldn't request irq\n"); 237 + clk_disable_unprepare(clk); 238 + return ret; 239 + } 240 + 241 + ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING, 242 + "clockevents/nps:starting", 243 + nps_timer_starting_cpu, 244 + nps_timer_dying_cpu); 245 + if (ret) { 246 + pr_err("Failed to setup hotplug state"); 247 + clk_disable_unprepare(clk); 248 + free_percpu_irq(nps_timer0_irq, &nps_clockevent_device); 249 + return ret; 250 + } 251 + 252 + return 0; 253 + } 254 + 255 + CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clk_evt, "ezchip,nps400-timer0", 256 + nps_setup_clockevent); 257 + #endif /* CONFIG_EZNPS_MTM_EXT */
+63
include/soc/arc/aux.h
··· 1 + /* 2 + * Copyright (C) 2016-2017 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + */ 9 + 10 + #ifndef __SOC_ARC_AUX_H__ 11 + #define __SOC_ARC_AUX_H__ 12 + 13 + #ifdef CONFIG_ARC 14 + 15 + #define read_aux_reg(r) __builtin_arc_lr(r) 16 + 17 + /* gcc builtin sr needs reg param to be long immediate */ 18 + #define write_aux_reg(r, v) __builtin_arc_sr((unsigned int)(v), r) 19 + 20 + #else /* !CONFIG_ARC */ 21 + 22 + static inline int read_aux_reg(u32 r) 23 + { 24 + return 0; 25 + } 26 + 27 + /* 28 + * function helps elide unused variable warning 29 + * see: http://lists.infradead.org/pipermail/linux-snps-arc/2016-November/001748.html 30 + */ 31 + static inline void write_aux_reg(u32 r, u32 v) 32 + { 33 + ; 34 + } 35 + 36 + #endif 37 + 38 + #define READ_BCR(reg, into) \ 39 + { \ 40 + unsigned int tmp; \ 41 + tmp = read_aux_reg(reg); \ 42 + if (sizeof(tmp) == sizeof(into)) { \ 43 + into = *((typeof(into) *)&tmp); \ 44 + } else { \ 45 + extern void bogus_undefined(void); \ 46 + bogus_undefined(); \ 47 + } \ 48 + } 49 + 50 + #define WRITE_AUX(reg, into) \ 51 + { \ 52 + unsigned int tmp; \ 53 + if (sizeof(tmp) == sizeof(into)) { \ 54 + tmp = (*(unsigned int *)&(into)); \ 55 + write_aux_reg(reg, tmp); \ 56 + } else { \ 57 + extern void bogus_undefined(void); \ 58 + bogus_undefined(); \ 59 + } \ 60 + } 61 + 62 + 63 + #endif
+38
include/soc/arc/timers.h
··· 1 + /* 2 + * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __SOC_ARC_TIMERS_H 10 + #define __SOC_ARC_TIMERS_H 11 + 12 + #include <soc/arc/aux.h> 13 + 14 + /* Timer related Aux registers */ 15 + #define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */ 16 + #define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */ 17 + #define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */ 18 + #define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */ 19 + #define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */ 20 + #define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */ 21 + 22 + /* CTRL reg bits */ 23 + #define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ 24 + #define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ 25 + 26 + #define ARC_TIMERN_MAX 0xFFFFFFFF 27 + 28 + #define ARC_REG_TIMERS_BCR 0x75 29 + 30 + struct bcr_timer { 31 + #ifdef CONFIG_CPU_BIG_ENDIAN 32 + unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8; 33 + #else 34 + unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15; 35 + #endif 36 + }; 37 + 38 + #endif
+59
include/soc/nps/mtm.h
··· 1 + /* 2 + * Copyright (c) 2016, Mellanox Technologies. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + */ 32 + 33 + #ifndef SOC_NPS_MTM_H 34 + #define SOC_NPS_MTM_H 35 + 36 + #define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF 37 + #define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3 38 + 39 + static inline void hw_schd_save(unsigned int *flags) 40 + { 41 + __asm__ __volatile__( 42 + " .word %1\n" 43 + " st r3,[%0]\n" 44 + : 45 + : "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3) 46 + : "r3", "memory"); 47 + } 48 + 49 + static inline void hw_schd_restore(unsigned int flags) 50 + { 51 + __asm__ __volatile__( 52 + " mov r3, %0\n" 53 + " .word %1\n" 54 + : 55 + : "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3) 56 + : "r3"); 57 + } 58 + 59 + #endif /* SOC_NPS_MTM_H */