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-01-11 Here's likely the last bluetooth-next pull request for the 4.16 kernel. - Added support for Bluetooth on 2015+ MacBook (Pro) - Fix to QCA Rome suspend/resume handling - Two new QCA_ROME USB IDs in btusb - A few other minor fixes Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3d93e33780
|
@ -77,6 +77,7 @@ config BT_HCIBTSDIO
|
|||
config BT_HCIUART
|
||||
tristate "HCI UART driver"
|
||||
depends on SERIAL_DEV_BUS || !SERIAL_DEV_BUS
|
||||
depends on NVMEM || !NVMEM
|
||||
depends on TTY
|
||||
help
|
||||
Bluetooth HCI UART driver.
|
||||
|
@ -107,6 +108,7 @@ config BT_HCIUART_NOKIA
|
|||
tristate "UART Nokia H4+ protocol support"
|
||||
depends on BT_HCIUART
|
||||
depends on BT_HCIUART_SERDEV
|
||||
depends on GPIOLIB
|
||||
depends on PM
|
||||
select BT_HCIUART_H4
|
||||
select BT_BCM
|
||||
|
@ -168,6 +170,7 @@ config BT_HCIUART_3WIRE
|
|||
config BT_HCIUART_INTEL
|
||||
bool "Intel protocol support"
|
||||
depends on BT_HCIUART
|
||||
depends on GPIOLIB
|
||||
select BT_HCIUART_H4
|
||||
select BT_INTEL
|
||||
help
|
||||
|
@ -181,6 +184,7 @@ config BT_HCIUART_BCM
|
|||
depends on BT_HCIUART
|
||||
depends on BT_HCIUART_SERDEV
|
||||
depends on (!ACPI || SERIAL_DEV_CTRL_TTYPORT)
|
||||
depends on GPIOLIB
|
||||
select BT_HCIUART_H4
|
||||
select BT_BCM
|
||||
help
|
||||
|
|
|
@ -259,7 +259,7 @@ static int bpa10x_flush(struct hci_dev *hdev)
|
|||
|
||||
static int bpa10x_setup(struct hci_dev *hdev)
|
||||
{
|
||||
const u8 req[] = { 0x07 };
|
||||
static const u8 req[] = { 0x07 };
|
||||
struct sk_buff *skb;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
|
|
@ -44,8 +44,8 @@ struct bcm_set_sleep_mode {
|
|||
__u8 tristate_control;
|
||||
__u8 usb_auto_sleep;
|
||||
__u8 usb_resume_timeout;
|
||||
__u8 pulsed_host_wake;
|
||||
__u8 break_to_host;
|
||||
__u8 pulsed_host_wake;
|
||||
} __packed;
|
||||
|
||||
struct bcm_set_pcm_int_params {
|
||||
|
|
|
@ -75,7 +75,7 @@ EXPORT_SYMBOL_GPL(btintel_check_bdaddr);
|
|||
|
||||
int btintel_enter_mfg(struct hci_dev *hdev)
|
||||
{
|
||||
const u8 param[] = { 0x01, 0x00 };
|
||||
static const u8 param[] = { 0x01, 0x00 };
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/quirks.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
@ -264,6 +265,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
/* QCA ROME chipset */
|
||||
{ USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x0cf3, 0xe301), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
|
||||
|
@ -271,6 +273,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x0489, 0xe09f), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x0489, 0xe0a2), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x04ca, 0x3015), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x04ca, 0x3016), .driver_info = BTUSB_QCA_ROME },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
|
@ -388,9 +391,8 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
#define BTUSB_FIRMWARE_LOADED 7
|
||||
#define BTUSB_FIRMWARE_FAILED 8
|
||||
#define BTUSB_BOOTING 9
|
||||
#define BTUSB_RESET_RESUME 10
|
||||
#define BTUSB_DIAG_RUNNING 11
|
||||
#define BTUSB_OOB_WAKE_ENABLED 12
|
||||
#define BTUSB_DIAG_RUNNING 10
|
||||
#define BTUSB_OOB_WAKE_ENABLED 11
|
||||
|
||||
struct btusb_data {
|
||||
struct hci_dev *hdev;
|
||||
|
@ -3121,9 +3123,9 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
|
||||
/* QCA Rome devices lose their updated firmware over suspend,
|
||||
* but the USB hub doesn't notice any status change.
|
||||
* Explicitly request a device reset on resume.
|
||||
* explicitly request a device reset on resume.
|
||||
*/
|
||||
set_bit(BTUSB_RESET_RESUME, &data->flags);
|
||||
interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BT_HCIBTUSB_RTL
|
||||
|
@ -3134,7 +3136,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
* but the USB hub doesn't notice any status change.
|
||||
* Explicitly request a device reset on resume.
|
||||
*/
|
||||
set_bit(BTUSB_RESET_RESUME, &data->flags);
|
||||
interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3303,14 +3305,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
|
|||
enable_irq(data->oob_wake_irq);
|
||||
}
|
||||
|
||||
/* Optionally request a device reset on resume, but only when
|
||||
* wakeups are disabled. If wakeups are enabled we assume the
|
||||
* device will stay powered up throughout suspend.
|
||||
*/
|
||||
if (test_bit(BTUSB_RESET_RESUME, &data->flags) &&
|
||||
!device_may_wakeup(&data->udev->dev))
|
||||
data->udev->reset_resume = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/platform_data/x86/apple.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
@ -52,7 +53,37 @@
|
|||
|
||||
#define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */
|
||||
|
||||
/* device driver resources */
|
||||
/**
|
||||
* struct bcm_device - device driver resources
|
||||
* @serdev_hu: HCI UART controller struct
|
||||
* @list: bcm_device_list node
|
||||
* @dev: physical UART slave
|
||||
* @name: device name logged by bt_dev_*() functions
|
||||
* @device_wakeup: BT_WAKE pin,
|
||||
* assert = Bluetooth device must wake up or remain awake,
|
||||
* deassert = Bluetooth device may sleep when sleep criteria are met
|
||||
* @shutdown: BT_REG_ON pin,
|
||||
* power up or power down Bluetooth device internal regulators
|
||||
* @set_device_wakeup: callback to toggle BT_WAKE pin
|
||||
* either by accessing @device_wakeup or by calling @btlp
|
||||
* @set_shutdown: callback to toggle BT_REG_ON pin
|
||||
* either by accessing @shutdown or by calling @btpu/@btpd
|
||||
* @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
|
||||
* @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
|
||||
* @oper_speed: preferred baudrate of Bluetooth device;
|
||||
* set to 0 if @init_speed is already the preferred baudrate
|
||||
* @irq: interrupt triggered by HOST_WAKE_BT pin
|
||||
* @irq_active_low: whether @irq is active low
|
||||
* @hu: pointer to HCI UART controller struct,
|
||||
* used to disable flow control during runtime suspend and system sleep
|
||||
* @is_suspended: whether flow control is currently disabled
|
||||
*/
|
||||
struct bcm_device {
|
||||
/* Must be the first member, hci_serdev.c expects this. */
|
||||
struct hci_uart serdev_hu;
|
||||
|
@ -63,6 +94,11 @@ struct bcm_device {
|
|||
const char *name;
|
||||
struct gpio_desc *device_wakeup;
|
||||
struct gpio_desc *shutdown;
|
||||
int (*set_device_wakeup)(struct bcm_device *, bool);
|
||||
int (*set_shutdown)(struct bcm_device *, bool);
|
||||
#ifdef CONFIG_ACPI
|
||||
acpi_handle btlp, btpu, btpd;
|
||||
#endif
|
||||
|
||||
struct clk *clk;
|
||||
bool clk_enabled;
|
||||
|
@ -74,7 +110,7 @@ struct bcm_device {
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
struct hci_uart *hu;
|
||||
bool is_suspended; /* suspend/resume flag */
|
||||
bool is_suspended;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -170,11 +206,21 @@ static bool bcm_device_exists(struct bcm_device *device)
|
|||
|
||||
static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
|
||||
{
|
||||
if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled)
|
||||
clk_prepare_enable(dev->clk);
|
||||
int err;
|
||||
|
||||
gpiod_set_value(dev->shutdown, powered);
|
||||
gpiod_set_value(dev->device_wakeup, powered);
|
||||
if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) {
|
||||
err = clk_prepare_enable(dev->clk);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = dev->set_shutdown(dev, powered);
|
||||
if (err)
|
||||
goto err_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);
|
||||
|
@ -182,6 +228,13 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
|
|||
dev->clk_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);
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -191,9 +244,7 @@ static irqreturn_t bcm_host_wake(int irq, void *data)
|
|||
|
||||
bt_dev_dbg(bdev, "Host wake IRQ");
|
||||
|
||||
pm_runtime_get(bdev->dev);
|
||||
pm_runtime_mark_last_busy(bdev->dev);
|
||||
pm_runtime_put_autosuspend(bdev->dev);
|
||||
pm_request_resume(bdev->dev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -218,8 +269,10 @@ static int bcm_request_irq(struct bcm_data *bcm)
|
|||
bdev->irq_active_low ? IRQF_TRIGGER_FALLING :
|
||||
IRQF_TRIGGER_RISING,
|
||||
"host_wake", bdev);
|
||||
if (err)
|
||||
if (err) {
|
||||
bdev->irq = err;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
device_init_wakeup(bdev->dev, true);
|
||||
|
||||
|
@ -247,8 +300,8 @@ static const struct bcm_set_sleep_mode default_sleep_params = {
|
|||
/* Irrelevant USB flags */
|
||||
.usb_auto_sleep = 0,
|
||||
.usb_resume_timeout = 0,
|
||||
.break_to_host = 0,
|
||||
.pulsed_host_wake = 0,
|
||||
.break_to_host = 0
|
||||
};
|
||||
|
||||
static int bcm_setup_sleep(struct hci_uart *hu)
|
||||
|
@ -304,6 +357,7 @@ static int bcm_open(struct hci_uart *hu)
|
|||
{
|
||||
struct bcm_data *bcm;
|
||||
struct list_head *p;
|
||||
int err;
|
||||
|
||||
bt_dev_dbg(hu->hdev, "hu %p", hu);
|
||||
|
||||
|
@ -318,7 +372,10 @@ static int bcm_open(struct hci_uart *hu)
|
|||
mutex_lock(&bcm_device_lock);
|
||||
|
||||
if (hu->serdev) {
|
||||
serdev_device_open(hu->serdev);
|
||||
err = serdev_device_open(hu->serdev);
|
||||
if (err)
|
||||
goto err_free;
|
||||
|
||||
bcm->dev = serdev_device_get_drvdata(hu->serdev);
|
||||
goto out;
|
||||
}
|
||||
|
@ -346,17 +403,30 @@ out:
|
|||
if (bcm->dev) {
|
||||
hu->init_speed = bcm->dev->init_speed;
|
||||
hu->oper_speed = bcm->dev->oper_speed;
|
||||
bcm_gpio_set_power(bcm->dev, true);
|
||||
err = bcm_gpio_set_power(bcm->dev, true);
|
||||
if (err)
|
||||
goto err_unset_hu;
|
||||
}
|
||||
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
return 0;
|
||||
|
||||
err_unset_hu:
|
||||
#ifdef CONFIG_PM
|
||||
bcm->dev->hu = NULL;
|
||||
#endif
|
||||
err_free:
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
hu->priv = NULL;
|
||||
kfree(bcm);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int bcm_close(struct hci_uart *hu)
|
||||
{
|
||||
struct bcm_data *bcm = hu->priv;
|
||||
struct bcm_device *bdev = NULL;
|
||||
int err;
|
||||
|
||||
bt_dev_dbg(hu->hdev, "hu %p", hu);
|
||||
|
||||
|
@ -374,16 +444,17 @@ static int bcm_close(struct hci_uart *hu)
|
|||
}
|
||||
|
||||
if (bdev) {
|
||||
bcm_gpio_set_power(bdev, false);
|
||||
#ifdef CONFIG_PM
|
||||
pm_runtime_disable(bdev->dev);
|
||||
pm_runtime_set_suspended(bdev->dev);
|
||||
|
||||
if (device_can_wakeup(bdev->dev)) {
|
||||
if (IS_ENABLED(CONFIG_PM) && bdev->irq > 0) {
|
||||
devm_free_irq(bdev->dev, bdev->irq, bdev);
|
||||
device_init_wakeup(bdev->dev, false);
|
||||
pm_runtime_disable(bdev->dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
err = bcm_gpio_set_power(bdev, false);
|
||||
if (err)
|
||||
bt_dev_err(hu->hdev, "Failed to power down");
|
||||
else
|
||||
pm_runtime_set_suspended(bdev->dev);
|
||||
}
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
|
||||
|
@ -512,11 +583,8 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
|
|||
} else if (!bcm->rx_skb) {
|
||||
/* Delay auto-suspend when receiving completed packet */
|
||||
mutex_lock(&bcm_device_lock);
|
||||
if (bcm->dev && bcm_device_exists(bcm->dev)) {
|
||||
pm_runtime_get(bcm->dev->dev);
|
||||
pm_runtime_mark_last_busy(bcm->dev->dev);
|
||||
pm_runtime_put_autosuspend(bcm->dev->dev);
|
||||
}
|
||||
if (bcm->dev && bcm_device_exists(bcm->dev))
|
||||
pm_request_resume(bcm->dev->dev);
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
}
|
||||
|
||||
|
@ -566,6 +634,7 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu)
|
|||
static int bcm_suspend_device(struct device *dev)
|
||||
{
|
||||
struct bcm_device *bdev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
bt_dev_dbg(bdev, "");
|
||||
|
||||
|
@ -577,27 +646,37 @@ static int bcm_suspend_device(struct device *dev)
|
|||
}
|
||||
|
||||
/* Suspend the device */
|
||||
if (bdev->device_wakeup) {
|
||||
gpiod_set_value(bdev->device_wakeup, false);
|
||||
bt_dev_dbg(bdev, "suspend, delaying 15 ms");
|
||||
mdelay(15);
|
||||
err = bdev->set_device_wakeup(bdev, false);
|
||||
if (err) {
|
||||
if (bdev->is_suspended && bdev->hu) {
|
||||
bdev->is_suspended = false;
|
||||
hci_uart_set_flow_control(bdev->hu, false);
|
||||
}
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
bt_dev_dbg(bdev, "suspend, delaying 15 ms");
|
||||
msleep(15);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_resume_device(struct device *dev)
|
||||
{
|
||||
struct bcm_device *bdev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
bt_dev_dbg(bdev, "");
|
||||
|
||||
if (bdev->device_wakeup) {
|
||||
gpiod_set_value(bdev->device_wakeup, true);
|
||||
bt_dev_dbg(bdev, "resume, delaying 15 ms");
|
||||
mdelay(15);
|
||||
err = bdev->set_device_wakeup(bdev, true);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to power up\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
bt_dev_dbg(bdev, "resume, delaying 15 ms");
|
||||
msleep(15);
|
||||
|
||||
/* When this executes, the device has woken up already */
|
||||
if (bdev->is_suspended && bdev->hu) {
|
||||
bdev->is_suspended = false;
|
||||
|
@ -632,7 +711,7 @@ static int bcm_suspend(struct device *dev)
|
|||
if (pm_runtime_active(dev))
|
||||
bcm_suspend_device(dev);
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
if (device_may_wakeup(dev) && bdev->irq > 0) {
|
||||
error = enable_irq_wake(bdev->irq);
|
||||
if (!error)
|
||||
bt_dev_dbg(bdev, "BCM irq: enabled");
|
||||
|
@ -648,6 +727,7 @@ unlock:
|
|||
static int bcm_resume(struct device *dev)
|
||||
{
|
||||
struct bcm_device *bdev = dev_get_drvdata(dev);
|
||||
int err = 0;
|
||||
|
||||
bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended);
|
||||
|
||||
|
@ -662,19 +742,21 @@ static int bcm_resume(struct device *dev)
|
|||
if (!bdev->hu)
|
||||
goto unlock;
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
if (device_may_wakeup(dev) && bdev->irq > 0) {
|
||||
disable_irq_wake(bdev->irq);
|
||||
bt_dev_dbg(bdev, "BCM irq: disabled");
|
||||
}
|
||||
|
||||
bcm_resume_device(dev);
|
||||
err = bcm_resume_device(dev);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
if (!err) {
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -771,25 +853,84 @@ static int bcm_resource(struct acpi_resource *ares, void *data)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_apple_set_device_wakeup(struct bcm_device *dev, bool awake)
|
||||
{
|
||||
if (ACPI_FAILURE(acpi_execute_simple_method(dev->btlp, NULL, !awake)))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_apple_set_shutdown(struct bcm_device *dev, bool powered)
|
||||
{
|
||||
if (ACPI_FAILURE(acpi_evaluate_object(powered ? dev->btpu : dev->btpd,
|
||||
NULL, NULL, NULL)))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_apple_get_resources(struct bcm_device *dev)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev->dev);
|
||||
const union acpi_object *obj;
|
||||
|
||||
if (!adev ||
|
||||
ACPI_FAILURE(acpi_get_handle(adev->handle, "BTLP", &dev->btlp)) ||
|
||||
ACPI_FAILURE(acpi_get_handle(adev->handle, "BTPU", &dev->btpu)) ||
|
||||
ACPI_FAILURE(acpi_get_handle(adev->handle, "BTPD", &dev->btpd)))
|
||||
return -ENODEV;
|
||||
|
||||
if (!acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER, &obj) &&
|
||||
obj->buffer.length == 8)
|
||||
dev->init_speed = *(u64 *)obj->buffer.pointer;
|
||||
|
||||
dev->set_device_wakeup = bcm_apple_set_device_wakeup;
|
||||
dev->set_shutdown = bcm_apple_set_shutdown;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int bcm_apple_get_resources(struct bcm_device *dev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
static int bcm_gpio_set_device_wakeup(struct bcm_device *dev, bool awake)
|
||||
{
|
||||
gpiod_set_value(dev->device_wakeup, awake);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered)
|
||||
{
|
||||
gpiod_set_value(dev->shutdown, powered);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_get_resources(struct bcm_device *dev)
|
||||
{
|
||||
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->device_wakeup = devm_gpiod_get_optional(dev->dev,
|
||||
"device-wakeup",
|
||||
GPIOD_OUT_LOW);
|
||||
dev->device_wakeup = devm_gpiod_get(dev->dev, "device-wakeup",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(dev->device_wakeup))
|
||||
return PTR_ERR(dev->device_wakeup);
|
||||
|
||||
dev->shutdown = devm_gpiod_get_optional(dev->dev, "shutdown",
|
||||
GPIOD_OUT_LOW);
|
||||
dev->shutdown = devm_gpiod_get(dev->dev, "shutdown", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(dev->shutdown))
|
||||
return PTR_ERR(dev->shutdown);
|
||||
|
||||
dev->set_device_wakeup = bcm_gpio_set_device_wakeup;
|
||||
dev->set_shutdown = bcm_gpio_set_shutdown;
|
||||
|
||||
/* IRQ can be declared in ACPI table as Interrupt or GpioInt */
|
||||
if (dev->irq <= 0) {
|
||||
struct gpio_desc *gpio;
|
||||
|
@ -802,7 +943,7 @@ static int bcm_get_resources(struct bcm_device *dev)
|
|||
dev->irq = gpiod_to_irq(gpio);
|
||||
}
|
||||
|
||||
dev_info(dev->dev, "BCM irq: %d\n", dev->irq);
|
||||
dev_dbg(dev->dev, "BCM irq: %d\n", dev->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -892,7 +1033,9 @@ static int bcm_probe(struct platform_device *pdev)
|
|||
list_add_tail(&dev->list, &bcm_device_list);
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
|
||||
bcm_gpio_set_power(dev, false);
|
||||
ret = bcm_gpio_set_power(dev, false);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "Failed to power down\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -994,7 +1137,9 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
bcm_gpio_set_power(bcmdev, false);
|
||||
err = bcm_gpio_set_power(bcmdev, false);
|
||||
if (err)
|
||||
dev_err(&serdev->dev, "Failed to power down\n");
|
||||
|
||||
return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue