Blame view

drivers/bluetooth/hci_bcm.c 34.7 KB
1a59d1b8e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
e9a2dd261   Marcel Holtmann   Bluetooth: hci_ua...
2
3
4
5
6
  /*
   *
   *  Bluetooth HCI UART driver for Broadcom devices
   *
   *  Copyright (C) 2015  Intel Corporation
e9a2dd261   Marcel Holtmann   Bluetooth: hci_ua...
7
8
9
10
11
   */
  
  #include <linux/kernel.h>
  #include <linux/errno.h>
  #include <linux/skbuff.h>
18aeb4445   Frederic Danis   Bluetooth: btbcm:...
12
  #include <linux/firmware.h>
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
13
14
  #include <linux/module.h>
  #include <linux/acpi.h>
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
15
  #include <linux/of.h>
f25a96c8e   Guillaume La Roque   Bluetooth: hci_bc...
16
  #include <linux/of_irq.h>
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
17
  #include <linux/property.h>
4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
18
  #include <linux/platform_data/x86/apple.h>
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
19
  #include <linux/platform_device.h>
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
20
  #include <linux/regulator/consumer.h>
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
21
22
23
  #include <linux/clk.h>
  #include <linux/gpio/consumer.h>
  #include <linux/tty.h>
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
24
  #include <linux/interrupt.h>
5cebdfea3   Frederic Danis   Bluetooth: hci_bc...
25
  #include <linux/dmi.h>
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
26
  #include <linux/pm_runtime.h>
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
27
  #include <linux/serdev.h>
e9a2dd261   Marcel Holtmann   Bluetooth: hci_ua...
28
29
30
  
  #include <net/bluetooth/bluetooth.h>
  #include <net/bluetooth/hci_core.h>
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
31
  #include "btbcm.h"
e9a2dd261   Marcel Holtmann   Bluetooth: hci_ua...
32
  #include "hci_uart.h"
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
33

01d5e44ac   Marcel Holtmann   Bluetooth: hci_bc...
34
35
  #define BCM_NULL_PKT 0x00
  #define BCM_NULL_SIZE 0
94c58132c   Marcel Holtmann   Bluetooth: hci_bc...
36
37
  #define BCM_LM_DIAG_PKT 0x07
  #define BCM_LM_DIAG_SIZE 63
22bba8050   Jonathan Bakker   Bluetooth: hci_bc...
38
39
40
41
42
  #define BCM_TYPE49_PKT 0x31
  #define BCM_TYPE49_SIZE 0
  
  #define BCM_TYPE52_PKT 0x34
  #define BCM_TYPE52_SIZE 0
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
43
  #define BCM_AUTOSUSPEND_DELAY	5000 /* default autosleep delay */
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
44
  #define BCM_NUM_SUPPLIES 2
b7c2abac1   Lukas Wunner   Bluetooth: hci_bc...
45
  /**
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
46
47
48
49
50
   * struct bcm_device_data - device specific data
   * @no_early_set_baudrate: Disallow set baudrate before driver setup()
   */
  struct bcm_device_data {
  	bool	no_early_set_baudrate;
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
51
  	bool	drive_rts_on_open;
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
52
53
54
  };
  
  /**
b7c2abac1   Lukas Wunner   Bluetooth: hci_bc...
55
56
57
58
59
60
61
62
63
64
   * struct bcm_device - device driver resources
   * @serdev_hu: HCI UART controller struct
   * @list: bcm_device_list node
   * @dev: physical UART slave
   * @name: device name logged by bt_dev_*() functions
   * @device_wakeup: BT_WAKE pin,
   *	assert = Bluetooth device must wake up or remain awake,
   *	deassert = Bluetooth device may sleep when sleep criteria are met
   * @shutdown: BT_REG_ON pin,
   *	power up or power down Bluetooth device internal regulators
8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
65
   * @set_device_wakeup: callback to toggle BT_WAKE pin
4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
66
   *	either by accessing @device_wakeup or by calling @btlp
8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
67
   * @set_shutdown: callback to toggle BT_REG_ON pin
4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
68
69
70
71
   *	either by accessing @shutdown or by calling @btpu/@btpd
   * @btlp: Apple ACPI method to toggle BT_WAKE pin ("Bluetooth Low Power")
   * @btpu: Apple ACPI method to drive BT_REG_ON pin high ("Bluetooth Power Up")
   * @btpd: Apple ACPI method to drive BT_REG_ON pin low ("Bluetooth Power Down")
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
72
   * @txco_clk: external reference frequency clock used by Bluetooth device
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
73
   * @lpo_clk: external LPO clock used by Bluetooth device
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
74
75
   * @supplies: VBAT and VDDIO supplies used by Bluetooth device
   * @res_enabled: whether clocks and supplies are prepared and enabled
b7c2abac1   Lukas Wunner   Bluetooth: hci_bc...
76
77
78
79
80
81
82
83
84
85
   * @init_speed: default baudrate of Bluetooth device;
   *	the host UART is initially set to this baudrate so that
   *	it can configure the Bluetooth device for @oper_speed
   * @oper_speed: preferred baudrate of Bluetooth device;
   *	set to 0 if @init_speed is already the preferred baudrate
   * @irq: interrupt triggered by HOST_WAKE_BT pin
   * @irq_active_low: whether @irq is active low
   * @hu: pointer to HCI UART controller struct,
   *	used to disable flow control during runtime suspend and system sleep
   * @is_suspended: whether flow control is currently disabled
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
86
   * @no_early_set_baudrate: don't set_baudrate before setup()
b7c2abac1   Lukas Wunner   Bluetooth: hci_bc...
87
   */
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
88
  struct bcm_device {
8a9205683   Hans de Goede   Bluetooth: hci_bc...
89
90
  	/* Must be the first member, hci_serdev.c expects this. */
  	struct hci_uart		serdev_hu;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
91
  	struct list_head	list;
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
92
  	struct device		*dev;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
93
94
95
96
  
  	const char		*name;
  	struct gpio_desc	*device_wakeup;
  	struct gpio_desc	*shutdown;
8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
97
98
  	int			(*set_device_wakeup)(struct bcm_device *, bool);
  	int			(*set_shutdown)(struct bcm_device *, bool);
4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
99
100
  #ifdef CONFIG_ACPI
  	acpi_handle		btlp, btpu, btpd;
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
101
102
  	int			gpio_count;
  	int			gpio_int_idx;
4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
103
  #endif
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
104

55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
105
  	struct clk		*txco_clk;
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
106
  	struct clk		*lpo_clk;
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
107
108
  	struct regulator_bulk_data supplies[BCM_NUM_SUPPLIES];
  	bool			res_enabled;
ae0569088   Frederic Danis   Bluetooth: hci_bc...
109
110
  
  	u32			init_speed;
74183a1c5   Marcel Holtmann   Bluetooth: hci_bc...
111
  	u32			oper_speed;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
112
  	int			irq;
227630ccc   Hans de Goede   Bluetooth: hci_bc...
113
  	bool			irq_active_low;
81bd5d0c6   Michał Mirosław   Bluetooth: hci_bc...
114
  	bool			irq_acquired;
118612fb9   Frederic Danis   Bluetooth: hci_bc...
115

b7a622a24   Frederic Danis   Bluetooth: hci_bc...
116
  #ifdef CONFIG_PM
118612fb9   Frederic Danis   Bluetooth: hci_bc...
117
  	struct hci_uart		*hu;
b7c2abac1   Lukas Wunner   Bluetooth: hci_bc...
118
  	bool			is_suspended;
118612fb9   Frederic Danis   Bluetooth: hci_bc...
119
  #endif
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
120
  	bool			no_early_set_baudrate;
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
121
  	bool			drive_rts_on_open;
eb762b941   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
122
  	u8			pcm_int_params[5];
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
123
  };
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
124
  /* generic bcm uart resources */
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
125
  struct bcm_data {
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
126
127
128
129
  	struct sk_buff		*rx_skb;
  	struct sk_buff_head	txq;
  
  	struct bcm_device	*dev;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
130
  };
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
131
  /* List of BCM BT UART devices */
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
132
  static DEFINE_MUTEX(bcm_device_lock);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
133
  static LIST_HEAD(bcm_device_list);
e09070c51   Hans de Goede   Bluetooth: hci_bc...
134
135
136
  static int irq_polarity = -1;
  module_param(irq_polarity, int, 0444);
  MODULE_PARM_DESC(irq_polarity, "IRQ polarity 0: active-high 1: active-low");
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
137
138
139
140
141
142
143
  static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
  {
  	if (hu->serdev)
  		serdev_device_set_baudrate(hu->serdev, speed);
  	else
  		hci_uart_set_baudrate(hu, speed);
  }
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
144
145
146
147
148
149
150
151
152
153
  static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
  {
  	struct hci_dev *hdev = hu->hdev;
  	struct sk_buff *skb;
  	struct bcm_update_uart_baud_rate param;
  
  	if (speed > 3000000) {
  		struct bcm_write_uart_clock_setting clock;
  
  		clock.type = BCM_UART_CLOCK_48MHZ;
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
154
  		bt_dev_dbg(hdev, "Set Controller clock (%d)", clock.type);
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
155
156
157
158
159
160
161
  
  		/* This Broadcom specific command changes the UART's controller
  		 * clock for baud rate > 3000000.
  		 */
  		skb = __hci_cmd_sync(hdev, 0xfc45, 1, &clock, HCI_INIT_TIMEOUT);
  		if (IS_ERR(skb)) {
  			int err = PTR_ERR(skb);
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
162
163
  			bt_dev_err(hdev, "BCM: failed to write clock (%d)",
  				   err);
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
164
165
166
167
168
  			return err;
  		}
  
  		kfree_skb(skb);
  	}
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
169
  	bt_dev_dbg(hdev, "Set Controller UART speed to %d bit/s", speed);
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
170
171
172
173
174
175
176
177
178
179
180
  
  	param.zero = cpu_to_le16(0);
  	param.baud_rate = cpu_to_le32(speed);
  
  	/* This Broadcom specific command changes the UART's controller baud
  	 * rate.
  	 */
  	skb = __hci_cmd_sync(hdev, 0xfc18, sizeof(param), &param,
  			     HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		int err = PTR_ERR(skb);
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
181
182
  		bt_dev_err(hdev, "BCM: failed to write update baudrate (%d)",
  			   err);
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
183
184
185
186
187
188
189
  		return err;
  	}
  
  	kfree_skb(skb);
  
  	return 0;
  }
