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

Commit ce945552 authored by Hans de Goede's avatar Hans de Goede Committed by Marcel Holtmann
Browse files

Bluetooth: hci_h5: Add support for serdev enumerated devices



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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 1cc194ca
Loading
Loading
Loading
Loading
+48 −4
Original line number Diff line number Diff line
@@ -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>
@@ -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 */
@@ -193,9 +197,13 @@ static int h5_open(struct hci_uart *hu)

	BT_DBG("hu %p", hu);

	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;
@@ -229,6 +237,7 @@ static int h5_close(struct hci_uart *hu)
	skb_queue_purge(&h5->rel);
	skb_queue_purge(&h5->unrel);

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

	return 0;
@@ -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);
}