Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clocksource/drivers/moxart: Use struct to hold state

Add a struct moxart_timer to hold the driver state, including the
irqaction and struct clock_event_device.

Most importantly this holds values for enabling and disabling the timer,
so future support can be added for devices that use different bits for
enable/disable.

In preparation for future hardware support we add a MOXART prefix to the
existing values.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>

authored by

Joel Stanley and committed by
Daniel Lezcano
82fdd070 70164742

+84 -59
+84 -59
drivers/clocksource/moxart_timer.c
··· 21 21 #include <linux/io.h> 22 22 #include <linux/clocksource.h> 23 23 #include <linux/bitops.h> 24 + #include <linux/slab.h> 24 25 25 26 #define TIMER1_BASE 0x00 26 27 #define TIMER2_BASE 0x10 ··· 37 36 #define TIMER_INTR_MASK 0x38 38 37 39 38 /* 40 - * TIMER_CR flags: 39 + * Moxart TIMER_CR flags: 41 40 * 42 - * TIMEREG_CR_*_CLOCK 0: PCLK, 1: EXT1CLK 43 - * TIMEREG_CR_*_INT overflow interrupt enable bit 41 + * MOXART_CR_*_CLOCK 0: PCLK, 1: EXT1CLK 42 + * MOXART_CR_*_INT overflow interrupt enable bit 44 43 */ 45 - #define TIMEREG_CR_1_ENABLE BIT(0) 46 - #define TIMEREG_CR_1_CLOCK BIT(1) 47 - #define TIMEREG_CR_1_INT BIT(2) 48 - #define TIMEREG_CR_2_ENABLE BIT(3) 49 - #define TIMEREG_CR_2_CLOCK BIT(4) 50 - #define TIMEREG_CR_2_INT BIT(5) 51 - #define TIMEREG_CR_3_ENABLE BIT(6) 52 - #define TIMEREG_CR_3_CLOCK BIT(7) 53 - #define TIMEREG_CR_3_INT BIT(8) 54 - #define TIMEREG_CR_COUNT_UP BIT(9) 44 + #define MOXART_CR_1_ENABLE BIT(0) 45 + #define MOXART_CR_1_CLOCK BIT(1) 46 + #define MOXART_CR_1_INT BIT(2) 47 + #define MOXART_CR_2_ENABLE BIT(3) 48 + #define MOXART_CR_2_CLOCK BIT(4) 49 + #define MOXART_CR_2_INT BIT(5) 50 + #define MOXART_CR_3_ENABLE BIT(6) 51 + #define MOXART_CR_3_CLOCK BIT(7) 52 + #define MOXART_CR_3_INT BIT(8) 53 + #define MOXART_CR_COUNT_UP BIT(9) 55 54 56 - #define TIMER1_ENABLE (TIMEREG_CR_2_ENABLE | TIMEREG_CR_1_ENABLE) 57 - #define TIMER1_DISABLE (TIMEREG_CR_2_ENABLE) 55 + #define MOXART_TIMER1_ENABLE (MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE) 56 + #define MOXART_TIMER1_DISABLE (MOXART_CR_2_ENABLE) 58 57 59 - static void __iomem *base; 60 - static unsigned int clock_count_per_tick; 58 + struct moxart_timer { 59 + void __iomem *base; 60 + unsigned int t1_disable_val; 61 + unsigned int t1_enable_val; 62 + unsigned int count_per_tick; 63 + struct clock_event_device clkevt; 64 + struct irqaction act; 65 + }; 66 + 67 + static inline struct moxart_timer *to_moxart(struct clock_event_device *evt) 68 + { 69 + return container_of(evt, struct moxart_timer, clkevt); 70 + } 61 71 62 72 static inline void moxart_disable(struct clock_event_device *evt) 63 73 { 64 - writel(TIMER1_DISABLE, base + TIMER_CR); 74 + struct moxart_timer *timer = to_moxart(evt); 75 + 76 + writel(timer->t1_disable_val, timer->base + TIMER_CR); 65 77 } 66 78 67 79 static inline void moxart_enable(struct clock_event_device *evt) 68 80 { 69 - writel(TIMER1_ENABLE, base + TIMER_CR); 81 + struct moxart_timer *timer = to_moxart(evt); 82 + 83 + writel(timer->t1_enable_val, timer->base + TIMER_CR); 70 84 } 71 85 72 86 static int moxart_shutdown(struct clock_event_device *evt) ··· 93 77 static int moxart_set_oneshot(struct clock_event_device *evt) 94 78 { 95 79 moxart_disable(evt); 96 - writel(~0, base + TIMER1_BASE + REG_LOAD); 80 + writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD); 97 81 return 0; 98 82 } 99 83 100 84 static int moxart_set_periodic(struct clock_event_device *evt) 101 85 { 102 - writel(clock_count_per_tick, base + TIMER1_BASE + REG_LOAD); 86 + struct moxart_timer *timer = to_moxart(evt); 87 + 88 + moxart_disable(evt); 89 + writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD); 90 + writel(0, timer->base + TIMER1_BASE + REG_MATCH1); 103 91 moxart_enable(evt); 104 92 return 0; 105 93 } ··· 111 91 static int moxart_clkevt_next_event(unsigned long cycles, 112 92 struct clock_event_device *evt) 113 93 { 94 + struct moxart_timer *timer = to_moxart(evt); 114 95 u32 u; 115 96 116 97 moxart_disable(evt); 117 98 118 - u = readl(base + TIMER1_BASE + REG_COUNT) - cycles; 119 - writel(u, base + TIMER1_BASE + REG_MATCH1); 99 + u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles; 100 + writel(u, timer->base + TIMER1_BASE + REG_MATCH1); 120 101 121 102 moxart_enable(evt); 122 103 123 104 return 0; 124 105 } 125 - 126 - static struct clock_event_device moxart_clockevent = { 127 - .name = "moxart_timer", 128 - .rating = 200, 129 - .features = CLOCK_EVT_FEAT_PERIODIC | 130 - CLOCK_EVT_FEAT_ONESHOT, 131 - .set_state_shutdown = moxart_shutdown, 132 - .set_state_periodic = moxart_set_periodic, 133 - .set_state_oneshot = moxart_set_oneshot, 134 - .tick_resume = moxart_set_oneshot, 135 - .set_next_event = moxart_clkevt_next_event, 136 - }; 137 106 138 107 static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id) 139 108 { ··· 131 122 return IRQ_HANDLED; 132 123 } 133 124 134 - static struct irqaction moxart_timer_irq = { 135 - .name = "moxart-timer", 136 - .flags = IRQF_TIMER, 137 - .handler = moxart_timer_interrupt, 138 - .dev_id = &moxart_clockevent, 139 - }; 140 - 141 125 static int __init moxart_timer_init(struct device_node *node) 142 126 { 143 127 int ret, irq; 144 128 unsigned long pclk; 145 129 struct clk *clk; 130 + struct moxart_timer *timer; 146 131 147 - base = of_iomap(node, 0); 148 - if (!base) { 132 + timer = kzalloc(sizeof(*timer), GFP_KERNEL); 133 + if (!timer) 134 + return -ENOMEM; 135 + 136 + timer->base = of_iomap(node, 0); 137 + if (!timer->base) { 149 138 pr_err("%s: of_iomap failed\n", node->full_name); 150 139 return -ENXIO; 151 140 } ··· 154 147 return -EINVAL; 155 148 } 156 149 157 - ret = setup_irq(irq, &moxart_timer_irq); 158 - if (ret) { 159 - pr_err("%s: setup_irq failed\n", node->full_name); 160 - return ret; 161 - } 162 - 163 150 clk = of_clk_get(node, 0); 164 151 if (IS_ERR(clk)) { 165 152 pr_err("%s: of_clk_get failed\n", node->full_name); ··· 162 161 163 162 pclk = clk_get_rate(clk); 164 163 165 - ret = clocksource_mmio_init(base + TIMER2_BASE + REG_COUNT, 164 + if (of_device_is_compatible(node, "moxa,moxart-timer")) { 165 + timer->t1_enable_val = MOXART_TIMER1_ENABLE; 166 + timer->t1_disable_val = MOXART_TIMER1_DISABLE; 167 + } else 168 + panic("%s: unknown platform\n", node->full_name); 169 + 170 + timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); 171 + 172 + timer->clkevt.name = node->name; 173 + timer->clkevt.rating = 200; 174 + timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | 175 + CLOCK_EVT_FEAT_ONESHOT; 176 + timer->clkevt.set_state_shutdown = moxart_shutdown; 177 + timer->clkevt.set_state_periodic = moxart_set_periodic; 178 + timer->clkevt.set_state_oneshot = moxart_set_oneshot; 179 + timer->clkevt.tick_resume = moxart_set_oneshot; 180 + timer->clkevt.set_next_event = moxart_clkevt_next_event; 181 + timer->clkevt.cpumask = cpumask_of(0); 182 + timer->clkevt.irq = irq; 183 + timer->act.name = node->name; 184 + timer->act.flags = IRQF_TIMER; 185 + timer->act.handler = moxart_timer_interrupt; 186 + timer->act.dev_id = &timer->clkevt; 187 + 188 + ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT, 166 189 "moxart_timer", pclk, 200, 32, 167 190 clocksource_mmio_readl_down); 168 191 if (ret) { ··· 194 169 return ret; 195 170 } 196 171 197 - clock_count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); 172 + ret = setup_irq(irq, &timer->act); 173 + if (ret) { 174 + pr_err("%s: setup_irq failed\n", node->full_name); 175 + return ret; 176 + } 198 177 199 - writel(~0, base + TIMER2_BASE + REG_LOAD); 200 - writel(TIMEREG_CR_2_ENABLE, base + TIMER_CR); 201 - 202 - moxart_clockevent.cpumask = cpumask_of(0); 203 - moxart_clockevent.irq = irq; 178 + writel(~0, timer->base + TIMER2_BASE + REG_LOAD); 179 + writel(timer->t1_disable_val, timer->base + TIMER_CR); 204 180 205 181 /* 206 182 * documentation is not publicly available: ··· 209 183 * max_delta 0xfffffffe should be ok because count 210 184 * register size is u32 211 185 */ 212 - clockevents_config_and_register(&moxart_clockevent, pclk, 213 - 0x4, 0xfffffffe); 186 + clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe); 214 187 215 188 return 0; 216 189 }