bluetooth: add tiwl1283 btwilink driver + updated TI ST
authorFabien Peix <fabienx.peix@intel.com>
Mon, 21 Nov 2011 16:15:35 +0000 (17:15 +0100)
committerbuildbot <buildbot@intel.com>
Wed, 30 Nov 2011 13:57:04 +0000 (05:57 -0800)
BZ: 15234

Merged from GB R2 K2.6.35 to Kernel 3.0.8
This is the btwilink driver along an updated version of
shared transport.

Change-Id: I3e099edd3865250b122867cea4c6dbfef4528b76
Signed-off-by: Fabien Peix <fabienx.peix@intel.com>
Reviewed-on: http://android.intel.com:8080/25350
Reviewed-by: Champciaux, NicolasX <nicolasx.champciaux@intel.com>
Tested-by: Champciaux, NicolasX <nicolasx.champciaux@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/configs/i386_mfld_defconfig
arch/x86/platform/mrst/mrst.c
drivers/bluetooth/btwilink.c
drivers/misc/Kconfig
drivers/misc/ti-st/Kconfig
drivers/misc/ti-st/st_core.c
drivers/misc/ti-st/st_kim.c
drivers/misc/ti-st/st_ll.c
drivers/misc/ti-st/sysfs-uim [new file with mode: 0644]
include/linux/ti_wilink_st.h

index 70d811e..13c7622 100644 (file)
@@ -642,7 +642,31 @@ CONFIG_XPS=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIUART_ATH3K is not set
+# CONFIG_BT_HCIUART_LL is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+CONFIG_BT_WILINK=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=m
@@ -667,7 +691,7 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
 # CONFIG_MAC80211_DEBUG_MENU is not set
 # CONFIG_WIMAX is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=m
+CONFIG_RFKILL_PM=y
 # CONFIG_RFKILL_INPUT is not set
 # CONFIG_RFKILL_REGULATOR is not set
 # CONFIG_NET_9P is not set
@@ -741,6 +765,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_VMWARE_BALLOON is not set
 # CONFIG_BMP085 is not set
 # CONFIG_PCH_PHUB is not set
+# CONFIG_WL127X_RFKILL is not set
 # CONFIG_APANIC is not set
 CONFIG_A1026=y
 # CONFIG_C2PORT is not set
@@ -759,7 +784,7 @@ CONFIG_A1026=y
 #
 # Texas Instruments shared transport line discipline
 #
-# CONFIG_TI_ST is not set
+CONFIG_TI_ST=m
 # CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_SENSORS_LIS3_I2C is not set
 CONFIG_HAVE_IDE=y
index d58e7c4..bda8157 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/power/max17042_battery.h>
 #include <linux/power/intel_mdf_battery.h>
 #include <linux/nfc/pn544.h>
+#include <linux/skbuff.h>
+#include <linux/ti_wilink_st.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
@@ -2073,6 +2075,97 @@ static struct platform_device pb_device = {
        },
 };
 
