Skip to content

Commit cfd433c

Browse files
author
Paolo Abeni
committed
Merge branch 'ptp-ocp-fix-serial-port-information-export'
Vadim Fedorenko says: ==================== ptp: ocp: fix serial port information export Starting v6.8 the serial port subsystem changed the hierarchy of devices and symlinks are not working anymore. Previous discussion made it clear that the idea of symlinks for tty devices was wrong by design [1]. This series implements additional attributes to expose the information and removes symlinks for tty devices. [1] https://lore.kernel.org/netdev/2024060503-subsonic-pupil-bbee@gregkh/ v6 -> v7: - fix issues with applying patches v5 -> v6: - split conversion to array to separate patch per Jiri's feedback - move changelog to cover letter v4 -> v5: - remove unused variable in ptp_ocp_tty_show v3 -> v4: - re-organize info printing to use ptp_ocp_tty_port_name() - keep uintptr_t to be consistent with other code v2 -> v3: - replace serial ports definitions with array and enum for index - replace pointer math with direct array access - nit in documentation spelling v1 -> v2: - add Documentation/ABI changes ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 2560db6 + 40bec57 commit cfd433c

File tree

2 files changed

+119
-80
lines changed

2 files changed

+119
-80
lines changed

Documentation/ABI/testing/sysfs-timecard

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -258,24 +258,29 @@ Description: (RW) When retrieving the PHC with the PTP SYS_OFFSET_EXTENDED
258258
the estimated point where the FPGA latches the PHC time. This
259259
value may be changed by writing an unsigned integer.
260260

261-
What: /sys/class/timecard/ocpN/ttyGNSS
262-
What: /sys/class/timecard/ocpN/ttyGNSS2
263-
Date: September 2021
261+
What: /sys/class/timecard/ocpN/tty
262+
Date: August 2024
263+
Contact: Vadim Fedorenko <[email protected]>
264+
Description: (RO) Directory containing the sysfs nodes for TTY attributes
265+
266+
What: /sys/class/timecard/ocpN/tty/ttyGNSS
267+
What: /sys/class/timecard/ocpN/tty/ttyGNSS2
268+
Date: August 2024
264269
Contact: Jonathan Lemon <[email protected]>
265-
Description: These optional attributes link to the TTY serial ports
266-
associated with the GNSS devices.
270+
Description: (RO) These optional attributes contain names of the TTY serial
271+
ports associated with the GNSS devices.
267272

268-
What: /sys/class/timecard/ocpN/ttyMAC
269-
Date: September 2021
273+
What: /sys/class/timecard/ocpN/tty/ttyMAC
274+
Date: August 2024
270275
Contact: Jonathan Lemon <[email protected]>
271-
Description: This optional attribute links to the TTY serial port
272-
associated with the Miniature Atomic Clock.
276+
Description: (RO) This optional attribute contains name of the TTY serial
277+
port associated with the Miniature Atomic Clock.
273278

274-
What: /sys/class/timecard/ocpN/ttyNMEA
275-
Date: September 2021
279+
What: /sys/class/timecard/ocpN/tty/ttyNMEA
280+
Date: August 2024
276281
Contact: Jonathan Lemon <[email protected]>
277-
Description: This optional attribute links to the TTY serial port
278-
which outputs the PHC time in NMEA ZDA format.
282+
Description: (RO) This optional attribute contains name of the TTY serial
283+
port which outputs the PHC time in NMEA ZDA format.
279284

280285
What: /sys/class/timecard/ocpN/utc_tai_offset
281286
Date: September 2021

drivers/ptp/ptp_ocp.c