917522aae   Frederic Danis   Bluetooth: hci_bc...
190
  /* bcm_device_exists should be protected by bcm_device_lock */
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
191
192
193
  static bool bcm_device_exists(struct bcm_device *device)
  {
  	struct list_head *p;
81a190538   Arnd Bergmann   Bluetooth: hci_bc...
194
  #ifdef CONFIG_PM
8a9205683   Hans de Goede   Bluetooth: hci_bc...
195
196
197
  	/* Devices using serdev always exist */
  	if (device && device->hu && device->hu->serdev)
  		return true;
81a190538   Arnd Bergmann   Bluetooth: hci_bc...
198
  #endif
8a9205683   Hans de Goede   Bluetooth: hci_bc...
199

0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
200
201
202
203
204
205
206
207
208
209
210
211
  	list_for_each(p, &bcm_device_list) {
  		struct bcm_device *dev = list_entry(p, struct bcm_device, list);
  
  		if (device == dev)
  			return true;
  	}
  
  	return false;
  }
  
  static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
  {
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
212
  	int err;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
213

75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
214
  	if (powered && !dev->res_enabled) {
62611abc8   Chen-Yu Tsai   Bluetooth: hci_bc...
215
216
217
218
219
220
221
222
223
  		/* Intel Macs use bcm_apple_get_resources() and don't
  		 * have regulator supplies configured.
  		 */
  		if (dev->supplies[0].supply) {
  			err = regulator_bulk_enable(BCM_NUM_SUPPLIES,
  						    dev->supplies);
  			if (err)
  				return err;
  		}
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
224

90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
225
226
227
228
229
  		/* LPO clock needs to be 32.768 kHz */
  		err = clk_set_rate(dev->lpo_clk, 32768);
  		if (err) {
  			dev_err(dev->dev, "Could not set LPO clock rate
  ");
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
230
  			goto err_regulator_disable;
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
231
232
233
  		}
  
  		err = clk_prepare_enable(dev->lpo_clk);
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
234
  		if (err)
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
235
  			goto err_regulator_disable;
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
236
237
238
239
  
  		err = clk_prepare_enable(dev->txco_clk);
  		if (err)
  			goto err_lpo_clk_disable;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
240
241
242
243
  	}
  
  	err = dev->set_shutdown(dev, powered);
  	if (err)
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
244
  		goto err_txco_clk_disable;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
245
246
247
248
  
  	err = dev->set_device_wakeup(dev, powered);
  	if (err)
  		goto err_revert_shutdown;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
249

75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
250
  	if (!powered && dev->res_enabled) {
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
251
  		clk_disable_unprepare(dev->txco_clk);
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
252
  		clk_disable_unprepare(dev->lpo_clk);
62611abc8   Chen-Yu Tsai   Bluetooth: hci_bc...
253
254
255
256
257
258
259
  
  		/* Intel Macs use bcm_apple_get_resources() and don't
  		 * have regulator supplies configured.
  		 */
  		if (dev->supplies[0].supply)
  			regulator_bulk_disable(BCM_NUM_SUPPLIES,
  					       dev->supplies);
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
260
  	}
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
261

91927a9b3   Chen-Yu Tsai   Bluetooth: hci_bc...
262
  	/* wait for device to power on and come out of reset */
16946de59   Ondrej Jirman   bluetooth: hci_bc...
263
  	usleep_range(100000, 120000);
91927a9b3   Chen-Yu Tsai   Bluetooth: hci_bc...
264

75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
265
  	dev->res_enabled = powered;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
266
267
  
  	return 0;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
268
269
270
  
  err_revert_shutdown:
  	dev->set_shutdown(dev, !powered);
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
271
  err_txco_clk_disable:
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
272
  	if (powered && !dev->res_enabled)
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
273
  		clk_disable_unprepare(dev->txco_clk);
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
274
  err_lpo_clk_disable:
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
275
  	if (powered && !dev->res_enabled)
90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
276
  		clk_disable_unprepare(dev->lpo_clk);
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
277
278
279
  err_regulator_disable:
  	if (powered && !dev->res_enabled)
  		regulator_bulk_disable(BCM_NUM_SUPPLIES, dev->supplies);
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
280
  	return err;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
281
  }
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
282
  #ifdef CONFIG_PM
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
283
284
285
286
287
  static irqreturn_t bcm_host_wake(int irq, void *data)
  {
  	struct bcm_device *bdev = data;
  
  	bt_dev_dbg(bdev, "Host wake IRQ");
b09c61522   Hans de Goede   Revert "Bluetooth...
288
289
290
  	pm_runtime_get(bdev->dev);
  	pm_runtime_mark_last_busy(bdev->dev);
  	pm_runtime_put_autosuspend(bdev->dev);
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
291

6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
292
293
294
295
296
297
  	return IRQ_HANDLED;
  }
  
  static int bcm_request_irq(struct bcm_data *bcm)
  {
  	struct bcm_device *bdev = bcm->dev;
98dc77d57   Loic Poulain   Bluetooth: hci_bc...
298
  	int err;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
299

6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
300
301
302
303
304
  	mutex_lock(&bcm_device_lock);
  	if (!bcm_device_exists(bdev)) {
  		err = -ENODEV;
  		goto unlock;
  	}
98dc77d57   Loic Poulain   Bluetooth: hci_bc...
305
306
307
308
  	if (bdev->irq <= 0) {
  		err = -EOPNOTSUPP;
  		goto unlock;
  	}
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
309

c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
310
  	err = devm_request_irq(bdev->dev, bdev->irq, bcm_host_wake,
227630ccc   Hans de Goede   Bluetooth: hci_bc...
311
312
313
  			       bdev->irq_active_low ? IRQF_TRIGGER_FALLING :
  						      IRQF_TRIGGER_RISING,
  			       "host_wake", bdev);
4dc273306   Lukas Wunner   Bluetooth: hci_bc...
314
315
  	if (err) {
  		bdev->irq = err;
98dc77d57   Loic Poulain   Bluetooth: hci_bc...
316
  		goto unlock;
4dc273306   Lukas Wunner   Bluetooth: hci_bc...
317
  	}
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
318

81bd5d0c6   Michał Mirosław   Bluetooth: hci_bc...
319
  	bdev->irq_acquired = true;
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
320
  	device_init_wakeup(bdev->dev, true);
98dc77d57   Loic Poulain   Bluetooth: hci_bc...
321

c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
322
  	pm_runtime_set_autosuspend_delay(bdev->dev,
98dc77d57   Loic Poulain   Bluetooth: hci_bc...
323
  					 BCM_AUTOSUSPEND_DELAY);
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
324
325
326
  	pm_runtime_use_autosuspend(bdev->dev);
  	pm_runtime_set_active(bdev->dev);
  	pm_runtime_enable(bdev->dev);
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  
  unlock:
  	mutex_unlock(&bcm_device_lock);
  
  	return err;
  }
  
  static const struct bcm_set_sleep_mode default_sleep_params = {
  	.sleep_mode = 1,	/* 0=Disabled, 1=UART, 2=Reserved, 3=USB */
  	.idle_host = 2,		/* idle threshold HOST, in 300ms */
  	.idle_dev = 2,		/* idle threshold device, in 300ms */
  	.bt_wake_active = 1,	/* BT_WAKE active mode: 1 = high, 0 = low */
  	.host_wake_active = 0,	/* HOST_WAKE active mode: 1 = high, 0 = low */
  	.allow_host_sleep = 1,	/* Allow host sleep in SCO flag */
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
341
  	.combine_modes = 1,	/* Combine sleep and LPM flag */
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
342
343
344
345
  	.tristate_control = 0,	/* Allow tri-state control of UART tx flag */
  	/* Irrelevant USB flags */
  	.usb_auto_sleep = 0,
  	.usb_resume_timeout = 0,
ff8759609   Lukas Wunner   Bluetooth: btbcm:...
346
  	.break_to_host = 0,
e07c99b07   Hans de Goede   Bluetooth: hci_bc...
347
  	.pulsed_host_wake = 1,
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
348
349
350
351
352
353
354
  };
  
  static int bcm_setup_sleep(struct hci_uart *hu)
  {
  	struct bcm_data *bcm = hu->priv;
  	struct sk_buff *skb;
  	struct bcm_set_sleep_mode sleep_params = default_sleep_params;
227630ccc   Hans de Goede   Bluetooth: hci_bc...
355
  	sleep_params.host_wake_active = !bcm->dev->irq_active_low;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  
  	skb = __hci_cmd_sync(hu->hdev, 0xfc27, sizeof(sleep_params),
  			     &sleep_params, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		int err = PTR_ERR(skb);
  		bt_dev_err(hu->hdev, "Sleep VSC failed (%d)", err);
  		return err;
  	}
  	kfree_skb(skb);
  
  	bt_dev_dbg(hu->hdev, "Set Sleep Parameters VSC succeeded");
  
  	return 0;
  }
  #else
  static inline int bcm_request_irq(struct bcm_data *bcm) { return 0; }
  static inline int bcm_setup_sleep(struct hci_uart *hu) { return 0; }
  #endif
075e1f5e6   Marcel Holtmann   Bluetooth: hci_bc...
374
375
376
377
378
379
380
381
382
383
  static int bcm_set_diag(struct hci_dev *hdev, bool enable)
  {
  	struct hci_uart *hu = hci_get_drvdata(hdev);
  	struct bcm_data *bcm = hu->priv;
  	struct sk_buff *skb;
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return -ENETDOWN;
  
  	skb = bt_skb_alloc(3, GFP_KERNEL);
a1857390e   Dan Carpenter   Bluetooth: hci_bc...
384
385
  	if (!skb)
  		return -ENOMEM;
075e1f5e6   Marcel Holtmann   Bluetooth: hci_bc...
386

634fef610   Johannes Berg   networking: add a...
387
388
389
  	skb_put_u8(skb, BCM_LM_DIAG_PKT);
  	skb_put_u8(skb, 0xf0);
  	skb_put_u8(skb, enable);
075e1f5e6   Marcel Holtmann   Bluetooth: hci_bc...
390
391
392
393
394
395
  
  	skb_queue_tail(&bcm->txq, skb);
  	hci_uart_tx_wakeup(hu);
  
  	return 0;
  }
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
396
397
398
  static int bcm_open(struct hci_uart *hu)
  {
  	struct bcm_data *bcm;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
399
  	struct list_head *p;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
400
  	int err;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
401

65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
402
  	bt_dev_dbg(hu->hdev, "hu %p", hu);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
403

b36a1552d   Vladis Dronov   Bluetooth: hci_ua...
404
405
  	if (!hci_uart_has_flow_control(hu))
  		return -EOPNOTSUPP;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
406
407
408
409
410
411
412
  	bcm = kzalloc(sizeof(*bcm), GFP_KERNEL);
  	if (!bcm)
  		return -ENOMEM;
  
  	skb_queue_head_init(&bcm->txq);
  
  	hu->priv = bcm;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
413

8a9205683   Hans de Goede   Bluetooth: hci_bc...
414
  	mutex_lock(&bcm_device_lock);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
415
  	if (hu->serdev) {
8a9205683   Hans de Goede   Bluetooth: hci_bc...
416
  		bcm->dev = serdev_device_get_drvdata(hu->serdev);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
417
418
  		goto out;
  	}
95065a61e   Johan Hovold   Bluetooth: hci_bc...
419
420
  	if (!hu->tty->dev)
  		goto out;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
421
422
423
424
425
426
427
  	list_for_each(p, &bcm_device_list) {
  		struct bcm_device *dev = list_entry(p, struct bcm_device, list);
  
  		/* Retrieve saved bcm_device based on parent of the
  		 * platform device (saved during device probe) and
  		 * parent of tty device used by hci_uart
  		 */
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
428
  		if (hu->tty->dev->parent == dev->dev->parent) {
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
429
  			bcm->dev = dev;
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
430
  #ifdef CONFIG_PM
118612fb9   Frederic Danis   Bluetooth: hci_bc...
431
432
  			dev->hu = hu;
  #endif
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
433
434
435
  			break;
  		}
  	}
95065a61e   Johan Hovold   Bluetooth: hci_bc...
436
  out:
8a9205683   Hans de Goede   Bluetooth: hci_bc...
437
  	if (bcm->dev) {
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
438
439
  		if (bcm->dev->drive_rts_on_open)
  			hci_uart_set_flow_control(hu, true);
8a9205683   Hans de Goede   Bluetooth: hci_bc...
440
  		hu->init_speed = bcm->dev->init_speed;
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
441
442
443
444
445
446
  
  		/* If oper_speed is set, ldisc/serdev will set the baudrate
  		 * before calling setup()
  		 */
  		if (!bcm->dev->no_early_set_baudrate)
  			hu->oper_speed = bcm->dev->oper_speed;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
447
  		err = bcm_gpio_set_power(bcm->dev, true);
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
448
449
450
  
  		if (bcm->dev->drive_rts_on_open)
  			hci_uart_set_flow_control(hu, false);
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
451
452
  		if (err)
  			goto err_unset_hu;
8a9205683   Hans de Goede   Bluetooth: hci_bc...
453
454
455
  	}
  
  	mutex_unlock(&bcm_device_lock);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
456
  	return 0;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
457
458
459
  
  err_unset_hu:
  #ifdef CONFIG_PM
e9ca08074   Hans de Goede   Bluetooth: hci_se...
460
  	if (!hu->serdev)
8c6b8eda7   Hans de Goede   Bluetooth: hci_bc...
461
  		bcm->dev->hu = NULL;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
462
  #endif
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
463
464
465
466
  	mutex_unlock(&bcm_device_lock);
  	hu->priv = NULL;
  	kfree(bcm);
  	return err;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
467
468
469
470
471
  }
  
  static int bcm_close(struct hci_uart *hu)
  {
  	struct bcm_data *bcm = hu->priv;
8a9205683   Hans de Goede   Bluetooth: hci_bc...
472
  	struct bcm_device *bdev = NULL;
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
473
  	int err;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
474

65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
475
  	bt_dev_dbg(hu->hdev, "hu %p", hu);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
476

0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
477
  	/* Protect bcm->dev against removal of the device or driver */
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
478
  	mutex_lock(&bcm_device_lock);
8a9205683   Hans de Goede   Bluetooth: hci_bc...
479
480
  
  	if (hu->serdev) {
8a9205683   Hans de Goede   Bluetooth: hci_bc...
481
482
483
484
485
486
487
488
489
  		bdev = serdev_device_get_drvdata(hu->serdev);
  	} else if (bcm_device_exists(bcm->dev)) {
  		bdev = bcm->dev;
  #ifdef CONFIG_PM
  		bdev->hu = NULL;
  #endif
  	}
  
  	if (bdev) {
81bd5d0c6   Michał Mirosław   Bluetooth: hci_bc...
490
  		if (IS_ENABLED(CONFIG_PM) && bdev->irq_acquired) {
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
491
492
  			devm_free_irq(bdev->dev, bdev->irq, bdev);
  			device_init_wakeup(bdev->dev, false);
f4cf6b7e3   Lukas Wunner   Bluetooth: hci_bc...
493
  			pm_runtime_disable(bdev->dev);
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
494
  		}
54ba69f9e   Lukas Wunner   Bluetooth: hci_bc...
495

8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
496
497
498
499
500
  		err = bcm_gpio_set_power(bdev, false);
  		if (err)
  			bt_dev_err(hu->hdev, "Failed to power down");
  		else
  			pm_runtime_set_suspended(bdev->dev);
118612fb9   Frederic Danis   Bluetooth: hci_bc...
501
  	}
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
502
  	mutex_unlock(&bcm_device_lock);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
503

bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
504
505
506
507
508
509
510
511
512
513
514
  	skb_queue_purge(&bcm->txq);
  	kfree_skb(bcm->rx_skb);
  	kfree(bcm);
  
  	hu->priv = NULL;
  	return 0;
  }
  
  static int bcm_flush(struct hci_uart *hu)
  {
  	struct bcm_data *bcm = hu->priv;
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
515
  	bt_dev_dbg(hu->hdev, "hu %p", hu);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
516
517
518
519
520
521
522
523
  
  	skb_queue_purge(&bcm->txq);
  
  	return 0;
  }
  
  static int bcm_setup(struct hci_uart *hu)
  {
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
524
  	struct bcm_data *bcm = hu->priv;
0287c5d84   Hans de Goede   Bluetooth: btbcm:...
525
  	bool fw_load_done = false;
960ef1d72   Frederic Danis   Bluetooth: hci_ua...
526
  	unsigned int speed;
6be09b48a   Frederic Danis   Bluetooth: hci_ua...
527
  	int err;
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
528
  	bt_dev_dbg(hu->hdev, "hu %p", hu);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
529

075e1f5e6   Marcel Holtmann   Bluetooth: hci_bc...
530
  	hu->hdev->set_diag = bcm_set_diag;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
531
  	hu->hdev->set_bdaddr = btbcm_set_bdaddr;
0287c5d84   Hans de Goede   Bluetooth: btbcm:...
532
  	err = btbcm_initialize(hu->hdev, &fw_load_done);
6be09b48a   Frederic Danis   Bluetooth: hci_ua...
533
534
  	if (err)
  		return err;
0287c5d84   Hans de Goede   Bluetooth: btbcm:...
535
  	if (!fw_load_done)
6be09b48a   Frederic Danis   Bluetooth: hci_ua...
536
  		return 0;
6be09b48a   Frederic Danis   Bluetooth: hci_ua...
537

960ef1d72   Frederic Danis   Bluetooth: hci_ua...
538
539
540
541
542
543
544
545
546
  	/* Init speed if any */
  	if (hu->init_speed)
  		speed = hu->init_speed;
  	else if (hu->proto->init_speed)
  		speed = hu->proto->init_speed;
  	else
  		speed = 0;
  
  	if (speed)
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
547
  		host_set_baudrate(hu, speed);
960ef1d72   Frederic Danis   Bluetooth: hci_ua...
548
549
550
551
  
  	/* Operational speed if any */
  	if (hu->oper_speed)
  		speed = hu->oper_speed;
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
552
553
  	else if (bcm->dev && bcm->dev->oper_speed)
  		speed = bcm->dev->oper_speed;
960ef1d72   Frederic Danis   Bluetooth: hci_ua...
554
555
556
557
558
559
560
  	else if (hu->proto->oper_speed)
  		speed = hu->proto->oper_speed;
  	else
  		speed = 0;
  
  	if (speed) {
  		err = bcm_set_baudrate(hu, speed);
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
561
  		if (!err)
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
562
  			host_set_baudrate(hu, speed);
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
563
  	}
eb762b941   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
564
565
566
567
568
569
570
571
572
  	/* PCM parameters if provided */
  	if (bcm->dev && bcm->dev->pcm_int_params[0] != 0xff) {
  		struct bcm_set_pcm_int_params params;
  
  		btbcm_read_pcm_int_params(hu->hdev, &params);
  
  		memcpy(&params, bcm->dev->pcm_int_params, 5);
  		btbcm_write_pcm_int_params(hu->hdev, &params);
  	}
0383f16a8   Hans de Goede   Bluetooth: btbcm:...
573
  	err = btbcm_finalize(hu->hdev, &fw_load_done);
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
574
575
  	if (err)
  		return err;
f8c51d28e   Hans de Goede   Bluetooth: btbcm:...
576
577
578
579
580
  	/* Some devices ship with the controller default address.
  	 * Allow the bootloader to set a valid address through the
  	 * device tree.
  	 */
  	set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hu->hdev->quirks);
cdd24a200   Loic Poulain   Bluetooth: hci_bc...
581
  	if (!bcm_request_irq(bcm))
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
582
  		err = bcm_setup_sleep(hu);
6be09b48a   Frederic Danis   Bluetooth: hci_ua...
583
584
  
  	return err;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
585
  }
