drivers: misc: ti-st: apply wl12xx patch from TI
Rakesh Goyal [Wed, 25 Jan 2012 12:15:12 +0000 (17:15 +0530)]
patch is for following feature
1) use set_power() defined in platform file to
switch on/off BT.
2) send_ll_cmd  according to state

Reviewed-on: http://git-master/r/77318

Change-Id: I48ccb310ee4ce97c82835ef5701673c6f40231d4
Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/78018
Reviewed-by: Automatic_Commit_Validation_User

drivers/misc/ti-st/st_core.c
drivers/misc/ti-st/st_kim.c
drivers/misc/ti-st/st_ll.c
include/linux/ti_wilink_st.h

index ba168a7..c035902 100644 (file)
@@ -338,15 +338,31 @@ void st_int_recv(void *disc_data,
                        /* Unknow packet? */
                default:
                        type = *ptr;
-                       if (st_gdata->list[type] == NULL) {
-                               pr_err("chip/interface misbehavior dropping"
-                                       " frame starting with 0x%02x", type);
-                               goto done;
 
+                       /* Default case means non-HCILL packets,
+                        * possibilities are packets for:
+                        * (a) valid protocol -  Supported Protocols within
+                        *     the ST_MAX_CHANNELS.
+                        * (b) registered protocol - Checked by
+                        *     "st_gdata->list[type] == NULL)" are supported
+                        *     protocols only.
+                        *  Rules out any invalid protocol and
+                        *  unregistered protocols with channel ID < 16.
+                        */
+
+                       if ((type >= ST_MAX_CHANNELS) ||
+                                       (st_gdata->list[type] == NULL)) {
+                               pr_err("chip/interface misbehavior "
+                                               "dropping frame starting "
+                                               "with 0x%02x", type);
+                               goto done;
                        }
                        st_gdata->rx_skb = alloc_skb(
                                        st_gdata->list[type]->max_frame_size,
                                        GFP_ATOMIC);
+                       if (!st_gdata->rx_skb)
+                               goto done;
+
                        skb_reserve(st_gdata->rx_skb,
                                        st_gdata->list[type]->reserve);
                        /* next 2 required for BT only */
index 3a35805..901f4c4 100644 (file)
@@ -450,8 +450,8 @@ long st_kim_start(void *kim_data)
 
        do {
                /* platform specific enabling code here */
-               if (pdata->chip_enable)
-                       pdata->chip_enable(kim_gdata);
+               /*if (pdata->chip_enable)
+                       pdata->chip_enable();*/
 
                /* Configure BT nShutdown to HIGH state */
                gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
@@ -546,8 +546,8 @@ long st_kim_stop(void *kim_data)
        gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
 
        /* platform specific disable */
-       if (pdata->chip_disable)
-               pdata->chip_disable(kim_gdata);
+       /*if (pdata->chip_disable)
+               pdata->chip_disable();*/
        return err;
 }
 
@@ -683,6 +683,9 @@ static int kim_probe(struct platform_device *pdev)
        struct kim_data_s       *kim_gdata;
        struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
 
+       if (pdata->set_power)
+               pdata->set_power(1);
+
        if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
                /* multiple devices could exist */
                st_kim_devices[pdev->id] = pdev;
@@ -714,6 +717,8 @@ static int kim_probe(struct platform_device *pdev)
                return status;
        }
 
+       tegra_gpio_enable(kim_gdata->nshutdown);
+
        /* Configure nShutdown GPIO as output=0 */
        status = gpio_direction_output(kim_gdata->nshutdown, 0);
        if (unlikely(status)) {
@@ -776,15 +781,24 @@ static int kim_remove(struct platform_device *pdev)
 
        kfree(kim_gdata);
        kim_gdata = NULL;
+
+       if (pdata->set_power)
+               pdata->set_power(0);
+
        return 0;
 }
 
 int kim_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
+       int ret;
 
-       if (pdata->suspend)
-               return pdata->suspend(pdev, state);
+       if (pdata->suspend) {
+               ret = pdata->suspend(pdev, state);
+               if (pdata->set_power)
+                       pdata->set_power(0);
+               return ret;
+       }
 
        return -EOPNOTSUPP;
 }
