Skip to content

Commit

Permalink
Bluetooth: hci_h5: Add support for serdev enumerated devices
Browse files Browse the repository at this point in the history
Add basic support for serdev enumerated devices, note sine this does
not (yet) declare any of / ACPI ids to bind to atm this is a nop.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Hans de Goede authored and Marcel Holtmann committed Aug 3, 2018
1 parent 1cc194c commit ce94555
Showing 1 changed file with 48 additions and 4 deletions.
52 changes: 48 additions & 4 deletions drivers/bluetooth/hci_h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/serdev.h>
#include <linux/skbuff.h>

#include <net/bluetooth/bluetooth.h>
Expand Down Expand Up @@ -65,6 +66,9 @@ enum {
};

struct h5 {
/* Must be the first member, hci_serdev.c expects this. */
struct hci_uart serdev_hu;

struct sk_buff_head unack; /* Unack'ed packets queue */
struct sk_buff_head rel; /* Reliable packets queue */
struct sk_buff_head unrel; /* Unreliable packets queue */
Expand Down Expand Up @@ -193,9 +197,13 @@ static int h5_open(struct hci_uart *hu)

BT_DBG("hu %p", hu);

h5 = kzalloc(sizeof(*h5), GFP_KERNEL);
if (!h5)
return -ENOMEM;
if (hu->serdev) {
h5 = serdev_device_get_drvdata(hu->serdev);
} else {
h5 = kzalloc(sizeof(*h5), GFP_KERNEL);
if (!h5)
return -ENOMEM;
}

hu->priv = h5;
h5->hu = hu;
Expand Down Expand Up @@ -229,7 +237,8 @@ static int h5_close(struct hci_uart *hu)
skb_queue_purge(&h5->rel);
skb_queue_purge(&h5->unrel);

kfree(h5);
if (!hu->serdev)
kfree(h5);

return 0;
}
Expand Down Expand Up @@ -750,12 +759,47 @@ static const struct hci_uart_proto h5p = {
.flush = h5_flush,
};

static int h5_serdev_probe(struct serdev_device *serdev)
{
struct device *dev = &serdev->dev;
struct h5 *h5;

h5 = devm_kzalloc(dev, sizeof(*h5), GFP_KERNEL);
if (!h5)
return -ENOMEM;

set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.flags);

h5->hu = &h5->serdev_hu;
h5->serdev_hu.serdev = serdev;
serdev_device_set_drvdata(serdev, h5);

return hci_uart_register_device(&h5->serdev_hu, &h5p);
}

static void h5_serdev_remove(struct serdev_device *serdev)
{
struct h5 *h5 = serdev_device_get_drvdata(serdev);

hci_uart_unregister_device(&h5->serdev_hu);
}

static struct serdev_device_driver h5_serdev_driver = {
.probe = h5_serdev_probe,
.remove = h5_serdev_remove,
.driver = {
.name = "hci_uart_h5",
},
};

int __init h5_init(void)
{
serdev_device_driver_register(&h5_serdev_driver);
return hci_uart_register_proto(&h5p);
}

int __exit h5_deinit(void)
{
serdev_device_driver_unregister(&h5_serdev_driver);
return hci_uart_unregister_proto(&h5p);
}

0 comments on commit ce94555

Please sign in to comment.