mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'timers-core-2020-06-02' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "The truly boring timer and clocksource updates for 5.8: - Not a single new clocksource or clockevent driver! - Device tree updates for various chips - Fixes and improvements and cleanups all over the place" * tag 'timers-core-2020-06-02' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (27 commits) dt-bindings: timer: Add renesas,em-sti bindings clocksource/drivers/timer-versatile: Clear OF_POPULATED flag clocksource: mips-gic-timer: Mark GIC timer as unstable if ref clock changes clocksource: mips-gic-timer: Register as sched_clock clocksource: dw_apb_timer_of: Fix missing clockevent timers clocksource: dw_apb_timer: Affiliate of-based timer with any CPU clocksource: dw_apb_timer: Make CPU-affiliation being optional dt-bindings: timer: Move snps,dw-apb-timer DT schema from rtc dt-bindings: rtc: Convert snps,dw-apb-timer to DT schema clocksource/drivers/timer-ti-dm: Do one override clock parent in prepare() clocksource/drivers/timer-ti-dm: Fix spelling mistake "detectt" -> "detect" clocksource/drivers/timer-ti-dm: Fix warning for set but not used clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support clocksource/drivers/timer-ti-32k: Add support for initializing directly drivers/clocksource/arm_arch_timer: Remove duplicate error message clocksource/drivers/arc_timer: Remove duplicate error message clocksource/drivers/rda: drop redundant Kconfig dependency clocksource/drivers/timer-ti-dm: Fix warning for set but not used clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support clocksource/drivers/timer-ti-32k: Add support for initializing directly ...
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
* Designware APB timer
|
||||
|
||||
Required properties:
|
||||
- compatible: One of:
|
||||
"snps,dw-apb-timer"
|
||||
"snps,dw-apb-timer-sp" <DEPRECATED>
|
||||
"snps,dw-apb-timer-osc" <DEPRECATED>
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: IRQ line for the timer.
|
||||
- either clocks+clock-names or clock-frequency properties
|
||||
|
||||
Optional properties:
|
||||
- clocks : list of clock specifiers, corresponding to entries in
|
||||
the clock-names property;
|
||||
- clock-names : should contain "timer" and "pclk" entries, matching entries
|
||||
in the clocks property.
|
||||
- clock-frequency: The frequency in HZ of the timer.
|
||||
- clock-freq: For backwards compatibility with picoxcell
|
||||
|
||||
If using the clock specifiers, the pclk clock is optional, as not all
|
||||
systems may use one.
|
||||
|
||||
|
||||
Example:
|
||||
timer@ffe00000 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
interrupts = <0 170 4>;
|
||||
reg = <0xffe00000 0x1000>;
|
||||
clocks = <&timer_clk>, <&timer_pclk>;
|
||||
clock-names = "timer", "pclk";
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/renesas,em-sti.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas EMMA Mobile System Timer
|
||||
|
||||
maintainers:
|
||||
- Magnus Damm <magnus.damm@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,em-sti
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: sclk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
timer@e0180000 {
|
||||
compatible = "renesas,em-sti";
|
||||
reg = <0xe0180000 0x54>;
|
||||
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&sti_sclk>;
|
||||
clock-names = "sclk";
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/snps,dw-apb-timer.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Synopsys DesignWare APB Timer
|
||||
|
||||
maintainers:
|
||||
- Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: snps,dw-apb-timer
|
||||
- enum:
|
||||
- snps,dw-apb-timer-sp
|
||||
- snps,dw-apb-timer-osc
|
||||
deprecated: true
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Timer ticks reference clock source
|
||||
- description: APB interface clock source
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: timer
|
||||
- const: pclk
|
||||
|
||||
clock-frequency: true
|
||||
|
||||
clock-freq:
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
description: |
|
||||
Has the same meaning as the 'clock-frequency' property - timer clock
|
||||
frequency in HZ, but is defined only for the backwards compatibility
|
||||
with the picoxcell platform.
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- required:
|
||||
- clock-frequency
|
||||
- required:
|
||||
- clock-freq
|
||||
|
||||
examples:
|
||||
- |
|
||||
timer@ffe00000 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
interrupts = <0 170 4>;
|
||||
reg = <0xffe00000 0x1000>;
|
||||
clocks = <&timer_clk>, <&timer_pclk>;
|
||||
clock-names = "timer", "pclk";
|
||||
};
|
||||
- |
|
||||
timer@ffe00000 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
interrupts = <0 170 4>;
|
||||
reg = <0xffe00000 0x1000>;
|
||||
clocks = <&timer_clk>;
|
||||
clock-names = "timer";
|
||||
};
|
||||
- |
|
||||
timer@ffe00000 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
interrupts = <0 170 4>;
|
||||
reg = <0xffe00000 0x1000>;
|
||||
clock-frequency = <25000000>;
|
||||
};
|
||||
...
|
||||
@@ -105,6 +105,7 @@
|
||||
ti,timers = <&timer7>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&dmtimer7_pins>;
|
||||
ti,clock-source = <0x01>;
|
||||
};
|
||||
|
||||
vmmcsd_fixed: regulator-3v3 {
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
pinctrl-0 = <&pwm_pins>;
|
||||
ti,timers = <&timer11>;
|
||||
#pwm-cells = <3>;
|
||||
ti,clock-source = <0x01>;
|
||||
};
|
||||
|
||||
/* HS USB Host PHY on PORT 1 */
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
pinctrl-0 = <&pwm_pins>;
|
||||
ti,timers = <&timer10>;
|
||||
#pwm-cells = <3>;
|
||||
ti,clock-source = <0x01>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
compatible = "ti,omap-dmtimer-pwm";
|
||||
ti,timers = <&timer11>;
|
||||
#pwm-cells = <3>;
|
||||
ti,clock-source = <0x01>;
|
||||
};
|
||||
|
||||
hsusb2_phy: hsusb2_phy {
|
||||
|
||||
@@ -120,7 +120,6 @@ config OWL_TIMER
|
||||
|
||||
config RDA_TIMER
|
||||
bool "RDA timer driver" if COMPILE_TEST
|
||||
depends on GENERIC_CLOCKEVENTS
|
||||
select CLKSRC_MMIO
|
||||
select TIMER_OF
|
||||
help
|
||||
@@ -562,16 +561,16 @@ config CLKSRC_VERSATILE
|
||||
bool "ARM Versatile (Express) reference platforms clock source" if COMPILE_TEST
|
||||
depends on GENERIC_SCHED_CLOCK && !ARCH_USES_GETTIMEOFFSET
|
||||
select TIMER_OF
|
||||
default y if MFD_VEXPRESS_SYSREG
|
||||
default y if (ARCH_VEXPRESS || ARCH_VERSATILE) && ARM
|
||||
help
|
||||
This option enables clock source based on free running
|
||||
counter available in the "System Registers" block of
|
||||
ARM Versatile, RealView and Versatile Express reference
|
||||
platforms.
|
||||
ARM Versatile and Versatile Express reference platforms.
|
||||
|
||||
config CLKSRC_MIPS_GIC
|
||||
bool
|
||||
depends on MIPS_GIC
|
||||
select CLOCKSOURCE_WATCHDOG
|
||||
select TIMER_OF
|
||||
|
||||
config CLKSRC_TANGO_XTAL
|
||||
@@ -709,6 +708,7 @@ config MICROCHIP_PIT64B
|
||||
bool "Microchip PIT64B support"
|
||||
depends on OF || COMPILE_TEST
|
||||
select CLKSRC_MMIO
|
||||
select TIMER_OF
|
||||
help
|
||||
This option enables Microchip PIT64B timer for Atmel
|
||||
based system. It supports the oneshot, the periodic
|
||||
|
||||
@@ -18,6 +18,7 @@ obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
|
||||
obj-$(CONFIG_DAVINCI_TIMER) += timer-davinci.o
|
||||
obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o
|
||||
obj-$(CONFIG_OMAP_DM_TIMER) += timer-ti-dm.o
|
||||
obj-$(CONFIG_OMAP_DM_TIMER) += timer-ti-dm-systimer.o
|
||||
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
|
||||
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
|
||||
obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o
|
||||
|
||||
@@ -334,10 +334,8 @@ static int __init arc_clockevent_setup(struct device_node *node)
|
||||
}
|
||||
|
||||
ret = arc_get_timer_clk(node);
|
||||
if (ret) {
|
||||
pr_err("clockevent: missing clk\n");
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Needs apriori irq_set_percpu_devid() done in intc map function */
|
||||
ret = request_percpu_irq(arc_timer_irq, timer_irq_handler,
|
||||
|
||||
@@ -1588,10 +1588,8 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
|
||||
arch_timers_present |= ARCH_TIMER_TYPE_CP15;
|
||||
|
||||
ret = acpi_gtdt_init(table, &platform_timer_count);
|
||||
if (ret) {
|
||||
pr_err("Failed to init GTDT table.\n");
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] =
|
||||
acpi_gtdt_map_ppi(ARCH_TIMER_PHYS_NONSECURE_PPI);
|
||||
|
||||
@@ -222,7 +222,8 @@ static int apbt_next_event(unsigned long delta,
|
||||
/**
|
||||
* dw_apb_clockevent_init() - use an APB timer as a clock_event_device
|
||||
*
|
||||
* @cpu: The CPU the events will be targeted at.
|
||||
* @cpu: The CPU the events will be targeted at or -1 if CPU affiliation
|
||||
* isn't required.
|
||||
* @name: The name used for the timer and the IRQ for it.
|
||||
* @rating: The rating to give the timer.
|
||||
* @base: I/O base for the timer registers.
|
||||
@@ -257,7 +258,7 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating,
|
||||
dw_ced->ced.max_delta_ticks = 0x7fffffff;
|
||||
dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced);
|
||||
dw_ced->ced.min_delta_ticks = 5000;
|
||||
dw_ced->ced.cpumask = cpumask_of(cpu);
|
||||
dw_ced->ced.cpumask = cpu < 0 ? cpu_possible_mask : cpumask_of(cpu);
|
||||
dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
|
||||
dw_ced->ced.set_state_shutdown = apbt_shutdown;
|
||||
|
||||
@@ -73,7 +73,7 @@ static void __init add_clockevent(struct device_node *event_timer)
|
||||
|
||||
timer_get_base_and_rate(event_timer, &iobase, &rate);
|
||||
|
||||
ced = dw_apb_clockevent_init(0, event_timer->name, 300, iobase, irq,
|
||||
ced = dw_apb_clockevent_init(-1, event_timer->name, 300, iobase, irq,
|
||||
rate);
|
||||
if (!ced)
|
||||
panic("Unable to initialise clockevent device");
|
||||
@@ -147,10 +147,6 @@ static int num_called;
|
||||
static int __init dw_apb_timer_init(struct device_node *timer)
|
||||
{
|
||||
switch (num_called) {
|
||||
case 0:
|
||||
pr_debug("%s: found clockevent timer\n", __func__);
|
||||
add_clockevent(timer);
|
||||
break;
|
||||
case 1:
|
||||
pr_debug("%s: found clocksource timer\n", __func__);
|
||||
add_clocksource(timer);
|
||||
@@ -161,6 +157,8 @@ static int __init dw_apb_timer_init(struct device_node *timer)
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: found clockevent timer\n", __func__);
|
||||
add_clockevent(timer);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/sched_clock.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/time.h>
|
||||
#include <asm/mips-cps.h>
|
||||
@@ -23,14 +24,14 @@
|
||||
static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
|
||||
static int gic_timer_irq;
|
||||
static unsigned int gic_frequency;
|
||||
static bool __read_mostly gic_clock_unstable;
|
||||
|
||||
static u64 notrace gic_read_count(void)
|
||||
static void gic_clocksource_unstable(char *reason);
|
||||
|
||||
static u64 notrace gic_read_count_2x32(void)
|
||||
{
|
||||
unsigned int hi, hi2, lo;
|
||||
|
||||
if (mips_cm_is64)
|
||||
return read_gic_counter();
|
||||
|
||||
do {
|
||||
hi = read_gic_counter_32h();
|
||||
lo = read_gic_counter_32l();
|
||||
@@ -40,6 +41,19 @@ static u64 notrace gic_read_count(void)
|
||||
return (((u64) hi) << 32) + lo;
|
||||
}
|
||||
|
||||
static u64 notrace gic_read_count_64(void)
|
||||
{
|
||||
return read_gic_counter();
|
||||
}
|
||||
|
||||
static u64 notrace gic_read_count(void)
|
||||
{
|
||||
if (mips_cm_is64)
|
||||
return gic_read_count_64();
|
||||
|
||||
return gic_read_count_2x32();
|
||||
}
|
||||
|
||||
static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
|
||||
{
|
||||
int cpu = cpumask_first(evt->cpumask);
|
||||
@@ -114,8 +128,10 @@ static int gic_clk_notifier(struct notifier_block *nb, unsigned long action,
|
||||
{
|
||||
struct clk_notifier_data *cnd = data;
|
||||
|
||||
if (action == POST_RATE_CHANGE)
|
||||
if (action == POST_RATE_CHANGE) {
|
||||
gic_clocksource_unstable("ref clock rate change");
|
||||
on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1);
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
@@ -161,6 +177,18 @@ static struct clocksource gic_clocksource = {
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_GIC,
|
||||
};
|
||||
|
||||
static void gic_clocksource_unstable(char *reason)
|
||||
{
|
||||
if (gic_clock_unstable)
|
||||
return;
|
||||
|
||||
gic_clock_unstable = true;
|
||||
|
||||
pr_info("GIC timer is unstable due to %s\n", reason);
|
||||
|
||||
clocksource_mark_unstable(&gic_clocksource);
|
||||
}
|
||||
|
||||
static int __init __gic_clocksource_init(void)
|
||||
{
|
||||
unsigned int count_width;
|
||||
@@ -228,6 +256,18 @@ static int __init gic_clocksource_of_init(struct device_node *node)
|
||||
/* And finally start the counter */
|
||||
clear_gic_config(GIC_CONFIG_COUNTSTOP);
|
||||
|
||||
/*
|
||||
* It's safe to use the MIPS GIC timer as a sched clock source only if
|
||||
* its ticks are stable, which is true on either the platforms with
|
||||
* stable CPU frequency or on the platforms with CM3 and CPU frequency
|
||||
* change performed by the CPC core clocks divider.
|
||||
*/
|
||||
if (mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ)) {
|
||||
sched_clock_register(mips_cm_is64 ?
|
||||
gic_read_count_64 : gic_read_count_2x32,
|
||||
64, gic_frequency);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
TIMER_OF_DECLARE(mips_gic_timer, "mti,gic-timer",
|
||||
|
||||
@@ -139,7 +139,6 @@ static int
|
||||
clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
|
||||
{
|
||||
u32 alm;
|
||||
int status = 0;
|
||||
unsigned int val;
|
||||
|
||||
BUG_ON(delta < 2);
|
||||
@@ -163,7 +162,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
|
||||
alm += delta;
|
||||
regmap_write(regmap_st, AT91_ST_RTAR, alm);
|
||||
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clkevt = {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <clocksource/timer-davinci.h>
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "%s: " fmt "\n", __func__
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#define DAVINCI_TIMER_REG_TIM12 0x10
|
||||
#define DAVINCI_TIMER_REG_TIM34 0x14
|
||||
@@ -250,31 +250,29 @@ int __init davinci_timer_register(struct clk *clk,
|
||||
|
||||
rv = clk_prepare_enable(clk);
|
||||
if (rv) {
|
||||
pr_err("Unable to prepare and enable the timer clock");
|
||||
pr_err("Unable to prepare and enable the timer clock\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!request_mem_region(timer_cfg->reg.start,
|
||||
resource_size(&timer_cfg->reg),
|
||||
"davinci-timer")) {
|
||||
pr_err("Unable to request memory region");
|
||||
pr_err("Unable to request memory region\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg));
|
||||
if (!base) {
|
||||
pr_err("Unable to map the register range");
|
||||
pr_err("Unable to map the register range\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
davinci_timer_init(base);
|
||||
tick_rate = clk_get_rate(clk);
|
||||
|
||||
clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL | __GFP_NOFAIL);
|
||||
if (!clockevent) {
|
||||
pr_err("Error allocating memory for clockevent data");
|
||||
clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL);
|
||||
if (!clockevent)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clockevent->dev.name = "tim12";
|
||||
clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT;
|
||||
@@ -298,7 +296,7 @@ int __init davinci_timer_register(struct clk *clk,
|
||||
davinci_timer_irq_timer, IRQF_TIMER,
|
||||
"clockevent/tim12", clockevent);
|
||||
if (rv) {
|
||||
pr_err("Unable to request the clockevent interrupt");
|
||||
pr_err("Unable to request the clockevent interrupt\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -325,7 +323,7 @@ int __init davinci_timer_register(struct clk *clk,
|
||||
|
||||
rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate);
|
||||
if (rv) {
|
||||
pr_err("Unable to register clocksource");
|
||||
pr_err("Unable to register clocksource\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -343,20 +341,20 @@ static int __init of_davinci_timer_register(struct device_node *np)
|
||||
|
||||
rv = of_address_to_resource(np, 0, &timer_cfg.reg);
|
||||
if (rv) {
|
||||
pr_err("Unable to get the register range for timer");
|
||||
pr_err("Unable to get the register range for timer\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = of_irq_to_resource_table(np, timer_cfg.irq,
|
||||
DAVINCI_TIMER_NUM_IRQS);
|
||||
if (rv != DAVINCI_TIMER_NUM_IRQS) {
|
||||
pr_err("Unable to get the interrupts for timer");
|
||||
pr_err("Unable to get the interrupts for timer\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
clk = of_clk_get(np, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("Unable to get the timer clock");
|
||||
pr_err("Unable to get the timer clock\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,17 +61,19 @@ static inline void tpm_irq_acknowledge(void)
|
||||
writel(TPM_STATUS_CH0F, timer_base + TPM_STATUS);
|
||||
}
|
||||
|
||||
static struct delay_timer tpm_delay_timer;
|
||||
|
||||
static inline unsigned long tpm_read_counter(void)
|
||||
{
|
||||
return readl(timer_base + TPM_CNT);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARM)
|
||||
static struct delay_timer tpm_delay_timer;
|
||||
|
||||
static unsigned long tpm_read_current_timer(void)
|
||||
{
|
||||
return tpm_read_counter();
|
||||
}
|
||||
#endif
|
||||
|
||||
static u64 notrace tpm_read_sched_clock(void)
|
||||
{
|
||||
@@ -144,9 +146,11 @@ static struct timer_of to_tpm = {
|
||||
|
||||
static int __init tpm_clocksource_init(void)
|
||||
{
|
||||
#if defined(CONFIG_ARM)
|
||||
tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
|
||||
tpm_delay_timer.freq = timer_of_rate(&to_tpm) >> 3;
|
||||
register_current_timer_delay(&tpm_delay_timer);
|
||||
#endif
|
||||
|
||||
sched_clock_register(tpm_read_sched_clock, counter_width,
|
||||
timer_of_rate(&to_tpm) >> 3);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/sched_clock.h>
|
||||
@@ -76,6 +77,49 @@ static u64 notrace omap_32k_read_sched_clock(void)
|
||||
return ti_32k_read_cycles(&ti_32k_timer.cs);
|
||||
}
|
||||
|
||||
static void __init ti_32k_timer_enable_clock(struct device_node *np,
|
||||
const char *name)
|
||||
{
|
||||
struct clk *clock;
|
||||
int error;
|
||||
|
||||
clock = of_clk_get_by_name(np->parent, name);
|
||||
if (IS_ERR(clock)) {
|
||||
/* Only some SoCs have a separate interface clock */
|
||||
if (PTR_ERR(clock) == -EINVAL && !strncmp("ick", name, 3))
|
||||
return;
|
||||
|
||||
pr_warn("%s: could not get clock %s %li\n",
|
||||
__func__, name, PTR_ERR(clock));
|
||||
return;
|
||||
}
|
||||
|
||||
error = clk_prepare_enable(clock);
|
||||
if (error) {
|
||||
pr_warn("%s: could not enable %s: %i\n",
|
||||
__func__, name, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init ti_32k_timer_module_init(struct device_node *np,
|
||||
void __iomem *base)
|
||||
{
|
||||
void __iomem *sysc = base + 4;
|
||||
|
||||
if (!of_device_is_compatible(np->parent, "ti,sysc"))
|
||||
return;
|
||||
|
||||
ti_32k_timer_enable_clock(np, "fck");
|
||||
ti_32k_timer_enable_clock(np, "ick");
|
||||
|
||||
/*
|
||||
* Force idle module as wkup domain is active with MPU.
|
||||
* No need to tag the module disabled for ti-sysc probe.
|
||||
*/
|
||||
writel_relaxed(0, sysc);
|
||||
}
|
||||
|
||||
static int __init ti_32k_timer_init(struct device_node *np)
|
||||
{
|
||||
int ret;
|
||||
@@ -90,6 +134,7 @@ static int __init ti_32k_timer_init(struct device_node *np)
|
||||
ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
|
||||
|
||||
ti_32k_timer.counter = ti_32k_timer.base;
|
||||
ti_32k_timer_module_init(np, ti_32k_timer.base);
|
||||
|
||||
/*
|
||||
* 32k sync Counter IP register offsets vary between the highlander
|
||||
@@ -104,6 +149,8 @@ static int __init ti_32k_timer_init(struct device_node *np)
|
||||
else
|
||||
ti_32k_timer.counter += OMAP2_32KSYNCNT_CR_OFF_LOW;
|
||||
|
||||
pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
|
||||
|
||||
ret = clocksource_register_hz(&ti_32k_timer.cs, 32768);
|
||||
if (ret) {
|
||||
pr_err("32k_counter: can't register clocksource\n");
|
||||
@@ -111,7 +158,6 @@ static int __init ti_32k_timer_init(struct device_node *np)
|
||||
}
|
||||
|
||||
sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
|
||||
pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -258,9 +258,7 @@ static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
|
||||
__omap_dm_timer_enable_posted(timer);
|
||||
omap_dm_timer_disable(timer);
|
||||
|
||||
rc = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 omap_dm_timer_reserved_systimer(int id)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user