94c58132c   Marcel Holtmann   Bluetooth: hci_bc...
586
587
588
589
590
591
  #define BCM_RECV_LM_DIAG \
  	.type = BCM_LM_DIAG_PKT, \
  	.hlen = BCM_LM_DIAG_SIZE, \
  	.loff = 0, \
  	.lsize = 0, \
  	.maxlen = BCM_LM_DIAG_SIZE
01d5e44ac   Marcel Holtmann   Bluetooth: hci_bc...
592
593
594
595
596
597
  #define BCM_RECV_NULL \
  	.type = BCM_NULL_PKT, \
  	.hlen = BCM_NULL_SIZE, \
  	.loff = 0, \
  	.lsize = 0, \
  	.maxlen = BCM_NULL_SIZE
22bba8050   Jonathan Bakker   Bluetooth: hci_bc...
598
599
600
601
602
603
604
605
606
607
608
609
610
  #define BCM_RECV_TYPE49 \
  	.type = BCM_TYPE49_PKT, \
  	.hlen = BCM_TYPE49_SIZE, \
  	.loff = 0, \
  	.lsize = 0, \
  	.maxlen = BCM_TYPE49_SIZE
  
  #define BCM_RECV_TYPE52 \
  	.type = BCM_TYPE52_PKT, \
  	.hlen = BCM_TYPE52_SIZE, \
  	.loff = 0, \
  	.lsize = 0, \
  	.maxlen = BCM_TYPE52_SIZE
