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

Configure Feed

Select the types of activity you want to include in your feed.

clocksource/drivers/vf-pit: Allocate the struct timer at init time

Instead of having a static global structure for a timer, let's
allocate it dynamically so we can create multiple instances in the
future to support multiple timers. At the same time, add the
rollbacking code in case of error.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20250804152344.1109310-8-daniel.lezcano@linaro.org

+37 -11
+37 -11
drivers/clocksource/timer-vf-pit.c
··· 37 37 struct clocksource cs; 38 38 }; 39 39 40 - static struct pit_timer pit_timer; 41 - 42 40 static void __iomem *clksrc_base; 43 41 44 42 static inline struct pit_timer *ced_to_pit(struct clock_event_device *ced) ··· 187 189 188 190 static int __init pit_timer_init(struct device_node *np) 189 191 { 192 + struct pit_timer *pit; 190 193 struct clk *pit_clk; 191 194 void __iomem *timer_base; 192 195 unsigned long clk_rate; 193 196 int irq, ret; 194 197 198 + pit = kzalloc(sizeof(*pit), GFP_KERNEL); 199 + if (!pit) 200 + return -ENOMEM; 201 + 202 + ret = -ENXIO; 195 203 timer_base = of_iomap(np, 0); 196 204 if (!timer_base) { 197 205 pr_err("Failed to iomap\n"); 198 - return -ENXIO; 206 + goto out_kfree; 199 207 } 200 208 209 + ret = -EINVAL; 201 210 irq = irq_of_parse_and_map(np, 0); 202 - if (irq <= 0) 203 - return -EINVAL; 211 + if (irq <= 0) { 212 + pr_err("Failed to irq_of_parse_and_map\n"); 213 + goto out_iounmap; 214 + } 204 215 205 216 pit_clk = of_clk_get(np, 0); 206 - if (IS_ERR(pit_clk)) 207 - return PTR_ERR(pit_clk); 217 + if (IS_ERR(pit_clk)) { 218 + ret = PTR_ERR(pit_clk); 219 + goto out_iounmap; 220 + } 208 221 209 222 ret = clk_prepare_enable(pit_clk); 210 223 if (ret) 211 - return ret; 224 + goto out_clk_put; 212 225 213 226 clk_rate = clk_get_rate(pit_clk); 214 227 215 228 /* enable the pit module */ 216 229 writel(~PITMCR_MDIS, timer_base + PITMCR); 217 230 218 - ret = pit_clocksource_init(&pit_timer, timer_base, clk_rate); 231 + ret = pit_clocksource_init(pit, timer_base, clk_rate); 219 232 if (ret) 220 - return ret; 233 + goto out_disable_unprepare; 221 234 222 - return pit_clockevent_init(&pit_timer, timer_base, clk_rate, irq, 0); 235 + ret = pit_clockevent_init(pit, timer_base, clk_rate, irq, 0); 236 + if (ret) 237 + goto out_pit_clocksource_unregister; 238 + 239 + return 0; 240 + 241 + out_pit_clocksource_unregister: 242 + clocksource_unregister(&pit->cs); 243 + out_disable_unprepare: 244 + clk_disable_unprepare(pit_clk); 245 + out_clk_put: 246 + clk_put(pit_clk); 247 + out_iounmap: 248 + iounmap(timer_base); 249 + out_kfree: 250 + kfree(pit); 251 + 252 + return ret; 223 253 } 224 254 TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);