+#if defined(CONFIG_TI_ST) || defined(CONFIG_TI_ST_MODULE)
+
+/* KIM related */
+static int mrst_kim_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       return 0;
+}
+static int mrst_kim_resume(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct ti_st_plat_data kim_pdata = {
+       .nshutdown_gpio = -1,/* BT, FM, GPS gpios */
+       .flow_cntrl     = 1,            /* flow control flag */
+       .suspend        = mrst_kim_suspend,
+       .resume         = mrst_kim_resume,
+};
+
+static struct platform_device linux_kim_device = {
+       .name           = "kim", /* named after init manager for ST */
+       .id             = -1,
+       .dev.platform_data = &kim_pdata,
+};
+
+/* BT WILINK related */
+static int mrst_bt_enable(struct platform_device *pdev)
+{
+       return 0;
+}
+static int mrst_bt_disable(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct ti_st_plat_data bt_pdata = {
+       .chip_enable    = mrst_bt_enable,
+       .chip_disable   = mrst_bt_disable,
+};
+
+static struct platform_device linux_bt_device = {
+       .name           = "btwilink", /* named after init manager for ST */
+       .id             = -1,
+       .dev.platform_data = &bt_pdata,
+};
+static int __init bluetooth_init(void)
+{
+       unsigned int UART_index;
+       long unsigned int UART_baud_rate;
+       int error_reg;
+
+       /* KIM INIT */
+       /* Get the GPIO number from the SFI table
+          if FM gpio is not provided then BT-reset line is
+          also used to enable FM
+       */
+       kim_pdata.nshutdown_gpio = get_gpio_by_name("BT-reset");
+       if (kim_pdata.nshutdown_gpio == -1)
+               return -ENODEV;
+
+       /* Get Share Transport uart settings */
+       /* TODO : add SFI table parsing and one SFI entry for this settings */
+       UART_index = 0;
+       UART_baud_rate = 3500000;
+
+       /* Share Transport uart settings */
+       sprintf((char *)kim_pdata.dev_name, "/dev/ttyMFD%u", UART_index);
+       kim_pdata.baud_rate = UART_baud_rate;
+
+       pr_info("%s: Setting platform_data with UART device name:%s and "
+                       "UART baud rate:%lu.\n",
+                       __func__, kim_pdata.dev_name, kim_pdata.baud_rate);
+
+       error_reg = platform_device_register(&linux_kim_device);
+       if (error_reg < 0) {
+               pr_err("platform_device_register for kim failed\n");
+               goto exit_on_error;
+       }
+
+       /* BT WILINK INIT */
+       error_reg = platform_device_register(&linux_bt_device);
+       if (error_reg < 0)
+               pr_err("platform_device_register for btwilink failed\n");
+exit_on_error:
+       return error_reg;
+
+}
+device_initcall(bluetooth_init);
+
+#endif
+
 /*
  * Shrink the non-existent buttons, register the gpio button
  * device if there is some
index 65d27af..5b269b6 100644 (file)
@@ -22,7 +22,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
-#define DEBUG
+
 #include <linux/platform_device.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index b918309..9cb2d0c 100644 (file)
@@ -63,7 +63,7 @@ config AD525X_DPOT_SPI
 
 config ANDROID_PMEM
        bool "Android pmem allocator"
-       default y
+       default n
 
 config ATMEL_PWM
        tristate "Atmel AT32/AT91 PWM support"
index abb5de1..0835bbc 100644 (file)
@@ -13,5 +13,4 @@ config TI_ST
          to register themselves with core and send data, the responses
          are returned to relevant protocol drivers based on their
          packet types.
-
 endmenu
index 54c91ff..051c806 100644 (file)
 #include <linux/skbuff.h>
 
 #include <linux/ti_wilink_st.h>
+#include <linux/pm_runtime.h>
+
+#ifndef DEBUG
+#ifdef pr_info
+#undef pr_info
+#define pr_info(fmt, arg...)
+#endif
+#endif
 
 /* function pointer pointing to either,
  * st_kim_recv during registration to receive fw download responses
@@ -145,7 +153,7 @@ void st_reg_complete(struct st_data_s *st_gdata, char err)
        for (i = 0; i < ST_MAX_CHANNELS; i++) {
                if (likely(st_gdata != NULL &&
                        st_gdata->is_registered[i] == true &&
-                               st_gdata->list[i]->reg_complete_cb != NULL)) {
+                          st_gdata->list[i]->reg_complete_cb != NULL)) {
                        st_gdata->list[i]->reg_complete_cb
                                (st_gdata->list[i]->priv_data, err);
                        pr_info("protocol %d's cb sent %d\n", i, err);
@@ -317,8 +325,16 @@ void st_int_recv(void *disc_data,
                         * and assume chip awake
                         */
                        spin_unlock_irqrestore(&st_gdata->lock, flags);
-                       if (st_ll_getstate(st_gdata) == ST_LL_AWAKE)
+                       if (st_ll_getstate(st_gdata) == ST_LL_AWAKE) {
+                               /* pm_runtime_get has already been done
+                                * in st_ll_sleep_state. st_wakeup_ack will
+                                * call st_ll_sleep_state again and another
+                                * pm_runtime_get will be done. We need to
+                                * compensate the first one here.
+                                */
+                               pm_runtime_put(st_gdata->tty_dev);
                                st_wakeup_ack(st_gdata, LL_WAKE_UP_ACK);
+                       }
                        spin_lock_irqsave(&st_gdata->lock, flags);
 
                        ptr++;
@@ -338,11 +354,26 @@ void st_int_recv(void *disc_data,
                        /* Unknow packet? */
                default:
                        type = *ptr;
+                       if (type < ST_MAX_CHANNELS) {
+                               if (!st_gdata->list[type]) {
+                                       pr_err("dropping frame "
+                                       "starting with 0x%02x\n", type);
+                                       goto done;
+                               }
+                       } else {
+                               pr_err("Invalid packet type : 0x%02x\n", type);
+                               goto done;
+                       }
                        st_gdata->rx_skb = alloc_skb(
                                        st_gdata->list[type]->max_frame_size,
                                        GFP_ATOMIC);
-                       skb_reserve(st_gdata->rx_skb,
+                       if (st_gdata->rx_skb) {
+                               skb_reserve(st_gdata->rx_skb,
                                        st_gdata->list[type]->reserve);
+                       } else {
+                               pr_err("alloc_skb error\n");
+                               goto done;
+                       }
                        /* next 2 required for BT only */
                        st_gdata->rx_skb->cb[0] = type; /*pkt_type*/
                        st_gdata->rx_skb->cb[1] = 0; /*incoming*/
@@ -354,6 +385,7 @@ void st_int_recv(void *disc_data,
                ptr++;
                count--;
        }
+done:
        spin_unlock_irqrestore(&st_gdata->lock, flags);
        pr_debug("done %s", __func__);
        return;
@@ -478,9 +510,9 @@ void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf)
 {
        seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n",
                        st_gdata->protos_registered,
-                       st_gdata->is_registered[0x04] == true ? 'R' : 'U',
-                       st_gdata->is_registered[0x08] == true ? 'R' : 'U',
-                       st_gdata->is_registered[0x09] == true ? 'R' : 'U');
+                       st_gdata->is_registered[ST_BT] == true ? 'R' : 'U',
+                       st_gdata->is_registered[ST_FM] == true ? 'R' : 'U',
+                       st_gdata->is_registered[ST_GPS] == true ? 'R' : 'U');
 }
 
 /********************************************************************/
@@ -605,7 +637,7 @@ long st_unregister(struct st_proto_s *proto)
        pr_debug("%s: %d ", __func__, proto->chnl_id);
 
        st_kim_ref(&st_gdata, 0);
-       if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) {
+       if (proto->chnl_id >= ST_MAX_CHANNELS) {
                pr_err(" chnl_id %d not supported", proto->chnl_id);
                return -EPROTONOSUPPORT;
        }
@@ -655,7 +687,6 @@ long st_write(struct sk_buff *skb)
                pr_err("data/tty unavailable to perform write");
                return -EINVAL;
        }
