~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/gianfar_ptp.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * PTP 1588 clock using the eTSEC
 
3
 *
 
4
 * 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
 */
 
20
#include <linux/device.h>
 
21
#include <linux/hrtimer.h>
 
22
#include <linux/init.h>
 
23
#include <linux/interrupt.h>
 
24
#include <linux/kernel.h>
 
25
#include <linux/module.h>
 
26
#include <linux/of.h>
 
27
#include <linux/of_platform.h>
 
28
#include <linux/timex.h>
 
29
#include <linux/io.h>
 
30
 
 
31
#include <linux/ptp_clock_kernel.h>
 
32
 
 
33
#include "gianfar.h"
 
34
 
 
35
/*
 
36
 * gianfar ptp registers
 
37
 * Generated by regen.tcl on Thu May 13 01:38:57 PM CEST 2010
 
38
 */
 
39
struct gianfar_ptp_registers {
 
40
        u32 tmr_ctrl;     /* Timer control register */
 
41
        u32 tmr_tevent;   /* Timestamp event register */
 
42
        u32 tmr_temask;   /* Timer event mask register */
 
43
        u32 tmr_pevent;   /* Timestamp event register */
 
44
        u32 tmr_pemask;   /* Timer event mask register */
 
45
        u32 tmr_stat;     /* Timestamp status register */
 
46
        u32 tmr_cnt_h;    /* Timer counter high register */
 
47
        u32 tmr_cnt_l;    /* Timer counter low register */
 
48
        u32 tmr_add;      /* Timer drift compensation addend register */
 
49
        u32 tmr_acc;      /* Timer accumulator register */
 
50
        u32 tmr_prsc;     /* Timer prescale */
 
51
        u8  res1[4];
 
52
        u32 tmroff_h;     /* Timer offset high */
 
53
        u32 tmroff_l;     /* Timer offset low */
 
54
        u8  res2[8];
 
55
        u32 tmr_alarm1_h; /* Timer alarm 1 high register */
 
56
        u32 tmr_alarm1_l; /* Timer alarm 1 high register */
 
57
        u32 tmr_alarm2_h; /* Timer alarm 2 high register */
 
58
        u32 tmr_alarm2_l; /* Timer alarm 2 high register */
 
59
        u8  res3[48];
 
60
        u32 tmr_fiper1;   /* Timer fixed period interval */
 
61
        u32 tmr_fiper2;   /* Timer fixed period interval */
 
62
        u32 tmr_fiper3;   /* Timer fixed period interval */
 
63
        u8  res4[20];
 
64
        u32 tmr_etts1_h;  /* Timestamp of general purpose external trigger */
 
65
        u32 tmr_etts1_l;  /* Timestamp of general purpose external trigger */
 
66
        u32 tmr_etts2_h;  /* Timestamp of general purpose external trigger */
 
67
        u32 tmr_etts2_l;  /* Timestamp of general purpose external trigger */
 
68
};
 
69
 
 
70
/* Bit definitions for the TMR_CTRL register */
 
71
#define ALM1P                 (1<<31) /* Alarm1 output polarity */
 
72
#define ALM2P                 (1<<30) /* Alarm2 output polarity */
 
73
#define FS                    (1<<28) /* FIPER start indication */
 
74
#define PP1L                  (1<<27) /* Fiper1 pulse loopback mode enabled. */
 
75
#define PP2L                  (1<<26) /* Fiper2 pulse loopback mode enabled. */
 
76
#define TCLK_PERIOD_SHIFT     (16) /* 1588 timer reference clock period. */
 
77
#define TCLK_PERIOD_MASK      (0x3ff)
 
78
#define RTPE                  (1<<15) /* Record Tx Timestamp to PAL Enable. */
 
79
#define FRD                   (1<<14) /* FIPER Realignment Disable */
 
80
#define ESFDP                 (1<<11) /* External Tx/Rx SFD Polarity. */
 
81
#define ESFDE                 (1<<10) /* External Tx/Rx SFD Enable. */
 
82
#define ETEP2                 (1<<9) /* External trigger 2 edge polarity */
 
83
#define ETEP1                 (1<<8) /* External trigger 1 edge polarity */
 
84
#define COPH                  (1<<7) /* Generated clock output phase. */
 
85
#define CIPH                  (1<<6) /* External oscillator input clock phase */
 
86
#define TMSR                  (1<<5) /* Timer soft reset. */
 
