bcm27xx: import latest patches from the RPi foundation
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch
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
5 BCM4354
6
7 commit 5d6f391073d5c1c903ac12be72c66b96b2ae93f4 upstream.
8
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.
14
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>
18 ---
19 drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++--
20 1 file changed, 29 insertions(+), 2 deletions(-)
21
22 --- a/drivers/bluetooth/hci_bcm.c
23 +++ b/drivers/bluetooth/hci_bcm.c
24 @@ -48,6 +48,14 @@
25 #define BCM_NUM_SUPPLIES 2
26
27 /**
28 + * struct bcm_device_data - device specific data
29 + * @no_early_set_baudrate: Disallow set baudrate before driver setup()
30 + */
31 +struct bcm_device_data {
32 + bool no_early_set_baudrate;
33 +};
34 +
35 +/**
36 * struct bcm_device - device driver resources
37 * @serdev_hu: HCI UART controller struct
38 * @list: bcm_device_list node
39 @@ -79,6 +87,7 @@
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()
44 */
45 struct bcm_device {
46 /* Must be the first member, hci_serdev.c expects this. */
47 @@ -113,6 +122,7 @@ struct bcm_device {
48 struct hci_uart *hu;
49 bool is_suspended;
50 #endif
51 + bool no_early_set_baudrate;
52 };
53
54 /* generic bcm uart resources */
55 @@ -450,7 +460,13 @@ out:
56 if (bcm->dev) {
57 hci_uart_set_flow_control(hu, true);
58 hu->init_speed = bcm->dev->init_speed;
59 - hu->oper_speed = bcm->dev->oper_speed;
60 +
61 + /* If oper_speed is set, ldisc/serdev will set the baudrate
62 + * before calling setup()
63 + */
64 + if (!bcm->dev->no_early_set_baudrate)
65 + hu->oper_speed = bcm->dev->oper_speed;
66 +
67 err = bcm_gpio_set_power(bcm->dev, true);
68 hci_uart_set_flow_control(hu, false);
69 if (err)
70 @@ -568,6 +584,8 @@ static int bcm_setup(struct hci_uart *hu
71 /* Operational speed if any */
72 if (hu->oper_speed)
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;
78 else
79 @@ -1377,6 +1395,7 @@ static struct platform_driver bcm_driver
80 static int bcm_serdev_probe(struct serdev_device *serdev)
81 {
82 struct bcm_device *bcmdev;
83 + const struct bcm_device_data *data;
84 int err;
85
86 bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
87 @@ -1411,6 +1430,10 @@ static int bcm_serdev_probe(struct serde
88 if (err)
89 dev_err(&serdev->dev, "Failed to power down\n");
90
91 + data = device_get_match_data(bcmdev->dev);
92 + if (data)
93 + bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
94 +
95 return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
96 }
97
98 @@ -1422,12 +1445,16 @@ static void bcm_serdev_remove(struct ser
99 }
100
101 #ifdef CONFIG_OF
102 +static struct bcm_device_data bcm4354_device_data = {
103 + .no_early_set_baudrate = true,
104 +};
105 +
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" },
114 { },
115 };