btmrvl_main.c 15.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/**
 * Marvell Bluetooth driver
 *
 * Copyright (C) 2009, Marvell International Ltd.
 *
 * This software file (the "File") is distributed by Marvell International
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 * (the "License").  You may use, redistribute and/or modify this File in
 * accordance with the terms and conditions of the License, a copy of which
 * is available by writing to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 * this warranty disclaimer.
 **/

21
#include <linux/module.h>
22
#include <linux/of.h>
23 24 25 26
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#include "btmrvl_drv.h"
27
#include "btmrvl_sdio.h"
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

#define VERSION "1.0"

/*
 * This function is called by interface specific interrupt handler.
 * It updates Power Save & Host Sleep states, and wakes up the main
 * thread.
 */
void btmrvl_interrupt(struct btmrvl_private *priv)
{
	priv->adapter->ps_state = PS_AWAKE;

	priv->adapter->wakeup_tries = 0;

	priv->adapter->int_count++;

	wake_up_interruptible(&priv->main_thread.wait_q);
}
EXPORT_SYMBOL_GPL(btmrvl_interrupt);

48
bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
49
{
50
	struct hci_event_hdr *hdr = (void *) skb->data;
51 52

	if (hdr->evt == HCI_EV_CMD_COMPLETE) {
53
		struct hci_ev_cmd_complete *ec;
54
		u16 opcode;
55

56
		ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
57
		opcode = __le16_to_cpu(ec->opcode);
58

59
		if (priv->btmrvl_dev.sendcmdflag) {
60 61 62
			priv->btmrvl_dev.sendcmdflag = false;
			priv->adapter->cmd_complete = true;
			wake_up_interruptible(&priv->adapter->cmd_wait_q);
63

64 65 66 67 68 69
			if (hci_opcode_ogf(opcode) == 0x3F) {
				BT_DBG("vendor event skipped: opcode=%#4.4x",
				       opcode);
				kfree_skb(skb);
				return false;
			}
70
		}
71
	}
72 73

	return true;
74 75 76 77 78 79 80
}
EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt);

int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
{
	struct btmrvl_adapter *adapter = priv->adapter;
	struct btmrvl_event *event;
81
	int ret = 0;
82 83 84 85 86 87 88 89 90

	event = (struct btmrvl_event *) skb->data;
	if (event->ec != 0xff) {
		BT_DBG("Not Marvell Event=%x", event->ec);
		ret = -EINVAL;
		goto exit;
	}

	switch (event->data[0]) {
91
	case BT_EVENT_AUTO_SLEEP_MODE:
92 93 94 95 96 97 98 99 100 101 102 103
		if (!event->data[2]) {
			if (event->data[1] == BT_PS_ENABLE)
				adapter->psmode = 1;
			else
				adapter->psmode = 0;
			BT_DBG("PS Mode:%s",
				(adapter->psmode) ? "Enable" : "Disable");
		} else {
			BT_DBG("PS Mode command failed");
		}
		break;

104
	case BT_EVENT_HOST_SLEEP_CONFIG:
105 106
		if (!event->data[3])
			BT_DBG("gpio=%x, gap=%x", event->data[1],
107
							event->data[2]);
108 109 110 111
		else
			BT_DBG("HSCFG command failed");
		break;

112
	case BT_EVENT_HOST_SLEEP_ENABLE:
113 114 115 116 117 118 119 120 121 122
		if (!event->data[1]) {
			adapter->hs_state = HS_ACTIVATED;
			if (adapter->psmode)
				adapter->ps_state = PS_SLEEP;
			BT_DBG("HS ACTIVATED!");
		} else {
			BT_DBG("HS Enable failed");
		}
		break;

123
	case BT_EVENT_MODULE_CFG_REQ:
124 125
		if (priv->btmrvl_dev.sendcmdflag &&
				event->data[1] == MODULE_BRINGUP_REQ) {
126 127 128 129
			BT_DBG("EVENT:%s",
				((event->data[2] == MODULE_BROUGHT_UP) ||
				(event->data[2] == MODULE_ALREADY_UP)) ?
				"Bring-up succeed" : "Bring-up failed");
130

131 132
			if (event->length > 3 && event->data[3])
				priv->btmrvl_dev.dev_type = HCI_AMP;
133 134 135 136
			else
				priv->btmrvl_dev.dev_type = HCI_BREDR;

			BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type);
137 138
		} else if (priv->btmrvl_dev.sendcmdflag &&
				event->data[1] == MODULE_SHUTDOWN_REQ) {
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
			BT_DBG("EVENT:%s", (event->data[2]) ?
				"Shutdown failed" : "Shutdown succeed");
		} else {
			BT_DBG("BT_CMD_MODULE_CFG_REQ resp for APP");
			ret = -EINVAL;
		}
		break;

	case BT_EVENT_POWER_STATE:
		if (event->data[1] == BT_PS_SLEEP)
			adapter->ps_state = PS_SLEEP;
		BT_DBG("EVENT:%s",
			(adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE");
		break;

	default:
		BT_DBG("Unknown Event=%d", event->data[0]);
		ret = -EINVAL;
		break;
	}

exit:
	if (!ret)
		kfree_skb(skb);

	return ret;
}
EXPORT_SYMBOL_GPL(btmrvl_process_event);

168
static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
169
				const void *param, u8 len)
