clocksource/drivers/rockchip: Add module support to rockchip timer

Signed-off-by: Tao Huang <huangtao@rock-chips.com>
Change-Id: Ieac5aecb5d50851a70e9f932c1340f253d62c7ec
This commit is contained in:
Tao Huang
2021-07-28 19:12:14 +08:00
parent 949dbda967
commit 4f2d80c1bb
3 changed files with 36 additions and 2 deletions

View File

@@ -220,7 +220,6 @@ config ARCH_ROCKCHIP
select ARCH_HAS_RESET_CONTROLLER
select PINCTRL
select PM
select ROCKCHIP_TIMER
help
This enables support for the ARMv8 based Rockchip chipsets,
like the RK3368.

View File

@@ -84,7 +84,9 @@ config IXP4XX_TIMER
Enables support for the Intel XScale IXP4xx SoC timer.
config ROCKCHIP_TIMER
bool "Rockchip timer driver" if COMPILE_TEST
tristate "Rockchip timer driver"
default ARCH_ROCKCHIP
depends on ARCH_ROCKCHIP || COMPILE_TEST
depends on ARM || ARM64
select TIMER_OF
select CLKSRC_MMIO

View File

@@ -8,11 +8,13 @@
#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#define TIMER_NAME "rk_timer"
@@ -45,7 +47,9 @@ struct rk_clkevt {
};
static struct rk_clkevt *rk_clkevt;
#ifndef MODULE
static struct rk_timer *rk_clksrc;
#endif
static inline struct rk_timer *rk_timer(struct clock_event_device *ce)
{
@@ -119,10 +123,12 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
#ifndef MODULE
static u64 notrace rk_timer_sched_read(void)
{
return ~readl_relaxed(rk_clksrc->base + TIMER_CURRENT_VALUE0);
}
#endif
static int __init
rk_timer_probe(struct rk_timer *timer, struct device_node *np)
@@ -250,6 +256,7 @@ out:
return ret;
}
#ifndef MODULE
static int __init rk_clksrc_init(struct device_node *np)
{
int ret = -EINVAL;
@@ -287,14 +294,17 @@ out:
rk_clksrc = ERR_PTR(ret);
return ret;
}
#endif
static int __init rk_timer_init(struct device_node *np)
{
if (!rk_clkevt)
return rk_clkevt_init(np);
#ifndef MODULE
if (!rk_clksrc)
return rk_clksrc_init(np);
#endif
pr_err("Too many timer definitions for '%s'\n", TIMER_NAME);
return -EINVAL;
@@ -302,3 +312,26 @@ static int __init rk_timer_init(struct device_node *np)
TIMER_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_init);
TIMER_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_init);
#ifdef MODULE
static int __init rk_timer_driver_probe(struct platform_device *pdev)
{
return rk_timer_init(pdev->dev.of_node);
}
static const struct of_device_id rk_timer_match_table[] = {
{ .compatible = "rockchip,rk3288-timer" },
{ .compatible = "rockchip,rk3399-timer" },
{ /* sentinel */ },
};
static struct platform_driver rk_timer_driver = {
.driver = {
.name = TIMER_NAME,
.of_match_table = rk_timer_match_table,
},
};
module_platform_driver_probe(rk_timer_driver, rk_timer_driver_probe);
MODULE_LICENSE("GPL");
#endif