linux-can-fixes-for-6.4-20230515
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEDs2BvajyNKlf9TJQvlAcSiqKBOgFAmRiloITHG1rbEBwZW5n dXRyb25peC5kZQAKCRC+UBxKKooE6KQjB/920q1esTr4MiOeVHShwj6OGqfjcWlf PvPzoMbMy2KuRgPF08HL3PO/fnrttSkI+qn1jJFD+IE+0QERbFf3adTOns+iiM2d li9kLQgFf6a6ne2lRFwGXsxIuABzGBpq4LO4TDl7CRx2U0FZgETVV/8ImqAaxafp ryS5ko3gghHmxAg96RjaPEMhZjaYpDqpY+AR6lD445CpzhGs5nhO/WKyJRm5wgue PlCUVjPyE9Wyf11e0MDkmFEAV4nR8qHIm0TnVz1h9Z3oOPWuvoOHJiXijrgjpKP8 kfhQcBE8HXi3euOH/RUSr54euk37sLk0UpOdkrq7mp2Lu1pb/IfNznrg =hpEt -----END PGP SIGNATURE----- Merge tag 'linux-can-fixes-for-6.4-20230515' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can Marc Kleine-Budde says: ==================== pull-request: can 2023-05-15 The first 2 patches are by Oliver Hartkopp and allow the MSG_CMSG_COMPAT flag for isotp and j1939. The next patch is by Oliver Hartkopp, too and adds missing CAN XL support in can_put_echo_skb(). Geert Uytterhoeven's patch let's the bxcan driver depend on ARCH_STM32. The last 5 patches are from Dario Binacchi and also affect the bxcan driver. The bxcan driver hit mainline with v6.4-rc1 and was originally written for IP cores containing 2 CAN interfaces with shared resources. Dario's series updates the DT bindings and driver to support IP cores with a single CAN interface instance as well as adding the bxcan to the stm32f746's device tree. * tag 'linux-can-fixes-for-6.4-20230515' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can: ARM: dts: stm32: add CAN support on stm32f746 can: bxcan: add support for single peripheral configuration ARM: dts: stm32: add pin map for CAN controller on stm32f7 ARM: dts: stm32f429: put can2 in secondary mode dt-bindings: net: can: add "st,can-secondary" property can: CAN_BXCAN should depend on ARCH_STM32 can: dev: fix missing CAN XL support in can_put_echo_skb() can: j1939: recvmsg(): allow MSG_CMSG_COMPAT flag can: isotp: recvmsg(): allow MSG_CMSG_COMPAT flag ==================== Link: https://lore.kernel.org/r/20230515204722.1000957-1-mkl@pengutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
47d55c62bd
|
@ -21,11 +21,22 @@ properties:
|
|||
|
||||
st,can-primary:
|
||||
description:
|
||||
Primary and secondary mode of the bxCAN peripheral is only relevant
|
||||
if the chip has two CAN peripherals. In that case they share some
|
||||
of the required logic.
|
||||
Primary mode of the bxCAN peripheral is only relevant if the chip has
|
||||
two CAN peripherals in dual CAN configuration. In that case they share
|
||||
some of the required logic.
|
||||
Not to be used if the peripheral is in single CAN configuration.
|
||||
To avoid misunderstandings, it should be noted that ST documentation
|
||||
uses the terms master/slave instead of primary/secondary.
|
||||
uses the terms master instead of primary.
|
||||
type: boolean
|
||||
|
||||
st,can-secondary:
|
||||
description:
|
||||
Secondary mode of the bxCAN peripheral is only relevant if the chip
|
||||
has two CAN peripherals in dual CAN configuration. In that case they
|
||||
share some of the required logic.
|
||||
Not to be used if the peripheral is in single CAN configuration.
|
||||
To avoid misunderstandings, it should be noted that ST documentation
|
||||
uses the terms slave instead of secondary.
|
||||
type: boolean
|
||||
|
||||
reg:
|
||||
|
|
|
@ -387,6 +387,7 @@
|
|||
interrupt-names = "tx", "rx0", "rx1", "sce";
|
||||
resets = <&rcc STM32F4_APB1_RESET(CAN2)>;
|
||||
clocks = <&rcc 0 STM32F4_APB1_CLOCK(CAN2)>;
|
||||
st,can-secondary;
|
||||
st,gcan = <&gcan>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -283,6 +283,88 @@
|
|||
slew-rate = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
can1_pins_a: can1-0 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('A', 12, AF9)>; /* CAN1_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('A', 11, AF9)>; /* CAN1_RX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
can1_pins_b: can1-1 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('B', 9, AF9)>; /* CAN1_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('B', 8, AF9)>; /* CAN1_RX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
can1_pins_c: can1-2 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('D', 1, AF9)>; /* CAN1_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('D', 0, AF9)>; /* CAN1_RX */
|
||||
bias-pull-up;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
can1_pins_d: can1-3 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('H', 14, AF9)>; /* CAN1_RX */
|
||||
bias-pull-up;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
can2_pins_a: can2-0 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('B', 6, AF9)>; /* CAN2_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('B', 5, AF9)>; /* CAN2_RX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
can2_pins_b: can2-1 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('B', 13, AF9)>; /* CAN2_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('B', 12, AF9)>; /* CAN2_RX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
can3_pins_a: can3-0 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('A', 15, AF11)>; /* CAN3_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('A', 8, AF11)>; /* CAN3_RX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
can3_pins_b: can3-1 {
|
||||
pins1 {
|
||||
pinmux = <STM32_PINMUX('B', 4, AF11)>; /* CAN3_TX */
|
||||
};
|
||||
pins2 {
|
||||
pinmux = <STM32_PINMUX('B', 3, AF11)>; /* CAN3_RX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -257,6 +257,23 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
can3: can@40003400 {
|
||||
compatible = "st,stm32f4-bxcan";
|
||||
reg = <0x40003400 0x200>;
|
||||
interrupts = <104>, <105>, <106>, <107>;
|
||||
interrupt-names = "tx", "rx0", "rx1", "sce";
|
||||
resets = <&rcc STM32F7_APB1_RESET(CAN3)>;
|
||||
clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
|
||||
st,gcan = <&gcan3>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gcan3: gcan@40003600 {
|
||||
compatible = "st,stm32f4-gcan", "syscon";
|
||||
reg = <0x40003600 0x200>;
|
||||
clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
|
||||
};
|
||||
|
||||
usart2: serial@40004400 {
|
||||
compatible = "st,stm32f7-uart";
|
||||
reg = <0x40004400 0x400>;
|
||||
|
@ -337,6 +354,36 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
can1: can@40006400 {
|
||||
compatible = "st,stm32f4-bxcan";
|
||||
reg = <0x40006400 0x200>;
|
||||
interrupts = <19>, <20>, <21>, <22>;
|
||||
interrupt-names = "tx", "rx0", "rx1", "sce";
|
||||
resets = <&rcc STM32F7_APB1_RESET(CAN1)>;
|
||||
clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN1)>;
|
||||
st,can-primary;
|
||||
st,gcan = <&gcan1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gcan1: gcan@40006600 {
|
||||
compatible = "st,stm32f4-gcan", "syscon";
|
||||
reg = <0x40006600 0x200>;
|
||||
clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN1)>;
|
||||
};
|
||||
|
||||
can2: can@40006800 {
|
||||
compatible = "st,stm32f4-bxcan";
|
||||
reg = <0x40006800 0x200>;
|
||||
interrupts = <63>, <64>, <65>, <66>;
|
||||
interrupt-names = "tx", "rx0", "rx1", "sce";
|
||||
resets = <&rcc STM32F7_APB1_RESET(CAN2)>;
|
||||
clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN2)>;
|
||||
st,can-secondary;
|
||||
st,gcan = <&gcan1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
cec: cec@40006c00 {
|
||||
compatible = "st,stm32-cec";
|
||||
reg = <0x40006C00 0x400>;
|
||||
|
|
|
@ -95,7 +95,7 @@ config CAN_AT91
|
|||
|
||||
config CAN_BXCAN
|
||||
tristate "STM32 Basic Extended CAN (bxCAN) devices"
|
||||
depends on OF || ARCH_STM32 || COMPILE_TEST
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
select CAN_RX_OFFLOAD
|
||||
help
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
#define BXCAN_FiR1_REG(b) (0x40 + (b) * 8)
|
||||
#define BXCAN_FiR2_REG(b) (0x44 + (b) * 8)
|
||||
|
||||
#define BXCAN_FILTER_ID(primary) (primary ? 0 : 14)
|
||||
#define BXCAN_FILTER_ID(cfg) ((cfg) == BXCAN_CFG_DUAL_SECONDARY ? 14 : 0)
|
||||
|
||||
/* Filter primary register (FMR) bits */
|
||||
#define BXCAN_FMR_CANSB_MASK GENMASK(13, 8)
|
||||
|
@ -135,6 +135,12 @@ enum bxcan_lec_code {
|
|||
BXCAN_LEC_UNUSED
|
||||
};
|
||||
|
||||
enum bxcan_cfg {
|
||||
BXCAN_CFG_SINGLE = 0,
|
||||
BXCAN_CFG_DUAL_PRIMARY,
|
||||
BXCAN_CFG_DUAL_SECONDARY
|
||||
};
|
||||
|
||||
/* Structure of the message buffer */
|
||||
struct bxcan_mb {
|
||||
u32 id; /* can identifier */
|
||||
|
@ -167,7 +173,7 @@ struct bxcan_priv {
|
|||
struct regmap *gcan;
|
||||
int tx_irq;
|
||||
int sce_irq;
|
||||
bool primary;
|
||||
enum bxcan_cfg cfg;
|
||||
struct clk *clk;
|
||||
spinlock_t rmw_lock; /* lock for read-modify-write operations */
|
||||
unsigned int tx_head;
|
||||
|
@ -202,17 +208,17 @@ static inline void bxcan_rmw(struct bxcan_priv *priv, void __iomem *addr,
|
|||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
}
|
||||
|
||||
static void bxcan_disable_filters(struct bxcan_priv *priv, bool primary)
|
||||
static void bxcan_disable_filters(struct bxcan_priv *priv, enum bxcan_cfg cfg)
|
||||
{
|
||||
unsigned int fid = BXCAN_FILTER_ID(primary);
|
||||
unsigned int fid = BXCAN_FILTER_ID(cfg);
|
||||
u32 fmask = BIT(fid);
|
||||
|
||||
regmap_update_bits(priv->gcan, BXCAN_FA1R_REG, fmask, 0);
|
||||
}
|
||||
|
||||
static void bxcan_enable_filters(struct bxcan_priv *priv, bool primary)
|
||||
static void bxcan_enable_filters(struct bxcan_priv *priv, enum bxcan_cfg cfg)
|
||||
{
|
||||
unsigned int fid = BXCAN_FILTER_ID(primary);
|
||||
unsigned int fid = BXCAN_FILTER_ID(cfg);
|
||||
u32 fmask = BIT(fid);
|
||||
|
||||
/* Filter settings:
|
||||
|
@ -680,7 +686,7 @@ static int bxcan_chip_start(struct net_device *ndev)
|
|||
BXCAN_BTR_BRP_MASK | BXCAN_BTR_TS1_MASK | BXCAN_BTR_TS2_MASK |
|
||||
BXCAN_BTR_SJW_MASK, set);
|
||||
|
||||
bxcan_enable_filters(priv, priv->primary);
|
||||
bxcan_enable_filters(priv, priv->cfg);
|
||||
|
||||
/* Clear all internal status */
|
||||
priv->tx_head = 0;
|
||||
|
@ -806,7 +812,7 @@ static void bxcan_chip_stop(struct net_device *ndev)
|
|||
BXCAN_IER_EPVIE | BXCAN_IER_EWGIE | BXCAN_IER_FOVIE1 |
|
||||
BXCAN_IER_FFIE1 | BXCAN_IER_FMPIE1 | BXCAN_IER_FOVIE0 |
|
||||
BXCAN_IER_FFIE0 | BXCAN_IER_FMPIE0 | BXCAN_IER_TMEIE, 0);
|
||||
bxcan_disable_filters(priv, priv->primary);
|
||||
bxcan_disable_filters(priv, priv->cfg);
|
||||
bxcan_enter_sleep_mode(priv);
|
||||
priv->can.state = CAN_STATE_STOPPED;
|
||||
}
|
||||
|
@ -931,7 +937,7 @@ static int bxcan_probe(struct platform_device *pdev)
|
|||
struct clk *clk = NULL;
|
||||
void __iomem *regs;
|
||||
struct regmap *gcan;
|
||||
bool primary;
|
||||
enum bxcan_cfg cfg;
|
||||
int err, rx_irq, tx_irq, sce_irq;
|
||||
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
|
@ -946,7 +952,13 @@ static int bxcan_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(gcan);
|
||||
}
|
||||
|
||||
primary = of_property_read_bool(np, "st,can-primary");
|
||||
if (of_property_read_bool(np, "st,can-primary"))
|
||||
cfg = BXCAN_CFG_DUAL_PRIMARY;
|
||||
else if (of_property_read_bool(np, "st,can-secondary"))
|
||||
cfg = BXCAN_CFG_DUAL_SECONDARY;
|
||||
else
|
||||
cfg = BXCAN_CFG_SINGLE;
|
||||
|
||||
clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "failed to get clock\n");
|
||||
|
@ -992,7 +1004,7 @@ static int bxcan_probe(struct platform_device *pdev)
|
|||
priv->clk = clk;
|
||||
priv->tx_irq = tx_irq;
|
||||
priv->sce_irq = sce_irq;
|
||||
priv->primary = primary;
|
||||
priv->cfg = cfg;
|
||||
priv->can.clock.freq = clk_get_rate(clk);
|
||||
spin_lock_init(&priv->rmw_lock);
|
||||
priv->tx_head = 0;
|
||||
|
|
|
@ -54,7 +54,8 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
/* check flag whether this packet has to be looped back */
|
||||
if (!(dev->flags & IFF_ECHO) ||
|
||||
(skb->protocol != htons(ETH_P_CAN) &&
|
||||
skb->protocol != htons(ETH_P_CANFD))) {
|
||||
skb->protocol != htons(ETH_P_CANFD) &&
|
||||
skb->protocol != htons(ETH_P_CANXL))) {
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1139,7 +1139,7 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
|
|||
struct isotp_sock *so = isotp_sk(sk);
|
||||
int ret = 0;
|
||||
|
||||
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK))
|
||||
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK | MSG_CMSG_COMPAT))
|
||||
return -EINVAL;
|
||||
|
||||
if (!so->bound)
|
||||
|
|
|
@ -798,7 +798,7 @@ static int j1939_sk_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||
struct j1939_sk_buff_cb *skcb;
|
||||
int ret = 0;
|
||||
|
||||
if (flags & ~(MSG_DONTWAIT | MSG_ERRQUEUE))
|
||||
if (flags & ~(MSG_DONTWAIT | MSG_ERRQUEUE | MSG_CMSG_COMPAT))
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & MSG_ERRQUEUE)
|
||||
|
|
Loading…
Reference in New Issue