can: flexcan: add platform data header
PATCH v3 1/5 can: flexcan: add platform data header
Add platform data header for flexcan.
---
Changes for v2:
- move header file in more proper location
- remove irq defines
- change variable types to match driver types
Changes for v3:
- rename to more generic flexcan.h
- reorder struct fields to avoid paddings
- remove unused big_endian
--- include/linux/can/platform/flexcan.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 include/linux/can/platform/flexcan.h
include/linux/can/platform/flexcan.h new file +25 -0
@@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (C) 2021 Angelo Dureghello <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* 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. +*/ + +#ifndef _PLAT_FLEXCAN_H +#define _PLAT_FLEXCAN_H + +struct mcf_flexcan_platform_data { +u32 clock_frequency; +u8 clk_src; +}; + +#define FLEXCAN_MCF5411X_MB_CNT_MCF 16 + +#endif /* _PLAT_FLEXCAN_H */
Signature · 1 line
2.31.1
PATCH v3 2/5 m68k: stmark2: update board setup
Add configuration for flexcan pads.
---
Changes for v2:
none
Changes for v3:
none
--- arch/m68k/coldfire/stmark2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/m68k/coldfire/stmark2.c +4 -2
@@ -111,7 +111,9 @@ static int __init init_stmark2(void)__raw_writeb (0x00 ,MCFGPIO_PAR_BE );__raw_writeb (0x00 ,MCFGPIO_PAR_FBCTL );__raw_writeb (0x00 ,MCFGPIO_PAR_CS ); -__raw_writeb (0x00 ,MCFGPIO_PAR_CANI2C ); + +/* CAN pads */ +__raw_writeb (0x50 ,MCFGPIO_PAR_CANI2C );platform_add_devices (stmark2_devices,ARRAY_SIZE (stmark2_devices));
@@ -121,4 +123,4 @@ static int __init init_stmark2(void)return 0 ; } -late_initcall (init_stmark2); +device_initcall (init_stmark2);
Signature · 1 line
2.31.1
PATCH v3 3/5 m68k: m5441x: add flexcan support
In reply to Angelo DureghelloAdd flexcan support.
---
Changes for v2:
- add irq resources for ERR and BOFF interrutps Changes for v3:
- differentiate device name, for future variants addition
--- arch/m68k/coldfire/device.c | 42 +++++++++++++++++++++++++++++++ arch/m68k/coldfire/m5441x.c | 8 +++--- arch/m68k/include/asm/m5441xsim.h | 19 ++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-)
arch/m68k/coldfire/device.c +42 -0
@@ -23,6 +23,7 @@#include <linux/platform_data/edma.h> #include <linux/platform_data/dma-mcf-edma.h> #include <linux/platform_data/mmc-esdhc-mcf.h> +#include <linux/can/platform/flexcan.h> /* * All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
@@ -581,6 +582,44 @@ static struct platform_device mcf_esdhc = { };#endif /* MCFSDHC_BASE */ +#if IS_ENABLED (CONFIG_CAN ) +static struct mcf_flexcan_platform_data mcf5441x_flexcan_info = { + .clk_src =1 , + .clock_frequency =120000000 , +}; + +static struct resource mcf5441x_flexcan0_resource[] = { + { + .start =MCFFLEXCAN_BASE0 , + .end =MCFFLEXCAN_BASE0 +MCFFLEXCAN_SIZE , + .flags =IORESOURCE_MEM , + }, + { + .start =MCF_IRQ_IFL0 , + .end =MCF_IRQ_IFL0 , + .flags =IORESOURCE_IRQ , + }, + { + .start =MCF_IRQ_BOFF0 , + .end =MCF_IRQ_BOFF0 , + .flags =IORESOURCE_IRQ , + }, + { + .start =MCF_IRQ_ERR0 , + .end =MCF_IRQ_ERR0 , + .flags =IORESOURCE_IRQ , + }, +}; + +static struct platform_device mcf_flexcan0 = { + .name ="flexcan-mcf5441x" , + .id =0 , + .num_resources =ARRAY_SIZE (mcf5441x_flexcan0_resource), + .resource = mcf5441x_flexcan0_resource, + .dev.platform_data = &mcf5441x_flexcan_info, +}; +#endif /* IS_ENABLED(CONFIG_CAN) */ +static struct platform_device *mcf_devices[]__initdata = { &mcf_uart, #if IS_ENABLED(CONFIG_FEC)
@@ -616,6 +655,9 @@ static struct platform_device *mcf_devices[] __initdata = {#ifdef MCFSDHC_BASE &mcf_esdhc,#endif +#if IS_ENABLED (CONFIG_CAN ) + &mcf_flexcan0, +#endif };/*
arch/m68k/coldfire/m5441x.c +4 -4
@@ -18,8 +18,8 @@#include <asm/mcfclk.h> DEFINE_CLK (0 ,"flexbus" ,2 ,MCF_CLK ); -DEFINE_CLK (0 ,"mcfcan.0" ,8 ,MCF_CLK ); -DEFINE_CLK (0 ,"mcfcan.1" ,9 ,MCF_CLK ); +DEFINE_CLK (0 ,"flexcan.0" ,8 ,MCF_CLK ); +DEFINE_CLK (0 ,"flexcan.1" ,9 ,MCF_CLK );DEFINE_CLK (0 ,"imx1-i2c.1" ,14 ,MCF_CLK );DEFINE_CLK (0 ,"mcfdspi.1" ,15 ,MCF_CLK );DEFINE_CLK (0 ,"edma" ,17 ,MCF_CLK );
@@ -146,6 +146,8 @@ struct clk *mcf_clks[] = {static struct clk *const enable_clks[]__initconst = {/* make sure these clocks are enabled */ + &__clk_0_8,/* flexcan.0 */ + &__clk_0_9,/* flexcan.1 */ &__clk_0_15,/* dspi.1 */ &__clk_0_17,/* eDMA */ &__clk_0_18,/* intc0 */
@@ -166,8 +168,6 @@ static struct clk * const enable_clks[] __initconst = { &__clk_1_37, /* gpio */ };static struct clk *const disable_clks[]__initconst = { - &__clk_0_8,/* can.0 */ - &__clk_0_9,/* can.1 */ &__clk_0_14,/* i2c.1 */ &__clk_0_22,/* i2c.0 */ &__clk_0_23,/* dspi.0 */
arch/m68k/include/asm/m5441xsim.h +19 -0
@@ -73,6 +73,12 @@#define MCFINT0_FECENTC1 55/* on interrupt controller 1 */ +#define MCFINT1_FLEXCAN0_IFL 0 +#define MCFINT1_FLEXCAN0_BOFF 1 +#define MCFINT1_FLEXCAN0_ERR 3 +#define MCFINT1_FLEXCAN1_IFL 4 +#define MCFINT1_FLEXCAN1_BOFF 5 +#define MCFINT1_FLEXCAN1_ERR 7#define MCFINT1_UART4 48#define MCFINT1_UART5 49#define MCFINT1_UART6 50
@@ -314,4 +320,17 @@#define MCF_IRQ_SDHC (MCFINT2_VECBASE + MCFINT2_SDHC)#define MCFSDHC_CLK (MCFSDHC_BASE + 0x2c) +/* +* Flexcan module +*/ +#define MCFFLEXCAN_BASE0 0xfc020000 +#define MCFFLEXCAN_BASE1 0xfc024000 +#define MCFFLEXCAN_SIZE 0x4000 +#define MCF_IRQ_IFL0 (MCFINT1_VECBASE + MCFINT1_FLEXCAN0_IFL) +#define MCF_IRQ_BOFF0 (MCFINT1_VECBASE + MCFINT1_FLEXCAN0_BOFF) +#define MCF_IRQ_ERR0 (MCFINT1_VECBASE + MCFINT1_FLEXCAN0_ERR) +#define MCF_IRQ_IFL1 (MCFINT1_VECBASE + MCFINT1_FLEXCAN1_IFL) +#define MCF_IRQ_BOFF1 (MCFINT1_VECBASE + MCFINT1_FLEXCAN1_BOFF) +#define MCF_IRQ_ERR1 (MCFINT1_VECBASE + MCFINT1_FLEXCAN1_ERR) +#endif /* m5441xsim_h */
Signature · 1 line
2.31.1
PATCH v3 4/5 can: flexcan: update Kconfig to allow non-of cases
In reply to Angelo DureghelloUpdate flexcan to support architectures without fdt.
---
Changes for v2:
none
Changes for v3:
- change to just remove OF
--- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/Kconfig +1 -1
@@ -97,7 +97,7 @@ config CAN_AT91 config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on OF && HAS_IOMEM + depends on HAS_IOMEM help Say Y here if you want to support for Freescale FlexCAN.
Signature · 1 line
2.31.1
Geert Uytterhoeven
maintainerRe: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Hi Angelo,
Quoted 17 lines · Angelo Dureghello
Update flexcan to support architectures without fdt.
Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
none
Changes for v3:
- change to just remove OF--- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/can/Kconfig +0
-0
drivers/net/can/Kconfig config CAN_AT91 · line 100
Quoted 5 lines
drivers/net/can/Kconfig +1
-1@@ -97,7 +97,7 @@ config CAN_AT91 config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on OF && HAS_IOMEM + depends on HAS_IOMEM
I think you want to add a line
depends on ARCH_LAYERSCAPE || ARCH_MXC || COLDFIRE ||
FSL_SOC_BOOKE || COMPILE_TEST
(or PPC instead of FSL_SOC_BOOKE?)
so the question doesn't pop up when compiling a kernel for a system that cannot have a Freescale FlexCAN IP block.
drivers/net/can/Kconfig config CAN_AT91 · line 102
Quoted 2 lines
drivers/net/can/Kconfig +0
-0help Say Y here if you want to support for Freescale FlexCAN.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Marc Kleine-Budde
maintainerRe: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Quoted 27 lines · Geert Uytterhoeven
Quoted 17 lines · Angelo Dureghello
Update flexcan to support architectures without fdt.
Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
none
Changes for v3:
- change to just remove OF--- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/can/Kconfig +0
-0drivers/net/can/Kconfig config CAN_AT91 · line 100
Quoted 5 lines
drivers/net/can/Kconfig +1
-1@@ -97,7 +97,7 @@ config CAN_AT91 config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on OF && HAS_IOMEM + depends on HAS_IOMEMI think you want to add a line
Quoted 6 lines
depends on ARCH_LAYERSCAPE || ARCH_MXC || COLDFIRE ||
FSL_SOC_BOOKE||COMPILE_TEST(or PPC instead of
FSL_SOC_BOOKE?)
so the question doesn't pop up when compiling a kernel for a system that cannot have a Freescale FlexCAN IP block.
Back in 2018 Pankaj Bansal replaced the "depends on ARM || PPC" by "OF && HAS_IOMEM", see:
| 0f8af56f74cd can: flexcan: enable flexcan for all architectures
So I think there won't be too many configs where the oldconfig question would pop up.
regards,
Marc
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Geert Uytterhoeven
maintainerRe: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Hi Marc,
Quoted 31 lines · Marc Kleine-Budde
Quoted 30 lines · Geert Uytterhoeven
Quoted 17 lines · Angelo Dureghello
Update flexcan to support architectures without fdt.
Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
none
Changes for v3:
- change to just remove OF--- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/can/Kconfig +0
-0drivers/net/can/Kconfig config CAN_AT91 · line 100
Quoted 5 lines
drivers/net/can/Kconfig +1
-1@@ -97,7 +97,7 @@ config CAN_AT91 config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on OF && HAS_IOMEM + depends on HAS_IOMEMI think you want to add a line
depends on ARCH_LAYERSCAPE || ARCH_MXC || COLDFIRE ||
FSL_SOC_BOOKE||COMPILE_TEST
Quoted 8 lines
Quoted 3 lines
(or PPC instead of
FSL_SOC_BOOKE?)
so the question doesn't pop up when compiling a kernel for a system that cannot have a Freescale FlexCAN IP block.Back in 2018 Pankaj Bansal replaced the "depends on ARM || PPC" by "OF &&
HAS_IOMEM", see:|
0f8af56f74cdcan: flexcan: enable flexcan for all architectures
Probably the real reason behind that was to enable it on ARM64 (more specifically ARCH_LAYERSCAPE || ARCH_MXC).
Quoted 2 lines
So I think there won't be too many configs where the oldconfig question would pop up.
Now it will, as Mr. Torvalds' main machine does not satisfy "ARM || PPC" or "OF && HAS_IOMEM", but does "HAS_IOMEM" ;-)
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Marc Kleine-Budde
maintainerRe: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Quoted 38 lines · Geert Uytterhoeven
Hi Marc,
Quoted 35 lines · Marc Kleine-Budde
Quoted 33 lines · Geert Uytterhoeven
Quoted 17 lines · Angelo Dureghello
Update flexcan to support architectures without fdt.
Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
none
Changes for v3:
- change to just remove OF--- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/can/Kconfig +0
-0drivers/net/can/Kconfig config CAN_AT91 · line 100
Quoted 5 lines
drivers/net/can/Kconfig +1
-1@@ -97,7 +97,7 @@ config CAN_AT91 config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on OF && HAS_IOMEM + depends on HAS_IOMEMI think you want to add a line
depends on ARCH_LAYERSCAPE || ARCH_MXC || COLDFIRE ||
FSL_SOC_BOOKE||COMPILE_TEST(or PPC instead of
FSL_SOC_BOOKE?)
so the question doesn't pop up when compiling a kernel for a system that cannot have a Freescale FlexCAN IP block.
Quoted 7 lines
Quoted 4 lines
Back in 2018 Pankaj Bansal replaced the "depends on ARM || PPC" by "OF &&
HAS_IOMEM", see:|
0f8af56f74cdcan: flexcan: enable flexcan for all architecturesProbably the real reason behind that was to enable it on ARM64 (more specifically
ARCH_LAYERSCAPE||ARCH_MXC).
Probably. What about the original proposed change: "(OF || M5441x) && HAS_IOMEM"?
Quoted 5 lines
Quoted 2 lines
So I think there won't be too many configs where the oldconfig question would pop up.
Now it will, as Mr. Torvalds' main machine does not satisfy "ARM || PPC" or "OF &&
HAS_IOMEM", but does "HAS_IOMEM" ;-)
IC, that would be one question too much :)
Thanks,
Marc
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Geert Uytterhoeven
maintainerRe: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Hi Marc,
Quoted 30 lines · Marc Kleine-Budde
Quoted 29 lines · Geert Uytterhoeven
Quoted 28 lines · Marc Kleine-Budde
Quoted 17 lines · Geert Uytterhoeven
drivers/net/can/Kconfig config CAN_AT91 · line 100
Quoted 12 lines · Angelo Dureghello
Update flexcan to support architectures without fdt.
Signed-off-by Angelo Dureghello <[email protected]>drivers/net/can/Kconfig +1
-1@@ -97,7 +97,7 @@ config CAN_AT91 config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on OF && HAS_IOMEM + depends on HAS_IOMEMI think you want to add a line
Quoted 6 lines
depends on ARCH_LAYERSCAPE || ARCH_MXC || COLDFIRE ||
FSL_SOC_BOOKE||COMPILE_TEST(or PPC instead of
FSL_SOC_BOOKE?)
so the question doesn't pop up when compiling a kernel for a system that cannot have a Freescale FlexCAN IP block.Back in 2018 Pankaj Bansal replaced the "depends on ARM || PPC" by "OF &&
HAS_IOMEM", see:
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
|
0f8af56f74cdcan: flexcan: enable flexcan for all architecturesProbably the real reason behind that was to enable it on ARM64 (more specifically
ARCH_LAYERSCAPE||ARCH_MXC).Probably. What about the original proposed change: "(OF || M5441x) &&
HAS_IOMEM"?
Yeah, the Flexcan might pop up on RISC-V, too.
But any new platforms should use OF.
Given the Flexcan is probably present on more than just M5441x, I'd go for:
depends on OF || COLDFIRE || COMPILE_TEST
depends on HAS_IOMEM
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
So I think there won't be too many configs where the oldconfig question would pop up.
Now it will, as Mr. Torvalds' main machine does not satisfy "ARM || PPC" or "OF &&
HAS_IOMEM", but does "HAS_IOMEM" ;-)IC, that would be one question too much :)
I do doubt he has CONFIG_CAN enabled ;-)
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Marc Kleine-Budde
maintainerRe: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Quoted 9 lines · Geert Uytterhoeven
Quoted 1 line
Probably. What about the original proposed change: "(OF || M5441x) &&
HAS_IOMEM"?Yeah, the Flexcan might pop up on RISC-V, too.
But any new platforms should use OF.
Given the Flexcan is probably present on more than just M5441x, I'd go for:depends on OF || COLDFIRE ||
COMPILE_TEST
depends onHAS_IOMEM
Looks good to me!
Quoted 9 lines
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
So I think there won't be too many configs where the oldconfig question would pop up.
Now it will, as Mr. Torvalds' main machine does not satisfy "ARM || PPC" or "OF &&
HAS_IOMEM", but does "HAS_IOMEM" ;-)IC, that would be one question too much :)
I do doubt he has
CONFIG_CANenabled ;-)
:D
regards,
Marc
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH v3 4/5] can: flexcan: update Kconfig to allow non-of cases
Hi Marc, Geert,
thanks, fixed all, but i am still fighting on an occasional strange heisenbug.
After several hours of "candump can0" on coldfire and "cangen can0" from PC (peak_usb) at 1Mbit/s, coldfire side suddenly produces a 129 RX errors from one packet to another 0 -> 129.
In this condition, after reset and reboot, issue seems to persist, at the first received packet coldfire produces no ack, i still get 129 rx errors:
[ 18.090000] flexcan flexcan-mcf5441x.0 can0: flexcan_chip_start: reading mcr=0x60a3020f ctrl=0x052d2056 [ 18.090000] flexcan_irq() ecr=0x00008100 esr=0x0001c912 [ 18.090000] flexcan flexcan-mcf5441x.0 can0: Controller changed from Error Active State (0) into Error Passive State (2).
Issue seems to disappear again after resoldering the can transceiver (SN65HVD230).
So it seems some issue with my hw, investigating on this before v4, need to be fully sure it's not a driver issue. By oscilloscope, differential signal and rx signal seems perfect, no rings. Also baudrate seems nearly perfect.
Quoted 19 lines · Marc Kleine-Budde
Quoted 9 lines · Geert Uytterhoeven
Quoted 1 line
Probably. What about the original proposed change: "(OF || M5441x) &&
HAS_IOMEM"?Yeah, the Flexcan might pop up on RISC-V, too.
But any new platforms should use OF.
Given the Flexcan is probably present on more than just M5441x, I'd go for:depends on OF || COLDFIRE ||
COMPILE_TEST
depends onHAS_IOMEMLooks good to me!
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
So I think there won't be too many configs where the oldconfig question would pop up.
Now it will, as Mr. Torvalds' main machine does not satisfy "ARM || PPC" or "OF &&
HAS_IOMEM", but does "HAS_IOMEM" ;-)
Quoted 9 lines
Quoted 3 lines
Quoted 1 line
IC, that would be one question too much :)
I do doubt he has
CONFIG_CANenabled ;-):D
regards,
Marc
Regards,
angelo
PATCH v3 5/5 can: flexcan: add mcf5441x support
In reply to Angelo DureghelloAdd flexcan support for NXP ColdFire mcf5441x family.
This flexcan module is quite similar to imx6 flexcan module, but with some exceptions:
- 3 separate interrupt sources, MB, BOFF and ERR,
- implements 16 mb only,
- m68k architecture is not supporting devicetrees, so a platform data check/case has been added,
- ColdFire is m68k, so big-endian cpu, with a little-endian flexcan module.
---
Changes for v2:
- re-add platform data handling restarting from 2c0ac9208135
- re-add flexcan_id_table, as from 2c0ac9208135
- usinig irq resources for ERR and BOFF interrupts
- add missing free_irq() for interrupts
- minor syntax fixes
Changes for v3:
- change platform data include name
- add mcf5441x to hw feature flags
- add mb column to hw feature flags
- fix irq free order
- add proper error handlings
- remove unrelated changes
- split quirk in mb_n and irq_n quirks
--- drivers/net/can/flexcan.c | 126 ++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 20 deletions(-)
drivers/net/can/flexcan.c +106 -20
@@ -28,6 +28,7 @@#include <linux/of_device.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> +#include <linux/can/platform/flexcan.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h>
@@ -208,18 +209,19 @@/* FLEXCAN hardware feature flags * * Below is some version info we got: -* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode +* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB * Filter? connected? Passive detection ption in MB Supported? -* MX25 FlexCAN2 03.00.00.00 no no no no no no -* MX28 FlexCAN2 03.00.04.00 yes yes no no no no -* MX35 FlexCAN2 03.00.00.00 no no no no no no -* MX53 FlexCAN2 03.00.00.00 yes no no no no no -* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no -* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes -* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes -* VF610 FlexCAN3 ? no yes no yes yes? no -* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no -* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes +* MX25 FlexCAN2 03.00.00.00 no no no no no no 64 +* MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 +* MX35 FlexCAN2 03.00.00.00 no no no no no no 64 +* MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 +* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 +* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 +* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 +* VF610 FlexCAN3 ? no yes no yes yes? no 64 +* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 +* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 +* MCF5441X FlexCAN2 ? no yes no no yes no 16 * * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. */
@@ -246,6 +248,10 @@#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10)/* Setup stop mode with SCU firmware to support wakeup */ #define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) +/* Setup 3 separate interrupts, main, boff and err */ +#define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) +/* Setup 16 mailboxes */ +#define FLEXCAN_QUIRK_NR_MB_16 BIT(13)/* Structure of the message buffer */ struct flexcan_mb {
@@ -363,6 +369,9 @@ struct flexcan_priv {struct regulator *reg_xceiver;struct flexcan_stop_mode stm; +int irq_boff; +int irq_err; +/* IPC handle when setup stop mode by System Controller firmware(scfw) */ struct imx_sc_ipc *sc_ipc_handle;
@@ -371,6 +380,11 @@ struct flexcan_priv {void (*write)(u32 val,void __iomem *addr); }; +static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = { + .quirks =FLEXCAN_QUIRK_BROKEN_PERR_STATE | +FLEXCAN_QUIRK_NR_IRQ_3 |FLEXCAN_QUIRK_NR_MB_16 , +}; +static const struct flexcan_devtype_data fsl_p1010_devtype_data = { .quirks =FLEXCAN_QUIRK_BROKEN_WERR_STATE | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
@@ -637,13 +651,17 @@ static int flexcan_clks_enable(const struct flexcan_priv *priv) {int err; - err =clk_prepare_enable (priv->clk_ipg); -if (err) -return err; +if (priv->clk_ipg) { + err =clk_prepare_enable (priv->clk_ipg); +if (err) +return err; + } - err =clk_prepare_enable (priv->clk_per); -if (err) -clk_disable_unprepare (priv->clk_ipg); +if (priv->clk_per) { + err =clk_prepare_enable (priv->clk_per); +if (err) +clk_disable_unprepare (priv->clk_ipg); + }return err; }
@@ -1401,8 +1419,12 @@ static int flexcan_rx_offload_setup(struct net_device *dev) priv->mb_size =sizeof (struct flexcan_mb ) +CANFD_MAX_DLEN ; else priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; - priv->mb_count = (sizeof (priv->regs->mb[0 ]) / priv->mb_size) + - (sizeof (priv->regs->mb[1 ]) / priv->mb_size); + +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_MB_16 ) + priv->mb_count =FLEXCAN_MCF5411X_MB_CNT_MCF ; +else + priv->mb_count = (sizeof (priv->regs->mb[0 ]) / priv->mb_size) + + (sizeof (priv->regs->mb[1 ]) / priv->mb_size);if (priv->devtype_data->quirks &FLEXCAN_QUIRK_USE_OFF_TIMESTAMP ) priv->tx_mb_reserved =
@@ -1774,6 +1796,18 @@ static int flexcan_open(struct net_device *dev)if (err) goto out_can_rx_offload_disable; +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { + err =request_irq (priv->irq_boff, + flexcan_irq,IRQF_SHARED , dev->name, dev); +if (err) + goto out_can_irq_disable; + + err =request_irq (priv->irq_err, + flexcan_irq,IRQF_SHARED , dev->name, dev); +if (err) + goto out_can_irq_boff_disable; + } +flexcan_chip_interrupts_enable (dev);can_led_event (dev,CAN_LED_EVENT_OPEN );
@@ -1782,6 +1816,10 @@ static int flexcan_open(struct net_device *dev)return 0 ; + out_can_irq_boff_disable: +free_irq (priv->irq_boff, dev); + out_can_irq_disable: +free_irq (dev->irq, dev); out_can_rx_offload_disable:can_rx_offload_disable (&priv->offload);flexcan_chip_stop (dev);
@@ -1803,6 +1841,12 @@ static int flexcan_close(struct net_device *dev)netif_stop_queue (dev);flexcan_chip_interrupts_disable (dev); + +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { +free_irq (priv->irq_err, dev); +free_irq (priv->irq_boff, dev); + } +free_irq (dev->irq, dev);can_rx_offload_disable (&priv->offload);flexcan_chip_stop_disable_on_error (dev);
@@ -2039,14 +2083,26 @@ static const struct of_device_id flexcan_of_match[] = { };MODULE_DEVICE_TABLE (of, flexcan_of_match); +static const struct platform_device_id flexcan_id_table[] = { + { + .name ="flexcan-mcf5441x" , + .driver_data = (kernel_ulong_t)&fsl_mcf5441x_devtype_data, + }, { +/* sentinel */ + }, +}; +MODULE_DEVICE_TABLE (platform, flexcan_id_table); +static int flexcan_probe (struct platform_device *pdev) { +const struct of_device_id *of_id;const struct flexcan_devtype_data *devtype_data;struct net_device *dev;struct flexcan_priv *priv;struct regulator *reg_xceiver;struct clk *clk_ipg =NULL , *clk_per =NULL ;struct flexcan_regs __iomem *regs; +struct mcf_flexcan_platform_data *pdata;int err, irq;u8 clk_src =1 ;u32 clock_freq =0 ;
@@ -2064,6 +2120,12 @@ static int flexcan_probe(struct platform_device *pdev) "clock-frequency", &clock_freq);of_property_read_u8 (pdev->dev.of_node,"fsl,clk-source" , &clk_src); + }else { + pdata =dev_get_platdata (&pdev->dev); +if (pdata) { + clock_freq = pdata->clock_frequency; + clk_src = pdata->clk_src; + } }if (!clock_freq) {
@@ -2089,7 +2151,14 @@ static int flexcan_probe(struct platform_device *pdev)if (IS_ERR (regs))return PTR_ERR (regs); - devtype_data =of_device_get_match_data (&pdev->dev); + of_id =of_match_device (flexcan_of_match, &pdev->dev); +if (of_id) + devtype_data = of_id->data; +else if (platform_get_device_id (pdev)->driver_data) + devtype_data = (struct flexcan_devtype_data *) +platform_get_device_id (pdev)->driver_data; +else +return -ENODEV ;if ((devtype_data->quirks &FLEXCAN_QUIRK_SUPPORT_FD ) && !(devtype_data->quirks &FLEXCAN_QUIRK_USE_OFF_TIMESTAMP )) {
@@ -2133,6 +2202,19 @@ static int flexcan_probe(struct platform_device *pdev) priv->devtype_data = devtype_data; priv->reg_xceiver = reg_xceiver; +if (devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { + priv->irq_boff =platform_get_irq (pdev,1 ); +if (priv->irq_boff <=0 ) { + err = -ENODEV ; + goto failed_get_irq_boff; + } + priv->irq_err =platform_get_irq (pdev,2 ); +if (priv->irq_err <=0 ) { + err = -ENODEV ; + goto failed_get_irq_err; + } + } +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_SUPPORT_FD ) { priv->can.ctrlmode_supported |=CAN_CTRLMODE_FD |CAN_CTRLMODE_FD_NON_ISO ;
@@ -2170,6 +2252,9 @@ static int flexcan_probe(struct platform_device *pdev) failed_register:pm_runtime_put_noidle (&pdev->dev);pm_runtime_disable (&pdev->dev); + failed_get_irq_err: +free_irq (priv->irq_boff, dev); + failed_get_irq_boff:free_candev (dev);return err; }
@@ -2322,6 +2407,7 @@ static struct platform_driver flexcan_driver = { }, .probe = flexcan_probe, .remove = flexcan_remove, + .id_table = flexcan_id_table, };module_platform_driver (flexcan_driver);
Signature · 1 line
2.31.1
Marc Kleine-Budde
maintainerRe: [PATCH v3 5/5] can: flexcan: add mcf5441x support
Quoted 148 lines · Angelo Dureghello
Add flexcan support for NXP ColdFire mcf5441x family.
This flexcan module is quite similar to imx6 flexcan module, but with some exceptions:
- 3 separate interrupt sources, MB, BOFF and ERR,
- implements 16 mb only,
- m68k architecture is not supporting devicetrees, so a platform data check/case has been added,
- ColdFire is m68k, so big-endian cpu, with a little-endian flexcan module.Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
- re-add platform data handling restarting from2c0ac9208135
- re-addflexcan_id_table, as from2c0ac9208135
- usinig irq resources for ERR and BOFF interrupts
- add missingfree_irq()for interrupts
- minor syntax fixes
Changes for v3:
- change platform data include name
- add mcf5441x to hw feature flags
- add mb column to hw feature flags
- fix irq free order
- add proper error handlings
- remove unrelated changes
- split quirk inmb_nandirq_nquirks--- drivers/net/can/flexcan.c | 126 ++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 20 deletions(-)drivers/net/can/flexcan.c +41
-19@@ -28,6 +28,7 @@#include <linux/of_device.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> +#include <linux/can/platform/flexcan.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -208,18 +209,19 @@/* FLEXCAN hardware feature flags * * Below is some version info we got: -* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode +* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB * Filter? connected? Passive detection ption in MB Supported? -* MX25 FlexCAN2 03.00.00.00 no no no no no no -* MX28 FlexCAN2 03.00.04.00 yes yes no no no no -* MX35 FlexCAN2 03.00.00.00 no no no no no no -* MX53 FlexCAN2 03.00.00.00 yes no no no no no -* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no -* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes -* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes -* VF610 FlexCAN3 ? no yes no yes yes? no -* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no -* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes +* MX25 FlexCAN2 03.00.00.00 no no no no no no 64 +* MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 +* MX35 FlexCAN2 03.00.00.00 no no no no no no 64 +* MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 +* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 +* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 +* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 +* VF610 FlexCAN3 ? no yes no yes yes? no 64 +* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 +* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 +* MCF5441X FlexCAN2 ? no yes no no yes no 16 * * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. */ @@ -246,6 +248,10 @@#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10)/* Setup stop mode with SCU firmware to support wakeup */ #define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) +/* Setup 3 separate interrupts, main, boff and err */ +#define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) +/* Setup 16 mailboxes */ +#define FLEXCAN_QUIRK_NR_MB_16 BIT(13)/* Structure of the message buffer */ struct flexcan_mb {@@ -363,6 +369,9 @@ struct flexcan_priv {struct regulator *reg_xceiver;struct flexcan_stop_mode stm; +int irq_boff; +int irq_err; +/* IPC handle when setup stop mode by System Controller firmware(scfw) */ struct imx_sc_ipc *sc_ipc_handle;@@ -371,6 +380,11 @@ struct flexcan_priv {void (*write)(u32 val,void __iomem *addr); }; +static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = { + .quirks =FLEXCAN_QUIRK_BROKEN_PERR_STATE | +FLEXCAN_QUIRK_NR_IRQ_3 |FLEXCAN_QUIRK_NR_MB_16 , +}; +static const struct flexcan_devtype_data fsl_p1010_devtype_data = { .quirks =FLEXCAN_QUIRK_BROKEN_WERR_STATE | FLEXCAN_QUIRK_BROKEN_PERR_STATE |@@ -637,13 +651,17 @@ static int flexcan_clks_enable(const struct flexcan_priv *priv) {int err; - err =clk_prepare_enable (priv->clk_ipg); -if (err) -return err; +if (priv->clk_ipg) { + err =clk_prepare_enable (priv->clk_ipg); +if (err) +return err; + } - err =clk_prepare_enable (priv->clk_per); -if (err) -clk_disable_unprepare (priv->clk_ipg); +if (priv->clk_per) { + err =clk_prepare_enable (priv->clk_per); +if (err) +clk_disable_unprepare (priv->clk_ipg); + }return err; }@@ -1401,8 +1419,12 @@ static int flexcan_rx_offload_setup(struct net_device *dev) priv->mb_size =sizeof (struct flexcan_mb ) +CANFD_MAX_DLEN ; else priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; - priv->mb_count = (sizeof (priv->regs->mb[0 ]) / priv->mb_size) + - (sizeof (priv->regs->mb[1 ]) / priv->mb_size); + +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_MB_16 ) + priv->mb_count =FLEXCAN_MCF5411X_MB_CNT_MCF ; +else + priv->mb_count = (sizeof (priv->regs->mb[0 ]) / priv->mb_size) + + (sizeof (priv->regs->mb[1 ]) / priv->mb_size);if (priv->devtype_data->quirks &FLEXCAN_QUIRK_USE_OFF_TIMESTAMP ) priv->tx_mb_reserved =
drivers/net/can/flexcan.c static int flexcan_open(struct net_device *dev) · line 1803
Quoted 8 lines
drivers/net/can/flexcan.c +5
-0@@ -1774,6 +1796,18 @@ static int flexcan_open(struct net_device *dev)if (err) goto out_can_rx_offload_disable; +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { + err =request_irq (priv->irq_boff, + flexcan_irq,IRQF_SHARED , dev->name, dev); +if (err) + goto out_can_irq_disable;
out_free_irq
drivers/net/can/flexcan.c static int flexcan_open(struct net_device *dev) · line 1808
Quoted 5 lines
drivers/net/can/flexcan.c +5
-0+ + err =request_irq (priv->irq_err, + flexcan_irq,IRQF_SHARED , dev->name, dev); +if (err) + goto out_can_irq_boff_disable;
out_free_irq_boff
Quoted 91 lines
drivers/net/can/flexcan.c +40
-1+ } +flexcan_chip_interrupts_enable (dev);can_led_event (dev,CAN_LED_EVENT_OPEN );@@ -1782,6 +1816,10 @@ static int flexcan_open(struct net_device *dev)return 0 ; + out_can_irq_boff_disable: +free_irq (priv->irq_boff, dev); + out_can_irq_disable: +free_irq (dev->irq, dev); out_can_rx_offload_disable:can_rx_offload_disable (&priv->offload);flexcan_chip_stop (dev);@@ -1803,6 +1841,12 @@ static int flexcan_close(struct net_device *dev)netif_stop_queue (dev);flexcan_chip_interrupts_disable (dev); + +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { +free_irq (priv->irq_err, dev); +free_irq (priv->irq_boff, dev); + } +free_irq (dev->irq, dev);can_rx_offload_disable (&priv->offload);flexcan_chip_stop_disable_on_error (dev);@@ -2039,14 +2083,26 @@ static const struct of_device_id flexcan_of_match[] = { };MODULE_DEVICE_TABLE (of, flexcan_of_match); +static const struct platform_device_id flexcan_id_table[] = { + { + .name ="flexcan-mcf5441x" , + .driver_data = (kernel_ulong_t)&fsl_mcf5441x_devtype_data, + }, { +/* sentinel */ + }, +}; +MODULE_DEVICE_TABLE (platform, flexcan_id_table); +static int flexcan_probe (struct platform_device *pdev) { +const struct of_device_id *of_id;const struct flexcan_devtype_data *devtype_data;struct net_device *dev;struct flexcan_priv *priv;struct regulator *reg_xceiver;struct clk *clk_ipg =NULL , *clk_per =NULL ;struct flexcan_regs __iomem *regs; +struct mcf_flexcan_platform_data *pdata;int err, irq;u8 clk_src =1 ;u32 clock_freq =0 ;@@ -2064,6 +2120,12 @@ static int flexcan_probe(struct platform_device *pdev) "clock-frequency", &clock_freq);of_property_read_u8 (pdev->dev.of_node,"fsl,clk-source" , &clk_src); + }else { + pdata =dev_get_platdata (&pdev->dev); +if (pdata) { + clock_freq = pdata->clock_frequency; + clk_src = pdata->clk_src; + } }if (!clock_freq) {@@ -2089,7 +2151,14 @@ static int flexcan_probe(struct platform_device *pdev)if (IS_ERR (regs))return PTR_ERR (regs); - devtype_data =of_device_get_match_data (&pdev->dev); + of_id =of_match_device (flexcan_of_match, &pdev->dev); +if (of_id) + devtype_data = of_id->data; +else if (platform_get_device_id (pdev)->driver_data) + devtype_data = (struct flexcan_devtype_data *) +platform_get_device_id (pdev)->driver_data; +else +return -ENODEV ;if ((devtype_data->quirks &FLEXCAN_QUIRK_SUPPORT_FD ) && !(devtype_data->quirks &FLEXCAN_QUIRK_USE_OFF_TIMESTAMP )) {@@ -2133,6 +2202,19 @@ static int flexcan_probe(struct platform_device *pdev) priv->devtype_data = devtype_data; priv->reg_xceiver = reg_xceiver; +if (devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { + priv->irq_boff =platform_get_irq (pdev,1 );
drivers/net/can/flexcan.c static int flexcan_probe(struct platform_device *pdev) · line 2216
Quoted 10 lines
drivers/net/can/flexcan.c +10
-0+if (priv->irq_boff <=0 ) { + err = -ENODEV ; + goto failed_get_irq_boff; + } + priv->irq_err =platform_get_irq (pdev,2 ); +if (priv->irq_err <=0 ) { + err = -ENODEV ; + goto failed_get_irq_err; + } + }
I suggest to move this directly after the platform_get_irq(pdev, 0), that makes error handling a lot easier.
drivers/net/can/flexcan.c static int flexcan_probe(struct platform_device *pdev) · line 2256
Quoted 10 lines
drivers/net/can/flexcan.c +3
-0+if (priv->devtype_data->quirks &FLEXCAN_QUIRK_SUPPORT_FD ) { priv->can.ctrlmode_supported |=CAN_CTRLMODE_FD |CAN_CTRLMODE_FD_NON_ISO ;@@ -2170,6 +2252,9 @@ static int flexcan_probe(struct platform_device *pdev) failed_register:pm_runtime_put_noidle (&pdev->dev);pm_runtime_disable (&pdev->dev); + failed_get_irq_err: +free_irq (priv->irq_boff, dev);
This is wrong - you cannot free an IRQ you have not requested.
Quoted 16 lines
drivers/net/can/flexcan.c +2
-0+ failed_get_irq_boff:free_candev (dev);return err; }@@ -2322,6 +2407,7 @@ static struct platform_driver flexcan_driver = { }, .probe = flexcan_probe, .remove = flexcan_remove, + .id_table = flexcan_id_table, };module_platform_driver (flexcan_driver);Signature · 1 line
2.31.1
Marc
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH v3 5/5] can: flexcan: add mcf5441x support
Hi Marc,
Quoted 257 lines · Marc Kleine-Budde
Quoted 148 lines · Angelo Dureghello
Add flexcan support for NXP ColdFire mcf5441x family.
This flexcan module is quite similar to imx6 flexcan module, but with some exceptions:
- 3 separate interrupt sources, MB, BOFF and ERR,
- implements 16 mb only,
- m68k architecture is not supporting devicetrees, so a platform data check/case has been added,
- ColdFire is m68k, so big-endian cpu, with a little-endian flexcan module.Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
- re-add platform data handling restarting from2c0ac9208135
- re-addflexcan_id_table, as from2c0ac9208135
- usinig irq resources for ERR and BOFF interrupts
- add missingfree_irq()for interrupts
- minor syntax fixes
Changes for v3:
- change platform data include name
- add mcf5441x to hw feature flags
- add mb column to hw feature flags
- fix irq free order
- add proper error handlings
- remove unrelated changes
- split quirk inmb_nandirq_nquirks--- drivers/net/can/flexcan.c | 126 ++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 20 deletions(-)drivers/net/can/flexcan.c +41
-19@@ -28,6 +28,7 @@#include <linux/of_device.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> +#include <linux/can/platform/flexcan.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -208,18 +209,19 @@/* FLEXCAN hardware feature flags * * Below is some version info we got: -* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode +* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB * Filter? connected? Passive detection ption in MB Supported? -* MX25 FlexCAN2 03.00.00.00 no no no no no no -* MX28 FlexCAN2 03.00.04.00 yes yes no no no no -* MX35 FlexCAN2 03.00.00.00 no no no no no no -* MX53 FlexCAN2 03.00.00.00 yes no no no no no -* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no -* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes -* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes -* VF610 FlexCAN3 ? no yes no yes yes? no -* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no -* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes +* MX25 FlexCAN2 03.00.00.00 no no no no no no 64 +* MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 +* MX35 FlexCAN2 03.00.00.00 no no no no no no 64 +* MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 +* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 +* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 +* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 +* VF610 FlexCAN3 ? no yes no yes yes? no 64 +* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 +* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 +* MCF5441X FlexCAN2 ? no yes no no yes no 16 * * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. */ @@ -246,6 +248,10 @@#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10)/* Setup stop mode with SCU firmware to support wakeup */ #define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) +/* Setup 3 separate interrupts, main, boff and err */ +#define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) +/* Setup 16 mailboxes */ +#define FLEXCAN_QUIRK_NR_MB_16 BIT(13)/* Structure of the message buffer */ struct flexcan_mb {@@ -363,6 +369,9 @@ struct flexcan_priv {struct regulator *reg_xceiver;struct flexcan_stop_mode stm; +int irq_boff; +int irq_err; +/* IPC handle when setup stop mode by System Controller firmware(scfw) */ struct imx_sc_ipc *sc_ipc_handle;@@ -371,6 +380,11 @@ struct flexcan_priv {void (*write)(u32 val,void __iomem *addr); }; +static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = { + .quirks =FLEXCAN_QUIRK_BROKEN_PERR_STATE | +FLEXCAN_QUIRK_NR_IRQ_3 |FLEXCAN_QUIRK_NR_MB_16 , +}; +static const struct flexcan_devtype_data fsl_p1010_devtype_data = { .quirks =FLEXCAN_QUIRK_BROKEN_WERR_STATE | FLEXCAN_QUIRK_BROKEN_PERR_STATE |@@ -637,13 +651,17 @@ static int flexcan_clks_enable(const struct flexcan_priv *priv) {int err; - err =clk_prepare_enable (priv->clk_ipg); -if (err) -return err; +if (priv->clk_ipg) { + err =clk_prepare_enable (priv->clk_ipg); +if (err) +return err; + } - err =clk_prepare_enable (priv->clk_per); -if (err) -clk_disable_unprepare (priv->clk_ipg); +if (priv->clk_per) { + err =clk_prepare_enable (priv->clk_per); +if (err) +clk_disable_unprepare (priv->clk_ipg); + }return err; }@@ -1401,8 +1419,12 @@ static int flexcan_rx_offload_setup(struct net_device *dev) priv->mb_size =sizeof (struct flexcan_mb ) +CANFD_MAX_DLEN ; else priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; - priv->mb_count = (sizeof (priv->regs->mb[0 ]) / priv->mb_size) + - (sizeof (priv->regs->mb[1 ]) / priv->mb_size); + +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_MB_16 ) + priv->mb_count =FLEXCAN_MCF5411X_MB_CNT_MCF ; +else + priv->mb_count = (sizeof (priv->regs->mb[0 ]) / priv->mb_size) + + (sizeof (priv->regs->mb[1 ]) / priv->mb_size);if (priv->devtype_data->quirks &FLEXCAN_QUIRK_USE_OFF_TIMESTAMP ) priv->tx_mb_reserved =drivers/net/can/flexcan.c static int flexcan_open(struct net_device *dev) · line 1803
Quoted 8 lines
drivers/net/can/flexcan.c +5
-0@@ -1774,6 +1796,18 @@ static int flexcan_open(struct net_device *dev)if (err) goto out_can_rx_offload_disable; +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { + err =request_irq (priv->irq_boff, + flexcan_irq,IRQF_SHARED , dev->name, dev); +if (err) + goto out_can_irq_disable;
out_free_irqdrivers/net/can/flexcan.c static int flexcan_open(struct net_device *dev) · line 1808
Quoted 5 lines
drivers/net/can/flexcan.c +5
-0+ + err =request_irq (priv->irq_err, + flexcan_irq,IRQF_SHARED , dev->name, dev); +if (err) + goto out_can_irq_boff_disable;
out_free_irq_boffQuoted 89 lines
drivers/net/can/flexcan.c +38
-1+ } +flexcan_chip_interrupts_enable (dev);can_led_event (dev,CAN_LED_EVENT_OPEN );@@ -1782,6 +1816,10 @@ static int flexcan_open(struct net_device *dev)return 0 ; + out_can_irq_boff_disable: +free_irq (priv->irq_boff, dev); + out_can_irq_disable: +free_irq (dev->irq, dev); out_can_rx_offload_disable:can_rx_offload_disable (&priv->offload);flexcan_chip_stop (dev);@@ -1803,6 +1841,12 @@ static int flexcan_close(struct net_device *dev)netif_stop_queue (dev);flexcan_chip_interrupts_disable (dev); + +if (priv->devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { +free_irq (priv->irq_err, dev); +free_irq (priv->irq_boff, dev); + } +free_irq (dev->irq, dev);can_rx_offload_disable (&priv->offload);flexcan_chip_stop_disable_on_error (dev);@@ -2039,14 +2083,26 @@ static const struct of_device_id flexcan_of_match[] = { };MODULE_DEVICE_TABLE (of, flexcan_of_match); +static const struct platform_device_id flexcan_id_table[] = { + { + .name ="flexcan-mcf5441x" , + .driver_data = (kernel_ulong_t)&fsl_mcf5441x_devtype_data, + }, { +/* sentinel */ + }, +}; +MODULE_DEVICE_TABLE (platform, flexcan_id_table); +static int flexcan_probe (struct platform_device *pdev) { +const struct of_device_id *of_id;const struct flexcan_devtype_data *devtype_data;struct net_device *dev;struct flexcan_priv *priv;struct regulator *reg_xceiver;struct clk *clk_ipg =NULL , *clk_per =NULL ;struct flexcan_regs __iomem *regs; +struct mcf_flexcan_platform_data *pdata;int err, irq;u8 clk_src =1 ;u32 clock_freq =0 ;@@ -2064,6 +2120,12 @@ static int flexcan_probe(struct platform_device *pdev) "clock-frequency", &clock_freq);of_property_read_u8 (pdev->dev.of_node,"fsl,clk-source" , &clk_src); + }else { + pdata =dev_get_platdata (&pdev->dev); +if (pdata) { + clock_freq = pdata->clock_frequency; + clk_src = pdata->clk_src; + } }if (!clock_freq) {@@ -2089,7 +2151,14 @@ static int flexcan_probe(struct platform_device *pdev)if (IS_ERR (regs))return PTR_ERR (regs); - devtype_data =of_device_get_match_data (&pdev->dev); + of_id =of_match_device (flexcan_of_match, &pdev->dev); +if (of_id) + devtype_data = of_id->data; +else if (platform_get_device_id (pdev)->driver_data) + devtype_data = (struct flexcan_devtype_data *) +platform_get_device_id (pdev)->driver_data; +else +return -ENODEV ;if ((devtype_data->quirks &FLEXCAN_QUIRK_SUPPORT_FD ) && !(devtype_data->quirks &FLEXCAN_QUIRK_USE_OFF_TIMESTAMP )) {@@ -2133,6 +2202,19 @@ static int flexcan_probe(struct platform_device *pdev) priv->devtype_data = devtype_data; priv->reg_xceiver = reg_xceiver;
Quoted 16 lines
drivers/net/can/flexcan.c static int flexcan_probe(struct platform_device *pdev) · line 2216
Quoted 12 lines
drivers/net/can/flexcan.c +12
-0+if (devtype_data->quirks &FLEXCAN_QUIRK_NR_IRQ_3 ) { + priv->irq_boff =platform_get_irq (pdev,1 ); +if (priv->irq_boff <=0 ) { + err = -ENODEV ; + goto failed_get_irq_boff; + } + priv->irq_err =platform_get_irq (pdev,2 ); +if (priv->irq_err <=0 ) { + err = -ENODEV ; + goto failed_get_irq_err; + } + }I suggest to move this directly after the
platform_get_irq(pdev, 0), that makes error handling a lot easier.
Moving that above can't be done, devtype_data is still not assigned and i get seg. fault.
I can eventually move
irq = platform_get_irq(pdev, 0);
just before
if (devtype_data->quirks & FLEXCAN_QUIRK_NR_IRQ_3)
Quoted 24 lines
drivers/net/can/flexcan.c static int flexcan_probe(struct platform_device *pdev) · line 2256
Quoted 10 lines
drivers/net/can/flexcan.c +3
-0+if (priv->devtype_data->quirks &FLEXCAN_QUIRK_SUPPORT_FD ) { priv->can.ctrlmode_supported |=CAN_CTRLMODE_FD |CAN_CTRLMODE_FD_NON_ISO ;@@ -2170,6 +2252,9 @@ static int flexcan_probe(struct platform_device *pdev) failed_register:pm_runtime_put_noidle (&pdev->dev);pm_runtime_disable (&pdev->dev); + failed_get_irq_err: +free_irq (priv->irq_boff, dev);This is wrong - you cannot free an IRQ you have not requested.
Quoted 11 lines
drivers/net/can/flexcan.c +2
-0+ failed_get_irq_boff:free_candev (dev);return err; }@@ -2322,6 +2407,7 @@ static struct platform_driver flexcan_driver = { }, .probe = flexcan_probe, .remove = flexcan_remove, + .id_table = flexcan_id_table, };
Quoted 8 lines
Quoted 5 lines
drivers/net/can/flexcan.c +0
-0module_platform_driver (flexcan_driver);Signature · 1 line
2.31.1Marc
All the rest is fixed,7
Thanks !
Regards,
angelo
Marc Kleine-Budde
maintainerQuoted 31 lines · Angelo Dureghello
Add platform data header for flexcan.
Signed-off-by Angelo Dureghello <[email protected]>---
Changes for v2:
- move header file in more proper location
- remove irq defines
- change variable types to match driver types
Changes for v3:
- rename to more genericflexcan.h
- reorder struct fields to avoid paddings
- remove unusedbig_endian--- include/linux/can/platform/flexcan.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 include/linux/can/platform/flexcan.hinclude/linux/can/platform/flexcan.h new file +8
-0@@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (C) 2021 Angelo Dureghello <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +*
include/linux/can/platform/flexcan.h line 18
Quoted 10 lines
include/linux/can/platform/flexcan.h new file +10
-0+* 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. +*/ + +#ifndef _PLAT_FLEXCAN_H +#define _PLAT_FLEXCAN_H + +struct mcf_flexcan_platform_data {
please remove the mcf_ prefix
Quoted 11 lines
include/linux/can/platform/flexcan.h new file +7
-0+u32 clock_frequency; + u8 clk_src; +}; + +#define FLEXCAN_MCF5411X_MB_CNT_MCF 16 + +#endif /* _PLAT_FLEXCAN_H */ Signature · 1 line
2.31.1
Marc
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |