Serial core's uart_write_wakeup( ) is used to unthrottle line discipline to send more data notifying that there is less number of data available in TTY circular buffer by MSM HSUART driver with uart port spinlock acquire. Here serial core is calling HCI Line Discipline driver's hci_uart_tty_wakeup( ) without scheduling tasklet in 3.4 kernel compare to 3.0 kernel. Due to that HCI Line Discipline driver pushes all available data to TTY Core as part of hardirq context in 3.4 kernel compare to softirq context on 3.0 kernel, which is causing watchdog timeout issue. Hence move all hci_uart_tty_wakeup() work to tasklet context to resolve this issue. Change-Id: I7e5d98d3cda7b6c862e97799cddbfbe97a28467f Signed-off-by: Ram Mohan Korukonda <rkorukon@codeaurora.org>
113 lines
2.8 KiB
C
113 lines
2.8 KiB
C
/*
|
|
*
|
|
* Bluetooth HCI UART driver
|
|
*
|
|
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
|
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
|
|
* Copyright (c) 2000-2001, 2010, 2012 Code Aurora Forum. All rights reserved.
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#ifndef N_HCI
|
|
#define N_HCI 15
|
|
#endif
|
|
|
|
/* Ioctls */
|
|
#define HCIUARTSETPROTO _IOW('U', 200, int)
|
|
#define HCIUARTGETPROTO _IOR('U', 201, int)
|
|
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
|
#define HCIUARTSETFLAGS _IOW('U', 203, int)
|
|
#define HCIUARTGETFLAGS _IOR('U', 204, int)
|
|
|
|
/* UART protocols */
|
|
#define HCI_UART_MAX_PROTO 7
|
|
|
|
#define HCI_UART_H4 0
|
|
#define HCI_UART_BCSP 1
|
|
#define HCI_UART_3WIRE 2
|
|
#define HCI_UART_H4DS 3
|
|
#define HCI_UART_LL 4
|
|
#define HCI_UART_IBS 5
|
|
#define HCI_UART_ATH3K 6
|
|
|
|
#define HCI_UART_RAW_DEVICE 0
|
|
|
|
struct hci_uart;
|
|
|
|
struct hci_uart_proto {
|
|
unsigned int id;
|
|
int (*open)(struct hci_uart *hu);
|
|
int (*close)(struct hci_uart *hu);
|
|
int (*flush)(struct hci_uart *hu);
|
|
int (*recv)(struct hci_uart *hu, void *data, int len);
|
|
int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
|
|
struct sk_buff *(*dequeue)(struct hci_uart *hu);
|
|
};
|
|
|
|
struct hci_uart {
|
|
struct tty_struct *tty;
|
|
struct hci_dev *hdev;
|
|
unsigned long flags;
|
|
unsigned long hdev_flags;
|
|
|
|
struct hci_uart_proto *proto;
|
|
struct tasklet_struct tty_wakeup_task;
|
|
void *priv;
|
|
|
|
struct sk_buff *tx_skb;
|
|
unsigned long tx_state;
|
|
spinlock_t rx_lock;
|
|
};
|
|
|
|
/* HCI_UART proto flag bits */
|
|
#define HCI_UART_PROTO_SET 0
|
|
#define HCI_UART_PROTO_SET_IN_PROGRESS 1
|
|
|
|
/* TX states */
|
|
#define HCI_UART_SENDING 1
|
|
#define HCI_UART_TX_WAKEUP 2
|
|
|
|
int hci_uart_register_proto(struct hci_uart_proto *p);
|
|
int hci_uart_unregister_proto(struct hci_uart_proto *p);
|
|
int hci_uart_tx_wakeup(struct hci_uart *hu);
|
|
|
|
#ifdef CONFIG_BT_HCIUART_H4
|
|
int h4_init(void);
|
|
int h4_deinit(void);
|
|
#endif
|
|
|
|
#ifdef CONFIG_BT_HCIUART_BCSP
|
|
int bcsp_init(void);
|
|
int bcsp_deinit(void);
|
|
#endif
|
|
|
|
#ifdef CONFIG_BT_HCIUART_LL
|
|
int ll_init(void);
|
|
int ll_deinit(void);
|
|
#endif
|
|
|
|
#ifdef CONFIG_BT_HCIUART_ATH3K
|
|
int ath_init(void);
|
|
int ath_deinit(void);
|
|
#endif
|
|
|
|
#ifdef CONFIG_BT_HCIUART_IBS
|
|
int ibs_init(void);
|
|
int ibs_deinit(void);
|
|
#endif
|