1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2017, Linaro Ltd. All rights reserved. 4 * 5 * Author: Daniel Lezcano <daniel.lezcano@linaro.org> 6 */ 7 #include <linux/clk.h> 8 #include <linux/interrupt.h> 9 #include <linux/of.h> 10 #include <linux/of_address.h> 11 #include <linux/of_irq.h> 12 #include <linux/slab.h> 13 14 #include "timer-of.h" 15 16 /** 17 * timer_of_irq_exit - Release the interrupt 18 * @of_irq: an of_timer_irq structure pointer 19 * 20 * Free the irq resource 21 */ 22 static __init void timer_of_irq_exit(struct of_timer_irq *of_irq) 23 { 24 struct timer_of *to = container_of(of_irq, struct timer_of, of_irq); 25 26 struct clock_event_device *clkevt = &to->clkevt; 27 28 of_irq->percpu ? free_percpu_irq(of_irq->irq, clkevt) : 29 free_irq(of_irq->irq, clkevt); 30 } 31 32 /** 33 * timer_of_irq_init - Request the interrupt 34 * @np: a device tree node pointer 35 * @of_irq: an of_timer_irq structure pointer 36 * 37 * Get the interrupt number from the DT from its definition and 38 * request it. The interrupt is gotten by falling back the following way: 39 * 40 * - Get interrupt number by name 41 * - Get interrupt number by index 42 * 43 * When the interrupt is per CPU, 'request_percpu_irq()' is called, 44 * otherwise 'request_irq()' is used. 45 * 46 * Returns 0 on success, < 0 otherwise 47 */ 48 static __init int timer_of_irq_init(struct device_node *np, 49 struct of_timer_irq *of_irq) 50 { 51 int ret; 52 struct timer_of *to = container_of(of_irq, struct timer_of, of_irq); 53 struct clock_event_device *clkevt = &to->clkevt; 54 55 if (of_irq->name) { 56 of_irq->irq = ret = of_irq_get_byname(np, of_irq->name); 57 if (ret < 0) { 58 pr_err("Failed to get interrupt %s for %s\n", 59 of_irq->name, np->full_name); 60 return ret; 61 } 62 } else { 63 of_irq->irq = irq_of_parse_and_map(np, of_irq->index); 64 } 65 if (!of_irq->irq) { 66 pr_err("Failed to map interrupt for %pOF\n", np); 67 return -EINVAL; 68 } 69 70 ret = of_irq->percpu ? 71 request_percpu_irq(of_irq->irq, of_irq->handler, 72 np->full_name, clkevt) : 73 request_irq(of_irq->irq, of_irq->handler, 74 of_irq->flags ? of_irq->flags : IRQF_TIMER, 75 np->full_name, clkevt); 76 if (ret) { 77 pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np); 78 return ret; 79 } 80 81 clkevt->irq = of_irq->irq; 82 83 return 0; 84 } 85 86 /** 87 * timer_of_clk_exit - Release the clock resources 88 * @of_clk: a of_timer_clk structure pointer 89 * 90 * Disables and releases the refcount on the clk 91 */ 92 static __init void timer_of_clk_exit(struct of_timer_clk *of_clk) 93 { 94 of_clk->rate = 0; 95 clk_disable_unprepare(of_clk->clk); 96 clk_put(of_clk->clk); 97 } 98 99 /** 100 * timer_of_clk_init - Initialize the clock resources 101 * @np: a device tree node pointer 102 * @of_clk: a of_timer_clk structure pointer 103 * 104 * Get the clock by name or by index, enable it and get the rate 105 * 106 * Returns 0 on success, < 0 otherwise 107 */ 108 static __init int timer_of_clk_init(struct device_node *np, 109 struct of_timer_clk *of_clk) 110 { 111 int ret; 112 113 of_clk->clk = of_clk->name ? of_clk_get_by_name(np, of_clk->name) : 114 of_clk_get(np, of_clk->index); 115 if (IS_ERR(of_clk->clk)) { 116 pr_err("Failed to get clock for %pOF\n", np); 117 return PTR_ERR(of_clk->clk); 118 } 119 120 ret = clk_prepare_enable(of_clk->clk); 121 if (ret) { 122 pr_err("Failed for enable clock for %pOF\n", np); 123 goto out_clk_put; 124 } 125 126 of_clk->rate = clk_get_rate(of_clk->clk); 127 if (!of_clk->rate) { 128 ret = -EINVAL; 129 pr_err("Failed to get clock rate for %pOF\n", np); 130 goto out_clk_disable; 131 } 132 133 of_clk->period = DIV_ROUND_UP(of_clk->rate, HZ); 134 out: 135 return ret; 136 137 out_clk_disable: 138 clk_disable_unprepare(of_clk->clk); 139 out_clk_put: 140 clk_put(of_clk->clk); 141 142 goto out; 143 } 144 145 static __init void timer_of_base_exit(struct of_timer_base *of_base) 146 { 147 iounmap(of_base->base); 148 } 149 150 static __init int timer_of_base_init(struct device_node *np, 151 struct of_timer_base *of_base) 152 { 153 of_base->base = of_base->name ? 154 of_io_request_and_map(np, of_base->index, of_base->name) : 155 of_iomap(np, of_base->index); 156 if (IS_ERR(of_base->base)) { 157 pr_err("Failed to iomap (%s)\n", of_base->name); 158 return PTR_ERR(of_base->base); 159 } 160 161 return 0; 162 } 163 164 int __init timer_of_init(struct device_node *np, struct timer_of *to) 165 { 166 int ret = -EINVAL; 167 int flags = 0; 168 169 if (to->flags & TIMER_OF_BASE) { 170 ret = timer_of_base_init(np, &to->of_base); 171 if (ret) 172 goto out_fail; 173 flags |= TIMER_OF_BASE; 174 } 175 176 if (to->flags & TIMER_OF_CLOCK) { 177 ret = timer_of_clk_init(np, &to->of_clk); 178 if (ret) 179 goto out_fail; 180 flags |= TIMER_OF_CLOCK; 181 } 182 183 if (to->flags & TIMER_OF_IRQ) { 184 ret = timer_of_irq_init(np, &to->of_irq); 185 if (ret) 186 goto out_fail; 187 flags |= TIMER_OF_IRQ; 188 } 189 190 if (!to->clkevt.name) 191 to->clkevt.name = np->name; 192 193 to->np = np; 194 195 return ret; 196 197 out_fail: 198 if (flags & TIMER_OF_IRQ) 199 timer_of_irq_exit(&to->of_irq); 200 201 if (flags & TIMER_OF_CLOCK) 202 timer_of_clk_exit(&to->of_clk); 203 204 if (flags & TIMER_OF_BASE) 205 timer_of_base_exit(&to->of_base); 206 return ret; 207 } 208 209 /** 210 * timer_of_cleanup - release timer_of ressources 211 * @to: timer_of structure 212 * 213 * Release the ressources that has been used in timer_of_init(). 214 * This function should be called in init error cases 215 */ 216 void __init timer_of_cleanup(struct timer_of *to) 217 { 218 if (to->flags & TIMER_OF_IRQ) 219 timer_of_irq_exit(&to->of_irq); 220 221 if (to->flags & TIMER_OF_CLOCK) 222 timer_of_clk_exit(&to->of_clk); 223 224 if (to->flags & TIMER_OF_BASE) 225 timer_of_base_exit(&to->of_base); 226 } 227