-
        pr_debug("%d to be written", skb->len);
        len = skb->len;
 
@@ -685,6 +716,16 @@ static int st_tty_open(struct tty_struct *tty)
        st_gdata->tty = tty;
        tty->disc_data = st_gdata;
 
+       if (tty->dev->parent)
+               st_gdata->tty_dev = tty->dev->parent;
+       else
+               return -EINVAL;
+
+       /* Asynchronous Get is enough here since we just want to avoid
+        * interface to be released too early
+        */
+       pm_runtime_get(st_gdata->tty_dev);
+
        /* don't do an wakeup for now */
        clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 
@@ -717,7 +758,7 @@ static void st_tty_close(struct tty_struct *tty)
         */
        spin_lock_irqsave(&st_gdata->lock, flags);
        for (i = ST_BT; i < ST_MAX_CHANNELS; i++) {
-               if (st_gdata->list[i] != NULL)
+               if (st_gdata->is_registered[i] == true)
                        pr_err("%d not un-registered", i);
                st_gdata->list[i] = NULL;
        }
@@ -744,6 +785,8 @@ static void st_tty_close(struct tty_struct *tty)
        st_gdata->rx_skb = NULL;
        spin_unlock_irqrestore(&st_gdata->lock, flags);
 
+       pm_runtime_put(st_gdata->tty_dev);
+
        pr_debug("%s: done ", __func__);
 }
 
@@ -868,5 +911,3 @@ void st_core_exit(struct st_data_s *st_gdata)
                kfree(st_gdata);
        }
 }
