Some MIPS fixes for the 5.4 cycle:
- Build fixes for Cavium Octeon & PMC-Sierra MSP systems, as well as all pre-MIPSr6 configurations built with binutils < 2.25. - Boot fixes for 64-bit Loongson systems & SGI IP28 systems. - Wire up the new clone3 syscall. - Clean ups for a few build-time warnings. -----BEGIN PGP SIGNATURE----- iIsEABYIADMWIQRgLjeFAZEXQzy86/s+p5+stXUA3QUCXZekBBUccGF1bC5idXJ0 b25AbWlwcy5jb20ACgkQPqefrLV1AN1aSQD+OSdb9fs1Gqakn1bM/TmvAB5lNxhM 8Xy47aqWURt4rpIBAJegfqjq2SWyVNxeNV0fNcqQl9DcjABhOyCJ316U6rMD =TNtT -----END PGP SIGNATURE----- Merge tag 'mips_fixes_5.4_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux Pull MIPS fixes from Paul Burton: - Build fixes for Cavium Octeon & PMC-Sierra MSP systems, as well as all pre-MIPSr6 configurations built with binutils < 2.25. - Boot fixes for 64-bit Loongson systems & SGI IP28 systems. - Wire up the new clone3 syscall. - Clean ups for a few build-time warnings. * tag 'mips_fixes_5.4_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: MIPS: fw/arc: Remove unused addr variable MIPS: pmcs-msp71xx: Remove unused addr variable MIPS: pmcs-msp71xx: Add missing MAX_PROM_MEM definition mips: Loongson: Fix the link time qualifier of 'serial_exit()' MIPS: init: Prevent adding memory before PHYS_OFFSET MIPS: init: Fix reservation of memory between PHYS_OFFSET and mem start MIPS: VDSO: Fix build for binutils < 2.25 MIPS: VDSO: Remove unused gettimeofday.c MIPS: Wire up clone3 syscall MIPS: octeon: Include required header; fix octeon ethernet build MIPS: cpu-bugs64: Mark inline functions as __always_inline MIPS: dts: ar9331: fix interrupt-controller size MIPS: Loongson64: Fix boot failure after dropping boot_mem_map
This commit is contained in:
commit
4ea655343c
|
@ -99,7 +99,7 @@
|
|||
|
||||
miscintc: interrupt-controller@18060010 {
|
||||
compatible = "qca,ar7240-misc-intc";
|
||||
reg = <0x18060010 0x4>;
|
||||
reg = <0x18060010 0x8>;
|
||||
|
||||
interrupt-parent = <&cpuintc>;
|
||||
interrupts = <6>;
|
||||
|
|
|
@ -160,7 +160,6 @@ void __init prom_meminit(void)
|
|||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
int i;
|
||||
|
||||
if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <asm/octeon/octeon-feature.h>
|
||||
|
||||
#include <asm/octeon/cvmx-ipd-defs.h>
|
||||
#include <asm/octeon/cvmx-pip-defs.h>
|
||||
|
||||
enum cvmx_ipd_mode {
|
||||
CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
# endif
|
||||
#define __ARCH_WANT_SYS_FORK
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
#define __ARCH_WANT_SYS_CLONE3
|
||||
|
||||
/* whitelists for checksyscalls */
|
||||
#define __IGNORE_fadvise64_64
|
||||
|
|
|
@ -24,7 +24,8 @@ static char r4kwar[] __initdata =
|
|||
static char daddiwar[] __initdata =
|
||||
"Enable CPU_DADDI_WORKAROUNDS to rectify.";
|
||||
|
||||
static inline void align_mod(const int align, const int mod)
|
||||
static __always_inline __init
|
||||
void align_mod(const int align, const int mod)
|
||||
{
|
||||
asm volatile(
|
||||
".set push\n\t"
|
||||
|
@ -38,8 +39,9 @@ static inline void align_mod(const int align, const int mod)
|
|||
: "n"(align), "n"(mod));
|
||||
}
|
||||
|
||||
static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w,
|
||||
const int align, const int mod)
|
||||
static __always_inline __init
|
||||
void mult_sh_align_mod(long *v1, long *v2, long *w,
|
||||
const int align, const int mod)
|
||||
{
|
||||
unsigned long flags;
|
||||
int m1, m2;
|
||||
|
@ -113,7 +115,7 @@ static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w,
|
|||
*w = lw;
|
||||
}
|
||||
|
||||
static inline void check_mult_sh(void)
|
||||
static __always_inline __init void check_mult_sh(void)
|
||||
{
|
||||
long v1[8], v2[8], w[8];
|
||||
int bug, fix, i;
|
||||
|
@ -176,7 +178,7 @@ asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
|
|||
exception_exit(prev_state);
|
||||
}
|
||||
|
||||
static inline void check_daddi(void)
|
||||
static __init void check_daddi(void)
|
||||
{
|
||||
extern asmlinkage void handle_daddi_ov(void);
|
||||
unsigned long flags;
|
||||
|
@ -242,7 +244,7 @@ static inline void check_daddi(void)
|
|||
|
||||
int daddiu_bug = IS_ENABLED(CONFIG_CPU_MIPSR6) ? 0 : -1;
|
||||
|
||||
static inline void check_daddiu(void)
|
||||
static __init void check_daddiu(void)
|
||||
{
|
||||
long v, w, tmp;
|
||||
|
||||
|
|
|
@ -108,6 +108,9 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
|
|||
return;
|
||||
}
|
||||
|
||||
if (start < PHYS_OFFSET)
|
||||
return;
|
||||
|
||||
memblock_add(start, size);
|
||||
/* Reserve any memory except the ordinary RAM ranges. */
|
||||
switch (type) {
|
||||
|
@ -321,7 +324,7 @@ static void __init bootmem_init(void)
|
|||
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
||||
*/
|
||||
if (ramstart > PHYS_OFFSET)
|
||||
memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
|
||||
memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
|
||||
|
||||
if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
|
||||
pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
|
||||
|
|
|
@ -80,6 +80,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
|
|||
|
||||
save_static_function(sys_fork);
|
||||
save_static_function(sys_clone);
|
||||
save_static_function(sys_clone3);
|
||||
|
||||
SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
|
||||
{
|
||||
|
|
|
@ -373,4 +373,4 @@
|
|||
432 n32 fsmount sys_fsmount
|
||||
433 n32 fspick sys_fspick
|
||||
434 n32 pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
435 n32 clone3 __sys_clone3
|
||||
|
|
|
@ -349,4 +349,4 @@
|
|||
432 n64 fsmount sys_fsmount
|
||||
433 n64 fspick sys_fspick
|
||||
434 n64 pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
435 n64 clone3 __sys_clone3
|
||||
|
|
|
@ -422,4 +422,4 @@
|
|||
432 o32 fsmount sys_fsmount
|
||||
433 o32 fspick sys_fspick
|
||||
434 o32 pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
435 o32 clone3 __sys_clone3
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
|
@ -64,24 +65,22 @@ void __init prom_init_memory(void)
|
|||
node_id = loongson_memmap->map[i].node_id;
|
||||
mem_type = loongson_memmap->map[i].mem_type;
|
||||
|
||||
if (node_id == 0) {
|
||||
switch (mem_type) {
|
||||
case SYSTEM_RAM_LOW:
|
||||
add_memory_region(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20,
|
||||
BOOT_MEM_RAM);
|
||||
break;
|
||||
case SYSTEM_RAM_HIGH:
|
||||
add_memory_region(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20,
|
||||
BOOT_MEM_RAM);
|
||||
break;
|
||||
case SYSTEM_RAM_RESERVED:
|
||||
add_memory_region(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20,
|
||||
BOOT_MEM_RESERVED);
|
||||
break;
|
||||
}
|
||||
if (node_id != 0)
|
||||
continue;
|
||||
|
||||
switch (mem_type) {
|
||||
case SYSTEM_RAM_LOW:
|
||||
memblock_add(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20);
|
||||
break;
|
||||
case SYSTEM_RAM_HIGH:
|
||||
memblock_add(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20);
|
||||
break;
|
||||
case SYSTEM_RAM_RESERVED:
|
||||
memblock_reserve(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ static int __init serial_init(void)
|
|||
}
|
||||
module_init(serial_init);
|
||||
|
||||
static void __init serial_exit(void)
|
||||
static void __exit serial_exit(void)
|
||||
{
|
||||
platform_device_unregister(&uart8250_device);
|
||||
}
|
||||
|
|
|
@ -142,8 +142,6 @@ static void __init szmem(unsigned int node)
|
|||
(u32)node_id, mem_type, mem_start, mem_size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
start_pfn, end_pfn, num_physpages);
|
||||
add_memory_region((node_id << 44) + mem_start,
|
||||
(u64)mem_size << 20, BOOT_MEM_RAM);
|
||||
memblock_add_node(PFN_PHYS(start_pfn),
|
||||
PFN_PHYS(end_pfn - start_pfn), node);
|
||||
break;
|
||||
|
@ -156,16 +154,12 @@ static void __init szmem(unsigned int node)
|
|||
(u32)node_id, mem_type, mem_start, mem_size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
start_pfn, end_pfn, num_physpages);
|
||||
add_memory_region((node_id << 44) + mem_start,
|
||||
(u64)mem_size << 20, BOOT_MEM_RAM);
|
||||
memblock_add_node(PFN_PHYS(start_pfn),
|
||||
PFN_PHYS(end_pfn - start_pfn), node);
|
||||
break;
|
||||
case SYSTEM_RAM_RESERVED:
|
||||
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n",
|
||||
(u32)node_id, mem_type, mem_start, mem_size);
|
||||
add_memory_region((node_id << 44) + mem_start,
|
||||
(u64)mem_size << 20, BOOT_MEM_RESERVED);
|
||||
memblock_reserve(((node_id << 44) + mem_start),
|
||||
mem_size << 20);
|
||||
break;
|
||||
|
@ -191,8 +185,6 @@ static void __init node_mem_init(unsigned int node)
|
|||
NODE_DATA(node)->node_start_pfn = start_pfn;
|
||||
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
|
||||
|
||||
free_bootmem_with_active_regions(node, end_pfn);
|
||||
|
||||
if (node == 0) {
|
||||
/* kernel end address */
|
||||
unsigned long kernel_end_pfn = PFN_UP(__pa_symbol(&_end));
|
||||
|
@ -209,8 +201,6 @@ static void __init node_mem_init(unsigned int node)
|
|||
memblock_reserve((node_addrspace_offset | 0xfe000000),
|
||||
32 << 20);
|
||||
}
|
||||
|
||||
sparse_memory_present_with_active_regions(node);
|
||||
}
|
||||
|
||||
static __init void prom_meminit(void)
|
||||
|
@ -227,6 +217,7 @@ static __init void prom_meminit(void)
|
|||
cpumask_clear(&__node_data[(node)]->cpumask);
|
||||
}
|
||||
}
|
||||
memblocks_present();
|
||||
max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
|
||||
|
||||
for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) {
|
||||
|
|
|
@ -61,6 +61,7 @@ int init_debug = 1;
|
|||
/* memory blocks */
|
||||
struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
|
||||
|
||||
#define MAX_PROM_MEM 5
|
||||
static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
|
||||
static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
|
||||
static unsigned int nr_prom_mem __initdata;
|
||||
|
@ -358,7 +359,7 @@ void __init prom_meminit(void)
|
|||
p++;
|
||||
|
||||
if (type == BOOT_MEM_ROM_DATA) {
|
||||
if (nr_prom_mem >= 5) {
|
||||
if (nr_prom_mem >= MAX_PROM_MEM) {
|
||||
pr_err("Too many ROM DATA regions");
|
||||
continue;
|
||||
}
|
||||
|
@ -377,7 +378,6 @@ void __init prom_free_prom_memory(void)
|
|||
char *ptr;
|
||||
int len = 0;
|
||||
int i;
|
||||
unsigned long addr;
|
||||
|
||||
/*
|
||||
* preserve environment variables and command line from pmon/bbload
|
||||
|
|
|
@ -59,7 +59,7 @@ CFLAGS_REMOVE_vgettimeofday.o = -pg
|
|||
ifndef CONFIG_CPU_MIPSR6
|
||||
ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
|
||||
$(warning MIPS VDSO requires binutils >= 2.25)
|
||||
obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
|
||||
obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y))
|
||||
ccflags-vdso += -DDISABLE_MIPS_VDSO
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -1,269 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2015 Imagination Technologies
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*/
|
||||
|
||||
#include "vdso.h"
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/clocksource.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
|
||||
|
||||
static __always_inline long gettimeofday_fallback(struct timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
register struct timezone *tz asm("a1") = _tz;
|
||||
register struct timeval *tv asm("a0") = _tv;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_gettimeofday;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (tv), "r" (tz), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline long clock_gettime_fallback(clockid_t _clkid,
|
||||
struct timespec *_ts)
|
||||
{
|
||||
register struct timespec *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_clock_gettime;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
static __always_inline int do_realtime_coarse(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __always_inline int do_monotonic_coarse(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
u64 to_mono_sec;
|
||||
u64 to_mono_nsec;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
|
||||
|
||||
to_mono_sec = data->wall_to_mono_sec;
|
||||
to_mono_nsec = data->wall_to_mono_nsec;
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
ts->tv_sec += to_mono_sec;
|
||||
timespec_add_ns(ts, to_mono_nsec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
|
||||
static __always_inline u64 read_r4k_count(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push\n"
|
||||
" .set mips32r2\n"
|
||||
" rdhwr %0, $2\n"
|
||||
" .set pop\n"
|
||||
: "=r" (count));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
|
||||
static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
|
||||
{
|
||||
void __iomem *gic = get_gic(data);
|
||||
u32 hi, hi2, lo;
|
||||
|
||||
do {
|
||||
hi = __raw_readl(gic + sizeof(lo));
|
||||
lo = __raw_readl(gic);
|
||||
hi2 = __raw_readl(gic + sizeof(lo));
|
||||
} while (hi2 != hi);
|
||||
|
||||
return (((u64)hi) << 32) + lo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline u64 get_ns(const union mips_vdso_data *data)
|
||||
{
|
||||
u64 cycle_now, delta, nsec;
|
||||
|
||||
switch (data->clock_mode) {
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
case VDSO_CLOCK_R4K:
|
||||
cycle_now = read_r4k_count();
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
case VDSO_CLOCK_GIC:
|
||||
cycle_now = read_gic_count(data);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
delta = (cycle_now - data->cs_cycle_last) & data->cs_mask;
|
||||
|
||||
nsec = (delta * data->cs_mult) + data->xtime_nsec;
|
||||
nsec >>= data->cs_shift;
|
||||
|
||||
return nsec;
|
||||
}
|
||||
|
||||
static __always_inline int do_realtime(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
u64 ns;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
if (data->clock_mode == VDSO_CLOCK_NONE)
|
||||
return -ENOSYS;
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ns = get_ns(data);
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
ts->tv_nsec = 0;
|
||||
timespec_add_ns(ts, ns);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __always_inline int do_monotonic(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
u64 ns;
|
||||
u64 to_mono_sec;
|
||||
u64 to_mono_nsec;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
if (data->clock_mode == VDSO_CLOCK_NONE)
|
||||
return -ENOSYS;
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ns = get_ns(data);
|
||||
|
||||
to_mono_sec = data->wall_to_mono_sec;
|
||||
to_mono_nsec = data->wall_to_mono_nsec;
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
ts->tv_sec += to_mono_sec;
|
||||
ts->tv_nsec = 0;
|
||||
timespec_add_ns(ts, ns + to_mono_nsec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
|
||||
|
||||
/*
|
||||
* This is behind the ifdef so that we don't provide the symbol when there's no
|
||||
* possibility of there being a usable clocksource, because there's nothing we
|
||||
* can do without it. When libc fails the symbol lookup it should fall back on
|
||||
* the standard syscall path.
|
||||
*/
|
||||
int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
const union mips_vdso_data *data = get_vdso_data();
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
|
||||
ret = do_realtime(&ts, data);
|
||||
if (ret)
|
||||
return gettimeofday_fallback(tv, tz);
|
||||
|
||||
if (tv) {
|
||||
tv->tv_sec = ts.tv_sec;
|
||||
tv->tv_usec = ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
if (tz) {
|
||||
tz->tz_minuteswest = data->tz_minuteswest;
|
||||
tz->tz_dsttime = data->tz_dsttime;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */
|
||||
|
||||
int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
|
||||
{
|
||||
const union mips_vdso_data *data = get_vdso_data();
|
||||
int ret = -1;
|
||||
|
||||
switch (clkid) {
|
||||
case CLOCK_REALTIME_COARSE:
|
||||
ret = do_realtime_coarse(ts, data);
|
||||
break;
|
||||
case CLOCK_MONOTONIC_COARSE:
|
||||
ret = do_monotonic_coarse(ts, data);
|
||||
break;
|
||||
case CLOCK_REALTIME:
|
||||
ret = do_realtime(ts, data);
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
ret = do_monotonic(ts, data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
ret = clock_gettime_fallback(clkid, ts);
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue