Skip to content

Commit

Permalink
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner:
 "The timer departement provides:

   - More y2038 work in the area of ntp and pps.

   - Optimization of posix cpu timers

   - New time related selftests

   - Some new clocksource drivers

   - The usual pile of fixes, cleanups and improvements"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
  timeconst: Update path in comment
  timers/x86/hpet: Type adjustments
  clocksource/drivers/armada-370-xp: Implement ARM delay timer
  clocksource/drivers/tango_xtal: Add new timer for Tango SoCs
  clocksource/drivers/imx: Allow timer irq affinity change
  clocksource/drivers/exynos_mct: Use container_of() instead of this_cpu_ptr()
  clocksource/drivers/h8300_*: Remove unneeded memset()s
  clocksource/drivers/sh_cmt: Remove unneeded memset() in sh_cmt_setup()
  clocksource/drivers/em_sti: Remove unneeded memset()s
  clocksource/drivers/mediatek: Use GPT as sched clock source
  clockevents/drivers/mtk: Fix spurious interrupt leading to crash
  posix_cpu_timer: Reduce unnecessary sighand lock contention
  posix_cpu_timer: Convert cputimer->running to bool
  posix_cpu_timer: Check thread timers only when there are active thread timers
  posix_cpu_timer: Optimize fastpath_timer_check()
  timers, kselftest: Add 'adjtick' test to validate adjtimex() tick adjustments
  timers: Use __fls in apply_slack()
  clocksource: Remove return statement from void functions
  net: sfc: avoid using timespec
  ntp/pps: use y2038 safe types in pps_event_time
  ...
  • Loading branch information
torvalds committed Nov 3, 2015
2 parents 316dde2 + 03f136a commit 7b2a430
Show file tree
Hide file tree
Showing 34 changed files with 468 additions and 120 deletions.
6 changes: 3 additions & 3 deletions arch/x86/include/asm/hpet.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@
/* hpet memory map physical address */
extern unsigned long hpet_address;
extern unsigned long force_hpet_address;
extern int boot_hpet_disable;
extern bool boot_hpet_disable;
extern u8 hpet_blockid;
extern int hpet_force_user;
extern u8 hpet_msi_disable;
extern bool hpet_force_user;
extern bool hpet_msi_disable;
extern int is_hpet_enabled(void);
extern int hpet_enable(void);
extern void hpet_disable(void);
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/early-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ static void __init intel_graphics_stolen(int num, int slot, int func)
static void __init force_disable_hpet(int num, int slot, int func)
{
#ifdef CONFIG_HPET_TIMER
boot_hpet_disable = 1;
boot_hpet_disable = true;
pr_info("x86/hpet: Will disable the HPET for this platform because it's not reliable\n");
#endif
}
Expand Down
29 changes: 14 additions & 15 deletions arch/x86/kernel/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
*/
unsigned long hpet_address;
u8 hpet_blockid; /* OS timer block num */
u8 hpet_msi_disable;
bool hpet_msi_disable;

#ifdef CONFIG_PCI_MSI
static unsigned long hpet_num_timers;
static unsigned int hpet_num_timers;
#endif
static void __iomem *hpet_virt_address;

Expand Down Expand Up @@ -86,9 +86,9 @@ static inline void hpet_clear_mapping(void)
/*
* HPET command line enable / disable
*/
int boot_hpet_disable;
int hpet_force_user;
static int hpet_verbose;
bool boot_hpet_disable;
bool hpet_force_user;
static bool hpet_verbose;

static int __init hpet_setup(char *str)
{
Expand All @@ -98,11 +98,11 @@ static int __init hpet_setup(char *str)
if (next)
*next++ = 0;
if (!strncmp("disable", str, 7))
boot_hpet_disable = 1;
boot_hpet_disable = true;
if (!strncmp("force", str, 5))
hpet_force_user = 1;
hpet_force_user = true;
if (!strncmp("verbose", str, 7))
hpet_verbose = 1;
hpet_verbose = true;
str = next;
}
return 1;
Expand All @@ -111,7 +111,7 @@ __setup("hpet=", hpet_setup);

static int __init disable_hpet(char *str)
{
boot_hpet_disable = 1;
boot_hpet_disable = true;
return 1;
}
__setup("nohpet", disable_hpet);
Expand All @@ -124,7 +124,7 @@ static inline int is_hpet_capable(void)
/*
* HPET timer interrupt enable / disable
*/
static int hpet_legacy_int_enabled;
static bool hpet_legacy_int_enabled;

/**
* is_hpet_enabled - check whether the hpet timer interrupt is enabled
Expand Down Expand Up @@ -230,7 +230,7 @@ static struct clock_event_device hpet_clockevent;

static void hpet_stop_counter(void)
{
unsigned long cfg = hpet_readl(HPET_CFG);
u32 cfg = hpet_readl(HPET_CFG);
cfg &= ~HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
}
Expand Down Expand Up @@ -272,7 +272,7 @@ static void hpet_enable_legacy_int(void)

cfg |= HPET_CFG_LEGACY;
hpet_writel(cfg, HPET_CFG);
hpet_legacy_int_enabled = 1;
hpet_legacy_int_enabled = true;
}

static void hpet_legacy_clockevent_register(void)
Expand Down Expand Up @@ -983,7 +983,7 @@ void hpet_disable(void)
cfg = *hpet_boot_cfg;
else if (hpet_legacy_int_enabled) {
cfg &= ~HPET_CFG_LEGACY;
hpet_legacy_int_enabled = 0;
hpet_legacy_int_enabled = false;
}
cfg &= ~HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
Expand Down Expand Up @@ -1121,8 +1121,7 @@ EXPORT_SYMBOL_GPL(hpet_rtc_timer_init);

static void hpet_disable_rtc_channel(void)
{
unsigned long cfg;
cfg = hpet_readl(HPET_T1_CFG);
u32 cfg = hpet_readl(HPET_T1_CFG);
cfg &= ~HPET_TN_ENABLE;
hpet_writel(cfg, HPET_T1_CFG);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E6XX_CU,
*/
static void force_disable_hpet_msi(struct pci_dev *unused)
{
hpet_msi_disable = 1;
hpet_msi_disable = true;
}

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
Expand Down
4 changes: 4 additions & 0 deletions drivers/clocksource/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ config CLKSRC_MIPS_GIC
depends on MIPS_GIC
select CLKSRC_OF

config CLKSRC_TANGO_XTAL
bool
select CLKSRC_OF

config CLKSRC_PXA
def_bool y if ARCH_PXA || ARCH_SA1100
select CLKSRC_OF if OF
Expand Down
1 change: 1 addition & 0 deletions drivers/clocksource/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o
obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o
obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o
obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o
obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
obj-$(CONFIG_H8300) += h8300_timer8.o
Expand Down
2 changes: 0 additions & 2 deletions drivers/clocksource/em_sti.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ static int em_sti_register_clocksource(struct em_sti_priv *p)
{
struct clocksource *cs = &p->cs;

memset(cs, 0, sizeof(*cs));
cs->name = dev_name(&p->pdev->dev);
cs->rating = 200;
cs->read = em_sti_clocksource_read;
Expand Down Expand Up @@ -285,7 +284,6 @@ static void em_sti_register_clockevent(struct em_sti_priv *p)
{
struct clock_event_device *ced = &p->ced;

memset(ced, 0, sizeof(*ced));
ced->name = dev_name(&p->pdev->dev);
ced->features = CLOCK_EVT_FEAT_ONESHOT;
ced->rating = 200;
Expand Down
12 changes: 8 additions & 4 deletions drivers/clocksource/exynos_mct.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,24 +382,28 @@ static void exynos4_mct_tick_start(unsigned long cycles,
static int exynos4_tick_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
struct mct_clock_event_device *mevt;

mevt = container_of(evt, struct mct_clock_event_device, evt);
exynos4_mct_tick_start(cycles, mevt);

return 0;
}

static int set_state_shutdown(struct clock_event_device *evt)
{
exynos4_mct_tick_stop(this_cpu_ptr(&percpu_mct_tick));
struct mct_clock_event_device *mevt;

mevt = container_of(evt, struct mct_clock_event_device, evt);
exynos4_mct_tick_stop(mevt);
return 0;
}

static int set_state_periodic(struct clock_event_device *evt)
{
struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
struct mct_clock_event_device *mevt;
unsigned long cycles_per_jiffy;

mevt = container_of(evt, struct mct_clock_event_device, evt);
cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
>> evt->shift);
exynos4_mct_tick_stop(mevt);
Expand Down
1 change: 0 additions & 1 deletion drivers/clocksource/h8300_timer16.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev)
int ret, irq;
unsigned int ch;

memset(p, 0, sizeof(*p));
p->pdev = pdev;

res[REG_CH] = platform_get_resource(p->pdev,
Expand Down
1 change: 0 additions & 1 deletion drivers/clocksource/h8300_timer8.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ static int timer8_setup(struct timer8_priv *p,
int irq;
int ret;

memset(p, 0, sizeof(*p));
p->pdev = pdev;

res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
Expand Down
1 change: 0 additions & 1 deletion drivers/clocksource/h8300_tpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ static int __init tpu_setup(struct tpu_priv *p, struct platform_device *pdev)
{
struct resource *res[2];

memset(p, 0, sizeof(*p));
p->pdev = pdev;

res[CH_L] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_L);
Expand Down
26 changes: 16 additions & 10 deletions drivers/clocksource/mtk_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>

#define GPT_IRQ_EN_REG 0x00
Expand Down Expand Up @@ -59,6 +60,13 @@ struct mtk_clock_event_device {
struct clock_event_device dev;
};

static void __iomem *gpt_sched_reg __read_mostly;

static u64 notrace mtk_read_sched_clock(void)
{
return readl_relaxed(gpt_sched_reg);
}

static inline struct mtk_clock_event_device *to_mtk_clk(
struct clock_event_device *c)
{
Expand Down Expand Up @@ -141,14 +149,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}

static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
{
/* Disable all interrupts */
writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
/* Acknowledge all interrupts */
writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
}

static void
mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
{
Expand All @@ -168,6 +168,12 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
{
u32 val;

/* Disable all interrupts */
writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);

/* Acknowledge all spurious pending interrupts */
writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);

val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
writel(val | GPT_IRQ_ENABLE(timer),
evt->gpt_base + GPT_IRQ_EN_REG);
Expand Down Expand Up @@ -220,8 +226,6 @@ static void __init mtk_timer_init(struct device_node *node)
}
rate = clk_get_rate(clk);

mtk_timer_global_reset(evt);

if (request_irq(evt->dev.irq, mtk_timer_interrupt,
IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
pr_warn("failed to setup irq %d\n", evt->dev.irq);
Expand All @@ -234,6 +238,8 @@ static void __init mtk_timer_init(struct device_node *node)
mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN);
clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
node->name, rate, 300, 32, clocksource_mmio_readl_up);
gpt_sched_reg = evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC);
sched_clock_register(mtk_read_sched_clock, 32, rate);

/* Configure clock event */
mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);
Expand Down
1 change: 0 additions & 1 deletion drivers/clocksource/sh_cmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
unsigned int i;
int ret;

