mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-11 11:56:48 +00:00
flexcan: Prefer device tree clock frequency if available.
If our CAN device's device tree node has a clock-frequency property, then use that value for the can devices clock frequency. If not, fall back to asking the platform/mach code for the clock frequency associated with the flexcan device. Signed-off-by: Robin Holt <holt@sgi.com> Acked-by: Wolfgang Grandegger <wg@grandegger.com>, Cc: Kumar Gala <galak@kernel.crashing.org> Cc: Marc Kleine-Budde <mkl@pengutronix.de>, Cc: U Bhaskar-B22300 <B22300@freescale.com> Cc: Scott Wood <scottwood@freescale.com> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: socketcan-core@lists.berlios.de, Cc: netdev@vger.kernel.org, Cc: PPC list <linuxppc-dev@lists.ozlabs.org> Cc: devicetree-discuss@lists.ozlabs.org Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c8aef4cb78
commit
97efe9aef1
@ -11,6 +11,7 @@ Required properties:
|
|||||||
|
|
||||||
- reg : Offset and length of the register set for this device
|
- reg : Offset and length of the register set for this device
|
||||||
- interrupts : Interrupt tuple for this device
|
- interrupts : Interrupt tuple for this device
|
||||||
|
- clock-frequency : The oscillator frequency driving the flexcan device
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -19,4 +20,5 @@ Example:
|
|||||||
reg = <0x1c000 0x1000>;
|
reg = <0x1c000 0x1000>;
|
||||||
interrupts = <48 0x2>;
|
interrupts = <48 0x2>;
|
||||||
interrupt-parent = <&mpic>;
|
interrupt-parent = <&mpic>;
|
||||||
|
clock-frequency = <200000000>; // filled in by bootloader
|
||||||
};
|
};
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#define DRV_NAME "flexcan"
|
#define DRV_NAME "flexcan"
|
||||||
@ -925,16 +926,29 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct flexcan_priv *priv;
|
struct flexcan_priv *priv;
|
||||||
struct resource *mem;
|
struct resource *mem;
|
||||||
struct clk *clk;
|
struct clk *clk = NULL;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
resource_size_t mem_size;
|
resource_size_t mem_size;
|
||||||
int err, irq;
|
int err, irq;
|
||||||
|
u32 clock_freq = 0;
|
||||||
|
|
||||||
clk = clk_get(&pdev->dev, NULL);
|
if (pdev->dev.of_node) {
|
||||||
if (IS_ERR(clk)) {
|
const u32 *clock_freq_p;
|
||||||
dev_err(&pdev->dev, "no clock defined\n");
|
|
||||||
err = PTR_ERR(clk);
|
clock_freq_p = of_get_property(pdev->dev.of_node,
|
||||||
goto failed_clock;
|
"clock-frequency", NULL);
|
||||||
|
if (clock_freq_p)
|
||||||
|
clock_freq = *clock_freq_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clock_freq) {
|
||||||
|
clk = clk_get(&pdev->dev, NULL);
|
||||||
|
if (IS_ERR(clk)) {
|
||||||
|
dev_err(&pdev->dev, "no clock defined\n");
|
||||||
|
err = PTR_ERR(clk);
|
||||||
|
goto failed_clock;
|
||||||
|
}
|
||||||
|
clock_freq = clk_get_rate(clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
@ -967,7 +981,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
|
|||||||
dev->flags |= IFF_ECHO; /* we support local echo in hardware */
|
dev->flags |= IFF_ECHO; /* we support local echo in hardware */
|
||||||
|
|
||||||
priv = netdev_priv(dev);
|
priv = netdev_priv(dev);
|
||||||
priv->can.clock.freq = clk_get_rate(clk);
|
priv->can.clock.freq = clock_freq;
|
||||||
priv->can.bittiming_const = &flexcan_bittiming_const;
|
priv->can.bittiming_const = &flexcan_bittiming_const;
|
||||||
priv->can.do_set_mode = flexcan_set_mode;
|
priv->can.do_set_mode = flexcan_set_mode;
|
||||||
priv->can.do_get_berr_counter = flexcan_get_berr_counter;
|
priv->can.do_get_berr_counter = flexcan_get_berr_counter;
|
||||||
@ -1002,7 +1016,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
|
|||||||
failed_map:
|
failed_map:
|
||||||
release_mem_region(mem->start, mem_size);
|
release_mem_region(mem->start, mem_size);
|
||||||
failed_get:
|
failed_get:
|
||||||
clk_put(clk);
|
if (clk)
|
||||||
|
clk_put(clk);
|
||||||
failed_clock:
|
failed_clock:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -1020,7 +1035,8 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
|
|||||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
release_mem_region(mem->start, resource_size(mem));
|
release_mem_region(mem->start, resource_size(mem));
|
||||||
|
|
||||||
clk_put(priv->clk);
|
if (priv->clk)
|
||||||
|
clk_put(priv->clk);
|
||||||
|
|
||||||
free_candev(dev);
|
free_candev(dev);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user