diff options
-rw-r--r-- | Documentation/devicetree/bindings/net/can/fsl-flexcan.txt | 8 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/net/can/xilinx_can.txt | 1 | ||||
-rw-r--r-- | drivers/net/can/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/can/flexcan.c | 365 | ||||
-rw-r--r-- | drivers/net/can/rcar/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/can/rcar/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/can/rcar/rcar_can.c | 6 | ||||
-rw-r--r-- | drivers/net/can/rcar/rcar_canfd.c | 6 | ||||
-rw-r--r-- | drivers/net/can/sja1000/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/can/sja1000/plx_pci.c | 65 | ||||
-rw-r--r-- | drivers/net/can/usb/ucan.c | 2 | ||||
-rw-r--r-- | drivers/net/can/xilinx_can.c | 36 |
12 files changed, 402 insertions, 92 deletions
diff --git a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt index bfc0c433654f..bc77477c6878 100644 --- a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt +++ b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt | |||
@@ -24,6 +24,14 @@ Optional properties: | |||
24 | if this property is present then controller is assumed to be big | 24 | if this property is present then controller is assumed to be big |
25 | endian. | 25 | endian. |
26 | 26 | ||
27 | - fsl,stop-mode: register bits of stop mode control, the format is | ||
28 | <&gpr req_gpr req_bit ack_gpr ack_bit>. | ||
29 | gpr is the phandle to general purpose register node. | ||
30 | req_gpr is the gpr register offset of CAN stop request. | ||
31 | req_bit is the bit offset of CAN stop request. | ||
32 | ack_gpr is the gpr register offset of CAN stop acknowledge. | ||
33 | ack_bit is the bit offset of CAN stop acknowledge. | ||
34 | |||
27 | Example: | 35 | Example: |
28 | 36 | ||
29 | can@1c000 { | 37 | can@1c000 { |
diff --git a/Documentation/devicetree/bindings/net/can/xilinx_can.txt b/Documentation/devicetree/bindings/net/can/xilinx_can.txt index 060e2d46bad9..100cc40b8510 100644 --- a/Documentation/devicetree/bindings/net/can/xilinx_can.txt +++ b/Documentation/devicetree/bindings/net/can/xilinx_can.txt | |||
@@ -6,6 +6,7 @@ Required properties: | |||
6 | - "xlnx,zynq-can-1.0" for Zynq CAN controllers | 6 | - "xlnx,zynq-can-1.0" for Zynq CAN controllers |
7 | - "xlnx,axi-can-1.00.a" for Axi CAN controllers | 7 | - "xlnx,axi-can-1.00.a" for Axi CAN controllers |
8 | - "xlnx,canfd-1.0" for CAN FD controllers | 8 | - "xlnx,canfd-1.0" for CAN FD controllers |
9 | - "xlnx,canfd-2.0" for CAN FD 2.0 controllers | ||
9 | - reg : Physical base address and size of the controller | 10 | - reg : Physical base address and size of the controller |
10 | registers map. | 11 | registers map. |
11 | - interrupts : Property with a value describing the interrupt | 12 | - interrupts : Property with a value describing the interrupt |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 7cdd0cead693..e0f0ad7a550a 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -96,7 +96,7 @@ config CAN_AT91 | |||
96 | 96 | ||
97 | config CAN_FLEXCAN | 97 | config CAN_FLEXCAN |
98 | tristate "Support for Freescale FLEXCAN based chips" | 98 | tristate "Support for Freescale FLEXCAN based chips" |
99 | depends on ARM || PPC | 99 | depends on OF && HAS_IOMEM |
100 | ---help--- | 100 | ---help--- |
101 | Say Y here if you want to support for Freescale FlexCAN. | 101 | Say Y here if you want to support for Freescale FlexCAN. |
102 | 102 | ||
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 75ce11395ee8..0f36eafe3ac1 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -19,11 +19,13 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/mfd/syscon.h> | ||
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/of.h> | 24 | #include <linux/of.h> |
24 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
28 | #include <linux/regmap.h> | ||
27 | 29 | ||
28 | #define DRV_NAME "flexcan" | 30 | #define DRV_NAME "flexcan" |
29 | 31 | ||
@@ -131,16 +133,15 @@ | |||
131 | (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) | 133 | (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) |
132 | #define FLEXCAN_ESR_ALL_INT \ | 134 | #define FLEXCAN_ESR_ALL_INT \ |
133 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ | 135 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ |
134 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT) | 136 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \ |
137 | FLEXCAN_ESR_WAK_INT) | ||
135 | 138 | ||
136 | /* FLEXCAN interrupt flag register (IFLAG) bits */ | 139 | /* FLEXCAN interrupt flag register (IFLAG) bits */ |
137 | /* Errata ERR005829 step7: Reserve first valid MB */ | 140 | /* Errata ERR005829 step7: Reserve first valid MB */ |
138 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 | 141 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 |
139 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 | 142 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
140 | #define FLEXCAN_TX_MB 63 | ||
141 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) | 143 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) |
142 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1) | 144 | #define FLEXCAN_IFLAG_MB(x) BIT((x) & 0x1f) |
143 | #define FLEXCAN_IFLAG_MB(x) BIT(x & 0x1f) | ||
144 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) | 145 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
145 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) | 146 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
146 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) | 147 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
@@ -189,12 +190,13 @@ | |||
189 | #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ | 190 | #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ |
190 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ | 191 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ |
191 | #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE register access */ | 192 | #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE register access */ |
193 | #define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8) /* Setup stop mode to support wakeup */ | ||
192 | 194 | ||
193 | /* Structure of the message buffer */ | 195 | /* Structure of the message buffer */ |
194 | struct flexcan_mb { | 196 | struct flexcan_mb { |
195 | u32 can_ctrl; | 197 | u32 can_ctrl; |
196 | u32 can_id; | 198 | u32 can_id; |
197 | u32 data[2]; | 199 | u32 data[]; |
198 | }; | 200 | }; |
199 | 201 | ||
200 | /* Structure of the hardware registers */ | 202 | /* Structure of the hardware registers */ |
@@ -223,7 +225,7 @@ struct flexcan_regs { | |||
223 | u32 rxfgmask; /* 0x48 */ | 225 | u32 rxfgmask; /* 0x48 */ |
224 | u32 rxfir; /* 0x4c */ | 226 | u32 rxfir; /* 0x4c */ |
225 | u32 _reserved3[12]; /* 0x50 */ | 227 | u32 _reserved3[12]; /* 0x50 */ |
226 | struct flexcan_mb mb[64]; /* 0x80 */ | 228 | u8 mb[2][512]; /* 0x80 */ |
227 | /* FIFO-mode: | 229 | /* FIFO-mode: |
228 | * MB | 230 | * MB |
229 | * 0x080...0x08f 0 RX message buffer | 231 | * 0x080...0x08f 0 RX message buffer |
@@ -253,12 +255,24 @@ struct flexcan_devtype_data { | |||
253 | u32 quirks; /* quirks needed for different IP cores */ | 255 | u32 quirks; /* quirks needed for different IP cores */ |
254 | }; | 256 | }; |
255 | 257 | ||
258 | struct flexcan_stop_mode { | ||
259 | struct regmap *gpr; | ||
260 | u8 req_gpr; | ||
261 | u8 req_bit; | ||
262 | u8 ack_gpr; | ||
263 | u8 ack_bit; | ||
264 | }; | ||
265 | |||
256 | struct flexcan_priv { | 266 | struct flexcan_priv { |
257 | struct can_priv can; | 267 | struct can_priv can; |
258 | struct can_rx_offload offload; | 268 | struct can_rx_offload offload; |
259 | 269 | ||
260 | struct flexcan_regs __iomem *regs; | 270 | struct flexcan_regs __iomem *regs; |
271 | struct flexcan_mb __iomem *tx_mb; | ||
261 | struct flexcan_mb __iomem *tx_mb_reserved; | 272 | struct flexcan_mb __iomem *tx_mb_reserved; |
273 | u8 tx_mb_idx; | ||
274 | u8 mb_count; | ||
275 | u8 mb_size; | ||
262 | u32 reg_ctrl_default; | 276 | u32 reg_ctrl_default; |
263 | u32 reg_imask1_default; | 277 | u32 reg_imask1_default; |
264 | u32 reg_imask2_default; | 278 | u32 reg_imask2_default; |
@@ -267,6 +281,7 @@ struct flexcan_priv { | |||
267 | struct clk *clk_per; | 281 | struct clk *clk_per; |
268 | const struct flexcan_devtype_data *devtype_data; | 282 | const struct flexcan_devtype_data *devtype_data; |
269 | struct regulator *reg_xceiver; | 283 | struct regulator *reg_xceiver; |
284 | struct flexcan_stop_mode stm; | ||
270 | 285 | ||
271 | /* Read and Write APIs */ | 286 | /* Read and Write APIs */ |
272 | u32 (*read)(void __iomem *addr); | 287 | u32 (*read)(void __iomem *addr); |
@@ -290,7 +305,8 @@ static const struct flexcan_devtype_data fsl_imx28_devtype_data = { | |||
290 | 305 | ||
291 | static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { | 306 | static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
292 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | | 307 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
293 | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, | 308 | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
309 | FLEXCAN_QUIRK_SETUP_STOP_MODE, | ||
294 | }; | 310 | }; |
295 | 311 | ||
296 | static const struct flexcan_devtype_data fsl_vf610_devtype_data = { | 312 | static const struct flexcan_devtype_data fsl_vf610_devtype_data = { |
@@ -350,6 +366,68 @@ static inline void flexcan_write_le(u32 val, void __iomem *addr) | |||
350 | iowrite32(val, addr); | 366 | iowrite32(val, addr); |
351 | } | 367 | } |
352 | 368 | ||
369 | static struct flexcan_mb __iomem *flexcan_get_mb(const struct flexcan_priv *priv, | ||
370 | u8 mb_index) | ||
371 | { | ||
372 | u8 bank_size; | ||
373 | bool bank; | ||
374 | |||
375 | if (WARN_ON(mb_index >= priv->mb_count)) | ||
376 | return NULL; | ||
377 | |||
378 | bank_size = sizeof(priv->regs->mb[0]) / priv->mb_size; | ||
379 | |||
380 | bank = mb_index >= bank_size; | ||
381 | if (bank) | ||
382 | mb_index -= bank_size; | ||
383 | |||
384 | return (struct flexcan_mb __iomem *) | ||
385 | (&priv->regs->mb[bank][priv->mb_size * mb_index]); | ||
386 | } | ||
387 | |||
388 | static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable) | ||
389 | { | ||
390 | struct flexcan_regs __iomem *regs = priv->regs; | ||
391 | u32 reg_mcr; | ||
392 | |||
393 | reg_mcr = priv->read(®s->mcr); | ||
394 | |||
395 | if (enable) | ||
396 | reg_mcr |= FLEXCAN_MCR_WAK_MSK; | ||
397 | else | ||
398 | reg_mcr &= ~FLEXCAN_MCR_WAK_MSK; | ||
399 | |||
400 | priv->write(reg_mcr, ®s->mcr); | ||
401 | } | ||
402 | |||
403 | static inline void flexcan_enter_stop_mode(struct flexcan_priv *priv) | ||
404 | { | ||
405 | struct flexcan_regs __iomem *regs = priv->regs; | ||
406 | u32 reg_mcr; | ||
407 | |||
408 | reg_mcr = priv->read(®s->mcr); | ||
409 | reg_mcr |= FLEXCAN_MCR_SLF_WAK; | ||
410 | priv->write(reg_mcr, ®s->mcr); | ||
411 | |||
412 | /* enable stop request */ | ||
413 | regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, | ||
414 | 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); | ||
415 | } | ||
416 | |||
417 | static inline void flexcan_exit_stop_mode(struct flexcan_priv *priv) | ||
418 | { | ||
419 | struct flexcan_regs __iomem *regs = priv->regs; | ||
420 | u32 reg_mcr; | ||
421 | |||
422 | /* remove stop request */ | ||
423 | regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, | ||
424 | 1 << priv->stm.req_bit, 0); | ||
425 | |||
426 | reg_mcr = priv->read(®s->mcr); | ||
427 | reg_mcr &= ~FLEXCAN_MCR_SLF_WAK; | ||
428 | priv->write(reg_mcr, ®s->mcr); | ||
429 | } | ||
430 | |||
353 | static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) | 431 | static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) |
354 | { | 432 | { |
355 | struct flexcan_regs __iomem *regs = priv->regs; | 433 | struct flexcan_regs __iomem *regs = priv->regs; |
@@ -512,11 +590,11 @@ static int flexcan_get_berr_counter(const struct net_device *dev, | |||
512 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) | 590 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
513 | { | 591 | { |
514 | const struct flexcan_priv *priv = netdev_priv(dev); | 592 | const struct flexcan_priv *priv = netdev_priv(dev); |
515 | struct flexcan_regs __iomem *regs = priv->regs; | ||
516 | struct can_frame *cf = (struct can_frame *)skb->data; | 593 | struct can_frame *cf = (struct can_frame *)skb->data; |
517 | u32 can_id; | 594 | u32 can_id; |
518 | u32 data; | 595 | u32 data; |
519 | u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cf->can_dlc << 16); | 596 | u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cf->can_dlc << 16); |
597 | int i; | ||
520 | 598 | ||
521 | if (can_dropped_invalid_skb(dev, skb)) | 599 | if (can_dropped_invalid_skb(dev, skb)) |
522 | return NETDEV_TX_OK; | 600 | return NETDEV_TX_OK; |
@@ -533,27 +611,23 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de | |||
533 | if (cf->can_id & CAN_RTR_FLAG) | 611 | if (cf->can_id & CAN_RTR_FLAG) |
534 | ctrl |= FLEXCAN_MB_CNT_RTR; | 612 | ctrl |= FLEXCAN_MB_CNT_RTR; |
535 | 613 | ||
536 | if (cf->can_dlc > 0) { | 614 | for (i = 0; i < cf->can_dlc; i += sizeof(u32)) { |
537 | data = be32_to_cpup((__be32 *)&cf->data[0]); | 615 | data = be32_to_cpup((__be32 *)&cf->data[i]); |
538 | priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[0]); | 616 | priv->write(data, &priv->tx_mb->data[i / sizeof(u32)]); |
539 | } | ||
540 | if (cf->can_dlc > 4) { | ||
541 | data = be32_to_cpup((__be32 *)&cf->data[4]); | ||
542 | priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[1]); | ||
543 | } | 617 | } |
544 | 618 | ||
545 | can_put_echo_skb(skb, dev, 0); | 619 | can_put_echo_skb(skb, dev, 0); |
546 | 620 | ||
547 | priv->write(can_id, ®s->mb[FLEXCAN_TX_MB].can_id); | 621 | priv->write(can_id, &priv->tx_mb->can_id); |
548 | priv->write(ctrl, ®s->mb[FLEXCAN_TX_MB].can_ctrl); | 622 | priv->write(ctrl, &priv->tx_mb->can_ctrl); |
549 | 623 | ||
550 | /* Errata ERR005829 step8: | 624 | /* Errata ERR005829 step8: |
551 | * Write twice INACTIVE(0x8) code to first MB. | 625 | * Write twice INACTIVE(0x8) code to first MB. |
552 | */ | 626 | */ |
553 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 627 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
554 | &priv->tx_mb_reserved->can_ctrl); | 628 | &priv->tx_mb_reserved->can_ctrl); |
555 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 629 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
556 | &priv->tx_mb_reserved->can_ctrl); | 630 | &priv->tx_mb_reserved->can_ctrl); |
557 | 631 | ||
558 | return NETDEV_TX_OK; | 632 | return NETDEV_TX_OK; |
559 | } | 633 | } |
@@ -672,8 +746,11 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, | |||
672 | { | 746 | { |
673 | struct flexcan_priv *priv = rx_offload_to_priv(offload); | 747 | struct flexcan_priv *priv = rx_offload_to_priv(offload); |
674 | struct flexcan_regs __iomem *regs = priv->regs; | 748 | struct flexcan_regs __iomem *regs = priv->regs; |
675 | struct flexcan_mb __iomem *mb = ®s->mb[n]; | 749 | struct flexcan_mb __iomem *mb; |
676 | u32 reg_ctrl, reg_id, reg_iflag1; | 750 | u32 reg_ctrl, reg_id, reg_iflag1; |
751 | int i; | ||
752 | |||
753 | mb = flexcan_get_mb(priv, n); | ||
677 | 754 | ||
678 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 755 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
679 | u32 code; | 756 | u32 code; |
@@ -714,8 +791,10 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, | |||
714 | cf->can_id |= CAN_RTR_FLAG; | 791 | cf->can_id |= CAN_RTR_FLAG; |
715 | cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); | 792 | cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); |
716 | 793 | ||
717 | *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0])); | 794 | for (i = 0; i < cf->can_dlc; i += sizeof(u32)) { |
718 | *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1])); | 795 | __be32 data = cpu_to_be32(priv->read(&mb->data[i / sizeof(u32)])); |
796 | *(__be32 *)(cf->data + i) = data; | ||
797 | } | ||
719 | 798 | ||
720 | /* mark as read */ | 799 | /* mark as read */ |
721 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 800 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
@@ -744,7 +823,7 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) | |||
744 | u32 iflag1, iflag2; | 823 | u32 iflag1, iflag2; |
745 | 824 | ||
746 | iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & | 825 | iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & |
747 | ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); | 826 | ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
748 | iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; | 827 | iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; |
749 | 828 | ||
750 | return (u64)iflag2 << 32 | iflag1; | 829 | return (u64)iflag2 << 32 | iflag1; |
@@ -794,8 +873,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
794 | reg_iflag2 = priv->read(®s->iflag2); | 873 | reg_iflag2 = priv->read(®s->iflag2); |
795 | 874 | ||
796 | /* transmission complete interrupt */ | 875 | /* transmission complete interrupt */ |
797 | if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) { | 876 | if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { |
798 | u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl); | 877 | u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl); |
799 | 878 | ||
800 | handled = IRQ_HANDLED; | 879 | handled = IRQ_HANDLED; |
801 | stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, | 880 | stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, |
@@ -805,8 +884,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
805 | 884 | ||
806 | /* after sending a RTR frame MB is in RX mode */ | 885 | /* after sending a RTR frame MB is in RX mode */ |
807 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 886 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
808 | ®s->mb[FLEXCAN_TX_MB].can_ctrl); | 887 | &priv->tx_mb->can_ctrl); |
809 | priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), ®s->iflag2); | 888 | priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag2); |
810 | netif_wake_queue(dev); | 889 | netif_wake_queue(dev); |
811 | } | 890 | } |
812 | 891 | ||
@@ -821,7 +900,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
821 | /* state change interrupt or broken error state quirk fix is enabled */ | 900 | /* state change interrupt or broken error state quirk fix is enabled */ |
822 | if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || | 901 | if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || |
823 | (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | | 902 | (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
824 | FLEXCAN_QUIRK_BROKEN_PERR_STATE))) | 903 | FLEXCAN_QUIRK_BROKEN_PERR_STATE))) |
825 | flexcan_irq_state(dev, reg_esr); | 904 | flexcan_irq_state(dev, reg_esr); |
826 | 905 | ||
827 | /* bus error IRQ - handle if bus error reporting is activated */ | 906 | /* bus error IRQ - handle if bus error reporting is activated */ |
@@ -919,6 +998,7 @@ static int flexcan_chip_start(struct net_device *dev) | |||
919 | struct flexcan_regs __iomem *regs = priv->regs; | 998 | struct flexcan_regs __iomem *regs = priv->regs; |
920 | u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; | 999 | u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; |
921 | int err, i; | 1000 | int err, i; |
1001 | struct flexcan_mb __iomem *mb; | ||
922 | 1002 | ||
923 | /* enable module */ | 1003 | /* enable module */ |
924 | err = flexcan_chip_enable(priv); | 1004 | err = flexcan_chip_enable(priv); |
@@ -935,11 +1015,9 @@ static int flexcan_chip_start(struct net_device *dev) | |||
935 | /* MCR | 1015 | /* MCR |
936 | * | 1016 | * |
937 | * enable freeze | 1017 | * enable freeze |
938 | * enable fifo | ||
939 | * halt now | 1018 | * halt now |
940 | * only supervisor access | 1019 | * only supervisor access |
941 | * enable warning int | 1020 | * enable warning int |
942 | * disable local echo | ||
943 | * enable individual RX masking | 1021 | * enable individual RX masking |
944 | * choose format C | 1022 | * choose format C |
945 | * set max mailbox number | 1023 | * set max mailbox number |
@@ -947,14 +1025,37 @@ static int flexcan_chip_start(struct net_device *dev) | |||
947 | reg_mcr = priv->read(®s->mcr); | 1025 | reg_mcr = priv->read(®s->mcr); |
948 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); | 1026 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
949 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | | 1027 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | |
950 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | | 1028 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C | |
951 | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB); | 1029 | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); |
952 | 1030 | ||
1031 | /* MCR | ||
1032 | * | ||
1033 | * FIFO: | ||
1034 | * - disable for timestamp mode | ||
1035 | * - enable for FIFO mode | ||
1036 | */ | ||
953 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) | 1037 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
954 | reg_mcr &= ~FLEXCAN_MCR_FEN; | 1038 | reg_mcr &= ~FLEXCAN_MCR_FEN; |
955 | else | 1039 | else |
956 | reg_mcr |= FLEXCAN_MCR_FEN; | 1040 | reg_mcr |= FLEXCAN_MCR_FEN; |
957 | 1041 | ||
1042 | /* MCR | ||
1043 | * | ||
1044 | * NOTE: In loopback mode, the CAN_MCR[SRXDIS] cannot be | ||
1045 | * asserted because this will impede the self reception | ||
1046 | * of a transmitted message. This is not documented in | ||
1047 | * earlier versions of flexcan block guide. | ||
1048 | * | ||
1049 | * Self Reception: | ||
1050 | * - enable Self Reception for loopback mode | ||
1051 | * (by clearing "Self Reception Disable" bit) | ||
1052 | * - disable for normal operation | ||
1053 | */ | ||
1054 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) | ||
1055 | reg_mcr &= ~FLEXCAN_MCR_SRX_DIS; | ||
1056 | else | ||
1057 | reg_mcr |= FLEXCAN_MCR_SRX_DIS; | ||
1058 | |||
958 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); | 1059 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
959 | priv->write(reg_mcr, ®s->mcr); | 1060 | priv->write(reg_mcr, ®s->mcr); |
960 | 1061 | ||
@@ -999,14 +1100,16 @@ static int flexcan_chip_start(struct net_device *dev) | |||
999 | 1100 | ||
1000 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1101 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
1001 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { | 1102 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { |
1103 | mb = flexcan_get_mb(priv, i); | ||
1002 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, | 1104 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, |
1003 | ®s->mb[i].can_ctrl); | 1105 | &mb->can_ctrl); |
1004 | } | 1106 | } |
1005 | } else { | 1107 | } else { |
1006 | /* clear and invalidate unused mailboxes first */ | 1108 | /* clear and invalidate unused mailboxes first */ |
1007 | for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) { | 1109 | for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= priv->mb_count; i++) { |
1110 | mb = flexcan_get_mb(priv, i); | ||
1008 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, | 1111 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, |
1009 | ®s->mb[i].can_ctrl); | 1112 | &mb->can_ctrl); |
1010 | } | 1113 | } |
1011 | } | 1114 | } |
1012 | 1115 | ||
@@ -1016,7 +1119,7 @@ static int flexcan_chip_start(struct net_device *dev) | |||
1016 | 1119 | ||
1017 | /* mark TX mailbox as INACTIVE */ | 1120 | /* mark TX mailbox as INACTIVE */ |
1018 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 1121 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
1019 | ®s->mb[FLEXCAN_TX_MB].can_ctrl); | 1122 | &priv->tx_mb->can_ctrl); |
1020 | 1123 | ||
1021 | /* acceptance mask/acceptance code (accept everything) */ | 1124 | /* acceptance mask/acceptance code (accept everything) */ |
1022 | priv->write(0x0, ®s->rxgmask); | 1125 | priv->write(0x0, ®s->rxgmask); |
@@ -1027,7 +1130,7 @@ static int flexcan_chip_start(struct net_device *dev) | |||
1027 | priv->write(0x0, ®s->rxfgmask); | 1130 | priv->write(0x0, ®s->rxfgmask); |
1028 | 1131 | ||
1029 | /* clear acceptance filters */ | 1132 | /* clear acceptance filters */ |
1030 | for (i = 0; i < ARRAY_SIZE(regs->mb); i++) | 1133 | for (i = 0; i < priv->mb_count; i++) |
1031 | priv->write(0, ®s->rximr[i]); | 1134 | priv->write(0, ®s->rximr[i]); |
1032 | 1135 | ||
1033 | /* On Vybrid, disable memory error detection interrupts | 1136 | /* On Vybrid, disable memory error detection interrupts |
@@ -1128,10 +1231,49 @@ static int flexcan_open(struct net_device *dev) | |||
1128 | if (err) | 1231 | if (err) |
1129 | goto out_close; | 1232 | goto out_close; |
1130 | 1233 | ||
1234 | priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; | ||
1235 | priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + | ||
1236 | (sizeof(priv->regs->mb[1]) / priv->mb_size); | ||
1237 | |||
1238 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) | ||
1239 | priv->tx_mb_reserved = | ||
1240 | flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP); | ||
1241 | else | ||
1242 | priv->tx_mb_reserved = | ||
1243 | flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); | ||
1244 | priv->tx_mb_idx = priv->mb_count - 1; | ||
1245 | priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); | ||
1246 | |||
1247 | priv->reg_imask1_default = 0; | ||
1248 | priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | ||
1249 | |||
1250 | priv->offload.mailbox_read = flexcan_mailbox_read; | ||
1251 | |||
1252 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | ||
1253 | u64 imask; | ||
1254 | |||
1255 | priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; | ||
1256 | priv->offload.mb_last = priv->mb_count - 2; | ||
1257 | |||
1258 | imask = GENMASK_ULL(priv->offload.mb_last, | ||
1259 | priv->offload.mb_first); | ||
1260 | priv->reg_imask1_default |= imask; | ||
1261 | priv->reg_imask2_default |= imask >> 32; | ||
1262 | |||
1263 | err = can_rx_offload_add_timestamp(dev, &priv->offload); | ||
1264 | } else { | ||
1265 | priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | | ||
1266 | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; | ||
1267 | err = can_rx_offload_add_fifo(dev, &priv->offload, | ||
1268 | FLEXCAN_NAPI_WEIGHT); | ||
1269 | } | ||
1270 | if (err) | ||
1271 | goto out_free_irq; | ||
1272 | |||
1131 | /* start chip and queuing */ | 1273 | /* start chip and queuing */ |
1132 | err = flexcan_chip_start(dev); | 1274 | err = flexcan_chip_start(dev); |
1133 | if (err) | 1275 | if (err) |
1134 | goto out_free_irq; | 1276 | goto out_offload_del; |
1135 | 1277 | ||
1136 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 1278 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
1137 | 1279 | ||
@@ -1140,6 +1282,8 @@ static int flexcan_open(struct net_device *dev) | |||
1140 | 1282 | ||
1141 | return 0; | 1283 | return 0; |
1142 | 1284 | ||
1285 | out_offload_del: | ||
1286 | can_rx_offload_del(&priv->offload); | ||
1143 | out_free_irq: | 1287 | out_free_irq: |
1144 | free_irq(dev->irq, dev); | 1288 | free_irq(dev->irq, dev); |
1145 | out_close: | 1289 | out_close: |
@@ -1160,6 +1304,7 @@ static int flexcan_close(struct net_device *dev) | |||
1160 | can_rx_offload_disable(&priv->offload); | 1304 | can_rx_offload_disable(&priv->offload); |
1161 | flexcan_chip_stop(dev); | 1305 | flexcan_chip_stop(dev); |
1162 | 1306 | ||
1307 | can_rx_offload_del(&priv->offload); | ||
1163 | free_irq(dev->irq, dev); | 1308 | free_irq(dev->irq, dev); |
1164 | clk_disable_unprepare(priv->clk_per); | 1309 | clk_disable_unprepare(priv->clk_per); |
1165 | clk_disable_unprepare(priv->clk_ipg); | 1310 | clk_disable_unprepare(priv->clk_ipg); |
@@ -1260,6 +1405,59 @@ static void unregister_flexcandev(struct net_device *dev) | |||
1260 | unregister_candev(dev); | 1405 | unregister_candev(dev); |
1261 | } | 1406 | } |
1262 | 1407 | ||
1408 | static int flexcan_setup_stop_mode(struct platform_device *pdev) | ||
1409 | { | ||
1410 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1411 | struct device_node *np = pdev->dev.of_node; | ||
1412 | struct device_node *gpr_np; | ||
1413 | struct flexcan_priv *priv; | ||
1414 | phandle phandle; | ||
1415 | u32 out_val[5]; | ||
1416 | int ret; | ||
1417 | |||
1418 | if (!np) | ||
1419 | return -EINVAL; | ||
1420 | |||
1421 | /* stop mode property format is: | ||
1422 | * <&gpr req_gpr req_bit ack_gpr ack_bit>. | ||
1423 | */ | ||
1424 | ret = of_property_read_u32_array(np, "fsl,stop-mode", out_val, | ||
1425 | ARRAY_SIZE(out_val)); | ||
1426 | if (ret) { | ||
1427 | dev_dbg(&pdev->dev, "no stop-mode property\n"); | ||
1428 | return ret; | ||
1429 | } | ||
1430 | phandle = *out_val; | ||
1431 | |||
1432 | gpr_np = of_find_node_by_phandle(phandle); | ||
1433 | if (!gpr_np) { | ||
1434 | dev_dbg(&pdev->dev, "could not find gpr node by phandle\n"); | ||
1435 | return PTR_ERR(gpr_np); | ||
1436 | } | ||
1437 | |||
1438 | priv = netdev_priv(dev); | ||
1439 | priv->stm.gpr = syscon_node_to_regmap(gpr_np); | ||
1440 | of_node_put(gpr_np); | ||
1441 | if (IS_ERR(priv->stm.gpr)) { | ||
1442 | dev_dbg(&pdev->dev, "could not find gpr regmap\n"); | ||
1443 | return PTR_ERR(priv->stm.gpr); | ||
1444 | } | ||
1445 | |||
1446 | priv->stm.req_gpr = out_val[1]; | ||
1447 | priv->stm.req_bit = out_val[2]; | ||
1448 | priv->stm.ack_gpr = out_val[3]; | ||
1449 | priv->stm.ack_bit = out_val[4]; | ||
1450 | |||
1451 | dev_dbg(&pdev->dev, | ||
1452 | "gpr %s req_gpr=0x02%x req_bit=%u ack_gpr=0x02%x ack_bit=%u\n", | ||
1453 | gpr_np->full_name, priv->stm.req_gpr, priv->stm.req_bit, | ||
1454 | priv->stm.ack_gpr, priv->stm.ack_bit); | ||
1455 | |||
1456 | device_set_wakeup_capable(&pdev->dev, true); | ||
1457 | |||
1458 | return 0; | ||
1459 | } | ||
1460 | |||
1263 | static const struct of_device_id flexcan_of_match[] = { | 1461 | static const struct of_device_id flexcan_of_match[] = { |
1264 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, | 1462 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, |
1265 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, | 1463 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, |
@@ -1371,35 +1569,6 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1371 | priv->devtype_data = devtype_data; | 1569 | priv->devtype_data = devtype_data; |
1372 | priv->reg_xceiver = reg_xceiver; | 1570 | priv->reg_xceiver = reg_xceiver; |
1373 | 1571 | ||
1374 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) | ||
1375 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; | ||
1376 | else | ||
1377 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; | ||
1378 | |||
1379 | priv->reg_imask1_default = 0; | ||
1380 | priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); | ||
1381 | |||
1382 | priv->offload.mailbox_read = flexcan_mailbox_read; | ||
1383 | |||
1384 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | ||
1385 | u64 imask; | ||
1386 | |||
1387 | priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; | ||
1388 | priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST; | ||
1389 | |||
1390 | imask = GENMASK_ULL(priv->offload.mb_last, priv->offload.mb_first); | ||
1391 | priv->reg_imask1_default |= imask; | ||
1392 | priv->reg_imask2_default |= imask >> 32; | ||
1393 | |||
1394 | err = can_rx_offload_add_timestamp(dev, &priv->offload); | ||
1395 | } else { | ||
1396 | priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | | ||
1397 | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; | ||
1398 | err = can_rx_offload_add_fifo(dev, &priv->offload, FLEXCAN_NAPI_WEIGHT); | ||
1399 | } | ||
1400 | if (err) | ||
1401 | goto failed_offload; | ||
1402 | |||
1403 | err = register_flexcandev(dev); | 1572 | err = register_flexcandev(dev); |
1404 | if (err) { | 1573 | if (err) { |
1405 | dev_err(&pdev->dev, "registering netdev failed\n"); | 1574 | dev_err(&pdev->dev, "registering netdev failed\n"); |
@@ -1408,12 +1577,17 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1408 | 1577 | ||
1409 | devm_can_led_init(dev); | 1578 | devm_can_led_init(dev); |
1410 | 1579 | ||
1580 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) { | ||
1581 | err = flexcan_setup_stop_mode(pdev); | ||
1582 | if (err) | ||
1583 | dev_dbg(&pdev->dev, "failed to setup stop-mode\n"); | ||
1584 | } | ||
1585 | |||
1411 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", | 1586 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", |
1412 | priv->regs, dev->irq); | 1587 | priv->regs, dev->irq); |
1413 | 1588 | ||
1414 | return 0; | 1589 | return 0; |
1415 | 1590 | ||
1416 | failed_offload: | ||
1417 | failed_register: | 1591 | failed_register: |
1418 | free_candev(dev); | 1592 | free_candev(dev); |
1419 | return err; | 1593 | return err; |
@@ -1422,10 +1596,8 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1422 | static int flexcan_remove(struct platform_device *pdev) | 1596 | static int flexcan_remove(struct platform_device *pdev) |
1423 | { | 1597 | { |
1424 | struct net_device *dev = platform_get_drvdata(pdev); | 1598 | struct net_device *dev = platform_get_drvdata(pdev); |
1425 | struct flexcan_priv *priv = netdev_priv(dev); | ||
1426 | 1599 | ||
1427 | unregister_flexcandev(dev); | 1600 | unregister_flexcandev(dev); |
1428 | can_rx_offload_del(&priv->offload); | ||
1429 | free_candev(dev); | 1601 | free_candev(dev); |
1430 | 1602 | ||
1431 | return 0; | 1603 | return 0; |
@@ -1438,9 +1610,17 @@ static int __maybe_unused flexcan_suspend(struct device *device) | |||
1438 | int err; | 1610 | int err; |
1439 | 1611 | ||
1440 | if (netif_running(dev)) { | 1612 | if (netif_running(dev)) { |
1441 | err = flexcan_chip_disable(priv); | 1613 | /* if wakeup is enabled, enter stop mode |
1442 | if (err) | 1614 | * else enter disabled mode. |
1443 | return err; | 1615 | */ |
1616 | if (device_may_wakeup(device)) { | ||
1617 | enable_irq_wake(dev->irq); | ||
1618 | flexcan_enter_stop_mode(priv); | ||
1619 | } else { | ||
1620 | err = flexcan_chip_disable(priv); | ||
1621 | if (err) | ||
1622 | return err; | ||
1623 | } | ||
1444 | netif_stop_queue(dev); | 1624 | netif_stop_queue(dev); |
1445 | netif_device_detach(dev); | 1625 | netif_device_detach(dev); |
1446 | } | 1626 | } |
@@ -1459,14 +1639,45 @@ static int __maybe_unused flexcan_resume(struct device *device) | |||
1459 | if (netif_running(dev)) { | 1639 | if (netif_running(dev)) { |
1460 | netif_device_attach(dev); | 1640 | netif_device_attach(dev); |
1461 | netif_start_queue(dev); | 1641 | netif_start_queue(dev); |
1462 | err = flexcan_chip_enable(priv); | 1642 | if (device_may_wakeup(device)) { |
1463 | if (err) | 1643 | disable_irq_wake(dev->irq); |
1464 | return err; | 1644 | } else { |
1645 | err = flexcan_chip_enable(priv); | ||
1646 | if (err) | ||
1647 | return err; | ||
1648 | } | ||
1465 | } | 1649 | } |
1466 | return 0; | 1650 | return 0; |
1467 | } | 1651 | } |
1468 | 1652 | ||
1469 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); | 1653 | static int __maybe_unused flexcan_noirq_suspend(struct device *device) |
1654 | { | ||
1655 | struct net_device *dev = dev_get_drvdata(device); | ||
1656 | struct flexcan_priv *priv = netdev_priv(dev); | ||
1657 | |||
1658 | if (netif_running(dev) && device_may_wakeup(device)) | ||
1659 | flexcan_enable_wakeup_irq(priv, true); | ||
1660 | |||
1661 | return 0; | ||
1662 | } | ||
1663 | |||
1664 | static int __maybe_unused flexcan_noirq_resume(struct device *device) | ||
1665 | { | ||
1666 | struct net_device *dev = dev_get_drvdata(device); | ||
1667 | struct flexcan_priv *priv = netdev_priv(dev); | ||
1668 | |||
1669 | if (netif_running(dev) && device_may_wakeup(device)) { | ||
1670 | flexcan_enable_wakeup_irq(priv, false); | ||
1671 | flexcan_exit_stop_mode(priv); | ||
1672 | } | ||
1673 | |||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1677 | static const struct dev_pm_ops flexcan_pm_ops = { | ||
1678 | SET_SYSTEM_SLEEP_PM_OPS(flexcan_suspend, flexcan_resume) | ||
1679 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(flexcan_noirq_suspend, flexcan_noirq_resume) | ||
1680 | }; | ||
1470 | 1681 | ||
1471 | static struct platform_driver flexcan_driver = { | 1682 | static struct platform_driver flexcan_driver = { |
1472 | .driver = { | 1683 | .driver = { |
diff --git a/drivers/net/can/rcar/Kconfig b/drivers/net/can/rcar/Kconfig index 7b03a3a37db7..bd5a8fcd83e1 100644 --- a/drivers/net/can/rcar/Kconfig +++ b/drivers/net/can/rcar/Kconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
1 | config CAN_RCAR | 2 | config CAN_RCAR |
2 | tristate "Renesas R-Car CAN controller" | 3 | tristate "Renesas R-Car CAN controller" |
3 | depends on ARCH_RENESAS || ARM | 4 | depends on ARCH_RENESAS || ARM |
diff --git a/drivers/net/can/rcar/Makefile b/drivers/net/can/rcar/Makefile index 08de36a4cfcc..c9185b0c04a8 100644 --- a/drivers/net/can/rcar/Makefile +++ b/drivers/net/can/rcar/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
1 | # | 2 | # |
2 | # Makefile for the Renesas R-Car CAN & CAN FD controller drivers | 3 | # Makefile for the Renesas R-Car CAN & CAN FD controller drivers |
3 | # | 4 | # |
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c index 771a46083739..13e66297b65f 100644 --- a/drivers/net/can/rcar/rcar_can.c +++ b/drivers/net/can/rcar/rcar_can.c | |||
@@ -1,12 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
1 | /* Renesas R-Car CAN device driver | 2 | /* Renesas R-Car CAN device driver |
2 | * | 3 | * |
3 | * Copyright (C) 2013 Cogent Embedded, Inc. <source@cogentembedded.com> | 4 | * Copyright (C) 2013 Cogent Embedded, Inc. <source@cogentembedded.com> |
4 | * Copyright (C) 2013 Renesas Solutions Corp. | 5 | * Copyright (C) 2013 Renesas Solutions Corp. |
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | 6 | */ |
11 | 7 | ||
12 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 602c19e23f05..05410008aa6b 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c | |||
@@ -1,11 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
1 | /* Renesas R-Car CAN FD device driver | 2 | /* Renesas R-Car CAN FD device driver |
2 | * | 3 | * |
3 | * Copyright (C) 2015 Renesas Electronics Corp. | 4 | * Copyright (C) 2015 Renesas Electronics Corp. |
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | */ | 5 | */ |
10 | 6 | ||
11 | /* The R-Car CAN FD controller can operate in either one of the below two modes | 7 | /* The R-Car CAN FD controller can operate in either one of the below two modes |
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index 1e65cb6c2591..f6dc89927ece 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig | |||
@@ -88,6 +88,7 @@ config CAN_PLX_PCI | |||
88 | - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/) | 88 | - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/) |
89 | - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/) | 89 | - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/) |
90 | - Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com) | 90 | - Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com) |
91 | - ASEM CAN raw - 2 isolated CAN channels (www.asem.it) | ||
91 | 92 | ||
92 | config CAN_TSCAN1 | 93 | config CAN_TSCAN1 |
93 | tristate "TS-CAN1 PC104 boards" | 94 | tristate "TS-CAN1 PC104 boards" |
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index f8ff25c8ee2e..9bcdefea138a 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c | |||
@@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " | |||
46 | "esd CAN-PCIe/2000, " | 46 | "esd CAN-PCIe/2000, " |
47 | "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), " | 47 | "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), " |
48 | "IXXAT PC-I 04/PCI, " | 48 | "IXXAT PC-I 04/PCI, " |
49 | "ELCUS CAN-200-PCI") | 49 | "ELCUS CAN-200-PCI, " |
50 | "ASEM DUAL CAN-RAW") | ||
50 | MODULE_LICENSE("GPL v2"); | 51 | MODULE_LICENSE("GPL v2"); |
51 | 52 | ||
52 | #define PLX_PCI_MAX_CHAN 2 | 53 | #define PLX_PCI_MAX_CHAN 2 |
@@ -70,7 +71,9 @@ struct plx_pci_card { | |||
70 | */ | 71 | */ |
71 | 72 | ||
72 | #define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */ | 73 | #define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */ |
74 | #define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */ | ||
73 | #define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */ | 75 | #define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */ |
76 | #define PLX_LINT2_POL (1 << 4) /* Local interrupt 2 polarity */ | ||
74 | #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */ | 77 | #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */ |
75 | #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */ | 78 | #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */ |
76 | 79 | ||
@@ -92,6 +95,9 @@ struct plx_pci_card { | |||
92 | */ | 95 | */ |
93 | #define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL) | 96 | #define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL) |
94 | 97 | ||
98 | /* OCR setting for ASEM Dual CAN raw */ | ||
99 | #define ASEM_PCI_OCR 0xfe | ||
100 | |||
95 | /* | 101 | /* |
96 | * In the CDR register, you should set CBP to 1. | 102 | * In the CDR register, you should set CBP to 1. |
97 | * You will probably also want to set the clock divider value to 7 | 103 | * You will probably also want to set the clock divider value to 7 |
@@ -145,10 +151,20 @@ struct plx_pci_card { | |||
145 | #define MOXA_PCI_VENDOR_ID 0x1393 | 151 | #define MOXA_PCI_VENDOR_ID 0x1393 |
146 | #define MOXA_PCI_DEVICE_ID 0x0100 | 152 | #define MOXA_PCI_DEVICE_ID 0x0100 |
147 | 153 | ||
154 | #define ASEM_RAW_CAN_VENDOR_ID 0x10b5 | ||
155 | #define ASEM_RAW_CAN_DEVICE_ID 0x9030 | ||
156 | #define ASEM_RAW_CAN_SUB_VENDOR_ID 0x3000 | ||
157 | #define ASEM_RAW_CAN_SUB_DEVICE_ID 0x1001 | ||
158 | #define ASEM_RAW_CAN_SUB_DEVICE_ID_BIS 0x1002 | ||
159 | #define ASEM_RAW_CAN_RST_REGISTER 0x54 | ||
160 | #define ASEM_RAW_CAN_RST_MASK_CAN1 0x20 | ||
161 | #define ASEM_RAW_CAN_RST_MASK_CAN2 0x04 | ||
162 | |||
148 | static void plx_pci_reset_common(struct pci_dev *pdev); | 163 | static void plx_pci_reset_common(struct pci_dev *pdev); |
149 | static void plx9056_pci_reset_common(struct pci_dev *pdev); | 164 | static void plx9056_pci_reset_common(struct pci_dev *pdev); |
150 | static void plx_pci_reset_marathon_pci(struct pci_dev *pdev); | 165 | static void plx_pci_reset_marathon_pci(struct pci_dev *pdev); |
151 | static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev); | 166 | static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev); |
167 | static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev); | ||
152 | 168 | ||
153 | struct plx_pci_channel_map { | 169 | struct plx_pci_channel_map { |
154 | u32 bar; | 170 | u32 bar; |
@@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = { | |||
269 | /* based on PLX9052 */ | 285 | /* based on PLX9052 */ |
270 | }; | 286 | }; |
271 | 287 | ||
288 | static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = { | ||
289 | "ASEM Dual CAN raw PCI", 2, | ||
290 | PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR, | ||
291 | {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} }, | ||
292 | &plx_pci_reset_asem_dual_can_raw | ||
293 | /* based on PLX9030 */ | ||
294 | }; | ||
295 | |||
272 | static const struct pci_device_id plx_pci_tbl[] = { | 296 | static const struct pci_device_id plx_pci_tbl[] = { |
273 | { | 297 | { |
274 | /* Adlink PCI-7841/cPCI-7841 */ | 298 | /* Adlink PCI-7841/cPCI-7841 */ |
@@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = { | |||
375 | 0, 0, | 399 | 0, 0, |
376 | (kernel_ulong_t)&plx_pci_card_info_moxa | 400 | (kernel_ulong_t)&plx_pci_card_info_moxa |
377 | }, | 401 | }, |
402 | { | ||
403 | /* ASEM Dual CAN raw */ | ||
404 | ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID, | ||
405 | ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID, | ||
406 | 0, 0, | ||
407 | (kernel_ulong_t)&plx_pci_card_info_asem_dual_can | ||
408 | }, | ||
409 | { | ||
410 | /* ASEM Dual CAN raw -new model */ | ||
411 | ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID, | ||
412 | ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID_BIS, | ||
413 | 0, 0, | ||
414 | (kernel_ulong_t)&plx_pci_card_info_asem_dual_can | ||
415 | }, | ||
378 | { 0,} | 416 | { 0,} |
379 | }; | 417 | }; |
380 | MODULE_DEVICE_TABLE(pci, plx_pci_tbl); | 418 | MODULE_DEVICE_TABLE(pci, plx_pci_tbl); |
@@ -524,6 +562,31 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev) | |||
524 | } | 562 | } |
525 | } | 563 | } |
526 | 564 | ||
565 | /* Special reset function for ASEM Dual CAN raw card */ | ||
566 | static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev) | ||
567 | { | ||
568 | void __iomem *bar0_addr; | ||
569 | u8 tmpval; | ||
570 | |||
571 | plx_pci_reset_common(pdev); | ||
572 | |||
573 | bar0_addr = pci_iomap(pdev, 0, 0); | ||
574 | if (!bar0_addr) { | ||
575 | dev_err(&pdev->dev, "Failed to remap reset space 0 (BAR0)\n"); | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | /* reset the two SJA1000 chips */ | ||
580 | tmpval = ioread8(bar0_addr + ASEM_RAW_CAN_RST_REGISTER); | ||
581 | tmpval &= ~(ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2); | ||
582 | iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER); | ||
583 | usleep_range(300, 400); | ||
584 | tmpval |= ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2; | ||
585 | iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER); | ||
586 | usleep_range(300, 400); | ||
587 | pci_iounmap(pdev, bar0_addr); | ||
588 | } | ||
589 | |||
527 | static void plx_pci_del_card(struct pci_dev *pdev) | 590 | static void plx_pci_del_card(struct pci_dev *pdev) |
528 | { | 591 | { |
529 | struct plx_pci_card *card = pci_get_drvdata(pdev); | 592 | struct plx_pci_card *card = pci_get_drvdata(pdev); |
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c index f3d5bda012a1..04aac3bb54ef 100644 --- a/drivers/net/can/usb/ucan.c +++ b/drivers/net/can/usb/ucan.c | |||
@@ -715,7 +715,7 @@ static void ucan_read_bulk_callback(struct urb *urb) | |||
715 | up->in_ep_size, | 715 | up->in_ep_size, |
716 | urb->transfer_buffer, | 716 | urb->transfer_buffer, |
717 | urb->transfer_dma); | 717 | urb->transfer_dma); |
718 | netdev_dbg(up->netdev, "not resumbmitting urb; status: %d\n", | 718 | netdev_dbg(up->netdev, "not resubmitting urb; status: %d\n", |
719 | urb->status); | 719 | urb->status); |
720 | return; | 720 | return; |
721 | default: | 721 | default: |
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 045f0845e665..97d0933d9bd9 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c | |||
@@ -63,6 +63,7 @@ enum xcan_reg { | |||
63 | XCAN_FSR_OFFSET = 0x00E8, /* RX FIFO Status */ | 63 | XCAN_FSR_OFFSET = 0x00E8, /* RX FIFO Status */ |
64 | XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */ | 64 | XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */ |
65 | XCAN_RXMSG_BASE_OFFSET = 0x1100, /* RX Message Space */ | 65 | XCAN_RXMSG_BASE_OFFSET = 0x1100, /* RX Message Space */ |
66 | XCAN_RXMSG_2_BASE_OFFSET = 0x2100, /* RX Message Space */ | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | #define XCAN_FRAME_ID_OFFSET(frame_base) ((frame_base) + 0x00) | 69 | #define XCAN_FRAME_ID_OFFSET(frame_base) ((frame_base) + 0x00) |
@@ -75,6 +76,8 @@ enum xcan_reg { | |||
75 | XCAN_CANFD_FRAME_SIZE * (n)) | 76 | XCAN_CANFD_FRAME_SIZE * (n)) |
76 | #define XCAN_RXMSG_FRAME_OFFSET(n) (XCAN_RXMSG_BASE_OFFSET + \ | 77 | #define XCAN_RXMSG_FRAME_OFFSET(n) (XCAN_RXMSG_BASE_OFFSET + \ |
77 | XCAN_CANFD_FRAME_SIZE * (n)) | 78 | XCAN_CANFD_FRAME_SIZE * (n)) |
79 | #define XCAN_RXMSG_2_FRAME_OFFSET(n) (XCAN_RXMSG_2_BASE_OFFSET + \ | ||
80 | XCAN_CANFD_FRAME_SIZE * (n)) | ||
78 | 81 | ||
79 | /* the single TX mailbox used by this driver on CAN FD HW */ | 82 | /* the single TX mailbox used by this driver on CAN FD HW */ |
80 | #define XCAN_TX_MAILBOX_IDX 0 | 83 | #define XCAN_TX_MAILBOX_IDX 0 |
@@ -152,6 +155,7 @@ enum xcan_reg { | |||
152 | * instead of the regular FIFO at 0x50 | 155 | * instead of the regular FIFO at 0x50 |
153 | */ | 156 | */ |
154 | #define XCAN_FLAG_RX_FIFO_MULTI 0x0010 | 157 | #define XCAN_FLAG_RX_FIFO_MULTI 0x0010 |
158 | #define XCAN_FLAG_CANFD_2 0x0020 | ||
155 | 159 | ||
156 | struct xcan_devtype_data { | 160 | struct xcan_devtype_data { |
157 | unsigned int flags; | 161 | unsigned int flags; |
@@ -221,6 +225,18 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd = { | |||
221 | .brp_inc = 1, | 225 | .brp_inc = 1, |
222 | }; | 226 | }; |
223 | 227 | ||
228 | static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { | ||
229 | .name = DRIVER_NAME, | ||
230 | .tseg1_min = 1, | ||
231 | .tseg1_max = 256, | ||
232 | .tseg2_min = 1, | ||
233 | .tseg2_max = 128, | ||
234 | .sjw_max = 128, | ||
235 | .brp_min = 1, | ||
236 | .brp_max = 256, | ||
237 | .brp_inc = 1, | ||
238 | }; | ||
239 | |||
224 | /** | 240 | /** |
225 | * xcan_write_reg_le - Write a value to the device register little endian | 241 | * xcan_write_reg_le - Write a value to the device register little endian |
226 | * @priv: Driver private data structure | 242 | * @priv: Driver private data structure |
@@ -612,7 +628,7 @@ static int xcan_start_xmit_mailbox(struct sk_buff *skb, struct net_device *ndev) | |||
612 | * | 628 | * |
613 | * Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY when the tx queue is full | 629 | * Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY when the tx queue is full |
614 | */ | 630 | */ |
615 | static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 631 | static netdev_tx_t xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
616 | { | 632 | { |
617 | struct xcan_priv *priv = netdev_priv(ndev); | 633 | struct xcan_priv *priv = netdev_priv(ndev); |
618 | int ret; | 634 | int ret; |
@@ -973,7 +989,10 @@ static int xcan_rx_fifo_get_next_frame(struct xcan_priv *priv) | |||
973 | if (!(fsr & XCAN_FSR_FL_MASK)) | 989 | if (!(fsr & XCAN_FSR_FL_MASK)) |
974 | return -ENOENT; | 990 | return -ENOENT; |
975 | 991 | ||
976 | offset = XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); | 992 | if (priv->devtype.flags & XCAN_FLAG_CANFD_2) |
993 | offset = XCAN_RXMSG_2_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); | ||
994 | else | ||
995 | offset = XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); | ||
977 | 996 | ||
978 | } else { | 997 | } else { |
979 | /* check if RX FIFO is empty */ | 998 | /* check if RX FIFO is empty */ |
@@ -1430,11 +1449,24 @@ static const struct xcan_devtype_data xcan_canfd_data = { | |||
1430 | .bus_clk_name = "s_axi_aclk", | 1449 | .bus_clk_name = "s_axi_aclk", |
1431 | }; | 1450 | }; |
1432 | 1451 | ||
1452 | static const struct xcan_devtype_data xcan_canfd2_data = { | ||
1453 | .flags = XCAN_FLAG_EXT_FILTERS | | ||
1454 | XCAN_FLAG_RXMNF | | ||
1455 | XCAN_FLAG_TX_MAILBOXES | | ||
1456 | XCAN_FLAG_CANFD_2 | | ||
1457 | XCAN_FLAG_RX_FIFO_MULTI, | ||
1458 | .bittiming_const = &xcan_bittiming_const_canfd2, | ||
1459 | .btr_ts2_shift = XCAN_BTR_TS2_SHIFT_CANFD, | ||
1460 | .btr_sjw_shift = XCAN_BTR_SJW_SHIFT_CANFD, | ||
1461 | .bus_clk_name = "s_axi_aclk", | ||
1462 | }; | ||
1463 | |||
1433 | /* Match table for OF platform binding */ | 1464 | /* Match table for OF platform binding */ |
1434 | static const struct of_device_id xcan_of_match[] = { | 1465 | static const struct of_device_id xcan_of_match[] = { |
1435 | { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data }, | 1466 | { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data }, |
1436 | { .compatible = "xlnx,axi-can-1.00.a", .data = &xcan_axi_data }, | 1467 | { .compatible = "xlnx,axi-can-1.00.a", .data = &xcan_axi_data }, |
1437 | { .compatible = "xlnx,canfd-1.0", .data = &xcan_canfd_data }, | 1468 | { .compatible = "xlnx,canfd-1.0", .data = &xcan_canfd_data }, |
1469 | { .compatible = "xlnx,canfd-2.0", .data = &xcan_canfd2_data }, | ||
1438 | { /* end of list */ }, | 1470 | { /* end of list */ }, |
1439 | }; | 1471 | }; |
1440 | MODULE_DEVICE_TABLE(of, xcan_of_match); | 1472 | MODULE_DEVICE_TABLE(of, xcan_of_match); |