Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ device the slave device is attached to.
Required properties:

 - compatible: should contain one of the following:
   * "brcm,bcm20702a1"
   * "brcm,bcm4330-bt"
   * "brcm,bcm43438-bt"

Optional properties:
@@ -18,8 +20,13 @@ 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
 - vbat-supply: phandle to regulator supply for VBAT
 - vddio-supply: phandle to regulator supply for VDDIO


Example:
+13 −1
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#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_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}})

@@ -64,15 +66,23 @@ 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.
	 *
	 * 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);
@@ -330,6 +340,8 @@ 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 */
	{ 0x4217, "BCM4329B1"   },	/* 002.002.023 */
	{ }
};

+39 −41
Original line number Diff line number Diff line
@@ -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 },
@@ -1935,11 +1936,9 @@ 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,
					   const void *ptr, unsigned int len)
@@ -1953,11 +1952,9 @@ 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)
{
@@ -2055,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);
@@ -2106,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)",
@@ -2190,23 +2216,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
	 * ibt-<hw_variant>-<hw_revision>-<fw_revision>.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, &params, fwname,
						sizeof(fwname), "sfi");
	if (!err) {
		bt_dev_err(hdev, "Unsupported Intel firmware naming");
		return -EINVAL;
	}
@@ -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
	 * 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, &params, fwname,
						sizeof(fwname), "ddc");
	if (!err) {
		bt_dev_err(hdev, "Unsupported Intel firmware naming");
		return -EINVAL;
	}
+120 −14
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/property.h>
#include <linux/platform_data/x86/apple.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
#include <linux/tty.h>
@@ -51,8 +52,16 @@
#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

/**
 * struct bcm_device - device driver resources
 * @serdev_hu: HCI UART controller struct
@@ -71,8 +80,10 @@
 * @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
 * @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;
 *	the host UART is initially set to this baudrate so that
 *	it can configure the Bluetooth device for @oper_speed
@@ -102,8 +113,10 @@ struct bcm_device {
	int			gpio_int_idx;
#endif

	struct clk		*clk;
	bool			clk_enabled;
	struct clk		*txco_clk;
	struct clk		*lpo_clk;
	struct regulator_bulk_data supplies[BCM_NUM_SUPPLIES];
	bool			res_enabled;

	u32			init_speed;
	u32			oper_speed;
@@ -214,32 +227,59 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
{
	int err;

	if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) {
		err = clk_prepare_enable(dev->clk);
	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");
			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);
	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 && !IS_ERR(dev->clk) && dev->clk_enabled)
		clk_disable_unprepare(dev->clk);
	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;
	/* wait for device to power on and come out of reset */
	usleep_range(10000, 20000);

	dev->res_enabled = powered;

	return 0;

err_revert_shutdown:
	dev->set_shutdown(dev, !powered);
err_clk_disable:
	if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled)
		clk_disable_unprepare(dev->clk);
err_txco_clk_disable:
	if (powered && !dev->res_enabled)
		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;
}

@@ -561,12 +601,28 @@ static int bcm_setup(struct hci_uart *hu)
	.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)
@@ -896,16 +952,57 @@ 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;
	int err;

	dev->name = dev_name(dev->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->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",
						     GPIOD_OUT_LOW);
@@ -920,6 +1017,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;
@@ -1314,6 +1418,8 @@ 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" },
	{ },
};
+81 −0
Original line number Diff line number Diff line
@@ -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)
{
@@ -907,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 };
@@ -921,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
@@ -935,12 +1011,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,
	},
};

Loading