170
{
171
	struct sk_buff *skb;
172
	struct hci_command_hdr *hdr;
173

174
	skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC);
175 176
	if (skb == NULL) {
		BT_ERR("No free skb");
177
		return -ENOMEM;
178 179
	}

180
	hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
181
	hdr->opcode = cpu_to_le16(opcode);
182
	hdr->plen = len;
183 184

	if (len)
185
		memcpy(skb_put(skb, len), param, len);
186 187 188 189 190 191 192 193 194 195 196

	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;

	skb_queue_head(&priv->adapter->tx_queue, skb);

	priv->btmrvl_dev.sendcmdflag = true;

	priv->adapter->cmd_complete = false;

	wake_up_interruptible(&priv->main_thread.wait_q);

197 198
	if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
				priv->adapter->cmd_complete,
199 200 201 202 203
				msecs_to_jiffies(WAIT_UNTIL_CMD_RESP)))
		return -ETIMEDOUT;

	return 0;
}
204

205
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
206 207 208 209 210 211
{
	int ret;

	ret = btmrvl_send_sync_cmd(priv, BT_CMD_MODULE_CFG_REQ, &subcmd, 1);
	if (ret)
		BT_ERR("module_cfg_cmd(%x) failed\n", subcmd);
212 213 214 215 216

	return ret;
}
EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd)
{
	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
	int ret;

	if (!card->support_pscan_win_report)
		return 0;

	ret = btmrvl_send_sync_cmd(priv, BT_CMD_PSCAN_WIN_REPORT_ENABLE,
				   &subcmd, 1);
	if (ret)
		BT_ERR("PSCAN_WIN_REPORT_ENABLE command failed: %#x", ret);

	return ret;
}
EXPORT_SYMBOL_GPL(btmrvl_pscan_window_reporting);

234 235
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
{
236 237
	int ret;
	u8 param[2];
238

239 240
	param[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
	param[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
241

242 243
	BT_DBG("Sending HSCFG Command, gpio=0x%x, gap=0x%x",
	       param[0], param[1]);
244

245 246 247
	ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_CONFIG, param, 2);
	if (ret)
		BT_ERR("HSCFG command failed\n");
248

249
	return ret;
250 251 252
}
EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);

253 254
int btmrvl_enable_ps(struct btmrvl_private *priv)
{
255 256
	int ret;
	u8 param;
257 258

	if (priv->btmrvl_dev.psmode)
259
		param = BT_PS_ENABLE;
260
	else
261
		param = BT_PS_DISABLE;
262

263 264 265
	ret = btmrvl_send_sync_cmd(priv, BT_CMD_AUTO_SLEEP_MODE, &param, 1);
	if (ret)
		BT_ERR("PSMODE command failed\n");
266 267 268 269 270

	return 0;
}
EXPORT_SYMBOL_GPL(btmrvl_enable_ps);

271
int btmrvl_enable_hs(struct btmrvl_private *priv)
272
{
273
	int ret;
274

275 276 277
	ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
	if (ret)
		BT_ERR("Host sleep enable command failed\n");
278 279 280

	return ret;
}
281
EXPORT_SYMBOL_GPL(btmrvl_enable_hs);
282 283 284

