cregit-Linux how code gets into the kernel

Release 4.11 drivers/clocksource/time-orion.c

/*
 * Marvell Orion SoC timer handling.
 *
 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 *
 * Timer 0 is used as free-running clocksource, while timer 1 is
 * used as clock_event_device.
 */

#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>
#include <linux/sched_clock.h>


#define TIMER_CTRL		0x00

#define  TIMER0_EN		BIT(0)

#define  TIMER0_RELOAD_EN	BIT(1)

#define  TIMER1_EN		BIT(2)

#define  TIMER1_RELOAD_EN	BIT(3)

#define TIMER0_RELOAD		0x10

#define TIMER0_VAL		0x14

#define TIMER1_RELOAD		0x18

#define TIMER1_VAL		0x1c


#define ORION_ONESHOT_MIN	1

#define ORION_ONESHOT_MAX	0xfffffffe


static void __iomem *timer_base;

/*
 * Free-running clocksource handling.
 */

static u64 notrace orion_read_sched_clock(void) { return ~readl(timer_base + TIMER0_VAL); }

Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth1794.44%150.00%
Stephen Boyd15.56%150.00%
Total18100.00%2100.00%

/* * Clockevent handling. */ static u32 ticks_per_jiffy;
static int orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev) { /* setup and enable one-shot timer */ writel(delta, timer_base + TIMER1_VAL); atomic_io_modify(timer_base + TIMER_CTRL, TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_EN); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth3482.93%150.00%
Ezequiel García717.07%150.00%
Total41100.00%2100.00%


static int orion_clkevt_shutdown(struct clock_event_device *dev) { /* disable timer */ atomic_io_modify(timer_base + TIMER_CTRL, TIMER1_RELOAD_EN | TIMER1_EN, 0); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Viresh Kumar2071.43%150.00%
Sebastian Hesselbarth828.57%150.00%
Total28100.00%2100.00%


static int orion_clkevt_set_periodic(struct clock_event_device *dev) { /* setup and enable periodic timer at 1/HZ intervals */ writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); atomic_io_modify(timer_base + TIMER_CTRL, TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_RELOAD_EN | TIMER1_EN); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth3363.46%133.33%
Viresh Kumar1121.15%133.33%
Ezequiel García815.38%133.33%
Total52100.00%3100.00%

static struct clock_event_device orion_clkevt = { .name = "orion_event", .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, .shift = 32, .rating = 300, .set_next_event = orion_clkevt_next_event, .set_state_shutdown = orion_clkevt_shutdown, .set_state_periodic = orion_clkevt_set_periodic, .set_state_oneshot = orion_clkevt_shutdown, .tick_resume = orion_clkevt_shutdown, };
static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id) { orion_clkevt.event_handler(&orion_clkevt); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth24100.00%1100.00%
Total24100.00%1100.00%

static struct irqaction orion_clkevt_irq = { .name = "orion_event", .flags = IRQF_TIMER, .handler = orion_clkevt_irq_handler, };
static int __init orion_timer_init(struct device_node *np) { struct clk *clk; int irq, ret; /* timer registers are shared with watchdog timer */ timer_base = of_iomap(np, 0); if (!timer_base) { pr_err("%s: unable to map resource\n", np->name); return -ENXIO; } clk = of_clk_get(np, 0); if (IS_ERR(clk)) { pr_err("%s: unable to get clk\n", np->name); return PTR_ERR(clk); } ret = clk_prepare_enable(clk); if (ret) { pr_err("Failed to prepare clock"); return ret; } /* we are only interested in timer1 irq */ irq = irq_of_parse_and_map(np, 1); if (irq <= 0) { pr_err("%s: unable to parse timer1 irq\n", np->name); return -EINVAL; } /* setup timer0 as free-running clocksource */ writel(~0, timer_base + TIMER0_VAL); writel(~0, timer_base + TIMER0_RELOAD); atomic_io_modify(timer_base + TIMER_CTRL, TIMER0_RELOAD_EN | TIMER0_EN, TIMER0_RELOAD_EN | TIMER0_EN); ret = clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", clk_get_rate(clk), 300, 32, clocksource_mmio_readl_down); if (ret) { pr_err("Failed to initialize mmio timer"); return ret; } sched_clock_register(orion_read_sched_clock, 32, clk_get_rate(clk)); /* setup timer1 as clockevent timer */ ret = setup_irq(irq, &orion_clkevt_irq); if (ret) { pr_err("%s: unable to setup irq\n", np->name); return ret; } ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; orion_clkevt.cpumask = cpumask_of(0); orion_clkevt.irq = irq; clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk), ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth21672.48%125.00%
Daniel Lezcano7324.50%125.00%
Ezequiel García82.68%125.00%
Stephen Boyd10.34%125.00%
Total298100.00%4100.00%

CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init);

Overall Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth48276.51%114.29%
Daniel Lezcano7411.75%228.57%
Viresh Kumar487.62%114.29%
Ezequiel García233.65%114.29%
Stephen Boyd30.48%228.57%
Total630100.00%7100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.