.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * PTP 1588 clock for Freescale QorIQ 1588 timer |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2010 OMICRON electronics GmbH |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | | - * |
---|
16 | | - * You should have received a copy of the GNU General Public License |
---|
17 | | - * along with this program; if not, write to the Free Software |
---|
18 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
19 | 6 | */ |
---|
20 | 7 | |
---|
21 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
22 | 9 | |
---|
23 | 10 | #include <linux/device.h> |
---|
24 | 11 | #include <linux/hrtimer.h> |
---|
25 | | -#include <linux/interrupt.h> |
---|
26 | 12 | #include <linux/kernel.h> |
---|
27 | 13 | #include <linux/module.h> |
---|
28 | 14 | #include <linux/of.h> |
---|
.. | .. |
---|
37 | 23 | * Register access functions |
---|
38 | 24 | */ |
---|
39 | 25 | |
---|
40 | | -/* Caller must hold qoriq_ptp->lock. */ |
---|
41 | | -static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp) |
---|
| 26 | +/* Caller must hold ptp_qoriq->lock. */ |
---|
| 27 | +static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq) |
---|
42 | 28 | { |
---|
43 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 29 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
44 | 30 | u64 ns; |
---|
45 | 31 | u32 lo, hi; |
---|
46 | 32 | |
---|
47 | | - lo = qoriq_read(®s->ctrl_regs->tmr_cnt_l); |
---|
48 | | - hi = qoriq_read(®s->ctrl_regs->tmr_cnt_h); |
---|
| 33 | + lo = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_l); |
---|
| 34 | + hi = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_h); |
---|
49 | 35 | ns = ((u64) hi) << 32; |
---|
50 | 36 | ns |= lo; |
---|
51 | 37 | return ns; |
---|
52 | 38 | } |
---|
53 | 39 | |
---|
54 | | -/* Caller must hold qoriq_ptp->lock. */ |
---|
55 | | -static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns) |
---|
| 40 | +/* Caller must hold ptp_qoriq->lock. */ |
---|
| 41 | +static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns) |
---|
56 | 42 | { |
---|
57 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 43 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
58 | 44 | u32 hi = ns >> 32; |
---|
59 | 45 | u32 lo = ns & 0xffffffff; |
---|
60 | 46 | |
---|
61 | | - qoriq_write(®s->ctrl_regs->tmr_cnt_l, lo); |
---|
62 | | - qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi); |
---|
| 47 | + ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_l, lo); |
---|
| 48 | + ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_h, hi); |
---|
63 | 49 | } |
---|
64 | 50 | |
---|
65 | | -/* Caller must hold qoriq_ptp->lock. */ |
---|
66 | | -static void set_alarm(struct qoriq_ptp *qoriq_ptp) |
---|
| 51 | +/* Caller must hold ptp_qoriq->lock. */ |
---|
| 52 | +static void set_alarm(struct ptp_qoriq *ptp_qoriq) |
---|
67 | 53 | { |
---|
68 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 54 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
69 | 55 | u64 ns; |
---|
70 | 56 | u32 lo, hi; |
---|
71 | 57 | |
---|
72 | | - ns = tmr_cnt_read(qoriq_ptp) + 1500000000ULL; |
---|
| 58 | + ns = tmr_cnt_read(ptp_qoriq) + 1500000000ULL; |
---|
73 | 59 | ns = div_u64(ns, 1000000000UL) * 1000000000ULL; |
---|
74 | | - ns -= qoriq_ptp->tclk_period; |
---|
| 60 | + ns -= ptp_qoriq->tclk_period; |
---|
75 | 61 | hi = ns >> 32; |
---|
76 | 62 | lo = ns & 0xffffffff; |
---|
77 | | - qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo); |
---|
78 | | - qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi); |
---|
| 63 | + ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_l, lo); |
---|
| 64 | + ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_h, hi); |
---|
79 | 65 | } |
---|
80 | 66 | |
---|
81 | | -/* Caller must hold qoriq_ptp->lock. */ |
---|
82 | | -static void set_fipers(struct qoriq_ptp *qoriq_ptp) |
---|
| 67 | +/* Caller must hold ptp_qoriq->lock. */ |
---|
| 68 | +static void set_fipers(struct ptp_qoriq *ptp_qoriq) |
---|
83 | 69 | { |
---|
84 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 70 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
85 | 71 | |
---|
86 | | - set_alarm(qoriq_ptp); |
---|
87 | | - qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1); |
---|
88 | | - qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2); |
---|
| 72 | + set_alarm(ptp_qoriq); |
---|
| 73 | + ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1); |
---|
| 74 | + ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2); |
---|
| 75 | + |
---|
| 76 | + if (ptp_qoriq->fiper3_support) |
---|
| 77 | + ptp_qoriq->write(®s->fiper_regs->tmr_fiper3, |
---|
| 78 | + ptp_qoriq->tmr_fiper3); |
---|
89 | 79 | } |
---|
| 80 | + |
---|
| 81 | +int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index, bool update_event) |
---|
| 82 | +{ |
---|
| 83 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
| 84 | + struct ptp_clock_event event; |
---|
| 85 | + void __iomem *reg_etts_l; |
---|
| 86 | + void __iomem *reg_etts_h; |
---|
| 87 | + u32 valid, lo, hi; |
---|
| 88 | + |
---|
| 89 | + switch (index) { |
---|
| 90 | + case 0: |
---|
| 91 | + valid = ETS1_VLD; |
---|
| 92 | + reg_etts_l = ®s->etts_regs->tmr_etts1_l; |
---|
| 93 | + reg_etts_h = ®s->etts_regs->tmr_etts1_h; |
---|
| 94 | + break; |
---|
| 95 | + case 1: |
---|
| 96 | + valid = ETS2_VLD; |
---|
| 97 | + reg_etts_l = ®s->etts_regs->tmr_etts2_l; |
---|
| 98 | + reg_etts_h = ®s->etts_regs->tmr_etts2_h; |
---|
| 99 | + break; |
---|
| 100 | + default: |
---|
| 101 | + return -EINVAL; |
---|
| 102 | + } |
---|
| 103 | + |
---|
| 104 | + event.type = PTP_CLOCK_EXTTS; |
---|
| 105 | + event.index = index; |
---|
| 106 | + |
---|
| 107 | + if (ptp_qoriq->extts_fifo_support) |
---|
| 108 | + if (!(ptp_qoriq->read(®s->ctrl_regs->tmr_stat) & valid)) |
---|
| 109 | + return 0; |
---|
| 110 | + |
---|
| 111 | + do { |
---|
| 112 | + lo = ptp_qoriq->read(reg_etts_l); |
---|
| 113 | + hi = ptp_qoriq->read(reg_etts_h); |
---|
| 114 | + |
---|
| 115 | + if (update_event) { |
---|
| 116 | + event.timestamp = ((u64) hi) << 32; |
---|
| 117 | + event.timestamp |= lo; |
---|
| 118 | + ptp_clock_event(ptp_qoriq->clock, &event); |
---|
| 119 | + } |
---|
| 120 | + |
---|
| 121 | + if (!ptp_qoriq->extts_fifo_support) |
---|
| 122 | + break; |
---|
| 123 | + } while (ptp_qoriq->read(®s->ctrl_regs->tmr_stat) & valid); |
---|
| 124 | + |
---|
| 125 | + return 0; |
---|
| 126 | +} |
---|
| 127 | +EXPORT_SYMBOL_GPL(extts_clean_up); |
---|
90 | 128 | |
---|
91 | 129 | /* |
---|
92 | 130 | * Interrupt service routine |
---|
93 | 131 | */ |
---|
94 | 132 | |
---|
95 | | -static irqreturn_t isr(int irq, void *priv) |
---|
| 133 | +irqreturn_t ptp_qoriq_isr(int irq, void *priv) |
---|
96 | 134 | { |
---|
97 | | - struct qoriq_ptp *qoriq_ptp = priv; |
---|
98 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 135 | + struct ptp_qoriq *ptp_qoriq = priv; |
---|
| 136 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
99 | 137 | struct ptp_clock_event event; |
---|
100 | | - u64 ns; |
---|
101 | | - u32 ack = 0, lo, hi, mask, val; |
---|
| 138 | + u32 ack = 0, mask, val, irqs; |
---|
102 | 139 | |
---|
103 | | - val = qoriq_read(®s->ctrl_regs->tmr_tevent); |
---|
| 140 | + spin_lock(&ptp_qoriq->lock); |
---|
104 | 141 | |
---|
105 | | - if (val & ETS1) { |
---|
| 142 | + val = ptp_qoriq->read(®s->ctrl_regs->tmr_tevent); |
---|
| 143 | + mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask); |
---|
| 144 | + |
---|
| 145 | + spin_unlock(&ptp_qoriq->lock); |
---|
| 146 | + |
---|
| 147 | + irqs = val & mask; |
---|
| 148 | + |
---|
| 149 | + if (irqs & ETS1) { |
---|
106 | 150 | ack |= ETS1; |
---|
107 | | - hi = qoriq_read(®s->etts_regs->tmr_etts1_h); |
---|
108 | | - lo = qoriq_read(®s->etts_regs->tmr_etts1_l); |
---|
109 | | - event.type = PTP_CLOCK_EXTTS; |
---|
110 | | - event.index = 0; |
---|
111 | | - event.timestamp = ((u64) hi) << 32; |
---|
112 | | - event.timestamp |= lo; |
---|
113 | | - ptp_clock_event(qoriq_ptp->clock, &event); |
---|
| 151 | + extts_clean_up(ptp_qoriq, 0, true); |
---|
114 | 152 | } |
---|
115 | 153 | |
---|
116 | | - if (val & ETS2) { |
---|
| 154 | + if (irqs & ETS2) { |
---|
117 | 155 | ack |= ETS2; |
---|
118 | | - hi = qoriq_read(®s->etts_regs->tmr_etts2_h); |
---|
119 | | - lo = qoriq_read(®s->etts_regs->tmr_etts2_l); |
---|
120 | | - event.type = PTP_CLOCK_EXTTS; |
---|
121 | | - event.index = 1; |
---|
122 | | - event.timestamp = ((u64) hi) << 32; |
---|
123 | | - event.timestamp |= lo; |
---|
124 | | - ptp_clock_event(qoriq_ptp->clock, &event); |
---|
| 156 | + extts_clean_up(ptp_qoriq, 1, true); |
---|
125 | 157 | } |
---|
126 | 158 | |
---|
127 | | - if (val & ALM2) { |
---|
128 | | - ack |= ALM2; |
---|
129 | | - if (qoriq_ptp->alarm_value) { |
---|
130 | | - event.type = PTP_CLOCK_ALARM; |
---|
131 | | - event.index = 0; |
---|
132 | | - event.timestamp = qoriq_ptp->alarm_value; |
---|
133 | | - ptp_clock_event(qoriq_ptp->clock, &event); |
---|
134 | | - } |
---|
135 | | - if (qoriq_ptp->alarm_interval) { |
---|
136 | | - ns = qoriq_ptp->alarm_value + qoriq_ptp->alarm_interval; |
---|
137 | | - hi = ns >> 32; |
---|
138 | | - lo = ns & 0xffffffff; |
---|
139 | | - spin_lock(&qoriq_ptp->lock); |
---|
140 | | - qoriq_write(®s->alarm_regs->tmr_alarm2_l, lo); |
---|
141 | | - qoriq_write(®s->alarm_regs->tmr_alarm2_h, hi); |
---|
142 | | - spin_unlock(&qoriq_ptp->lock); |
---|
143 | | - qoriq_ptp->alarm_value = ns; |
---|
144 | | - } else { |
---|
145 | | - qoriq_write(®s->ctrl_regs->tmr_tevent, ALM2); |
---|
146 | | - spin_lock(&qoriq_ptp->lock); |
---|
147 | | - mask = qoriq_read(®s->ctrl_regs->tmr_temask); |
---|
148 | | - mask &= ~ALM2EN; |
---|
149 | | - qoriq_write(®s->ctrl_regs->tmr_temask, mask); |
---|
150 | | - spin_unlock(&qoriq_ptp->lock); |
---|
151 | | - qoriq_ptp->alarm_value = 0; |
---|
152 | | - qoriq_ptp->alarm_interval = 0; |
---|
153 | | - } |
---|
154 | | - } |
---|
155 | | - |
---|
156 | | - if (val & PP1) { |
---|
| 159 | + if (irqs & PP1) { |
---|
157 | 160 | ack |= PP1; |
---|
158 | 161 | event.type = PTP_CLOCK_PPS; |
---|
159 | | - ptp_clock_event(qoriq_ptp->clock, &event); |
---|
| 162 | + ptp_clock_event(ptp_qoriq->clock, &event); |
---|
160 | 163 | } |
---|
161 | 164 | |
---|
162 | 165 | if (ack) { |
---|
163 | | - qoriq_write(®s->ctrl_regs->tmr_tevent, ack); |
---|
| 166 | + ptp_qoriq->write(®s->ctrl_regs->tmr_tevent, ack); |
---|
164 | 167 | return IRQ_HANDLED; |
---|
165 | 168 | } else |
---|
166 | 169 | return IRQ_NONE; |
---|
167 | 170 | } |
---|
| 171 | +EXPORT_SYMBOL_GPL(ptp_qoriq_isr); |
---|
168 | 172 | |
---|
169 | 173 | /* |
---|
170 | 174 | * PTP clock operations |
---|
171 | 175 | */ |
---|
172 | 176 | |
---|
173 | | -static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
---|
| 177 | +int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
---|
174 | 178 | { |
---|
175 | 179 | u64 adj, diff; |
---|
176 | 180 | u32 tmr_add; |
---|
177 | 181 | int neg_adj = 0; |
---|
178 | | - struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps); |
---|
179 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 182 | + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); |
---|
| 183 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
180 | 184 | |
---|
181 | 185 | if (scaled_ppm < 0) { |
---|
182 | 186 | neg_adj = 1; |
---|
183 | 187 | scaled_ppm = -scaled_ppm; |
---|
184 | 188 | } |
---|
185 | | - tmr_add = qoriq_ptp->tmr_add; |
---|
| 189 | + tmr_add = ptp_qoriq->tmr_add; |
---|
186 | 190 | adj = tmr_add; |
---|
187 | 191 | |
---|
188 | | - /* calculate diff as adj*(scaled_ppm/65536)/1000000 |
---|
189 | | - * and round() to the nearest integer |
---|
| 192 | + /* |
---|
| 193 | + * Calculate diff and round() to the nearest integer |
---|
| 194 | + * |
---|
| 195 | + * diff = adj * (ppb / 1000000000) |
---|
| 196 | + * = adj * scaled_ppm / 65536000000 |
---|
190 | 197 | */ |
---|
191 | | - adj *= scaled_ppm; |
---|
192 | | - diff = div_u64(adj, 8000000); |
---|
193 | | - diff = (diff >> 13) + ((diff >> 12) & 1); |
---|
| 198 | + diff = mul_u64_u64_div_u64(adj, scaled_ppm, 32768000000); |
---|
| 199 | + diff = DIV64_U64_ROUND_UP(diff, 2); |
---|
194 | 200 | |
---|
195 | 201 | tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; |
---|
196 | | - |
---|
197 | | - qoriq_write(®s->ctrl_regs->tmr_add, tmr_add); |
---|
| 202 | + ptp_qoriq->write(®s->ctrl_regs->tmr_add, tmr_add); |
---|
198 | 203 | |
---|
199 | 204 | return 0; |
---|
200 | 205 | } |
---|
| 206 | +EXPORT_SYMBOL_GPL(ptp_qoriq_adjfine); |
---|
201 | 207 | |
---|
202 | | -static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta) |
---|
| 208 | +int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta) |
---|
203 | 209 | { |
---|
204 | 210 | s64 now; |
---|
205 | 211 | unsigned long flags; |
---|
206 | | - struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps); |
---|
| 212 | + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); |
---|
207 | 213 | |
---|
208 | | - spin_lock_irqsave(&qoriq_ptp->lock, flags); |
---|
| 214 | + spin_lock_irqsave(&ptp_qoriq->lock, flags); |
---|
209 | 215 | |
---|
210 | | - now = tmr_cnt_read(qoriq_ptp); |
---|
| 216 | + now = tmr_cnt_read(ptp_qoriq); |
---|
211 | 217 | now += delta; |
---|
212 | | - tmr_cnt_write(qoriq_ptp, now); |
---|
213 | | - set_fipers(qoriq_ptp); |
---|
| 218 | + tmr_cnt_write(ptp_qoriq, now); |
---|
| 219 | + set_fipers(ptp_qoriq); |
---|
214 | 220 | |
---|
215 | | - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); |
---|
| 221 | + spin_unlock_irqrestore(&ptp_qoriq->lock, flags); |
---|
216 | 222 | |
---|
217 | 223 | return 0; |
---|
218 | 224 | } |
---|
| 225 | +EXPORT_SYMBOL_GPL(ptp_qoriq_adjtime); |
---|
219 | 226 | |
---|
220 | | -static int ptp_qoriq_gettime(struct ptp_clock_info *ptp, |
---|
221 | | - struct timespec64 *ts) |
---|
| 227 | +int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) |
---|
222 | 228 | { |
---|
223 | 229 | u64 ns; |
---|
224 | 230 | unsigned long flags; |
---|
225 | | - struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps); |
---|
| 231 | + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); |
---|
226 | 232 | |
---|
227 | | - spin_lock_irqsave(&qoriq_ptp->lock, flags); |
---|
| 233 | + spin_lock_irqsave(&ptp_qoriq->lock, flags); |
---|
228 | 234 | |
---|
229 | | - ns = tmr_cnt_read(qoriq_ptp); |
---|
| 235 | + ns = tmr_cnt_read(ptp_qoriq); |
---|
230 | 236 | |
---|
231 | | - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); |
---|
| 237 | + spin_unlock_irqrestore(&ptp_qoriq->lock, flags); |
---|
232 | 238 | |
---|
233 | 239 | *ts = ns_to_timespec64(ns); |
---|
234 | 240 | |
---|
235 | 241 | return 0; |
---|
236 | 242 | } |
---|
| 243 | +EXPORT_SYMBOL_GPL(ptp_qoriq_gettime); |
---|
237 | 244 | |
---|
238 | | -static int ptp_qoriq_settime(struct ptp_clock_info *ptp, |
---|
239 | | - const struct timespec64 *ts) |
---|
| 245 | +int ptp_qoriq_settime(struct ptp_clock_info *ptp, |
---|
| 246 | + const struct timespec64 *ts) |
---|
240 | 247 | { |
---|
241 | 248 | u64 ns; |
---|
242 | 249 | unsigned long flags; |
---|
243 | | - struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps); |
---|
| 250 | + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); |
---|
244 | 251 | |
---|
245 | 252 | ns = timespec64_to_ns(ts); |
---|
246 | 253 | |
---|
247 | | - spin_lock_irqsave(&qoriq_ptp->lock, flags); |
---|
| 254 | + spin_lock_irqsave(&ptp_qoriq->lock, flags); |
---|
248 | 255 | |
---|
249 | | - tmr_cnt_write(qoriq_ptp, ns); |
---|
250 | | - set_fipers(qoriq_ptp); |
---|
| 256 | + tmr_cnt_write(ptp_qoriq, ns); |
---|
| 257 | + set_fipers(ptp_qoriq); |
---|
251 | 258 | |
---|
252 | | - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); |
---|
| 259 | + spin_unlock_irqrestore(&ptp_qoriq->lock, flags); |
---|
253 | 260 | |
---|
254 | 261 | return 0; |
---|
255 | 262 | } |
---|
| 263 | +EXPORT_SYMBOL_GPL(ptp_qoriq_settime); |
---|
256 | 264 | |
---|
257 | | -static int ptp_qoriq_enable(struct ptp_clock_info *ptp, |
---|
258 | | - struct ptp_clock_request *rq, int on) |
---|
| 265 | +int ptp_qoriq_enable(struct ptp_clock_info *ptp, |
---|
| 266 | + struct ptp_clock_request *rq, int on) |
---|
259 | 267 | { |
---|
260 | | - struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps); |
---|
261 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 268 | + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); |
---|
| 269 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
262 | 270 | unsigned long flags; |
---|
263 | | - u32 bit, mask; |
---|
| 271 | + u32 bit, mask = 0; |
---|
264 | 272 | |
---|
265 | 273 | switch (rq->type) { |
---|
266 | 274 | case PTP_CLK_REQ_EXTTS: |
---|
.. | .. |
---|
274 | 282 | default: |
---|
275 | 283 | return -EINVAL; |
---|
276 | 284 | } |
---|
277 | | - spin_lock_irqsave(&qoriq_ptp->lock, flags); |
---|
278 | | - mask = qoriq_read(®s->ctrl_regs->tmr_temask); |
---|
279 | | - if (on) |
---|
280 | | - mask |= bit; |
---|
281 | | - else |
---|
282 | | - mask &= ~bit; |
---|
283 | | - qoriq_write(®s->ctrl_regs->tmr_temask, mask); |
---|
284 | | - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); |
---|
285 | | - return 0; |
---|
286 | 285 | |
---|
287 | | - case PTP_CLK_REQ_PPS: |
---|
288 | | - spin_lock_irqsave(&qoriq_ptp->lock, flags); |
---|
289 | | - mask = qoriq_read(®s->ctrl_regs->tmr_temask); |
---|
290 | 286 | if (on) |
---|
291 | | - mask |= PP1EN; |
---|
292 | | - else |
---|
293 | | - mask &= ~PP1EN; |
---|
294 | | - qoriq_write(®s->ctrl_regs->tmr_temask, mask); |
---|
295 | | - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); |
---|
296 | | - return 0; |
---|
| 287 | + extts_clean_up(ptp_qoriq, rq->extts.index, false); |
---|
297 | 288 | |
---|
298 | | - default: |
---|
299 | 289 | break; |
---|
| 290 | + case PTP_CLK_REQ_PPS: |
---|
| 291 | + bit = PP1EN; |
---|
| 292 | + break; |
---|
| 293 | + default: |
---|
| 294 | + return -EOPNOTSUPP; |
---|
300 | 295 | } |
---|
301 | 296 | |
---|
302 | | - return -EOPNOTSUPP; |
---|
| 297 | + spin_lock_irqsave(&ptp_qoriq->lock, flags); |
---|
| 298 | + |
---|
| 299 | + mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask); |
---|
| 300 | + if (on) { |
---|
| 301 | + mask |= bit; |
---|
| 302 | + ptp_qoriq->write(®s->ctrl_regs->tmr_tevent, bit); |
---|
| 303 | + } else { |
---|
| 304 | + mask &= ~bit; |
---|
| 305 | + } |
---|
| 306 | + |
---|
| 307 | + ptp_qoriq->write(®s->ctrl_regs->tmr_temask, mask); |
---|
| 308 | + |
---|
| 309 | + spin_unlock_irqrestore(&ptp_qoriq->lock, flags); |
---|
| 310 | + return 0; |
---|
303 | 311 | } |
---|
| 312 | +EXPORT_SYMBOL_GPL(ptp_qoriq_enable); |
---|
304 | 313 | |
---|
305 | 314 | static const struct ptp_clock_info ptp_qoriq_caps = { |
---|
306 | 315 | .owner = THIS_MODULE, |
---|
.. | .. |
---|
319 | 328 | }; |
---|
320 | 329 | |
---|
321 | 330 | /** |
---|
322 | | - * qoriq_ptp_nominal_freq - calculate nominal frequency according to |
---|
| 331 | + * ptp_qoriq_nominal_freq - calculate nominal frequency according to |
---|
323 | 332 | * reference clock frequency |
---|
324 | 333 | * |
---|
325 | 334 | * @clk_src: reference clock frequency |
---|
.. | .. |
---|
330 | 339 | * |
---|
331 | 340 | * Return the nominal frequency |
---|
332 | 341 | */ |
---|
333 | | -static u32 qoriq_ptp_nominal_freq(u32 clk_src) |
---|
| 342 | +static u32 ptp_qoriq_nominal_freq(u32 clk_src) |
---|
334 | 343 | { |
---|
335 | 344 | u32 remainder = 0; |
---|
336 | 345 | |
---|
.. | .. |
---|
350 | 359 | } |
---|
351 | 360 | |
---|
352 | 361 | /** |
---|
353 | | - * qoriq_ptp_auto_config - calculate a set of default configurations |
---|
| 362 | + * ptp_qoriq_auto_config - calculate a set of default configurations |
---|
354 | 363 | * |
---|
355 | | - * @qoriq_ptp: pointer to qoriq_ptp |
---|
| 364 | + * @ptp_qoriq: pointer to ptp_qoriq |
---|
356 | 365 | * @node: pointer to device_node |
---|
357 | 366 | * |
---|
358 | 367 | * If below dts properties are not provided, this function will be |
---|
.. | .. |
---|
362 | 371 | * "fsl,tmr-add" |
---|
363 | 372 | * "fsl,tmr-fiper1" |
---|
364 | 373 | * "fsl,tmr-fiper2" |
---|
| 374 | + * "fsl,tmr-fiper3" (required only for DPAA2 and ENETC hardware) |
---|
365 | 375 | * "fsl,max-adj" |
---|
366 | 376 | * |
---|
367 | 377 | * Return 0 if success |
---|
368 | 378 | */ |
---|
369 | | -static int qoriq_ptp_auto_config(struct qoriq_ptp *qoriq_ptp, |
---|
| 379 | +static int ptp_qoriq_auto_config(struct ptp_qoriq *ptp_qoriq, |
---|
370 | 380 | struct device_node *node) |
---|
371 | 381 | { |
---|
372 | 382 | struct clk *clk; |
---|
.. | .. |
---|
376 | 386 | u32 remainder = 0; |
---|
377 | 387 | u32 clk_src = 0; |
---|
378 | 388 | |
---|
379 | | - qoriq_ptp->cksel = DEFAULT_CKSEL; |
---|
| 389 | + ptp_qoriq->cksel = DEFAULT_CKSEL; |
---|
380 | 390 | |
---|
381 | 391 | clk = of_clk_get(node, 0); |
---|
382 | 392 | if (!IS_ERR(clk)) { |
---|
.. | .. |
---|
389 | 399 | return -EINVAL; |
---|
390 | 400 | } |
---|
391 | 401 | |
---|
392 | | - nominal_freq = qoriq_ptp_nominal_freq(clk_src); |
---|
| 402 | + nominal_freq = ptp_qoriq_nominal_freq(clk_src); |
---|
393 | 403 | if (!nominal_freq) |
---|
394 | 404 | return -EINVAL; |
---|
395 | 405 | |
---|
396 | | - qoriq_ptp->tclk_period = 1000000000UL / nominal_freq; |
---|
397 | | - qoriq_ptp->tmr_prsc = DEFAULT_TMR_PRSC; |
---|
| 406 | + ptp_qoriq->tclk_period = 1000000000UL / nominal_freq; |
---|
| 407 | + ptp_qoriq->tmr_prsc = DEFAULT_TMR_PRSC; |
---|
398 | 408 | |
---|
399 | 409 | /* Calculate initial frequency compensation value for TMR_ADD register. |
---|
400 | 410 | * freq_comp = ceil(2^32 / freq_ratio) |
---|
.. | .. |
---|
405 | 415 | if (remainder) |
---|
406 | 416 | freq_comp++; |
---|
407 | 417 | |
---|
408 | | - qoriq_ptp->tmr_add = freq_comp; |
---|
409 | | - qoriq_ptp->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - qoriq_ptp->tclk_period; |
---|
410 | | - qoriq_ptp->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - qoriq_ptp->tclk_period; |
---|
| 418 | + ptp_qoriq->tmr_add = freq_comp; |
---|
| 419 | + ptp_qoriq->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - ptp_qoriq->tclk_period; |
---|
| 420 | + ptp_qoriq->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - ptp_qoriq->tclk_period; |
---|
| 421 | + ptp_qoriq->tmr_fiper3 = DEFAULT_FIPER3_PERIOD - ptp_qoriq->tclk_period; |
---|
411 | 422 | |
---|
412 | 423 | /* max_adj = 1000000000 * (freq_ratio - 1.0) - 1 |
---|
413 | 424 | * freq_ratio = reference_clock_freq / nominal_freq |
---|
414 | 425 | */ |
---|
415 | 426 | max_adj = 1000000000ULL * (clk_src - nominal_freq); |
---|
416 | 427 | max_adj = div_u64(max_adj, nominal_freq) - 1; |
---|
417 | | - qoriq_ptp->caps.max_adj = max_adj; |
---|
| 428 | + ptp_qoriq->caps.max_adj = max_adj; |
---|
418 | 429 | |
---|
419 | 430 | return 0; |
---|
420 | 431 | } |
---|
421 | 432 | |
---|
422 | | -static int qoriq_ptp_probe(struct platform_device *dev) |
---|
| 433 | +int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base, |
---|
| 434 | + const struct ptp_clock_info *caps) |
---|
423 | 435 | { |
---|
424 | | - struct device_node *node = dev->dev.of_node; |
---|
425 | | - struct qoriq_ptp *qoriq_ptp; |
---|
426 | | - struct qoriq_ptp_registers *regs; |
---|
| 436 | + struct device_node *node = ptp_qoriq->dev->of_node; |
---|
| 437 | + struct ptp_qoriq_registers *regs; |
---|
427 | 438 | struct timespec64 now; |
---|
428 | | - int err = -ENOMEM; |
---|
429 | | - u32 tmr_ctrl; |
---|
430 | 439 | unsigned long flags; |
---|
431 | | - void __iomem *base; |
---|
| 440 | + u32 tmr_ctrl; |
---|
432 | 441 | |
---|
433 | | - qoriq_ptp = kzalloc(sizeof(*qoriq_ptp), GFP_KERNEL); |
---|
434 | | - if (!qoriq_ptp) |
---|
435 | | - goto no_memory; |
---|
| 442 | + if (!node) |
---|
| 443 | + return -ENODEV; |
---|
436 | 444 | |
---|
437 | | - err = -EINVAL; |
---|
| 445 | + ptp_qoriq->base = base; |
---|
| 446 | + ptp_qoriq->caps = *caps; |
---|
438 | 447 | |
---|
439 | | - qoriq_ptp->caps = ptp_qoriq_caps; |
---|
| 448 | + if (of_property_read_u32(node, "fsl,cksel", &ptp_qoriq->cksel)) |
---|
| 449 | + ptp_qoriq->cksel = DEFAULT_CKSEL; |
---|
440 | 450 | |
---|
441 | | - if (of_property_read_u32(node, "fsl,cksel", &qoriq_ptp->cksel)) |
---|
442 | | - qoriq_ptp->cksel = DEFAULT_CKSEL; |
---|
| 451 | + if (of_property_read_bool(node, "fsl,extts-fifo")) |
---|
| 452 | + ptp_qoriq->extts_fifo_support = true; |
---|
| 453 | + else |
---|
| 454 | + ptp_qoriq->extts_fifo_support = false; |
---|
| 455 | + |
---|
| 456 | + if (of_device_is_compatible(node, "fsl,dpaa2-ptp") || |
---|
| 457 | + of_device_is_compatible(node, "fsl,enetc-ptp")) |
---|
| 458 | + ptp_qoriq->fiper3_support = true; |
---|
443 | 459 | |
---|
444 | 460 | if (of_property_read_u32(node, |
---|
445 | | - "fsl,tclk-period", &qoriq_ptp->tclk_period) || |
---|
| 461 | + "fsl,tclk-period", &ptp_qoriq->tclk_period) || |
---|
446 | 462 | of_property_read_u32(node, |
---|
447 | | - "fsl,tmr-prsc", &qoriq_ptp->tmr_prsc) || |
---|
| 463 | + "fsl,tmr-prsc", &ptp_qoriq->tmr_prsc) || |
---|
448 | 464 | of_property_read_u32(node, |
---|
449 | | - "fsl,tmr-add", &qoriq_ptp->tmr_add) || |
---|
| 465 | + "fsl,tmr-add", &ptp_qoriq->tmr_add) || |
---|
450 | 466 | of_property_read_u32(node, |
---|
451 | | - "fsl,tmr-fiper1", &qoriq_ptp->tmr_fiper1) || |
---|
| 467 | + "fsl,tmr-fiper1", &ptp_qoriq->tmr_fiper1) || |
---|
452 | 468 | of_property_read_u32(node, |
---|
453 | | - "fsl,tmr-fiper2", &qoriq_ptp->tmr_fiper2) || |
---|
| 469 | + "fsl,tmr-fiper2", &ptp_qoriq->tmr_fiper2) || |
---|
454 | 470 | of_property_read_u32(node, |
---|
455 | | - "fsl,max-adj", &qoriq_ptp->caps.max_adj)) { |
---|
| 471 | + "fsl,max-adj", &ptp_qoriq->caps.max_adj) || |
---|
| 472 | + (ptp_qoriq->fiper3_support && |
---|
| 473 | + of_property_read_u32(node, "fsl,tmr-fiper3", |
---|
| 474 | + &ptp_qoriq->tmr_fiper3))) { |
---|
456 | 475 | pr_warn("device tree node missing required elements, try automatic configuration\n"); |
---|
457 | 476 | |
---|
458 | | - if (qoriq_ptp_auto_config(qoriq_ptp, node)) |
---|
459 | | - goto no_config; |
---|
| 477 | + if (ptp_qoriq_auto_config(ptp_qoriq, node)) |
---|
| 478 | + return -ENODEV; |
---|
460 | 479 | } |
---|
| 480 | + |
---|
| 481 | + if (of_property_read_bool(node, "little-endian")) { |
---|
| 482 | + ptp_qoriq->read = qoriq_read_le; |
---|
| 483 | + ptp_qoriq->write = qoriq_write_le; |
---|
| 484 | + } else { |
---|
| 485 | + ptp_qoriq->read = qoriq_read_be; |
---|
| 486 | + ptp_qoriq->write = qoriq_write_be; |
---|
| 487 | + } |
---|
| 488 | + |
---|
| 489 | + /* The eTSEC uses differnt memory map with DPAA/ENETC */ |
---|
| 490 | + if (of_device_is_compatible(node, "fsl,etsec-ptp")) { |
---|
| 491 | + ptp_qoriq->regs.ctrl_regs = base + ETSEC_CTRL_REGS_OFFSET; |
---|
| 492 | + ptp_qoriq->regs.alarm_regs = base + ETSEC_ALARM_REGS_OFFSET; |
---|
| 493 | + ptp_qoriq->regs.fiper_regs = base + ETSEC_FIPER_REGS_OFFSET; |
---|
| 494 | + ptp_qoriq->regs.etts_regs = base + ETSEC_ETTS_REGS_OFFSET; |
---|
| 495 | + } else { |
---|
| 496 | + ptp_qoriq->regs.ctrl_regs = base + CTRL_REGS_OFFSET; |
---|
| 497 | + ptp_qoriq->regs.alarm_regs = base + ALARM_REGS_OFFSET; |
---|
| 498 | + ptp_qoriq->regs.fiper_regs = base + FIPER_REGS_OFFSET; |
---|
| 499 | + ptp_qoriq->regs.etts_regs = base + ETTS_REGS_OFFSET; |
---|
| 500 | + } |
---|
| 501 | + |
---|
| 502 | + spin_lock_init(&ptp_qoriq->lock); |
---|
| 503 | + |
---|
| 504 | + ktime_get_real_ts64(&now); |
---|
| 505 | + ptp_qoriq_settime(&ptp_qoriq->caps, &now); |
---|
| 506 | + |
---|
| 507 | + tmr_ctrl = |
---|
| 508 | + (ptp_qoriq->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT | |
---|
| 509 | + (ptp_qoriq->cksel & CKSEL_MASK) << CKSEL_SHIFT; |
---|
| 510 | + |
---|
| 511 | + spin_lock_irqsave(&ptp_qoriq->lock, flags); |
---|
| 512 | + |
---|
| 513 | + regs = &ptp_qoriq->regs; |
---|
| 514 | + ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, tmr_ctrl); |
---|
| 515 | + ptp_qoriq->write(®s->ctrl_regs->tmr_add, ptp_qoriq->tmr_add); |
---|
| 516 | + ptp_qoriq->write(®s->ctrl_regs->tmr_prsc, ptp_qoriq->tmr_prsc); |
---|
| 517 | + ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1); |
---|
| 518 | + ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2); |
---|
| 519 | + |
---|
| 520 | + if (ptp_qoriq->fiper3_support) |
---|
| 521 | + ptp_qoriq->write(®s->fiper_regs->tmr_fiper3, |
---|
| 522 | + ptp_qoriq->tmr_fiper3); |
---|
| 523 | + |
---|
| 524 | + set_alarm(ptp_qoriq); |
---|
| 525 | + ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, |
---|
| 526 | + tmr_ctrl|FIPERST|RTPE|TE|FRD); |
---|
| 527 | + |
---|
| 528 | + spin_unlock_irqrestore(&ptp_qoriq->lock, flags); |
---|
| 529 | + |
---|
| 530 | + ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, ptp_qoriq->dev); |
---|
| 531 | + if (IS_ERR(ptp_qoriq->clock)) |
---|
| 532 | + return PTR_ERR(ptp_qoriq->clock); |
---|
| 533 | + |
---|
| 534 | + ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock); |
---|
| 535 | + ptp_qoriq_create_debugfs(ptp_qoriq); |
---|
| 536 | + return 0; |
---|
| 537 | +} |
---|
| 538 | +EXPORT_SYMBOL_GPL(ptp_qoriq_init); |
---|
| 539 | + |
---|
| 540 | +void ptp_qoriq_free(struct ptp_qoriq *ptp_qoriq) |
---|
| 541 | +{ |
---|
| 542 | + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; |
---|
| 543 | + |
---|
| 544 | + ptp_qoriq->write(®s->ctrl_regs->tmr_temask, 0); |
---|
| 545 | + ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, 0); |
---|
| 546 | + |
---|
| 547 | + ptp_qoriq_remove_debugfs(ptp_qoriq); |
---|
| 548 | + ptp_clock_unregister(ptp_qoriq->clock); |
---|
| 549 | + iounmap(ptp_qoriq->base); |
---|
| 550 | + free_irq(ptp_qoriq->irq, ptp_qoriq); |
---|
| 551 | +} |
---|
| 552 | +EXPORT_SYMBOL_GPL(ptp_qoriq_free); |
---|
| 553 | + |
---|
| 554 | +static int ptp_qoriq_probe(struct platform_device *dev) |
---|
| 555 | +{ |
---|
| 556 | + struct ptp_qoriq *ptp_qoriq; |
---|
| 557 | + int err = -ENOMEM; |
---|
| 558 | + void __iomem *base; |
---|
| 559 | + |
---|
| 560 | + ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL); |
---|
| 561 | + if (!ptp_qoriq) |
---|
| 562 | + goto no_memory; |
---|
| 563 | + |
---|
| 564 | + ptp_qoriq->dev = &dev->dev; |
---|
461 | 565 | |
---|
462 | 566 | err = -ENODEV; |
---|
463 | 567 | |
---|
464 | | - qoriq_ptp->irq = platform_get_irq(dev, 0); |
---|
465 | | - |
---|
466 | | - if (qoriq_ptp->irq < 0) { |
---|
| 568 | + ptp_qoriq->irq = platform_get_irq(dev, 0); |
---|
| 569 | + if (ptp_qoriq->irq < 0) { |
---|
467 | 570 | pr_err("irq not in device tree\n"); |
---|
468 | 571 | goto no_node; |
---|
469 | 572 | } |
---|
470 | | - if (request_irq(qoriq_ptp->irq, isr, IRQF_SHARED, DRIVER, qoriq_ptp)) { |
---|
| 573 | + if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED, |
---|
| 574 | + DRIVER, ptp_qoriq)) { |
---|
471 | 575 | pr_err("request_irq failed\n"); |
---|
472 | 576 | goto no_node; |
---|
473 | 577 | } |
---|
474 | 578 | |
---|
475 | | - qoriq_ptp->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0); |
---|
476 | | - if (!qoriq_ptp->rsrc) { |
---|
| 579 | + ptp_qoriq->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0); |
---|
| 580 | + if (!ptp_qoriq->rsrc) { |
---|
477 | 581 | pr_err("no resource\n"); |
---|
478 | 582 | goto no_resource; |
---|
479 | 583 | } |
---|
480 | | - if (request_resource(&iomem_resource, qoriq_ptp->rsrc)) { |
---|
| 584 | + if (request_resource(&iomem_resource, ptp_qoriq->rsrc)) { |
---|
481 | 585 | pr_err("resource busy\n"); |
---|
482 | 586 | goto no_resource; |
---|
483 | 587 | } |
---|
484 | 588 | |
---|
485 | | - spin_lock_init(&qoriq_ptp->lock); |
---|
486 | | - |
---|
487 | | - base = ioremap(qoriq_ptp->rsrc->start, |
---|
488 | | - resource_size(qoriq_ptp->rsrc)); |
---|
| 589 | + base = ioremap(ptp_qoriq->rsrc->start, |
---|
| 590 | + resource_size(ptp_qoriq->rsrc)); |
---|
489 | 591 | if (!base) { |
---|
490 | 592 | pr_err("ioremap ptp registers failed\n"); |
---|
491 | 593 | goto no_ioremap; |
---|
492 | 594 | } |
---|
493 | 595 | |
---|
494 | | - qoriq_ptp->base = base; |
---|
495 | | - |
---|
496 | | - if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) { |
---|
497 | | - qoriq_ptp->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET; |
---|
498 | | - qoriq_ptp->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET; |
---|
499 | | - qoriq_ptp->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET; |
---|
500 | | - qoriq_ptp->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET; |
---|
501 | | - } else { |
---|
502 | | - qoriq_ptp->regs.ctrl_regs = base + CTRL_REGS_OFFSET; |
---|
503 | | - qoriq_ptp->regs.alarm_regs = base + ALARM_REGS_OFFSET; |
---|
504 | | - qoriq_ptp->regs.fiper_regs = base + FIPER_REGS_OFFSET; |
---|
505 | | - qoriq_ptp->regs.etts_regs = base + ETTS_REGS_OFFSET; |
---|
506 | | - } |
---|
507 | | - |
---|
508 | | - ktime_get_real_ts64(&now); |
---|
509 | | - ptp_qoriq_settime(&qoriq_ptp->caps, &now); |
---|
510 | | - |
---|
511 | | - tmr_ctrl = |
---|
512 | | - (qoriq_ptp->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT | |
---|
513 | | - (qoriq_ptp->cksel & CKSEL_MASK) << CKSEL_SHIFT; |
---|
514 | | - |
---|
515 | | - spin_lock_irqsave(&qoriq_ptp->lock, flags); |
---|
516 | | - |
---|
517 | | - regs = &qoriq_ptp->regs; |
---|
518 | | - qoriq_write(®s->ctrl_regs->tmr_ctrl, tmr_ctrl); |
---|
519 | | - qoriq_write(®s->ctrl_regs->tmr_add, qoriq_ptp->tmr_add); |
---|
520 | | - qoriq_write(®s->ctrl_regs->tmr_prsc, qoriq_ptp->tmr_prsc); |
---|
521 | | - qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1); |
---|
522 | | - qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2); |
---|
523 | | - set_alarm(qoriq_ptp); |
---|
524 | | - qoriq_write(®s->ctrl_regs->tmr_ctrl, tmr_ctrl|FIPERST|RTPE|TE|FRD); |
---|
525 | | - |
---|
526 | | - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); |
---|
527 | | - |
---|
528 | | - qoriq_ptp->clock = ptp_clock_register(&qoriq_ptp->caps, &dev->dev); |
---|
529 | | - if (IS_ERR(qoriq_ptp->clock)) { |
---|
530 | | - err = PTR_ERR(qoriq_ptp->clock); |
---|
| 596 | + err = ptp_qoriq_init(ptp_qoriq, base, &ptp_qoriq_caps); |
---|
| 597 | + if (err) |
---|
531 | 598 | goto no_clock; |
---|
532 | | - } |
---|
533 | | - qoriq_ptp->phc_index = ptp_clock_index(qoriq_ptp->clock); |
---|
534 | 599 | |
---|
535 | | - platform_set_drvdata(dev, qoriq_ptp); |
---|
536 | | - |
---|
| 600 | + platform_set_drvdata(dev, ptp_qoriq); |
---|
537 | 601 | return 0; |
---|
538 | 602 | |
---|
539 | 603 | no_clock: |
---|
540 | | - iounmap(qoriq_ptp->base); |
---|
| 604 | + iounmap(base); |
---|
541 | 605 | no_ioremap: |
---|
542 | | - release_resource(qoriq_ptp->rsrc); |
---|
| 606 | + release_resource(ptp_qoriq->rsrc); |
---|
543 | 607 | no_resource: |
---|
544 | | - free_irq(qoriq_ptp->irq, qoriq_ptp); |
---|
545 | | -no_config: |
---|
| 608 | + free_irq(ptp_qoriq->irq, ptp_qoriq); |
---|
546 | 609 | no_node: |
---|
547 | | - kfree(qoriq_ptp); |
---|
| 610 | + kfree(ptp_qoriq); |
---|
548 | 611 | no_memory: |
---|
549 | 612 | return err; |
---|
550 | 613 | } |
---|
551 | 614 | |
---|
552 | | -static int qoriq_ptp_remove(struct platform_device *dev) |
---|
| 615 | +static int ptp_qoriq_remove(struct platform_device *dev) |
---|
553 | 616 | { |
---|
554 | | - struct qoriq_ptp *qoriq_ptp = platform_get_drvdata(dev); |
---|
555 | | - struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; |
---|
| 617 | + struct ptp_qoriq *ptp_qoriq = platform_get_drvdata(dev); |
---|
556 | 618 | |
---|
557 | | - qoriq_write(®s->ctrl_regs->tmr_temask, 0); |
---|
558 | | - qoriq_write(®s->ctrl_regs->tmr_ctrl, 0); |
---|
559 | | - |
---|
560 | | - ptp_clock_unregister(qoriq_ptp->clock); |
---|
561 | | - iounmap(qoriq_ptp->base); |
---|
562 | | - release_resource(qoriq_ptp->rsrc); |
---|
563 | | - free_irq(qoriq_ptp->irq, qoriq_ptp); |
---|
564 | | - kfree(qoriq_ptp); |
---|
565 | | - |
---|
| 619 | + ptp_qoriq_free(ptp_qoriq); |
---|
| 620 | + release_resource(ptp_qoriq->rsrc); |
---|
| 621 | + kfree(ptp_qoriq); |
---|
566 | 622 | return 0; |
---|
567 | 623 | } |
---|
568 | 624 | |
---|
.. | .. |
---|
573 | 629 | }; |
---|
574 | 630 | MODULE_DEVICE_TABLE(of, match_table); |
---|
575 | 631 | |
---|
576 | | -static struct platform_driver qoriq_ptp_driver = { |
---|
| 632 | +static struct platform_driver ptp_qoriq_driver = { |
---|
577 | 633 | .driver = { |
---|
578 | 634 | .name = "ptp_qoriq", |
---|
579 | 635 | .of_match_table = match_table, |
---|
580 | 636 | }, |
---|
581 | | - .probe = qoriq_ptp_probe, |
---|
582 | | - .remove = qoriq_ptp_remove, |
---|
| 637 | + .probe = ptp_qoriq_probe, |
---|
| 638 | + .remove = ptp_qoriq_remove, |
---|
583 | 639 | }; |
---|
584 | 640 | |
---|
585 | | -module_platform_driver(qoriq_ptp_driver); |
---|
| 641 | +module_platform_driver(ptp_qoriq_driver); |
---|
586 | 642 | |
---|
587 | 643 | MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>"); |
---|
588 | 644 | MODULE_DESCRIPTION("PTP clock for Freescale QorIQ 1588 timer"); |
---|