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
112 #define DELAY_REQ 0x1
113 #define PDELAY_REQ 0x2
114 #define PDELAY_RESP 0x3
116 static LIST_HEAD(ines_clocks
);
117 static DEFINE_MUTEX(ines_clocks_lock
);
119 struct ines_global_regs
{
130 struct ines_port_registers
{
139 struct ines_timestamp
{
140 struct list_head list
;
151 struct ines_port_registers
*regs
;
152 struct mii_timestamper mii_ts
;
153 struct ines_clock
*clock
;
157 struct delayed_work ts_work
;
158 /* lock protects event list and tx_skb */
160 struct sk_buff
*tx_skb
;
161 struct list_head events
;
162 struct list_head pool
;
163 struct ines_timestamp pool_data
[INES_MAX_EVENTS
];
167 struct ines_port port
[INES_N_PORTS
];
168 struct ines_global_regs __iomem
*regs
;
170 struct device_node
*node
;
172 struct list_head list
;
175 static bool ines_match(struct sk_buff
*skb
, unsigned int ptp_class
,
176 struct ines_timestamp
*ts
, struct device
*dev
);
177 static int ines_rxfifo_read(struct ines_port
*port
);
178 static u64
ines_rxts64(struct ines_port
*port
, unsigned int words
);
179 static bool ines_timestamp_expired(struct ines_timestamp
*ts
);
180 static u64
ines_txts64(struct ines_port
*port
, unsigned int words
);
181 static void ines_txtstamp_work(struct work_struct
*work
);
182 static bool is_sync_pdelay_resp(struct sk_buff
*skb
, int type
);
183 static u8
tag_to_msgtype(u8 tag
);
185 static void ines_clock_cleanup(struct ines_clock
*clock
)
187 struct ines_port
*port
;
190 for (i
= 0; i
< INES_N_PORTS
; i
++) {
191 port
= &clock
->port
[i
];
192 cancel_delayed_work_sync(&port
->ts_work
);
196 static int ines_clock_init(struct ines_clock
*clock
, struct device
*device
,
199 struct device_node
*node
= device
->of_node
;
200 unsigned long port_addr
;
201 struct ines_port
*port
;
204 INIT_LIST_HEAD(&clock
->list
);
208 clock
->regs
= clock
->base
;
210 for (i
= 0; i
< INES_N_PORTS
; i
++) {
211 port
= &clock
->port
[i
];
212 port_addr
= (unsigned long) clock
->base
+
213 INES_PORT_OFFSET
+ i
* INES_PORT_SIZE
;
214 port
->regs
= (struct ines_port_registers
*) port_addr
;
217 INIT_DELAYED_WORK(&port
->ts_work
, ines_txtstamp_work
);
218 spin_lock_init(&port
->lock
);
219 INIT_LIST_HEAD(&port
->events
);
220 INIT_LIST_HEAD(&port
->pool
);
221 for (j
= 0; j
< INES_MAX_EVENTS
; j
++)
222 list_add(&port
->pool_data
[j
].list
, &port
->pool
);
225 ines_write32(clock
, 0xBEEF, test
);
226 ines_write32(clock
, 0xBEEF, test2
);
228 dev_dbg(device
, "ID 0x%x\n", ines_read32(clock
, id
));
229 dev_dbg(device
, "TEST 0x%x\n", ines_read32(clock
, test
));
230 dev_dbg(device
, "VERSION 0x%x\n", ines_read32(clock
, version
));
231 dev_dbg(device
, "TEST2 0x%x\n", ines_read32(clock
, test2
));
233 for (i
= 0; i
< INES_N_PORTS
; i
++) {
234 port
= &clock
->port
[i
];
235 ines_write32(port
, PORT_CONF
, port_conf
);
241 static struct ines_port
*ines_find_port(struct device_node
*node
, u32 index
)
243 struct ines_port
*port
= NULL
;
244 struct ines_clock
*clock
;
245 struct list_head
*this;
247 mutex_lock(&ines_clocks_lock
);
248 list_for_each(this, &ines_clocks
) {
249 clock
= list_entry(this, struct ines_clock
, list
);
250 if (clock
->node
== node
) {
251 port
= &clock
->port
[index
];
255 mutex_unlock(&ines_clocks_lock
);
259 static u64
ines_find_rxts(struct ines_port
*port
, struct sk_buff
*skb
, int type
)
261 struct list_head
*this, *next
;
262 struct ines_timestamp
*ts
;
266 if (type
== PTP_CLASS_NONE
)
269 spin_lock_irqsave(&port
->lock
, flags
);
270 ines_rxfifo_read(port
);
271 list_for_each_safe(this, next
, &port
->events
) {
272 ts
= list_entry(this, struct ines_timestamp
, list
);
273 if (ines_timestamp_expired(ts
)) {
274 list_del_init(&ts
->list
);
275 list_add(&ts
->list
, &port
->pool
);
278 if (ines_match(skb
, type
, ts
, port
->clock
->dev
)) {
279 ns
= ts
->sec
* 1000000000ULL + ts
->nsec
;
280 list_del_init(&ts
->list
);
281 list_add(&ts
->list
, &port
->pool
);
285 spin_unlock_irqrestore(&port
->lock
, flags
);
290 static u64
ines_find_txts(struct ines_port
*port
, struct sk_buff
*skb
)
292 unsigned int class = ptp_classify_raw(skb
), i
;
293 u32 data_rd_pos
, buf_stat
, mask
, ts_stat_tx
;
294 struct ines_timestamp ts
;
298 mask
= TX_FIFO_NE_1
<< port
->index
;
300 spin_lock_irqsave(&port
->lock
, flags
);
302 for (i
= 0; i
< INES_FIFO_DEPTH
; i
++) {
304 buf_stat
= ines_read32(port
->clock
, buf_stat
);
305 if (!(buf_stat
& mask
)) {
306 dev_dbg(port
->clock
->dev
,
307 "Tx timestamp FIFO unexpectedly empty\n");
310 ts_stat_tx
= ines_read32(port
, ts_stat_tx
);
311 data_rd_pos
= (ts_stat_tx
>> DATA_READ_POS_SHIFT
) &
314 dev_err(port
->clock
->dev
,
315 "unexpected Tx read pos %u\n", data_rd_pos
);
319 ts
.tag
= ines_read32(port
, ts_tx
);
320 ts
.sec
= ines_txts64(port
, 3);
321 ts
.nsec
= ines_txts64(port
, 2);
322 ts
.clkid
= ines_txts64(port
, 4);
323 ts
.portnum
= ines_read32(port
, ts_tx
);
324 ts
.seqid
= ines_read32(port
, ts_tx
);
326 if (ines_match(skb
, class, &ts
, port
->clock
->dev
)) {
327 ns
= ts
.sec
* 1000000000ULL + ts
.nsec
;
332 spin_unlock_irqrestore(&port
->lock
, flags
);
336 static int ines_hwtstamp(struct mii_timestamper
*mii_ts
, struct ifreq
*ifr
)
338 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
339 u32 cm_one_step
= 0, port_conf
, ts_stat_rx
, ts_stat_tx
;
340 struct hwtstamp_config cfg
;
343 if (copy_from_user(&cfg
, ifr
->ifr_data
, sizeof(cfg
)))
346 /* reserved for future extensions */
350 switch (cfg
.tx_type
) {
351 case HWTSTAMP_TX_OFF
:
355 ts_stat_tx
= TS_ENABLE
;
357 case HWTSTAMP_TX_ONESTEP_P2P
:
358 ts_stat_tx
= TS_ENABLE
;
359 cm_one_step
= CM_ONE_STEP
;
365 switch (cfg
.rx_filter
) {
366 case HWTSTAMP_FILTER_NONE
:
369 case HWTSTAMP_FILTER_ALL
:
370 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT
:
371 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC
:
372 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ
:
374 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT
:
375 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC
:
376 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
:
377 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT
:
378 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC
:
379 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
:
380 case HWTSTAMP_FILTER_PTP_V2_EVENT
:
381 case HWTSTAMP_FILTER_PTP_V2_SYNC
:
382 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
:
383 ts_stat_rx
= TS_ENABLE
;
384 cfg
.rx_filter
= HWTSTAMP_FILTER_PTP_V2_EVENT
;
390 spin_lock_irqsave(&port
->lock
, flags
);
392 port_conf
= ines_read32(port
, port_conf
);
393 port_conf
&= ~CM_ONE_STEP
;
394 port_conf
|= cm_one_step
;
396 ines_write32(port
, port_conf
, port_conf
);
397 ines_write32(port
, ts_stat_rx
, ts_stat_rx
);
398 ines_write32(port
, ts_stat_tx
, ts_stat_tx
);
400 port
->rxts_enabled
= ts_stat_rx
== TS_ENABLE
;
401 port
->txts_enabled
= ts_stat_tx
== TS_ENABLE
;
403 spin_unlock_irqrestore(&port
->lock
, flags
);
405 return copy_to_user(ifr
->ifr_data
, &cfg
, sizeof(cfg
)) ? -EFAULT
: 0;
408 static void ines_link_state(struct mii_timestamper
*mii_ts
,
409 struct phy_device
*phydev
)
411 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
412 u32 port_conf
, speed_conf
;
415 switch (phydev
->speed
) {
417 speed_conf
= PHY_SPEED_10
<< PHY_SPEED_SHIFT
;
420 speed_conf
= PHY_SPEED_100
<< PHY_SPEED_SHIFT
;
423 speed_conf
= PHY_SPEED_1000
<< PHY_SPEED_SHIFT
;
426 dev_err(port
->clock
->dev
, "bad speed: %d\n", phydev
->speed
);
429 spin_lock_irqsave(&port
->lock
, flags
);
431 port_conf
= ines_read32(port
, port_conf
);
432 port_conf
&= ~(0x3 << PHY_SPEED_SHIFT
);
433 port_conf
|= speed_conf
;
435 ines_write32(port
, port_conf
, port_conf
);
437 spin_unlock_irqrestore(&port
->lock
, flags
);
440 static bool ines_match(struct sk_buff
*skb
, unsigned int ptp_class
,
441 struct ines_timestamp
*ts
, struct device
*dev
)
443 struct ptp_header
*hdr
;
448 if (unlikely(ptp_class
& PTP_CLASS_V1
))
451 hdr
= ptp_parse_header(skb
, ptp_class
);
455 msgtype
= ptp_get_msgtype(hdr
, ptp_class
);
456 clkid
= be64_to_cpup((__be64
*)&hdr
->source_port_identity
.clock_identity
.id
[0]);
457 portn
= be16_to_cpu(hdr
->source_port_identity
.port_number
);
458 seqid
= be16_to_cpu(hdr
->sequence_id
);
460 if (tag_to_msgtype(ts
->tag
& 0x7) != msgtype
) {
461 dev_dbg(dev
, "msgtype mismatch ts %hhu != skb %hhu\n",
462 tag_to_msgtype(ts
->tag
& 0x7), msgtype
);
465 if (ts
->clkid
!= clkid
) {
466 dev_dbg(dev
, "clkid mismatch ts %llx != skb %llx\n",
470 if (ts
->portnum
!= portn
) {
471 dev_dbg(dev
, "portn mismatch ts %hu != skb %hu\n",
475 if (ts
->seqid
!= seqid
) {
476 dev_dbg(dev
, "seqid mismatch ts %hu != skb %hu\n",
484 static bool ines_rxtstamp(struct mii_timestamper
*mii_ts
,
485 struct sk_buff
*skb
, int type
)
487 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
488 struct skb_shared_hwtstamps
*ssh
;
491 if (!port
->rxts_enabled
)
494 ns
= ines_find_rxts(port
, skb
, type
);
498 ssh
= skb_hwtstamps(skb
);
499 ssh
->hwtstamp
= ns_to_ktime(ns
);
505 static int ines_rxfifo_read(struct ines_port
*port
)
507 u32 data_rd_pos
, buf_stat
, mask
, ts_stat_rx
;
508 struct ines_timestamp
*ts
;
511 mask
= RX_FIFO_NE_1
<< port
->index
;
513 for (i
= 0; i
< INES_FIFO_DEPTH
; i
++) {
514 if (list_empty(&port
->pool
)) {
515 dev_err(port
->clock
->dev
, "event pool is empty\n");
518 buf_stat
= ines_read32(port
->clock
, buf_stat
);
519 if (!(buf_stat
& mask
))
522 ts_stat_rx
= ines_read32(port
, ts_stat_rx
);
523 data_rd_pos
= (ts_stat_rx
>> DATA_READ_POS_SHIFT
) &
526 dev_err(port
->clock
->dev
, "unexpected Rx read pos %u\n",
531 ts
= list_first_entry(&port
->pool
, struct ines_timestamp
, list
);
532 ts
->tmo
= jiffies
+ HZ
;
533 ts
->tag
= ines_read32(port
, ts_rx
);
534 ts
->sec
= ines_rxts64(port
, 3);
535 ts
->nsec
= ines_rxts64(port
, 2);
536 ts
->clkid
= ines_rxts64(port
, 4);
537 ts
->portnum
= ines_read32(port
, ts_rx
);
538 ts
->seqid
= ines_read32(port
, ts_rx
);
540 list_del_init(&ts
->list
);
541 list_add_tail(&ts
->list
, &port
->events
);
547 static u64
ines_rxts64(struct ines_port
*port
, unsigned int words
)
553 word
= ines_read32(port
, ts_rx
);
556 for (i
= 0; i
< words
; i
++) {
557 word
= ines_read32(port
, ts_rx
);
564 static bool ines_timestamp_expired(struct ines_timestamp
*ts
)
566 return time_after(jiffies
, ts
->tmo
);
569 static int ines_ts_info(struct mii_timestamper
*mii_ts
,
570 struct ethtool_ts_info
*info
)
572 info
->so_timestamping
=
573 SOF_TIMESTAMPING_TX_HARDWARE
|
574 SOF_TIMESTAMPING_TX_SOFTWARE
|
575 SOF_TIMESTAMPING_RX_HARDWARE
|
576 SOF_TIMESTAMPING_RX_SOFTWARE
|
577 SOF_TIMESTAMPING_SOFTWARE
|
578 SOF_TIMESTAMPING_RAW_HARDWARE
;
580 info
->phc_index
= -1;
583 (1 << HWTSTAMP_TX_OFF
) |
584 (1 << HWTSTAMP_TX_ON
) |
585 (1 << HWTSTAMP_TX_ONESTEP_P2P
);
588 (1 << HWTSTAMP_FILTER_NONE
) |
589 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
);
594 static u64
ines_txts64(struct ines_port
*port
, unsigned int words
)
600 word
= ines_read32(port
, ts_tx
);
603 for (i
= 0; i
< words
; i
++) {
604 word
= ines_read32(port
, ts_tx
);
611 static bool ines_txts_onestep(struct ines_port
*port
, struct sk_buff
*skb
, int type
)
616 spin_lock_irqsave(&port
->lock
, flags
);
617 port_conf
= ines_read32(port
, port_conf
);
618 spin_unlock_irqrestore(&port
->lock
, flags
);
620 if (port_conf
& CM_ONE_STEP
)
621 return is_sync_pdelay_resp(skb
, type
);
626 static void ines_txtstamp(struct mii_timestamper
*mii_ts
,
627 struct sk_buff
*skb
, int type
)
629 struct ines_port
*port
= container_of(mii_ts
, struct ines_port
, mii_ts
);
630 struct sk_buff
*old_skb
= NULL
;
633 if (!port
->txts_enabled
|| ines_txts_onestep(port
, skb
, type
)) {
638 spin_lock_irqsave(&port
->lock
, flags
);
641 old_skb
= port
->tx_skb
;
645 spin_unlock_irqrestore(&port
->lock
, flags
);
649 schedule_delayed_work(&port
->ts_work
, 1);
652 static void ines_txtstamp_work(struct work_struct
*work
)
654 struct ines_port
*port
=
655 container_of(work
, struct ines_port
, ts_work
.work
);
656 struct skb_shared_hwtstamps ssh
;
661 spin_lock_irqsave(&port
->lock
, flags
);
664 spin_unlock_irqrestore(&port
->lock
, flags
);
666 ns
= ines_find_txts(port
, skb
);
671 ssh
.hwtstamp
= ns_to_ktime(ns
);
672 skb_complete_tx_timestamp(skb
, &ssh
);
675 static bool is_sync_pdelay_resp(struct sk_buff
*skb
, int type
)
677 struct ptp_header
*hdr
;
680 hdr
= ptp_parse_header(skb
, type
);
684 msgtype
= ptp_get_msgtype(hdr
, type
);
686 switch ((msgtype
& 0xf)) {
695 static u8
tag_to_msgtype(u8 tag
)
698 case MESSAGE_TYPE_SYNC
:
700 case MESSAGE_TYPE_P_DELAY_REQ
:
702 case MESSAGE_TYPE_P_DELAY_RESP
:
704 case MESSAGE_TYPE_DELAY_REQ
:
710 static struct mii_timestamper
*ines_ptp_probe_channel(struct device
*device
,
713 struct device_node
*node
= device
->of_node
;
714 struct ines_port
*port
;
716 if (index
> INES_N_PORTS
- 1) {
717 dev_err(device
, "bad port index %u\n", index
);
718 return ERR_PTR(-EINVAL
);
720 port
= ines_find_port(node
, index
);
722 dev_err(device
, "missing port index %u\n", index
);
723 return ERR_PTR(-ENODEV
);
725 port
->mii_ts
.rxtstamp
= ines_rxtstamp
;
726 port
->mii_ts
.txtstamp
= ines_txtstamp
;
727 port
->mii_ts
.hwtstamp
= ines_hwtstamp
;
728 port
->mii_ts
.link_state
= ines_link_state
;
729 port
->mii_ts
.ts_info
= ines_ts_info
;
731 return &port
->mii_ts
;
734 static void ines_ptp_release_channel(struct device
*device
,
735 struct mii_timestamper
*mii_ts
)
739 static struct mii_timestamping_ctrl ines_ctrl
= {
740 .probe_channel
= ines_ptp_probe_channel
,
741 .release_channel
= ines_ptp_release_channel
,
744 static int ines_ptp_ctrl_probe(struct platform_device
*pld
)
746 struct ines_clock
*clock
;
750 addr
= devm_platform_ioremap_resource(pld
, 0);
755 clock
= kzalloc(sizeof(*clock
), GFP_KERNEL
);
760 if (ines_clock_init(clock
, &pld
->dev
, addr
)) {
765 err
= register_mii_tstamp_controller(&pld
->dev
, &ines_ctrl
);
770 mutex_lock(&ines_clocks_lock
);
771 list_add_tail(&ines_clocks
, &clock
->list
);
772 mutex_unlock(&ines_clocks_lock
);
774 dev_set_drvdata(&pld
->dev
, clock
);
779 static int ines_ptp_ctrl_remove(struct platform_device
*pld
)
781 struct ines_clock
*clock
= dev_get_drvdata(&pld
->dev
);
783 unregister_mii_tstamp_controller(&pld
->dev
);
784 mutex_lock(&ines_clocks_lock
);
785 list_del(&clock
->list
);
786 mutex_unlock(&ines_clocks_lock
);
787 ines_clock_cleanup(clock
);
792 static const struct of_device_id ines_ptp_ctrl_of_match
[] = {
793 { .compatible
= "ines,ptp-ctrl" },
797 MODULE_DEVICE_TABLE(of
, ines_ptp_ctrl_of_match
);
799 static struct platform_driver ines_ptp_ctrl_driver
= {
800 .probe
= ines_ptp_ctrl_probe
,
801 .remove
= ines_ptp_ctrl_remove
,
803 .name
= "ines_ptp_ctrl",
804 .of_match_table
= of_match_ptr(ines_ptp_ctrl_of_match
),
807 module_platform_driver(ines_ptp_ctrl_driver
);