hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/bluetooth/hci_mrvl.c
....@@ -1,24 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 *
34 * Bluetooth HCI UART driver for marvell devices
45 *
56 * Copyright (C) 2016 Marvell International Ltd.
67 * Copyright (C) 2016 Intel Corporation
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program; if not, write to the Free Software
20
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
- *
228 */
239
2410 #include <linux/kernel.h>
....@@ -27,6 +13,8 @@
2713 #include <linux/firmware.h>
2814 #include <linux/module.h>
2915 #include <linux/tty.h>
16
+#include <linux/of.h>
17
+#include <linux/serdev.h>
3018
3119 #include <net/bluetooth/bluetooth.h>
3220 #include <net/bluetooth/hci_core.h>
....@@ -54,6 +42,10 @@
5442 u8 id, rev;
5543 };
5644
45
+struct mrvl_serdev {
46
+ struct hci_uart hu;
47
+};
48
+
5749 struct hci_mrvl_pkt {
5850 __le16 lhs;
5951 __le16 rhs;
....@@ -63,6 +55,7 @@
6355 static int mrvl_open(struct hci_uart *hu)
6456 {
6557 struct mrvl_data *mrvl;
58
+ int ret;
6659
6760 BT_DBG("hu %p", hu);
6861
....@@ -79,7 +72,18 @@
7972 set_bit(STATE_CHIP_VER_PENDING, &mrvl->flags);
8073
8174 hu->priv = mrvl;
75
+
76
+ if (hu->serdev) {
77
+ ret = serdev_device_open(hu->serdev);
78
+ if (ret)
79
+ goto err;
80
+ }
81
+
8282 return 0;
83
+err:
84
+ kfree(mrvl);
85
+
86
+ return ret;
8387 }
8488
8589 static int mrvl_close(struct hci_uart *hu)
....@@ -87,6 +91,9 @@
8791 struct mrvl_data *mrvl = hu->priv;
8892
8993 BT_DBG("hu %p", hu);
94
+
95
+ if (hu->serdev)
96
+ serdev_device_close(hu->serdev);
9097
9198 skb_queue_purge(&mrvl->txq);
9299 skb_queue_purge(&mrvl->rawq);
....@@ -356,7 +363,14 @@
356363 return -EINVAL;
357364 }
358365
359
- hci_uart_set_baudrate(hu, 3000000);
366
+ /* Let the final ack go out before switching the baudrate */
367
+ hci_uart_wait_until_sent(hu);
368
+
369
+ if (hu->serdev)
370
+ serdev_device_set_baudrate(hu->serdev, 3000000);
371
+ else
372
+ hci_uart_set_baudrate(hu, 3000000);
373
+
360374 hci_uart_set_flow_control(hu, false);
361375
362376 err = mrvl_load_firmware(hu->hdev, "mrvl/uart8897_bt.bin");
....@@ -379,12 +393,54 @@
379393 .dequeue = mrvl_dequeue,
380394 };
381395
396
+static int mrvl_serdev_probe(struct serdev_device *serdev)
397
+{
398
+ struct mrvl_serdev *mrvldev;
399
+
400
+ mrvldev = devm_kzalloc(&serdev->dev, sizeof(*mrvldev), GFP_KERNEL);
401
+ if (!mrvldev)
402
+ return -ENOMEM;
403
+
404
+ mrvldev->hu.serdev = serdev;
405
+ serdev_device_set_drvdata(serdev, mrvldev);
406
+
407
+ return hci_uart_register_device(&mrvldev->hu, &mrvl_proto);
408
+}
409
+
410
+static void mrvl_serdev_remove(struct serdev_device *serdev)
411
+{
412
+ struct mrvl_serdev *mrvldev = serdev_device_get_drvdata(serdev);
413
+
414
+ hci_uart_unregister_device(&mrvldev->hu);
415
+}
416
+
417
+#ifdef CONFIG_OF
418
+static const struct of_device_id mrvl_bluetooth_of_match[] = {
419
+ { .compatible = "mrvl,88w8897" },
420
+ { },
421
+};
422
+MODULE_DEVICE_TABLE(of, mrvl_bluetooth_of_match);
423
+#endif
424
+
425
+static struct serdev_device_driver mrvl_serdev_driver = {
426
+ .probe = mrvl_serdev_probe,
427
+ .remove = mrvl_serdev_remove,
428
+ .driver = {
429
+ .name = "hci_uart_mrvl",
430
+ .of_match_table = of_match_ptr(mrvl_bluetooth_of_match),
431
+ },
432
+};
433
+
382434 int __init mrvl_init(void)
383435 {
436
+ serdev_device_driver_register(&mrvl_serdev_driver);
437
+
384438 return hci_uart_register_proto(&mrvl_proto);
385439 }
386440
387441 int __exit mrvl_deinit(void)
388442 {
443
+ serdev_device_driver_unregister(&mrvl_serdev_driver);
444
+
389445 return hci_uart_unregister_proto(&mrvl_proto);
390446 }