87
#define BYP                   (1<<3) /* Bypass drift compensated clock */
 
88
#define TE                    (1<<2) /* 1588 timer enable. */
 
89
#define CKSEL_SHIFT           (0)    /* 1588 Timer reference clock source */
 
90
#define CKSEL_MASK            (0x3)
 
91
 
 
92
/* Bit definitions for the TMR_TEVENT register */
 
93
#define ETS2                  (1<<25) /* External trigger 2 timestamp sampled */
 
94
#define ETS1                  (1<<24) /* External trigger 1 timestamp sampled */
 
95
#define ALM2                  (1<<17) /* Current time = alarm time register 2 */
 
96
#define ALM1                  (1<<16) /* Current time = alarm time register 1 */
 
97
#define PP1                   (1<<7)  /* periodic pulse generated on FIPER1 */
 
98
#define PP2                   (1<<6)  /* periodic pulse generated on FIPER2 */
 
99
#define PP3                   (1<<5)  /* periodic pulse generated on FIPER3 */
 
100
 
 
101
/* Bit definitions for the TMR_TEMASK register */
 
102
#define ETS2EN                (1<<25) /* External trigger 2 timestamp enable */
 
103
#define ETS1EN                (1<<24) /* External trigger 1 timestamp enable */
 
104
#define ALM2EN                (1<<17) /* Timer ALM2 event enable */
 
105
#define ALM1EN                (1<<16) /* Timer ALM1 event enable */
 
106
#define PP1EN                 (1<<7) /* Periodic pulse event 1 enable */
 
107
#define PP2EN                 (1<<6) /* Periodic pulse event 2 enable */
 
108
 
 
109
/* Bit definitions for the TMR_PEVENT register */
 
110
#define TXP2                  (1<<9) /* PTP transmitted timestamp im TXTS2 */
 
111
#define TXP1                  (1<<8) /* PTP transmitted timestamp in TXTS1 */
 
112
#define RXP                   (1<<0) /* PTP frame has been received */
 
113
 
 
114
/* Bit definitions for the TMR_PEMASK register */
 
115
#define TXP2EN                (1<<9) /* Transmit PTP packet event 2 enable */
 
116
#define TXP1EN                (1<<8) /* Transmit PTP packet event 1 enable */
 
117
#define RXPEN                 (1<<0) /* Receive PTP packet event enable */
 
118
 
 
119
/* Bit definitions for the TMR_STAT register */
 
120
#define STAT_VEC_SHIFT        (0) /* Timer general purpose status vector */
 
121
#define STAT_VEC_MASK         (0x3f)
 
122
 
 
123
/* Bit definitions for the TMR_PRSC register */
 
124
#define PRSC_OCK_SHIFT        (0) /* Output clock division/prescale factor. */
 
125
#define PRSC_OCK_MASK         (0xffff)
 
126
 
 
127
 
 
128
#define DRIVER          "gianfar_ptp"
 
129
#define DEFAULT_CKSEL   1
 
130
#define N_ALARM         1 /* first alarm is used internally to reset fipers */
 
131
#define N_EXT_TS        2
 
132
#define REG_SIZE        sizeof(struct gianfar_ptp_registers)
 
133
 
 
134
struct etsects {
 
135
        struct gianfar_ptp_registers *regs;
 
136
        spinlock_t lock; /* protects regs */
 
137
        struct ptp_clock *clock;
 
138
        struct ptp_clock_info caps;
 
139
        struct resource *rsrc;
 
140
        int irq;
 
141
        u64 alarm_interval; /* for periodic alarm */
 
142
        u64 alarm_value;
 
143
        u32 tclk_period;  /* nanoseconds */
 
144
        u32 tmr_prsc;
 
145
        u32 tmr_add;
 
146
        u32 cksel;
 
147
        u32 tmr_fiper1;
 
148
        u32 tmr_fiper2;
 
149
};
 
150
 
 
151
/*
 
152
 * Register access functions
 
153
 */
 
154
 
 
155
/* Caller must hold etsects->lock. */
 
156
static u64 tmr_cnt_read(struct etsects *etsects)
 
157
{
 
158
        u64 ns;
 
159
        u32 lo, hi;
 
160
 
 
161
        lo = gfar_read(&etsects->regs->tmr_cnt_l);
 
162
        hi = gfar_read(&etsects->regs->tmr_cnt_h);
 
163
        ns = ((u64) hi) << 32;
 
164
        ns |= lo;
 
165
        return ns;
 
166
}
 
