| .. | .. |
|---|
| 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"); |
|---|