int btmrvl_prepare_command(struct btmrvl_private *priv)
{
285
	int ret = 0;
286 287 288

	if (priv->btmrvl_dev.hscfgcmd) {
		priv->btmrvl_dev.hscfgcmd = 0;
289
		btmrvl_send_hscfg_cmd(priv);
290 291 292 293
	}

	if (priv->btmrvl_dev.pscmd) {
		priv->btmrvl_dev.pscmd = 0;
294
		btmrvl_enable_ps(priv);
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
	}

	if (priv->btmrvl_dev.hscmd) {
		priv->btmrvl_dev.hscmd = 0;

		if (priv->btmrvl_dev.hsmode) {
			ret = btmrvl_enable_hs(priv);
		} else {
			ret = priv->hw_wakeup_firmware(priv);
			priv->adapter->hs_state = HS_DEACTIVATED;
		}
	}

	return ret;
}

static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
{
313
	int ret = 0;
314

315
	if (!skb || !skb->data)
316 317 318 319
		return -EINVAL;

	if (!skb->len || ((skb->len + BTM_HEADER_LEN) > BTM_UPLD_SIZE)) {
		BT_ERR("Tx Error: Bad skb length %d : %d",
320
						skb->len, BTM_UPLD_SIZE);
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
		return -EINVAL;
	}

	if (skb_headroom(skb) < BTM_HEADER_LEN) {
		struct sk_buff *tmp = skb;

		skb = skb_realloc_headroom(skb, BTM_HEADER_LEN);
		if (!skb) {
			BT_ERR("Tx Error: realloc_headroom failed %d",
				BTM_HEADER_LEN);
			skb = tmp;
			return -EINVAL;
		}

		kfree_skb(tmp);
	}

	skb_push(skb, BTM_HEADER_LEN);

	/* header type: byte[3]
	 * HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor
	 * header length: byte[2][1][0]
	 */

	skb->data[0] = (skb->len & 0x0000ff);
	skb->data[1] = (skb->len & 0x00ff00) >> 8;
	skb->data[2] = (skb->len & 0xff0000) >> 16;
	skb->data[3] = bt_cb(skb)->pkt_type;

	if (priv->hw_host_to_card)
		ret = priv->hw_host_to_card(priv, skb->data, skb->len);

	return ret;
}

static void btmrvl_init_adapter(struct btmrvl_private *priv)
{
358 359
	int buf_size;

360 361 362 363
	skb_queue_head_init(&priv->adapter->tx_queue);

	priv->adapter->ps_state = PS_AWAKE;

364 365 366 367 368 369 370 371 372 373 374 375 376
	buf_size = ALIGN_SZ(SDIO_BLOCK_SIZE, BTSDIO_DMA_ALIGN);
	priv->adapter->hw_regs_buf = kzalloc(buf_size, GFP_KERNEL);
	if (!priv->adapter->hw_regs_buf) {
		priv->adapter->hw_regs = NULL;
		BT_ERR("Unable to allocate buffer for hw_regs.");
	} else {
		priv->adapter->hw_regs =
			(u8 *)ALIGN_ADDR(priv->adapter->hw_regs_buf,
					 BTSDIO_DMA_ALIGN);
		BT_DBG("hw_regs_buf=%p hw_regs=%p",
		       priv->adapter->hw_regs_buf, priv->adapter->hw_regs);
	}

377 378 379 380 381 382 383
	init_waitqueue_head(&priv->adapter->cmd_wait_q);
}

static void btmrvl_free_adapter(struct btmrvl_private *priv)
{
	skb_queue_purge(&priv->adapter->tx_queue);

384
	kfree(priv->adapter->hw_regs_buf);
385 386 387 388 389
	kfree(priv->adapter);

	priv->adapter = NULL;
}

390
static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
391
{
392
	struct btmrvl_private *priv = hci_get_drvdata(hdev);
393

394
	BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
395 396 397 398

	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
		BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
		print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
399
							skb->data, skb->len);
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
		return -EBUSY;
	}

	switch (bt_cb(skb)->pkt_type) {
	case HCI_COMMAND_PKT:
		hdev->stat.cmd_tx++;
		break;

	case HCI_ACLDATA_PKT:
		hdev->stat.acl_tx++;
		break;

	case HCI_SCODATA_PKT:
		hdev->stat.sco_tx++;
		break;
	}

	skb_queue_tail(&priv->adapter->tx_queue, skb);

	wake_up_interruptible(&priv->main_thread.wait_q);

	return 0;
}