memset(cmt, 0, sizeof(*cmt));
cmt->pdev = pdev;
raw_spin_lock_init(&cmt->lock);

Expand Down
66 changes: 66 additions & 0 deletions drivers/clocksource/tango_xtal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <linux/clocksource.h>
#include <linux/sched_clock.h>
#include <linux/of_address.h>
#include <linux/printk.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/clk.h>

static void __iomem *xtal_in_cnt;
static struct delay_timer delay_timer;

static unsigned long notrace read_xtal_counter(void)
{
return readl_relaxed(xtal_in_cnt);
}

static u64 notrace read_sched_clock(void)
{
return read_xtal_counter();
}

static cycle_t read_clocksource(struct clocksource *cs)
{
return read_xtal_counter();
}

static struct clocksource tango_xtal = {
.name = "tango-xtal",
.rating = 350,
.read = read_clocksource,
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};

static void __init tango_clocksource_init(struct device_node *np)
{
struct clk *clk;
int xtal_freq, ret;

xtal_in_cnt = of_iomap(np, 0);
if (xtal_in_cnt == NULL) {
pr_err("%s: invalid address\n", np->full_name);
return;
}

clk = of_clk_get(np, 0);
if (IS_ERR(clk)) {
pr_err("%s: invalid clock\n", np->full_name);
return;
}

xtal_freq = clk_get_rate(clk);
delay_timer.freq = xtal_freq;
delay_timer.read_current_timer = read_xtal_counter;

ret = clocksource_register_hz(&tango_xtal, xtal_freq);
if (ret != 0) {
pr_err("%s: registration failed\n", np->full_name);
return;
}

sched_clock_register(read_sched_clock, 32, xtal_freq);
register_current_timer_delay(&delay_timer);
}

CLOCKSOURCE_OF_DECLARE(tango, "sigma,tick-counter", tango_clocksource_init);
14 changes: 14 additions & 0 deletions drivers/clocksource/time-armada-370-xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <linux/percpu.h>
#include <linux/syscore_ops.h>

#include <asm/delay.h>

/*
* Timer block registers.
*/
Expand Down Expand Up @@ -249,6 +251,15 @@ struct syscore_ops armada_370_xp_timer_syscore_ops = {
.resume = armada_370_xp_timer_resume,
};

static unsigned long armada_370_delay_timer_read(void)
{
return ~readl(timer_base + TIMER0_VAL_OFF);
}

static struct delay_timer armada_370_delay_timer = {
.read_current_timer = armada_370_delay_timer_read,
};

static void __init armada_370_xp_timer_common_init(struct device_node *np)
{
u32 clr = 0, set = 0;
Expand Down Expand Up @@ -287,6 +298,9 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
TIMER0_RELOAD_EN | enable_mask,
TIMER0_RELOAD_EN | enable_mask);

armada_370_delay_timer.freq = timer_clk;
register_current_timer_delay(&armada_370_delay_timer);

/*
* Set scale and timer for sched_clock.
*/
Expand Down
Loading

0 comments on commit 7b2a430

Please sign in to comment.