Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get bluetooth working on MBP13,3 #1

Open
wants to merge 4 commits into
base: hci_bcm
Choose a base branch
from
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