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