diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2017-03-08 14:09:09 -0800 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-03-09 11:51:28 +0100 |
commit | a76714f7f9c6f1e3f1ebafc4fc2e197181ac9e8c (patch) | |
tree | 22211660a21c58bd450610360bd2dd2391f53962 /drivers/clocksource | |
parent | d6200fe41500c9b06e12d43aaddd060eee8e1b8d (diff) | |
download | barebox-a76714f7f9c6f1e3f1ebafc4fc2e197181ac9e8c.tar.gz barebox-a76714f7f9c6f1e3f1ebafc4fc2e197181ac9e8c.tar.xz |
clocksource: at91: Move to 'drivers/clocksource'
Move PIT driver code to 'drivers/clocsource' and accomodate it by
adjusting Kconfig variables. Rename the file to 'timer-atmel-pit.c' to
re-align the driver with code in Linux kernel.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/Kconfig | 4 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
-rw-r--r-- | drivers/clocksource/timer-atmel-pit.c | 114 |
3 files changed, 119 insertions, 0 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f1ab554f96..f3c3255ffc 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -53,3 +53,7 @@ config CLOCKSOURCE_UEMD config CLOCKSOURCE_ROCKCHIP bool depends on ARCH_ROCKCHIP + +config CLOCKSOURCE_ATMEL_PIT + bool + depends on SOC_AT91SAM9 || SOC_SAMA5 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 39982ffb28..0564d8f5a9 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o obj-$(CONFIG_CLOCKSOURCE_UEMD) += uemd.o obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o +obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c new file mode 100644 index 0000000000..cc7ad2f39a --- /dev/null +++ b/drivers/clocksource/timer-atmel-pit.c @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <common.h> +#include <init.h> +#include <clock.h> +#include <mach/hardware.h> +#include <mach/at91_pit.h> +#include <mach/io.h> +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> + +#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) +#define pit_write(reg, val) __raw_writel(val, pit_base + reg) +#define pit_read(reg) __raw_readl(pit_base + reg) + +static __iomem void *pit_base; + +uint64_t at91sam9_clocksource_read(void) +{ + return pit_read(AT91_PIT_PIIR); +} + +static struct clocksource cs = { + .read = at91sam9_clocksource_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 10, +}; + +static void at91_pit_stop(void) +{ + /* Disable timer and irqs */ + pit_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts, wait for PIT to stop counting */ + while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0); +} + +static void at91sam926x_pit_reset(void) +{ + at91_pit_stop(); + + /* Start PIT but don't enable IRQ */ + pit_write(AT91_PIT_MR, 0xfffff | AT91_PIT_PITEN); +} + +static int at91_pit_probe(struct device_d *dev) +{ + struct clk *clk; + u32 pit_rate; + int ret; + + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(clk); + if (ret < 0) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(clk); + return ret; + } + + pit_base = dev_request_mem_region_err_null(dev, 0); + if (!pit_base) + return -ENOENT; + + pit_rate = clk_get_rate(clk) / 16; + + at91sam926x_pit_reset(); + + cs.mult = clocksource_hz2mult(pit_rate, cs.shift); + + return init_clock(&cs); +} + +static struct driver_d at91_pit_driver = { + .name = "at91-pit", + .probe = at91_pit_probe, +}; + +static int at91_pit_init(void) +{ + return platform_driver_register(&at91_pit_driver); +} +postcore_initcall(at91_pit_init); |