static int btmrvl_flush(struct hci_dev *hdev)
{
426
	struct btmrvl_private *priv = hci_get_drvdata(hdev);
427 428 429 430 431 432 433 434

	skb_queue_purge(&priv->adapter->tx_queue);

	return 0;
}

static int btmrvl_close(struct hci_dev *hdev)
{
435
	struct btmrvl_private *priv = hci_get_drvdata(hdev);
436

437
	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
438 439 440 441 442 443 444 445 446 447 448 449 450 451
		return 0;

	skb_queue_purge(&priv->adapter->tx_queue);

	return 0;
}

static int btmrvl_open(struct hci_dev *hdev)
{
	set_bit(HCI_RUNNING, &hdev->flags);

	return 0;
}

452
static int btmrvl_download_cal_data(struct btmrvl_private *priv,
453
				    u8 *data, int len)
454
{
455
	int ret;
456 457 458 459

	data[0] = 0x00;
	data[1] = 0x00;
	data[2] = 0x00;
460
	data[3] = len;
461 462

	print_hex_dump_bytes("Calibration data: ",
463
			     DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len);
464 465

	ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
466
				   BT_CAL_HDR_LEN + len);
467 468 469 470 471 472
	if (ret)
		BT_ERR("Failed to download caibration data\n");

	return 0;
}

473
static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
474
{
475
	struct device_node *dt_node;
476
	u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
477 478
	const char name[] = "btmrvl_caldata";
	const char property[] = "btmrvl,caldata";
479 480
	int ret;

481 482 483 484
	dt_node = of_find_node_by_name(NULL, name);
	if (!dt_node)
		return -ENODEV;

485 486 487
	ret = of_property_read_u8_array(dt_node, property,
					cal_data + BT_CAL_HDR_LEN,
					BT_CAL_DATA_SIZE);
488 489 490
	if (ret)
		return ret;

491
	BT_DBG("Use cal data from device tree");
492
	ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
493
	if (ret) {
494
		BT_ERR("Fail to download calibrate data");
495 496 497 498 499 500
		return ret;
	}

	return 0;
}

501 502 503 504 505 506
static int btmrvl_setup(struct hci_dev *hdev)
{
	struct btmrvl_private *priv = hci_get_drvdata(hdev);

	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);

507
	btmrvl_cal_data_dt(priv);
508

509 510
	btmrvl_pscan_window_reporting(priv, 0x01);

511 512 513 514 515 516 517 518 519
	priv->btmrvl_dev.psmode = 1;
	btmrvl_enable_ps(priv);

	priv->btmrvl_dev.gpio_gap = 0xffff;
	btmrvl_send_hscfg_cmd(priv);

	return 0;
}

520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
/*
 * This function handles the event generated by firmware, rx data
 * received from firmware, and tx data sent from kernel.
 */
static int btmrvl_service_main_thread(void *data)
{
	struct btmrvl_thread *thread = data;
	struct btmrvl_private *priv = thread->priv;
	struct btmrvl_adapter *adapter = priv->adapter;
	wait_queue_t wait;
	struct sk_buff *skb;
	ulong flags;

	init_waitqueue_entry(&wait, current);

	for (;;) {
		add_wait_queue(&thread->wait_q, &wait);

		set_current_state(TASK_INTERRUPTIBLE);
539 540 541 542
		if (kthread_should_stop()) {
			BT_DBG("main_thread: break from main thread");
			break;
		}
543 544

		if (adapter->wakeup_tries ||
545 546 547
				((!adapter->int_count) &&
				(!priv->btmrvl_dev.tx_dnld_rdy ||
				skb_queue_empty(&adapter->tx_queue)))) {
548 549 550 551 552 553 554 555 556 557 558 559 560
			BT_DBG("main_thread is sleeping...");
			schedule();
		}

		set_current_state(TASK_RUNNING);

		remove_wait_queue(&thread->wait_q, &wait);

		BT_DBG("main_thread woke up");

		spin_lock_irqsave(&priv->driver_lock, flags);
		if (adapter->int_count) {
			adapter->int_count = 0;
561 562
			spin_unlock_irqrestore(&priv->driver_lock, flags);
			priv->hw_process_int_status(priv);
563 564
		} else if (adapter->ps_state == PS_SLEEP &&
					!skb_queue_empty(&adapter->tx_queue)) {
565 566 567 568
			spin_unlock_irqrestore(&priv->driver_lock, flags);
			adapter->wakeup_tries++;
			priv->hw_wakeup_firmware(priv);
			continue;
569 570
		} else {
			spin_unlock_irqrestore(&priv->driver_lock, flags);
571 572 573 574 575 576 577 578 579 580 581 582 583
		}

		if (adapter->ps_state == PS_SLEEP)
			continue;

		if (!priv->btmrvl_dev.tx_dnld_rdy)
			continue;

		skb = skb_dequeue(&adapter->tx_queue);
		if (skb) {
			if (btmrvl_tx_pkt(priv, skb))
				priv->btmrvl_dev.hcidev->stat.err_tx++;
			else
584
				priv->btmrvl_dev.hcidev->stat.byte_tx += skb->len;
585 586 587 588 589 590 591 592

			kfree_skb(skb);
		}
	}

	return 0;
}

