@@ -332,6 +332,8 @@ static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r);
332
332
static irqreturn_t ptp_ocp_ts_irq (int irq , void * priv );
333
333
static irqreturn_t ptp_ocp_signal_irq (int irq , void * priv );
334
334
static int ptp_ocp_ts_enable (void * priv , u32 req , bool enable );
335
+ static int ptp_ocp_signal_from_perout (struct ptp_ocp * bp , int gen ,
336
+ struct ptp_perout_request * req );
335
337
static int ptp_ocp_signal_enable (void * priv , u32 req , bool enable );
336
338
static int ptp_ocp_sma_store (struct ptp_ocp * bp , const char * buf , int sma_nr );
337
339
@@ -867,13 +869,27 @@ ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq,
867
869
ext = bp -> pps ;
868
870
break ;
869
871
case PTP_CLK_REQ_PEROUT :
870
- if (on &&
871
- (rq -> perout .period .sec != 1 || rq -> perout .period .nsec != 0 ))
872
- return - EINVAL ;
873
- /* This is a request for 1PPS on an output SMA.
874
- * Allow, but assume manual configuration.
875
- */
876
- return 0 ;
872
+ switch (rq -> perout .index ) {
873
+ case 0 :
874
+ /* This is a request for 1PPS on an output SMA.
875
+ * Allow, but assume manual configuration.
876
+ */
877
+ if (on && (rq -> perout .period .sec != 1 ||
878
+ rq -> perout .period .nsec != 0 ))
879
+ return - EINVAL ;
880
+ return 0 ;
881
+ case 1 :
882
+ case 2 :
883
+ case 3 :
884
+ case 4 :
885
+ req = rq -> perout .index - 1 ;
886
+ ext = bp -> signal_out [req ];
887
+ err = ptp_ocp_signal_from_perout (bp , req , & rq -> perout );
888
+ if (err )
889
+ return err ;
890
+ break ;
891
+ }
892
+ break ;
877
893
default :
878
894
return - EOPNOTSUPP ;
879
895
}
@@ -885,6 +901,24 @@ ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq,
885
901
return err ;
886
902
}
887
903
904
+ static int
905
+ ptp_ocp_verify (struct ptp_clock_info * ptp_info , unsigned pin ,
906
+ enum ptp_pin_function func , unsigned chan )
907
+ {
908
+ struct ptp_ocp * bp = container_of (ptp_info , struct ptp_ocp , ptp_info );
909
+ char buf [16 ];
910
+
911
+ if (func != PTP_PF_PEROUT )
912
+ return - EOPNOTSUPP ;
913
+
914
+ if (chan )
915
+ sprintf (buf , "OUT: GEN%d" , chan );
916
+ else
917
+ sprintf (buf , "OUT: PHC" );
918
+
919
+ return ptp_ocp_sma_store (bp , buf , pin + 1 );
920
+ }
921
+
888
922
static const struct ptp_clock_info ptp_ocp_clock_info = {
889
923
.owner = THIS_MODULE ,
890
924
.name = KBUILD_MODNAME ,
@@ -895,9 +929,10 @@ static const struct ptp_clock_info ptp_ocp_clock_info = {
895
929
.adjfine = ptp_ocp_null_adjfine ,
896
930
.adjphase = ptp_ocp_null_adjphase ,
897
931
.enable = ptp_ocp_enable ,
932
+ .verify = ptp_ocp_verify ,
898
933
.pps = true,
899
934
.n_ext_ts = 4 ,
900
- .n_per_out = 1 ,
935
+ .n_per_out = 5 ,
901
936
};
902
937
903
938
static void
@@ -1465,6 +1500,30 @@ ptp_ocp_signal_set(struct ptp_ocp *bp, int gen, struct ptp_ocp_signal *s)
1465
1500
return 0 ;
1466
1501
}
1467
1502
1503
+ static int
1504
+ ptp_ocp_signal_from_perout (struct ptp_ocp * bp , int gen ,
1505
+ struct ptp_perout_request * req )
1506
+ {
1507
+ struct ptp_ocp_signal s = { };
1508
+
1509
+ s .polarity = bp -> signal [gen ].polarity ;
1510
+ s .period = ktime_set (req -> period .sec , req -> period .nsec );
1511
+ if (!s .period )
1512
+ return 0 ;
1513
+
1514
+ if (req -> flags & PTP_PEROUT_DUTY_CYCLE ) {
1515
+ s .pulse = ktime_set (req -> on .sec , req -> on .nsec );
1516
+ s .duty = ktime_divns (s .pulse * 100 , s .period );
1517
+ }
1518
+
1519
+ if (req -> flags & PTP_PEROUT_PHASE )
1520
+ s .phase = ktime_set (req -> phase .sec , req -> phase .nsec );
1521
+ else
1522
+ s .start = ktime_set (req -> start .sec , req -> start .nsec );
1523
+
1524
+ return ptp_ocp_signal_set (bp , gen , & s );
1525
+ }
1526
+
1468
1527
static int
1469
1528
ptp_ocp_signal_enable (void * priv , u32 req , bool enable )
1470
1529
{
@@ -1740,11 +1799,32 @@ ptp_ocp_sma_init(struct ptp_ocp *bp)
1740
1799
}
1741
1800
}
1742
1801
1802
+ static int
1803
+ ptp_ocp_fb_set_pins (struct ptp_ocp * bp )
1804
+ {
1805
+ struct ptp_pin_desc * config ;
1806
+ int i ;
1807
+
1808
+ config = kzalloc (sizeof (* config ) * 4 , GFP_KERNEL );
1809
+ if (!config )
1810
+ return - ENOMEM ;
1811
+
1812
+ for (i = 0 ; i < 4 ; i ++ ) {
1813
+ sprintf (config [i ].name , "sma%d" , i + 1 );
1814
+ config [i ].index = i ;
1815
+ }
1816
+
1817
+ bp -> ptp_info .n_pins = 4 ;
1818
+ bp -> ptp_info .pin_config = config ;
1819
+
1820
+ return 0 ;
1821
+ }
1822
+
1743
1823
/* FB specific board initializers; last "resource" registered. */
1744
1824
static int
1745
1825
ptp_ocp_fb_board_init (struct ptp_ocp * bp , struct ocp_resource * r )
1746
1826
{
1747
- int ver ;
1827
+ int ver , err ;
1748
1828
1749
1829
bp -> flash_start = 1024 * 4096 ;
1750
1830
bp -> eeprom_map = fb_eeprom_map ;
@@ -1761,6 +1841,10 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
1761
1841
ptp_ocp_sma_init (bp );
1762
1842
ptp_ocp_signal_init (bp );
1763
1843
1844
+ err = ptp_ocp_fb_set_pins (bp );
1845
+ if (err )
1846
+ return err ;
1847
+
1764
1848
return ptp_ocp_init_clock (bp );
1765
1849
}
1766
1850
@@ -3238,6 +3322,7 @@ ptp_ocp_detach(struct ptp_ocp *bp)
3238
3322
pci_free_irq_vectors (bp -> pdev );
3239
3323
if (bp -> ptp )
3240
3324
ptp_clock_unregister (bp -> ptp );
3325
+ kfree (bp -> ptp_info .pin_config );
3241
3326
device_unregister (& bp -> dev );
3242
3327
}
3243
3328
0 commit comments