1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Bluetooth HCI UART driver for marvell devices
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2016 Marvell International Ltd.
7*4882a593Smuzhiyun * Copyright (C) 2016 Intel Corporation
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/errno.h>
12*4882a593Smuzhiyun #include <linux/skbuff.h>
13*4882a593Smuzhiyun #include <linux/firmware.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/tty.h>
16*4882a593Smuzhiyun #include <linux/of.h>
17*4882a593Smuzhiyun #include <linux/serdev.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <net/bluetooth/bluetooth.h>
20*4882a593Smuzhiyun #include <net/bluetooth/hci_core.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #include "hci_uart.h"
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #define HCI_FW_REQ_PKT 0xA5
25*4882a593Smuzhiyun #define HCI_CHIP_VER_PKT 0xAA
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define MRVL_ACK 0x5A
28*4882a593Smuzhiyun #define MRVL_NAK 0xBF
29*4882a593Smuzhiyun #define MRVL_RAW_DATA 0x1F
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun enum {
32*4882a593Smuzhiyun STATE_CHIP_VER_PENDING,
33*4882a593Smuzhiyun STATE_FW_REQ_PENDING,
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun struct mrvl_data {
37*4882a593Smuzhiyun struct sk_buff *rx_skb;
38*4882a593Smuzhiyun struct sk_buff_head txq;
39*4882a593Smuzhiyun struct sk_buff_head rawq;
40*4882a593Smuzhiyun unsigned long flags;
41*4882a593Smuzhiyun unsigned int tx_len;
42*4882a593Smuzhiyun u8 id, rev;
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun struct mrvl_serdev {
46*4882a593Smuzhiyun struct hci_uart hu;
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun struct hci_mrvl_pkt {
50*4882a593Smuzhiyun __le16 lhs;
51*4882a593Smuzhiyun __le16 rhs;
52*4882a593Smuzhiyun } __packed;
53*4882a593Smuzhiyun #define HCI_MRVL_PKT_SIZE 4
54*4882a593Smuzhiyun
mrvl_open(struct hci_uart * hu)55*4882a593Smuzhiyun static int mrvl_open(struct hci_uart *hu)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun struct mrvl_data *mrvl;
58*4882a593Smuzhiyun int ret;
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun BT_DBG("hu %p", hu);
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun if (!hci_uart_has_flow_control(hu))
63*4882a593Smuzhiyun return -EOPNOTSUPP;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun mrvl = kzalloc(sizeof(*mrvl), GFP_KERNEL);
66*4882a593Smuzhiyun if (!mrvl)
67*4882a593Smuzhiyun return -ENOMEM;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun skb_queue_head_init(&mrvl->txq);
70*4882a593Smuzhiyun skb_queue_head_init(&mrvl->rawq);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun set_bit(STATE_CHIP_VER_PENDING, &mrvl->flags);
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun hu->priv = mrvl;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun if (hu->serdev) {
77*4882a593Smuzhiyun ret = serdev_device_open(hu->serdev);
78*4882a593Smuzhiyun if (ret)
79*4882a593Smuzhiyun goto err;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun return 0;
83*4882a593Smuzhiyun err:
84*4882a593Smuzhiyun kfree(mrvl);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun return ret;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
mrvl_close(struct hci_uart * hu)89*4882a593Smuzhiyun static int mrvl_close(struct hci_uart *hu)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun BT_DBG("hu %p", hu);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun if (hu->serdev)
96*4882a593Smuzhiyun serdev_device_close(hu->serdev);
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun skb_queue_purge(&mrvl->txq);
99*4882a593Smuzhiyun skb_queue_purge(&mrvl->rawq);
100*4882a593Smuzhiyun kfree_skb(mrvl->rx_skb);
101*4882a593Smuzhiyun kfree(mrvl);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun hu->priv = NULL;
104*4882a593Smuzhiyun return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
mrvl_flush(struct hci_uart * hu)107*4882a593Smuzhiyun static int mrvl_flush(struct hci_uart *hu)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun BT_DBG("hu %p", hu);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun skb_queue_purge(&mrvl->txq);
114*4882a593Smuzhiyun skb_queue_purge(&mrvl->rawq);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun return 0;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
mrvl_dequeue(struct hci_uart * hu)119*4882a593Smuzhiyun static struct sk_buff *mrvl_dequeue(struct hci_uart *hu)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
122*4882a593Smuzhiyun struct sk_buff *skb;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun skb = skb_dequeue(&mrvl->txq);
125*4882a593Smuzhiyun if (!skb) {
126*4882a593Smuzhiyun /* Any raw data ? */
127*4882a593Smuzhiyun skb = skb_dequeue(&mrvl->rawq);
128*4882a593Smuzhiyun } else {
129*4882a593Smuzhiyun /* Prepend skb with frame type */
130*4882a593Smuzhiyun memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun return skb;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
mrvl_enqueue(struct hci_uart * hu,struct sk_buff * skb)136*4882a593Smuzhiyun static int mrvl_enqueue(struct hci_uart *hu, struct sk_buff *skb)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun skb_queue_tail(&mrvl->txq, skb);
141*4882a593Smuzhiyun return 0;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
mrvl_send_ack(struct hci_uart * hu,unsigned char type)144*4882a593Smuzhiyun static void mrvl_send_ack(struct hci_uart *hu, unsigned char type)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
147*4882a593Smuzhiyun struct sk_buff *skb;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* No H4 payload, only 1 byte header */
150*4882a593Smuzhiyun skb = bt_skb_alloc(0, GFP_ATOMIC);
151*4882a593Smuzhiyun if (!skb) {
152*4882a593Smuzhiyun bt_dev_err(hu->hdev, "Unable to alloc ack/nak packet");
153*4882a593Smuzhiyun return;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun hci_skb_pkt_type(skb) = type;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun skb_queue_tail(&mrvl->txq, skb);
158*4882a593Smuzhiyun hci_uart_tx_wakeup(hu);
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
mrvl_recv_fw_req(struct hci_dev * hdev,struct sk_buff * skb)161*4882a593Smuzhiyun static int mrvl_recv_fw_req(struct hci_dev *hdev, struct sk_buff *skb)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct hci_mrvl_pkt *pkt = (void *)skb->data;
164*4882a593Smuzhiyun struct hci_uart *hu = hci_get_drvdata(hdev);
165*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
166*4882a593Smuzhiyun int ret = 0;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun if ((pkt->lhs ^ pkt->rhs) != 0xffff) {
169*4882a593Smuzhiyun bt_dev_err(hdev, "Corrupted mrvl header");
170*4882a593Smuzhiyun mrvl_send_ack(hu, MRVL_NAK);
171*4882a593Smuzhiyun ret = -EINVAL;
172*4882a593Smuzhiyun goto done;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun mrvl_send_ack(hu, MRVL_ACK);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun if (!test_bit(STATE_FW_REQ_PENDING, &mrvl->flags)) {
177*4882a593Smuzhiyun bt_dev_err(hdev, "Received unexpected firmware request");
178*4882a593Smuzhiyun ret = -EINVAL;
179*4882a593Smuzhiyun goto done;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun mrvl->tx_len = le16_to_cpu(pkt->lhs);
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun clear_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
185*4882a593Smuzhiyun smp_mb__after_atomic();
186*4882a593Smuzhiyun wake_up_bit(&mrvl->flags, STATE_FW_REQ_PENDING);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun done:
189*4882a593Smuzhiyun kfree_skb(skb);
190*4882a593Smuzhiyun return ret;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
mrvl_recv_chip_ver(struct hci_dev * hdev,struct sk_buff * skb)193*4882a593Smuzhiyun static int mrvl_recv_chip_ver(struct hci_dev *hdev, struct sk_buff *skb)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun struct hci_mrvl_pkt *pkt = (void *)skb->data;
196*4882a593Smuzhiyun struct hci_uart *hu = hci_get_drvdata(hdev);
197*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
198*4882a593Smuzhiyun u16 version = le16_to_cpu(pkt->lhs);
199*4882a593Smuzhiyun int ret = 0;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun if ((pkt->lhs ^ pkt->rhs) != 0xffff) {
202*4882a593Smuzhiyun bt_dev_err(hdev, "Corrupted mrvl header");
203*4882a593Smuzhiyun mrvl_send_ack(hu, MRVL_NAK);
204*4882a593Smuzhiyun ret = -EINVAL;
205*4882a593Smuzhiyun goto done;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun mrvl_send_ack(hu, MRVL_ACK);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun if (!test_bit(STATE_CHIP_VER_PENDING, &mrvl->flags)) {
210*4882a593Smuzhiyun bt_dev_err(hdev, "Received unexpected chip version");
211*4882a593Smuzhiyun goto done;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun mrvl->id = version;
215*4882a593Smuzhiyun mrvl->rev = version >> 8;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun bt_dev_info(hdev, "Controller id = %x, rev = %x", mrvl->id, mrvl->rev);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun clear_bit(STATE_CHIP_VER_PENDING, &mrvl->flags);
220*4882a593Smuzhiyun smp_mb__after_atomic();
221*4882a593Smuzhiyun wake_up_bit(&mrvl->flags, STATE_CHIP_VER_PENDING);
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun done:
224*4882a593Smuzhiyun kfree_skb(skb);
225*4882a593Smuzhiyun return ret;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun #define HCI_RECV_CHIP_VER \
229*4882a593Smuzhiyun .type = HCI_CHIP_VER_PKT, \
230*4882a593Smuzhiyun .hlen = HCI_MRVL_PKT_SIZE, \
231*4882a593Smuzhiyun .loff = 0, \
232*4882a593Smuzhiyun .lsize = 0, \
233*4882a593Smuzhiyun .maxlen = HCI_MRVL_PKT_SIZE
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun #define HCI_RECV_FW_REQ \
236*4882a593Smuzhiyun .type = HCI_FW_REQ_PKT, \
237*4882a593Smuzhiyun .hlen = HCI_MRVL_PKT_SIZE, \
238*4882a593Smuzhiyun .loff = 0, \
239*4882a593Smuzhiyun .lsize = 0, \
240*4882a593Smuzhiyun .maxlen = HCI_MRVL_PKT_SIZE
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun static const struct h4_recv_pkt mrvl_recv_pkts[] = {
243*4882a593Smuzhiyun { H4_RECV_ACL, .recv = hci_recv_frame },
244*4882a593Smuzhiyun { H4_RECV_SCO, .recv = hci_recv_frame },
245*4882a593Smuzhiyun { H4_RECV_EVENT, .recv = hci_recv_frame },
246*4882a593Smuzhiyun { HCI_RECV_FW_REQ, .recv = mrvl_recv_fw_req },
247*4882a593Smuzhiyun { HCI_RECV_CHIP_VER, .recv = mrvl_recv_chip_ver },
248*4882a593Smuzhiyun };
249*4882a593Smuzhiyun
mrvl_recv(struct hci_uart * hu,const void * data,int count)250*4882a593Smuzhiyun static int mrvl_recv(struct hci_uart *hu, const void *data, int count)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
255*4882a593Smuzhiyun return -EUNATCH;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count,
258*4882a593Smuzhiyun mrvl_recv_pkts,
259*4882a593Smuzhiyun ARRAY_SIZE(mrvl_recv_pkts));
260*4882a593Smuzhiyun if (IS_ERR(mrvl->rx_skb)) {
261*4882a593Smuzhiyun int err = PTR_ERR(mrvl->rx_skb);
262*4882a593Smuzhiyun bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
263*4882a593Smuzhiyun mrvl->rx_skb = NULL;
264*4882a593Smuzhiyun return err;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun return count;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
mrvl_load_firmware(struct hci_dev * hdev,const char * name)270*4882a593Smuzhiyun static int mrvl_load_firmware(struct hci_dev *hdev, const char *name)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun struct hci_uart *hu = hci_get_drvdata(hdev);
273*4882a593Smuzhiyun struct mrvl_data *mrvl = hu->priv;
274*4882a593Smuzhiyun const struct firmware *fw = NULL;
275*4882a593Smuzhiyun const u8 *fw_ptr, *fw_max;
276*4882a593Smuzhiyun int err;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun err = request_firmware(&fw, name, &hdev->dev);
279*4882a593Smuzhiyun if (err < 0) {
280*4882a593Smuzhiyun bt_dev_err(hdev, "Failed to load firmware file %s", name);
281*4882a593Smuzhiyun return err;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun fw_ptr = fw->data;
285*4882a593Smuzhiyun fw_max = fw->data + fw->size;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun bt_dev_info(hdev, "Loading %s", name);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun set_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun while (fw_ptr <= fw_max) {
292*4882a593Smuzhiyun struct sk_buff *skb;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun /* Controller drives the firmware load by sending firmware
295*4882a593Smuzhiyun * request packets containing the expected fragment size.
296*4882a593Smuzhiyun */
297*4882a593Smuzhiyun err = wait_on_bit_timeout(&mrvl->flags, STATE_FW_REQ_PENDING,
298*4882a593Smuzhiyun TASK_INTERRUPTIBLE,
299*4882a593Smuzhiyun msecs_to_jiffies(2000));
300*4882a593Smuzhiyun if (err == 1) {
301*4882a593Smuzhiyun bt_dev_err(hdev, "Firmware load interrupted");
302*4882a593Smuzhiyun err = -EINTR;
303*4882a593Smuzhiyun break;
304*4882a593Smuzhiyun } else if (err) {
305*4882a593Smuzhiyun bt_dev_err(hdev, "Firmware request timeout");
306*4882a593Smuzhiyun err = -ETIMEDOUT;
307*4882a593Smuzhiyun break;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun bt_dev_dbg(hdev, "Firmware request, expecting %d bytes",
311*4882a593Smuzhiyun mrvl->tx_len);
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun if (fw_ptr == fw_max) {
314*4882a593Smuzhiyun /* Controller requests a null size once firmware is
315*4882a593Smuzhiyun * fully loaded. If controller expects more data, there
316*4882a593Smuzhiyun * is an issue.
317*4882a593Smuzhiyun */
318*4882a593Smuzhiyun if (!mrvl->tx_len) {
319*4882a593Smuzhiyun bt_dev_info(hdev, "Firmware loading complete");
320*4882a593Smuzhiyun } else {
321*4882a593Smuzhiyun bt_dev_err(hdev, "Firmware loading failure");
322*4882a593Smuzhiyun err = -EINVAL;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun break;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun if (fw_ptr + mrvl->tx_len > fw_max) {
328*4882a593Smuzhiyun mrvl->tx_len = fw_max - fw_ptr;
329*4882a593Smuzhiyun bt_dev_dbg(hdev, "Adjusting tx_len to %d",
330*4882a593Smuzhiyun mrvl->tx_len);
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun skb = bt_skb_alloc(mrvl->tx_len, GFP_KERNEL);
334*4882a593Smuzhiyun if (!skb) {
335*4882a593Smuzhiyun bt_dev_err(hdev, "Failed to alloc mem for FW packet");
336*4882a593Smuzhiyun err = -ENOMEM;
337*4882a593Smuzhiyun break;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun bt_cb(skb)->pkt_type = MRVL_RAW_DATA;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun skb_put_data(skb, fw_ptr, mrvl->tx_len);
342*4882a593Smuzhiyun fw_ptr += mrvl->tx_len;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun set_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun skb_queue_tail(&mrvl->rawq, skb);
347*4882a593Smuzhiyun hci_uart_tx_wakeup(hu);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun release_firmware(fw);
351*4882a593Smuzhiyun return err;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
mrvl_setup(struct hci_uart * hu)354*4882a593Smuzhiyun static int mrvl_setup(struct hci_uart *hu)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun int err;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun hci_uart_set_flow_control(hu, true);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun err = mrvl_load_firmware(hu->hdev, "mrvl/helper_uart_3000000.bin");
361*4882a593Smuzhiyun if (err) {
362*4882a593Smuzhiyun bt_dev_err(hu->hdev, "Unable to download firmware helper");
363*4882a593Smuzhiyun return -EINVAL;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun /* Let the final ack go out before switching the baudrate */
367*4882a593Smuzhiyun hci_uart_wait_until_sent(hu);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun if (hu->serdev)
370*4882a593Smuzhiyun serdev_device_set_baudrate(hu->serdev, 3000000);
371*4882a593Smuzhiyun else
372*4882a593Smuzhiyun hci_uart_set_baudrate(hu, 3000000);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun hci_uart_set_flow_control(hu, false);
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun err = mrvl_load_firmware(hu->hdev, "mrvl/uart8897_bt.bin");
377*4882a593Smuzhiyun if (err)
378*4882a593Smuzhiyun return err;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun return 0;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun static const struct hci_uart_proto mrvl_proto = {
384*4882a593Smuzhiyun .id = HCI_UART_MRVL,
385*4882a593Smuzhiyun .name = "Marvell",
386*4882a593Smuzhiyun .init_speed = 115200,
387*4882a593Smuzhiyun .open = mrvl_open,
388*4882a593Smuzhiyun .close = mrvl_close,
389*4882a593Smuzhiyun .flush = mrvl_flush,
390*4882a593Smuzhiyun .setup = mrvl_setup,
391*4882a593Smuzhiyun .recv = mrvl_recv,
392*4882a593Smuzhiyun .enqueue = mrvl_enqueue,
393*4882a593Smuzhiyun .dequeue = mrvl_dequeue,
394*4882a593Smuzhiyun };
395*4882a593Smuzhiyun
mrvl_serdev_probe(struct serdev_device * serdev)396*4882a593Smuzhiyun static int mrvl_serdev_probe(struct serdev_device *serdev)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun struct mrvl_serdev *mrvldev;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun mrvldev = devm_kzalloc(&serdev->dev, sizeof(*mrvldev), GFP_KERNEL);
401*4882a593Smuzhiyun if (!mrvldev)
402*4882a593Smuzhiyun return -ENOMEM;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun mrvldev->hu.serdev = serdev;
405*4882a593Smuzhiyun serdev_device_set_drvdata(serdev, mrvldev);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun return hci_uart_register_device(&mrvldev->hu, &mrvl_proto);
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
mrvl_serdev_remove(struct serdev_device * serdev)410*4882a593Smuzhiyun static void mrvl_serdev_remove(struct serdev_device *serdev)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun struct mrvl_serdev *mrvldev = serdev_device_get_drvdata(serdev);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun hci_uart_unregister_device(&mrvldev->hu);
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun #ifdef CONFIG_OF
418*4882a593Smuzhiyun static const struct of_device_id mrvl_bluetooth_of_match[] = {
419*4882a593Smuzhiyun { .compatible = "mrvl,88w8897" },
420*4882a593Smuzhiyun { },
421*4882a593Smuzhiyun };
422*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, mrvl_bluetooth_of_match);
423*4882a593Smuzhiyun #endif
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun static struct serdev_device_driver mrvl_serdev_driver = {
426*4882a593Smuzhiyun .probe = mrvl_serdev_probe,
427*4882a593Smuzhiyun .remove = mrvl_serdev_remove,
428*4882a593Smuzhiyun .driver = {
429*4882a593Smuzhiyun .name = "hci_uart_mrvl",
430*4882a593Smuzhiyun .of_match_table = of_match_ptr(mrvl_bluetooth_of_match),
431*4882a593Smuzhiyun },
432*4882a593Smuzhiyun };
433*4882a593Smuzhiyun
mrvl_init(void)434*4882a593Smuzhiyun int __init mrvl_init(void)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun serdev_device_driver_register(&mrvl_serdev_driver);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun return hci_uart_register_proto(&mrvl_proto);
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
mrvl_deinit(void)441*4882a593Smuzhiyun int __exit mrvl_deinit(void)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun serdev_device_driver_unregister(&mrvl_serdev_driver);
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun return hci_uart_unregister_proto(&mrvl_proto);
446*4882a593Smuzhiyun }
447