aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch115
1 files changed, 115 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch b/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch
new file mode 100644
index 0000000000..da8f37b3dd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch
@@ -0,0 +1,115 @@
+From 4c40c6ae0510be0fc9626d1717ff4163358cbfb2 Mon Sep 17 00:00:00 2001
+From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Date: Tue, 26 Nov 2019 08:17:29 +0100
+Subject: [PATCH] Bluetooth: hci_bcm: Disallow set_baudrate for
+ BCM4354
+
+commit 5d6f391073d5c1c903ac12be72c66b96b2ae93f4 upstream.
+
+Without updating the patchram, the BCM4354 does not support a higher
+operating speed. The normal bcm_setup follows the correct order
+(init_speed, patchram and then oper_speed) but the serdev driver will
+set the operating speed before calling the hu->setup function. Thus,
+for the BCM4354, don't set the operating speed before patchram.
+
+Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+---
+ drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -48,6 +48,14 @@
+ #define BCM_NUM_SUPPLIES 2
+
+ /**
++ * struct bcm_device_data - device specific data
++ * @no_early_set_baudrate: Disallow set baudrate before driver setup()
++ */
++struct bcm_device_data {
++ bool no_early_set_baudrate;
++};
++
++/**
+ * struct bcm_device - device driver resources
+ * @serdev_hu: HCI UART controller struct
+ * @list: bcm_device_list node
+@@ -79,6 +87,7 @@
+ * @hu: pointer to HCI UART controller struct,
+ * used to disable flow control during runtime suspend and system sleep
+ * @is_suspended: whether flow control is currently disabled
++ * @no_early_set_baudrate: don't set_baudrate before setup()
+ */
+ struct bcm_device {
+ /* Must be the first member, hci_serdev.c expects this. */
+@@ -113,6 +122,7 @@ struct bcm_device {
+ struct hci_uart *hu;
+ bool is_suspended;
+ #endif
++ bool no_early_set_baudrate;
+ };
+
+ /* generic bcm uart resources */
+@@ -450,7 +460,13 @@ out:
+ if (bcm->dev) {
+ hci_uart_set_flow_control(hu, true);
+ hu->init_speed = bcm->dev->init_speed;
+- hu->oper_speed = bcm->dev->oper_speed;
++
++ /* If oper_speed is set, ldisc/serdev will set the baudrate
++ * before calling setup()
++ */
++ if (!bcm->dev->no_early_set_baudrate)
++ hu->oper_speed = bcm->dev->oper_speed;
++
+ err = bcm_gpio_set_power(bcm->dev, true);
+ hci_uart_set_flow_control(hu, false);
+ if (err)
+@@ -568,6 +584,8 @@ static int bcm_setup(struct hci_uart *hu
+ /* Operational speed if any */
+ if (hu->oper_speed)
+ speed = hu->oper_speed;
++ else if (bcm->dev && bcm->dev->oper_speed)
++ speed = bcm->dev->oper_speed;
+ else if (hu->proto->oper_speed)
+ speed = hu->proto->oper_speed;
+ else
+@@ -1377,6 +1395,7 @@ static struct platform_driver bcm_driver
+ static int bcm_serdev_probe(struct serdev_device *serdev)
+ {
+ struct bcm_device *bcmdev;
++ const struct bcm_device_data *data;
+ int err;
+
+ bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
+@@ -1411,6 +1430,10 @@ static int bcm_serdev_probe(struct serde
+ if (err)
+ dev_err(&serdev->dev, "Failed to power down\n");
+
++ data = device_get_match_data(bcmdev->dev);
++ if (data)
++ bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
++
+ return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
+ }
+
+@@ -1422,12 +1445,16 @@ static void bcm_serdev_remove(struct ser
+ }
+
+ #ifdef CONFIG_OF
++static struct bcm_device_data bcm4354_device_data = {
++ .no_early_set_baudrate = true,
++};
++
+ static const struct of_device_id bcm_bluetooth_of_match[] = {
+ { .compatible = "brcm,bcm20702a1" },
+ { .compatible = "brcm,bcm4345c5" },
+ { .compatible = "brcm,bcm4330-bt" },
+ { .compatible = "brcm,bcm43438-bt" },
+- { .compatible = "brcm,bcm43540-bt" },
++ { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
+ { .compatible = "brcm,bcm4335a0" },
+ { },
+ };