Merge tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC-specific updates from Arnd Bergmann: "This is a larger set of new functionality for the existing SoC families, including: - vt8500 gains support for new CPU cores, notably the Cortex-A9 based wm8850 - prima2 gains support for the "marco" SoC family, its SMP based cousin - tegra gains support for the new Tegra4 (Tegra114) family - socfpga now supports a newer version of the hardware including SMP - i.mx31 and bcm2835 are now using DT probing for their clocks - lots of updates for sh-mobile - OMAP updates for clocks, power management and USB - i.mx6q and tegra now support cpuidle - kirkwood now supports PCIe hot plugging - tegra clock support is updated - tegra USB PHY probing gets implemented diffently" * tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (148 commits) ARM: prima2: remove duplicate v7_invalidate_l1 ARM: shmobile: r8a7779: Correct TMU clock support again ARM: prima2: fix __init section for cpu hotplug ARM: OMAP: Consolidate OMAP USB-HS platform data (part 3/3) ARM: OMAP: Consolidate OMAP USB-HS platform data (part 1/3) arm: socfpga: Add SMP support for actual socfpga harware arm: Add v7_invalidate_l1 to cache-v7.S arm: socfpga: Add entries to enable make dtbs socfpga arm: socfpga: Add new device tree source for actual socfpga HW ARM: tegra: sort Kconfig selects for Tegra114 ARM: tegra: enable ARCH_REQUIRE_GPIOLIB for Tegra114 ARM: tegra: Fix build error w/ ARCH_TEGRA_114_SOC w/o ARCH_TEGRA_3x_SOC ARM: tegra: Fix build error for gic update ARM: tegra: remove empty tegra_smp_init_cpus() ARM: shmobile: Register ARM architected timer ARM: MARCO: fix the build issue due to gic-vic-to-irqchip move ARM: shmobile: r8a7779: Correct TMU clock support ARM: mxs_defconfig: Select CONFIG_DEVTMPFS_MOUNT ARM: mxs: decrease mxs_clockevent_device.min_delta_ns to 2 clock cycles ARM: mxs: use apbx bus clock to drive the timers on timrotv2 ...
This commit is contained in:
@@ -28,7 +28,11 @@ obj-$(CONFIG_MXC_ULPI) += ulpi.o
|
||||
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
|
||||
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
|
||||
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-y += cpuidle.o
|
||||
obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SND_IMX_SOC
|
||||
obj-y += ssi-fiq.o
|
||||
|
@@ -62,7 +62,7 @@ static const char *clko_sel_clks[] = {
|
||||
"32k", "usb_div", "dptc",
|
||||
};
|
||||
|
||||
static const char *ssi_sel_clks[] = { "spll", "mpll", };
|
||||
static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
|
||||
|
||||
enum mx27_clks {
|
||||
dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
|
||||
@@ -82,7 +82,7 @@ enum mx27_clks {
|
||||
csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
|
||||
uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
|
||||
uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
|
||||
mpll_sel, clk_max
|
||||
mpll_sel, spll_gate, clk_max
|
||||
};
|
||||
|
||||
static struct clk *clk[clk_max];
|
||||
@@ -104,6 +104,7 @@ int __init mx27_clocks_init(unsigned long fref)
|
||||
ARRAY_SIZE(mpll_sel_clks));
|
||||
clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
|
||||
clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
|
||||
clk[spll_gate] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
|
||||
clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
|
||||
|
||||
if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
|
||||
@@ -121,7 +122,7 @@ int __init mx27_clocks_init(unsigned long fref)
|
||||
clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
|
||||
clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
|
||||
clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6);
|
||||
clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3);
|
||||
clk[usb_div] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 28, 3);
|
||||
clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
|
||||
clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
|
||||
if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
|
||||
|
@@ -34,8 +34,8 @@ static const char *csi_sel[] = { "upll", "spll", };
|
||||
static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
|
||||
|
||||
enum mx31_clks {
|
||||
ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
|
||||
per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
|
||||
dummy, ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg,
|
||||
per_div, per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
|
||||
fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
|
||||
iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
|
||||
uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
|
||||
@@ -46,12 +46,15 @@ enum mx31_clks {
|
||||
};
|
||||
|
||||
static struct clk *clk[clk_max];
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
int __init mx31_clocks_init(unsigned long fref)
|
||||
{
|
||||
void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
|
||||
int i;
|
||||
struct device_node *np;
|
||||
|
||||
clk[dummy] = imx_clk_fixed("dummy", 0);
|
||||
clk[ckih] = imx_clk_fixed("ckih", fref);
|
||||
clk[ckil] = imx_clk_fixed("ckil", 32768);
|
||||
clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
|
||||
@@ -116,6 +119,14 @@ int __init mx31_clocks_init(unsigned long fref)
|
||||
pr_err("imx31 clk %d: register failed with %ld\n",
|
||||
i, PTR_ERR(clk[i]));
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
|
||||
|
||||
if (np) {
|
||||
clk_data.clks = clk;
|
||||
clk_data.clk_num = ARRAY_SIZE(clk);
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
}
|
||||
|
||||
clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
|
||||
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
|
||||
clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
|
||||
|
@@ -67,13 +67,13 @@ enum mx35_clks {
|
||||
|
||||
static struct clk *clk[clk_max];
|
||||
|
||||
int __init mx35_clocks_init()
|
||||
int __init mx35_clocks_init(void)
|
||||
{
|
||||
void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
|
||||
u32 pdr0, consumer_sel, hsp_sel;
|
||||
struct arm_ahb_div *aad;
|
||||
unsigned char *hsp_div;
|
||||
int i;
|
||||
u32 i;
|
||||
|
||||
pdr0 = __raw_readl(base + MXC_CCM_PDR0);
|
||||
consumer_sel = (pdr0 >> 16) & 0xf;
|
||||
|
@@ -54,8 +54,19 @@
|
||||
#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
|
||||
#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
|
||||
|
||||
#define CGPR 0x64
|
||||
#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
|
||||
|
||||
static void __iomem *ccm_base;
|
||||
|
||||
void imx6q_set_chicken_bit(void)
|
||||
{
|
||||
u32 val = readl_relaxed(ccm_base + CGPR);
|
||||
|
||||
val |= BM_CGPR_CHICKEN_BIT;
|
||||
writel_relaxed(val, ccm_base + CGPR);
|
||||
}
|
||||
|
||||
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||
{
|
||||
u32 val = readl_relaxed(ccm_base + CLPCR);
|
||||
@@ -66,6 +77,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||
break;
|
||||
case WAIT_UNCLOCKED:
|
||||
val |= 0x1 << BP_CLPCR_LPM;
|
||||
val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
|
||||
break;
|
||||
case STOP_POWER_ON:
|
||||
val |= 0x2 << BP_CLPCR_LPM;
|
||||
|
@@ -116,9 +116,11 @@ extern u32 *pl310_get_save_ptr(void);
|
||||
extern void v7_secondary_startup(void);
|
||||
extern void imx_scu_map_io(void);
|
||||
extern void imx_smp_prepare(void);
|
||||
extern void imx_scu_standby_enable(void);
|
||||
#else
|
||||
static inline void imx_scu_map_io(void) {}
|
||||
static inline void imx_smp_prepare(void) {}
|
||||
static inline void imx_scu_standby_enable(void) {}
|
||||
#endif
|
||||
extern void imx_enable_cpu(int cpu, bool enable);
|
||||
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
|
||||
@@ -128,6 +130,7 @@ extern void imx_gpc_init(void);
|
||||
extern void imx_gpc_pre_suspend(void);
|
||||
extern void imx_gpc_post_resume(void);
|
||||
extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
|
||||
extern void imx6q_set_chicken_bit(void);
|
||||
|
||||
extern void imx_cpu_die(unsigned int cpu);
|
||||
extern int imx_cpu_kill(unsigned int cpu);
|
||||
|
95
arch/arm/mach-imx/cpuidle-imx6q.c
Normal file
95
arch/arm/mach-imx/cpuidle-imx6q.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/proc-fns.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "cpuidle.h"
|
||||
|
||||
static atomic_t master = ATOMIC_INIT(0);
|
||||
static DEFINE_SPINLOCK(master_lock);
|
||||
|
||||
static int imx6q_enter_wait(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
int cpu = dev->cpu;
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
|
||||
|
||||
if (atomic_inc_return(&master) == num_online_cpus()) {
|
||||
/*
|
||||
* With this lock, we prevent other cpu to exit and enter
|
||||
* this function again and become the master.
|
||||
*/
|
||||
if (!spin_trylock(&master_lock))
|
||||
goto idle;
|
||||
imx6q_set_lpm(WAIT_UNCLOCKED);
|
||||
cpu_do_idle();
|
||||
imx6q_set_lpm(WAIT_CLOCKED);
|
||||
spin_unlock(&master_lock);
|
||||
goto done;
|
||||
}
|
||||
|
||||
idle:
|
||||
cpu_do_idle();
|
||||
done:
|
||||
atomic_dec(&master);
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each cpu, setup the broadcast timer because local timer
|
||||
* stops for the states other than WFI.
|
||||
*/
|
||||
static void imx6q_setup_broadcast_timer(void *arg)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
|
||||
}
|
||||
|
||||
static struct cpuidle_driver imx6q_cpuidle_driver = {
|
||||
.name = "imx6q_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
/* WFI */
|
||||
ARM_CPUIDLE_WFI_STATE,
|
||||
/* WAIT */
|
||||
{
|
||||
.exit_latency = 50,
|
||||
.target_residency = 75,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = imx6q_enter_wait,
|
||||
.name = "WAIT",
|
||||
.desc = "Clock off",
|
||||
},
|
||||
},
|
||||
.state_count = 2,
|
||||
.safe_state_index = 0,
|
||||
};
|
||||
|
||||
int __init imx6q_cpuidle_init(void)
|
||||
{
|
||||
/* Need to enable SCU standby for entering WAIT modes */
|
||||
imx_scu_standby_enable();
|
||||
|
||||
/* Set chicken bit to get a reliable WAIT mode support */
|
||||
imx6q_set_chicken_bit();
|
||||
|
||||
/* Configure the broadcast timer on each cpu */
|
||||
on_each_cpu(imx6q_setup_broadcast_timer, NULL, 1);
|
||||
|
||||
return imx_cpuidle_init(&imx6q_cpuidle_driver);
|
||||
}
|
@@ -14,9 +14,14 @@
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
extern int imx_cpuidle_init(struct cpuidle_driver *drv);
|
||||
extern int imx6q_cpuidle_init(void);
|
||||
#else
|
||||
static inline int imx_cpuidle_init(struct cpuidle_driver *drv)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int imx6q_cpuidle_init(void)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
@@ -101,11 +101,16 @@ static void imx_gpc_irq_mask(struct irq_data *d)
|
||||
void __init imx_gpc_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int i;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
|
||||
gpc_base = of_iomap(np, 0);
|
||||
WARN_ON(!gpc_base);
|
||||
|
||||
/* Initially mask all interrupts */
|
||||
for (i = 0; i < IMR_NUM; i++)
|
||||
writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
|
||||
|
||||
/* Register GPC as the secondary interrupt controller behind GIC */
|
||||
gic_arch_extn.irq_mask = imx_gpc_irq_mask;
|
||||
gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
|
||||
|
@@ -17,53 +17,6 @@
|
||||
|
||||
.section ".text.head", "ax"
|
||||
|
||||
/*
|
||||
* The secondary kernel init calls v7_flush_dcache_all before it enables
|
||||
* the L1; however, the L1 comes out of reset in an undefined state, so
|
||||
* the clean + invalidate performed by v7_flush_dcache_all causes a bunch
|
||||
* of cache lines with uninitialized data and uninitialized tags to get
|
||||
* written out to memory, which does really unpleasant things to the main
|
||||
* processor. We fix this by performing an invalidate, rather than a
|
||||
* clean + invalidate, before jumping into the kernel.
|
||||
*
|
||||
* This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
|
||||
* to be called for both secondary cores startup and primary core resume
|
||||
* procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
|
||||
*/
|
||||
ENTRY(v7_invalidate_l1)
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
|
||||
mcr p15, 2, r0, c0, c0, 0
|
||||
mrc p15, 1, r0, c0, c0, 0
|
||||
|
||||
ldr r1, =0x7fff
|
||||
and r2, r1, r0, lsr #13
|
||||
|
||||
ldr r1, =0x3ff
|
||||
|
||||
and r3, r1, r0, lsr #3 @ NumWays - 1
|
||||
add r2, r2, #1 @ NumSets
|
||||
|
||||
and r0, r0, #0x7
|
||||
add r0, r0, #4 @ SetShift
|
||||
|
||||
clz r1, r3 @ WayShift
|
||||
add r4, r3, #1 @ NumWays
|
||||
1: sub r2, r2, #1 @ NumSets--
|
||||
mov r3, r4 @ Temp = NumWays
|
||||
2: subs r3, r3, #1 @ Temp--
|
||||
mov r5, r3, lsl r1
|
||||
mov r6, r2, lsl r0
|
||||
orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
|
||||
mcr p15, 0, r5, c7, c6, 2
|
||||
bgt 2b
|
||||
cmp r2, #0
|
||||
bgt 1b
|
||||
dsb
|
||||
isb
|
||||
mov pc, lr
|
||||
ENDPROC(v7_invalidate_l1)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
ENTRY(v7_secondary_startup)
|
||||
bl v7_invalidate_l1
|
||||
|
@@ -18,24 +18,9 @@
|
||||
#include "common.h"
|
||||
#include "mx31.h"
|
||||
|
||||
static const struct of_dev_auxdata imx31_auxdata_lookup[] __initconst = {
|
||||
OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART1_BASE_ADDR,
|
||||
"imx21-uart.0", NULL),
|
||||
OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART2_BASE_ADDR,
|
||||
"imx21-uart.1", NULL),
|
||||
OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART3_BASE_ADDR,
|
||||
"imx21-uart.2", NULL),
|
||||
OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART4_BASE_ADDR,
|
||||
"imx21-uart.3", NULL),
|
||||
OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART5_BASE_ADDR,
|
||||
"imx21-uart.4", NULL),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static void __init imx31_dt_init(void)
|
||||
{
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
imx31_auxdata_lookup, NULL);
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
static const char *imx31_dt_board_compat[] __initdata = {
|
||||
|
@@ -12,7 +12,6 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
@@ -27,7 +26,6 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/micrel_phy.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@@ -202,17 +200,14 @@ static void __init imx6q_init_machine(void)
|
||||
imx6q_1588_init();
|
||||
}
|
||||
|
||||
static struct cpuidle_driver imx6q_cpuidle_driver = {
|
||||
.name = "imx6q_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
||||
.state_count = 1,
|
||||
};
|
||||
|
||||
static void __init imx6q_init_late(void)
|
||||
{
|
||||
imx_cpuidle_init(&imx6q_cpuidle_driver);
|
||||
/*
|
||||
* WAIT mode is broken on TO 1.0 and 1.1, so there is no point
|
||||
* to run cpuidle on them.
|
||||
*/
|
||||
if (imx6q_revision() > IMX_CHIP_REVISION_1_1)
|
||||
imx6q_cpuidle_init();
|
||||
}
|
||||
|
||||
static void __init imx6q_map_io(void)
|
||||
|
@@ -20,6 +20,8 @@
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define SCU_STANDBY_ENABLE (1 << 5)
|
||||
|
||||
static void __iomem *scu_base;
|
||||
|
||||
static struct map_desc scu_io_desc __initdata = {
|
||||
@@ -42,6 +44,14 @@ void __init imx_scu_map_io(void)
|
||||
scu_base = IMX_IO_ADDRESS(base);
|
||||
}
|
||||
|
||||
void imx_scu_standby_enable(void)
|
||||
{
|
||||
u32 val = readl_relaxed(scu_base);
|
||||
|
||||
val |= SCU_STANDBY_ENABLE;
|
||||
writel_relaxed(val, scu_base);
|
||||
}
|
||||
|
||||
static void __cpuinit imx_secondary_init(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
|
@@ -152,7 +152,8 @@ static int v2_set_next_event(unsigned long evt,
|
||||
|
||||
__raw_writel(tcmp, timer_base + V2_TCMP);
|
||||
|
||||
return (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
|
||||
return evt < 0x7fffffff &&
|
||||
(int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
|
||||
-ETIME : 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user