From 0eadcbd1521c17addbd3d684cb9823572b1fc2c9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 10 Jul 2022 16:22:43 +0200 Subject: [PATCH] 5.10-stable patches added patches: can-kvaser_usb-kvaser_usb_leaf-fix-bittiming-limits.patch can-kvaser_usb-kvaser_usb_leaf-fix-can-clock-frequency-regression.patch can-kvaser_usb-replace-run-time-checks-with-struct-kvaser_usb_driver_info.patch powerpc-powernv-delay-rng-platform-device-creation-until-later-in-boot.patch --- ...kvaser_usb_leaf-fix-bittiming-limits.patch | 195 ++++++ ...f-fix-can-clock-frequency-regression.patch | 149 +++++ ...s-with-struct-kvaser_usb_driver_info.patch | 619 ++++++++++++++++++ ...-device-creation-until-later-in-boot.patch | 73 +++ queue-5.10/series | 4 + 5 files changed, 1040 insertions(+) create mode 100644 queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-bittiming-limits.patch create mode 100644 queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-can-clock-frequency-regression.patch create mode 100644 queue-5.10/can-kvaser_usb-replace-run-time-checks-with-struct-kvaser_usb_driver_info.patch create mode 100644 queue-5.10/powerpc-powernv-delay-rng-platform-device-creation-until-later-in-boot.patch diff --git a/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-bittiming-limits.patch b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-bittiming-limits.patch new file mode 100644 index 00000000000..646fef74afd --- /dev/null +++ b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-bittiming-limits.patch @@ -0,0 +1,195 @@ +From foo@baz Sun Jul 10 04:19:33 PM CEST 2022 +From: Jimmy Assarsson +Date: Fri, 8 Jul 2022 20:48:19 +0200 +Subject: can: kvaser_usb: kvaser_usb_leaf: fix bittiming limits +To: stable@vger.kernel.org, linux-can@vger.kernel.org, Marc Kleine-Budde +Cc: Jimmy Assarsson , Jimmy Assarsson +Message-ID: <20220708184819.281103-4-extja@kvaser.com> + +From: Jimmy Assarsson + +commit b3b6df2c56d80b8c6740433cff5f016668b8de70 upstream. + +Use correct bittiming limits depending on device. For devices based on +USBcanII, Leaf M32C or Leaf i.MX28. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Fixes: b4f20130af23 ("can: kvaser_usb: add support for Kvaser Leaf v2 and usb mini PCIe") +Fixes: f5d4abea3ce0 ("can: kvaser_usb: Add support for the USBcan-II family") +Link: https://lore.kernel.org/all/20220603083820.800246-4-extja@kvaser.com +Cc: stable@vger.kernel.org +Signed-off-by: Jimmy Assarsson +[mkl: remove stray netlink.h include] +[mkl: keep struct can_bittiming_const kvaser_usb_flexc_bittiming_const in kvaser_usb_hydra.c] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 4 - + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 76 ++++++++++++---------- + 3 files changed, 47 insertions(+), 35 deletions(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -188,4 +188,6 @@ int kvaser_usb_send_cmd_async(struct kva + + int kvaser_usb_can_rx_over_error(struct net_device *netdev); + ++extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const; ++ + #endif /* KVASER_USB_H */ +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -371,7 +371,7 @@ static const struct can_bittiming_const + .brp_inc = 1, + }; + +-static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = { ++const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = { + .name = "kvaser_usb_flex", + .tseg1_min = 4, + .tseg1_max = 16, +@@ -2024,5 +2024,5 @@ static const struct kvaser_usb_dev_cfg k + .freq = 24000000, + }, + .timestamp_freq = 1, +- .bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c, ++ .bittiming_const = &kvaser_usb_flexc_bittiming_const, + }; +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -100,16 +100,6 @@ + #define USBCAN_ERROR_STATE_RX_ERROR BIT(1) + #define USBCAN_ERROR_STATE_BUSERROR BIT(2) + +-/* bittiming parameters */ +-#define KVASER_USB_TSEG1_MIN 1 +-#define KVASER_USB_TSEG1_MAX 16 +-#define KVASER_USB_TSEG2_MIN 1 +-#define KVASER_USB_TSEG2_MAX 8 +-#define KVASER_USB_SJW_MAX 4 +-#define KVASER_USB_BRP_MIN 1 +-#define KVASER_USB_BRP_MAX 64 +-#define KVASER_USB_BRP_INC 1 +- + /* ctrl modes */ + #define KVASER_CTRL_MODE_NORMAL 1 + #define KVASER_CTRL_MODE_SILENT 2 +@@ -342,48 +332,68 @@ struct kvaser_usb_err_summary { + }; + }; + +-static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = { +- .name = "kvaser_usb", +- .tseg1_min = KVASER_USB_TSEG1_MIN, +- .tseg1_max = KVASER_USB_TSEG1_MAX, +- .tseg2_min = KVASER_USB_TSEG2_MIN, +- .tseg2_max = KVASER_USB_TSEG2_MAX, +- .sjw_max = KVASER_USB_SJW_MAX, +- .brp_min = KVASER_USB_BRP_MIN, +- .brp_max = KVASER_USB_BRP_MAX, +- .brp_inc = KVASER_USB_BRP_INC, ++static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = { ++ .name = "kvaser_usb_ucii", ++ .tseg1_min = 4, ++ .tseg1_max = 16, ++ .tseg2_min = 2, ++ .tseg2_max = 8, ++ .sjw_max = 4, ++ .brp_min = 1, ++ .brp_max = 16, ++ .brp_inc = 1, ++}; ++ ++static const struct can_bittiming_const kvaser_usb_leaf_m32c_bittiming_const = { ++ .name = "kvaser_usb_leaf", ++ .tseg1_min = 3, ++ .tseg1_max = 16, ++ .tseg2_min = 2, ++ .tseg2_max = 8, ++ .sjw_max = 4, ++ .brp_min = 2, ++ .brp_max = 128, ++ .brp_inc = 2, + }; + +-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = { ++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = { + .clock = { + .freq = 8000000, + }, + .timestamp_freq = 1, +- .bittiming_const = &kvaser_usb_leaf_bittiming_const, ++ .bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const, ++}; ++ ++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = { ++ .clock = { ++ .freq = 16000000, ++ }, ++ .timestamp_freq = 1, ++ .bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const, + }; + +-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = { ++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = { + .clock = { + .freq = 16000000, + }, + .timestamp_freq = 1, +- .bittiming_const = &kvaser_usb_leaf_bittiming_const, ++ .bittiming_const = &kvaser_usb_flexc_bittiming_const, + }; + +-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = { ++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = { + .clock = { + .freq = 24000000, + }, + .timestamp_freq = 1, +- .bittiming_const = &kvaser_usb_leaf_bittiming_const, ++ .bittiming_const = &kvaser_usb_flexc_bittiming_const, + }; + +-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = { ++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = { + .clock = { + .freq = 32000000, + }, + .timestamp_freq = 1, +- .bittiming_const = &kvaser_usb_leaf_bittiming_const, ++ .bittiming_const = &kvaser_usb_flexc_bittiming_const, + }; + + static void * +@@ -529,17 +539,17 @@ static void kvaser_usb_leaf_get_software + /* Firmware expects bittiming parameters calculated for 16MHz + * clock, regardless of the actual clock + */ +- dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; ++ dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg; + } else { + switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { + case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: +- dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; ++ dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_16mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: +- dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; ++ dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_24mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: +- dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; ++ dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_32mhz; + break; + } + } +@@ -566,7 +576,7 @@ static int kvaser_usb_leaf_get_software_ + dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); + dev->max_tx_urbs = + le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); +- dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz; ++ dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg; + break; + } + diff --git a/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-can-clock-frequency-regression.patch b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-can-clock-frequency-regression.patch new file mode 100644 index 00000000000..9f36ba5c922 --- /dev/null +++ b/queue-5.10/can-kvaser_usb-kvaser_usb_leaf-fix-can-clock-frequency-regression.patch @@ -0,0 +1,149 @@ +From foo@baz Sun Jul 10 04:19:33 PM CEST 2022 +From: Jimmy Assarsson +Date: Fri, 8 Jul 2022 20:48:18 +0200 +Subject: can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression +To: stable@vger.kernel.org, linux-can@vger.kernel.org, Marc Kleine-Budde +Cc: Jimmy Assarsson , Jimmy Assarsson +Message-ID: <20220708184819.281103-3-extja@kvaser.com> + +From: Jimmy Assarsson + +commit e6c80e601053ffdac5709f11ff3ec1e19ed05f7b upstream. + +The firmware of M32C based Leaf devices expects bittiming parameters +calculated for 16MHz clock. Since we use the actual clock frequency of +the device, the device may end up with wrong bittiming parameters, +depending on user requested parameters. + +This regression affects M32C based Leaf devices with non-16MHz clock. + +Fixes: 854a2bede1f0 ("can: kvaser_usb: get CAN clock frequency from device") +Link: https://lore.kernel.org/all/20220603083820.800246-3-extja@kvaser.com +Cc: stable@vger.kernel.org +Signed-off-by: Jimmy Assarsson +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 1 + drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 29 +++++++++++++++-------- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 25 ++++++++++++------- + 3 files changed, 36 insertions(+), 19 deletions(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -38,6 +38,7 @@ + /* Kvaser USB device quirks */ + #define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) + #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) ++#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2) + + /* Device capabilities */ + #define KVASER_USB_CAP_BERR_CAP 0x01 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -92,26 +92,33 @@ static const struct kvaser_usb_driver_in + }; + + static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = { +- .quirks = 0, ++ .quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, + }; + + static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { +- .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS, ++ .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | ++ KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, + }; + + static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | +- KVASER_USB_QUIRK_HAS_SILENT_MODE, ++ KVASER_USB_QUIRK_HAS_SILENT_MODE | ++ KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, + }; + ++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = { ++ .quirks = 0, ++ .ops = &kvaser_usb_leaf_dev_ops, ++}; ++ + static const struct usb_device_id kvaser_usb_table[] = { +- /* Leaf USB product IDs */ ++ /* Leaf M32C USB product IDs */ + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID), +@@ -152,16 +159,18 @@ static const struct usb_device_id kvaser + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, ++ ++ /* Leaf i.MX28 USB product IDs */ + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID), +- .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID), +- .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID), +- .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID), +- .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID), +- .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + + /* USBCANII USB product IDs */ + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), +@@ -190,7 +199,7 @@ static const struct usb_device_id kvaser + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID), ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -525,16 +525,23 @@ static void kvaser_usb_leaf_get_software + dev->fw_version = le32_to_cpu(softinfo->fw_version); + dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); + +- switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { +- case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: ++ if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) { ++ /* Firmware expects bittiming parameters calculated for 16MHz ++ * clock, regardless of the actual clock ++ */ + dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; +- break; +- case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: +- dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; +- break; +- case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: +- dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; +- break; ++ } else { ++ switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { ++ case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: ++ dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; ++ break; ++ case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: ++ dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; ++ break; ++ case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: ++ dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; ++ break; ++ } + } + } + diff --git a/queue-5.10/can-kvaser_usb-replace-run-time-checks-with-struct-kvaser_usb_driver_info.patch b/queue-5.10/can-kvaser_usb-replace-run-time-checks-with-struct-kvaser_usb_driver_info.patch new file mode 100644 index 00000000000..5727c965e3d --- /dev/null +++ b/queue-5.10/can-kvaser_usb-replace-run-time-checks-with-struct-kvaser_usb_driver_info.patch @@ -0,0 +1,619 @@ +From foo@baz Sun Jul 10 04:19:33 PM CEST 2022 +From: Jimmy Assarsson +Date: Fri, 8 Jul 2022 20:48:17 +0200 +Subject: can: kvaser_usb: replace run-time checks with struct kvaser_usb_driver_info +To: stable@vger.kernel.org, linux-can@vger.kernel.org, Marc Kleine-Budde +Cc: Jimmy Assarsson , Jimmy Assarsson +Message-ID: <20220708184819.281103-2-extja@kvaser.com> + +From: Jimmy Assarsson + +commit 49f274c72357d2d74cba70b172cf369768909707 upstream. + +Unify and move compile-time known information into new struct +kvaser_usb_driver_info, in favor of run-time checks. + +All Kvaser USBcanII supports listen-only mode and error counter +reporting. + +Link: https://lore.kernel.org/all/20220603083820.800246-2-extja@kvaser.com +Suggested-by: Marc Kleine-Budde +Cc: stable@vger.kernel.org +Signed-off-by: Jimmy Assarsson +[mkl: move struct kvaser_usb_driver_info into kvaser_usb_core.c] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 22 +- + drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 244 ++++++++++++----------- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 24 +- + 3 files changed, 155 insertions(+), 135 deletions(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -35,9 +35,9 @@ + #define KVASER_USB_RX_BUFFER_SIZE 3072 + #define KVASER_USB_MAX_NET_DEVICES 5 + +-/* USB devices features */ +-#define KVASER_USB_HAS_SILENT_MODE BIT(0) +-#define KVASER_USB_HAS_TXRX_ERRORS BIT(1) ++/* Kvaser USB device quirks */ ++#define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) ++#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) + + /* Device capabilities */ + #define KVASER_USB_CAP_BERR_CAP 0x01 +@@ -65,12 +65,7 @@ struct kvaser_usb_dev_card_data_hydra { + struct kvaser_usb_dev_card_data { + u32 ctrlmode_supported; + u32 capabilities; +- union { +- struct { +- enum kvaser_usb_leaf_family family; +- } leaf; +- struct kvaser_usb_dev_card_data_hydra hydra; +- }; ++ struct kvaser_usb_dev_card_data_hydra hydra; + }; + + /* Context for an outstanding, not yet ACKed, transmission */ +@@ -84,7 +79,7 @@ struct kvaser_usb { + struct usb_device *udev; + struct usb_interface *intf; + struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES]; +- const struct kvaser_usb_dev_ops *ops; ++ const struct kvaser_usb_driver_info *driver_info; + const struct kvaser_usb_dev_cfg *cfg; + + struct usb_endpoint_descriptor *bulk_in, *bulk_out; +@@ -166,6 +161,12 @@ struct kvaser_usb_dev_ops { + int *cmd_len, u16 transid); + }; + ++struct kvaser_usb_driver_info { ++ u32 quirks; ++ enum kvaser_usb_leaf_family family; ++ const struct kvaser_usb_dev_ops *ops; ++}; ++ + struct kvaser_usb_dev_cfg { + const struct can_clock clock; + const unsigned int timestamp_freq; +@@ -185,4 +186,5 @@ int kvaser_usb_send_cmd_async(struct kva + int len); + + int kvaser_usb_can_rx_over_error(struct net_device *netdev); ++ + #endif /* KVASER_USB_H */ +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -79,104 +79,125 @@ + #define USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID 269 + #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 270 + +-static inline bool kvaser_is_leaf(const struct usb_device_id *id) +-{ +- return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID && +- id->idProduct <= USB_CAN_R_PRODUCT_ID) || +- (id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID && +- id->idProduct <= USB_MINI_PCIE_2HS_PRODUCT_ID); +-} ++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = { ++ .quirks = 0, ++ .ops = &kvaser_usb_hydra_dev_ops, ++}; + +-static inline bool kvaser_is_usbcan(const struct usb_device_id *id) +-{ +- return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID && +- id->idProduct <= USB_MEMORATOR_PRODUCT_ID; +-} ++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = { ++ .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | ++ KVASER_USB_QUIRK_HAS_SILENT_MODE, ++ .family = KVASER_USBCAN, ++ .ops = &kvaser_usb_leaf_dev_ops, ++}; + +-static inline bool kvaser_is_hydra(const struct usb_device_id *id) +-{ +- return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID && +- id->idProduct <= USB_HYBRID_PRO_CANLIN_PRODUCT_ID; +-} ++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = { ++ .quirks = 0, ++ .family = KVASER_LEAF, ++ .ops = &kvaser_usb_leaf_dev_ops, ++}; ++ ++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { ++ .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS, ++ .family = KVASER_LEAF, ++ .ops = &kvaser_usb_leaf_dev_ops, ++}; ++ ++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = { ++ .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | ++ KVASER_USB_QUIRK_HAS_SILENT_MODE, ++ .family = KVASER_LEAF, ++ .ops = &kvaser_usb_leaf_dev_ops, ++}; + + static const struct usb_device_id kvaser_usb_table[] = { + /* Leaf USB product IDs */ +- { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS | +- KVASER_USB_HAS_SILENT_MODE }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + + /* USBCANII USB product IDs */ + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID), +- .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, + + /* Minihydra USB product IDs */ +- { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) }, +- { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, ++ { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID), ++ .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { } + }; + MODULE_DEVICE_TABLE(usb, kvaser_usb_table); +@@ -267,6 +288,7 @@ int kvaser_usb_can_rx_over_error(struct + static void kvaser_usb_read_bulk_callback(struct urb *urb) + { + struct kvaser_usb *dev = urb->context; ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + int err; + unsigned int i; + +@@ -283,8 +305,8 @@ static void kvaser_usb_read_bulk_callbac + goto resubmit_urb; + } + +- dev->ops->dev_read_bulk_callback(dev, urb->transfer_buffer, +- urb->actual_length); ++ ops->dev_read_bulk_callback(dev, urb->transfer_buffer, ++ urb->actual_length); + + resubmit_urb: + usb_fill_bulk_urb(urb, dev->udev, +@@ -378,6 +400,7 @@ static int kvaser_usb_open(struct net_de + { + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv->dev; ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + int err; + + err = open_candev(netdev); +@@ -388,11 +411,11 @@ static int kvaser_usb_open(struct net_de + if (err) + goto error; + +- err = dev->ops->dev_set_opt_mode(priv); ++ err = ops->dev_set_opt_mode(priv); + if (err) + goto error; + +- err = dev->ops->dev_start_chip(priv); ++ err = ops->dev_start_chip(priv); + if (err) { + netdev_warn(netdev, "Cannot start device, error %d\n", err); + goto error; +@@ -449,22 +472,23 @@ static int kvaser_usb_close(struct net_d + { + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv->dev; ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + int err; + + netif_stop_queue(netdev); + +- err = dev->ops->dev_flush_queue(priv); ++ err = ops->dev_flush_queue(priv); + if (err) + netdev_warn(netdev, "Cannot flush queue, error %d\n", err); + +- if (dev->ops->dev_reset_chip) { +- err = dev->ops->dev_reset_chip(dev, priv->channel); ++ if (ops->dev_reset_chip) { ++ err = ops->dev_reset_chip(dev, priv->channel); + if (err) + netdev_warn(netdev, "Cannot reset card, error %d\n", + err); + } + +- err = dev->ops->dev_stop_chip(priv); ++ err = ops->dev_stop_chip(priv); + if (err) + netdev_warn(netdev, "Cannot stop device, error %d\n", err); + +@@ -503,6 +527,7 @@ static netdev_tx_t kvaser_usb_start_xmit + { + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv->dev; ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + struct net_device_stats *stats = &netdev->stats; + struct kvaser_usb_tx_urb_context *context = NULL; + struct urb *urb; +@@ -545,8 +570,8 @@ static netdev_tx_t kvaser_usb_start_xmit + goto freeurb; + } + +- buf = dev->ops->dev_frame_to_cmd(priv, skb, &context->dlc, &cmd_len, +- context->echo_index); ++ buf = ops->dev_frame_to_cmd(priv, skb, &context->dlc, &cmd_len, ++ context->echo_index); + if (!buf) { + stats->tx_dropped++; + dev_kfree_skb(skb); +@@ -630,15 +655,16 @@ static void kvaser_usb_remove_interfaces + } + } + +-static int kvaser_usb_init_one(struct kvaser_usb *dev, +- const struct usb_device_id *id, int channel) ++static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) + { + struct net_device *netdev; + struct kvaser_usb_net_priv *priv; ++ const struct kvaser_usb_driver_info *driver_info = dev->driver_info; ++ const struct kvaser_usb_dev_ops *ops = driver_info->ops; + int err; + +- if (dev->ops->dev_reset_chip) { +- err = dev->ops->dev_reset_chip(dev, channel); ++ if (ops->dev_reset_chip) { ++ err = ops->dev_reset_chip(dev, channel); + if (err) + return err; + } +@@ -667,20 +693,19 @@ static int kvaser_usb_init_one(struct kv + priv->can.state = CAN_STATE_STOPPED; + priv->can.clock.freq = dev->cfg->clock.freq; + priv->can.bittiming_const = dev->cfg->bittiming_const; +- priv->can.do_set_bittiming = dev->ops->dev_set_bittiming; +- priv->can.do_set_mode = dev->ops->dev_set_mode; +- if ((id->driver_info & KVASER_USB_HAS_TXRX_ERRORS) || ++ priv->can.do_set_bittiming = ops->dev_set_bittiming; ++ priv->can.do_set_mode = ops->dev_set_mode; ++ if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) || + (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP)) +- priv->can.do_get_berr_counter = dev->ops->dev_get_berr_counter; +- if (id->driver_info & KVASER_USB_HAS_SILENT_MODE) ++ priv->can.do_get_berr_counter = ops->dev_get_berr_counter; ++ if (driver_info->quirks & KVASER_USB_QUIRK_HAS_SILENT_MODE) + priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; + + priv->can.ctrlmode_supported |= dev->card_data.ctrlmode_supported; + + if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { + priv->can.data_bittiming_const = dev->cfg->data_bittiming_const; +- priv->can.do_set_data_bittiming = +- dev->ops->dev_set_data_bittiming; ++ priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming; + } + + netdev->flags |= IFF_ECHO; +@@ -711,29 +736,22 @@ static int kvaser_usb_probe(struct usb_i + struct kvaser_usb *dev; + int err; + int i; ++ const struct kvaser_usb_driver_info *driver_info; ++ const struct kvaser_usb_dev_ops *ops; ++ ++ driver_info = (const struct kvaser_usb_driver_info *)id->driver_info; ++ if (!driver_info) ++ return -ENODEV; + + dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + +- if (kvaser_is_leaf(id)) { +- dev->card_data.leaf.family = KVASER_LEAF; +- dev->ops = &kvaser_usb_leaf_dev_ops; +- } else if (kvaser_is_usbcan(id)) { +- dev->card_data.leaf.family = KVASER_USBCAN; +- dev->ops = &kvaser_usb_leaf_dev_ops; +- } else if (kvaser_is_hydra(id)) { +- dev->ops = &kvaser_usb_hydra_dev_ops; +- } else { +- dev_err(&intf->dev, +- "Product ID (%d) is not a supported Kvaser USB device\n", +- id->idProduct); +- return -ENODEV; +- } +- + dev->intf = intf; ++ dev->driver_info = driver_info; ++ ops = driver_info->ops; + +- err = dev->ops->dev_setup_endpoints(dev); ++ err = ops->dev_setup_endpoints(dev); + if (err) { + dev_err(&intf->dev, "Cannot get usb endpoint(s)"); + return err; +@@ -747,22 +765,22 @@ static int kvaser_usb_probe(struct usb_i + + dev->card_data.ctrlmode_supported = 0; + dev->card_data.capabilities = 0; +- err = dev->ops->dev_init_card(dev); ++ err = ops->dev_init_card(dev); + if (err) { + dev_err(&intf->dev, + "Failed to initialize card, error %d\n", err); + return err; + } + +- err = dev->ops->dev_get_software_info(dev); ++ err = ops->dev_get_software_info(dev); + if (err) { + dev_err(&intf->dev, + "Cannot get software info, error %d\n", err); + return err; + } + +- if (dev->ops->dev_get_software_details) { +- err = dev->ops->dev_get_software_details(dev); ++ if (ops->dev_get_software_details) { ++ err = ops->dev_get_software_details(dev); + if (err) { + dev_err(&intf->dev, + "Cannot get software details, error %d\n", err); +@@ -780,14 +798,14 @@ static int kvaser_usb_probe(struct usb_i + + dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs); + +- err = dev->ops->dev_get_card_info(dev); ++ err = ops->dev_get_card_info(dev); + if (err) { + dev_err(&intf->dev, "Cannot get card info, error %d\n", err); + return err; + } + +- if (dev->ops->dev_get_capabilities) { +- err = dev->ops->dev_get_capabilities(dev); ++ if (ops->dev_get_capabilities) { ++ err = ops->dev_get_capabilities(dev); + if (err) { + dev_err(&intf->dev, + "Cannot get capabilities, error %d\n", err); +@@ -797,7 +815,7 @@ static int kvaser_usb_probe(struct usb_i + } + + for (i = 0; i < dev->nchannels; i++) { +- err = kvaser_usb_init_one(dev, id, i); ++ err = kvaser_usb_init_one(dev, i); + if (err) { + kvaser_usb_remove_interfaces(dev); + return err; +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -405,7 +405,7 @@ kvaser_usb_leaf_frame_to_cmd(const struc + sizeof(struct kvaser_cmd_tx_can); + cmd->u.tx_can.channel = priv->channel; + +- switch (dev->card_data.leaf.family) { ++ switch (dev->driver_info->family) { + case KVASER_LEAF: + cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags; + break; +@@ -551,7 +551,7 @@ static int kvaser_usb_leaf_get_software_ + if (err) + return err; + +- switch (dev->card_data.leaf.family) { ++ switch (dev->driver_info->family) { + case KVASER_LEAF: + kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); + break; +@@ -598,7 +598,7 @@ static int kvaser_usb_leaf_get_card_info + + dev->nchannels = cmd.u.cardinfo.nchannels; + if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES || +- (dev->card_data.leaf.family == KVASER_USBCAN && ++ (dev->driver_info->family == KVASER_USBCAN && + dev->nchannels > MAX_USBCAN_NET_DEVICES)) + return -EINVAL; + +@@ -734,7 +734,7 @@ kvaser_usb_leaf_rx_error_update_can_stat + new_state < CAN_STATE_BUS_OFF) + priv->can.can_stats.restarts++; + +- switch (dev->card_data.leaf.family) { ++ switch (dev->driver_info->family) { + case KVASER_LEAF: + if (es->leaf.error_factor) { + priv->can.can_stats.bus_error++; +@@ -813,7 +813,7 @@ static void kvaser_usb_leaf_rx_error(con + } + } + +- switch (dev->card_data.leaf.family) { ++ switch (dev->driver_info->family) { + case KVASER_LEAF: + if (es->leaf.error_factor) { + cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; +@@ -1005,7 +1005,7 @@ static void kvaser_usb_leaf_rx_can_msg(c + stats = &priv->netdev->stats; + + if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) && +- (dev->card_data.leaf.family == KVASER_LEAF && ++ (dev->driver_info->family == KVASER_LEAF && + cmd->id == CMD_LEAF_LOG_MESSAGE)) { + kvaser_usb_leaf_leaf_rx_error(dev, cmd); + return; +@@ -1021,7 +1021,7 @@ static void kvaser_usb_leaf_rx_can_msg(c + return; + } + +- switch (dev->card_data.leaf.family) { ++ switch (dev->driver_info->family) { + case KVASER_LEAF: + rx_data = cmd->u.leaf.rx_can.data; + break; +@@ -1036,7 +1036,7 @@ static void kvaser_usb_leaf_rx_can_msg(c + return; + } + +- if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id == ++ if (dev->driver_info->family == KVASER_LEAF && cmd->id == + CMD_LEAF_LOG_MESSAGE) { + cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id); + if (cf->can_id & KVASER_EXTENDED_FRAME) +@@ -1133,14 +1133,14 @@ static void kvaser_usb_leaf_handle_comma + break; + + case CMD_LEAF_LOG_MESSAGE: +- if (dev->card_data.leaf.family != KVASER_LEAF) ++ if (dev->driver_info->family != KVASER_LEAF) + goto warn; + kvaser_usb_leaf_rx_can_msg(dev, cmd); + break; + + case CMD_CHIP_STATE_EVENT: + case CMD_CAN_ERROR_EVENT: +- if (dev->card_data.leaf.family == KVASER_LEAF) ++ if (dev->driver_info->family == KVASER_LEAF) + kvaser_usb_leaf_leaf_rx_error(dev, cmd); + else + kvaser_usb_leaf_usbcan_rx_error(dev, cmd); +@@ -1152,12 +1152,12 @@ static void kvaser_usb_leaf_handle_comma + + /* Ignored commands */ + case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: +- if (dev->card_data.leaf.family != KVASER_USBCAN) ++ if (dev->driver_info->family != KVASER_USBCAN) + goto warn; + break; + + case CMD_FLUSH_QUEUE_REPLY: +- if (dev->card_data.leaf.family != KVASER_LEAF) ++ if (dev->driver_info->family != KVASER_LEAF) + goto warn; + break; + diff --git a/queue-5.10/powerpc-powernv-delay-rng-platform-device-creation-until-later-in-boot.patch b/queue-5.10/powerpc-powernv-delay-rng-platform-device-creation-until-later-in-boot.patch new file mode 100644 index 00000000000..d9c89cbf32d --- /dev/null +++ b/queue-5.10/powerpc-powernv-delay-rng-platform-device-creation-until-later-in-boot.patch @@ -0,0 +1,73 @@ +From 887502826549caa7e4215fd9e628f48f14c0825a Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Thu, 30 Jun 2022 14:16:54 +0200 +Subject: powerpc/powernv: delay rng platform device creation until later in boot + +From: Jason A. Donenfeld + +commit 887502826549caa7e4215fd9e628f48f14c0825a upstream. + +The platform device for the rng must be created much later in boot. +Otherwise it tries to connect to a parent that doesn't yet exist, +resulting in this splat: + + [ 0.000478] kobject: '(null)' ((____ptrval____)): is not initialized, yet kobject_get() is being called. + [ 0.002925] [c000000002a0fb30] [c00000000073b0bc] kobject_get+0x8c/0x100 (unreliable) + [ 0.003071] [c000000002a0fba0] [c00000000087e464] device_add+0xf4/0xb00 + [ 0.003194] [c000000002a0fc80] [c000000000a7f6e4] of_device_add+0x64/0x80 + [ 0.003321] [c000000002a0fcb0] [c000000000a800d0] of_platform_device_create_pdata+0xd0/0x1b0 + [ 0.003476] [c000000002a0fd00] [c00000000201fa44] pnv_get_random_long_early+0x240/0x2e4 + [ 0.003623] [c000000002a0fe20] [c000000002060c38] random_init+0xc0/0x214 + +This patch fixes the issue by doing the platform device creation inside +of machine_subsys_initcall. + +Fixes: f3eac426657d ("powerpc/powernv: wire up rng during setup_arch") +Cc: stable@vger.kernel.org +Reported-by: Sachin Sant +Signed-off-by: Jason A. Donenfeld +Tested-by: Sachin Sant +[mpe: Change "of node" to "platform device" in change log] +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220630121654.1939181-1-Jason@zx2c4.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/platforms/powernv/rng.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/platforms/powernv/rng.c ++++ b/arch/powerpc/platforms/powernv/rng.c +@@ -176,12 +176,8 @@ static int __init pnv_get_random_long_ea + NULL) != pnv_get_random_long_early) + return 0; + +- for_each_compatible_node(dn, NULL, "ibm,power-rng") { +- if (rng_create(dn)) +- continue; +- /* Create devices for hwrng driver */ +- of_platform_device_create(dn, NULL, NULL); +- } ++ for_each_compatible_node(dn, NULL, "ibm,power-rng") ++ rng_create(dn); + + if (!ppc_md.get_random_seed) + return 0; +@@ -205,10 +201,18 @@ void __init pnv_rng_init(void) + + static int __init pnv_rng_late_init(void) + { ++ struct device_node *dn; + unsigned long v; ++ + /* In case it wasn't called during init for some other reason. */ + if (ppc_md.get_random_seed == pnv_get_random_long_early) + pnv_get_random_long_early(&v); ++ ++ if (ppc_md.get_random_seed == powernv_get_random_long) { ++ for_each_compatible_node(dn, NULL, "ibm,power-rng") ++ of_platform_device_create(dn, NULL, NULL); ++ } ++ + return 0; + } + machine_subsys_initcall(powernv, pnv_rng_late_init); diff --git a/queue-5.10/series b/queue-5.10/series index d8823265c9d..b2670adb340 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -17,3 +17,7 @@ fbcon-prevent-that-screen-size-is-smaller-than-font-size.patch pm-runtime-redefine-pm_runtime_release_supplier.patch memregion-fix-memregion_free-fallback-definition.patch video-of_display_timing.h-include-errno.h.patch +powerpc-powernv-delay-rng-platform-device-creation-until-later-in-boot.patch +can-kvaser_usb-replace-run-time-checks-with-struct-kvaser_usb_driver_info.patch +can-kvaser_usb-kvaser_usb_leaf-fix-can-clock-frequency-regression.patch +can-kvaser_usb-kvaser_usb_leaf-fix-bittiming-limits.patch -- 2.47.3