167
 
 
168
/* Caller must hold etsects->lock. */
 
169
static void tmr_cnt_write(struct etsects *etsects, u64 ns)
 
170
{
 
171
        u32 hi = ns >> 32;
 
172
        u32 lo = ns & 0xffffffff;
 
173
 
 
174
        gfar_write(&etsects->regs->tmr_cnt_l, lo);
 
175
        gfar_write(&etsects->regs->tmr_cnt_h, hi);
 
176
}
 
177
 
 
178
/* Caller must hold etsects->lock. */
 
179
static void set_alarm(struct etsects *etsects)
 
180
{
 
181
        u64 ns;
 
182
        u32 lo, hi;
 
183
 
 
184
        ns = tmr_cnt_read(etsects) + 1500000000ULL;
 
185
        ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
 
186
        ns -= etsects->tclk_period;
 
187
        hi = ns >> 32;
 
188
        lo = ns & 0xffffffff;
 
189
        gfar_write(&etsects->regs->tmr_alarm1_l, lo);
 
190
        gfar_write(&etsects->regs->tmr_alarm1_h, hi);
 
191
}
 
192
 
 
193
/* Caller must hold etsects->lock. */
 
194
static void set_fipers(struct etsects *etsects)
 
195
{
 
196
        u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl);
 
197
 
 
198
        gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl & (~TE));
 
199
        gfar_write(&etsects->regs->tmr_prsc,   etsects->tmr_prsc);
 
200
        gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);
 
201
        gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);
 
202
        set_alarm(etsects);
 
203
        gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|TE);
 
204
}
 
205
 
 
206
/*
 
207
 * Interrupt service routine
 
208
 */
 
209
 
 
210
static irqreturn_t isr(int irq, void *priv)
 
211
{
 
212
        struct etsects *etsects = priv;
 
213
        struct ptp_clock_event event;
 
214
        u64 ns;
 
215
        u32 ack = 0, lo, hi, mask, val;
 
216
 
 
217
        val = gfar_read(&etsects->regs->tmr_tevent);
 
218
 
 
219
        if (val & ETS1) {
 
220
                ack |= ETS1;
 
221
                hi = gfar_read(&etsects->regs->tmr_etts1_h);
 
222
                lo = gfar_read(&etsects->regs->tmr_etts1_l);
 
223
                event.type = PTP_CLOCK_EXTTS;
 
224
                event.index = 0;
 
225
                event.timestamp = ((u64) hi) << 32;
 
226
                event.timestamp |= lo;
 
227
                ptp_clock_event(etsects->clock, &event);
 
228
        }
 
229
 
 
230
        if (val & ETS2) {
 
231
                ack |= ETS2;
 
232
                hi = gfar_read(&etsects->regs->tmr_etts2_h);
 
233
                lo = gfar_read(&etsects->regs->tmr_etts2_l);
 
234
                event.type = PTP_CLOCK_EXTTS;
 
235
                event.index = 1;
 
236
                event.timestamp = ((u64) hi) << 32;
 
237
                event.timestamp |= lo;
 
238
                ptp_clock_event(etsects->clock, &event);
 
239
        }
 
240
 
 
241
        if (val & ALM2) {
 
242
                ack |= ALM2;
 
243
                if (etsects->alarm_value) {
 
244
                        event.type = PTP_CLOCK_ALARM;
 
245
                        event.index = 0;
 
246
                        event.timestamp = etsects->alarm_value;
 
247
                        ptp_clock_event(etsects->clock, &event);
 
248
                }
 
249
                if (etsects->alarm_interval) {
 
250
                        ns = etsects->alarm_value + etsects->alarm_interval;
 
251
                        hi = ns >> 32;
 
252
                        lo = ns & 0xffffffff;
 
253
                        spin_lock(&etsects->lock);
 
254
                        gfar_write(&etsects->regs->tmr_alarm2_l, lo);
 
255
                        gfar_write(&etsects->regs->tmr_alarm2_h, hi);
 
256
                        spin_unlock(&etsects->lock);
 
257
                        etsects->alarm_value = ns;
 
258
                } else {
 
259
                        gfar_write(&etsects->regs->tmr_tevent, ALM2);
 
260
                        spin_lock(&etsects->lock);
 
261
                        mask = gfar_read(&etsects->regs->tmr_temask);
 
262
                        mask &= ~ALM2EN;
 
263
                        gfar_write(&etsects->regs->tmr_temask, mask);
 
264
                        spin_unlock(&etsects->lock);
 
265
                        etsects->alarm_value = 0;
 
266
                        etsects->alarm_interval = 0;
 
267
                }
 
268
        }
 
269
 
 
270
        if (val & PP1) {
 
271
                ack |= PP1;
 
272
                event.type = PTP_CLOCK_PPS;
 
273
                ptp_clock_event(etsects->clock, &event);
 
274
        }
 
275
 
 
276
        if (ack) {
 
277
                gfar_write(&etsects->regs->tmr_tevent, ack);
 
278
                return IRQ_HANDLED;
 
279
        } else
 
280
                return IRQ_NONE;
 
281
}
 