-
-
index 38fd2f0..2ba9653 100644 (file)
 #include <linux/seq_file.h>
 #include <linux/sched.h>
 #include <linux/sysfs.h>
+#include <linux/rfkill.h>
 #include <linux/tty.h>
 
-#include <linux/skbuff.h>
+/* understand BT events for fw response */
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/hci.h>
+
 #include <linux/ti_wilink_st.h>
 
+#ifndef DEBUG
+#ifdef pr_info
+#undef pr_info
+#define pr_info(fmt, arg...)
+#endif
+#endif
 
 #define MAX_ST_DEVICES 3       /* Imagine 1 on each UART for now */
 static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
@@ -163,10 +174,11 @@ void kim_int_recv(struct kim_data_s *kim_gdata,
                }               /* end of if rx_state */
                switch (*ptr) {
                        /* Bluetooth event packet? */
-               case 0x04:
+               case HCI_EVENT_PKT:
+                       pr_debug("Event packet");
                        kim_gdata->rx_state = ST_W4_HEADER;
-                       kim_gdata->rx_count = 2;
-                       type = *ptr;
+                       kim_gdata->rx_count = HCI_EVENT_HDR_SIZE;
+                       type = HCI_EVENT_PKT;
                        break;
                default:
                        pr_info("unknown packet");
@@ -177,7 +189,7 @@ void kim_int_recv(struct kim_data_s *kim_gdata,
                ptr++;
                count--;
                kim_gdata->rx_skb =
-                       alloc_skb(1024+8, GFP_ATOMIC);
+                   alloc_skb(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
                if (!kim_gdata->rx_skb) {
                        pr_err("can't allocate mem for new packet");
                        kim_gdata->rx_state = ST_W4_PACKET_TYPE;
@@ -189,6 +201,7 @@ void kim_int_recv(struct kim_data_s *kim_gdata,
                kim_gdata->rx_skb->cb[1] = 0;
 
        }
+       pr_debug("done %s", __func__);
        return;
 }
 
@@ -268,7 +281,10 @@ static long download_firmware(struct kim_data_s *kim_gdata)
        int wr_room_space;
        int cmd_size;
        unsigned long timeout;
+       struct st_data_s *core_data;
+       core_data = kim_gdata->core_data;
 
+       pr_err("download_firmware start");
        err = read_local_version(kim_gdata, bts_scr_name);
        if (err != 0) {
                pr_err("kim: failed to read local ver");
@@ -309,6 +325,12 @@ static long download_firmware(struct kim_data_s *kim_gdata)
                                skip_change_remote_baud(&ptr, &len);
                                break;
                        }
+                       /*Enable the ST_LL state machine if HCILL SLEEP command
+                        * enabled in BT init script*/
+                       if (unlikely
+                          (((struct hci_command *)action_ptr)->opcode ==
+                            HCILL_SLEEP_MODE_OPCODE))
+                               st_ll_enable(core_data);
                        /*
                         * Make sure we have enough free space in uart
                         * tx buffer to write current firmware command
@@ -386,6 +408,14 @@ static long download_firmware(struct kim_data_s *kim_gdata)
        }
        /* fw download complete */
        release_firmware(kim_gdata->fw_entry);
+       pr_err("download_firmware complete");
+
+
+       /* If the firmware wasn't parsed completely, warn user about remaining
+        * commands in firmware, so that the firmware can be relooked at
+        */
+       if (len != 0)
+               pr_err("%s:incomplete, script not parsed completely", __func__);
        return 0;
 }
 
@@ -401,6 +431,7 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count)
        struct st_data_s        *st_gdata = (struct st_data_s *)disc_data;
        struct kim_data_s       *kim_gdata = st_gdata->kim_data;
 
+       pr_debug(" %s ", __func__);
        /* copy to local buffer */
        if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
                /* must be the read_ver_cmd */
@@ -421,6 +452,7 @@ void st_kim_complete(void *kim_data)
 {
        struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
        complete(&kim_gdata->ldisc_installed);
+       pr_info("%s", __func__);
 }
 
 /**
@@ -440,6 +472,7 @@ long st_kim_start(void *kim_data)
 
        do {
                /* Configure BT nShutdown to HIGH state */
+               pr_err("Access to gpio %d", kim_gdata->nshutdown);
                gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
                mdelay(5);      /* FIXME: a proper toggle */
                gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
@@ -460,7 +493,15 @@ long st_kim_start(void *kim_data)
                        pr_info("ldisc_install = 0");
                        sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
                                        NULL, "install");