593
int btmrvl_register_hdev(struct btmrvl_private *priv)
594 595 596 597 598 599 600 601 602 603 604
{
	struct hci_dev *hdev = NULL;
	int ret;

	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can not allocate HCI device");
		goto err_hdev;
	}

	priv->btmrvl_dev.hcidev = hdev;
605
	hci_set_drvdata(hdev, priv);
606

607 608
	hdev->bus   = HCI_SDIO;
	hdev->open  = btmrvl_open;
609 610
	hdev->close = btmrvl_close;
	hdev->flush = btmrvl_flush;
611
	hdev->send  = btmrvl_send_frame;
612
	hdev->setup = btmrvl_setup;
613

614 615
	hdev->dev_type = priv->btmrvl_dev.dev_type;

616 617 618 619 620 621
	ret = hci_register_dev(hdev);
	if (ret < 0) {
		BT_ERR("Can not register HCI device");
		goto err_hci_register_dev;
	}

622 623 624 625
#ifdef CONFIG_DEBUG_FS
	btmrvl_debugfs_init(hdev);
#endif

626
	return 0;
627 628 629 630 631

err_hci_register_dev:
	hci_free_dev(hdev);

err_hdev:
632 633 634
	/* Stop the thread servicing the interrupts */
	kthread_stop(priv->main_thread.task);

635
	btmrvl_free_adapter(priv);
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
	kfree(priv);

	return -ENOMEM;
}
EXPORT_SYMBOL_GPL(btmrvl_register_hdev);

struct btmrvl_private *btmrvl_add_card(void *card)
{
	struct btmrvl_private *priv;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		BT_ERR("Can not allocate priv");
		goto err_priv;
	}

	priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL);
	if (!priv->adapter) {
		BT_ERR("Allocate buffer for btmrvl_adapter failed!");
		goto err_adapter;
	}

	btmrvl_init_adapter(priv);

	BT_DBG("Starting kthread...");
	priv->main_thread.priv = priv;
	spin_lock_init(&priv->driver_lock);

	init_waitqueue_head(&priv->main_thread.wait_q);
	priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
				&priv->main_thread, "btmrvl_main_service");

	priv->btmrvl_dev.card = card;
	priv->btmrvl_dev.tx_dnld_rdy = true;

	return priv;
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690

err_adapter:
	kfree(priv);

err_priv:
	return NULL;
}
EXPORT_SYMBOL_GPL(btmrvl_add_card);

int btmrvl_remove_card(struct btmrvl_private *priv)
{
	struct hci_dev *hdev;

	hdev = priv->btmrvl_dev.hcidev;

	wake_up_interruptible(&priv->adapter->cmd_wait_q);

	kthread_stop(priv->main_thread.task);

691 692 693 694
#ifdef CONFIG_DEBUG_FS
	btmrvl_debugfs_remove(hdev);
#endif

695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
	hci_unregister_dev(hdev);

	hci_free_dev(hdev);

	priv->btmrvl_dev.hcidev = NULL;

	btmrvl_free_adapter(priv);

	kfree(priv);

	return 0;
}
EXPORT_SYMBOL_GPL(btmrvl_remove_card);

MODULE_AUTHOR("Marvell International Ltd.");
710
MODULE_DESCRIPTION("Marvell Bluetooth driver ver " VERSION);
711 712
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");