282
 
 
283
/*
 
284
 * PTP clock operations
 
285
 */
 
286
 
 
287
static int ptp_gianfar_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
 
288
{
 
289
        u64 adj;
 
290
        u32 diff, tmr_add;
 
291
        int neg_adj = 0;
 
292
        struct etsects *etsects = container_of(ptp, struct etsects, caps);
 
293
 
 
294
        if (ppb < 0) {
 
295
                neg_adj = 1;
 
296
                ppb = -ppb;
 
297
        }
 
298
        tmr_add = etsects->tmr_add;
 
299
        adj = tmr_add;
 
300
        adj *= ppb;
 
301
        diff = div_u64(adj, 1000000000ULL);
 
302
 
 
303
        tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
 
304
 
 
305
        gfar_write(&etsects->regs->tmr_add, tmr_add);
 
306
 
 
307
        return 0;
 
308
}
 
309
 
 
310
static int ptp_gianfar_adjtime(struct ptp_clock_info *ptp, s64 delta)
 
311
{
 
312
        s64 now;
 
313
        unsigned long flags;
 
314
        struct etsects *etsects = container_of(ptp, struct etsects, caps);
 
315
 
 
316
        spin_lock_irqsave(&etsects->lock, flags);
 
317
 
 
318
        now = tmr_cnt_read(etsects);
 
319
        now += delta;
 
320
        tmr_cnt_write(etsects, now);
 
321
 
 
322
        spin_unlock_irqrestore(&etsects->lock, flags);
 
323
 
 
324
        set_fipers(etsects);
 
325
 
 
326
        return 0;
 
327
}
 
328
 
 
329
static int ptp_gianfar_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
 
330
{
 
331
        u64 ns;
 
332
        u32 remainder;
 
333
        unsigned long flags;
 
334
        struct etsects *etsects = container_of(ptp, struct etsects, caps);
 
335
 
 
336
        spin_lock_irqsave(&etsects->lock, flags);
 
337
 
 
338
        ns = tmr_cnt_read(etsects);
 
339
 
 
340
        spin_unlock_irqrestore(&etsects->lock, flags);
 
341
 
 
342
        ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
 
343
        ts->tv_nsec = remainder;
 
344
        return 0;
 
345
}
 
346
 
 
347
static int ptp_gianfar_settime(struct ptp_clock_info *ptp,
 
348
                               const struct timespec *ts)
 
349
{
 
350
        u64 ns;
 
351
        unsigned long flags;
 
352
        struct etsects *etsects = container_of(ptp, struct etsects, caps);
 
353
 
 
354
        ns = ts->tv_sec * 1000000000ULL;
 
355
        ns += ts->tv_nsec;
 
356
 
 
357
        spin_lock_irqsave(&etsects->lock, flags);
 
358
 
 
359
        tmr_cnt_write(etsects, ns);
 
360
        set_fipers(etsects);
 
361
 
 
362
        spin_unlock_irqrestore(&etsects->lock, flags);
 
363
 
 
364
        return 0;
 
365
}
 
366
 
 
367
static int ptp_gianfar_enable(struct ptp_clock_info *ptp,
 
368
                              struct ptp_clock_request *rq, int on)
 