Lines changed: 101 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,15 @@ struct ptp_ocp_serial_port {
316316
#define OCP_SERIAL_LEN 6
317317
#define OCP_SMA_NUM 4
318318

319+
enum {
320+
PORT_GNSS,
321+
PORT_GNSS2,
322+
PORT_MAC, /* miniature atomic clock */
323+
PORT_NMEA,
324+
325+
__PORT_COUNT,
326+
};
327+
319328
struct ptp_ocp {
320329
struct pci_dev *pdev;
321330
struct device dev;
@@ -357,10 +366,7 @@ struct ptp_ocp {
357366
struct delayed_work sync_work;
358367
int id;
359368
int n_irqs;
360-
struct ptp_ocp_serial_port gnss_port;
361-
struct ptp_ocp_serial_port gnss2_port;
362-
struct ptp_ocp_serial_port mac_port; /* miniature atomic clock */
363-
struct ptp_ocp_serial_port nmea_port;
369+
struct ptp_ocp_serial_port port[__PORT_COUNT];
364370
bool fw_loader;
365371
u8 fw_tag;
366372
u16 fw_version;
@@ -655,28 +661,28 @@ static struct ocp_resource ocp_fb_resource[] = {
655661
},
656662
},
657663
{
658-
OCP_SERIAL_RESOURCE(gnss_port),
664+
OCP_SERIAL_RESOURCE(port[PORT_GNSS]),
659665
.offset = 0x00160000 + 0x1000, .irq_vec = 3,
660666
.extra = &(struct ptp_ocp_serial_port) {
661667
.baud = 115200,
662668
},
663669
},
664670
{
665-
OCP_SERIAL_RESOURCE(gnss2_port),
671+
OCP_SERIAL_RESOURCE(port[PORT_GNSS2]),
666672
.offset = 0x00170000 + 0x1000, .irq_vec = 4,
667673
.extra = &(struct ptp_ocp_serial_port) {
668674
.baud = 115200,
669675
},
670676
},
671677
{
672-
OCP_SERIAL_RESOURCE(mac_port),
678+
OCP_SERIAL_RESOURCE(port[PORT_MAC]),
673679
.offset = 0x00180000 + 0x1000, .irq_vec = 5,
674680
.extra = &(struct ptp_ocp_serial_port) {
675681
.baud = 57600,
676682
},
677683
},
678684
{
679-
OCP_SERIAL_RESOURCE(nmea_port),
685+
OCP_SERIAL_RESOURCE(port[PORT_NMEA]),
680686
.offset = 0x00190000 + 0x1000, .irq_vec = 10,
681687
},
682688
{
@@ -740,7 +746,7 @@ static struct ocp_resource ocp_art_resource[] = {
740746
.offset = 0x01000000, .size = 0x10000,
741747
},
742748
{
743-
OCP_SERIAL_RESOURCE(gnss_port),
749+
OCP_SERIAL_RESOURCE(port[PORT_GNSS]),
744750
.offset = 0x00160000 + 0x1000, .irq_vec = 3,
745751
.extra = &(struct ptp_ocp_serial_port) {
746752
.baud = 115200,
@@ -839,7 +845,7 @@ static struct ocp_resource ocp_art_resource[] = {
839845
},
840846
},
841847
{
842-
OCP_SERIAL_RESOURCE(mac_port),
848+
OCP_SERIAL_RESOURCE(port[PORT_MAC]),
843849
.offset = 0x00190000, .irq_vec = 7,
844850
.extra = &(struct ptp_ocp_serial_port) {
845851
.baud = 9600,
@@ -950,14 +956,14 @@ static struct ocp_resource ocp_adva_resource[] = {
950956
.offset = 0x00220000, .size = 0x1000,
951957
},
952958
{
953-
OCP_SERIAL_RESOURCE(gnss_port),
959+
OCP_SERIAL_RESOURCE(port[PORT_GNSS]),
954960
.offset = 0x00160000 + 0x1000, .irq_vec = 3,
955961
.extra = &(struct ptp_ocp_serial_port) {
956962
.baud = 9600,
957963
},
958964
},
959965
{
960-
OCP_SERIAL_RESOURCE(mac_port),
966+
OCP_SERIAL_RESOURCE(port[PORT_MAC]),
961967
.offset = 0x00180000 + 0x1000, .irq_vec = 5,
962968
.extra = &(struct ptp_ocp_serial_port) {
963969
.baud = 115200,
@@ -1649,6 +1655,15 @@ ptp_ocp_tod_gnss_name(int idx)
16491655
return gnss_name[idx];
16501656
}
16511657

1658+
static const char *
1659+
ptp_ocp_tty_port_name(int idx)
1660+
{
1661+
static const char * const tty_name[] = {
1662+
"GNSS", "GNSS2", "MAC", "NMEA"
1663+
};
1664+
return tty_name[idx];
1665+
}
1666+
16521667
struct ptp_ocp_nvmem_match_info {
16531668
struct ptp_ocp *bp;
16541669
const void * const tag;
@@ -3346,6 +3361,54 @@ static EXT_ATTR_RO(freq, frequency, 1);
33463361
static EXT_ATTR_RO(freq, frequency, 2);
33473362
static EXT_ATTR_RO(freq, frequency, 3);
33483363

3364+
static ssize_t
3365+
ptp_ocp_tty_show(struct device *dev, struct device_attribute *attr, char *buf)
3366+
{
3367+
struct dev_ext_attribute *ea = to_ext_attr(attr);
3368+
struct ptp_ocp *bp = dev_get_drvdata(dev);
3369+
3370+
return sysfs_emit(buf, "ttyS%d", bp->port[(uintptr_t)ea->var].line);
3371+
}
3372+
3373+
static umode_t
3374+
ptp_ocp_timecard_tty_is_visible(struct kobject *kobj, struct attribute *attr, int n)
3375+
{
3376+
struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj));
3377+
struct ptp_ocp_serial_port *port;
3378+
struct device_attribute *dattr;
3379+
struct dev_ext_attribute *ea;
3380+
3381+
if (strncmp(attr->name, "tty", 3))
3382+
return attr->mode;
3383+
3384+
dattr = container_of(attr, struct device_attribute, attr);
3385+
ea = container_of(dattr, struct dev_ext_attribute, attr);
3386+
port = &bp->port[(uintptr_t)ea->var];
3387+
return port->line == -1 ? 0 : 0444;
3388+
}
3389+
3390+
#define EXT_TTY_ATTR_RO(_name, _val) \
3391+
struct dev_ext_attribute dev_attr_tty##_name = \
3392+
{ __ATTR(tty##_name, 0444, ptp_ocp_tty_show, NULL), (void *)_val }
3393+
3394+
static EXT_TTY_ATTR_RO(GNSS, PORT_GNSS);
3395+
static EXT_TTY_ATTR_RO(GNSS2, PORT_GNSS2);
3396+
static EXT_TTY_ATTR_RO(MAC, PORT_MAC);
3397+
static EXT_TTY_ATTR_RO(NMEA, PORT_NMEA);
3398+
static struct attribute *ptp_ocp_timecard_tty_attrs[] = {
3399+
&dev_attr_ttyGNSS.attr.attr,
3400+
&dev_attr_ttyGNSS2.attr.attr,
3401+
&dev_attr_ttyMAC.attr.attr,
3402+
&dev_attr_ttyNMEA.attr.attr,
3403+
NULL,
3404+
};
3405+
3406+
static const struct attribute_group ptp_ocp_timecard_tty_group = {
3407+
.name = "tty",
3408+
.attrs = ptp_ocp_timecard_tty_attrs,
3409+
.is_visible = ptp_ocp_timecard_tty_is_visible,
3410+
};
3411+
33493412
static ssize_t
33503413
serialnum_show(struct device *dev, struct device_attribute *attr, char *buf)
33513414
{
@@ -3775,6 +3838,7 @@ static const struct attribute_group fb_timecard_group = {
37753838

37763839
static const struct ocp_attr_group fb_timecard_groups[] = {
37773840
{ .cap = OCP_CAP_BASIC, .group = &fb_timecard_group },
3841+
{ .cap = OCP_CAP_BASIC, .group = &ptp_ocp_timecard_tty_group },
37783842
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal0_group },
37793843
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal1_group },
37803844
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal2_group },
@@ -3814,6 +3878,7 @@ static const struct attribute_group art_timecard_group = {
38143878

38153879
static const struct ocp_attr_group art_timecard_groups[] = {
38163880
{ .cap = OCP_CAP_BASIC, .group = &art_timecard_group },
3881+
{ .cap = OCP_CAP_BASIC, .group = &ptp_ocp_timecard_tty_group },
38173882
{ },
38183883
};
38193884

@@ -3841,6 +3906,7 @@ static const struct attribute_group adva_timecard_group = {
38413906

38423907
static const struct ocp_attr_group adva_timecard_groups[] = {
38433908
{ .cap = OCP_CAP_BASIC, .group = &adva_timecard_group },
3909+
{ .cap = OCP_CAP_BASIC, .group = &ptp_ocp_timecard_tty_group },
38443910
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal0_group },
38453911
{ .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal1_group },
38463912
{ .cap = OCP_CAP_FREQ, .group = &fb_timecard_freq0_group },
@@ -3960,16 +4026,11 @@ ptp_ocp_summary_show(struct seq_file *s, void *data)
39604026
bp = dev_get_drvdata(dev);
39614027

39624028
seq_printf(s, "%7s: /dev/ptp%d\n", "PTP", ptp_clock_index(bp->ptp));
3963-
if (bp->gnss_port.line != -1)
3964-
seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS1",
3965-
bp->gnss_port.line);
3966-
if (bp->gnss2_port.line != -1)
3967-
seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS2",
3968-
bp->gnss2_port.line);
3969-
if (bp->mac_port.line != -1)
3970-
seq_printf(s, "%7s: /dev/ttyS%d\n", "MAC", bp->mac_port.line);
3971-
if (bp->nmea_port.line != -1)
3972-
seq_printf(s, "%7s: /dev/ttyS%d\n", "NMEA", bp->nmea_port.line);
4029+
for (i = 0; i < __PORT_COUNT; i++) {
4030+
if (bp->port[i].line != -1)
4031+
seq_printf(s, "%7s: /dev/ttyS%d\n", ptp_ocp_tty_port_name(i),
4032+
bp->port[i].line);
4033+
}
39734034

39744035
memset(sma_val, 0xff, sizeof(sma_val));
39754036
if (bp->sma_map1) {
@@ -4279,7 +4340,7 @@ ptp_ocp_dev_release(struct device *dev)
42794340
static int
42804341
ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev)
42814342
{
4282-
int err;
4343+
int i, err;
42834344

42844345
mutex_lock(&ptp_ocp_lock);
42854346
err = idr_alloc(&ptp_ocp_idr, bp, 0, 0, GFP_KERNEL);
@@ -4292,10 +4353,10 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev)
42924353

42934354
bp->ptp_info = ptp_ocp_clock_info;
42944355
spin_lock_init(&bp->lock);
4295-
bp->gnss_port.line = -1;
4296-
bp->gnss2_port.line = -1;
4297-
bp->mac_port.line = -1;
4298-
bp->nmea_port.line = -1;
4356+
4357+
for (i = 0; i < __PORT_COUNT; i++)
4358+
bp->port[i].line = -1;
4359+
42994360
bp->pdev = pdev;
43004361

43014362
device_initialize(&bp->dev);
@@ -4352,22 +4413,6 @@ ptp_ocp_complete(struct ptp_ocp *bp)
43524413
struct pps_device *pps;
43534414
char buf[32];
43544415

4355-
if (bp->gnss_port.line != -1) {
4356-
sprintf(buf, "ttyS%d", bp->gnss_port.line);
4357-
ptp_ocp_link_child(bp, buf, "ttyGNSS");
4358-
}
4359-
if (bp->gnss2_port.line != -1) {
4360-
sprintf(buf, "ttyS%d", bp->gnss2_port.line);
4361-
ptp_ocp_link_child(bp, buf, "ttyGNSS2");
4362-
}
4363-
if (bp->mac_port.line != -1) {
4364-
sprintf(buf, "ttyS%d", bp->mac_port.line);
4365-
ptp_ocp_link_child(bp, buf, "ttyMAC");
4366-
}
4367-
if (bp->nmea_port.line != -1) {
4368-
sprintf(buf, "ttyS%d", bp->nmea_port.line);
4369-
ptp_ocp_link_child(bp, buf, "ttyNMEA");
4370-
}
43714416
sprintf(buf, "ptp%d", ptp_clock_index(bp->ptp));
43724417
ptp_ocp_link_child(bp, buf, "ptp");
43734418

@@ -4416,23 +4461,20 @@ ptp_ocp_info(struct ptp_ocp *bp)
44164461
};
44174462
struct device *dev = &bp->pdev->dev;
44184463
u32 reg;
4464+
int i;
44194465

44204466
ptp_ocp_phc_info(bp);
44214467

4422-
ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port.line,
4423-
bp->gnss_port.baud);
4424-
ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port.line,
4425-
bp->gnss2_port.baud);
4426-
ptp_ocp_serial_info(dev, "MAC", bp->mac_port.line, bp->mac_port.baud);
4427-
if (bp->nmea_out && bp->nmea_port.line != -1) {
4428-
bp->nmea_port.baud = -1;
4468+
for (i = 0; i < __PORT_COUNT; i++) {
4469+
if (i == PORT_NMEA && bp->nmea_out && bp->port[PORT_NMEA].line != -1) {
4470+
bp->port[PORT_NMEA].baud = -1;
44294471

4430-
reg = ioread32(&bp->nmea_out->uart_baud);
4431-
if (reg < ARRAY_SIZE(nmea_baud))
4432-
bp->nmea_port.baud = nmea_baud[reg];
4433-
4434-
ptp_ocp_serial_info(dev, "NMEA", bp->nmea_port.line,
4435-
bp->nmea_port.baud);
4472+
reg = ioread32(&bp->nmea_out->uart_baud);
4473+
if (reg < ARRAY_SIZE(nmea_baud))
4474+
bp->port[PORT_NMEA].baud = nmea_baud[reg];
4475+
}
4476+
ptp_ocp_serial_info(dev, ptp_ocp_tty_port_name(i), bp->port[i].line,
4477+
bp->port[i].baud);
44364478
}
44374479
}
44384480

@@ -4441,9 +4483,6 @@ ptp_ocp_detach_sysfs(struct ptp_ocp *bp)
44414483
{
44424484
struct device *dev = &bp->dev;
44434485

4444-
sysfs_remove_link(&dev->kobj, "ttyGNSS");
4445-
sysfs_remove_link(&dev->kobj, "ttyGNSS2");
4446-
sysfs_remove_link(&dev->kobj, "ttyMAC");
44474486
sysfs_remove_link(&dev->kobj, "ptp");
44484487
sysfs_remove_link(&dev->kobj, "pps");
44494488
}
@@ -4473,14 +4512,9 @@ ptp_ocp_detach(struct ptp_ocp *bp)
44734512
for (i = 0; i < 4; i++)
44744513
if (bp->signal_out[i])
44754514
ptp_ocp_unregister_ext(bp->signal_out[i]);
4476-
if (bp->gnss_port.line != -1)
4477-
serial8250_unregister_port(bp->gnss_port.line);
4478-
if (bp->gnss2_port.line != -1)
4479-
serial8250_unregister_port(bp->gnss2_port.line);
4480-
if (bp->mac_port.line != -1)
4481-
serial8250_unregister_port(bp->mac_port.line);
4482-
if (bp->nmea_port.line != -1)
4483-
serial8250_unregister_port(bp->nmea_port.line);
4515+
for (i = 0; i < __PORT_COUNT; i++)
4516+
if (bp->port[i].line != -1)
4517+
serial8250_unregister_port(bp->port[i].line);
44844518
platform_device_unregister(bp->spi_flash);
44854519
platform_device_unregister(bp->i2c_ctrl);
44864520
if (bp->i2c_clk)

0 commit comments

Comments
 (0)