Skip to content

Commit 862e2b6

Browse files
Sergei Shtylyovmarckleinebudde
authored andcommitted
can: rcar_can: support all input clocks
When writing the driver, I didn't give enough attention to the possible sources of the CAN clock: although the value of the CLKR register was specified by the platform data, the driver only handled one case, that is CAN clock being sourced from the clkp1 clock, the same that clocks the whole CAN module. In order to fix that overlook, we'll have to handle the CAN clock separately from the peripheral clock (however, clkp1 will be specified for a CAN device only once)... Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent e0d1f48 commit 862e2b6

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

drivers/net/can/rcar_can.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct rcar_can_priv {
8787
struct napi_struct napi;
8888
struct rcar_can_regs __iomem *regs;
8989
struct clk *clk;
90+
struct clk *can_clk;
9091
u8 tx_dlc[RCAR_CAN_FIFO_DEPTH];
9192
u32 tx_head;
9293
u32 tx_tail;
@@ -505,14 +506,20 @@ static int rcar_can_open(struct net_device *ndev)
505506

506507
err = clk_prepare_enable(priv->clk);
507508
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",
509510
err);
510511
goto out;
511512
}
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+
}
512519
err = open_candev(ndev);
513520
if (err) {
514521
netdev_err(ndev, "open_candev() failed, error %d\n", err);
515-
goto out_clock;
522+
goto out_can_clock;
516523
}
517524
napi_enable(&priv->napi);
518525
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)
527534
out_close:
528535
napi_disable(&priv->napi);
529536
close_candev(ndev);
537+
out_can_clock:
538+
clk_disable_unprepare(priv->can_clk);
530539
out_clock:
531540
clk_disable_unprepare(priv->clk);
532541
out:
@@ -565,6 +574,7 @@ static int rcar_can_close(struct net_device *ndev)
565574
rcar_can_stop(ndev);
566575
free_irq(ndev->irq, ndev);
567576
napi_disable(&priv->napi);
577+
clk_disable_unprepare(priv->can_clk);
568578
clk_disable_unprepare(priv->clk);
569579
close_candev(ndev);
570580
can_led_event(ndev, CAN_LED_EVENT_STOP);
@@ -715,13 +725,20 @@ static int rcar_can_get_berr_counter(const struct net_device *dev,
715725
return 0;
716726
}
717727

728+
static const char * const clock_names[] = {
729+
[CLKR_CLKP1] = "clkp1",
730+
[CLKR_CLKP2] = "clkp2",
731+
[CLKR_CLKEXT] = "can_clk",
732+
};
733+
718734
static int rcar_can_probe(struct platform_device *pdev)
719735
{
720736
struct rcar_can_platform_data *pdata;
721737
struct rcar_can_priv *priv;
722738
struct net_device *ndev;
723739
struct resource *mem;
724740
void __iomem *addr;
741+
u32 clock_select;
725742
int err = -ENODEV;
726743
int irq;
727744

@@ -730,6 +747,7 @@ static int rcar_can_probe(struct platform_device *pdev)
730747
dev_err(&pdev->dev, "No platform data provided!\n");
731748
goto fail;
732749
}
750+
clock_select = pdata->clock_select;
733751

734752
irq = platform_get_irq(pdev, 0);
735753
if (!irq) {
@@ -753,10 +771,22 @@ static int rcar_can_probe(struct platform_device *pdev)
753771

754772
priv = netdev_priv(ndev);
755773

756-
priv->clk = devm_clk_get(&pdev->dev, NULL);
774+
priv->clk = devm_clk_get(&pdev->dev, "clkp1");
757775
if (IS_ERR(priv->clk)) {
758776
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);
760790
goto fail_clk;
761791
}
762792

@@ -765,8 +795,8 @@ static int rcar_can_probe(struct platform_device *pdev)
765795
ndev->flags |= IFF_ECHO;
766796
priv->ndev = ndev;
767797
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);
770800
priv->can.bittiming_const = &rcar_can_bittiming_const;
771801
priv->can.do_set_mode = rcar_can_do_set_mode;
772802
priv->can.do_get_berr_counter = rcar_can_get_berr_counter;

0 commit comments

Comments
 (0)