369
{
 
370
        struct etsects *etsects = container_of(ptp, struct etsects, caps);
 
371
        unsigned long flags;
 
372
        u32 bit, mask;
 
373
 
 
374
        switch (rq->type) {
 
375
        case PTP_CLK_REQ_EXTTS:
 
376
                switch (rq->extts.index) {
 
377
                case 0:
 
378
                        bit = ETS1EN;
 
379
                        break;
 
380
                case 1:
 
381
                        bit = ETS2EN;
 
382
                        break;
 
383
                default:
 
384
                        return -EINVAL;
 
385
                }
 
386
                spin_lock_irqsave(&etsects->lock, flags);
 
387
                mask = gfar_read(&etsects->regs->tmr_temask);
 
388
                if (on)
 
389
                        mask |= bit;
 
390
                else
 
391
                        mask &= ~bit;
 
392
                gfar_write(&etsects->regs->tmr_temask, mask);
 
393
                spin_unlock_irqrestore(&etsects->lock, flags);
 
394
                return 0;
 
395
 
 
396
        case PTP_CLK_REQ_PPS:
 
397
                spin_lock_irqsave(&etsects->lock, flags);
 
398
                mask = gfar_read(&etsects->regs->tmr_temask);
 
399
                if (on)
 
400
                        mask |= PP1EN;
 
401
                else
 
402
                        mask &= ~PP1EN;
 
403
                gfar_write(&etsects->regs->tmr_temask, mask);
 
404
                spin_unlock_irqrestore(&etsects->lock, flags);
 
405
                return 0;
 
406
 
 
407
        default:
 
408
                break;
 
409
        }
 
410
 
 
411
        return -EOPNOTSUPP;
 
412
}
 
413
 
 
414
static struct ptp_clock_info ptp_gianfar_caps = {
 
415
        .owner          = THIS_MODULE,
 
416
        .name           = "gianfar clock",
 
417
        .max_adj        = 512000,
 
418
        .n_alarm        = N_ALARM,
 
419
        .n_ext_ts       = N_EXT_TS,
 
420
        .n_per_out      = 0,
 
421
        .pps            = 1,
 
422
        .adjfreq        = ptp_gianfar_adjfreq,
 
423
        .adjtime        = ptp_gianfar_adjtime,
 
424
        .gettime        = ptp_gianfar_gettime,
 
425
        .settime        = ptp_gianfar_settime,
 
426
        .enable         = ptp_gianfar_enable,
 
427
};
 
428
 
 
429
/* OF device tree */
 
430
 
 
431
static int get_of_u32(struct device_node *node, char *str, u32 *val)
 
432
{
 
433
        int plen;
 
434
        const u32 *prop = of_get_property(node, str, &plen);
 
435
 
 
436
        if (!prop || plen != sizeof(*prop))
 
437
                return -1;
 
438
        *val = *prop;
 
439
        return 0;
 
440
}
 
441
 
 
442
static int gianfar_ptp_probe(struct platform_device *dev)
 
443
{
 
444
        struct device_node *node = dev->dev.of_node;
 
445
        struct etsects *etsects;
 
446
        struct timespec now;
 
447
        int err = -ENOMEM;
 
448
        u32 tmr_ctrl;
 
449
        unsigned long flags;
 
450
 
 
451
        etsects = kzalloc(sizeof(*etsects), GFP_KERNEL);
 
452
        if (!etsects)
 
453
                goto no_memory;
 
454
 
 
455
        err = -ENODEV;
 
456
 
 
457
        etsects->caps = ptp_gianfar_caps;
 
458
        etsects->cksel = DEFAULT_CKSEL;
 
459
 
 
460
        if (get_of_u32(node, "fsl,tclk-period", &etsects->tclk_period) ||
 
461
            get_of_u32(node, "fsl,tmr-prsc", &etsects->tmr_prsc) ||
 
462
            get_of_u32(node, "fsl,tmr-add", &etsects->tmr_add) ||
 
463
            get_of_u32(node, "fsl,tmr-fiper1", &etsects->tmr_fiper1) ||
 
464
            get_of_u32(node, "fsl,tmr-fiper2", &etsects->tmr_fiper2) ||
 
465
            get_of_u32(node, "fsl,max-adj", &etsects->caps.max_adj)) {
 
466
                pr_err("device tree node missing required elements\n");
 
467
                goto no_node;
 
468
        }
 
469
 
 
470
        etsects->irq = platform_get_irq(dev, 0);
 
471
 
 
472
        if (etsects->irq == NO_IRQ) {
 
473
                pr_err("irq not in device tree\n");
 
474
                goto no_node;
 
475
        }
 
476
        if (request_irq(etsects->irq, isr, 0, DRIVER, etsects)) {
 
477
                pr_err("request_irq failed\n");
 
478
                goto no_node;
 
479
        }
 
480
 
 
481
        etsects->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
 
482
        if (!etsects->rsrc) {
 
483
                pr_err("no resource\n");
 
484
                goto no_resource;
 
485
        }
 
486
        if (request_resource(&ioport_resource, etsects->rsrc)) {
 
487
                pr_err("resource busy\n");
 
488
                goto no_resource;
 
489
        }
 
490
 
 
491
        spin_lock_init(&etsects->lock);
 
492
 
 
493
        etsects->regs = ioremap(etsects->rsrc->start,
 
494
                                1 + etsects->rsrc->end - etsects->rsrc->start);
 
495
        if (!etsects->regs) {
 
496
                pr_err("ioremap ptp registers failed\n");
 
497
                goto no_ioremap;
 
498
        }
 
499
        getnstimeofday(&now);
 
500
        ptp_gianfar_settime(&etsects->caps, &now);
 
501
 
 
502
        tmr_ctrl =
 
503
          (etsects->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
 
504
          (etsects->cksel & CKSEL_MASK) << CKSEL_SHIFT;
 
505
 
 
506
        spin_lock_irqsave(&etsects->lock, flags);
 
507
 
 
508
        gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl);
 
509
        gfar_write(&etsects->regs->tmr_add,    etsects->tmr_add);
 
510
        gfar_write(&etsects->regs->tmr_prsc,   etsects->tmr_prsc);
 
511
        gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);
 