79b8df936   Marcel Holtmann   Bluetooth: hci_ua...
611
  static const struct h4_recv_pkt bcm_recv_pkts[] = {
94c58132c   Marcel Holtmann   Bluetooth: hci_bc...
612
613
614
615
  	{ H4_RECV_ACL,      .recv = hci_recv_frame },
  	{ H4_RECV_SCO,      .recv = hci_recv_frame },
  	{ H4_RECV_EVENT,    .recv = hci_recv_frame },
  	{ BCM_RECV_LM_DIAG, .recv = hci_recv_diag  },
01d5e44ac   Marcel Holtmann   Bluetooth: hci_bc...
616
  	{ BCM_RECV_NULL,    .recv = hci_recv_diag  },
22bba8050   Jonathan Bakker   Bluetooth: hci_bc...
617
618
  	{ BCM_RECV_TYPE49,  .recv = hci_recv_diag  },
  	{ BCM_RECV_TYPE52,  .recv = hci_recv_diag  },
79b8df936   Marcel Holtmann   Bluetooth: hci_ua...
619
  };
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
620
621
622
623
624
625
  static int bcm_recv(struct hci_uart *hu, const void *data, int count)
  {
  	struct bcm_data *bcm = hu->priv;
  
  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
  		return -EUNATCH;
79b8df936   Marcel Holtmann   Bluetooth: hci_ua...
626
627
  	bcm->rx_skb = h4_recv_buf(hu->hdev, bcm->rx_skb, data, count,
  				  bcm_recv_pkts, ARRAY_SIZE(bcm_recv_pkts));
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
628
629
  	if (IS_ERR(bcm->rx_skb)) {
  		int err = PTR_ERR(bcm->rx_skb);
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
630
  		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
371341676   Chan-yeol Park   Bluetooth: hci_ua...
631
  		bcm->rx_skb = NULL;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
632
  		return err;
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
633
634
635
  	} else if (!bcm->rx_skb) {
  		/* Delay auto-suspend when receiving completed packet */
  		mutex_lock(&bcm_device_lock);
b09c61522   Hans de Goede   Revert "Bluetooth...
636
637
638
639
640
  		if (bcm->dev && bcm_device_exists(bcm->dev)) {
  			pm_runtime_get(bcm->dev->dev);
  			pm_runtime_mark_last_busy(bcm->dev->dev);
  			pm_runtime_put_autosuspend(bcm->dev->dev);
  		}
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
641
  		mutex_unlock(&bcm_device_lock);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
642
643
644
645
646
647
648
649
  	}
  
  	return count;
  }
  
  static int bcm_enqueue(struct hci_uart *hu, struct sk_buff *skb)
  {
  	struct bcm_data *bcm = hu->priv;
65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
650
  	bt_dev_dbg(hu->hdev, "hu %p skb %p", hu, skb);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
651
652
  
  	/* Prepend skb with frame type */
618e8bc22   Marcel Holtmann   Bluetooth: Use ne...
653
  	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
654
655
656
657
658
659
660
661
  	skb_queue_tail(&bcm->txq, skb);
  
  	return 0;
  }
  
  static struct sk_buff *bcm_dequeue(struct hci_uart *hu)
  {
  	struct bcm_data *bcm = hu->priv;
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
662
663
664
665
666
667
668
  	struct sk_buff *skb = NULL;
  	struct bcm_device *bdev = NULL;
  
  	mutex_lock(&bcm_device_lock);
  
  	if (bcm_device_exists(bcm->dev)) {
  		bdev = bcm->dev;
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
669
  		pm_runtime_get_sync(bdev->dev);
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
670
671
672
673
674
675
  		/* Shall be resumed here */
  	}
  
  	skb = skb_dequeue(&bcm->txq);
  
  	if (bdev) {
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
676
677
  		pm_runtime_mark_last_busy(bdev->dev);
  		pm_runtime_put_autosuspend(bdev->dev);
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
678
  	}
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
679

e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
680
681
682
  	mutex_unlock(&bcm_device_lock);
  
  	return skb;
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
683
  }
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
684
685
  #ifdef CONFIG_PM
  static int bcm_suspend_device(struct device *dev)
