ARC fixes for 4.5
- Corner case of returning to delay slot from interrupt - Changing default interrupt prioiry level - Kconfig'ize support for super pages - Other minor fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWvxdUAAoJEGnX8d3iisJeRkYP/2HZAt4J6c5MPk/NSy8rabVX 2bB1m5jYXlBmJAIsmWm+WcDL72MdrB1Owtc5tEN+hIoQQa2QQpxolp32IslHg0o8 C9CCzmF+iR8wz3caVk3javpsbze23XbHho/kdx/l2Ed3Fi+syI/9jF1GiboydRtR X22an1lslA6Y44pYxFmSFcMCv7XclFkJNe1ltxsgN9/QapnNrE/HWqUIy+SMr2Oo Tpo3m/Dc+IfMMejYyupc3keyAhyeux69lJXPuOzYiurgGUIyXz15Un2mQ9gZWf0u W56L/55VpQVuah46qrp5CBTLmdJA5cBqr0F8RqmZAqrEYLgn5SD4IhDjamo1qsP/ FfFh0cG955SoEyCsUOPILWUFR5TeS4rJK+ZJjErUb+dwEC1BWZR0/Dn1s9KJN8b7 GgGV8yXruDACFlFnCqnlxVs1TKOPOUqD2NZRAdsKunp+ywNrvGdD43xWONcriyvr 2KW0nb+mH3RRk8HQzKjfqsVhLMoR7n1MD/+tg8ME8usLn1ik0hBerT56CX0Wh/yQ VnOUX6xqlaRydeJJgCUyByz3+jJVvj8sk/VZbr19F0p9id6wpiPQeNus2AcoHFKW OyvWcfxzqKegXrYtMsy8IoFzx73zJaXV3ht0I09rhAj3JkdF7vFEIUpKIhsWqxAK yWKKqLcVKga/2Yc8jduI =FNDd -----END PGP SIGNATURE----- Merge tag 'arc-4.5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc Pull ARC fixes from Vineet Gupta: "I've been sitting on some of these fixes for a while. - Corner case of returning to delay slot from interrupt - Changing default interrupt prioiry level - Kconfig'ize support for super pages - Other minor fixes" * tag 'arc-4.5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: ARC: mm: Introduce explicit super page size support ARCv2: intc: Allow interruption by lowest priority interrupt ARCv2: Check for LL-SC livelock only if LLSC is enabled ARC: shrink cpuinfo by not saving full timer BCR ARCv2: clocksource: Rename GRTC -> GFRC ... ARCv2: STAR 9000950267: Handle return from intr to Delay Slot #2
This commit is contained in:
commit
e835a65f7a
11 changed files with 119 additions and 61 deletions
|
@ -338,6 +338,19 @@ config ARC_PAGE_SIZE_4K
|
|||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "MMU Super Page Size"
|
||||
depends on ISA_ARCV2 && TRANSPARENT_HUGEPAGE
|
||||
default ARC_HUGEPAGE_2M
|
||||
|
||||
config ARC_HUGEPAGE_2M
|
||||
bool "2MB"
|
||||
|
||||
config ARC_HUGEPAGE_16M
|
||||
bool "16MB"
|
||||
|
||||
endchoice
|
||||
|
||||
if ISA_ARCOMPACT
|
||||
|
||||
config ARC_COMPACT_IRQ_LEVELS
|
||||
|
@ -410,7 +423,7 @@ config ARC_HAS_RTC
|
|||
default n
|
||||
depends on !SMP
|
||||
|
||||
config ARC_HAS_GRTC
|
||||
config ARC_HAS_GFRC
|
||||
bool "SMP synchronized 64-bit cycle counter"
|
||||
default y
|
||||
depends on SMP
|
||||
|
@ -566,6 +579,12 @@ endmenu
|
|||
endmenu # "ARC Architecture Configuration"
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config FORCE_MAX_ZONEORDER
|
||||
int "Maximum zone order"
|
||||
default "12" if ARC_HUGEPAGE_16M
|
||||
default "11"
|
||||
|
||||
source "net/Kconfig"
|
||||
source "drivers/Kconfig"
|
||||
source "fs/Kconfig"
|
||||
|
|
|
@ -16,7 +16,7 @@ CONFIG_ARC_PLAT_AXS10X=y
|
|||
CONFIG_AXS103=y
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_ARC_HAS_GRTC is not set
|
||||
# CONFIG_ARC_HAS_GFRC is not set
|
||||
CONFIG_ARC_UBOOT_SUPPORT=y
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
|
||||
CONFIG_PREEMPT=y
|
||||
|
|
|
@ -349,14 +349,13 @@ struct cpuinfo_arc {
|
|||
struct cpuinfo_arc_bpu bpu;
|
||||
struct bcr_identity core;
|
||||
struct bcr_isa isa;
|
||||
struct bcr_timer timers;
|
||||
unsigned int vec_base;
|
||||
struct cpuinfo_arc_ccm iccm, dccm;
|
||||
struct {
|
||||
unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3,
|
||||
fpu_sp:1, fpu_dp:1, pad2:6,
|
||||
debug:1, ap:1, smart:1, rtt:1, pad3:4,
|
||||
pad4:8;
|
||||
timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4;
|
||||
} extn;
|
||||
struct bcr_mpy extn_mpy;
|
||||
struct bcr_extn_xymem extn_xymem;
|
||||
|
|
|
@ -30,8 +30,11 @@
|
|||
/* Was Intr taken in User Mode */
|
||||
#define AUX_IRQ_ACT_BIT_U 31
|
||||
|
||||
/* 0 is highest level, but taken by FIRQs, if present in design */
|
||||
#define ARCV2_IRQ_DEF_PRIO 0
|
||||
/*
|
||||
* User space should be interruptable even by lowest prio interrupt
|
||||
* Safe even if actual interrupt priorities is fewer or even one
|
||||
*/
|
||||
#define ARCV2_IRQ_DEF_PRIO 15
|
||||
|
||||
/* seed value for status register */
|
||||
#define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \
|
||||
|
|
|
@ -39,8 +39,8 @@ struct mcip_cmd {
|
|||
#define CMD_DEBUG_SET_MASK 0x34
|
||||
#define CMD_DEBUG_SET_SELECT 0x36
|
||||
|
||||
#define CMD_GRTC_READ_LO 0x42
|
||||
#define CMD_GRTC_READ_HI 0x43
|
||||
#define CMD_GFRC_READ_LO 0x42
|
||||
#define CMD_GFRC_READ_HI 0x43
|
||||
|
||||
#define CMD_IDU_ENABLE 0x71
|
||||
#define CMD_IDU_DISABLE 0x72
|
||||
|
|
|
@ -179,37 +179,44 @@
|
|||
#define __S111 PAGE_U_X_W_R
|
||||
|
||||
/****************************************************************
|
||||
* Page Table Lookup split
|
||||
* 2 tier (PGD:PTE) software page walker
|
||||
*
|
||||
* We implement 2 tier paging and since this is all software, we are free
|
||||
* to customize the span of a PGD / PTE entry to suit us
|
||||
*
|
||||
* 32 bit virtual address
|
||||
* [31] 32 bit virtual address [0]
|
||||
* -------------------------------------------------------
|
||||
* | BITS_FOR_PGD | BITS_FOR_PTE | BITS_IN_PAGE |
|
||||
* | | <------------ PGDIR_SHIFT ----------> |
|
||||
* | | |
|
||||
* | BITS_FOR_PGD | BITS_FOR_PTE | <-- PAGE_SHIFT --> |
|
||||
* -------------------------------------------------------
|
||||
* | | |
|
||||
* | | --> off in page frame
|
||||
* | |
|
||||
* | ---> index into Page Table
|
||||
* |
|
||||
* ----> index into Page Directory
|
||||
*
|
||||
* In a single page size configuration, only PAGE_SHIFT is fixed
|
||||
* So both PGD and PTE sizing can be tweaked
|
||||
* e.g. 8K page (PAGE_SHIFT 13) can have
|
||||
* - PGDIR_SHIFT 21 -> 11:8:13 address split
|
||||
* - PGDIR_SHIFT 24 -> 8:11:13 address split
|
||||
*
|
||||
* If Super Page is configured, PGDIR_SHIFT becomes fixed too,
|
||||
* so the sizing flexibility is gone.
|
||||
*/
|
||||
|
||||
#define BITS_IN_PAGE PAGE_SHIFT
|
||||
|
||||
/* Optimal Sizing of Pg Tbl - based on MMU page size */
|
||||
#if defined(CONFIG_ARC_PAGE_SIZE_8K)
|
||||
#define BITS_FOR_PTE 8 /* 11:8:13 */
|
||||
#elif defined(CONFIG_ARC_PAGE_SIZE_16K)
|
||||
#define BITS_FOR_PTE 8 /* 10:8:14 */
|
||||
#elif defined(CONFIG_ARC_PAGE_SIZE_4K)
|
||||
#define BITS_FOR_PTE 9 /* 11:9:12 */
|
||||
#if defined(CONFIG_ARC_HUGEPAGE_16M)
|
||||
#define PGDIR_SHIFT 24
|
||||
#elif defined(CONFIG_ARC_HUGEPAGE_2M)
|
||||
#define PGDIR_SHIFT 21
|
||||
#else
|
||||
/*
|
||||
* Only Normal page support so "hackable" (see comment above)
|
||||
* Default value provides 11:8:13 (8K), 11:9:12 (4K)
|
||||
*/
|
||||
#define PGDIR_SHIFT 21
|
||||
#endif
|
||||
|
||||
#define BITS_FOR_PGD (32 - BITS_FOR_PTE - BITS_IN_PAGE)
|
||||
#define BITS_FOR_PTE (PGDIR_SHIFT - PAGE_SHIFT)
|
||||
#define BITS_FOR_PGD (32 - PGDIR_SHIFT)
|
||||
|
||||
#define PGDIR_SHIFT (32 - BITS_FOR_PGD)
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT) /* vaddr span, not PDG sz */
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
|
|
|
@ -211,7 +211,11 @@ debug_marker_syscall:
|
|||
; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig
|
||||
; entry was via Exception in DS which got preempted in kernel).
|
||||
;
|
||||
; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling
|
||||
; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround
|
||||
;
|
||||
; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline
|
||||
; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly
|
||||
|
||||
.Lintr_ret_to_delay_slot:
|
||||
debug_marker_ds:
|
||||
|
||||
|
@ -222,18 +226,23 @@ debug_marker_ds:
|
|||
ld r2, [sp, PT_ret]
|
||||
ld r3, [sp, PT_status32]
|
||||
|
||||
; STAT32 for Int return created from scratch
|
||||
; (No delay dlot, disable Further intr in trampoline)
|
||||
|
||||
bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK
|
||||
st r0, [sp, PT_status32]
|
||||
|
||||
mov r1, .Lintr_ret_to_delay_slot_2
|
||||
st r1, [sp, PT_ret]
|
||||
|
||||
; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots
|
||||
st r2, [sp, 0]
|
||||
st r3, [sp, 4]
|
||||
|
||||
b .Lisr_ret_fast_path
|
||||
|
||||
.Lintr_ret_to_delay_slot_2:
|
||||
; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP
|
||||
sub sp, sp, SZ_PT_REGS
|
||||
st r9, [sp, -4]
|
||||
|
||||
|
@ -243,11 +252,19 @@ debug_marker_ds:
|
|||
ld r9, [sp, 4]
|
||||
sr r9, [erstatus]
|
||||
|
||||
; restore AUX_USER_SP if returning to U mode
|
||||
bbit0 r9, STATUS_U_BIT, 1f
|
||||
ld r9, [sp, PT_sp]
|
||||
sr r9, [AUX_USER_SP]
|
||||
|
||||
1:
|
||||
ld r9, [sp, 8]
|
||||
sr r9, [erbta]
|
||||
|
||||
ld r9, [sp, -4]
|
||||
add sp, sp, SZ_PT_REGS
|
||||
|
||||
; return from pure kernel mode to delay slot
|
||||
rtie
|
||||
|
||||
END(ret_from_exception)
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <linux/irqchip.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
static int irq_prio;
|
||||
|
||||
/*
|
||||
* Early Hardware specific Interrupt setup
|
||||
* -Called very early (start_kernel -> setup_arch -> setup_processor)
|
||||
|
@ -24,6 +26,14 @@ void arc_init_IRQ(void)
|
|||
{
|
||||
unsigned int tmp;
|
||||
|
||||
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 {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int res3:18, save_idx_regs:1, res2:1,
|
||||
|
@ -46,28 +56,25 @@ void arc_init_IRQ(void)
|
|||
|
||||
WRITE_AUX(AUX_IRQ_CTRL, ictrl);
|
||||
|
||||
/* setup status32, don't enable intr yet as kernel doesn't want */
|
||||
tmp = read_aux_reg(0xa);
|
||||
tmp |= ISA_INIT_STATUS_BITS;
|
||||
tmp &= ~STATUS_IE_MASK;
|
||||
asm volatile("flag %0 \n"::"r"(tmp));
|
||||
|
||||
/*
|
||||
* ARCv2 core intc provides multiple interrupt priorities (upto 16).
|
||||
* Typical builds though have only two levels (0-high, 1-low)
|
||||
* Linux by default uses lower prio 1 for most irqs, reserving 0 for
|
||||
* NMI style interrupts in future (say perf)
|
||||
*
|
||||
* Read the intc BCR to confirm that Linux default priority is avail
|
||||
* in h/w
|
||||
*
|
||||
* Note:
|
||||
* IRQ_BCR[27..24] contains N-1 (for N priority levels) and prio level
|
||||
* is 0 based.
|
||||
*/
|
||||
tmp = (read_aux_reg(ARC_REG_IRQ_BCR) >> 24 ) & 0xF;
|
||||
if (ARCV2_IRQ_DEF_PRIO > tmp)
|
||||
panic("Linux default irq prio incorrect\n");
|
||||
|
||||
READ_BCR(ARC_REG_IRQ_BCR, irq_bcr);
|
||||
|
||||
irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */
|
||||
pr_info("archs-intc\t: %d priority levels (default %d)%s\n",
|
||||
irq_prio + 1, irq_prio,
|
||||
irq_bcr.firq ? " FIRQ (not used)":"");
|
||||
|
||||
/* setup status32, don't enable intr yet as kernel doesn't want */
|
||||
tmp = read_aux_reg(0xa);
|
||||
tmp |= STATUS_AD_MASK | (irq_prio << 1);
|
||||
tmp &= ~STATUS_IE_MASK;
|
||||
asm volatile("flag %0 \n"::"r"(tmp));
|
||||
}
|
||||
|
||||
static void arcv2_irq_mask(struct irq_data *data)
|
||||
|
@ -86,7 +93,7 @@ void arcv2_irq_enable(struct irq_data *data)
|
|||
{
|
||||
/* set default priority */
|
||||
write_aux_reg(AUX_IRQ_SELECT, data->irq);
|
||||
write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO);
|
||||
write_aux_reg(AUX_IRQ_PRIORITY, irq_prio);
|
||||
|
||||
/*
|
||||
* hw auto enables (linux unmask) all by default
|
||||
|
|
|
@ -96,13 +96,13 @@ static void mcip_probe_n_setup(void)
|
|||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad3:8,
|
||||
idu:1, llm:1, num_cores:6,
|
||||
iocoh:1, grtc:1, dbg:1, pad2:1,
|
||||
iocoh:1, gfrc:1, dbg:1, pad2:1,
|
||||
msg:1, sem:1, ipi:1, pad:1,
|
||||
ver:8;
|
||||
#else
|
||||
unsigned int ver:8,
|
||||
pad:1, ipi:1, sem:1, msg:1,
|
||||
pad2:1, dbg:1, grtc:1, iocoh:1,
|
||||
pad2:1, dbg:1, gfrc:1, iocoh:1,
|
||||
num_cores:6, llm:1, idu:1,
|
||||
pad3:8;
|
||||
#endif
|
||||
|
@ -116,7 +116,7 @@ static void mcip_probe_n_setup(void)
|
|||
IS_AVAIL1(mp.ipi, "IPI "),
|
||||
IS_AVAIL1(mp.idu, "IDU "),
|
||||
IS_AVAIL1(mp.dbg, "DEBUG "),
|
||||
IS_AVAIL1(mp.grtc, "GRTC"));
|
||||
IS_AVAIL1(mp.gfrc, "GFRC"));
|
||||
|
||||
idu_detected = mp.idu;
|
||||
|
||||
|
@ -125,8 +125,8 @@ static void mcip_probe_n_setup(void)
|
|||
__mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARC_HAS_GRTC) && !mp.grtc)
|
||||
panic("kernel trying to use non-existent GRTC\n");
|
||||
if (IS_ENABLED(CONFIG_ARC_HAS_GFRC) && !mp.gfrc)
|
||||
panic("kernel trying to use non-existent GFRC\n");
|
||||
}
|
||||
|
||||
struct plat_smp_ops plat_smp_ops = {
|
||||
|
|
|
@ -45,6 +45,7 @@ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
|
|||
static void read_arc_build_cfg_regs(void)
|
||||
{
|
||||
struct bcr_perip uncached_space;
|
||||
struct bcr_timer timer;
|
||||
struct bcr_generic bcr;
|
||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
||||
unsigned long perip_space;
|
||||
|
@ -53,7 +54,11 @@ static void read_arc_build_cfg_regs(void)
|
|||
READ_BCR(AUX_IDENTITY, cpu->core);
|
||||
READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa);
|
||||
|
||||
READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers);
|
||||
READ_BCR(ARC_REG_TIMERS_BCR, timer);
|
||||
cpu->extn.timer0 = timer.t0;
|
||||
cpu->extn.timer1 = timer.t1;
|
||||
cpu->extn.rtc = timer.rtc;
|
||||
|
||||
cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE);
|
||||
|
||||
READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
|
||||
|
@ -208,9 +213,9 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
|
|||
(unsigned int)(arc_get_core_freq() / 10000) % 100);
|
||||
|
||||
n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
|
||||
IS_AVAIL1(cpu->timers.t0, "Timer0 "),
|
||||
IS_AVAIL1(cpu->timers.t1, "Timer1 "),
|
||||
IS_AVAIL2(cpu->timers.rtc, "64-bit RTC ",
|
||||
IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
|
||||
IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
|
||||
IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
|
||||
CONFIG_ARC_HAS_RTC));
|
||||
|
||||
n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
|
||||
|
@ -293,13 +298,13 @@ static void arc_chk_core_config(void)
|
|||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
||||
int fpu_enabled;
|
||||
|
||||
if (!cpu->timers.t0)
|
||||
if (!cpu->extn.timer0)
|
||||
panic("Timer0 is not present!\n");
|
||||
|
||||
if (!cpu->timers.t1)
|
||||
if (!cpu->extn.timer1)
|
||||
panic("Timer1 is not present!\n");
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->timers.rtc)
|
||||
if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->extn.rtc)
|
||||
panic("RTC is not present\n");
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_DCCM
|
||||
|
@ -334,6 +339,7 @@ static void arc_chk_core_config(void)
|
|||
panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
|
||||
|
||||
if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic &&
|
||||
IS_ENABLED(CONFIG_ARC_HAS_LLSC) &&
|
||||
!IS_ENABLED(CONFIG_ARC_STAR_9000923308))
|
||||
panic("llock/scond livelock workaround missing\n");
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
/********** Clock Source Device *********/
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_GRTC
|
||||
#ifdef CONFIG_ARC_HAS_GFRC
|
||||
|
||||
static int arc_counter_setup(void)
|
||||
{
|
||||
|
@ -83,10 +83,10 @@ static cycle_t arc_counter_read(struct clocksource *cs)
|
|||
|
||||
local_irq_save(flags);
|
||||
|
||||
__mcip_cmd(CMD_GRTC_READ_LO, 0);
|
||||
__mcip_cmd(CMD_GFRC_READ_LO, 0);
|
||||
stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK);
|
||||
|
||||
__mcip_cmd(CMD_GRTC_READ_HI, 0);
|
||||
__mcip_cmd(CMD_GFRC_READ_HI, 0);
|
||||
stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
@ -95,7 +95,7 @@ static cycle_t arc_counter_read(struct clocksource *cs)
|
|||
}
|
||||
|
||||
static struct clocksource arc_counter = {
|
||||
.name = "ARConnect GRTC",
|
||||
.name = "ARConnect GFRC",
|
||||
.rating = 400,
|
||||
.read = arc_counter_read,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
|
|
Loading…
Reference in a new issue