aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/flexcan.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index cc1e0a7b554f..e02337953f41 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -33,6 +33,7 @@
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/list.h> 34#include <linux/list.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/of.h>
36#include <linux/platform_device.h> 37#include <linux/platform_device.h>
37 38
38#define DRV_NAME "flexcan" 39#define DRV_NAME "flexcan"
@@ -925,16 +926,29 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
925 struct net_device *dev; 926 struct net_device *dev;
926 struct flexcan_priv *priv; 927 struct flexcan_priv *priv;
927 struct resource *mem; 928 struct resource *mem;
928 struct clk *clk; 929 struct clk *clk = NULL;
929 void __iomem *base; 930 void __iomem *base;
930 resource_size_t mem_size; 931 resource_size_t mem_size;
931 int err, irq; 932 int err, irq;
933 u32 clock_freq = 0;
934
935 if (pdev->dev.of_node) {
936 const u32 *clock_freq_p;
932 937
933 clk = clk_get(&pdev->dev, NULL); 938 clock_freq_p = of_get_property(pdev->dev.of_node,
934 if (IS_ERR(clk)) { 939 "clock-frequency", NULL);
935 dev_err(&pdev->dev, "no clock defined\n"); 940 if (clock_freq_p)
936 err = PTR_ERR(clk); 941 clock_freq = *clock_freq_p;
937 goto failed_clock; 942 }
943
944 if (!clock_freq) {
945 clk = clk_get(&pdev->dev, NULL);
946 if (IS_ERR(clk)) {
947 dev_err(&pdev->dev, "no clock defined\n");
948 err = PTR_ERR(clk);
949 goto failed_clock;
950 }
951 clock_freq = clk_get_rate(clk);
938 } 952 }
939 953
940 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 954 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -967,7 +981,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
967 dev->flags |= IFF_ECHO; /* we support local echo in hardware */ 981 dev->flags |= IFF_ECHO; /* we support local echo in hardware */
968 982
969 priv = netdev_priv(dev); 983 priv = netdev_priv(dev);
970 priv->can.clock.freq = clk_get_rate(clk); 984 priv->can.clock.freq = clock_freq;
971 priv->can.bittiming_const = &flexcan_bittiming_const; 985 priv->can.bittiming_const = &flexcan_bittiming_const;
972 priv->can.do_set_mode = flexcan_set_mode; 986 priv->can.do_set_mode = flexcan_set_mode;
973 priv->can.do_get_berr_counter = flexcan_get_berr_counter; 987 priv->can.do_get_berr_counter = flexcan_get_berr_counter;
@@ -1002,7 +1016,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
1002 failed_map: 1016 failed_map:
1003 release_mem_region(mem->start, mem_size); 1017 release_mem_region(mem->start, mem_size);
1004 failed_get: 1018 failed_get:
1005 clk_put(clk); 1019 if (clk)
1020 clk_put(clk);
1006 failed_clock: 1021 failed_clock:
1007 return err; 1022 return err;
1008} 1023}
@@ -1020,7 +1035,8 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
1020 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1035 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1021 release_mem_region(mem->start, resource_size(mem)); 1036 release_mem_region(mem->start, resource_size(mem));
1022 1037
1023 clk_put(priv->clk); 1038 if (priv->clk)
1039 clk_put(priv->clk);
1024 1040
1025 free_candev(dev); 1041 free_candev(dev);
1026 1042