118612fb9   Frederic Danis   Bluetooth: hci_bc...
686
  {
78277d737   Hans de Goede   Bluetooth: hci_bc...
687
  	struct bcm_device *bdev = dev_get_drvdata(dev);
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
688
  	int err;
118612fb9   Frederic Danis   Bluetooth: hci_bc...
689

b7a622a24   Frederic Danis   Bluetooth: hci_bc...
690
  	bt_dev_dbg(bdev, "");
917522aae   Frederic Danis   Bluetooth: hci_bc...
691

b7a622a24   Frederic Danis   Bluetooth: hci_bc...
692
  	if (!bdev->is_suspended && bdev->hu) {
118612fb9   Frederic Danis   Bluetooth: hci_bc...
693
  		hci_uart_set_flow_control(bdev->hu, true);
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
694
  		/* Once this returns, driver suspends BT via GPIO */
118612fb9   Frederic Danis   Bluetooth: hci_bc...
695
696
697
698
  		bdev->is_suspended = true;
  	}
  
  	/* Suspend the device */
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
699
700
701
702
703
704
705
706
  	err = bdev->set_device_wakeup(bdev, false);
  	if (err) {
  		if (bdev->is_suspended && bdev->hu) {
  			bdev->is_suspended = false;
  			hci_uart_set_flow_control(bdev->hu, false);
  		}
  		return -EBUSY;
  	}
3e81a4ca5   Lukas Wunner   Bluetooth: hci_bc...
707
  	bt_dev_dbg(bdev, "suspend, delaying 15 ms");
e4b9e5b86   Lukas Wunner   Bluetooth: hci_bc...
708
  	msleep(15);
118612fb9   Frederic Danis   Bluetooth: hci_bc...
709

b7a622a24   Frederic Danis   Bluetooth: hci_bc...
710
711
712
713
714
  	return 0;
  }
  
  static int bcm_resume_device(struct device *dev)
  {
78277d737   Hans de Goede   Bluetooth: hci_bc...
715
  	struct bcm_device *bdev = dev_get_drvdata(dev);
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
716
  	int err;
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
717
718
  
  	bt_dev_dbg(bdev, "");
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
719
720
721
722
723
724
  	err = bdev->set_device_wakeup(bdev, true);
  	if (err) {
  		dev_err(dev, "Failed to power up
  ");
  		return err;
  	}
3e81a4ca5   Lukas Wunner   Bluetooth: hci_bc...
725
  	bt_dev_dbg(bdev, "resume, delaying 15 ms");
e4b9e5b86   Lukas Wunner   Bluetooth: hci_bc...
726
  	msleep(15);
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
727
728
729
730
731
732
733
734
735
736
737
738
739
  
  	/* When this executes, the device has woken up already */
  	if (bdev->is_suspended && bdev->hu) {
  		bdev->is_suspended = false;
  
  		hci_uart_set_flow_control(bdev->hu, false);
  	}
  
  	return 0;
  }
  #endif
  
  #ifdef CONFIG_PM_SLEEP
8a9205683   Hans de Goede   Bluetooth: hci_bc...
740
  /* suspend callback */
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
741
742
  static int bcm_suspend(struct device *dev)
  {
78277d737   Hans de Goede   Bluetooth: hci_bc...
743
  	struct bcm_device *bdev = dev_get_drvdata(dev);
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
744
745
746
  	int error;
  
  	bt_dev_dbg(bdev, "suspend: is_suspended %d", bdev->is_suspended);
8a9205683   Hans de Goede   Bluetooth: hci_bc...
747
748
749
750
  	/*
  	 * When used with a device instantiated as platform_device, bcm_suspend
  	 * can be called at any time as long as the platform device is bound,
  	 * so it should use bcm_device_lock to protect access to hci_uart
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
751
752
753
754
755
756
  	 * and device_wake-up GPIO.
  	 */
  	mutex_lock(&bcm_device_lock);
  
  	if (!bdev->hu)
  		goto unlock;
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
757
758
  	if (pm_runtime_active(dev))
  		bcm_suspend_device(dev);
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
759

4a59f1fab   Ronald Tschalär   Bluetooth: hci_bc...
760
  	if (device_may_wakeup(dev) && bdev->irq > 0) {
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
761
762
763
764
  		error = enable_irq_wake(bdev->irq);
  		if (!error)
  			bt_dev_dbg(bdev, "BCM irq: enabled");
  	}
917522aae   Frederic Danis   Bluetooth: hci_bc...
765
  unlock:
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
766
  	mutex_unlock(&bcm_device_lock);
917522aae   Frederic Danis   Bluetooth: hci_bc...
767

118612fb9   Frederic Danis   Bluetooth: hci_bc...
768
769
  	return 0;
  }
8a9205683   Hans de Goede   Bluetooth: hci_bc...
770
  /* resume callback */
118612fb9   Frederic Danis   Bluetooth: hci_bc...
771
772
  static int bcm_resume(struct device *dev)
  {
78277d737   Hans de Goede   Bluetooth: hci_bc...
773
  	struct bcm_device *bdev = dev_get_drvdata(dev);
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
774
  	int err = 0;
118612fb9   Frederic Danis   Bluetooth: hci_bc...
775

65ad07c9e   Frederic Danis   Bluetooth: hci_bc...
776
  	bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended);
118612fb9   Frederic Danis   Bluetooth: hci_bc...
777

8a9205683   Hans de Goede   Bluetooth: hci_bc...
778
779
780
781
  	/*
  	 * When used with a device instantiated as platform_device, bcm_resume
  	 * can be called at any time as long as platform device is bound,
  	 * so it should use bcm_device_lock to protect access to hci_uart
b7a622a24   Frederic Danis   Bluetooth: hci_bc...
782
783
  	 * and device_wake-up GPIO.
  	 */
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
784
  	mutex_lock(&bcm_device_lock);
917522aae   Frederic Danis   Bluetooth: hci_bc...
785
786
787
  
  	if (!bdev->hu)
  		goto unlock;
4a59f1fab   Ronald Tschalär   Bluetooth: hci_bc...
788
  	if (device_may_wakeup(dev) && bdev->irq > 0) {
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
789
790
791
  		disable_irq_wake(bdev->irq);
  		bt_dev_dbg(bdev, "BCM irq: disabled");
  	}
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
792
  	err = bcm_resume_device(dev);
118612fb9   Frederic Danis   Bluetooth: hci_bc...
793

917522aae   Frederic Danis   Bluetooth: hci_bc...
794
  unlock:
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
795
  	mutex_unlock(&bcm_device_lock);
917522aae   Frederic Danis   Bluetooth: hci_bc...
796

8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
797
798
799
800
801
  	if (!err) {
  		pm_runtime_disable(dev);
  		pm_runtime_set_active(dev);
  		pm_runtime_enable(dev);
  	}
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
802

118612fb9   Frederic Danis   Bluetooth: hci_bc...
803
804
805
  	return 0;
  }
  #endif
ff7c8380c   YueHaibing   Bluetooth: hci_bc...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
  static const struct dmi_system_id bcm_broken_irq_dmi_table[] = {
  	{
  		.ident = "Meegopad T08",
  		.matches = {
  			DMI_EXACT_MATCH(DMI_BOARD_VENDOR,
  					"To be filled by OEM."),
  			DMI_EXACT_MATCH(DMI_BOARD_NAME, "T3 MRD"),
  			DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V1.1"),
  		},
  	},
  	{ }
  };
  
  #ifdef CONFIG_ACPI
9644e6b98   Hans de Goede   Bluetooth: hci_bc...
821
822
823
  static const struct acpi_gpio_params first_gpio = { 0, 0, false };
  static const struct acpi_gpio_params second_gpio = { 1, 0, false };
  static const struct acpi_gpio_params third_gpio = { 2, 0, false };
89ab37b48   Daniel Drake   Bluetooth: hci_bc...
824
825
  
  static const struct acpi_gpio_mapping acpi_bcm_int_last_gpios[] = {
9644e6b98   Hans de Goede   Bluetooth: hci_bc...
826
827
828
  	{ "device-wakeup-gpios", &first_gpio, 1 },
  	{ "shutdown-gpios", &second_gpio, 1 },
  	{ "host-wakeup-gpios", &third_gpio, 1 },
89ab37b48   Daniel Drake   Bluetooth: hci_bc...
829
830
  	{ },
  };
89ab37b48   Daniel Drake   Bluetooth: hci_bc...
831
  static const struct acpi_gpio_mapping acpi_bcm_int_first_gpios[] = {
9644e6b98   Hans de Goede   Bluetooth: hci_bc...
832
833
834
  	{ "host-wakeup-gpios", &first_gpio, 1 },
  	{ "device-wakeup-gpios", &second_gpio, 1 },
  	{ "shutdown-gpios", &third_gpio, 1 },
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
835
836
  	{ },
  };
ae0569088   Frederic Danis   Bluetooth: hci_bc...
837
838
839
  static int bcm_resource(struct acpi_resource *ares, void *data)
  {
  	struct bcm_device *dev = data;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
840
841
842
843
844
845
846
  	struct acpi_resource_extended_irq *irq;
  	struct acpi_resource_gpio *gpio;
  	struct acpi_resource_uart_serialbus *sb;
  
  	switch (ares->type) {
  	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  		irq = &ares->data.extended_irq;
bb5208b31   Hans de Goede   Bluetooth: hci_bc...
847
848
849
850
  		if (irq->polarity != ACPI_ACTIVE_LOW)
  			dev_info(dev->dev, "ACPI Interrupt resource is active-high, this is usually wrong, treating the IRQ as active-low
  ");
  		dev->irq_active_low = true;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
851
852
853
854
  		break;
  
  	case ACPI_RESOURCE_TYPE_GPIO:
  		gpio = &ares->data.gpio;
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
855
856
  		if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) {
  			dev->gpio_int_idx = dev->gpio_count;
227630ccc   Hans de Goede   Bluetooth: hci_bc...
857
  			dev->irq_active_low = gpio->polarity == ACPI_ACTIVE_LOW;
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
858
859
  		}
  		dev->gpio_count++;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
860
861
862
  		break;
  
  	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
ae0569088   Frederic Danis   Bluetooth: hci_bc...
863
  		sb = &ares->data.uart_serial_bus;
74183a1c5   Marcel Holtmann   Bluetooth: hci_bc...
864
  		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_UART) {
ae0569088   Frederic Danis   Bluetooth: hci_bc...
865
  			dev->init_speed = sb->default_baud_rate;
74183a1c5   Marcel Holtmann   Bluetooth: hci_bc...
866
867
  			dev->oper_speed = 4000000;
  		}
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
868
869
870
871
  		break;
  
  	default:
  		break;
ae0569088   Frederic Danis   Bluetooth: hci_bc...
872
  	}
9d54fd6a9   Hans de Goede   Bluetooth: hci_bc...
873
  	return 0;
ae0569088   Frederic Danis   Bluetooth: hci_bc...
874
  }