@@ -793,8 +807,11 @@ int kim_resume(struct platform_device *pdev)
 {
        struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
 
-       if (pdata->resume)
+       if (pdata->resume) {
+               if (pdata->set_power)
+                       pdata->set_power(1);
                return pdata->resume(pdev);
+       }
 
        return -EOPNOTSUPP;
 }
index 1ff460a..c2908e0 100644 (file)
@@ -54,33 +54,40 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
        /* communicate to platform about chip asleep */
        kim_data = st_data->kim_data;
        pdata = kim_data->kim_pdev->dev.platform_data;
-       if (pdata->chip_asleep)
-               pdata->chip_asleep(NULL);
+       /*if (pdata->chip_asleep)
+               pdata->chip_asleep();*/
 }
 
 static void ll_device_want_to_wakeup(struct st_data_s *st_data)
 {
-       struct kim_data_s       *kim_data;
-       struct ti_st_plat_data  *pdata;
+       struct kim_data_s       *kim_data = st_data->kim_data;
+       struct ti_st_plat_data  *pdata = kim_data->kim_pdev->dev.platform_data;
 
        /* diff actions in diff states */
        switch (st_data->ll_state) {
        case ST_LL_ASLEEP:
+               /* communicate to platform about chip wakeup */
+               /*if (pdata->chip_awake)
+                       pdata->chip_awake();*/
+
                send_ll_cmd(st_data, LL_WAKE_UP_ACK);   /* send wake_ack */
                break;
        case ST_LL_ASLEEP_TO_AWAKE:
                /* duplicate wake_ind */
-               pr_err("duplicate wake_ind while waiting for Wake ack");
+               pr_debug("duplicate wake_ind while waiting for Wake ack");
+               send_ll_cmd(st_data, LL_WAKE_UP_ACK);   /* send wake_ack */
                break;
        case ST_LL_AWAKE:
                /* duplicate wake_ind */
-               pr_err("duplicate wake_ind already AWAKE");
+               pr_debug("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 */
                pr_err("duplicate wake_ind");
                break;
        }
+
        /* update state */
        st_data->ll_state = ST_LL_AWAKE;
 
@@ -98,6 +105,12 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
  * enable ST LL */
 void st_ll_enable(struct st_data_s *ll)
 {
+       struct kim_data_s      *kim_data = ll->kim_data;
+       struct ti_st_plat_data *pdata = kim_data->kim_pdev->dev.platform_data;
+       /* communicate to platform about chip enable */
+       /*if (pdata->chip_enable)
+               pdata->chip_enable();*/
+
        ll->ll_state = ST_LL_AWAKE;
 }
 
@@ -105,13 +118,26 @@ void st_ll_enable(struct st_data_s *ll)
  * disable ST LL */
 void st_ll_disable(struct st_data_s *ll)
 {
+       struct kim_data_s      *kim_data = ll->kim_data;
+       struct ti_st_plat_data *pdata = kim_data->kim_pdev->dev.platform_data;
+       /* communicate to platform about chip disable */
+       /*if (pdata->chip_disable)
+               pdata->chip_disable();*/
+
        ll->ll_state = ST_LL_INVALID;
 }
 
 /* called when ST Core wants to update the state */
 void st_ll_wakeup(struct st_data_s *ll)
 {
+       struct kim_data_s       *kim_data = ll->kim_data;
+       struct ti_st_plat_data  *pdata = kim_data->kim_pdev->dev.platform_data;
+
        if (likely(ll->ll_state != ST_LL_AWAKE)) {
+               /* communicate to platform about chip wakeup */
+               /*if (pdata->chip_awake)
+                       pdata->chip_awake();*/
+
                send_ll_cmd(ll, LL_WAKE_UP_IND);        /* WAKE_IND */
                ll->ll_state = ST_LL_ASLEEP_TO_AWAKE;
        } else {
index 2ef4385..27eca07 100644 (file)
@@ -443,6 +443,7 @@ struct ti_st_plat_data {
        int (*chip_disable) (struct kim_data_s *);
        int (*chip_asleep) (struct kim_data_s *);
        int (*chip_awake) (struct kim_data_s *);
+       int (*set_power)(int);
 };
 
 #endif /* TI_WILINK_ST_H */