@@ -87,6 +87,7 @@ struct rcar_can_priv {
87
87
struct napi_struct napi ;
88
88
struct rcar_can_regs __iomem * regs ;
89
89
struct clk * clk ;
90
+ struct clk * can_clk ;
90
91
u8 tx_dlc [RCAR_CAN_FIFO_DEPTH ];
91
92
u32 tx_head ;
92
93
u32 tx_tail ;
@@ -505,14 +506,20 @@ static int rcar_can_open(struct net_device *ndev)
505
506
506
507
err = clk_prepare_enable (priv -> clk );
507
508
if (err ) {
508
- netdev_err (ndev , "clk_prepare_enable() failed, error %d\n" ,
509
+ netdev_err (ndev , "failed to enable periperal clock , error %d\n" ,
509
510
err );
510
511
goto out ;
511
512
}
513
+ err = clk_prepare_enable (priv -> can_clk );
514
+ if (err ) {
515
+ netdev_err (ndev , "failed to enable CAN clock, error %d\n" ,
516
+ err );
517
+ goto out_clock ;
518
+ }
512
519
err = open_candev (ndev );
513
520
if (err ) {
514
521
netdev_err (ndev , "open_candev() failed, error %d\n" , err );
515
- goto out_clock ;
522
+ goto out_can_clock ;
516
523
}
517
524
napi_enable (& priv -> napi );
518
525
err = request_irq (ndev -> irq , rcar_can_interrupt , 0 , ndev -> name , ndev );
@@ -527,6 +534,8 @@ static int rcar_can_open(struct net_device *ndev)
527
534
out_close :
528
535
napi_disable (& priv -> napi );
529
536
close_candev (ndev );
537
+ out_can_clock :
538
+ clk_disable_unprepare (priv -> can_clk );
530
539
out_clock :
531
540
clk_disable_unprepare (priv -> clk );
532
541
out :
@@ -565,6 +574,7 @@ static int rcar_can_close(struct net_device *ndev)
565
574
rcar_can_stop (ndev );
566
575
free_irq (ndev -> irq , ndev );
567
576
napi_disable (& priv -> napi );
577
+ clk_disable_unprepare (priv -> can_clk );
568
578
clk_disable_unprepare (priv -> clk );
569
579
close_candev (ndev );
570
580
can_led_event (ndev , CAN_LED_EVENT_STOP );
@@ -715,13 +725,20 @@ static int rcar_can_get_berr_counter(const struct net_device *dev,
715
725
return 0 ;
716
726
}
717
727
728
+ static const char * const clock_names [] = {
729
+ [CLKR_CLKP1 ] = "clkp1" ,
730
+ [CLKR_CLKP2 ] = "clkp2" ,
731
+ [CLKR_CLKEXT ] = "can_clk" ,
732
+ };
733
+
718
734
static int rcar_can_probe (struct platform_device * pdev )
719
735
{
720
736
struct rcar_can_platform_data * pdata ;
721
737
struct rcar_can_priv * priv ;
722
738
struct net_device * ndev ;
723
739
struct resource * mem ;
724
740
void __iomem * addr ;
741
+ u32 clock_select ;
725
742
int err = - ENODEV ;
726
743
int irq ;
727
744
@@ -730,6 +747,7 @@ static int rcar_can_probe(struct platform_device *pdev)
730
747
dev_err (& pdev -> dev , "No platform data provided!\n" );
731
748
goto fail ;
732
749
}
750
+ clock_select = pdata -> clock_select ;
733
751
734
752
irq = platform_get_irq (pdev , 0 );
735
753
if (!irq ) {
@@ -753,10 +771,22 @@ static int rcar_can_probe(struct platform_device *pdev)
753
771
754
772
priv = netdev_priv (ndev );
755
773
756
- priv -> clk = devm_clk_get (& pdev -> dev , NULL );
774
+ priv -> clk = devm_clk_get (& pdev -> dev , "clkp1" );
757
775
if (IS_ERR (priv -> clk )) {
758
776
err = PTR_ERR (priv -> clk );
759
- dev_err (& pdev -> dev , "cannot get clock: %d\n" , err );
777
+ dev_err (& pdev -> dev , "cannot get peripheral clock: %d\n" , err );
778
+ goto fail_clk ;
779
+ }
780
+
781
+ if (clock_select >= ARRAY_SIZE (clock_names )) {
782
+ err = - EINVAL ;
783
+ dev_err (& pdev -> dev , "invalid CAN clock selected\n" );
784
+ goto fail_clk ;
785
+ }
786
+ priv -> can_clk = devm_clk_get (& pdev -> dev , clock_names [clock_select ]);
787
+ if (IS_ERR (priv -> can_clk )) {
788
+ err = PTR_ERR (priv -> can_clk );
789
+ dev_err (& pdev -> dev , "cannot get CAN clock: %d\n" , err );
760
790
goto fail_clk ;
761
791
}
762
792
@@ -765,8 +795,8 @@ static int rcar_can_probe(struct platform_device *pdev)
765
795
ndev -> flags |= IFF_ECHO ;
766
796
priv -> ndev = ndev ;
767
797
priv -> regs = addr ;
768
- priv -> clock_select = pdata -> clock_select ;
769
- priv -> can .clock .freq = clk_get_rate (priv -> clk );
798
+ priv -> clock_select = clock_select ;
799
+ priv -> can .clock .freq = clk_get_rate (priv -> can_clk );
770
800
priv -> can .bittiming_const = & rcar_can_bittiming_const ;
771
801
priv -> can .do_set_mode = rcar_can_do_set_mode ;
772
802
priv -> can .do_get_berr_counter = rcar_can_get_berr_counter ;
0 commit comments