@@ -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+
319328struct 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+
16521667struct 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);
33463361static EXT_ATTR_RO (freq , frequency , 2 ) ;
33473362static 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+
33493412static ssize_t
33503413serialnum_show (struct device * dev , struct device_attribute * attr , char * buf )
33513414{
@@ -3775,6 +3838,7 @@ static const struct attribute_group fb_timecard_group = {
37753838
37763839static 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
38153879static 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
38423907static 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)
42794340static int
42804341ptp_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