-                       err = -ETIMEDOUT;
+
+                       /* wait for uart close */
+                       err = wait_for_completion_timeout(
+                                       &kim_gdata->ldisc_installed,
+                                       msecs_to_jiffies(1000));
+                       if (!err) {             /* timeout */
+                               pr_err("uart close  timeout");
+                               err = -ETIMEDOUT;
+                       }
                        continue;
                } else {
                        /* ldisc installed now */
@@ -472,6 +513,15 @@ long st_kim_start(void *kim_data)
                                pr_info("ldisc_install = 0");
                                sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
                                                NULL, "install");
+
+                               /* wait for ldisc to be un-installed */
+                               err = wait_for_completion_timeout(
+                                               &kim_gdata->ldisc_installed,
+                                               msecs_to_jiffies(1000));
+                               if (!err) {             /* timeout */
+                                       pr_err("uninstall ldisc timeout");
+                                       err = -ETIMEDOUT;
+                               }
                                continue;
                        } else {        /* on success don't retry */
                                break;
@@ -490,6 +540,7 @@ long st_kim_stop(void *kim_data)
        long err = 0;
        struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
 
+       pr_info("%s", __func__);
        INIT_COMPLETION(kim_gdata->ldisc_installed);
 
        /* Flush any pending characters in the driver and discipline. */
@@ -604,10 +655,6 @@ void st_kim_ref(struct st_data_s **core_data, int id)
        struct kim_data_s       *kim_gdata;
        /* get kim_gdata reference from platform device */
        pdev = st_get_plat_device(id);
-       if (!pdev) {
-               *core_data = NULL;
-               return;
-       }
        kim_gdata = dev_get_drvdata(&pdev->dev);
        *core_data = kim_gdata->core_data;
 }
@@ -654,7 +701,7 @@ static int kim_probe(struct platform_device *pdev)
                /* multiple devices could exist */
                st_kim_devices[pdev->id] = pdev;
        } else {
-               /* platform's sure about existence of 1 device */
+               /* platform's sure about existance of 1 device */
                st_kim_devices[0] = pdev;
        }
 
index 3f24951..eceaee9 100644 (file)
@@ -1,8 +1,7 @@
 /*
  *  Shared Transport driver
  *     HCI-LL module responsible for TI proprietary HCI_LL protocol
- *  Copyright (C) 2009-2010 Texas Instruments
- *  Author: Pavan Savoy <pavan_savoy@ti.com>
+ *  Copyright (C) 2009 Texas Instruments
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
  *
  */
 
+
 #define pr_fmt(fmt) "(stll) :" fmt
 #include <linux/skbuff.h>
 #include <linux/module.h>
 #include <linux/ti_wilink_st.h>
 