4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
  
  static int bcm_apple_set_device_wakeup(struct bcm_device *dev, bool awake)
  {
  	if (ACPI_FAILURE(acpi_execute_simple_method(dev->btlp, NULL, !awake)))
  		return -EIO;
  
  	return 0;
  }
  
  static int bcm_apple_set_shutdown(struct bcm_device *dev, bool powered)
  {
  	if (ACPI_FAILURE(acpi_evaluate_object(powered ? dev->btpu : dev->btpd,
  					      NULL, NULL, NULL)))
  		return -EIO;
  
  	return 0;
  }
  
  static int bcm_apple_get_resources(struct bcm_device *dev)
  {
  	struct acpi_device *adev = ACPI_COMPANION(dev->dev);
  	const union acpi_object *obj;
  
  	if (!adev ||
  	    ACPI_FAILURE(acpi_get_handle(adev->handle, "BTLP", &dev->btlp)) ||
  	    ACPI_FAILURE(acpi_get_handle(adev->handle, "BTPU", &dev->btpu)) ||
  	    ACPI_FAILURE(acpi_get_handle(adev->handle, "BTPD", &dev->btpd)))
  		return -ENODEV;
  
  	if (!acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER, &obj) &&
  	    obj->buffer.length == 8)
  		dev->init_speed = *(u64 *)obj->buffer.pointer;
  
  	dev->set_device_wakeup = bcm_apple_set_device_wakeup;
  	dev->set_shutdown = bcm_apple_set_shutdown;
  
  	return 0;
  }
  #else
  static inline int bcm_apple_get_resources(struct bcm_device *dev)
  {
  	return -EOPNOTSUPP;
  }
212d71833   Andy Shevchenko   Bluetooth: hci_bc...
918
  #endif /* CONFIG_ACPI */
ae0569088   Frederic Danis   Bluetooth: hci_bc...
919

8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
920
921
  static int bcm_gpio_set_device_wakeup(struct bcm_device *dev, bool awake)
  {
fb2d466be   Loic Poulain   Bluetooth: hci_bc...
922
  	gpiod_set_value_cansleep(dev->device_wakeup, awake);
8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
923
924
925
926
927
  	return 0;
  }
  
  static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered)
  {
fb2d466be   Loic Poulain   Bluetooth: hci_bc...
928
  	gpiod_set_value_cansleep(dev->shutdown, powered);
8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
929
930
  	return 0;
  }
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
  /* Try a bunch of names for TXCO */
  static struct clk *bcm_get_txco(struct device *dev)
  {
  	struct clk *clk;
  
  	/* New explicit name */
  	clk = devm_clk_get(dev, "txco");
  	if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
  		return clk;
  
  	/* Deprecated name */
  	clk = devm_clk_get(dev, "extclk");
  	if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
  		return clk;
  
  	/* Original code used no name at all */
  	return devm_clk_get(dev, NULL);
  }
42ef18f09   Hans de Goede   Bluetooth: hci_bc...
949
  static int bcm_get_resources(struct bcm_device *dev)
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
950
  {
2b05393b0   Hans de Goede   Bluetooth: hci_bc...
951
  	const struct dmi_system_id *dmi_id;
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
952
  	int err;
2b05393b0   Hans de Goede   Bluetooth: hci_bc...
953

c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
954
  	dev->name = dev_name(dev->dev);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
955

4c33162c1   Lukas Wunner   Bluetooth: hci_bc...
956
957
  	if (x86_apple_machine && !bcm_apple_get_resources(dev))
  		return 0;
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
958
  	dev->txco_clk = bcm_get_txco(dev->dev);
89ab37b48   Daniel Drake   Bluetooth: hci_bc...
959

28ac03b9a   Chen-Yu Tsai   Bluetooth: hci_bc...
960
  	/* Handle deferred probing */
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
961
962
  	if (dev->txco_clk == ERR_PTR(-EPROBE_DEFER))
  		return PTR_ERR(dev->txco_clk);
28ac03b9a   Chen-Yu Tsai   Bluetooth: hci_bc...
963

8c08947b7   Chen-Yu Tsai   Bluetooth: hci_bc...
964
  	/* Ignore all other errors as before */
55dbfcd0f   Chen-Yu Tsai   Bluetooth: hci_bc...
965
966
  	if (IS_ERR(dev->txco_clk))
  		dev->txco_clk = NULL;
8c08947b7   Chen-Yu Tsai   Bluetooth: hci_bc...
967

90bc07cc5   Chen-Yu Tsai   Bluetooth: hci_bc...
968
969
970
971
972
973
974
975
976
977
978
979
  	dev->lpo_clk = devm_clk_get(dev->dev, "lpo");
  	if (dev->lpo_clk == ERR_PTR(-EPROBE_DEFER))
  		return PTR_ERR(dev->lpo_clk);
  
  	if (IS_ERR(dev->lpo_clk))
  		dev->lpo_clk = NULL;
  
  	/* Check if we accidentally fetched the lpo clock twice */
  	if (dev->lpo_clk && clk_is_match(dev->lpo_clk, dev->txco_clk)) {
  		devm_clk_put(dev->dev, dev->txco_clk);
  		dev->txco_clk = NULL;
  	}
ab2f336cb   Stefan Wahren   Bluetooth: hci_bc...
980
981
  	dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup",
  						     GPIOD_OUT_LOW);
62aaefa7d   Uwe Kleine-König   Bluetooth: hci_bc...
982
983
  	if (IS_ERR(dev->device_wakeup))
  		return PTR_ERR(dev->device_wakeup);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
984

ab2f336cb   Stefan Wahren   Bluetooth: hci_bc...
985
986
  	dev->shutdown = devm_gpiod_get_optional(dev->dev, "shutdown",
  						GPIOD_OUT_LOW);
62aaefa7d   Uwe Kleine-König   Bluetooth: hci_bc...
987
988
  	if (IS_ERR(dev->shutdown))
  		return PTR_ERR(dev->shutdown);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
989

8353b4a63   Lukas Wunner   Bluetooth: hci_bc...
990
991
  	dev->set_device_wakeup = bcm_gpio_set_device_wakeup;
  	dev->set_shutdown = bcm_gpio_set_shutdown;
75d11676d   Chen-Yu Tsai   Bluetooth: hci_bc...
992
993
994
995
996
997
  	dev->supplies[0].supply = "vbat";
  	dev->supplies[1].supply = "vddio";
  	err = devm_regulator_bulk_get(dev->dev, BCM_NUM_SUPPLIES,
  				      dev->supplies);
  	if (err)
  		return err;
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
998
  	/* IRQ can be declared in ACPI table as Interrupt or GpioInt */
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
999
1000
  	if (dev->irq <= 0) {
  		struct gpio_desc *gpio;
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
1001
  		gpio = devm_gpiod_get_optional(dev->dev, "host-wakeup",
6cc4396c8   Frederic Danis   Bluetooth: hci_bc...
1002
1003
1004
1005
1006
1007
  					       GPIOD_IN);
  		if (IS_ERR(gpio))
  			return PTR_ERR(gpio);
  
  		dev->irq = gpiod_to_irq(gpio);
  	}
2b05393b0   Hans de Goede   Bluetooth: hci_bc...
1008
1009
1010
1011
1012
1013
1014
  	dmi_id = dmi_first_match(bcm_broken_irq_dmi_table);
  	if (dmi_id) {
  		dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm
  ",
  			 dmi_id->ident);
  		dev->irq = 0;
  	}
5954cdf17   Lukas Wunner   Bluetooth: hci_bc...
1015
1016
  	dev_dbg(dev->dev, "BCM irq: %d
  ", dev->irq);
212d71833   Andy Shevchenko   Bluetooth: hci_bc...
1017
1018
1019
1020
1021
1022
  	return 0;
  }
  
  #ifdef CONFIG_ACPI
  static int bcm_acpi_probe(struct bcm_device *dev)
  {
212d71833   Andy Shevchenko   Bluetooth: hci_bc...
1023
  	LIST_HEAD(resources);
212d71833   Andy Shevchenko   Bluetooth: hci_bc...
1024
  	const struct acpi_gpio_mapping *gpio_mapping = acpi_bcm_int_last_gpios;
9d54fd6a9   Hans de Goede   Bluetooth: hci_bc...
1025
  	struct resource_entry *entry;
212d71833   Andy Shevchenko   Bluetooth: hci_bc...
1026
  	int ret;
ae0569088   Frederic Danis   Bluetooth: hci_bc...
1027
  	/* Retrieve UART ACPI info */
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1028
  	dev->gpio_int_idx = -1;
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
1029
  	ret = acpi_dev_get_resources(ACPI_COMPANION(dev->dev),
e98d6d620   Jarkko Nikula   Bluetooth: hci_bc...
1030
  				     &resources, bcm_resource, dev);
5be00284d   Jarkko Nikula   Bluetooth: hci_bc...
1031
1032
  	if (ret < 0)
  		return ret;
9d54fd6a9   Hans de Goede   Bluetooth: hci_bc...
1033
1034
1035
1036
1037
1038
1039
  
  	resource_list_for_each_entry(entry, &resources) {
  		if (resource_type(entry->res) == IORESOURCE_IRQ) {
  			dev->irq = entry->res->start;
  			break;
  		}
  	}
09dbf1b78   Jarkko Nikula   Bluetooth: hci_bc...
1040
  	acpi_dev_free_resource_list(&resources);
ae0569088   Frederic Danis   Bluetooth: hci_bc...
1041

a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
  	/* If the DSDT uses an Interrupt resource for the IRQ, then there are
  	 * only 2 GPIO resources, we use the irq-last mapping for this, since
  	 * we already have an irq the 3th / last mapping will not be used.
  	 */
  	if (dev->irq)
  		gpio_mapping = acpi_bcm_int_last_gpios;
  	else if (dev->gpio_int_idx == 0)
  		gpio_mapping = acpi_bcm_int_first_gpios;
  	else if (dev->gpio_int_idx == 2)
  		gpio_mapping = acpi_bcm_int_last_gpios;
  	else
  		dev_warn(dev->dev, "Unexpected ACPI gpio_int_idx: %d
  ",
  			 dev->gpio_int_idx);
  
  	/* Warn if our expectations are not met. */
  	if (dev->gpio_count != (dev->irq ? 2 : 3))
  		dev_warn(dev->dev, "Unexpected number of ACPI GPIOs: %d
  ",
  			 dev->gpio_count);
  
  	ret = devm_acpi_dev_add_driver_gpios(dev->dev, gpio_mapping);
  	if (ret)
  		return ret;
e09070c51   Hans de Goede   Bluetooth: hci_bc...
1066
1067
1068
1069
1070
  	if (irq_polarity != -1) {
  		dev->irq_active_low = irq_polarity;
  		dev_warn(dev->dev, "Overwriting IRQ polarity to active %s by module-param
  ",
  			 dev->irq_active_low ? "low" : "high");
5cebdfea3   Frederic Danis   Bluetooth: hci_bc...
1071
  	}
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1072
1073
  	return 0;
  }
