From patchwork Mon Jul 9 15:57:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Wang X-Patchwork-Id: 10515165 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 624326032C for ; Mon, 9 Jul 2018 16:11:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4272728C92 for ; Mon, 9 Jul 2018 16:11:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3726E28C8D; Mon, 9 Jul 2018 16:11:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, MAILING_LIST_MULTI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8512B28C85 for ; Mon, 9 Jul 2018 16:11:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=apaZCIrtXE1FsPiM5YMmHwDOmQ54Yg7MSZGq/L0StmU=; b=oPG2S6KuhgwvLF YHq0yB4enS3iG1Ad4kPAz4zMBWMA0x1gxyE93rox8DJaHKyWtPEmFijuD69OI5cNVX1Uy96apLC7i 8+N0hQFh0PRjlxldn0N0+6W8pxd0OGsngYCwc9Vbl7Znp66TFp0PLNytl4QZwAZMi1ND7ypZ3tIQN Do5pqUJqz9JsnMZLFVY1tWjoBH8sGOBoQLlqbGdIryXA05YdRugAxU0hg4sYWWkLnDlcfBj8ICVVR ydXvhd5Mp0vfv4BnR0XO8uUb3ff06dGWwIRhV+tE7y7UQThP7RlDYWbQSbfdSzi9JspJx4W0CCEEc BcTTemPO+S2N41itVEhw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fcYkd-0008Hg-S2; Mon, 09 Jul 2018 16:10:59 +0000 Received: from [210.61.82.183] (helo=mailgw01.mediatek.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fcYXX-0005es-KU; Mon, 09 Jul 2018 15:57:31 +0000 X-UUID: f6ec863e269841848926597df1ea2905-20180709 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (mhqrelay.mediatek.com ESMTP with TLS) with ESMTP id 1888991550; Mon, 09 Jul 2018 23:57:07 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs08n2.mediatek.inc (172.21.101.56) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Mon, 9 Jul 2018 23:57:06 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1210.3 via Frontend Transport; Mon, 9 Jul 2018 23:57:06 +0800 From: To: , , , Subject: [PATCH v5 5/7] Bluetooth: Extend btuart driver for join more vendor devices Date: Mon, 9 Jul 2018 23:57:01 +0800 Message-ID: <85d449cdd34bf47d72935a821915e825c64a2145.1531150733.git.sean.wang@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180709_085728_015292_7E773663 X-CRM114-Status: GOOD ( 13.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Sean Wang , linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sean Wang Adding an independent btuart.h header allows these essential definitions can be reused in vendor driver. Also, struct btuart_vnd is extended with additional callbacks such as .init initializing vendor data, .shtudown, .recv and .send supporting SoC specific framing for that btuart can simply adapt to various Bluetooth uart-based devices. Signed-off-by: Sean Wang --- drivers/bluetooth/btuart.c | 73 ++++++++++++++++++++++++---------------------- drivers/bluetooth/btuart.h | 30 +++++++++++++++++++ 2 files changed, 68 insertions(+), 35 deletions(-) create mode 100644 drivers/bluetooth/btuart.h diff --git a/drivers/bluetooth/btuart.c b/drivers/bluetooth/btuart.c index a900aac..65d0086 100644 --- a/drivers/bluetooth/btuart.c +++ b/drivers/bluetooth/btuart.c @@ -33,35 +33,11 @@ #include #include "h4_recv.h" +#include "btuart.h" #include "btbcm.h" #define VERSION "1.0" -struct btuart_vnd { - const struct h4_recv_pkt *recv_pkts; - int recv_pkts_cnt; - unsigned int manufacturer; - int (*open)(struct hci_dev *hdev); - int (*close)(struct hci_dev *hdev); - int (*setup)(struct hci_dev *hdev); -}; - -struct btuart_dev { - struct hci_dev *hdev; - struct serdev_device *serdev; - - struct work_struct tx_work; - unsigned long tx_state; - struct sk_buff_head txq; - - struct sk_buff *rx_skb; - - const struct btuart_vnd *vnd; -}; - -#define BTUART_TX_STATE_ACTIVE 1 -#define BTUART_TX_STATE_WAKEUP 2 - static void btuart_tx_work(struct work_struct *work) { struct btuart_dev *bdev = container_of(work, struct btuart_dev, @@ -187,13 +163,27 @@ static int btuart_setup(struct hci_dev *hdev) return 0; } +static int btuart_shutdown(struct hci_dev *hdev) +{ + struct btuart_dev *bdev = hci_get_drvdata(hdev); + + if (bdev->vnd->shutdown) + return bdev->vnd->shutdown(hdev); + + return 0; +} + static int btuart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { struct btuart_dev *bdev = hci_get_drvdata(hdev); - /* Prepend skb with frame type */ - memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); - skb_queue_tail(&bdev->txq, skb); + if (bdev->vnd->send) { + bdev->vnd->send(hdev, skb); + } else { + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); + skb_queue_tail(&bdev->txq, skb); + } btuart_tx_wakeup(bdev); return 0; @@ -204,14 +194,23 @@ static int btuart_receive_buf(struct serdev_device *serdev, const u8 *data, { struct btuart_dev *bdev = serdev_device_get_drvdata(serdev); const struct btuart_vnd *vnd = bdev->vnd; + int err; - bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, data, count, - vnd->recv_pkts, vnd->recv_pkts_cnt); - if (IS_ERR(bdev->rx_skb)) { - int err = PTR_ERR(bdev->rx_skb); - bt_dev_err(bdev->hdev, "Frame reassembly failed (%d)", err); - bdev->rx_skb = NULL; - return err; + if (bdev->vnd->recv) { + err = bdev->vnd->recv(bdev->hdev, data, count); + if (err < 0) + return err; + } else { + bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, + data, count, vnd->recv_pkts, + vnd->recv_pkts_cnt); + if (IS_ERR(bdev->rx_skb)) { + err = PTR_ERR(bdev->rx_skb); + bt_dev_err(bdev->hdev, + "Frame reassembly failed (%d)", err); + bdev->rx_skb = NULL; + return err; + } } bdev->hdev->stat.byte_rx += count; @@ -429,6 +428,9 @@ static int btuart_probe(struct serdev_device *serdev) if (!bdev->vnd) bdev->vnd = &default_vnd; + if (bdev->vnd->init) + bdev->data = bdev->vnd->init(&serdev->dev); + bdev->serdev = serdev; serdev_device_set_drvdata(serdev, bdev); @@ -460,6 +462,7 @@ static int btuart_probe(struct serdev_device *serdev) hdev->close = btuart_close; hdev->flush = btuart_flush; hdev->setup = btuart_setup; + hdev->shutdown = btuart_shutdown; hdev->send = btuart_send_frame; SET_HCIDEV_DEV(hdev, &serdev->dev); diff --git a/drivers/bluetooth/btuart.h b/drivers/bluetooth/btuart.h new file mode 100644 index 0000000..6c1fe31 --- /dev/null +++ b/drivers/bluetooth/btuart.h @@ -0,0 +1,30 @@ +struct btuart_vnd { + const struct h4_recv_pkt *recv_pkts; + int recv_pkts_cnt; + unsigned int manufacturer; + void *(*init)(struct device *dev); + + int (*open)(struct hci_dev *hdev); + int (*close)(struct hci_dev *hdev); + int (*setup)(struct hci_dev *hdev); + int (*shutdown)(struct hci_dev *hdev); + int (*send)(struct hci_dev *hdev, struct sk_buff *skb); + int (*recv)(struct hci_dev *hdev, const u8 *data, size_t count); +}; + +struct btuart_dev { + struct hci_dev *hdev; + struct serdev_device *serdev; + + struct work_struct tx_work; + unsigned long tx_state; + struct sk_buff_head txq; + + struct sk_buff *rx_skb; + + const struct btuart_vnd *vnd; + void *data; +}; + +#define BTUART_TX_STATE_ACTIVE 1 +#define BTUART_TX_STATE_WAKEUP 2