Yes, the source is in fexcan.c, but I'm looking for the function/file calling "flexcan_core()". It must be somewhere under arch/powerpc. Sorry for confusion.
Thanks. Wolfgang.
/* * flexcan_iface.c * * Author: Bhaskar upadhaya <[email protected]> * Copyright 2011 Freescale Semiconductor, Inc. * * Based on code originally by Andrey Volkov <[email protected]> * * LICENCE: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include <linux/can/platform/flexcan.h> struct flexcan_interface flexcan_cb; #ifdef CONFIG_FLEXCAN_OF static unsigned long flexcan_get_clk_rate(struct clk *clock) { return clock->rate; } static void flexcan_clk_put(struct clk *clk) { kfree(clk); } static struct clk *flexcan_clk_get(struct device *dev, const char *id) { struct clk *clock; u32 *clock_freq = NULL; u32 *clock_divider = NULL; int err; clock = kmalloc(sizeof(struct clk), GFP_KERNEL); if (!clock) { dev_err(dev, "Cannot allocate memory\n"); err = -ENOMEM; goto failed_clock; } clock_freq = (u32 *) of_get_property(dev->of_node, "clock_freq", NULL); if (clock_freq == NULL) { dev_err(dev, "Cannot find clock_freq property\n"); err = -EINVAL; kfree(clock); goto failed_clock; } clock_divider = (u32 *) of_get_property(dev->of_node, \ "fsl,flexcan-clock-divider", NULL); if (clock_divider == NULL) { dev_err(dev, "Cannot find fsl,flexcan-clock-divider \ property\n"); err = -EINVAL; kfree(clock); goto failed_clock; } clock->rate = DIV_ROUND(*clock_freq / *clock_divider, 1000) * 1000; DBG(KERN_INFO "clock-frequency is %lu in line %d in function %s \r\n", clock->rate, __LINE__, __func__); return clock; failed_clock: return ERR_PTR(err); } static void flexcan_of_resource_init(struct flexcan_interface *flexcan_cb) { flexcan_cb->read = flexcan_read; flexcan_cb->write = flexcan_write; flexcan_cb->clk_enable = NULL; flexcan_cb->clk_disable = NULL; flexcan_cb->clk_get_rate = flexcan_get_clk_rate; flexcan_cb->clk_get = flexcan_clk_get; flexcan_cb->clk_put = flexcan_clk_put; } static int flexcan_of_probe(struct of_device *ofdev, const struct of_device_id *match) { u64 addr, size; int err, irq; struct flexcan_resource flexcan_res; addr = of_translate_address(ofdev->dev.of_node, of_get_address(ofdev->dev.of_node, 0, &size, NULL)); flexcan_res.addr = addr; flexcan_res.size = size; flexcan_res.drv_name = ofdev->dev.driver->name; irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (irq == NO_IRQ) { dev_err(&ofdev->dev, "cannot map to irq\n"); err = -EINVAL; goto failed_req; } flexcan_res.irq = irq; flexcan_of_resource_init(&flexcan_cb); err = flexcan_core(&ofdev->dev, flexcan_res, &flexcan_cb); if (err) { dev_err(&ofdev->dev, "Flexcan Initialization failed with err \ %d\n", err); err = -EINVAL; goto failed_req; } return 0; failed_req: return err; } static int flexcan_of_remove(struct of_device *ofdev) { struct net_device *dev = dev_get_drvdata(&ofdev->dev); struct flexcan_priv *priv = netdev_priv(dev); u64 addr, size; unregister_flexcandev(dev); dev_set_drvdata(&ofdev->dev, NULL); iounmap(priv->base); addr = of_translate_address(ofdev->dev.of_node, of_get_address(ofdev->dev.of_node, 0, &size, NULL)); release_mem_region(addr, size); free_candev(dev); return 0; } static struct of_device_id flexcan_match[] = { { .compatible = "fsl,flexcan-v1.0", }, {}, }; MODULE_DEVICE_TABLE(of, flexcan_match); static struct of_platform_driver flexcan_of_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .of_match_table = flexcan_match, }, .probe = flexcan_of_probe, .remove = flexcan_of_remove, }; #else void flexcan_plt_resource_init(struct flexcan_interface *flexcan_cb) { flexcan_cb->read = readl; flexcan_cb->write = writel; flexcan_cb->clk_enable = clk_enable; flexcan_cb->clk_disable = clk_disable; flexcan_cb->clk_get_rate = clk_get_rate; flexcan_cb->clk_get = clk_get; flexcan_cb->clk_put = clk_put; } static int __devinit flexcan_plt_probe(struct platform_device *pdev) { int err, irq; struct flexcan_resource flexcan_res; resource_size_t mem_size; struct resource *mem; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!mem || irq <= 0) { dev_err(&pdev->dev, "Cannot map to irq\n"); err = -ENODEV; goto failed_get; } mem_size = resource_size(mem); flexcan_res.addr = mem->start; flexcan_res.size = mem_size; flexcan_res.drv_name = pdev->name; flexcan_plt_resource_init(&flexcan_cb); err = flexcan_core(&pdev->dev, flexcan_res, &flexcan_cb); if (err) { dev_err(&pdev->dev, "Flexcan Initialization failed with err \ (%d) \n", err); err = -EINVAL; goto failed_req; } return 0; failed_req: return err; } static int __devexit flexcan_plt_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct flexcan_priv *priv = netdev_priv(dev); struct resource *mem; unregister_flexcandev(dev); platform_set_drvdata(pdev, NULL); iounmap(priv->base); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, resource_size(mem)); clk_put(priv->clk); free_candev(dev); return 0; } static struct platform_driver flexcan_plt_driver = { .driver.name = DRV_NAME, .probe = flexcan_plt_probe, .remove = __devexit_p(flexcan_plt_remove), }; #endif static int __init flexcan_init(void) { pr_info("%s netdevice driver\n", DRV_NAME); #ifdef CONFIG_FLEXCAN_OF return of_register_platform_driver(&flexcan_of_driver); #else return platform_driver_register(&flexcan_plt_driver); #endif } static void __exit flexcan_exit(void) { #ifdef CONFIG_FLEXCAN_OF of_unregister_platform_driver(&flexcan_of_driver); #else platform_driver_unregister(&flexcan_plt_driver); #endif pr_info("%s: driver removed\n", DRV_NAME); } module_init(flexcan_init); module_exit(flexcan_exit); MODULE_AUTHOR("Bhaskar Upadhaya <[email protected]>"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("CAN port driver for flexcan based chip"); _______________________________________________ Socketcan-users mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-users