50d78bcf5   Frederic Danis   Bluetooth: hci_bc...
1074
1075
1076
1077
1078
1079
  #else
  static int bcm_acpi_probe(struct bcm_device *dev)
  {
  	return -EINVAL;
  }
  #endif /* CONFIG_ACPI */
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1080

8a9205683   Hans de Goede   Bluetooth: hci_bc...
1081
1082
1083
  static int bcm_of_probe(struct bcm_device *bdev)
  {
  	device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
eb762b941   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1084
1085
  	device_property_read_u8_array(bdev->dev, "brcm,bt-pcm-int-params",
  				      bdev->pcm_int_params, 5);
f25a96c8e   Guillaume La Roque   Bluetooth: hci_bc...
1086
  	bdev->irq = of_irq_get_byname(bdev->dev->of_node, "host-wakeup");
b25e4df4a   Michał Mirosław   Bluetooth: hci_bc...
1087
1088
  	bdev->irq_active_low = irq_get_trigger_type(bdev->irq)
  			     & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW);
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1089
1090
  	return 0;
  }
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1091
1092
1093
  static int bcm_probe(struct platform_device *pdev)
  {
  	struct bcm_device *dev;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1094
1095
1096
1097
1098
  	int ret;
  
  	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
  	if (!dev)
  		return -ENOMEM;
c0d3ce580   Hans de Goede   Bluetooth: hci_bc...
1099
  	dev->dev = &pdev->dev;
4a56f891e   Hans de Goede   Bluetooth: hci_bc...
1100
  	dev->irq = platform_get_irq(pdev, 0);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1101

eb762b941   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1102
1103
  	/* Initialize routing field to an unused value */
  	dev->pcm_int_params[0] = 0xff;
201762e21   Hans de Goede   Bluetooth: hci_bc...
1104
  	if (has_acpi_companion(&pdev->dev)) {
212d71833   Andy Shevchenko   Bluetooth: hci_bc...
1105
  		ret = bcm_acpi_probe(dev);
201762e21   Hans de Goede   Bluetooth: hci_bc...
1106
1107
1108
  		if (ret)
  			return ret;
  	}
42ef18f09   Hans de Goede   Bluetooth: hci_bc...
1109
  	ret = bcm_get_resources(dev);
4d1c45580   Jarkko Nikula   Bluetooth: hci_bc...
1110
1111
  	if (ret)
  		return ret;
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1112
1113
1114
1115
1116
1117
1118
  
  	platform_set_drvdata(pdev, dev);
  
  	dev_info(&pdev->dev, "%s device registered.
  ", dev->name);
  
  	/* Place this instance on the device list */
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
1119
  	mutex_lock(&bcm_device_lock);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1120
  	list_add_tail(&dev->list, &bcm_device_list);
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
1121
  	mutex_unlock(&bcm_device_lock);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1122

8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
1123
1124
1125
1126
  	ret = bcm_gpio_set_power(dev, false);
  	if (ret)
  		dev_err(&pdev->dev, "Failed to power down
  ");
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1127
1128
1129
1130
1131
1132
1133
  
  	return 0;
  }
  
  static int bcm_remove(struct platform_device *pdev)
  {
  	struct bcm_device *dev = platform_get_drvdata(pdev);
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
1134
  	mutex_lock(&bcm_device_lock);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1135
  	list_del(&dev->list);
bb3ea16a4   Frederic Danis   Bluetooth: hci_bc...
1136
  	mutex_unlock(&bcm_device_lock);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1137

0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1138
1139
1140
1141
1142
  	dev_info(&pdev->dev, "%s device unregistered.
  ", dev->name);
  
  	return 0;
  }
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
1143
1144
  static const struct hci_uart_proto bcm_proto = {
  	.id		= HCI_UART_BCM,
143f0a28f   Loic Poulain   Bluetooth: hci_bc...
1145
  	.name		= "Broadcom",
aee61f7aa   Marcel Holtmann   Bluetooth: hci_ua...
1146
  	.manufacturer	= 15,
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
1147
  	.init_speed	= 115200,
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
1148
1149
1150
1151
  	.open		= bcm_open,
  	.close		= bcm_close,
  	.flush		= bcm_flush,
  	.setup		= bcm_setup,
61b2fc2bb   Frederic Danis   Bluetooth: hci_ua...
1152
  	.set_baudrate	= bcm_set_baudrate,
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
1153
1154
1155
1156
  	.recv		= bcm_recv,
  	.enqueue	= bcm_enqueue,
  	.dequeue	= bcm_dequeue,
  };
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1157
1158
  #ifdef CONFIG_ACPI
  static const struct acpi_device_id bcm_acpi_match[] = {
611215026   Hans de Goede   Bluetooth: hci_bc...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
  	{ "BCM2E00" },
  	{ "BCM2E01" },
  	{ "BCM2E02" },
  	{ "BCM2E03" },
  	{ "BCM2E04" },
  	{ "BCM2E05" },
  	{ "BCM2E06" },
  	{ "BCM2E07" },
  	{ "BCM2E08" },
  	{ "BCM2E09" },
  	{ "BCM2E0A" },
  	{ "BCM2E0B" },
  	{ "BCM2E0C" },
  	{ "BCM2E0D" },
  	{ "BCM2E0E" },
  	{ "BCM2E0F" },
  	{ "BCM2E10" },
  	{ "BCM2E11" },
  	{ "BCM2E12" },
  	{ "BCM2E13" },
  	{ "BCM2E14" },
  	{ "BCM2E15" },
  	{ "BCM2E16" },
  	{ "BCM2E17" },
  	{ "BCM2E18" },
  	{ "BCM2E19" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1185
  	{ "BCM2E1A" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  	{ "BCM2E1B" },
  	{ "BCM2E1C" },
  	{ "BCM2E1D" },
  	{ "BCM2E1F" },
  	{ "BCM2E20" },
  	{ "BCM2E21" },
  	{ "BCM2E22" },
  	{ "BCM2E23" },
  	{ "BCM2E24" },
  	{ "BCM2E25" },
  	{ "BCM2E26" },
  	{ "BCM2E27" },
  	{ "BCM2E28" },
  	{ "BCM2E29" },
  	{ "BCM2E2A" },
  	{ "BCM2E2B" },
  	{ "BCM2E2C" },
  	{ "BCM2E2D" },
  	{ "BCM2E2E" },
  	{ "BCM2E2F" },
  	{ "BCM2E30" },
  	{ "BCM2E31" },
  	{ "BCM2E32" },
  	{ "BCM2E33" },
  	{ "BCM2E34" },
  	{ "BCM2E35" },
  	{ "BCM2E36" },
  	{ "BCM2E37" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1214
1215
1216
  	{ "BCM2E38" },
  	{ "BCM2E39" },
  	{ "BCM2E3A" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1217
1218
  	{ "BCM2E3B" },
  	{ "BCM2E3C" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1219
  	{ "BCM2E3D" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1220
  	{ "BCM2E3E" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1221
1222
  	{ "BCM2E3F" },
  	{ "BCM2E40" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
  	{ "BCM2E41" },
  	{ "BCM2E42" },
  	{ "BCM2E43" },
  	{ "BCM2E44" },
  	{ "BCM2E45" },
  	{ "BCM2E46" },
  	{ "BCM2E47" },
  	{ "BCM2E48" },
  	{ "BCM2E49" },
  	{ "BCM2E4A" },
  	{ "BCM2E4B" },
  	{ "BCM2E4C" },
  	{ "BCM2E4D" },
  	{ "BCM2E4E" },
  	{ "BCM2E4F" },
  	{ "BCM2E50" },
  	{ "BCM2E51" },
  	{ "BCM2E52" },
  	{ "BCM2E53" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1242
1243
  	{ "BCM2E54" },
  	{ "BCM2E55" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
  	{ "BCM2E56" },
  	{ "BCM2E57" },
  	{ "BCM2E58" },
  	{ "BCM2E59" },
  	{ "BCM2E5A" },
  	{ "BCM2E5B" },
  	{ "BCM2E5C" },
  	{ "BCM2E5D" },
  	{ "BCM2E5E" },
  	{ "BCM2E5F" },
  	{ "BCM2E60" },
  	{ "BCM2E61" },
  	{ "BCM2E62" },
  	{ "BCM2E63" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1258
1259
  	{ "BCM2E64" },
  	{ "BCM2E65" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1260
  	{ "BCM2E66" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1261
  	{ "BCM2E67" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1262
1263
1264
1265
1266
1267
1268
  	{ "BCM2E68" },
  	{ "BCM2E69" },
  	{ "BCM2E6B" },
  	{ "BCM2E6D" },
  	{ "BCM2E6E" },
  	{ "BCM2E6F" },
  	{ "BCM2E70" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1269
1270
  	{ "BCM2E71" },
  	{ "BCM2E72" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1271
  	{ "BCM2E73" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1272
  	{ "BCM2E74" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1273
1274
1275
1276
1277
1278
  	{ "BCM2E75" },
  	{ "BCM2E76" },
  	{ "BCM2E77" },
  	{ "BCM2E78" },
  	{ "BCM2E79" },
  	{ "BCM2E7A" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1279
1280
  	{ "BCM2E7B" },
  	{ "BCM2E7C" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1281
  	{ "BCM2E7D" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1282
  	{ "BCM2E7E" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1283
1284
1285
1286
  	{ "BCM2E7F" },
  	{ "BCM2E80" },
  	{ "BCM2E81" },
  	{ "BCM2E82" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1287
1288
  	{ "BCM2E83" },
  	{ "BCM2E84" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
  	{ "BCM2E85" },
  	{ "BCM2E86" },
  	{ "BCM2E87" },
  	{ "BCM2E88" },
  	{ "BCM2E89" },
  	{ "BCM2E8A" },
  	{ "BCM2E8B" },
  	{ "BCM2E8C" },
  	{ "BCM2E8D" },
  	{ "BCM2E8E" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1299
  	{ "BCM2E90" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1300
1301
1302
  	{ "BCM2E92" },
  	{ "BCM2E93" },
  	{ "BCM2E94" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1303
1304
  	{ "BCM2E95" },
  	{ "BCM2E96" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
  	{ "BCM2E97" },
  	{ "BCM2E98" },
  	{ "BCM2E99" },
  	{ "BCM2E9A" },
  	{ "BCM2E9B" },
  	{ "BCM2E9C" },
  	{ "BCM2E9D" },
  	{ "BCM2EA0" },
  	{ "BCM2EA1" },
  	{ "BCM2EA2" },
  	{ "BCM2EA3" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1316
  	{ "BCM2EA4" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1317
1318
1319
1320
1321
  	{ "BCM2EA5" },
  	{ "BCM2EA6" },
  	{ "BCM2EA7" },
  	{ "BCM2EA8" },
  	{ "BCM2EA9" },
a4de1567b   Hans de Goede   Bluetooth: hci_bc...
1322
  	{ "BCM2EAA" },
611215026   Hans de Goede   Bluetooth: hci_bc...
1323
1324
  	{ "BCM2EAB" },
  	{ "BCM2EAC" },
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1325
1326
1327
1328
  	{ },
  };
  MODULE_DEVICE_TABLE(acpi, bcm_acpi_match);
  #endif
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1329
  /* suspend and resume callbacks */
e88ab30d3   Frederic Danis   Bluetooth: hci_bc...
1330
1331
1332
1333
  static const struct dev_pm_ops bcm_pm_ops = {
  	SET_SYSTEM_SLEEP_PM_OPS(bcm_suspend, bcm_resume)
  	SET_RUNTIME_PM_OPS(bcm_suspend_device, bcm_resume_device, NULL)
  };
118612fb9   Frederic Danis   Bluetooth: hci_bc...
1334

0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1335
1336
1337
1338
1339
1340
  static struct platform_driver bcm_driver = {
  	.probe = bcm_probe,
  	.remove = bcm_remove,
  	.driver = {
  		.name = "hci_bcm",
  		.acpi_match_table = ACPI_PTR(bcm_acpi_match),
118612fb9   Frederic Danis   Bluetooth: hci_bc...
1341
  		.pm = &bcm_pm_ops,
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1342
1343
  	},
  };
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1344
1345
  static int bcm_serdev_probe(struct serdev_device *serdev)
  {
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1346
  	struct bcm_device *bcmdev;
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1347
  	const struct bcm_device_data *data;
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1348
1349
1350
1351
1352
  	int err;
  
  	bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
  	if (!bcmdev)
  		return -ENOMEM;
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1353
  	bcmdev->dev = &serdev->dev;
81a190538   Arnd Bergmann   Bluetooth: hci_bc...
1354
  #ifdef CONFIG_PM
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1355
  	bcmdev->hu = &bcmdev->serdev_hu;
81a190538   Arnd Bergmann   Bluetooth: hci_bc...
1356
  #endif
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1357
  	bcmdev->serdev_hu.serdev = serdev;
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1358
  	serdev_device_set_drvdata(serdev, bcmdev);
eb762b941   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1359
1360
  	/* Initialize routing field to an unused value */
  	bcmdev->pcm_int_params[0] = 0xff;
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1361
1362
1363
1364
1365
1366
  	if (has_acpi_companion(&serdev->dev))
  		err = bcm_acpi_probe(bcmdev);
  	else
  		err = bcm_of_probe(bcmdev);
  	if (err)
  		return err;
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1367

8a9205683   Hans de Goede   Bluetooth: hci_bc...
1368
1369
1370
  	err = bcm_get_resources(bcmdev);
  	if (err)
  		return err;
f3863f1d7   Marcel Holtmann   Bluetooth: hci_bc...
1371
1372
1373
1374
1375
1376
  	if (!bcmdev->shutdown) {
  		dev_warn(&serdev->dev,
  			 "No reset resource, using default baud rate
  ");
  		bcmdev->oper_speed = bcmdev->init_speed;
  	}
8bfa7e1e0   Lukas Wunner   Bluetooth: hci_bc...
1377
1378
1379
1380
  	err = bcm_gpio_set_power(bcmdev, false);
  	if (err)
  		dev_err(&serdev->dev, "Failed to power down
  ");
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1381

5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1382
  	data = device_get_match_data(bcmdev->dev);
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
1383
  	if (data) {
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1384
  		bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
1385
1386
  		bcmdev->drive_rts_on_open = data->drive_rts_on_open;
  	}
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1387

8a9205683   Hans de Goede   Bluetooth: hci_bc...
1388
  	return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1389
1390
1391
1392
  }
  
  static void bcm_serdev_remove(struct serdev_device *serdev)
  {
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1393
  	struct bcm_device *bcmdev = serdev_device_get_drvdata(serdev);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1394

8a9205683   Hans de Goede   Bluetooth: hci_bc...
1395
  	hci_uart_unregister_device(&bcmdev->serdev_hu);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1396
1397
1398
  }
  
  #ifdef CONFIG_OF
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1399
1400
1401
  static struct bcm_device_data bcm4354_device_data = {
  	.no_early_set_baudrate = true,
  };
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
1402
1403
1404
  static struct bcm_device_data bcm43438_device_data = {
  	.drive_rts_on_open = true,
  };
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1405
  static const struct of_device_id bcm_bluetooth_of_match[] = {
92ffe0db3   Maxime Ripard   Bluetooth: hci_bc...
1406
  	{ .compatible = "brcm,bcm20702a1" },
88d1cc96c   Dmitry Osipenko   Bluetooth: hci_bc...
1407
  	{ .compatible = "brcm,bcm4329-bt" },
52c8c7a76   Ondrej Jirman   bluetooth: bcm: A...
1408
  	{ .compatible = "brcm,bcm4345c5" },
669045551   Chen-Yu Tsai   Bluetooth: hci_bc...
1409
  	{ .compatible = "brcm,bcm4330-bt" },
e601daed2   Stefan Wahren   Bluetooth: hci_bc...
1410
  	{ .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
5d6f39107   Abhishek Pandit-Subedi   Bluetooth: hci_bc...
1411
  	{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
1199ab4c9   Mohammad Rasim   Bluetooth: btbcm:...
1412
  	{ .compatible = "brcm,bcm4335a0" },
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
  	{ },
  };
  MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);
  #endif
  
  static struct serdev_device_driver bcm_serdev_driver = {
  	.probe = bcm_serdev_probe,
  	.remove = bcm_serdev_remove,
  	.driver = {
  		.name = "hci_uart_bcm",
  		.of_match_table = of_match_ptr(bcm_bluetooth_of_match),
8a9205683   Hans de Goede   Bluetooth: hci_bc...
1424
1425
  		.acpi_match_table = ACPI_PTR(bcm_acpi_match),
  		.pm = &bcm_pm_ops,
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1426
1427
  	},
  };
bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
1428
1429
  int __init bcm_init(void)
  {
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1430
1431
1432
  	/* For now, we need to keep both platform device
  	 * driver (ACPI generated) and serdev driver (DT).
  	 */
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1433
  	platform_driver_register(&bcm_driver);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1434
  	serdev_device_driver_register(&bcm_serdev_driver);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1435

bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
1436
1437
1438
1439
1440
  	return hci_uart_register_proto(&bcm_proto);
  }
  
  int __exit bcm_deinit(void)
  {
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1441
  	platform_driver_unregister(&bcm_driver);
33cd149e7   Loic Poulain   Bluetooth: hci_bc...
1442
  	serdev_device_driver_unregister(&bcm_serdev_driver);
0395ffc1e   Frederic Danis   Bluetooth: hci_bc...
1443

bdd8818e0   Marcel Holtmann   Bluetooth: hci_ua...
1444
1445
  	return hci_uart_unregister_proto(&bcm_proto);
  }