timer.c (3406B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Ralink RT2880 timer 4 * Author: John Crispin 5 * 6 * Copyright (C) 2013 John Crispin <john@phrozen.org> 7*/ 8 9#include <linux/platform_device.h> 10#include <linux/interrupt.h> 11#include <linux/timer.h> 12#include <linux/of_gpio.h> 13#include <linux/clk.h> 14 15#include <asm/mach-ralink/ralink_regs.h> 16 17#define TIMER_REG_TMRSTAT 0x00 18#define TIMER_REG_TMR0LOAD 0x10 19#define TIMER_REG_TMR0CTL 0x18 20 21#define TMRSTAT_TMR0INT BIT(0) 22 23#define TMR0CTL_ENABLE BIT(7) 24#define TMR0CTL_MODE_PERIODIC BIT(4) 25#define TMR0CTL_PRESCALER 1 26#define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER) 27#define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER)) 28 29struct rt_timer { 30 struct device *dev; 31 void __iomem *membase; 32 int irq; 33 unsigned long timer_freq; 34 unsigned long timer_div; 35}; 36 37static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val) 38{ 39 __raw_writel(val, rt->membase + reg); 40} 41 42static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg) 43{ 44 return __raw_readl(rt->membase + reg); 45} 46 47static irqreturn_t rt_timer_irq(int irq, void *_rt) 48{ 49 struct rt_timer *rt = (struct rt_timer *) _rt; 50 51 rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); 52 rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT); 53 54 return IRQ_HANDLED; 55} 56 57 58static int rt_timer_request(struct rt_timer *rt) 59{ 60 int err = request_irq(rt->irq, rt_timer_irq, 0, 61 dev_name(rt->dev), rt); 62 if (err) { 63 dev_err(rt->dev, "failed to request irq\n"); 64 } else { 65 u32 t = TMR0CTL_MODE_PERIODIC | TMR0CTL_PRESCALE_VAL; 66 rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); 67 } 68 return err; 69} 70 71static int rt_timer_config(struct rt_timer *rt, unsigned long divisor) 72{ 73 if (rt->timer_freq < divisor) 74 rt->timer_div = rt->timer_freq; 75 else 76 rt->timer_div = divisor; 77 78 rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); 79 80 return 0; 81} 82 83static int rt_timer_enable(struct rt_timer *rt) 84{ 85 u32 t; 86 87 rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); 88 89 t = rt_timer_r32(rt, TIMER_REG_TMR0CTL); 90 t |= TMR0CTL_ENABLE; 91 rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); 92 93 return 0; 94} 95 96static int rt_timer_probe(struct platform_device *pdev) 97{ 98 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 99 struct rt_timer *rt; 100 struct clk *clk; 101 102 rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL); 103 if (!rt) { 104 dev_err(&pdev->dev, "failed to allocate memory\n"); 105 return -ENOMEM; 106 } 107 108 rt->irq = platform_get_irq(pdev, 0); 109 if (rt->irq < 0) 110 return rt->irq; 111 112 rt->membase = devm_ioremap_resource(&pdev->dev, res); 113 if (IS_ERR(rt->membase)) 114 return PTR_ERR(rt->membase); 115 116 clk = devm_clk_get(&pdev->dev, NULL); 117 if (IS_ERR(clk)) { 118 dev_err(&pdev->dev, "failed get clock rate\n"); 119 return PTR_ERR(clk); 120 } 121 122 rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV; 123 if (!rt->timer_freq) 124 return -EINVAL; 125 126 rt->dev = &pdev->dev; 127 platform_set_drvdata(pdev, rt); 128 129 rt_timer_request(rt); 130 rt_timer_config(rt, 2); 131 rt_timer_enable(rt); 132 133 dev_info(&pdev->dev, "maximum frequency is %luHz\n", rt->timer_freq); 134 135 return 0; 136} 137 138static const struct of_device_id rt_timer_match[] = { 139 { .compatible = "ralink,rt2880-timer" }, 140 {}, 141}; 142 143static struct platform_driver rt_timer_driver = { 144 .probe = rt_timer_probe, 145 .driver = { 146 .name = "rt-timer", 147 .of_match_table = rt_timer_match, 148 .suppress_bind_attrs = true, 149 }, 150}; 151builtin_platform_driver(rt_timer_driver);