From f79ba4300202210eb10b3d41f70ef2b8538fa5c4 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Sat, 15 Dec 2018 02:22:17 -0500 Subject: 6lowpan: convert to DEFINE_SHOW_ATTRIBUTE Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code. Signed-off-by: Yangtao Li Signed-off-by: Marcel Holtmann --- net/6lowpan/debugfs.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/net/6lowpan/debugfs.c b/net/6lowpan/debugfs.c index 24915e0bb9ea..6c152f9ea26e 100644 --- a/net/6lowpan/debugfs.c +++ b/net/6lowpan/debugfs.c @@ -232,18 +232,7 @@ static int lowpan_context_show(struct seq_file *file, void *offset) return 0; } - -static int lowpan_context_open(struct inode *inode, struct file *file) -{ - return single_open(file, lowpan_context_show, inode->i_private); -} - -static const struct file_operations lowpan_context_fops = { - .open = lowpan_context_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(lowpan_context); static int lowpan_short_addr_get(void *data, u64 *val) { -- cgit v1.2.3-55-g7522 From 8e2924e383b714748e5891ac9ff2f5c945666891 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 5 Nov 2018 09:56:19 -0500 Subject: Bluetooth: Change to use DEFINE_SHOW_ATTRIBUTE macro Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code. Signed-off-by: Yangtao Li Reviewed-by: Kees Cook Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 12 +----------- net/bluetooth/rfcomm/core.c | 12 +----------- net/bluetooth/rfcomm/sock.c | 12 +----------- net/bluetooth/sco.c | 12 +----------- 4 files changed, 4 insertions(+), 44 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2146e0f3b6f8..2a7fb517d460 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -7650,17 +7650,7 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) return 0; } -static int l2cap_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, l2cap_debugfs_show, inode->i_private); -} - -static const struct file_operations l2cap_debugfs_fops = { - .open = l2cap_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(l2cap_debugfs); static struct dentry *l2cap_debugfs; diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index b98225d65e87..1a635df80643 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -2166,17 +2166,7 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) return 0; } -static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private); -} - -static const struct file_operations rfcomm_dlc_debugfs_fops = { - .open = rfcomm_dlc_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(rfcomm_dlc_debugfs); static struct dentry *rfcomm_dlc_debugfs; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index d606e9212291..aa0db1d1bd9b 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -1020,17 +1020,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) return 0; } -static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, rfcomm_sock_debugfs_show, inode->i_private); -} - -static const struct file_operations rfcomm_sock_debugfs_fops = { - .open = rfcomm_sock_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(rfcomm_sock_debugfs); static struct dentry *rfcomm_sock_debugfs; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 8f0f9279eac9..529b38996d8b 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1173,17 +1173,7 @@ static int sco_debugfs_show(struct seq_file *f, void *p) return 0; } -static int sco_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, sco_debugfs_show, inode->i_private); -} - -static const struct file_operations sco_debugfs_fops = { - .open = sco_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(sco_debugfs); static struct dentry *sco_debugfs; -- cgit v1.2.3-55-g7522 From 6ae81eebdef97109c32e545e90865bc5b14178f1 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:35 +0800 Subject: dt-bindings: net: broadcom-bluetooth: Fix external clock names The Broadcom Bluetooth controllers can take up to two external clocks: an external frequency reference, substituting the main crystal, and a LPO clock at 32.768 kHz substituting the internal LPO clock. In particular, the external LPO clock must be used when the controller does not have NVRAM connected, and the main reference frequency is not the default 20 MHz. This is described in detail in the datasheet. The original "extclk" clock name is ambiguous as to which of these it refers to, and some designs might even require both. This patch deprecates the existing name, and adds "txco" and "lpo". Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/net/broadcom-bluetooth.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt index 4194ff7e6ee6..711c75ac2bb5 100644 --- a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt @@ -18,8 +18,11 @@ Optional properties: - shutdown-gpios: GPIO specifier, used to enable the BT module - device-wakeup-gpios: GPIO specifier, used to wakeup the controller - host-wakeup-gpios: GPIO specifier, used to wakeup the host processor - - clocks: clock specifier if external clock provided to the controller - - clock-names: should be "extclk" + - clocks: 1 or 2 clocks as defined in clock-names below, in that order + - clock-names: names for clock inputs, matching the clocks given + - "extclk": deprecated, replaced by "txco" + - "txco": external reference clock (not a standalone crystal) + - "lpo": external low power 32.768 kHz clock Example: -- cgit v1.2.3-55-g7522 From 061a8aaf4c0f2885f1fa1dd6bf8ea27ab5059fa9 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:36 +0800 Subject: dt-bindings: net: broadcom-bluetooth: Add VBAT and VDDIO supplies The Broadcom Bluetooth chips have two power inputs, VBAT and VDDIO. The former provides overall power for the chip, while the latter powers the I/O pins and buffers. This patch adds properties for the two so we can describe the power supply relationships. Reviewed-by: Rob Herring Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/net/broadcom-bluetooth.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt index 711c75ac2bb5..78cfa0fbece9 100644 --- a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt @@ -23,6 +23,8 @@ Optional properties: - "extclk": deprecated, replaced by "txco" - "txco": external reference clock (not a standalone crystal) - "lpo": external low power 32.768 kHz clock + - vbat-supply: phandle to regulator supply for VBAT + - vddio-supply: phandle to regulator supply for VDDIO Example: -- cgit v1.2.3-55-g7522 From bfbc47bd5901168f0fdb337e9be1759bedf8ff4e Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:37 +0800 Subject: dt-bindings: net: broadcom-bluetooth: Add BCM20702A1 compatible string The BCM20702A1 is a Bluetooth 4.0 chip from Broadcom. It is found in the Ampak AP6210 WiFi+BT module, identified from the read verbose config info command response. However the Bluetooth firmware provided by vendors uses the name BCM20710. This patch elects to use the chip ID returned by the chip for the compatible string. Reviewed-by: Rob Herring Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/net/broadcom-bluetooth.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt index 78cfa0fbece9..d9d734a07faf 100644 --- a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt @@ -10,6 +10,7 @@ device the slave device is attached to. Required properties: - compatible: should contain one of the following: + * "brcm,bcm20702a1" * "brcm,bcm43438-bt" Optional properties: -- cgit v1.2.3-55-g7522 From 31f20f5f6d14ffe8d9a87c0ef58ee7ed72a3db63 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:38 +0800 Subject: dt-bindings: net: broadcom-bluetooth: Add BCM4330 compatible string The BCM4330 is a 802.11 a/b/g/n WiFi + Bluetooth 4.0 chip from Broadcom. It is found in the Ampak AP6330 WiFi+BT module. The partiular one I have identifies as BCM4330B1 for Bluetooth and BCM4330/4 for WiFi. It is unclear if the AP6330 module uses this revision of the BCM4330, or if there are multiple revisions. The module does not have revision markings. This patch elects to use just BCM4330 for the compatible string. Reviewed-by: Rob Herring Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/net/broadcom-bluetooth.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt index d9d734a07faf..c26f4e11037c 100644 --- a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt @@ -11,6 +11,7 @@ Required properties: - compatible: should contain one of the following: * "brcm,bcm20702a1" + * "brcm,bcm4330-bt" * "brcm,bcm43438-bt" Optional properties: -- cgit v1.2.3-55-g7522 From 28ac03b9ac3f784c2f048a910c8d0a7a87483b66 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:39 +0800 Subject: Bluetooth: hci_bcm: Handle deferred probing for the clock supply On some systems that actually have the bluetooth controller wired up with an extra clock signal, it's possible the bluetooth controller probes before the clock provider. clk_get would return a defer probe error, which was not handled by this driver. Handle this properly, so that these systems can work reliably. Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index ddbd8c6a0ceb..800132369134 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -907,6 +907,10 @@ static int bcm_get_resources(struct bcm_device *dev) dev->clk = devm_clk_get(dev->dev, NULL); + /* Handle deferred probing */ + if (dev->clk == ERR_PTR(-EPROBE_DEFER)) + return PTR_ERR(dev->clk); + dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup", GPIOD_OUT_LOW); if (IS_ERR(dev->device_wakeup)) -- cgit v1.2.3-55-g7522 From 8c08947b7c4f4496e7c23be970121280fcb6cbf5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:40 +0800 Subject: Bluetooth: hci_bcm: Simplify clk_get error handling The driver currently checks the clk pointer for an error condition, as returned by clk_get, before every invocation of the clk consumer API. This is redundant if the goal is simply to ignore the errors, thereby making the clk optional. The clk consumer API already checks if the pointer is NULL or not. Simplify the code a bit by assigning NULL to the clk pointer if the error condition is one we want to ignore, which is every error except deferred probing. Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 800132369134..ff73ecb8215f 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -214,7 +214,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) { int err; - if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) { + if (powered && !dev->clk_enabled) { err = clk_prepare_enable(dev->clk); if (err) return err; @@ -228,7 +228,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) if (err) goto err_revert_shutdown; - if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled) + if (!powered && dev->clk_enabled) clk_disable_unprepare(dev->clk); dev->clk_enabled = powered; @@ -238,7 +238,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) err_revert_shutdown: dev->set_shutdown(dev, !powered); err_clk_disable: - if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) + if (powered && !dev->clk_enabled) clk_disable_unprepare(dev->clk); return err; } @@ -911,6 +911,10 @@ static int bcm_get_resources(struct bcm_device *dev) if (dev->clk == ERR_PTR(-EPROBE_DEFER)) return PTR_ERR(dev->clk); + /* Ignore all other errors as before */ + if (IS_ERR(dev->clk)) + dev->clk = NULL; + dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup", GPIOD_OUT_LOW); if (IS_ERR(dev->device_wakeup)) -- cgit v1.2.3-55-g7522 From 55dbfcd0f621a745acfd8e3221c41be181b5b128 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:41 +0800 Subject: Bluetooth: hci_bcm: Use "txco" and "extclk" to get clock reference Originally the device tree binding only specified one clock reference, with the name "extclk". The driver simply retrieves the clock without bothering to specify a name. Since we added a second clock to the binding, we need to fetch the clocks by name now. First we try the new name "txco", then fall back to the old name "extclk", and finally try retrieving a clock without using any name, to cover any instances where a bad device tree or firmware worked by accident. In the last case, we should take care that we don't get the same clock twice when we add support for the "lpo" clock. Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index ff73ecb8215f..1584c95c9c34 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -71,8 +71,8 @@ * @btlp: Apple ACPI method to toggle BT_WAKE pin ("Bluetooth Low Power") * @btpu: Apple ACPI method to drive BT_REG_ON pin high ("Bluetooth Power Up") * @btpd: Apple ACPI method to drive BT_REG_ON pin low ("Bluetooth Power Down") - * @clk: clock used by Bluetooth device - * @clk_enabled: whether @clk is prepared and enabled + * @txco_clk: external reference frequency clock used by Bluetooth device + * @clk_enabled: whether @txco_clk is prepared and enabled * @init_speed: default baudrate of Bluetooth device; * the host UART is initially set to this baudrate so that * it can configure the Bluetooth device for @oper_speed @@ -102,7 +102,7 @@ struct bcm_device { int gpio_int_idx; #endif - struct clk *clk; + struct clk *txco_clk; bool clk_enabled; u32 init_speed; @@ -215,7 +215,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) int err; if (powered && !dev->clk_enabled) { - err = clk_prepare_enable(dev->clk); + err = clk_prepare_enable(dev->txco_clk); if (err) return err; } @@ -229,7 +229,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) goto err_revert_shutdown; if (!powered && dev->clk_enabled) - clk_disable_unprepare(dev->clk); + clk_disable_unprepare(dev->txco_clk); dev->clk_enabled = powered; @@ -239,7 +239,7 @@ err_revert_shutdown: dev->set_shutdown(dev, !powered); err_clk_disable: if (powered && !dev->clk_enabled) - clk_disable_unprepare(dev->clk); + clk_disable_unprepare(dev->txco_clk); return err; } @@ -896,6 +896,25 @@ static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered) return 0; } +/* Try a bunch of names for TXCO */ +static struct clk *bcm_get_txco(struct device *dev) +{ + struct clk *clk; + + /* New explicit name */ + clk = devm_clk_get(dev, "txco"); + if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) + return clk; + + /* Deprecated name */ + clk = devm_clk_get(dev, "extclk"); + if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) + return clk; + + /* Original code used no name at all */ + return devm_clk_get(dev, NULL); +} + static int bcm_get_resources(struct bcm_device *dev) { const struct dmi_system_id *dmi_id; @@ -905,15 +924,15 @@ static int bcm_get_resources(struct bcm_device *dev) if (x86_apple_machine && !bcm_apple_get_resources(dev)) return 0; - dev->clk = devm_clk_get(dev->dev, NULL); + dev->txco_clk = bcm_get_txco(dev->dev); /* Handle deferred probing */ - if (dev->clk == ERR_PTR(-EPROBE_DEFER)) - return PTR_ERR(dev->clk); + if (dev->txco_clk == ERR_PTR(-EPROBE_DEFER)) + return PTR_ERR(dev->txco_clk); /* Ignore all other errors as before */ - if (IS_ERR(dev->clk)) - dev->clk = NULL; + if (IS_ERR(dev->txco_clk)) + dev->txco_clk = NULL; dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup", GPIOD_OUT_LOW); -- cgit v1.2.3-55-g7522 From 90bc07cc59ac32f37d6de78a501246575c8866bf Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:42 +0800 Subject: Bluetooth: hci_bcm: Add support for LPO clock The Broadcom Bluetooth controllers support a secondary LPO clock at 32.768 kHz. This external clock provides low power timing, and also a way to detect the frequency of the main reference clock. On many designs without NVRAM and a non-default reference clock, this must be used or the controller will not function correctly. Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 1584c95c9c34..345d728a5434 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -72,7 +72,8 @@ * @btpu: Apple ACPI method to drive BT_REG_ON pin high ("Bluetooth Power Up") * @btpd: Apple ACPI method to drive BT_REG_ON pin low ("Bluetooth Power Down") * @txco_clk: external reference frequency clock used by Bluetooth device - * @clk_enabled: whether @txco_clk is prepared and enabled + * @lpo_clk: external LPO clock used by Bluetooth device + * @clk_enabled: whether clocks are prepared and enabled * @init_speed: default baudrate of Bluetooth device; * the host UART is initially set to this baudrate so that * it can configure the Bluetooth device for @oper_speed @@ -103,6 +104,7 @@ struct bcm_device { #endif struct clk *txco_clk; + struct clk *lpo_clk; bool clk_enabled; u32 init_speed; @@ -215,21 +217,34 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) int err; if (powered && !dev->clk_enabled) { - err = clk_prepare_enable(dev->txco_clk); + /* LPO clock needs to be 32.768 kHz */ + err = clk_set_rate(dev->lpo_clk, 32768); + if (err) { + dev_err(dev->dev, "Could not set LPO clock rate\n"); + return err; + } + + err = clk_prepare_enable(dev->lpo_clk); if (err) return err; + + err = clk_prepare_enable(dev->txco_clk); + if (err) + goto err_lpo_clk_disable; } err = dev->set_shutdown(dev, powered); if (err) - goto err_clk_disable; + goto err_txco_clk_disable; err = dev->set_device_wakeup(dev, powered); if (err) goto err_revert_shutdown; - if (!powered && dev->clk_enabled) + if (!powered && dev->clk_enabled) { clk_disable_unprepare(dev->txco_clk); + clk_disable_unprepare(dev->lpo_clk); + } dev->clk_enabled = powered; @@ -237,9 +252,12 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) err_revert_shutdown: dev->set_shutdown(dev, !powered); -err_clk_disable: +err_txco_clk_disable: if (powered && !dev->clk_enabled) clk_disable_unprepare(dev->txco_clk); +err_lpo_clk_disable: + if (powered && !dev->clk_enabled) + clk_disable_unprepare(dev->lpo_clk); return err; } @@ -934,6 +952,19 @@ static int bcm_get_resources(struct bcm_device *dev) if (IS_ERR(dev->txco_clk)) dev->txco_clk = NULL; + dev->lpo_clk = devm_clk_get(dev->dev, "lpo"); + if (dev->lpo_clk == ERR_PTR(-EPROBE_DEFER)) + return PTR_ERR(dev->lpo_clk); + + if (IS_ERR(dev->lpo_clk)) + dev->lpo_clk = NULL; + + /* Check if we accidentally fetched the lpo clock twice */ + if (dev->lpo_clk && clk_is_match(dev->lpo_clk, dev->txco_clk)) { + devm_clk_put(dev->dev, dev->txco_clk); + dev->txco_clk = NULL; + } + dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup", GPIOD_OUT_LOW); if (IS_ERR(dev->device_wakeup)) -- cgit v1.2.3-55-g7522 From 75d11676dccb643de1e850c8a29f5e9aa58157c0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:43 +0800 Subject: Bluetooth: hci_bcm: Add support for regulator supplies The Broadcom Bluetooth chips have two power inputs, VBAT and VDDIO. The former provides overall power for the chip, while the latter powers the I/O pins and buffers. Model these two as regulator supplies, and let the driver manage them in the same way as it does the clock supply. Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 345d728a5434..f2101038284e 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,8 @@ #define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */ +#define BCM_NUM_SUPPLIES 2 + /** * struct bcm_device - device driver resources * @serdev_hu: HCI UART controller struct @@ -73,7 +76,8 @@ * @btpd: Apple ACPI method to drive BT_REG_ON pin low ("Bluetooth Power Down") * @txco_clk: external reference frequency clock used by Bluetooth device * @lpo_clk: external LPO clock used by Bluetooth device - * @clk_enabled: whether clocks are prepared and enabled + * @supplies: VBAT and VDDIO supplies used by Bluetooth device + * @res_enabled: whether clocks and supplies are prepared and enabled * @init_speed: default baudrate of Bluetooth device; * the host UART is initially set to this baudrate so that * it can configure the Bluetooth device for @oper_speed @@ -105,7 +109,8 @@ struct bcm_device { struct clk *txco_clk; struct clk *lpo_clk; - bool clk_enabled; + struct regulator_bulk_data supplies[BCM_NUM_SUPPLIES]; + bool res_enabled; u32 init_speed; u32 oper_speed; @@ -216,17 +221,21 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) { int err; - if (powered && !dev->clk_enabled) { + if (powered && !dev->res_enabled) { + err = regulator_bulk_enable(BCM_NUM_SUPPLIES, dev->supplies); + if (err) + return err; + /* LPO clock needs to be 32.768 kHz */ err = clk_set_rate(dev->lpo_clk, 32768); if (err) { dev_err(dev->dev, "Could not set LPO clock rate\n"); - return err; + goto err_regulator_disable; } err = clk_prepare_enable(dev->lpo_clk); if (err) - return err; + goto err_regulator_disable; err = clk_prepare_enable(dev->txco_clk); if (err) @@ -241,23 +250,27 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) if (err) goto err_revert_shutdown; - if (!powered && dev->clk_enabled) { + if (!powered && dev->res_enabled) { clk_disable_unprepare(dev->txco_clk); clk_disable_unprepare(dev->lpo_clk); + regulator_bulk_disable(BCM_NUM_SUPPLIES, dev->supplies); } - dev->clk_enabled = powered; + dev->res_enabled = powered; return 0; err_revert_shutdown: dev->set_shutdown(dev, !powered); err_txco_clk_disable: - if (powered && !dev->clk_enabled) + if (powered && !dev->res_enabled) clk_disable_unprepare(dev->txco_clk); err_lpo_clk_disable: - if (powered && !dev->clk_enabled) + if (powered && !dev->res_enabled) clk_disable_unprepare(dev->lpo_clk); +err_regulator_disable: + if (powered && !dev->res_enabled) + regulator_bulk_disable(BCM_NUM_SUPPLIES, dev->supplies); return err; } @@ -936,6 +949,7 @@ static struct clk *bcm_get_txco(struct device *dev) static int bcm_get_resources(struct bcm_device *dev) { const struct dmi_system_id *dmi_id; + int err; dev->name = dev_name(dev->dev); @@ -978,6 +992,13 @@ static int bcm_get_resources(struct bcm_device *dev) dev->set_device_wakeup = bcm_gpio_set_device_wakeup; dev->set_shutdown = bcm_gpio_set_shutdown; + dev->supplies[0].supply = "vbat"; + dev->supplies[1].supply = "vddio"; + err = devm_regulator_bulk_get(dev->dev, BCM_NUM_SUPPLIES, + dev->supplies); + if (err) + return err; + /* IRQ can be declared in ACPI table as Interrupt or GpioInt */ if (dev->irq <= 0) { struct gpio_desc *gpio; -- cgit v1.2.3-55-g7522 From 91927a9b351f9779e323be1fb4e219a5951b1649 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:44 +0800 Subject: Bluetooth: hci_bcm: Wait for device to come out of reset after power on The datasheets for BCM20702 and BCM43438 both have power up time sequence graphs, however they are slightly different. Both chips also have an internal power-on-reset, which holds the chip in reset for a short time after the regulators are enabled. For the BCM20702, the time period from when the regulators are enabled, until the chip settles and comes out of sleep state, is 6564 ~ 8171 us. For the BCM43438, the graph only shows the time period from when the regulators are enabled until the chip responds by driving the host's CTS line low, assuming the host has already driven its RTS line low. This is shown to be 6.5 sleep cycles, with the sleep clock at 32.768 kHz. This is around 2 ms. Wait a full 10 ms after the regulators are enabled to account for signal rising times. Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index f2101038284e..538ce8059bff 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -256,6 +256,9 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) regulator_bulk_disable(BCM_NUM_SUPPLIES, dev->supplies); } + /* wait for device to power on and come out of reset */ + usleep_range(10000, 20000); + dev->res_enabled = powered; return 0; -- cgit v1.2.3-55-g7522 From 92ffe0db3c858ca568cf480899396e63344eab86 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 17 Dec 2018 12:04:45 +0800 Subject: Bluetooth: hci_bcm: Add BCM20702A1 variant The BCM20702A1 chip is a single-chip Bluetooth 4.0 controller and transceiver. It is found in the AMPAK AP6210 WiFi+BT package. Signed-off-by: Maxime Ripard Tested-by: Ondrej Jirman Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 6 ++++++ drivers/bluetooth/hci_bcm.c | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index e3e4d929e74f..22d4b530da03 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -33,6 +33,7 @@ #define VERSION "0.1" #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}}) +#define BDADDR_BCM20702A1 (&(bdaddr_t) {{0x00, 0x00, 0xa0, 0x02, 0x70, 0x20}}) #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}}) #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}}) @@ -64,6 +65,9 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller * with no configured address. * + * The address 20:70:02:A0:00:00 indicates a BCM20702A1 controller + * with no configured address. + * * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller * with waiting for configuration state. * @@ -71,6 +75,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) * with waiting for configuration state. */ if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) || + !bacmp(&bda->bdaddr, BDADDR_BCM20702A1) || !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || !bacmp(&bda->bdaddr, BDADDR_BCM4330B1)) { bt_dev_info(hdev, "BCM: Using default device address (%pMR)", @@ -330,6 +335,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = { { 0x2209, "BCM43430A1" }, /* 001.002.009 */ { 0x6119, "BCM4345C0" }, /* 003.001.025 */ { 0x230f, "BCM4356A2" }, /* 001.003.015 */ + { 0x220e, "BCM20702A1" }, /* 001.002.014 */ { } }; diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 538ce8059bff..8c75e7a67379 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -1396,6 +1396,7 @@ static void bcm_serdev_remove(struct serdev_device *serdev) #ifdef CONFIG_OF static const struct of_device_id bcm_bluetooth_of_match[] = { + { .compatible = "brcm,bcm20702a1" }, { .compatible = "brcm,bcm43438-bt" }, { }, }; -- cgit v1.2.3-55-g7522 From 66904555191cbcefa8aa552df018b4f56d94e3ae Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:46 +0800 Subject: Bluetooth: hci_bcm: Add compatible string for BCM4330 The BCM4330 chip is a 802.11 a/b/g/n + Bluetooth 4.0 + HS controller. This patch adds a compatible string match to the serdev driver for the Bluetooth part of the chip. Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 8c75e7a67379..a5cb580a07de 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -1397,6 +1397,7 @@ static void bcm_serdev_remove(struct serdev_device *serdev) #ifdef CONFIG_OF static const struct of_device_id bcm_bluetooth_of_match[] = { { .compatible = "brcm,bcm20702a1" }, + { .compatible = "brcm,bcm4330-bt" }, { .compatible = "brcm,bcm43438-bt" }, { }, }; -- cgit v1.2.3-55-g7522 From 0697607acab976723bf67de95d7b87167c30abf8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 17 Dec 2018 12:04:47 +0800 Subject: Bluetooth: btbcm: Add default address for BCM43430A0 The BCM43430A0 has the default MAC address 43:43:A0:12:1F:AC if none is given. This address was found when enabling Bluetooth on a bunch of boards with the AMPAK AP6210 module, all sharing the same address. It also contains the sequence 4343A0, which is suspicious as that is also the name the chip identifies itself as. Add this to the list of default MAC addresses and leave it to the user to configure a valid one. Signed-off-by: Chen-Yu Tsai Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 22d4b530da03..08e1f3dd4e03 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -34,6 +34,7 @@ #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}}) #define BDADDR_BCM20702A1 (&(bdaddr_t) {{0x00, 0x00, 0xa0, 0x02, 0x70, 0x20}}) +#define BDADDR_BCM43430A0 (&(bdaddr_t) {{0xac, 0x1f, 0x12, 0xa0, 0x43, 0x43}}) #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}}) #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}}) @@ -73,11 +74,15 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) * * The address 43:30:B1:00:00:00 indicates a BCM4330B1 controller * with waiting for configuration state. + * + * The address 43:43:A0:12:1F:AC indicates a BCM43430A0 controller + * with no configured address. */ if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) || !bacmp(&bda->bdaddr, BDADDR_BCM20702A1) || !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || - !bacmp(&bda->bdaddr, BDADDR_BCM4330B1)) { + !bacmp(&bda->bdaddr, BDADDR_BCM4330B1) || + !bacmp(&bda->bdaddr, BDADDR_BCM43430A0)) { bt_dev_info(hdev, "BCM: Using default device address (%pMR)", &bda->bdaddr); set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); -- cgit v1.2.3-55-g7522 From dff6d593b10fc04a24e07650c459947e9d6ff3c3 Mon Sep 17 00:00:00 2001 From: Andrea Parri Date: Tue, 27 Nov 2018 12:22:25 +0100 Subject: Bluetooth: Remove unnecessary smp_mb__after_atomic() barriers The barriers are redundant because atomic_test_and_clear_bit() already provides the required full ordering for the cases in question (that is, when the bit is cleared). Signed-off-by: Andrea Parri Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 8 ++------ drivers/bluetooth/hci_intel.c | 16 ++++------------ 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 7439a7eb50ac..885e17a1a9a5 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1935,10 +1935,8 @@ static void btusb_intel_bootup(struct btusb_data *data, const void *ptr, if (len != sizeof(*evt)) return; - if (test_and_clear_bit(BTUSB_BOOTING, &data->flags)) { - smp_mb__after_atomic(); + if (test_and_clear_bit(BTUSB_BOOTING, &data->flags)) wake_up_bit(&data->flags, BTUSB_BOOTING); - } } static void btusb_intel_secure_send_result(struct btusb_data *data, @@ -1953,10 +1951,8 @@ static void btusb_intel_secure_send_result(struct btusb_data *data, set_bit(BTUSB_FIRMWARE_FAILED, &data->flags); if (test_and_clear_bit(BTUSB_DOWNLOADING, &data->flags) && - test_bit(BTUSB_FIRMWARE_LOADED, &data->flags)) { - smp_mb__after_atomic(); + test_bit(BTUSB_FIRMWARE_LOADED, &data->flags)) wake_up_bit(&data->flags, BTUSB_DOWNLOADING); - } } static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb) diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 46ace321bf60..8caa1a6619ce 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -909,10 +909,8 @@ static int intel_recv_event(struct hci_dev *hdev, struct sk_buff *skb) set_bit(STATE_FIRMWARE_FAILED, &intel->flags); if (test_and_clear_bit(STATE_DOWNLOADING, &intel->flags) && - test_bit(STATE_FIRMWARE_LOADED, &intel->flags)) { - smp_mb__after_atomic(); + test_bit(STATE_FIRMWARE_LOADED, &intel->flags)) wake_up_bit(&intel->flags, STATE_DOWNLOADING); - } /* When switching to the operational firmware the device * sends a vendor specific event indicating that the bootup @@ -920,10 +918,8 @@ static int intel_recv_event(struct hci_dev *hdev, struct sk_buff *skb) */ } else if (skb->len == 9 && hdr->evt == 0xff && hdr->plen == 0x07 && skb->data[2] == 0x02) { - if (test_and_clear_bit(STATE_BOOTING, &intel->flags)) { - smp_mb__after_atomic(); + if (test_and_clear_bit(STATE_BOOTING, &intel->flags)) wake_up_bit(&intel->flags, STATE_BOOTING); - } } recv: return hci_recv_frame(hdev, skb); @@ -960,17 +956,13 @@ static int intel_recv_lpm(struct hci_dev *hdev, struct sk_buff *skb) break; case LPM_OP_SUSPEND_ACK: set_bit(STATE_SUSPENDED, &intel->flags); - if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) { - smp_mb__after_atomic(); + if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION); - } break; case LPM_OP_RESUME_ACK: clear_bit(STATE_SUSPENDED, &intel->flags); - if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) { - smp_mb__after_atomic(); + if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION); - } break; default: bt_dev_err(hdev, "Unknown LPM opcode (%02x)", lpm->opcode); -- cgit v1.2.3-55-g7522 From cba736465e5cbae22027789de748b8500e647555 Mon Sep 17 00:00:00 2001 From: Balakrishna Godavarthi Date: Thu, 22 Nov 2018 18:20:47 +0530 Subject: Bluetooth: hci_serdev: Remove setting of HCI_QUIRK_RESET_ON_CLOSE. HCI_QUIRK_RESET_ON_CLOSE quirk is required for BT v1.0 based devices, to send a reset command to the chip during hci device close. Serdev architecture is used for the latest BT chips, which doesn't require to send the reset command during close. If still chips required reset command during close, it would be better enabling it in the vendor probes or in proto setup. Signed-off-by: Balakrishna Godavarthi Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_serdev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c index c445aa9ac511..490abba94363 100644 --- a/drivers/bluetooth/hci_serdev.c +++ b/drivers/bluetooth/hci_serdev.c @@ -333,9 +333,6 @@ int hci_uart_register_device(struct hci_uart *hu, if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags)) set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks); - if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags)) - set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); - if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) hdev->dev_type = HCI_AMP; else -- cgit v1.2.3-55-g7522 From 75edd1f2f916f06248cd6a6e8ea706b44431d3eb Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 9 Nov 2018 13:27:36 +0000 Subject: Bluetooth: clean an indentation issue, remove extraneous space Trivial fix to clean up an indentation issue Signed-off-by: Colin Ian King Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index e8c9ef1e1922..ca73d36cc149 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1556,7 +1556,7 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance) connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) || mgmt_get_connectable(hdev); - if (!is_advertising_allowed(hdev, connectable)) + if (!is_advertising_allowed(hdev, connectable)) return -EPERM; /* Set require_privacy to true only when non-connectable -- cgit v1.2.3-55-g7522 From 7086b36b8080e6252162cf5d681f521738e7ced5 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 30 Oct 2018 11:34:19 +0000 Subject: Bluetooth: hci_intel: clean an indentation issue, remove extraneous spaces Trivial fix to clean up an indentation issue, remove spaces Signed-off-by: Colin Ian King Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_intel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 8caa1a6619ce..f31410526c57 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -596,8 +596,8 @@ static int intel_setup(struct hci_uart *hu) * is in bootloader mode or if it already has operational firmware * loaded. */ - err = btintel_read_version(hdev, &ver); - if (err) + err = btintel_read_version(hdev, &ver); + if (err) return err; /* The hardware platform number has a fixed value of 0x37 and -- cgit v1.2.3-55-g7522 From 28a75e4c813c7ae7de5b4baf4c29369769247cc6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 30 Oct 2018 14:17:22 +0100 Subject: Bluetooth: hci_h5: Add suspend / resume ops Add support for vendor specific suspend / resume callbacks. Signed-off-by: Hans de Goede Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_h5.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index 8eede1197cd2..beddb89a00f2 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -115,6 +115,8 @@ struct h5_vnd { int (*setup)(struct h5 *h5); void (*open)(struct h5 *h5); void (*close)(struct h5 *h5); + int (*suspend)(struct h5 *h5); + int (*resume)(struct h5 *h5); const struct acpi_gpio_mapping *acpi_gpio_map; }; @@ -841,6 +843,28 @@ static void h5_serdev_remove(struct serdev_device *serdev) hci_uart_unregister_device(&h5->serdev_hu); } +static int __maybe_unused h5_serdev_suspend(struct device *dev) +{ + struct h5 *h5 = dev_get_drvdata(dev); + int ret = 0; + + if (h5->vnd && h5->vnd->suspend) + ret = h5->vnd->suspend(h5); + + return ret; +} + +static int __maybe_unused h5_serdev_resume(struct device *dev) +{ + struct h5 *h5 = dev_get_drvdata(dev); + int ret = 0; + + if (h5->vnd && h5->vnd->resume) + ret = h5->vnd->resume(h5); + + return ret; +} + #ifdef CONFIG_BT_HCIUART_RTL static int h5_btrtl_setup(struct h5 *h5) { @@ -935,12 +959,17 @@ static const struct acpi_device_id h5_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, h5_acpi_match); #endif +static const struct dev_pm_ops h5_serdev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(h5_serdev_suspend, h5_serdev_resume) +}; + static struct serdev_device_driver h5_serdev_driver = { .probe = h5_serdev_probe, .remove = h5_serdev_remove, .driver = { .name = "hci_uart_h5", .acpi_match_table = ACPI_PTR(h5_acpi_match), + .pm = &h5_serdev_pm_ops, }, }; -- cgit v1.2.3-55-g7522 From 8589086f4efd5756d20cedd844b865e5d20164ec Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 30 Oct 2018 14:17:23 +0100 Subject: Bluetooth: hci_h5: Turn off RTL8723BS on suspend, reprobe on resume On many devices the RTL8723BS device gets reset during suspend/resume, causing it to lose its firmware and all state. Testing has shown it drops back to communicating at 115200 bps and sends sync-request packages, indicating it has been fully reset. This commit fixes this by queueing a reprobe on resume. This mirrors how USB RTL BT devices, which have the same problem, are handled in the btusb driver, there we set the USB_QUIRK_RESET_RESUME for all RTL devices, which also causes a reprobe on resume. The only difference is that here we need to do the reprobe ourselves. Since we are doing a full reprobe on resume now, we can also turn off the device on suspend to save power while suspended. Signed-off-by: Hans de Goede Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_h5.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index beddb89a00f2..069d1c8fde73 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -931,6 +931,56 @@ static void h5_btrtl_close(struct h5 *h5) gpiod_set_value_cansleep(h5->enable_gpio, 0); } +/* Suspend/resume support. On many devices the RTL BT device loses power during + * suspend/resume, causing it to lose its firmware and all state. So we simply + * turn it off on suspend and reprobe on resume. This mirrors how RTL devices + * are handled in the USB driver, where the USB_QUIRK_RESET_RESUME is used which + * also causes a reprobe on resume. + */ +static int h5_btrtl_suspend(struct h5 *h5) +{ + serdev_device_set_flow_control(h5->hu->serdev, false); + gpiod_set_value_cansleep(h5->device_wake_gpio, 0); + gpiod_set_value_cansleep(h5->enable_gpio, 0); + return 0; +} + +struct h5_btrtl_reprobe { + struct device *dev; + struct work_struct work; +}; + +static void h5_btrtl_reprobe_worker(struct work_struct *work) +{ + struct h5_btrtl_reprobe *reprobe = + container_of(work, struct h5_btrtl_reprobe, work); + int ret; + + ret = device_reprobe(reprobe->dev); + if (ret && ret != -EPROBE_DEFER) + dev_err(reprobe->dev, "Reprobe error %d\n", ret); + + put_device(reprobe->dev); + kfree(reprobe); + module_put(THIS_MODULE); +} + +static int h5_btrtl_resume(struct h5 *h5) +{ + struct h5_btrtl_reprobe *reprobe; + + reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL); + if (!reprobe) + return -ENOMEM; + + __module_get(THIS_MODULE); + + INIT_WORK(&reprobe->work, h5_btrtl_reprobe_worker); + reprobe->dev = get_device(&h5->hu->serdev->dev); + queue_work(system_long_wq, &reprobe->work); + return 0; +} + static const struct acpi_gpio_params btrtl_device_wake_gpios = { 0, 0, false }; static const struct acpi_gpio_params btrtl_enable_gpios = { 1, 0, false }; static const struct acpi_gpio_params btrtl_host_wake_gpios = { 2, 0, false }; @@ -945,6 +995,8 @@ static struct h5_vnd rtl_vnd = { .setup = h5_btrtl_setup, .open = h5_btrtl_open, .close = h5_btrtl_close, + .suspend = h5_btrtl_suspend, + .resume = h5_btrtl_resume, .acpi_gpio_map = acpi_btrtl_gpios, }; #endif -- cgit v1.2.3-55-g7522 From 2da711bcebe81209a9f2f90e145600eb1bae2b71 Mon Sep 17 00:00:00 2001 From: Raghuram Hegde Date: Wed, 19 Dec 2018 11:42:18 +0530 Subject: Bluetooth: btusb: Add support for Intel bluetooth device 8087:0029 Include the new USB product ID for Intel Bluetooth device 22260 family(CcPeak) The /sys/kernel/debug/usb/devices portion for this device is: T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=02 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=8087 ProdID=0029 Rev= 0.01 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms Signed-off-by: Raghuram Hegde Signed-off-by: Chethan T N Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 72 ++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 885e17a1a9a5..4761499db9ee 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -344,6 +344,7 @@ static const struct usb_device_id blacklist_table[] = { /* Intel Bluetooth devices */ { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW }, { USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW }, + { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW }, { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL }, @@ -2051,6 +2052,35 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb) return -EILSEQ; } +static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver, + struct intel_boot_params *params, + char *fw_name, size_t len, + const char *suffix) +{ + switch (ver->hw_variant) { + case 0x0b: /* SfP */ + case 0x0c: /* WsP */ + snprintf(fw_name, len, "intel/ibt-%u-%u.%s", + le16_to_cpu(ver->hw_variant), + le16_to_cpu(params->dev_revid), + suffix); + break; + case 0x11: /* JfP */ + case 0x12: /* ThP */ + case 0x13: /* HrP */ + case 0x14: /* CcP */ + snprintf(fw_name, len, "intel/ibt-%u-%u-%u.%s", + le16_to_cpu(ver->hw_variant), + le16_to_cpu(ver->hw_revision), + le16_to_cpu(ver->fw_revision), + suffix); + break; + default: + return false; + } + return true; +} + static int btusb_setup_intel_new(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -2102,7 +2132,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) case 0x11: /* JfP */ case 0x12: /* ThP */ case 0x13: /* HrP */ - case 0x14: /* QnJ, IcP */ + case 0x14: /* CcP */ break; default: bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)", @@ -2186,23 +2216,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * ibt---.sfi. * */ - switch (ver.hw_variant) { - case 0x0b: /* SfP */ - case 0x0c: /* WsP */ - snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi", - le16_to_cpu(ver.hw_variant), - le16_to_cpu(params.dev_revid)); - break; - case 0x11: /* JfP */ - case 0x12: /* ThP */ - case 0x13: /* HrP */ - case 0x14: /* QnJ, IcP */ - snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.sfi", - le16_to_cpu(ver.hw_variant), - le16_to_cpu(ver.hw_revision), - le16_to_cpu(ver.fw_revision)); - break; - default: + err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, fwname, + sizeof(fwname), "sfi"); + if (!err) { bt_dev_err(hdev, "Unsupported Intel firmware naming"); return -EINVAL; } @@ -2218,23 +2234,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) /* Save the DDC file name for later use to apply once the firmware * downloading is done. */ - switch (ver.hw_variant) { - case 0x0b: /* SfP */ - case 0x0c: /* WsP */ - snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.ddc", - le16_to_cpu(ver.hw_variant), - le16_to_cpu(params.dev_revid)); - break; - case 0x11: /* JfP */ - case 0x12: /* ThP */ - case 0x13: /* HrP */ - case 0x14: /* QnJ, IcP */ - snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.ddc", - le16_to_cpu(ver.hw_variant), - le16_to_cpu(ver.hw_revision), - le16_to_cpu(ver.fw_revision)); - break; - default: + err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, fwname, + sizeof(fwname), "ddc"); + if (!err) { bt_dev_err(hdev, "Unsupported Intel firmware naming"); return -EINVAL; } -- cgit v1.2.3-55-g7522 From e3ca60d06cf37ea57d77eb834dca418f9c2dea81 Mon Sep 17 00:00:00 2001 From: Paweł Chmiel Date: Wed, 19 Dec 2018 12:22:46 +0100 Subject: Bluetooth: btbcm: Add entry for BCM4329B1 UART bluetooth This patch adds the device ID for the BCM 4329 combo module used in the Samsung Aries based phones (Galaxy S and it's variants). ``` [ 11.508980] Bluetooth: hci0: BCM: chip id 41 [ 11.518975] Bluetooth: hci0: BCM: features 0x04 [ 11.550132] Bluetooth: hci0: BCM4329B1 [ 11.557046] Bluetooth: hci0: BCM4329B1 (002.002.023) build 0000 [ 13.737071] Bluetooth: hci0: BCM4329B1 (002.002.023) build 0744 ``` Output from hciconfig ``` hci0: Type: Primary Bus: UART BD Address: 43:29:B1:55:00:00 ACL MTU: 1021:6 SCO MTU: 64:1 UP RUNNING RX bytes:1675 acl:0 sco:0 events:145 errors:0 TX bytes:20426 acl:0 sco:0 commands:146 errors:0 Features: 0xbf 0xfe 0x8f 0xfe 0x9b 0xff 0x79 0x83 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: RSWITCH SNIFF Link mode: SLAVE ACCEPT Name: 'aries' Class: 0x000000 Service Classes: Unspecified Device Class: Miscellaneous, HCI Version: 2.1 (0x4) Revision: 0x2e8 LMP Version: 2.1 (0x4) Subversion: 0x4217 Manufacturer: Broadcom Corporation (15) ``` Signed-off-by: Paweł Chmiel Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 08e1f3dd4e03..d5d6e6e5da3b 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -341,6 +341,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = { { 0x6119, "BCM4345C0" }, /* 003.001.025 */ { 0x230f, "BCM4356A2" }, /* 001.003.015 */ { 0x220e, "BCM20702A1" }, /* 001.002.014 */ + { 0x4217, "BCM4329B1" }, /* 002.002.023 */ { } }; -- cgit v1.2.3-55-g7522 From 22bba80500fdf624a7cfbb65fdfa97a038ae224d Mon Sep 17 00:00:00 2001 From: Jonathan Bakker Date: Wed, 19 Dec 2018 12:22:28 +0100 Subject: Bluetooth: hci_bcm: Handle specific unknown packets after firmware loading The Broadcom controller on aries S5PV210 boards sends out a couple of unknown packets after the firmware is loaded. This will cause logging of errors such as: Bluetooth: hci0: Frame reassembly failed (-84) This is probably also the case with other boards, as there are related Android userspace patches for custom ROMs such as https://review.lineageos.org/#/c/LineageOS/android_system_bt/+/142721/ Since this appears to be intended behaviour, treated them as diagnostic packets. Note that this is another variant of commit 01d5e44ace8a ("Bluetooth: hci_bcm: Handle empty packet after firmware loading") Signed-off-by: Jonathan Bakker Signed-off-by: Paweł Chmiel Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index a5cb580a07de..ddbe518c3e5b 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -52,6 +52,12 @@ #define BCM_LM_DIAG_PKT 0x07 #define BCM_LM_DIAG_SIZE 63 +#define BCM_TYPE49_PKT 0x31 +#define BCM_TYPE49_SIZE 0 + +#define BCM_TYPE52_PKT 0x34 +#define BCM_TYPE52_SIZE 0 + #define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */ #define BCM_NUM_SUPPLIES 2 @@ -595,12 +601,28 @@ finalize: .lsize = 0, \ .maxlen = BCM_NULL_SIZE +#define BCM_RECV_TYPE49 \ + .type = BCM_TYPE49_PKT, \ + .hlen = BCM_TYPE49_SIZE, \ + .loff = 0, \ + .lsize = 0, \ + .maxlen = BCM_TYPE49_SIZE + +#define BCM_RECV_TYPE52 \ + .type = BCM_TYPE52_PKT, \ + .hlen = BCM_TYPE52_SIZE, \ + .loff = 0, \ + .lsize = 0, \ + .maxlen = BCM_TYPE52_SIZE + static const struct h4_recv_pkt bcm_recv_pkts[] = { { H4_RECV_ACL, .recv = hci_recv_frame }, { H4_RECV_SCO, .recv = hci_recv_frame }, { H4_RECV_EVENT, .recv = hci_recv_frame }, { BCM_RECV_LM_DIAG, .recv = hci_recv_diag }, { BCM_RECV_NULL, .recv = hci_recv_diag }, + { BCM_RECV_TYPE49, .recv = hci_recv_diag }, + { BCM_RECV_TYPE52, .recv = hci_recv_diag }, }; static int bcm_recv(struct hci_uart *hu, const void *data, int count) -- cgit v1.2.3-55-g7522 From 1629db9c75342325868243d6bca5853017d91cf8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 27 Nov 2018 11:37:46 +0200 Subject: Bluetooth: Fix unnecessary error message for HCI request completion In case a command which completes in Command Status was sent using the hci_cmd_send-family of APIs there would be a misleading error in the hci_get_cmd_complete function, since the code would be trying to fetch the Command Complete parameters when there are none. Avoid the misleading error and silently bail out from the function in case the received event is a command status. Signed-off-by: Johan Hedberg Acked-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index ef9928d7b4fb..ac2826ce162b 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5711,6 +5711,12 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, return true; } + /* Check if request ended in Command Status - no way to retreive + * any extra parameters in this case. + */ + if (hdr->evt == HCI_EV_CMD_STATUS) + return false; + if (hdr->evt != HCI_EV_CMD_COMPLETE) { bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)", hdr->evt); -- cgit v1.2.3-55-g7522