From: Phil Elwell Date: Fri, 7 Oct 2022 08:50:42 +0000 (+0100) Subject: Bluetooth: btbcm: Allow board-specific firmware names X-Git-Tag: accepted/tizen/unified/20230118.172025~318 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=54d44290debae98ac25416742a7534046b011125;p=platform%2Fkernel%2Flinux-rpi.git Bluetooth: btbcm: Allow board-specific firmware names There are some devices available from multiple vendors that report the same ID. In order to load the appropriate firmware, use the board name from the FDT as a disambiguating factor, as is done for WLAN firmwares. Signed-off-by: Phil Elwell --- diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index a18f289..ee18cfc 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,7 @@ #define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}}) #define BCM_FW_NAME_LEN 64 -#define BCM_FW_NAME_COUNT_MAX 2 +#define BCM_FW_NAME_COUNT_MAX 3 /* For kmalloc-ing the fw-name array instead of putting it on the stack */ typedef char bcm_fw_name[BCM_FW_NAME_LEN]; @@ -485,6 +486,8 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done) struct hci_rp_read_local_version *ver; const struct bcm_subver_table *bcm_subver_table; const char *hw_name = NULL; + struct device_node *root; + char *board_type = NULL; char postfix[16] = ""; int fw_name_count = 0; bcm_fw_name *fw_name; @@ -550,6 +553,30 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done) if (!fw_name) return -ENOMEM; + root = of_find_node_by_path("/"); + if (root) { + int i, len; + const char *tmp; + + of_property_read_string_index(root, "compatible", 0, &tmp); + + /* convert '/'s in the compatible string to '-'s */ + len = strlen(tmp) + 1; + board_type = kzalloc(len, GFP_KERNEL); + strscpy(board_type, tmp, len); + for (i = 0; i < board_type[i]; i++) { + if (board_type[i] == '/') + board_type[i] = '-'; + } + + of_node_put(root); + } + + if (hw_name && board_type && + snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN, + "brcm/%s.%s.hcd", hw_name, board_type) < BCM_FW_NAME_LEN) + fw_name_count++; + if (hw_name) { snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN, "brcm/%s%s.hcd", hw_name, postfix); @@ -583,6 +610,7 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done) } kfree(fw_name); + kfree(board_type); return 0; } EXPORT_SYMBOL_GPL(btbcm_initialize);