aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/bluesleep.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/bluetooth/bluesleep.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/bluetooth/bluesleep.c')
-rw-r--r--drivers/bluetooth/bluesleep.c864
1 files changed, 864 insertions, 0 deletions
diff --git a/drivers/bluetooth/bluesleep.c b/drivers/bluetooth/bluesleep.c
new file mode 100644
index 00000000000..0e2ec0befbe
--- /dev/null
+++ b/drivers/bluetooth/bluesleep.c
@@ -0,0 +1,864 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * You should have received a copy of the GNU General Public License
7 * along with this program; if not, write to the Free Software
8 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * Copyright (C) 2006-2007 - Motorola
16 * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
17 *
18 * Date Author Comment
19 * ----------- -------------- --------------------------------
20 * 2006-Apr-28 Motorola The kernel module for running the Bluetooth(R)
21 * Sleep-Mode Protocol from the Host side
22 * 2006-Sep-08 Motorola Added workqueue for handling sleep work.
23 * 2007-Jan-24 Motorola Added mbm_handle_ioi() call to ISR.
24 * 2009-Aug-10 Motorola Changed "add_timer" to "mod_timer" to solve
25 * race when flurry of queued work comes in.
26*/
27
28#include <linux/module.h> /* kernel module definitions */
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/interrupt.h>
32#include <linux/kernel.h>
33#include <linux/notifier.h>
34#include <linux/proc_fs.h>
35#include <linux/spinlock.h>
36#include <linux/timer.h>
37#include <linux/uaccess.h>
38#include <linux/version.h>
39#include <linux/workqueue.h>
40#include <linux/platform_device.h>
41
42#include <linux/irq.h>
43#include <linux/ioport.h>
44#include <linux/param.h>
45#include <linux/bitops.h>
46#include <linux/termios.h>
47#include <linux/wakelock.h>
48#include <mach/gpio.h>
49#include <linux/serial_core.h>
50#include <linux/tegra_uart.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h> /* event notifications */
54#include "hci_uart.h"
55
56#define BT_SLEEP_DBG
57#ifndef BT_SLEEP_DBG
58#define BT_DBG(fmt, arg...)
59#endif
60/*
61 * Defines
62 */
63
64#define VERSION "1.1"
65#define PROC_DIR "bluetooth/sleep"
66
67#define POLARITY_LOW 0
68#define POLARITY_HIGH 1
69
70/* enable/disable wake-on-bluetooth */
71#define BT_ENABLE_IRQ_WAKE 1
72
73struct bluesleep_info {
74 unsigned host_wake;
75 unsigned ext_wake;
76 unsigned host_wake_irq;
77 struct uart_port *uport;
78 struct wake_lock wake_lock;
79 int irq_polarity;
80 int has_ext_wake;
81};
82
83/* work function */
84static void bluesleep_sleep_work(struct work_struct *work);
85
86/* work queue */
87DECLARE_DELAYED_WORK(sleep_workqueue, bluesleep_sleep_work);
88
89/* Macros for handling sleep work */
90#define bluesleep_rx_busy() schedule_delayed_work(&sleep_workqueue, 0)
91#define bluesleep_tx_busy() schedule_delayed_work(&sleep_workqueue, 0)
92#define bluesleep_rx_idle() schedule_delayed_work(&sleep_workqueue, 0)
93#define bluesleep_tx_idle() schedule_delayed_work(&sleep_workqueue, 0)
94
95/* 10 second timeout */
96#define TX_TIMER_INTERVAL 10
97
98/* state variable names and bit positions */
99#define BT_PROTO 0x01
100#define BT_TXDATA 0x02
101#define BT_ASLEEP 0x04
102#define BT_EXT_WAKE 0x08
103#define BT_SUSPEND 0x10
104
105/* global pointer to a single hci device. */
106static struct hci_dev *bluesleep_hdev;
107
108static struct bluesleep_info *bsi;
109
110/* module usage */
111static atomic_t open_count = ATOMIC_INIT(1);
112
113/*
114 * Local function prototypes
115 */
116static int bluesleep_hci_event(struct notifier_block *this,
117 unsigned long event, void *data);
118static int bluesleep_start(void);
119static void bluesleep_stop(void);
120
121/*
122 * Global variables
123 */
124/** Global state flags */
125static unsigned long flags;
126
127/** Tasklet to respond to change in hostwake line */
128static struct tasklet_struct hostwake_task;
129
130/** Transmission timer */
131static void bluesleep_tx_timer_expire(unsigned long data);
132static DEFINE_TIMER(tx_timer, bluesleep_tx_timer_expire, 0, 0);
133
134/** Lock for state transitions */
135static spinlock_t rw_lock;
136
137/** Notifier block for HCI events */
138struct notifier_block hci_event_nblock = {
139 .notifier_call = bluesleep_hci_event,
140};
141
142struct proc_dir_entry *bluetooth_dir, *sleep_dir;
143
144/*
145 * Local functions
146 */
147static void hsuart_power(int on)
148{
149 if (test_bit(BT_SUSPEND, &flags))
150 return;
151 if (on) {
152 tegra_uart_request_clock_on(bsi->uport);
153 tegra_uart_set_mctrl(bsi->uport, TIOCM_RTS);
154 } else {
155 tegra_uart_set_mctrl(bsi->uport, 0);
156 tegra_uart_request_clock_off(bsi->uport);
157 }
158}
159
160/**
161 * @return 1 if the Host can go to sleep, 0 otherwise.
162 */
163int bluesleep_can_sleep(void)
164{
165 /* check if WAKE_BT_GPIO and BT_WAKE_GPIO are both deasserted */
166 return ((gpio_get_value(bsi->host_wake) != bsi->irq_polarity) &&
167 (!test_bit(BT_EXT_WAKE, &flags)) &&
168 (bsi->uport != NULL));
169}
170
171void bluesleep_sleep_wakeup(void)
172{
173 if (test_bit(BT_ASLEEP, &flags)) {
174 BT_DBG("waking up...");
175 wake_lock(&bsi->wake_lock);
176 /* Start the timer */
177 mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ));
178 if (bsi->has_ext_wake == 1)
179 gpio_set_value(bsi->ext_wake, 1);
180 set_bit(BT_EXT_WAKE, &flags);
181 clear_bit(BT_ASLEEP, &flags);
182 /*Activating UART */
183 }
184}
185
186/**
187 * @brief@ main sleep work handling function which update the flags
188 * and activate and deactivate UART ,check FIFO.
189 */
190static void bluesleep_sleep_work(struct work_struct *work)
191{
192 if (bluesleep_can_sleep()) {
193 /* already asleep, this is an error case */
194 if (test_bit(BT_ASLEEP, &flags)) {
195 BT_DBG("already asleep");
196 return;
197 }
198
199 if (tegra_uart_is_tx_empty(bsi->uport)) {
200 BT_DBG("going to sleep...");
201 set_bit(BT_ASLEEP, &flags);
202 /*Deactivating UART */
203 /* UART clk is not turned off immediately. Release
204 * wakelock after 500 ms.
205 */
206 wake_lock_timeout(&bsi->wake_lock, HZ / 2);
207 } else {
208 mod_timer(&tx_timer, jiffies + TX_TIMER_INTERVAL * HZ);
209 return;
210 }
211 } else if (!test_bit(BT_EXT_WAKE, &flags)
212 && !test_bit(BT_ASLEEP, &flags)) {
213 mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ));
214 if (bsi->has_ext_wake == 1)
215 gpio_set_value(bsi->ext_wake, 1);
216 set_bit(BT_EXT_WAKE, &flags);
217 } else {
218 bluesleep_sleep_wakeup();
219 }
220}
221
222/**
223 * A tasklet function that runs in tasklet context and reads the value
224 * of the HOST_WAKE GPIO pin and further defer the work.
225 * @param data Not used.
226 */
227static void bluesleep_hostwake_task(unsigned long data)
228{
229 BT_DBG("hostwake line change");
230
231 spin_lock(&rw_lock);
232 if ((gpio_get_value(bsi->host_wake) == bsi->irq_polarity))
233 bluesleep_rx_busy();
234 else
235 bluesleep_rx_idle();
236 spin_unlock(&rw_lock);
237
238}
239
240/**
241 * Handles proper timer action when outgoing data is delivered to the
242 * HCI line discipline. Sets BT_TXDATA.
243 */
244static void bluesleep_outgoing_data(void)
245{
246 unsigned long irq_flags;
247
248 spin_lock_irqsave(&rw_lock, irq_flags);
249 /* log data passing by */
250 set_bit(BT_TXDATA, &flags);
251 /* if the tx side is sleeping... */
252 if (!test_bit(BT_EXT_WAKE, &flags)) {
253 BT_DBG("tx was sleeping");
254 bluesleep_sleep_wakeup();
255 }
256 spin_unlock_irqrestore(&rw_lock, irq_flags);
257}
258
259/**
260 * Handles HCI device events.
261 * @param this Not used.
262 * @param event The event that occurred.
263 * @param data The HCI device associated with the event.
264 * @return <code>NOTIFY_DONE</code>.
265 */
266static int bluesleep_hci_event(struct notifier_block *this,
267 unsigned long event, void *data)
268{
269 struct hci_dev *hdev = (struct hci_dev *) data;
270 struct hci_uart *hu;
271 struct uart_state *state;
272
273 if (!hdev)
274 return NOTIFY_DONE;
275
276 switch (event) {
277 case HCI_DEV_REG:
278 if (!bluesleep_hdev) {
279 bluesleep_hdev = hdev;
280 hu = (struct hci_uart *) hdev->driver_data;
281 state = (struct uart_state *) hu->tty->driver_data;
282 bsi->uport = state->uart_port;
283 /* if bluetooth started, start bluesleep*/
284 bluesleep_start();
285 }
286 break;
287 case HCI_DEV_UNREG:
288 bluesleep_stop();
289 bluesleep_hdev = NULL;
290 bsi->uport = NULL;
291 /* if bluetooth stopped, stop bluesleep also */
292 break;
293 case HCI_DEV_WRITE:
294 bluesleep_outgoing_data();
295 break;
296 }
297
298 return NOTIFY_DONE;
299}
300
301/**
302 * Handles transmission timer expiration.
303 * @param data Not used.
304 */
305static void bluesleep_tx_timer_expire(unsigned long data)
306{
307 unsigned long irq_flags;
308
309 BT_DBG("Tx timer expired");
310
311 spin_lock_irqsave(&rw_lock, irq_flags);
312
313 /* were we silent during the last timeout? */
314 if (!test_bit(BT_TXDATA, &flags)) {
315 BT_DBG("Tx has been idle");
316 if (bsi->has_ext_wake == 1)
317 gpio_set_value(bsi->ext_wake, 0);
318 clear_bit(BT_EXT_WAKE, &flags);
319 bluesleep_tx_idle();
320 } else {
321 BT_DBG("Tx data during last period");
322 mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL*HZ));
323 }
324
325 /* clear the incoming data flag */
326 clear_bit(BT_TXDATA, &flags);
327
328 spin_unlock_irqrestore(&rw_lock, irq_flags);
329}
330
331/**
332 * Schedules a tasklet to run when receiving an interrupt on the
333 * <code>HOST_WAKE</code> GPIO pin.
334 * @param irq Not used.
335 * @param dev_id Not used.
336 */
337static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
338{
339 /* schedule a tasklet to handle the change in the host wake line */
340 tasklet_schedule(&hostwake_task);
341 return IRQ_HANDLED;
342}
343
344/**
345 * Starts the Sleep-Mode Protocol on the Host.
346 * @return On success, 0. On error, -1, and <code>errno</code> is set
347 * appropriately.
348 */
349static int bluesleep_start(void)
350{
351 int retval;
352 unsigned long irq_flags;
353
354 spin_lock_irqsave(&rw_lock, irq_flags);
355 if (test_bit(BT_PROTO, &flags)) {
356 spin_unlock_irqrestore(&rw_lock, irq_flags);
357 return 0;
358 }
359 spin_unlock_irqrestore(&rw_lock, irq_flags);
360
361 if (!atomic_dec_and_test(&open_count)) {
362 atomic_inc(&open_count);
363 return -EBUSY;
364 }
365
366 /* start the timer */
367 mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ));
368
369 /* assert BT_WAKE */
370 if (bsi->has_ext_wake == 1)
371 gpio_set_value(bsi->ext_wake, 1);
372 set_bit(BT_EXT_WAKE, &flags);
373#if BT_ENABLE_IRQ_WAKE
374 retval = enable_irq_wake(bsi->host_wake_irq);
375 if (retval < 0) {
376 BT_ERR("Couldn't enable BT_HOST_WAKE as wakeup interrupt");
377 goto fail;
378 }
379#endif
380 set_bit(BT_PROTO, &flags);
381 wake_lock(&bsi->wake_lock);
382 return 0;
383fail:
384 del_timer(&tx_timer);
385 atomic_inc(&open_count);
386
387 return retval;
388}
389
390/**
391 * Stops the Sleep-Mode Protocol on the Host.
392 */
393static void bluesleep_stop(void)
394{
395 unsigned long irq_flags;
396
397 spin_lock_irqsave(&rw_lock, irq_flags);
398 if (!test_bit(BT_PROTO, &flags)) {
399 spin_unlock_irqrestore(&rw_lock, irq_flags);
400 return;
401 }
402 /* assert BT_WAKE */
403 if (bsi->has_ext_wake == 1)
404 gpio_set_value(bsi->ext_wake, 1);
405 set_bit(BT_EXT_WAKE, &flags);
406 del_timer(&tx_timer);
407 clear_bit(BT_PROTO, &flags);
408
409 if (test_bit(BT_ASLEEP, &flags)) {
410 clear_bit(BT_ASLEEP, &flags);
411 hsuart_power(1);
412 }
413
414 atomic_inc(&open_count);
415 spin_unlock_irqrestore(&rw_lock, irq_flags);
416
417#if BT_ENABLE_IRQ_WAKE
418 if (disable_irq_wake(bsi->host_wake_irq))
419 BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n");
420#endif
421 wake_lock_timeout(&bsi->wake_lock, HZ / 2);
422}
423/**
424 * Read the <code>BT_WAKE</code> GPIO pin value via the proc interface.
425 * When this function returns, <code>page</code> will contain a 1 if the
426 * pin is high, 0 otherwise.
427 * @param page Buffer for writing data.
428 * @param start Not used.
429 * @param offset Not used.
430 * @param count Not used.
431 * @param eof Whether or not there is more data to be read.
432 * @param data Not used.
433 * @return The number of bytes written.
434 */
435static int bluepower_read_proc_btwake(char *page, char **start, off_t offset,
436 int count, int *eof, void *data)
437{
438 *eof = 1;
439 return sprintf(page, "btwake:%u\n",test_bit(BT_EXT_WAKE, &flags));
440}
441
442/**
443 * Write the <code>BT_WAKE</code> GPIO pin value via the proc interface.
444 * @param file Not used.
445 * @param buffer The buffer to read from.
446 * @param count The number of bytes to be written.
447 * @param data Not used.
448 * @return On success, the number of bytes written. On error, -1, and
449 * <code>errno</code> is set appropriately.
450 */
451static int bluepower_write_proc_btwake(struct file *file, const char *buffer,
452 unsigned long count, void *data)
453{
454 char *buf;
455
456 if (count < 1)
457 return -EINVAL;
458
459 buf = kmalloc(count, GFP_KERNEL);
460 if (!buf)
461 return -ENOMEM;
462
463 if (copy_from_user(buf, buffer, count)) {
464 kfree(buf);
465 return -EFAULT;
466 }
467 if (buf[0] == '0') {
468 if (bsi->has_ext_wake == 1)
469 gpio_set_value(bsi->ext_wake, 0);
470 clear_bit(BT_EXT_WAKE, &flags);
471 } else if (buf[0] == '1') {
472 if (bsi->has_ext_wake == 1)
473 gpio_set_value(bsi->ext_wake, 1);
474 set_bit(BT_EXT_WAKE, &flags);
475 } else {
476 kfree(buf);
477 return -EINVAL;
478 }
479
480 kfree(buf);
481 return count;
482}
483
484/**
485 * Read the <code>BT_HOST_WAKE</code> GPIO pin value via the proc interface.
486 * When this function returns, <code>page</code> will contain a 1 if the pin
487 * is high, 0 otherwise.
488 * @param page Buffer for writing data.
489 * @param start Not used.
490 * @param offset Not used.
491 * @param count Not used.
492 * @param eof Whether or not there is more data to be read.
493 * @param data Not used.
494 * @return The number of bytes written.
495 */
496static int bluepower_read_proc_hostwake(char *page, char **start, off_t offset,
497 int count, int *eof, void *data)
498{
499 *eof = 1;
500 return sprintf(page, "hostwake: %u\n", gpio_get_value(bsi->host_wake));
501}
502
503
504/**
505 * Read the low-power status of the Host via the proc interface.
506 * When this function returns, <code>page</code> contains a 1 if the Host
507 * is asleep, 0 otherwise.
508 * @param page Buffer for writing data.
509 * @param start Not used.
510 * @param offset Not used.
511 * @param count Not used.
512 * @param eof Whether or not there is more data to be read.
513 * @param data Not used.
514 * @return The number of bytes written.
515 */
516static int bluesleep_read_proc_asleep(char *page, char **start, off_t offset,
517 int count, int *eof, void *data)
518{
519 unsigned int asleep;
520
521 asleep = test_bit(BT_ASLEEP, &flags) ? 1 : 0;
522 *eof = 1;
523 return sprintf(page, "asleep: %u\n", asleep);
524}
525
526/**
527 * Read the low-power protocol being used by the Host via the proc interface.
528 * When this function returns, <code>page</code> will contain a 1 if the Host
529 * is using the Sleep Mode Protocol, 0 otherwise.
530 * @param page Buffer for writing data.
531 * @param start Not used.
532 * @param offset Not used.
533 * @param count Not used.
534 * @param eof Whether or not there is more data to be read.
535 * @param data Not used.
536 * @return The number of bytes written.
537 */
538static int bluesleep_read_proc_proto(char *page, char **start, off_t offset,
539 int count, int *eof, void *data)
540{
541 unsigned int proto;
542
543 proto = test_bit(BT_PROTO, &flags) ? 1 : 0;
544 *eof = 1;
545 return sprintf(page, "proto: %u\n", proto);
546}
547
548/**
549 * Modify the low-power protocol used by the Host via the proc interface.
550 * @param file Not used.
551 * @param buffer The buffer to read from.
552 * @param count The number of bytes to be written.
553 * @param data Not used.
554 * @return On success, the number of bytes written. On error, -1, and
555 * <code>errno</code> is set appropriately.
556 */
557static int bluesleep_write_proc_proto(struct file *file, const char *buffer,
558 unsigned long count, void *data)
559{
560 char proto;
561
562 if (count < 1)
563 return -EINVAL;
564
565 if (copy_from_user(&proto, buffer, 1))
566 return -EFAULT;
567
568 if (proto == '0')
569 bluesleep_stop();
570 else
571 bluesleep_start();
572
573 /* claim that we wrote everything */
574 return count;
575}
576
577
578static int bluesleep_probe(struct platform_device *pdev)
579{
580 int ret;
581 struct resource *res;
582
583 bsi = kzalloc(sizeof(struct bluesleep_info), GFP_KERNEL);
584 if (!bsi)
585 return -ENOMEM;
586
587 res = platform_get_resource_byname(pdev, IORESOURCE_IO,
588 "gpio_host_wake");
589 if (!res) {
590 BT_ERR("couldn't find host_wake gpio\n");
591 ret = -ENODEV;
592 goto free_bsi;
593 }
594 bsi->host_wake = res->start;
595
596 ret = gpio_request(bsi->host_wake, "bt_host_wake");
597 if (ret)
598 goto free_bsi;
599
600 /* configure host_wake as input */
601 ret = gpio_direction_input(bsi->host_wake);
602 if (ret < 0) {
603 pr_err("gpio-keys: failed to configure input"
604 " direction for GPIO %d, error %d\n",
605 bsi->host_wake, ret);
606 gpio_free(bsi->host_wake);
607 goto free_bsi;
608 }
609
610 res = platform_get_resource_byname(pdev, IORESOURCE_IO,
611 "gpio_ext_wake");
612
613 if (!res)
614 bsi->has_ext_wake = 0;
615 else
616 bsi->has_ext_wake = 1;
617
618 if (bsi->has_ext_wake) {
619 bsi->ext_wake = res->start;
620 ret = gpio_request(bsi->ext_wake, "bt_ext_wake");
621 if (ret)
622 goto free_bt_host_wake;
623
624 /* configure ext_wake as output mode*/
625 ret = gpio_direction_output(bsi->ext_wake, 1);
626 if (ret < 0) {
627 pr_err("gpio-keys: failed to configure output"
628 " direction for GPIO %d, error %d\n",
629 bsi->ext_wake, ret);
630 gpio_free(bsi->ext_wake);
631 goto free_bt_host_wake;
632 }
633 } else
634 set_bit(BT_EXT_WAKE, &flags);
635
636 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
637 "host_wake");
638 if (!res) {
639 BT_ERR("couldn't find host_wake irq\n");
640 ret = -ENODEV;
641 goto free_bt_host_wake;
642 }
643 bsi->host_wake_irq = res->start;
644 if (bsi->host_wake_irq < 0) {
645 BT_ERR("couldn't find host_wake irq\n");
646 ret = -ENODEV;
647 goto free_bt_ext_wake;
648 }
649 if (res->flags & IORESOURCE_IRQ_LOWEDGE)
650 bsi->irq_polarity = POLARITY_LOW;/*low edge (falling edge)*/
651 else
652 bsi->irq_polarity = POLARITY_HIGH;/*anything else*/
653
654 wake_lock_init(&bsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep");
655 clear_bit(BT_SUSPEND, &flags);
656
657 if (bsi->irq_polarity == POLARITY_LOW) {
658 ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
659 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
660 "bluetooth hostwake", NULL);
661 } else {
662 ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
663 IRQF_DISABLED | IRQF_TRIGGER_RISING,
664 "bluetooth hostwake", NULL);
665 }
666 if (ret < 0) {
667 BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ");
668 goto free_bt_ext_wake;
669 }
670
671 return 0;
672
673free_bt_ext_wake:
674 gpio_free(bsi->ext_wake);
675free_bt_host_wake:
676 gpio_free(bsi->host_wake);
677free_bsi:
678 kfree(bsi);
679 return ret;
680}
681
682static int bluesleep_remove(struct platform_device *pdev)
683{
684 free_irq(bsi->host_wake_irq, NULL);
685 gpio_free(bsi->host_wake);
686 gpio_free(bsi->ext_wake);
687 wake_lock_destroy(&bsi->wake_lock);
688 kfree(bsi);
689 return 0;
690}
691
692
693static int bluesleep_resume(struct platform_device *pdev)
694{
695 if (test_bit(BT_SUSPEND, &flags)) {
696 BT_DBG("bluesleep resuming...\n");
697 if ((bsi->uport != NULL) &&
698 (gpio_get_value(bsi->host_wake) == bsi->irq_polarity)) {
699 BT_DBG("bluesleep resume form BT event...\n");
700 tegra_uart_request_clock_on(bsi->uport);
701 tegra_uart_set_mctrl(bsi->uport, TIOCM_RTS);
702 }
703 clear_bit(BT_SUSPEND, &flags);
704 }
705 return 0;
706}
707
708static int bluesleep_suspend(struct platform_device *pdev, pm_message_t state)
709{
710 BT_DBG("bluesleep suspending...\n");
711 set_bit(BT_SUSPEND, &flags);
712 return 0;
713}
714
715static struct platform_driver bluesleep_driver = {
716 .probe = bluesleep_probe,
717 .remove = bluesleep_remove,
718 .suspend = bluesleep_suspend,
719 .resume = bluesleep_resume,
720 .driver = {
721 .name = "bluesleep",
722 .owner = THIS_MODULE,
723 },
724};
725/**
726 * Initializes the module.
727 * @return On success, 0. On error, -1, and <code>errno</code> is set
728 * appropriately.
729 */
730static int __init bluesleep_init(void)
731{
732 int retval;
733 struct proc_dir_entry *ent;
734
735 BT_INFO("BlueSleep Mode Driver Ver %s", VERSION);
736
737 retval = platform_driver_register(&bluesleep_driver);
738 if (retval)
739 return retval;
740
741 if (bsi == NULL)
742 return 0;
743
744 bluesleep_hdev = NULL;
745
746 bluetooth_dir = proc_mkdir("bluetooth", NULL);
747 if (bluetooth_dir == NULL) {
748 BT_ERR("Unable to create /proc/bluetooth directory");
749 return -ENOMEM;
750 }
751
752 sleep_dir = proc_mkdir("sleep", bluetooth_dir);
753 if (sleep_dir == NULL) {
754 BT_ERR("Unable to create /proc/%s directory", PROC_DIR);
755 return -ENOMEM;
756 }
757
758 /* Creating read/write "btwake" entry */
759 ent = create_proc_entry("btwake", 0, sleep_dir);
760 if (ent == NULL) {
761 BT_ERR("Unable to create /proc/%s/btwake entry", PROC_DIR);
762 retval = -ENOMEM;
763 goto fail;
764 }
765 ent->read_proc = bluepower_read_proc_btwake;
766 ent->write_proc = bluepower_write_proc_btwake;
767
768 /* read only proc entries */
769 if (create_proc_read_entry("hostwake", 0, sleep_dir,
770 bluepower_read_proc_hostwake, NULL) == NULL) {
771 BT_ERR("Unable to create /proc/%s/hostwake entry", PROC_DIR);
772 retval = -ENOMEM;
773 goto fail;
774 }
775
776 /* read/write proc entries */
777 ent = create_proc_entry("proto", 0, sleep_dir);
778 if (ent == NULL) {
779 BT_ERR("Unable to create /proc/%s/proto entry", PROC_DIR);
780 retval = -ENOMEM;
781 goto fail;
782 }
783 ent->read_proc = bluesleep_read_proc_proto;
784 ent->write_proc = bluesleep_write_proc_proto;
785
786 /* read only proc entries */
787 if (create_proc_read_entry("asleep", 0,
788 sleep_dir, bluesleep_read_proc_asleep, NULL) == NULL) {
789 BT_ERR("Unable to create /proc/%s/asleep entry", PROC_DIR);
790 retval = -ENOMEM;
791 goto fail;
792 }
793
794 flags = 0; /* clear all status bits */
795
796 /* Initialize spinlock. */
797 spin_lock_init(&rw_lock);
798
799 /* Initialize timer */
800 init_timer(&tx_timer);
801 tx_timer.function = bluesleep_tx_timer_expire;
802 tx_timer.data = 0;
803
804 /* initialize host wake tasklet */
805 tasklet_init(&hostwake_task, bluesleep_hostwake_task, 0);
806
807 /* assert bt wake */
808 if (bsi->has_ext_wake == 1)
809 gpio_set_value(bsi->ext_wake, 1);
810 set_bit(BT_EXT_WAKE, &flags);
811 hci_register_notifier(&hci_event_nblock);
812
813 return 0;
814
815fail:
816 remove_proc_entry("asleep", sleep_dir);
817 remove_proc_entry("proto", sleep_dir);
818 remove_proc_entry("hostwake", sleep_dir);
819 remove_proc_entry("btwake", sleep_dir);
820 remove_proc_entry("sleep", bluetooth_dir);
821 remove_proc_entry("bluetooth", 0);
822 return retval;
823}
824
825/**
826 * Cleans up the module.
827 */
828static void __exit bluesleep_exit(void)
829{
830 if (bsi == NULL)
831 return;
832
833 /* assert bt wake */
834 if (bsi->has_ext_wake == 1)
835 gpio_set_value(bsi->ext_wake, 1);
836 set_bit(BT_EXT_WAKE, &flags);
837 if (test_bit(BT_PROTO, &flags)) {
838 if (disable_irq_wake(bsi->host_wake_irq))
839 BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n");
840 free_irq(bsi->host_wake_irq, NULL);
841 del_timer(&tx_timer);
842 if (test_bit(BT_ASLEEP, &flags))
843 hsuart_power(1);
844 }
845
846 hci_unregister_notifier(&hci_event_nblock);
847 platform_driver_unregister(&bluesleep_driver);
848
849 remove_proc_entry("asleep", sleep_dir);
850 remove_proc_entry("proto", sleep_dir);
851 remove_proc_entry("hostwake", sleep_dir);
852 remove_proc_entry("btwake", sleep_dir);
853 remove_proc_entry("sleep", bluetooth_dir);
854 remove_proc_entry("bluetooth", 0);
855}
856
857module_init(bluesleep_init);
858module_exit(bluesleep_exit);
859
860MODULE_DESCRIPTION("Bluetooth Sleep Mode Driver ver %s " VERSION);
861#ifdef MODULE_LICENSE
862MODULE_LICENSE("GPL");
863#endif
864