This patch adds MPC512x support to mscan. Tested with a phyCORE-MPC5121e and 2.6.31. cansequence ran quite some time successfully.
Note 1: It depends on changes to the clock-implementation of the MPC512x. Those patches need to be discussed and approved on the ppc list and can be found here: http://patchwork.ozlabs.org/patch/37417/ http://patchwork.ozlabs.org/patch/37427/ (If they work for you, I'd be happy about Acked-by-tags.) Note 2: If this approach is accepted, I will next do the remaining cleanup work (giving the functions the proper 5xxx names, ...) as follow up patches to hopefully get this driver into mainline soonish. Signed-off-by: Wolfram Sang <[email protected]> Kconfig | 8 +++--- mscan/mpc52xx_can.c | 64 +++++++++++++++++++++++++++++++++++++++++----------- mscan/mscan.h | 3 +- 3 files changed, 57 insertions(+), 18 deletions(-) Index: Kconfig =================================================================== --- Kconfig (revision 1072) +++ Kconfig (working copy) @@ -234,12 +234,12 @@ the Motorola MC68HC12 Microcontroller Family. config CAN_MPC52XX - tristate "Freescale MPC5200 onboard CAN controller" - depends on CAN_MSCAN && (PPC_MPC52xx || PPC_52xx) + tristate "Freescale MPC5xxx onboard CAN controller" + depends on CAN_MSCAN && (PPC_MPC512x || PPC_MPC52xx || PPC_52xx) default LITE5200 ---help--- - If you say yes here you get support for Freescale MPC5200 - onboard dualCAN controller. + If you say yes here you get support for Freescale MPC5xxx + onboard CAN controller. This driver can also be built as a module. If so, the module will be called mpc52xx_can. Index: mscan/mscan.h =================================================================== --- mscan/mscan.h (revision 1072) +++ mscan/mscan.h (working copy) @@ -52,7 +52,8 @@ #define MSCAN_FOR_MPC5200 #endif -#ifdef MSCAN_FOR_MPC5200 +/* Following block only needed for MPC52xx! */ +#ifdef CONFIG_PPC_MPC52xx #define MSCAN_CLKSRC_BUS 0 #define MSCAN_CLKSRC_XTAL MSCAN_CLKSRC #else Index: mscan/mpc52xx_can.c =================================================================== --- mscan/mpc52xx_can.c (revision 1072) +++ mscan/mpc52xx_can.c (working copy) @@ -4,6 +4,7 @@ * Copyright (C) 2004-2005 Andrey Volkov <[email protected]>, * Varma Electronics Oy * Copyright (C) 2008-2009 Wolfgang Grandegger <[email protected]> + * Copyright (C) 2009 Wolfram Sang <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the version 2 of the GNU General Public License @@ -28,6 +29,7 @@ #include <socketcan/can/dev.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) #include <linux/of_platform.h> +#include <linux/clk.h> #include <sysdev/fsl_soc.h> #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) @@ -260,19 +262,53 @@ /* * Get the frequency of the external oscillator clock connected - * to the SYS_XTAL_IN pin, or retrun 0 if it cannot be determined. + * to the SYS_XTAL_IN pin, or return 0 if it cannot be determined. */ -static unsigned int __devinit mpc52xx_can_xtal_freq(struct device_node *np) + +#define CLK_NAME_SIZE 14 + +static unsigned int __devinit mpc512x_can_clock_freq(struct of_device *ofdev, + int clock_src) { + struct clk *mscan_clk, *port_clk; + char clk_name[CLK_NAME_SIZE]; + const u32 *cellp; + + cellp = of_get_property(ofdev->node, "cell-index", NULL); + if (!cellp) + return 0; + + mscan_clk = clk_get(NULL, "mscan_clk"); + if (!mscan_clk) { + dev_err(&ofdev->dev, "can't get mscan clock!\n"); + return 0; + } + clk_enable(mscan_clk); + + if (clock_src == MSCAN_CLKSRC_BUS) + return mpc5xxx_get_bus_frequency(ofdev->node); + + /* Do we have a port clock (Chip Rev2 and later) */ + snprintf(clk_name, CLK_NAME_SIZE, "mscan%d_clk", *cellp); + port_clk = clk_get(&ofdev->dev, clk_name); + + if (port_clk) + return clk_get_rate(port_clk); + else + return clk_get_rate(mscan_clk); +} + +static unsigned int __devinit mpc52xx_can_xtal_freq(struct of_device *ofdev) +{ struct mpc52xx_cdm __iomem *cdm; struct device_node *np_cdm; unsigned int freq; u32 val; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) - freq = mpc52xx_find_ipb_freq(np); + freq = mpc52xx_find_ipb_freq(ofdev->node); #else - freq = mpc5xxx_get_bus_frequency(np); + freq = mpc5xxx_get_bus_frequency(ofdev->node); #endif if (!freq) return 0; @@ -284,7 +320,7 @@ cdm = of_iomap(np_cdm, 0); of_node_put(np_cdm); if (!np_cdm) { - printk(KERN_ERR "%s() failed abnormally\n", __func__); + dev_err(&ofdev->dev, "couldn't find clock!"); return 0; } @@ -314,22 +350,21 @@ * bug, it can not be selected for the old MPC5200 Rev. A chips. */ -static unsigned int __devinit mpc52xx_can_clock_freq(struct device_node *np, +static unsigned int __devinit mpc52xx_can_clock_freq(struct of_device *ofdev, int clock_src) { unsigned int pvr; - pvr = mfspr(SPRN_PVR); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011) - return mpc52xx_find_ipb_freq(np); + return mpc52xx_find_ipb_freq(ofdev->node); #else if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011) - return mpc5xxx_get_bus_frequency(np); + return mpc5xxx_get_bus_frequency(ofdev->node); #endif - return mpc52xx_can_xtal_freq(np); + return mpc52xx_can_xtal_freq(ofdev); } static int __devinit mpc52xx_can_probe(struct of_device *ofdev, @@ -340,6 +375,7 @@ struct can_priv *priv; struct resource res; void __iomem *base; + unsigned int (*can_clock)(struct of_device *, int) = id->data; int err, irq, res_size, clock_src; err = of_address_to_resource(np, 0, &res); @@ -393,7 +429,8 @@ clock_src = MSCAN_CLKSRC_BUS; else clock_src = MSCAN_CLKSRC_XTAL; - priv->clock.freq = mpc52xx_can_clock_freq(np, clock_src); + + priv->clock.freq = can_clock(ofdev, clock_src); if (!priv->clock.freq) { dev_err(&ofdev->dev, "couldn't get MSCAN clock frequency\n"); err = -ENODEV; @@ -488,8 +525,9 @@ #endif static struct of_device_id __devinitdata mpc52xx_can_table[] = { - {.compatible = "fsl,mpc5200-mscan"}, - {.compatible = "fsl,mpc5200b-mscan"}, + { .compatible = "fsl,mpc5200-mscan", .data = mpc52xx_can_clock_freq }, + { .compatible = "fsl,mpc5200b-mscan", .data = mpc52xx_can_clock_freq }, + { .compatible = "fsl,mpc5121-mscan", .data = mpc512x_can_clock_freq }, {}, }; _______________________________________________ Socketcan-core mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-core
