aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2012-07-17 10:14:34 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2012-07-20 06:31:05 -0400
commit3d42a379b6fa5b46058e3302b1802b29f64865bb (patch)
tree4ff43bb4e81c80ee5e52f41e35ac94bd828bbe31
parent194b9a4cb91713ddb60c9f98f7212f6d8cb8e05f (diff)
can: flexcan: add 2nd clock to support imx53 and newer
This patch adds support for a second clock to the flexcan driver. On modern freescale ARM cores like the imx53 and imx6q two clocks ("ipg" and "per") must be enabled in order to access the CAN core. In the original driver, the clock was requested without specifying the connection id, further all mainline ARM archs with flexcan support (imx28, imx25, imx35) register their flexcan clock without a connection id, too. This patch first renames the existing clk variable to clk_ipg and converts it to devm for easier error handling. The connection id "ipg" is added to the devm_clk_get() call. Then a second clock "per" is requested. As all archs don't specify a connection id, both clk_get return the same clock. This ensures compatibility to existing flexcan support and adds support for imx53 at the same time. After this patch hits mainline, the archs may give their existing flexcan clock the "ipg" connection id and implement a dummy "per" clock. This patch has been tested on imx28 (unmodified clk tree) and on imx53 with a seperate "ipg" and "per" clock. Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Acked-by: Hui Wang <jason77.wang@gmail.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--drivers/net/can/flexcan.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index c8a6fc72606d..c5f143165f80 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -190,7 +190,8 @@ struct flexcan_priv {
190 u32 reg_esr; 190 u32 reg_esr;
191 u32 reg_ctrl_default; 191 u32 reg_ctrl_default;
192 192
193 struct clk *clk; 193 struct clk *clk_ipg;
194 struct clk *clk_per;
194 struct flexcan_platform_data *pdata; 195 struct flexcan_platform_data *pdata;
195 const struct flexcan_devtype_data *devtype_data; 196 const struct flexcan_devtype_data *devtype_data;
196}; 197};
@@ -828,7 +829,8 @@ static int flexcan_open(struct net_device *dev)
828 struct flexcan_priv *priv = netdev_priv(dev); 829 struct flexcan_priv *priv = netdev_priv(dev);
829 int err; 830 int err;
830 831
831 clk_prepare_enable(priv->clk); 832 clk_prepare_enable(priv->clk_ipg);
833 clk_prepare_enable(priv->clk_per);
832 834
833 err = open_candev(dev); 835 err = open_candev(dev);
834 if (err) 836 if (err)
@@ -850,7 +852,8 @@ static int flexcan_open(struct net_device *dev)
850 out_close: 852 out_close:
851 close_candev(dev); 853 close_candev(dev);
852 out: 854 out:
853 clk_disable_unprepare(priv->clk); 855 clk_disable_unprepare(priv->clk_per);
856 clk_disable_unprepare(priv->clk_ipg);
854 857
855 return err; 858 return err;
856} 859}
@@ -864,7 +867,8 @@ static int flexcan_close(struct net_device *dev)
864 flexcan_chip_stop(dev); 867 flexcan_chip_stop(dev);
865 868
866 free_irq(dev->irq, dev); 869 free_irq(dev->irq, dev);
867 clk_disable_unprepare(priv->clk); 870 clk_disable_unprepare(priv->clk_per);
871 clk_disable_unprepare(priv->clk_ipg);
868 872
869 close_candev(dev); 873 close_candev(dev);
870 874
@@ -903,7 +907,8 @@ static int __devinit register_flexcandev(struct net_device *dev)
903 struct flexcan_regs __iomem *regs = priv->base; 907 struct flexcan_regs __iomem *regs = priv->base;
904 u32 reg, err; 908 u32 reg, err;
905 909
906 clk_prepare_enable(priv->clk); 910 clk_prepare_enable(priv->clk_ipg);
911 clk_prepare_enable(priv->clk_per);
907 912
908 /* select "bus clock", chip must be disabled */ 913 /* select "bus clock", chip must be disabled */
909 flexcan_chip_disable(priv); 914 flexcan_chip_disable(priv);
@@ -936,7 +941,8 @@ static int __devinit register_flexcandev(struct net_device *dev)
936 out: 941 out:
937 /* disable core and turn off clocks */ 942 /* disable core and turn off clocks */
938 flexcan_chip_disable(priv); 943 flexcan_chip_disable(priv);
939 clk_disable_unprepare(priv->clk); 944 clk_disable_unprepare(priv->clk_per);
945 clk_disable_unprepare(priv->clk_ipg);
940 946
941 return err; 947 return err;
942} 948}
@@ -964,7 +970,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
964 struct net_device *dev; 970 struct net_device *dev;
965 struct flexcan_priv *priv; 971 struct flexcan_priv *priv;
966 struct resource *mem; 972 struct resource *mem;
967 struct clk *clk = NULL; 973 struct clk *clk_ipg = NULL, *clk_per = NULL;
968 struct pinctrl *pinctrl; 974 struct pinctrl *pinctrl;
969 void __iomem *base; 975 void __iomem *base;
970 resource_size_t mem_size; 976 resource_size_t mem_size;
@@ -980,13 +986,20 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
980 "clock-frequency", &clock_freq); 986 "clock-frequency", &clock_freq);
981 987
982 if (!clock_freq) { 988 if (!clock_freq) {
983 clk = clk_get(&pdev->dev, NULL); 989 clk_ipg = devm_clk_get(&pdev->dev, "ipg");
984 if (IS_ERR(clk)) { 990 if (IS_ERR(clk_ipg)) {
985 dev_err(&pdev->dev, "no clock defined\n"); 991 dev_err(&pdev->dev, "no ipg clock defined\n");
986 err = PTR_ERR(clk); 992 err = PTR_ERR(clk_ipg);
993 goto failed_clock;
994 }
995 clock_freq = clk_get_rate(clk_ipg);
996
997 clk_per = devm_clk_get(&pdev->dev, "per");
998 if (IS_ERR(clk_per)) {
999 dev_err(&pdev->dev, "no per clock defined\n");
1000 err = PTR_ERR(clk_per);
987 goto failed_clock; 1001 goto failed_clock;
988 } 1002 }
989 clock_freq = clk_get_rate(clk);
990 } 1003 }
991 1004
992 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1005 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1039,7 +1052,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
1039 CAN_CTRLMODE_BERR_REPORTING; 1052 CAN_CTRLMODE_BERR_REPORTING;
1040 priv->base = base; 1053 priv->base = base;
1041 priv->dev = dev; 1054 priv->dev = dev;
1042 priv->clk = clk; 1055 priv->clk_ipg = clk_ipg;
1056 priv->clk_per = clk_per;
1043 priv->pdata = pdev->dev.platform_data; 1057 priv->pdata = pdev->dev.platform_data;
1044 priv->devtype_data = devtype_data; 1058 priv->devtype_data = devtype_data;
1045 1059
@@ -1067,8 +1081,6 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
1067 failed_map: 1081 failed_map:
1068 release_mem_region(mem->start, mem_size); 1082 release_mem_region(mem->start, mem_size);
1069 failed_get: 1083 failed_get:
1070 if (clk)
1071 clk_put(clk);
1072 failed_clock: 1084 failed_clock:
1073 return err; 1085 return err;
1074} 1086}
@@ -1086,9 +1098,6 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
1086 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1098 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1087 release_mem_region(mem->start, resource_size(mem)); 1099 release_mem_region(mem->start, resource_size(mem));
1088 1100
1089 if (priv->clk)
1090 clk_put(priv->clk);
1091
1092 free_candev(dev); 1101 free_candev(dev);
1093 1102
1094 return 0; 1103 return 0;