Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions drivers/bluetooth/hci_bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ static LIST_HEAD(bcm_device_list);
#ifdef CONFIG_ACPI
static int bcm_apple_set_power(struct bcm_device *dev, bool enable)
{
return ACPI_SUCCESS(acpi_evaluate_object(enable ? dev->btpu : dev->btpd,
return ACPI_FAILURE(acpi_evaluate_object(enable ? dev->btpu : dev->btpd,
NULL, NULL, NULL));
}

static int bcm_apple_set_device_wake(struct bcm_device *dev, bool enable)
{
return ACPI_SUCCESS(acpi_execute_simple_method(dev->btlp,
NULL, enable));
return ACPI_FAILURE(acpi_execute_simple_method(dev->btlp,
NULL, enable ? 0 : 1));
}

static bool bcm_apple_probe(struct bcm_device *dev)
Expand All @@ -104,7 +104,8 @@ static bool bcm_apple_probe(struct bcm_device *dev)

if (!acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER, &obj) &&
obj->buffer.length == 8) {
dev->oper_speed = *(u64 *)obj->buffer.pointer;
dev->init_speed = *(u64 *)obj->buffer.pointer;
dev->oper_speed = dev->init_speed;
dev_info(&dev->pdev->dev, "oper_speed=%u\n", dev->oper_speed);
}

Expand Down Expand Up @@ -358,7 +359,8 @@ static int bcm_open(struct hci_uart *hu)
* platform device (saved during device probe) and
* parent of tty device used by hci_uart
*/
if (hu->tty->dev->parent == dev->pdev->dev.parent) {
if (hu->tty->dev->parent == dev->pdev->dev.parent ||
hu->tty->dev->parent->parent == dev->pdev->dev.parent) {
bcm->dev = dev;
hu->init_speed = dev->init_speed;
hu->oper_speed = dev->oper_speed;
Expand Down
31 changes: 13 additions & 18 deletions drivers/bluetooth/hci_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
struct sk_buff *skb = hu->tx_skb;

if (!skb) {
read_lock(&hu->proto_lock);
percpu_down_read(&hu->proto_lock);

if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
skb = hu->proto->dequeue(hu);

read_unlock(&hu->proto_lock);
percpu_up_read(&hu->proto_lock);
} else {
hu->tx_skb = NULL;
}
Expand All @@ -129,8 +129,6 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)

int hci_uart_tx_wakeup(struct hci_uart *hu)
{
read_lock(&hu->proto_lock);

if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
goto no_schedule;

Expand All @@ -144,8 +142,6 @@ int hci_uart_tx_wakeup(struct hci_uart *hu)
schedule_work(&hu->write_work);

no_schedule:
read_unlock(&hu->proto_lock);

return 0;
}
EXPORT_SYMBOL_GPL(hci_uart_tx_wakeup);
Expand Down Expand Up @@ -246,12 +242,12 @@ static int hci_uart_flush(struct hci_dev *hdev)
tty_ldisc_flush(tty);
tty_driver_flush_buffer(tty);

read_lock(&hu->proto_lock);
percpu_down_read(&hu->proto_lock);

if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
hu->proto->flush(hu);

read_unlock(&hu->proto_lock);
percpu_up_read(&hu->proto_lock);

return 0;
}
Expand All @@ -274,15 +270,15 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb),
skb->len);

read_lock(&hu->proto_lock);
percpu_down_read(&hu->proto_lock);

if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
read_unlock(&hu->proto_lock);
percpu_up_read(&hu->proto_lock);
return -EUNATCH;
}

hu->proto->enqueue(hu, skb);
read_unlock(&hu->proto_lock);
percpu_up_read(&hu->proto_lock);

hci_uart_tx_wakeup(hu);

Expand Down Expand Up @@ -478,7 +474,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
INIT_WORK(&hu->init_ready, hci_uart_init_work);
INIT_WORK(&hu->write_work, hci_uart_write_work);

rwlock_init(&hu->proto_lock);
percpu_init_rwsem(&hu->proto_lock);

/* Flush any pending characters in the driver */
tty_driver_flush_buffer(tty);
Expand All @@ -495,7 +491,6 @@ static void hci_uart_tty_close(struct tty_struct *tty)
{
struct hci_uart *hu = tty->disc_data;
struct hci_dev *hdev;
unsigned long flags;

BT_DBG("tty %p", tty);

Expand All @@ -512,9 +507,9 @@ static void hci_uart_tty_close(struct tty_struct *tty)
cancel_work_sync(&hu->write_work);

if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
write_lock_irqsave(&hu->proto_lock, flags);
percpu_down_write(&hu->proto_lock);
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
write_unlock_irqrestore(&hu->proto_lock, flags);
percpu_up_write(&hu->proto_lock);

if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
Expand Down Expand Up @@ -574,18 +569,18 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
if (!hu || tty != hu->tty)
return;

read_lock(&hu->proto_lock);
percpu_down_read(&hu->proto_lock);

if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
read_unlock(&hu->proto_lock);
percpu_up_read(&hu->proto_lock);
return;
}

/* It does not need a lock here as it is already protected by a mutex in
* tty caller
*/
hu->proto->recv(hu, data, count);
read_unlock(&hu->proto_lock);
percpu_up_read(&hu->proto_lock);

if (hu->hdev)
hu->hdev->stat.byte_rx += count;
Expand Down
2 changes: 1 addition & 1 deletion drivers/bluetooth/hci_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct hci_uart {
struct work_struct write_work;

const struct hci_uart_proto *proto;
rwlock_t proto_lock; /* Stop work for proto close */
struct percpu_rw_semaphore proto_lock; /* Stop work for proto close */
void *priv;

struct sk_buff *tx_skb;
Expand Down