1 From 4c40c6ae0510be0fc9626d1717ff4163358cbfb2 Mon Sep 17 00:00:00 2001
2 From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
3 Date: Tue, 26 Nov 2019 08:17:29 +0100
4 Subject: [PATCH] Bluetooth: hci_bcm: Disallow set_baudrate for
7 commit 5d6f391073d5c1c903ac12be72c66b96b2ae93f4 upstream.
9 Without updating the patchram, the BCM4354 does not support a higher
10 operating speed. The normal bcm_setup follows the correct order
11 (init_speed, patchram and then oper_speed) but the serdev driver will
12 set the operating speed before calling the hu->setup function. Thus,
13 for the BCM4354, don't set the operating speed before patchram.
15 Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
16 Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
17 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
19 drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++--
20 1 file changed, 29 insertions(+), 2 deletions(-)
22 --- a/drivers/bluetooth/hci_bcm.c
23 +++ b/drivers/bluetooth/hci_bcm.c
25 #define BCM_NUM_SUPPLIES 2
28 + * struct bcm_device_data - device specific data
29 + * @no_early_set_baudrate: Disallow set baudrate before driver setup()
31 +struct bcm_device_data {
32 + bool no_early_set_baudrate;
36 * struct bcm_device - device driver resources
37 * @serdev_hu: HCI UART controller struct
38 * @list: bcm_device_list node
40 * @hu: pointer to HCI UART controller struct,
41 * used to disable flow control during runtime suspend and system sleep
42 * @is_suspended: whether flow control is currently disabled
43 + * @no_early_set_baudrate: don't set_baudrate before setup()
46 /* Must be the first member, hci_serdev.c expects this. */
47 @@ -113,6 +122,7 @@ struct bcm_device {
51 + bool no_early_set_baudrate;
54 /* generic bcm uart resources */
55 @@ -450,7 +460,13 @@ out:
57 hci_uart_set_flow_control(hu, true);
58 hu->init_speed = bcm->dev->init_speed;
59 - hu->oper_speed = bcm->dev->oper_speed;
61 + /* If oper_speed is set, ldisc/serdev will set the baudrate
62 + * before calling setup()
64 + if (!bcm->dev->no_early_set_baudrate)
65 + hu->oper_speed = bcm->dev->oper_speed;
67 err = bcm_gpio_set_power(bcm->dev, true);
68 hci_uart_set_flow_control(hu, false);
70 @@ -568,6 +584,8 @@ static int bcm_setup(struct hci_uart *hu
71 /* Operational speed if any */
73 speed = hu->oper_speed;
74 + else if (bcm->dev && bcm->dev->oper_speed)
75 + speed = bcm->dev->oper_speed;
76 else if (hu->proto->oper_speed)
77 speed = hu->proto->oper_speed;
79 @@ -1377,6 +1395,7 @@ static struct platform_driver bcm_driver
80 static int bcm_serdev_probe(struct serdev_device *serdev)
82 struct bcm_device *bcmdev;
83 + const struct bcm_device_data *data;
86 bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
87 @@ -1411,6 +1430,10 @@ static int bcm_serdev_probe(struct serde
89 dev_err(&serdev->dev, "Failed to power down\n");
91 + data = device_get_match_data(bcmdev->dev);
93 + bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
95 return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
98 @@ -1422,12 +1445,16 @@ static void bcm_serdev_remove(struct ser
102 +static struct bcm_device_data bcm4354_device_data = {
103 + .no_early_set_baudrate = true,
106 static const struct of_device_id bcm_bluetooth_of_match[] = {
107 { .compatible = "brcm,bcm20702a1" },
108 { .compatible = "brcm,bcm4345c5" },
109 { .compatible = "brcm,bcm4330-bt" },
110 { .compatible = "brcm,bcm43438-bt" },
111 - { .compatible = "brcm,bcm43540-bt" },
112 + { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
113 { .compatible = "brcm,bcm4335a0" },