+#include <linux/pm_runtime.h>
+
+#ifndef DEBUG
+#ifdef pr_info
+#undef pr_info
+#define pr_info(fmt, arg...)
+#endif
+#endif
+
 /**********************************************************************/
 /* internal functions */
 static void send_ll_cmd(struct st_data_s *st_data,
@@ -39,10 +48,15 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
 {
        pr_debug("%s", __func__);
        /* sanity check */
-       if (st_data->ll_state != ST_LL_AWAKE)
-               pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND"
+       if (st_data->ll_state != ST_LL_AWAKE) {
+               pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND "
                          "in state %ld", st_data->ll_state);
 
+               /* Since Driver is asked to go to sleep but not aware to be
+               * awake Runtime PM is not aware of the state change either
+               * Requesting the device has not been done, so we do it*/
+               pm_runtime_get(st_data->tty_dev);
+       }
        send_ll_cmd(st_data, LL_SLEEP_ACK);
        /* update state */
        st_data->ll_state = ST_LL_ASLEEP;
@@ -62,6 +76,7 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
        case ST_LL_AWAKE:
                /* duplicate wake_ind */
                pr_err("duplicate wake_ind already AWAKE");
+               send_ll_cmd(st_data, LL_WAKE_UP_ACK);   /* send wake_ack */
                break;
        case ST_LL_AWAKE_TO_ASLEEP:
                /* duplicate wake_ind */
@@ -116,16 +131,23 @@ unsigned long st_ll_sleep_state(struct st_data_s *st_data,
        case LL_SLEEP_IND:      /* sleep ind */
                pr_debug("sleep indication recvd");
                ll_device_want_to_sleep(st_data);
+               pm_runtime_put(st_data->tty_dev);
                break;
        case LL_SLEEP_ACK:      /* sleep ack */
                pr_err("sleep ack rcvd: host shouldn't");
                break;
        case LL_WAKE_UP_IND:    /* wake ind */
                pr_debug("wake indication recvd");
+               /* Getting the Device is done to avoid power gating the
+               * Interface (for example UART). This can be done
+               * asynchronously since low level driver is getting the device
+               * when doing a transfert */
+               pm_runtime_get(st_data->tty_dev);
                ll_device_want_to_wakeup(st_data);
                break;
        case LL_WAKE_UP_ACK:    /* wake ack */
                pr_debug("wake ack rcvd");
+               pm_runtime_get(st_data->tty_dev);
                st_data->ll_state = ST_LL_AWAKE;
                break;
        default:
diff --git a/drivers/misc/ti-st/sysfs-uim b/drivers/misc/ti-st/sysfs-uim
new file mode 100644 (file)
index 0000000..626bda5
--- /dev/null
@@ -0,0 +1,28 @@
+What:           /sys/class/rfkill/rfkill%d/
+Date:           March 22
+Contact:        Pavan Savoy <pavan_savoy@ti.com>
+Description:
+               Creates the rfkill entries for Radio apps like
+               BT app, FM app or GPS app to toggle corresponding
+               cores of the chip
+
+What:           /dev/rfkill
+Date:           March 22
+Contact:        Pavan Savoy <pavan_savoy@ti.com>
+Description:
+               A daemon which maintains the ldisc installation and
+               uninstallation would be ppolling on this device and listening
+               on events which would suggest either to install or un-install
+               line discipline
+
+What:           /sys/kernel/debug/ti-st/version
+Contact:        Pavan Savoy <pavan_savoy@ti.com>
+Description:
+               WiLink chip's ROM version exposed to user-space for some
+               proprietary protocol stacks to make use of.
+
+What:           /sys/kernel/debug/ti-st/protocols
+Contact:        Pavan Savoy <pavan_savoy@ti.com>
+Description:
+               The reason for chip being ON, the list of protocols registered.
+
index b004e55..9887d67 100644 (file)
@@ -156,6 +156,7 @@ struct st_data_s {
        unsigned long ll_state;
        void *kim_data;
        struct tty_struct *tty;
+       struct device *tty_dev;
 };
 
 /*
@@ -203,8 +204,8 @@ void gps_chrdrv_stub_init(void);
 /* time in msec to wait for
  * line discipline to be installed
  */
-#define LDISC_TIME     1000
-#define CMD_RESP_TIME  800
+#define LDISC_TIME     5000 /*1000*/
+#define CMD_RESP_TIME  4000 /*800*/
 #define CMD_WR_TIME    5000
 #define MAKEWORD(a, b)  ((unsigned short)(((unsigned char)(a)) \
        | ((unsigned short)((unsigned char)(b))) << 8))
@@ -371,6 +372,7 @@ struct hci_command {
 #define LL_WAKE_UP_IND 0x32
 #define LL_WAKE_UP_ACK 0x33
 
+#define HCILL_SLEEP_MODE_OPCODE 0xFD0C
 /* initialize and de-init ST LL */
 long st_ll_init(struct st_data_s *);
 long st_ll_deinit(struct st_data_s *);
@@ -418,6 +420,8 @@ struct ti_st_plat_data {
        unsigned long baud_rate;
        int (*suspend)(struct platform_device *, pm_message_t);
        int (*resume)(struct platform_device *);
+       int (*chip_enable) (struct kim_data_s *kim_data);
+       int (*chip_disable) (struct kim_data_s *kim_data);
 };
 
 #endif /* TI_WILINK_ST_H */