512
        gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);
 
513
        set_alarm(etsects);
 
514
        gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|FS|RTPE|TE);
 
515
 
 
516
        spin_unlock_irqrestore(&etsects->lock, flags);
 
517
 
 
518
        etsects->clock = ptp_clock_register(&etsects->caps);
 
519
        if (IS_ERR(etsects->clock)) {
 
520
                err = PTR_ERR(etsects->clock);
 
521
                goto no_clock;
 
522
        }
 
523
 
 
524
        dev_set_drvdata(&dev->dev, etsects);
 
525
 
 
526
        return 0;
 
527
 
 
528
no_clock:
 
529
no_ioremap:
 
530
        release_resource(etsects->rsrc);
 
531
no_resource:
 
532
        free_irq(etsects->irq, etsects);
 
533
no_node:
 
534
        kfree(etsects);
 
535
no_memory:
 
536
        return err;
 
537
}
 
538
 
 
539
static int gianfar_ptp_remove(struct platform_device *dev)
 
540
{
 
541
        struct etsects *etsects = dev_get_drvdata(&dev->dev);
 
542
 
 
543
        gfar_write(&etsects->regs->tmr_temask, 0);
 
544
        gfar_write(&etsects->regs->tmr_ctrl,   0);
 
545
 
 
546
        ptp_clock_unregister(etsects->clock);
 
547
        iounmap(etsects->regs);
 
548
        release_resource(etsects->rsrc);
 
549
        free_irq(etsects->irq, etsects);
 
550
        kfree(etsects);
 
551
 
 
552
        return 0;
 
553
}
 
554
 
 
555
static struct of_device_id match_table[] = {
 
556
        { .compatible = "fsl,etsec-ptp" },
 
557
        {},
 
558
};
 
559
 
 
560
static struct platform_driver gianfar_ptp_driver = {
 
561
        .driver = {
 
562
                .name           = "gianfar_ptp",
 
563
                .of_match_table = match_table,
 
564
                .owner          = THIS_MODULE,
 
565
        },
 
566
        .probe       = gianfar_ptp_probe,
 
567
        .remove      = gianfar_ptp_remove,
 
568
};
 
569
 
 
570
/* module operations */
 
571
 
 
572
static int __init ptp_gianfar_init(void)
 
573
{
 
574
        return platform_driver_register(&gianfar_ptp_driver);
 
575
}
 
576
 
 
577
module_init(ptp_gianfar_init);
 
578
 
 
579
static void __exit ptp_gianfar_exit(void)
 
580
{
 
581
        platform_driver_unregister(&gianfar_ptp_driver);
 
582
}
 
583
 
 
584
module_exit(ptp_gianfar_exit);
 
585
 
 
586
MODULE_AUTHOR("Richard Cochran <richard.cochran@omicron.at>");
 
587
MODULE_DESCRIPTION("PTP clock using the eTSEC");
 
588
MODULE_LICENSE("GPL");