1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2018 MOSER-BAER AG
6 #define pr_fmt(fmt) "InES_PTP: " fmt
8 #include <linux/ethtool.h>
9 #include <linux/export.h>
10 #include <linux/if_vlan.h>
11 #include <linux/mii_timestamper.h>
12 #include <linux/module.h>
13 #include <linux/net_tstamp.h>
15 #include <linux/of_address.h>
16 #include <linux/of_irq.h>
17 #include <linux/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/ptp_classify.h>
20 #include <linux/ptp_clock_kernel.h>
21 #include <linux/stddef.h>
23 MODULE_DESCRIPTION("Driver for the ZHAW InES PTP time stamping IP core");
24 MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
25 MODULE_VERSION("1.0");
26 MODULE_LICENSE("GPL");
29 #define MCAST_MAC_SELECT_SHIFT 2
30 #define MCAST_MAC_SELECT_MASK 0x3
31 #define IO_RESET BIT(1)
32 #define PTP_RESET BIT(0)
34 /* VERSION register */
35 #define IF_MAJOR_VER_SHIFT 12
36 #define IF_MAJOR_VER_MASK 0xf
37 #define IF_MINOR_VER_SHIFT 8
38 #define IF_MINOR_VER_MASK 0xf
39 #define FPGA_MAJOR_VER_SHIFT 4
40 #define FPGA_MAJOR_VER_MASK 0xf
41 #define FPGA_MINOR_VER_SHIFT 0
42 #define FPGA_MINOR_VER_MASK 0xf
44 /* INT_STAT register */
45 #define RX_INTR_STATUS_3 BIT(5)
46 #define RX_INTR_STATUS_2 BIT(4)
47 #define RX_INTR_STATUS_1 BIT(3)
48 #define TX_INTR_STATUS_3 BIT(2)
49 #define TX_INTR_STATUS_2 BIT(1)
50 #define TX_INTR_STATUS_1 BIT(0)
52 /* INT_MSK register */
53 #define RX_INTR_MASK_3 BIT(5)
54 #define RX_INTR_MASK_2 BIT(4)
55 #define RX_INTR_MASK_1 BIT(3)
56 #define TX_INTR_MASK_3 BIT(2)
57 #define TX_INTR_MASK_2 BIT(1)
58 #define TX_INTR_MASK_1 BIT(0)
60 /* BUF_STAT register */
61 #define RX_FIFO_NE_3 BIT(5)
62 #define RX_FIFO_NE_2 BIT(4)
63 #define RX_FIFO_NE_1 BIT(3)
64 #define TX_FIFO_NE_3 BIT(2)
65 #define TX_FIFO_NE_2 BIT(1)
66 #define TX_FIFO_NE_1 BIT(0)
68 /* PORT_CONF register */
69 #define CM_ONE_STEP BIT(6)
70 #define PHY_SPEED_SHIFT 4
71 #define PHY_SPEED_MASK 0x3
72 #define P2P_DELAY_WR_POS_SHIFT 2
73 #define P2P_DELAY_WR_POS_MASK 0x3
74 #define PTP_MODE_SHIFT 0
75 #define PTP_MODE_MASK 0x3
77 /* TS_STAT_TX register */
78 #define TS_ENABLE BIT(15)
79 #define DATA_READ_POS_SHIFT 8
80 #define DATA_READ_POS_MASK 0x1f
81 #define DISCARDED_EVENTS_SHIFT 4
82 #define DISCARDED_EVENTS_MASK 0xf
84 #define INES_N_PORTS 3
85 #define INES_REGISTER_SIZE 0x80
86 #define INES_PORT_OFFSET 0x20
87 #define INES_PORT_SIZE 0x20
88 #define INES_FIFO_DEPTH 90
89 #define INES_MAX_EVENTS 100
93 #define TC_E2E_PTP_V2 2
94 #define TC_P2P_PTP_V2 3
96 #define PHY_SPEED_10 0
97 #define PHY_SPEED_100 1
98 #define PHY_SPEED_1000 2
101 ((PHY_SPEED_1000 << PHY_SPEED_SHIFT) | (BC_PTP_V2 << PTP_MODE_SHIFT))
103 #define ines_read32(s, r) __raw_readl((void __iomem *)&s->regs->r)
104 #define ines_write32(s, v, r) __raw_writel(v, (void __iomem *)&s->regs->r)
106 #define MESSAGE_TYPE_SYNC 1
107 #define MESSAGE_TYPE_P_DELAY_REQ 2
108 #define MESSAGE_TYPE_P_DELAY_RESP 3
109 #define MESSAGE_TYPE_DELAY_REQ 4
111 static LIST_HEAD(ines_clocks
);
112 static DEFINE_MUTEX(ines_clocks_lock
);
114 struct ines_global_regs
{
125 struct ines_port_registers
{
134 struct ines_timestamp
{
135 struct list_head list
;
146 struct ines_port_registers
*regs
;
147 struct mii_timestamper mii_ts
;
148 struct ines_clock
*clock
;
152 struct delayed_work ts_work
;
153 /* lock protects event list and tx_skb */
155 struct sk_buff
*tx_skb
;
156 struct list_head events
;
157 struct list_head pool
;
158 struct ines_timestamp pool_data
[INES_MAX_EVENTS
];
162 struct ines_port port
[INES_N_PORTS
];
163 struct ines_global_regs __iomem
*regs
;
165 struct device_node
*node
;
167 struct list_head list
;
170 static bool ines_match(struct sk_buff
*skb
, unsigned int ptp_class
,
171 struct ines_timestamp
*ts
, struct device
*dev
);
172 static int ines_rxfifo_read(struct ines_port
*port
);
173 static u64
ines_rxts64(struct ines_port
*port
, unsigned int words
);
174 static bool ines_timestamp_expired(struct ines_timestamp
*ts
);
175 static u64
ines_txts64(struct ines_port
*port
, unsigned int words
);
176 static void ines_txtstamp_work(struct work_struct
*work
);
177 static bool is_sync_pdelay_resp(struct sk_buff
*skb
, int type
);
178 static u8
tag_to_msgtype(u8 tag
);
180 static void ines_clock_cleanup(struct ines_clock
*clock
)
182 struct ines_port
*port
;
185 for (i
= 0; i
< INES_N_PORTS
; i
++) {
186 port
= &clock
->port
[i
];
187 cancel_delayed_work_sync(&port
->ts_work
);
191 static int ines_clock_init(struct ines_clock
*clock
, struct device
*device
,
194 struct device_node
*node
= device
->of_node
;
195 unsigned long port_addr
;
196 struct ines_port
*port
;
199 INIT_LIST_HEAD(&clock
->list
);
203 clock
->regs
= clock
->base
;
205 for (i
= 0; i
< INES_N_PORTS
; i
++) {
206 port
= &clock
->port
[i
];
207 port_addr
= (unsigned long) clock
->base
+
208 INES_PORT_OFFSET
+ i
* INES_PORT_SIZE
;
209 port
->regs
= (struct ines_port_registers
*) port_addr
;
212 INIT_DELAYED_WORK(&port
->ts_work
, ines_txtstamp_work
);
213 spin_lock_init(&port
->lock
);
214 INIT_LIST_HEAD(&port
->events
);
215 INIT_LIST_HEAD(&port
->pool
);
216 for (j
= 0; j
< INES_MAX_EVENTS
; j
++)
217 list_add(&port
->pool_data
[j
].list
, &port
->pool
);
220 ines_write32(clock
, 0xBEEF, test
);
221 ines_write32(clock
, 0xBEEF, test2
);
223 dev_dbg(device
, "ID 0x%x\n", ines_read32(clock
, id
));
224 dev_dbg(device
, "TEST 0x%x\n", ines_read32(clock
, test
));
225 dev_dbg(device
, "VERSION 0x%x\n", ines_read32(clock
, version
));
226 dev_dbg(device
, "TEST2 0x%x\n", ines_read32(clock
, test2
));
228 for (i
= 0; i
< INES_N_PORTS
; i
++) {
229 port
= &clock
->port
[i
];
230 ines_write32(port
, PORT_CONF
, port_conf
);
236 static struct ines_port
*ines_find_port(struct device_node
*node
, u32 index
)
238 struct ines_port
*port
= NULL
;
239 struct ines_clock
*clock
;
240 struct list_head
*this;
242 mutex_lock(&ines_clocks_lock
);
243 list_for_each(this, &ines_clocks
) {
244 clock
= list_entry(this, struct ines_clock
, list
);
245 if (clock
->node
== node
) {
246 port
= &clock
->port
[index
];
250 mutex_unlock(&ines_clocks_lock
);
254 static u64
ines_find_rxts(struct ines_port
*port
, struct sk_buff
*skb
, int type
)
256 struct list_head
*this, *next
;
257 struct ines_timestamp
*ts
;
261 if (type
== PTP_CLASS_NONE
)
264 spin_lock_irqsave(&port
->lock
, flags
);
265 ines_rxfifo_read(port
);
266 list_for_each_safe(this, next
, &port
->events
) {
267 ts
= list_entry(this, struct ines_timestamp
, list
);
268 if (ines_timestamp_expired(ts
)) {
269 list_del_init(&ts
->list
);
270 list_add(&ts
->list
, &port
->pool
);
273 if (ines_match(skb
, type
, ts
, port
->clock
->dev
)) {
274 ns
= ts
->sec
* 1000000000ULL + ts
->nsec
;
275 list_del_init(&ts
->list
);
276 list_add(&ts
->list
, &port
->pool
);
280 spin_unlock_irqrestore(&port
->lock
, flags
);
285 static u64
ines_find_txts(struct ines_port
*port
, struct sk_buff
*skb
)
287 unsigned int class = ptp_classify_raw(skb
), i
;
288 u32 data_rd_pos
, buf_stat
, mask
, ts_stat_tx
;
289 struct ines_timestamp ts
;
293 mask
= TX_FIFO_NE_1
<< port
->index
;
295 spin_lock_irqsave(&port
->lock
, flags
);
297 for (i
= 0; i
< INES_FIFO_DEPTH
; i
++) {
299 buf_stat
= ines_read32(port
->clock
, buf_stat
);
300 if (!(buf_stat
& mask
)) {
301 dev_dbg(port
->clock
->dev
,
302 "Tx timestamp FIFO unexpectedly empty\n");
305 ts_stat_tx
= ines_read32(port
, ts_stat_tx
);
306 data_rd_pos
= (ts_stat_tx
>> DATA_READ_POS_SHIFT
) &
309 dev_err(port
->clock
->dev
,
310 "unexpected Tx read pos %u\n", data_rd_pos
);
314 ts
.tag
= ines_read32(port
, ts_tx
);
315 ts
.sec
= ines_txts64(port
, 3);
316 ts
.nsec
= ines_txts64(port
, 2);
317 ts
.clkid
= ines_txts64(port
, 4);
318 ts
.portnum
= ines_read32(port
, ts_tx
);
319 ts
.seqid
= ines_read32(port
, ts_tx
);
321 if (ines_match(skb
, class, &ts
, port
->clock
->dev
)) {
322 ns
= ts
.sec
* 1000000000ULL + ts
.nsec
;
327 spin_unlock_irqrestore(&port
->lock
, flags
);
331 static int ines_hwtstamp(struct mii_timestamper
*mii_ts
, struct ifreq
*ifr
)
333 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
334 u32 cm_one_step
= 0, port_conf
, ts_stat_rx
, ts_stat_tx
;
335 struct hwtstamp_config cfg
;
338 if (copy_from_user(&cfg
, ifr
->ifr_data
, sizeof(cfg
)))
341 /* reserved for future extensions */
345 switch (cfg
.tx_type
) {
346 case HWTSTAMP_TX_OFF
:
350 ts_stat_tx
= TS_ENABLE
;
352 case HWTSTAMP_TX_ONESTEP_P2P
:
353 ts_stat_tx
= TS_ENABLE
;
354 cm_one_step
= CM_ONE_STEP
;
360 switch (cfg
.rx_filter
) {
361 case HWTSTAMP_FILTER_NONE
:
364 case HWTSTAMP_FILTER_ALL
:
365 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT
:
366 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC
:
367 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ
:
369 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT
:
370 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC
:
371 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
:
372 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT
:
373 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC
:
374 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
:
375 case HWTSTAMP_FILTER_PTP_V2_EVENT
:
376 case HWTSTAMP_FILTER_PTP_V2_SYNC
:
377 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
:
378 ts_stat_rx
= TS_ENABLE
;
379 cfg
.rx_filter
= HWTSTAMP_FILTER_PTP_V2_EVENT
;
385 spin_lock_irqsave(&port
->lock
, flags
);
387 port_conf
= ines_read32(port
, port_conf
);
388 port_conf
&= ~CM_ONE_STEP
;
389 port_conf
|= cm_one_step
;
391 ines_write32(port
, port_conf
, port_conf
);
392 ines_write32(port
, ts_stat_rx
, ts_stat_rx
);
393 ines_write32(port
, ts_stat_tx
, ts_stat_tx
);
395 port
->rxts_enabled
= ts_stat_rx
== TS_ENABLE
;
396 port
->txts_enabled
= ts_stat_tx
== TS_ENABLE
;
398 spin_unlock_irqrestore(&port
->lock
, flags
);
400 return copy_to_user(ifr
->ifr_data
, &cfg
, sizeof(cfg
)) ? -EFAULT
: 0;
403 static void ines_link_state(struct mii_timestamper
*mii_ts
,
404 struct phy_device
*phydev
)
406 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
407 u32 port_conf
, speed_conf
;
410 switch (phydev
->speed
) {
412 speed_conf
= PHY_SPEED_10
<< PHY_SPEED_SHIFT
;
415 speed_conf
= PHY_SPEED_100
<< PHY_SPEED_SHIFT
;
418 speed_conf
= PHY_SPEED_1000
<< PHY_SPEED_SHIFT
;
421 dev_err(port
->clock
->dev
, "bad speed: %d\n", phydev
->speed
);
424 spin_lock_irqsave(&port
->lock
, flags
);
426 port_conf
= ines_read32(port
, port_conf
);
427 port_conf
&= ~(0x3 << PHY_SPEED_SHIFT
);
428 port_conf
|= speed_conf
;
430 ines_write32(port
, port_conf
, port_conf
);
432 spin_unlock_irqrestore(&port
->lock
, flags
);
435 static bool ines_match(struct sk_buff
*skb
, unsigned int ptp_class
,
436 struct ines_timestamp
*ts
, struct device
*dev
)
438 struct ptp_header
*hdr
;
443 if (unlikely(ptp_class
& PTP_CLASS_V1
))
446 hdr
= ptp_parse_header(skb
, ptp_class
);
450 msgtype
= ptp_get_msgtype(hdr
, ptp_class
);
451 clkid
= be64_to_cpup((__be64
*)&hdr
->source_port_identity
.clock_identity
.id
[0]);
452 portn
= be16_to_cpu(hdr
->source_port_identity
.port_number
);
453 seqid
= be16_to_cpu(hdr
->sequence_id
);
455 if (tag_to_msgtype(ts
->tag
& 0x7) != msgtype
) {
456 dev_dbg(dev
, "msgtype mismatch ts %hhu != skb %hhu\n",
457 tag_to_msgtype(ts
->tag
& 0x7), msgtype
);
460 if (ts
->clkid
!= clkid
) {
461 dev_dbg(dev
, "clkid mismatch ts %llx != skb %llx\n",
465 if (ts
->portnum
!= portn
) {
466 dev_dbg(dev
, "portn mismatch ts %hu != skb %hu\n",
470 if (ts
->seqid
!= seqid
) {
471 dev_dbg(dev
, "seqid mismatch ts %hu != skb %hu\n",
479 static bool ines_rxtstamp(struct mii_timestamper
*mii_ts
,
480 struct sk_buff
*skb
, int type
)
482 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
483 struct skb_shared_hwtstamps
*ssh
;
486 if (!port
->rxts_enabled
)
489 ns
= ines_find_rxts(port
, skb
, type
);
493 ssh
= skb_hwtstamps(skb
);
494 ssh
->hwtstamp
= ns_to_ktime(ns
);
500 static int ines_rxfifo_read(struct ines_port
*port
)
502 u32 data_rd_pos
, buf_stat
, mask
, ts_stat_rx
;
503 struct ines_timestamp
*ts
;
506 mask
= RX_FIFO_NE_1
<< port
->index
;
508 for (i
= 0; i
< INES_FIFO_DEPTH
; i
++) {
509 if (list_empty(&port
->pool
)) {
510 dev_err(port
->clock
->dev
, "event pool is empty\n");
513 buf_stat
= ines_read32(port
->clock
, buf_stat
);
514 if (!(buf_stat
& mask
))
517 ts_stat_rx
= ines_read32(port
, ts_stat_rx
);
518 data_rd_pos
= (ts_stat_rx
>> DATA_READ_POS_SHIFT
) &
521 dev_err(port
->clock
->dev
, "unexpected Rx read pos %u\n",
526 ts
= list_first_entry(&port
->pool
, struct ines_timestamp
, list
);
527 ts
->tmo
= jiffies
+ HZ
;
528 ts
->tag
= ines_read32(port
, ts_rx
);
529 ts
->sec
= ines_rxts64(port
, 3);
530 ts
->nsec
= ines_rxts64(port
, 2);
531 ts
->clkid
= ines_rxts64(port
, 4);
532 ts
->portnum
= ines_read32(port
, ts_rx
);
533 ts
->seqid
= ines_read32(port
, ts_rx
);
535 list_del_init(&ts
->list
);
536 list_add_tail(&ts
->list
, &port
->events
);
542 static u64
ines_rxts64(struct ines_port
*port
, unsigned int words
)
548 word
= ines_read32(port
, ts_rx
);
551 for (i
= 0; i
< words
; i
++) {
552 word
= ines_read32(port
, ts_rx
);
559 static bool ines_timestamp_expired(struct ines_timestamp
*ts
)
561 return time_after(jiffies
, ts
->tmo
);
564 static int ines_ts_info(struct mii_timestamper
*mii_ts
,
565 struct ethtool_ts_info
*info
)
567 info
->so_timestamping
=
568 SOF_TIMESTAMPING_TX_HARDWARE
|
569 SOF_TIMESTAMPING_TX_SOFTWARE
|
570 SOF_TIMESTAMPING_RX_HARDWARE
|
571 SOF_TIMESTAMPING_RX_SOFTWARE
|
572 SOF_TIMESTAMPING_SOFTWARE
|
573 SOF_TIMESTAMPING_RAW_HARDWARE
;
575 info
->phc_index
= -1;
578 (1 << HWTSTAMP_TX_OFF
) |
579 (1 << HWTSTAMP_TX_ON
) |
580 (1 << HWTSTAMP_TX_ONESTEP_P2P
);
583 (1 << HWTSTAMP_FILTER_NONE
) |
584 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
);
589 static u64
ines_txts64(struct ines_port
*port
, unsigned int words
)
595 word
= ines_read32(port
, ts_tx
);
598 for (i
= 0; i
< words
; i
++) {
599 word
= ines_read32(port
, ts_tx
);
606 static bool ines_txts_onestep(struct ines_port
*port
, struct sk_buff
*skb
, int type
)
611 spin_lock_irqsave(&port
->lock
, flags
);
612 port_conf
= ines_read32(port
, port_conf
);
613 spin_unlock_irqrestore(&port
->lock
, flags
);
615 if (port_conf
& CM_ONE_STEP
)
616 return is_sync_pdelay_resp(skb
, type
);
621 static void ines_txtstamp(struct mii_timestamper
*mii_ts
,
622 struct sk_buff
*skb
, int type
)
624 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
625 struct sk_buff
*old_skb
= NULL
;
628 if (!port
->txts_enabled
|| ines_txts_onestep(port
, skb
, type
)) {
633 spin_lock_irqsave(&port
->lock
, flags
);
636 old_skb
= port
->tx_skb
;
640 spin_unlock_irqrestore(&port
->lock
, flags
);
644 schedule_delayed_work(&port
->ts_work
, 1);
647 static void ines_txtstamp_work(struct work_struct
*work
)
649 struct ines_port
*port
=
650 container_of(work
, struct ines_port
, ts_work
.work
);
651 struct skb_shared_hwtstamps ssh
;
656 spin_lock_irqsave(&port
->lock
, flags
);
659 spin_unlock_irqrestore(&port
->lock
, flags
);
661 ns
= ines_find_txts(port
, skb
);
666 ssh
.hwtstamp
= ns_to_ktime(ns
);
667 skb_complete_tx_timestamp(skb
, &ssh
);
670 static bool is_sync_pdelay_resp(struct sk_buff
*skb
, int type
)
672 struct ptp_header
*hdr
;
675 hdr
= ptp_parse_header(skb
, type
);
679 msgtype
= ptp_get_msgtype(hdr
, type
);
682 case PTP_MSGTYPE_SYNC
:
683 case PTP_MSGTYPE_PDELAY_RESP
:
690 static u8
tag_to_msgtype(u8 tag
)
693 case MESSAGE_TYPE_SYNC
:
694 return PTP_MSGTYPE_SYNC
;
695 case MESSAGE_TYPE_P_DELAY_REQ
:
696 return PTP_MSGTYPE_PDELAY_REQ
;
697 case MESSAGE_TYPE_P_DELAY_RESP
:
698 return PTP_MSGTYPE_PDELAY_RESP
;
699 case MESSAGE_TYPE_DELAY_REQ
:
700 return PTP_MSGTYPE_DELAY_REQ
;
705 static struct mii_timestamper
*ines_ptp_probe_channel(struct device
*device
,
708 struct device_node
*node
= device
->of_node
;
709 struct ines_port
*port
;
711 if (index
> INES_N_PORTS
- 1) {
712 dev_err(device
, "bad port index %u\n", index
);
713 return ERR_PTR(-EINVAL
);
715 port
= ines_find_port(node
, index
);
717 dev_err(device
, "missing port index %u\n", index
);
718 return ERR_PTR(-ENODEV
);
720 port
->mii_ts
.rxtstamp
= ines_rxtstamp
;
721 port
->mii_ts
.txtstamp
= ines_txtstamp
;
722 port
->mii_ts
.hwtstamp
= ines_hwtstamp
;
723 port
->mii_ts
.link_state
= ines_link_state
;
724 port
->mii_ts
.ts_info
= ines_ts_info
;
726 return &port
->mii_ts
;
729 static void ines_ptp_release_channel(struct device
*device
,
730 struct mii_timestamper
*mii_ts
)
734 static struct mii_timestamping_ctrl ines_ctrl
= {
735 .probe_channel
= ines_ptp_probe_channel
,
736 .release_channel
= ines_ptp_release_channel
,
739 static int ines_ptp_ctrl_probe(struct platform_device
*pld
)
741 struct ines_clock
*clock
;
745 addr
= devm_platform_ioremap_resource(pld
, 0);
750 clock
= kzalloc(sizeof(*clock
), GFP_KERNEL
);
755 if (ines_clock_init(clock
, &pld
->dev
, addr
)) {
760 err
= register_mii_tstamp_controller(&pld
->dev
, &ines_ctrl
);
765 mutex_lock(&ines_clocks_lock
);
766 list_add_tail(&ines_clocks
, &clock
->list
);
767 mutex_unlock(&ines_clocks_lock
);
769 dev_set_drvdata(&pld
->dev
, clock
);
774 static int ines_ptp_ctrl_remove(struct platform_device
*pld
)
776 struct ines_clock
*clock
= dev_get_drvdata(&pld
->dev
);
778 unregister_mii_tstamp_controller(&pld
->dev
);
779 mutex_lock(&ines_clocks_lock
);
780 list_del(&clock
->list
);
781 mutex_unlock(&ines_clocks_lock
);
782 ines_clock_cleanup(clock
);
787 static const struct of_device_id ines_ptp_ctrl_of_match
[] = {
788 { .compatible
= "ines,ptp-ctrl" },
792 MODULE_DEVICE_TABLE(of
, ines_ptp_ctrl_of_match
);
794 static struct platform_driver ines_ptp_ctrl_driver
= {
795 .probe
= ines_ptp_ctrl_probe
,
796 .remove
= ines_ptp_ctrl_remove
,
798 .name
= "ines_ptp_ctrl",
799 .of_match_table
= of_match_ptr(ines_ptp_ctrl_of_match
),
802 module_platform_driver(ines_ptp_ctrl_driver
);