Commit 29d3c047 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2018-12-19

Here's the main bluetooth-next pull request for 4.21:

 - Multiple fixes & improvements for Broadcom-based controllers
 - New USB ID for an Intel controller
 - Support for new Broadcom controller variants
 - Use DEFINE_SHOW_ATTRIBUTE to simplify debugfs code
 - Eliminate confusing "last event is not cmd complete" warning message
 - Added vendor suspend/resume support for H:5 (3-Wire UART) controllers
 - Various other smaller improvements & fixes

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5a862f86 1629db9c
...@@ -10,6 +10,8 @@ device the slave device is attached to. ...@@ -10,6 +10,8 @@ device the slave device is attached to.
Required properties: Required properties:
- compatible: should contain one of the following: - compatible: should contain one of the following:
* "brcm,bcm20702a1"
* "brcm,bcm4330-bt"
* "brcm,bcm43438-bt" * "brcm,bcm43438-bt"
Optional properties: Optional properties:
...@@ -18,8 +20,13 @@ Optional properties: ...@@ -18,8 +20,13 @@ Optional properties:
- shutdown-gpios: GPIO specifier, used to enable the BT module - shutdown-gpios: GPIO specifier, used to enable the BT module
- device-wakeup-gpios: GPIO specifier, used to wakeup the controller - device-wakeup-gpios: GPIO specifier, used to wakeup the controller
- host-wakeup-gpios: GPIO specifier, used to wakeup the host processor - host-wakeup-gpios: GPIO specifier, used to wakeup the host processor
- clocks: clock specifier if external clock provided to the controller - clocks: 1 or 2 clocks as defined in clock-names below, in that order
- clock-names: should be "extclk" - 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
- vbat-supply: phandle to regulator supply for VBAT
- vddio-supply: phandle to regulator supply for VDDIO
Example: Example:
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define VERSION "0.1" #define VERSION "0.1"
#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}}) #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_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}})
#define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}}) #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}})
...@@ -64,15 +66,23 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) ...@@ -64,15 +66,23 @@ int btbcm_check_bdaddr(struct hci_dev *hdev)
* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
* with no configured address. * 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 * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller
* with waiting for configuration state. * with waiting for configuration state.
* *
* The address 43:30:B1:00:00:00 indicates a BCM4330B1 controller * The address 43:30:B1:00:00:00 indicates a BCM4330B1 controller
* with waiting for configuration state. * 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) || if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) ||
!bacmp(&bda->bdaddr, BDADDR_BCM20702A1) ||
!bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || !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)", bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
&bda->bdaddr); &bda->bdaddr);
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
...@@ -330,6 +340,8 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = { ...@@ -330,6 +340,8 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
{ 0x2209, "BCM43430A1" }, /* 001.002.009 */ { 0x2209, "BCM43430A1" }, /* 001.002.009 */
{ 0x6119, "BCM4345C0" }, /* 003.001.025 */ { 0x6119, "BCM4345C0" }, /* 003.001.025 */
{ 0x230f, "BCM4356A2" }, /* 001.003.015 */ { 0x230f, "BCM4356A2" }, /* 001.003.015 */
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */
{ 0x4217, "BCM4329B1" }, /* 002.002.023 */
{ } { }
}; };
......
...@@ -344,6 +344,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -344,6 +344,7 @@ static const struct usb_device_id blacklist_table[] = {
/* Intel Bluetooth devices */ /* Intel Bluetooth devices */
{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW }, { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW },
{ USB_DEVICE(0x8087, 0x0026), .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, 0x07da), .driver_info = BTUSB_CSR },
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
...@@ -1935,10 +1936,8 @@ static void btusb_intel_bootup(struct btusb_data *data, const void *ptr, ...@@ -1935,10 +1936,8 @@ static void btusb_intel_bootup(struct btusb_data *data, const void *ptr,
if (len != sizeof(*evt)) if (len != sizeof(*evt))
return; return;
if (test_and_clear_bit(BTUSB_BOOTING, &data->flags)) { if (test_and_clear_bit(BTUSB_BOOTING, &data->flags))
smp_mb__after_atomic();
wake_up_bit(&data->flags, BTUSB_BOOTING); wake_up_bit(&data->flags, BTUSB_BOOTING);
}
} }
static void btusb_intel_secure_send_result(struct btusb_data *data, static void btusb_intel_secure_send_result(struct btusb_data *data,
...@@ -1953,10 +1952,8 @@ static void btusb_intel_secure_send_result(struct btusb_data *data, ...@@ -1953,10 +1952,8 @@ static void btusb_intel_secure_send_result(struct btusb_data *data,
set_bit(BTUSB_FIRMWARE_FAILED, &data->flags); set_bit(BTUSB_FIRMWARE_FAILED, &data->flags);
if (test_and_clear_bit(BTUSB_DOWNLOADING, &data->flags) && if (test_and_clear_bit(BTUSB_DOWNLOADING, &data->flags) &&
test_bit(BTUSB_FIRMWARE_LOADED, &data->flags)) { test_bit(BTUSB_FIRMWARE_LOADED, &data->flags))
smp_mb__after_atomic();
wake_up_bit(&data->flags, BTUSB_DOWNLOADING); wake_up_bit(&data->flags, BTUSB_DOWNLOADING);
}
} }
static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb) static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb)
...@@ -2055,6 +2052,35 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2055,6 +2052,35 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
return -EILSEQ; 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) static int btusb_setup_intel_new(struct hci_dev *hdev)
{ {
struct btusb_data *data = hci_get_drvdata(hdev); struct btusb_data *data = hci_get_drvdata(hdev);
...@@ -2106,7 +2132,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) ...@@ -2106,7 +2132,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
case 0x11: /* JfP */ case 0x11: /* JfP */
case 0x12: /* ThP */ case 0x12: /* ThP */
case 0x13: /* HrP */ case 0x13: /* HrP */
case 0x14: /* QnJ, IcP */ case 0x14: /* CcP */
break; break;
default: default:
bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)", bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
...@@ -2190,23 +2216,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) ...@@ -2190,23 +2216,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi. * ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
* *
*/ */
switch (ver.hw_variant) { err = btusb_setup_intel_new_get_fw_name(&ver, &params, fwname,
case 0x0b: /* SfP */ sizeof(fwname), "sfi");
case 0x0c: /* WsP */ if (!err) {
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:
bt_dev_err(hdev, "Unsupported Intel firmware naming"); bt_dev_err(hdev, "Unsupported Intel firmware naming");
return -EINVAL; return -EINVAL;
} }
...@@ -2222,23 +2234,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) ...@@ -2222,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 /* Save the DDC file name for later use to apply once the firmware
* downloading is done. * downloading is done.
*/ */
switch (ver.hw_variant) { err = btusb_setup_intel_new_get_fw_name(&ver, &params, fwname,
case 0x0b: /* SfP */ sizeof(fwname), "ddc");
case 0x0c: /* WsP */ if (!err) {
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:
bt_dev_err(hdev, "Unsupported Intel firmware naming"); bt_dev_err(hdev, "Unsupported Intel firmware naming");
return -EINVAL; return -EINVAL;
} }
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/property.h> #include <linux/property.h>
#include <linux/platform_data/x86/apple.h> #include <linux/platform_data/x86/apple.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/tty.h> #include <linux/tty.h>
...@@ -51,8 +52,16 @@ ...@@ -51,8 +52,16 @@
#define BCM_LM_DIAG_PKT 0x07 #define BCM_LM_DIAG_PKT 0x07
#define BCM_LM_DIAG_SIZE 63 #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_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */
#define BCM_NUM_SUPPLIES 2
/** /**
* struct bcm_device - device driver resources * struct bcm_device - device driver resources
* @serdev_hu: HCI UART controller struct * @serdev_hu: HCI UART controller struct
...@@ -71,8 +80,10 @@ ...@@ -71,8 +80,10 @@
* @btlp: Apple ACPI method to toggle BT_WAKE pin ("Bluetooth Low Power") * @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") * @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") * @btpd: Apple ACPI method to drive BT_REG_ON pin low ("Bluetooth Power Down")
* @clk: clock used by Bluetooth device * @txco_clk: external reference frequency clock used by Bluetooth device
* @clk_enabled: whether @clk is prepared and enabled * @lpo_clk: external LPO clock used by Bluetooth device
* @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; * @init_speed: default baudrate of Bluetooth device;
* the host UART is initially set to this baudrate so that * the host UART is initially set to this baudrate so that
* it can configure the Bluetooth device for @oper_speed * it can configure the Bluetooth device for @oper_speed
...@@ -102,8 +113,10 @@ struct bcm_device { ...@@ -102,8 +113,10 @@ struct bcm_device {
int gpio_int_idx; int gpio_int_idx;
#endif #endif
struct clk *clk; struct clk *txco_clk;
bool clk_enabled; struct clk *lpo_clk;
struct regulator_bulk_data supplies[BCM_NUM_SUPPLIES];
bool res_enabled;
u32 init_speed; u32 init_speed;
u32 oper_speed; u32 oper_speed;
...@@ -214,32 +227,59 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) ...@@ -214,32 +227,59 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
{ {
int err; int err;
if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) { if (powered && !dev->res_enabled) {
err = clk_prepare_enable(dev->clk); err = regulator_bulk_enable(BCM_NUM_SUPPLIES, dev->supplies);
if (err) if (err)
return 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");
goto err_regulator_disable;
}
err = clk_prepare_enable(dev->lpo_clk);
if (err)
goto err_regulator_disable;
err = clk_prepare_enable(dev->txco_clk);
if (err)
goto err_lpo_clk_disable;
} }
err = dev->set_shutdown(dev, powered); err = dev->set_shutdown(dev, powered);
if (err) if (err)
goto err_clk_disable; goto err_txco_clk_disable;
err = dev->set_device_wakeup(dev, powered); err = dev->set_device_wakeup(dev, powered);
if (err) if (err)
goto err_revert_shutdown; goto err_revert_shutdown;
if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled) if (!powered && dev->res_enabled) {
clk_disable_unprepare(dev->clk); clk_disable_unprepare(dev->txco_clk);
clk_disable_unprepare(dev->lpo_clk);
regulator_bulk_disable(BCM_NUM_SUPPLIES, dev->supplies);
}
/* wait for device to power on and come out of reset */
usleep_range(10000, 20000);
dev->clk_enabled = powered; dev->res_enabled = powered;
return 0; return 0;
err_revert_shutdown: err_revert_shutdown:
dev->set_shutdown(dev, !powered); dev->set_shutdown(dev, !powered);
err_clk_disable: err_txco_clk_disable:
if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) if (powered && !dev->res_enabled)
clk_disable_unprepare(dev->clk); clk_disable_unprepare(dev->txco_clk);
err_lpo_clk_disable:
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; return err;
} }
...@@ -561,12 +601,28 @@ static int bcm_setup(struct hci_uart *hu) ...@@ -561,12 +601,28 @@ static int bcm_setup(struct hci_uart *hu)
.lsize = 0, \ .lsize = 0, \
.maxlen = BCM_NULL_SIZE .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[] = { static const struct h4_recv_pkt bcm_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame }, { H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame }, { H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame }, { H4_RECV_EVENT, .recv = hci_recv_frame },
{ BCM_RECV_LM_DIAG, .recv = hci_recv_diag }, { BCM_RECV_LM_DIAG, .recv = hci_recv_diag },
{ BCM_RECV_NULL, .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) static int bcm_recv(struct hci_uart *hu, const void *data, int count)
...@@ -896,16 +952,57 @@ static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered) ...@@ -896,16 +952,57 @@ static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered)
return 0; 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) static int bcm_get_resources(struct bcm_device *dev)
{ {
const struct dmi_system_id *dmi_id; const struct dmi_system_id *dmi_id;
int err;
dev->name = dev_name(dev->dev); dev->name = dev_name(dev->dev);
if (x86_apple_machine && !bcm_apple_get_resources(dev)) if (x86_apple_machine && !bcm_apple_get_resources(dev))
return 0; return 0;
dev->clk = devm_clk_get(dev->dev, NULL); dev->txco_clk = bcm_get_txco(dev->dev);
/* Handle deferred probing */
if (dev->txco_clk == ERR_PTR(-EPROBE_DEFER))
return PTR_ERR(dev->txco_clk);
/* Ignore all other errors as before */
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", dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup",
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
...@@ -920,6 +1017,13 @@ static int bcm_get_resources(struct bcm_device *dev) ...@@ -920,6 +1017,13 @@ static int bcm_get_resources(struct bcm_device *dev)
dev->set_device_wakeup = bcm_gpio_set_device_wakeup; dev->set_device_wakeup = bcm_gpio_set_device_wakeup;
dev->set_shutdown = bcm_gpio_set_shutdown; 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 */ /* IRQ can be declared in ACPI table as Interrupt or GpioInt */
if (dev->irq <= 0) { if (dev->irq <= 0) {
struct gpio_desc *gpio; struct gpio_desc *gpio;
...@@ -1314,6 +1418,8 @@ static void bcm_serdev_remove(struct serdev_device *serdev) ...@@ -1314,6 +1418,8 @@ static void bcm_serdev_remove(struct serdev_device *serdev)
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id bcm_bluetooth_of_match[] = { static const struct of_device_id bcm_bluetooth_of_match[] = {
{ .compatible = "brcm,bcm20702a1" },
{ .compatible = "brcm,bcm4330-bt" },
{ .compatible = "brcm,bcm43438-bt" }, { .compatible = "brcm,bcm43438-bt" },
{ }, { },
}; };
......
...@@ -115,6 +115,8 @@ struct h5_vnd { ...@@ -115,6 +115,8 @@ struct h5_vnd {
int (*setup)(struct h5 *h5); int (*setup)(struct h5 *h5);
void (*open)(struct h5 *h5); void (*open)(struct h5 *h5);
void (*close)(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; const struct acpi_gpio_mapping *acpi_gpio_map;
}; };
...@@ -841,6 +843,28 @@ static void h5_serdev_remove(struct serdev_device *serdev) ...@@ -841,6 +843,28 @@ static void h5_serdev_remove(struct serdev_device *serdev)
hci_uart_unregister_device(&h5->serdev_hu); 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 #ifdef CONFIG_BT_HCIUART_RTL
static int h5_btrtl_setup(struct h5 *h5) static int h5_btrtl_setup(struct h5 *h5)
{ {
...@@ -907,6 +931,56 @@ static void h5_btrtl_close(struct h5 *h5) ...@@ -907,6 +931,56 @@ static void h5_btrtl_close(struct h5 *h5)
gpiod_set_value_cansleep(h5->enable_gpio, 0); 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_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_enable_gpios = { 1, 0, false };
static const struct acpi_gpio_params btrtl_host_wake_gpios = { 2, 0, false }; static const struct acpi_gpio_params btrtl_host_wake_gpios = { 2, 0, false };
...@@ -921,6 +995,8 @@ static struct h5_vnd rtl_vnd = { ...@@ -921,6 +995,8 @@ static struct h5_vnd rtl_vnd = {
.setup = h5_btrtl_setup, .setup = h5_btrtl_setup,
.open = h5_btrtl_open, .open = h5_btrtl_open,
.close = h5_btrtl_close, .close = h5_btrtl_close,
.suspend = h5_btrtl_suspend,
.resume = h5_btrtl_resume,
.acpi_gpio_map = acpi_btrtl_gpios, .acpi_gpio_map = acpi_btrtl_gpios,
}; };
#endif #endif
...@@ -935,12 +1011,17 @@ static const struct acpi_device_id h5_acpi_match[] = { ...@@ -935,12 +1011,17 @@ static const struct acpi_device_id h5_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, h5_acpi_match); MODULE_DEVICE_TABLE(acpi, h5_acpi_match);
#endif #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 = { static struct serdev_device_driver h5_serdev_driver = {
.probe = h5_serdev_probe, .probe = h5_serdev_probe,
.remove = h5_serdev_remove, .remove = h5_serdev_remove,
.driver = { .driver = {
.name = "hci_uart_h5", .name = "hci_uart_h5",
.acpi_match_table = ACPI_PTR(h5_acpi_match), .acpi_match_table = ACPI_PTR(h5_acpi_match),
.pm = &h5_serdev_pm_ops,
}, },
}; };
......
...@@ -596,8 +596,8 @@ static int intel_setup(struct hci_uart *hu) ...@@ -596,8 +596,8 @@ static int intel_setup(struct hci_uart *hu)
* is in bootloader mode or if it already has operational firmware * is in bootloader mode or if it already has operational firmware
* loaded. * loaded.
*/ */
err = btintel_read_version(hdev, &ver); err = btintel_read_version(hdev, &ver);
if (err) if (err)
return err; return err;
/* The hardware platform number has a fixed value of 0x37 and /* The hardware platform number has a fixed value of 0x37 and
...@@ -909,10 +909,8 @@ static int intel_recv_event(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -909,10 +909,8 @@ static int intel_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
set_bit(STATE_FIRMWARE_FAILED, &intel->flags); set_bit(STATE_FIRMWARE_FAILED, &intel->flags);
if (test_and_clear_bit(STATE_DOWNLOADING, &intel->flags) && if (test_and_clear_bit(STATE_DOWNLOADING, &intel->flags) &&
test_bit(STATE_FIRMWARE_LOADED, &intel->flags)) { test_bit(STATE_FIRMWARE_LOADED, &intel->flags))
smp_mb__after_atomic();
wake_up_bit(&intel->flags, STATE_DOWNLOADING); wake_up_bit(&intel->flags, STATE_DOWNLOADING);
}
/* When switching to the operational firmware the device /* When switching to the operational firmware the device
* sends a vendor specific event indicating that the bootup * 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) ...@@ -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 && } else if (skb->len == 9 && hdr->evt == 0xff && hdr->plen == 0x07 &&
skb->data[2] == 0x02) { skb->data[2] == 0x02) {
if (test_and_clear_bit(STATE_BOOTING, &intel->flags)) { if (test_and_clear_bit(STATE_BOOTING, &intel->flags))
smp_mb__after_atomic();
wake_up_bit(&intel->flags, STATE_BOOTING); wake_up_bit(&intel->flags, STATE_BOOTING);
}
} }
recv: recv:
return hci_recv_frame(hdev, skb); return hci_recv_frame(hdev, skb);
...@@ -960,17 +956,13 @@ static int intel_recv_lpm(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -960,17 +956,13 @@ static int intel_recv_lpm(struct hci_dev *hdev, struct sk_buff *skb)
break; break;
case LPM_OP_SUSPEND_ACK: case LPM_OP_SUSPEND_ACK:
set_bit(STATE_SUSPENDED, &intel->flags); set_bit(STATE_SUSPENDED, &intel->flags);
if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) { if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags))
smp_mb__after_atomic();
wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION); wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION);
}
break; break;
case LPM_OP_RESUME_ACK: case LPM_OP_RESUME_ACK:
clear_bit(STATE_SUSPENDED, &intel->flags); clear_bit(STATE_SUSPENDED, &intel->flags);
if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) { if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags))
smp_mb__after_atomic();
wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION); wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION);
}
break; break;
default: default:
bt_dev_err(hdev, "Unknown LPM opcode (%02x)", lpm->opcode); bt_dev_err(hdev, "Unknown LPM opcode (%02x)", lpm->opcode);
......
...@@ -333,9 +333,6 @@ int hci_uart_register_device(struct hci_uart *hu, ...@@ -333,9 +333,6 @@ int hci_uart_register_device(struct hci_uart *hu,
if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags)) if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks); 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)) if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
hdev->dev_type = HCI_AMP; hdev->dev_type = HCI_AMP;
else else
......
...@@ -232,18 +232,7 @@ static int lowpan_context_show(struct seq_file *file, void *offset) ...@@ -232,18 +232,7 @@ static int lowpan_context_show(struct seq_file *file, void *offset)
return 0; return 0;
} }
DEFINE_SHOW_ATTRIBUTE(lowpan_context);
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,
};
static int lowpan_short_addr_get(void *data, u64 *val) static int lowpan_short_addr_get(void *data, u64 *val)
{ {
......
...@@ -5711,6 +5711,12 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, ...@@ -5711,6 +5711,12 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
return true; 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) { if (hdr->evt != HCI_EV_CMD_COMPLETE) {
bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)", bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
hdr->evt); hdr->evt);
......
...@@ -1556,7 +1556,7 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance) ...@@ -1556,7 +1556,7 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) || connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
mgmt_get_connectable(hdev); mgmt_get_connectable(hdev);
if (!is_advertising_allowed(hdev, connectable)) if (!is_advertising_allowed(hdev, connectable))
return -EPERM; return -EPERM;
/* Set require_privacy to true only when non-connectable /* Set require_privacy to true only when non-connectable
......
...@@ -7650,17 +7650,7 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) ...@@ -7650,17 +7650,7 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
return 0; return 0;
} }
static int l2cap_debugfs_open(struct inode *inode, struct file *file) DEFINE_SHOW_ATTRIBUTE(l2cap_debugfs);
{
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,
};
static struct dentry *l2cap_debugfs; static struct dentry *l2cap_debugfs;
......
...@@ -2166,17 +2166,7 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) ...@@ -2166,17 +2166,7 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
return 0; return 0;
} }
static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file) DEFINE_SHOW_ATTRIBUTE(rfcomm_dlc_debugfs);
{
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,
};
static struct dentry *rfcomm_dlc_debugfs; static struct dentry *rfcomm_dlc_debugfs;
......
...@@ -1020,17 +1020,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) ...@@ -1020,17 +1020,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
return 0; return 0;
} }
static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file) DEFINE_SHOW_ATTRIBUTE(rfcomm_sock_debugfs);
{
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,
};
static struct dentry *rfcomm_sock_debugfs; static struct dentry *rfcomm_sock_debugfs;
......
...@@ -1173,17 +1173,7 @@ static int sco_debugfs_show(struct seq_file *f, void *p) ...@@ -1173,17 +1173,7 @@ static int sco_debugfs_show(struct seq_file *f, void *p)
return 0; return 0;
} }
static int sco_debugfs_open(struct inode *inode, struct file *file) DEFINE_SHOW_ATTRIBUTE(sco_debugfs);
{
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,
};
static struct dentry *sco_debugfs; static struct dentry *sco_debugfs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment