summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/baseband-xmm-power2.c
diff options
context:
space:
mode:
authorMichael Hsu <mhsu@nvidia.com>2011-10-14 17:26:07 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:52:39 -0800
commit645f91c68b19172da28779e86c2d60045fc64705 (patch)
treebc570f012238e1578d528f004048a477ad361a92 /arch/arm/mach-tegra/baseband-xmm-power2.c
parent7a6f2363adc93e15bc2b1f96a3b4db9d75a43552 (diff)
arm: tegra: comms: GPIO changes for XMM modem ver 1130 or later
XMM modem version 1130 (or later) changes the GPIO power up sequence. Add module variable to support pre-1130 and post-1130 modem versions. BUG 828389 Reviewed-on: http://git-master/r/58240 (cherry picked from commit 0639c200face90d6dd0144acc7362c02909fa66c) Change-Id: If3a3486741d72d1251deeca3759af6b39c2031f1 Reviewed-on: http://git-master/r/62750 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: Rf848b30671a8739c11a376011165db6165f0a259
Diffstat (limited to 'arch/arm/mach-tegra/baseband-xmm-power2.c')
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power2.c540
1 files changed, 444 insertions, 96 deletions
diff --git a/arch/arm/mach-tegra/baseband-xmm-power2.c b/arch/arm/mach-tegra/baseband-xmm-power2.c
index 9601ed49e6a1..acb2ac344266 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power2.c
+++ b/arch/arm/mach-tegra/baseband-xmm-power2.c
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
@@ -32,15 +33,24 @@
MODULE_LICENSE("GPL");
-static struct baseband_power_platform_data *baseband_power2_driver_data;
+static unsigned long XYZ = 500 * 1000000 + 30 * 1000 + 50;
+
+module_param(modem_ver, ulong, 0644);
+MODULE_PARM_DESC(modem_ver,
+ "baseband xmm power2 - modem software version");
+module_param(modem_flash, ulong, 0644);
+MODULE_PARM_DESC(modem_flash,
+ "baseband xmm power2 - modem flash (1 = flash, 0 = flashless)");
+module_param(modem_pm, ulong, 0644);
+MODULE_PARM_DESC(modem_pm,
+ "baseband xmm power2 - modem power management (1 = pm, 0 = no pm)");
+module_param(XYZ, ulong, 0644);
+MODULE_PARM_DESC(XYZ,
+ "baseband xmm power2 - timing parameters X/Y/Z delay in ms");
-static enum {
- IPC_HSIC_SUS_REQ_UNINIT,
- IPC_HSIC_SUS_REQ_IRQ_READY,
- IPC_HSIC_SUS_REQ_INIT,
- IPC_HSIC_SUS_REQ_L,
- IPC_HSIC_SUS_REQ_H,
-} ipc_hsic_sus_req_state;
+static struct baseband_power_platform_data *baseband_power2_driver_data;
+static struct workqueue_struct *workqueue;
+static struct baseband_xmm_power_work_t *baseband_xmm_power2_work;
static enum {
IPC_AP_WAKE_UNINIT,
@@ -51,11 +61,8 @@ static enum {
IPC_AP_WAKE_H,
} ipc_ap_wake_state;
-static struct workqueue_struct *workqueue;
-static struct work_struct init1_work;
-static struct work_struct init2_work;
-
-static irqreturn_t ipc_hsic_sus_req_irq(int irq, void *dev_id)
+static irqreturn_t baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
+ (int irq, void *dev_id)
{
int value;
@@ -65,25 +72,65 @@ static irqreturn_t ipc_hsic_sus_req_irq(int irq, void *dev_id)
if (!baseband_power2_driver_data)
return IRQ_HANDLED;
- /* IPC_HSIC_SUS_REQ state machine */
- if (ipc_hsic_sus_req_state < IPC_HSIC_SUS_REQ_IRQ_READY) {
+ /* IPC_AP_WAKE state machine */
+ if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
pr_err("%s - spurious irq\n", __func__);
+ } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
+ value = gpio_get_value(baseband_power2_driver_data->
+ modem.xmm.ipc_ap_wake);
+ if (!value) {
+ pr_debug("%s - IPC_AP_WAKE_INIT1"
+ " - got falling edge\n",
+ __func__);
+ /* go to IPC_AP_WAKE_INIT1 state */
+ ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
+ /* queue work */
+ baseband_xmm_power2_work->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1;
+ queue_work(workqueue, (struct work_struct *)
+ baseband_xmm_power2_work);
+ } else {
+ pr_debug("%s - IPC_AP_WAKE_INIT1"
+ " - wait for falling edge\n",
+ __func__);
+ }
+ } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
+ value = gpio_get_value(baseband_power2_driver_data->
+ modem.xmm.ipc_ap_wake);
+ if (!value) {
+ pr_debug("%s - IPC_AP_WAKE_INIT2"
+ " - wait for rising edge\n",
+ __func__);
+ } else {
+ pr_debug("%s - IPC_AP_WAKE_INIT2"
+ " - got rising edge\n",
+ __func__);
+ /* go to IPC_AP_WAKE_INIT2 state */
+ ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
+ /* queue work */
+ baseband_xmm_power2_work->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2;
+ queue_work(workqueue, (struct work_struct *)
+ baseband_xmm_power2_work);
+ }
} else {
value = gpio_get_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_sus_req);
+ modem.xmm.ipc_ap_wake);
if (!value) {
pr_debug("%s - falling\n", __func__);
- ipc_hsic_sus_req_state = IPC_HSIC_SUS_REQ_L;
+ ipc_ap_wake_state = IPC_AP_WAKE_L;
} else {
pr_debug("%s - rising\n", __func__);
- ipc_hsic_sus_req_state = IPC_HSIC_SUS_REQ_H;
+ ipc_ap_wake_state = IPC_AP_WAKE_H;
}
+ return baseband_xmm_power_ipc_ap_wake_irq(irq, dev_id);
}
return IRQ_HANDLED;
}
-static irqreturn_t ipc_ap_wake_irq(int irq, void *dev_id)
+static irqreturn_t baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2
+ (int irq, void *dev_id)
{
int value;
@@ -100,29 +147,20 @@ static irqreturn_t ipc_ap_wake_irq(int irq, void *dev_id)
value = gpio_get_value(baseband_power2_driver_data->
modem.xmm.ipc_ap_wake);
if (!value) {
- pr_debug("%s - IPC_AP_WAKE_INIT1 - got falling edge\n",
- __func__);
- /* go to IPC_AP_WAKE_INIT1 state */
- ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
- /* queue work */
- queue_work(workqueue, &init1_work);
- } else {
- pr_debug("%s - IPC_AP_WAKE_INIT1 - wait for falling edge\n",
- __func__);
- }
- } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
- value = gpio_get_value(baseband_power2_driver_data->
- modem.xmm.ipc_ap_wake);
- if (!value) {
- pr_debug("%s - IPC_AP_WAKE_INIT2 - wait for rising edge\n",
- __func__);
- } else {
- pr_debug("%s - IPC_AP_WAKE_INIT2 - got rising edge\n",
+ pr_debug("%s - IPC_AP_WAKE_INIT1"
+ " - got falling edge\n",
__func__);
/* go to IPC_AP_WAKE_INIT2 state */
ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
/* queue work */
- queue_work(workqueue, &init2_work);
+ baseband_xmm_power2_work->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2;
+ queue_work(workqueue, (struct work_struct *)
+ baseband_xmm_power2_work);
+ } else {
+ pr_debug("%s - IPC_AP_WAKE_INIT1"
+ " - wait for falling edge\n",
+ __func__);
}
} else {
value = gpio_get_value(baseband_power2_driver_data->
@@ -134,12 +172,14 @@ static irqreturn_t ipc_ap_wake_irq(int irq, void *dev_id)
pr_debug("%s - rising\n", __func__);
ipc_ap_wake_state = IPC_AP_WAKE_H;
}
+ return baseband_xmm_power_ipc_ap_wake_irq(irq, dev_id);
}
return IRQ_HANDLED;
}
-static void baseband_xmm_power2_init1_work(struct work_struct *work)
+static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step1
+ (struct work_struct *work)
{
int value;
@@ -167,7 +207,8 @@ static void baseband_xmm_power2_init1_work(struct work_struct *work)
pr_debug("%s }\n", __func__);
}
-static void baseband_xmm_power2_init2_work(struct work_struct *work)
+static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step2
+ (struct work_struct *work)
{
int value;
@@ -194,8 +235,8 @@ static void baseband_xmm_power2_init2_work(struct work_struct *work)
struct file *filp;
oldfs = get_fs();
set_fs(KERNEL_DS);
- filp = filp_open("/sys/devices/platform/tegra-ehci.1/ehci_power", O_RDWR, 0);
- if (!filp) {
+ filp = filp_open(TEGRA_EHCI_DEVICE, O_RDWR, 0);
+ if (IS_ERR(filp) || (filp == NULL)) {
pr_err("open ehci_power failed\n");
} else {
filp->f_op->write(filp, "1", 1, &filp->f_pos);
@@ -225,69 +266,381 @@ static void baseband_xmm_power2_init2_work(struct work_struct *work)
pr_debug("%s }\n", __func__);
}
+static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step1
+ (struct work_struct *work)
+{
+ int X = XYZ / 1000000;
+ int Y = XYZ / 1000 - X * 1000;
+ int Z = XYZ % 1000;
+
+ pr_info("%s {\n", __func__);
+
+ pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
+
+ /* check for platform data */
+ if (!baseband_power2_driver_data)
+ return;
+
+ /* turn off usb host controller */
+ {
+ mm_segment_t oldfs;
+ struct file *filp;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open(TEGRA_EHCI_DEVICE, O_RDWR, 0);
+ if (IS_ERR(filp) || (filp == NULL)) {
+ pr_err("open ehci_power failed\n");
+ } else {
+ filp->f_op->write(filp, "0", 1, &filp->f_pos);
+ filp_close(filp, NULL);
+ }
+ set_fs(oldfs);
+ }
+
+ /* wait X ms */
+ mdelay(X);
+
+ /* set IPC_HSIC_ACTIVE low */
+ gpio_set_value(baseband_power2_driver_data->
+ modem.xmm.ipc_hsic_active, 0);
+
+ pr_info("%s }\n", __func__);
+}
+
+static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step2
+ (struct work_struct *work)
+{
+ int X = XYZ / 1000000;
+ int Y = XYZ / 1000 - X * 1000;
+ int Z = XYZ % 1000;
+
+ pr_info("%s {\n", __func__);
+
+ pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
+
+ /* check for platform data */
+ if (!baseband_power2_driver_data)
+ return;
+
+ /* wait Y ms */
+ mdelay(Y);
+
+ /* turn on usb host controller */
+ {
+ mm_segment_t oldfs;
+ struct file *filp;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open(TEGRA_EHCI_DEVICE, O_RDWR, 0);
+ if (IS_ERR(filp) || (filp == NULL)) {
+ pr_err("open ehci_power failed\n");
+ } else {
+ filp->f_op->write(filp, "1", 1, &filp->f_pos);
+ filp_close(filp, NULL);
+ }
+ set_fs(oldfs);
+ }
+
+ /* wait Z ms */
+ mdelay(Z);
+
+ /* set IPC_HSIC_ACTIVE high */
+ gpio_set_value(baseband_power2_driver_data->
+ modem.xmm.ipc_hsic_active, 1);
+
+ /* queue work function to check if enumeration succeeded */
+ baseband_xmm_power2_work->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3;
+ queue_work(workqueue, (struct work_struct *)
+ baseband_xmm_power2_work);
+
+ pr_info("%s }\n", __func__);
+}
+
+static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step3
+ (struct work_struct *work)
+{
+ int X = XYZ / 1000000;
+ int Y = XYZ / 1000 - X * 1000;
+ int Z = XYZ % 1000;
+ int enum_success = 0;
+
+ pr_info("%s {\n", __func__);
+
+ pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
+
+ /* check for platform data */
+ if (!baseband_power2_driver_data)
+ return;
+
+ /* wait 500 ms */
+ mdelay(500);
+
+ /* check if enumeration succeeded */
+ {
+ mm_segment_t oldfs;
+ struct file *filp;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open("/sys/bus/usb/devices/usb2/2-1/manufacturer",
+ O_RDONLY, 0);
+ if (IS_ERR(filp) || (filp == NULL)) {
+ pr_err("open /sys/bus/usb/devices"
+ "/usb2/2-1/manufacturer failed %ld\n",
+ PTR_ERR(filp));
+ } else {
+ filp_close(filp, NULL);
+ enum_success = 1;
+ }
+ set_fs(oldfs);
+ }
+
+ /* if enumeration failed, attempt recovery pulse */
+ if (!enum_success) {
+ pr_info("attempting recovery pulse...\n");
+ /* wait 20 ms */
+ mdelay(20);
+ /* set IPC_HSIC_ACTIVE low */
+ gpio_set_value(baseband_power2_driver_data->
+ modem.xmm.ipc_hsic_active, 0);
+ /* wait 20 ms */
+ mdelay(20);
+ /* set IPC_HSIC_ACTIVE high */
+ gpio_set_value(baseband_power2_driver_data->
+ modem.xmm.ipc_hsic_active, 1);
+ /* check if recovery pulse worked */
+ baseband_xmm_power2_work->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4;
+ queue_work(workqueue, (struct work_struct *)
+ baseband_xmm_power2_work);
+ }
+
+ pr_info("%s }\n", __func__);
+}
+
+static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step4
+ (struct work_struct *work)
+{
+ int X = XYZ / 1000000;
+ int Y = XYZ / 1000 - X * 1000;
+ int Z = XYZ % 1000;
+ int enum_success = 0;
+
+ pr_info("%s {\n", __func__);
+
+ pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
+
+ /* check for platform data */
+ if (!baseband_power2_driver_data)
+ return;
+
+ /* wait 500 ms */
+ mdelay(500);
+
+ /* check if enumeration succeeded */
+ {
+ mm_segment_t oldfs;
+ struct file *filp;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open("/sys/bus/usb/devices/usb2/2-1/manufacturer",
+ O_RDONLY, 0);
+ if (IS_ERR(filp) || (filp == NULL)) {
+ pr_err("open /sys/bus/usb/devices"
+ "/usb2/2-1/manufacturer failed %ld\n",
+ PTR_ERR(filp));
+ } else {
+ filp_close(filp, NULL);
+ enum_success = 1;
+ }
+ set_fs(oldfs);
+ }
+
+ /* if recovery pulse did not fix enumeration, retry from beginning */
+ if (!enum_success) {
+ static int retry = 3;
+ if (!retry) {
+ pr_info("failed to enumerate modem software"
+ " - too many retry attempts\n");
+ } else {
+ pr_info("recovery pulse failed to fix modem"
+ " enumeration..."
+ " restarting from beginning"
+ " - attempt #%d\n",
+ retry);
+ --retry;
+ ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
+ baseband_xmm_power2_work->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
+ queue_work(workqueue, (struct work_struct *)
+ baseband_xmm_power2_work);
+ }
+ }
+
+ pr_info("%s }\n", __func__);
+}
+
+static int free_ipc_ap_wake_irq;
+
+static void baseband_xmm_power2_work_func(struct work_struct *work)
+{
+ struct baseband_xmm_power_work_t *bbxmm_work
+ = (struct baseband_xmm_power_work_t *) work;
+ int err;
+
+ pr_debug("%s\n", __func__);
+
+ switch (bbxmm_work->state) {
+ case BBXMM_WORK_UNINIT:
+ pr_debug("BBXMM_WORK_UNINIT\n");
+ /* free baseband irq(s) */
+ if (free_ipc_ap_wake_irq) {
+ free_irq(gpio_to_irq(baseband_power2_driver_data
+ ->modem.xmm.ipc_ap_wake), NULL);
+ free_ipc_ap_wake_irq = 0;
+ }
+ break;
+ case BBXMM_WORK_INIT:
+ pr_debug("BBXMM_WORK_INIT\n");
+ /* request baseband irq(s) */
+ ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
+ err = request_irq(gpio_to_irq(baseband_power2_driver_data
+ ->modem.xmm.ipc_ap_wake),
+ (modem_ver < XMM_MODEM_VER_1130)
+ ? baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
+ : baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "BBXMM_POWER2_IPC_AP_WAKE_IRQ",
+ NULL);
+ if (err < 0) {
+ pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
+ __func__);
+ return;
+ }
+ free_ipc_ap_wake_irq = 1;
+ ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
+ /* go to next state */
+ bbxmm_work->state = (modem_flash && !modem_pm)
+ ? BBXMM_WORK_INIT_FLASH_STEP1
+ : (modem_flash && modem_pm)
+ ? BBXMM_WORK_INIT_FLASH_PM_STEP1
+ : (!modem_flash && modem_pm)
+ ? BBXMM_WORK_INIT_FLASHLESS_PM_STEP1
+ : BBXMM_WORK_UNINIT;
+ queue_work(workqueue, work);
+ break;
+ case BBXMM_WORK_INIT_FLASH_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
+ break;
+ case BBXMM_WORK_INIT_FLASH_PM_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
+ /* go to next state */
+ bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
+ ? BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1
+ : BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1;
+ queue_work(workqueue, work);
+ break;
+ case BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1\n");
+ break;
+ case BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1\n");
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
+ /* go to next state */
+ bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
+ ? BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ
+ : BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
+ queue_work(workqueue, work);
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ"
+ " - waiting for IPC_AP_WAKE_IRQ to trigger step1\n");
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
+ baseband_xmm_power2_flashless_pm_ver_lt_1130_step1(work);
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2\n");
+ baseband_xmm_power2_flashless_pm_ver_lt_1130_step2(work);
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
+ baseband_xmm_power2_flashless_pm_ver_ge_1130_step1(work);
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2\n");
+ baseband_xmm_power2_flashless_pm_ver_ge_1130_step2(work);
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3\n");
+ baseband_xmm_power2_flashless_pm_ver_ge_1130_step3(work);
+ break;
+ case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4\n");
+ baseband_xmm_power2_flashless_pm_ver_ge_1130_step4(work);
+ break;
+ }
+
+}
+
static int baseband_xmm_power2_driver_probe(struct platform_device *device)
{
struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *) device->dev.platform_data;
- int err;
+ = (struct baseband_power_platform_data *)
+ device->dev.platform_data;
pr_debug("%s\n", __func__);
/* save platform data */
baseband_power2_driver_data = data;
- /* request baseband irq(s) */
- ipc_hsic_sus_req_state = IPC_HSIC_SUS_REQ_UNINIT;
- err = request_irq(gpio_to_irq(data->modem.xmm.ipc_hsic_sus_req),
- ipc_hsic_sus_req_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "IPC_HSIC_SUS_REQ_IRQ",
- NULL);
- if (err < 0) {
- pr_err("%s - request irq IPC_HSIC_SUS_REQ_IRQ failed\n",
- __func__);
- return err;
- }
- ipc_hsic_sus_req_state = IPC_HSIC_SUS_REQ_IRQ_READY;
- ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
- err = request_irq(gpio_to_irq(data->modem.xmm.ipc_ap_wake),
- ipc_ap_wake_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "IPC_AP_WAKE_IRQ",
- NULL);
- if (err < 0) {
- pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
- __func__);
- return err;
- }
- ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
-
/* init work queue */
workqueue = create_singlethread_workqueue
- ("baseband_power_workqueue");
+ ("baseband_xmm_power2_workqueue");
if (!workqueue) {
pr_err("cannot create workqueue\n");
return -1;
}
- INIT_WORK(&init1_work, baseband_xmm_power2_init1_work);
- INIT_WORK(&init2_work, baseband_xmm_power2_init2_work);
+ baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *)
+ kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
+ if (!baseband_xmm_power2_work) {
+ pr_err("cannot allocate baseband_xmm_power2_work\n");
+ return -1;
+ }
+ INIT_WORK((struct work_struct *) baseband_xmm_power2_work,
+ baseband_xmm_power2_work_func);
+ baseband_xmm_power2_work->state = BBXMM_WORK_INIT;
+ queue_work(workqueue,
+ (struct work_struct *) baseband_xmm_power2_work);
return 0;
}
static int baseband_xmm_power2_driver_remove(struct platform_device *device)
{
+ struct baseband_power_platform_data *data
+ = (struct baseband_power_platform_data *)
+ device->dev.platform_data;
+
pr_debug("%s\n", __func__);
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!data)
return 0;
- /* free baseband irq(s) */
- free_irq(gpio_to_irq(baseband_power2_driver_data
- ->modem.xmm.ipc_ap_wake), NULL);
- free_irq(gpio_to_irq(baseband_power2_driver_data
- ->modem.xmm.ipc_hsic_sus_req), NULL);
+ /* free irq */
+ if (free_ipc_ap_wake_irq) {
+ free_irq(gpio_to_irq(data->modem.xmm.ipc_ap_wake), NULL);
+ free_ipc_ap_wake_irq = 0;
+ }
+
+ /* free work structure */
+ destroy_workqueue(workqueue);
+ kfree(baseband_xmm_power2_work);
+ baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *) 0;
return 0;
}
@@ -296,35 +649,31 @@ static int baseband_xmm_power2_driver_remove(struct platform_device *device)
static int baseband_xmm_power2_driver_suspend(struct platform_device *device,
pm_message_t state)
{
- pr_debug("%s\n", __func__);
+ struct baseband_power_platform_data *data
+ = (struct baseband_power_platform_data *)
+ device->dev.platform_data;
+
+ pr_debug("%s - nop\n", __func__);
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!data)
return 0;
- /* signal bb to suspend hsic */
- gpio_set_value(baseband_power2_driver_data
- ->modem.xmm.ipc_hsic_active, 0);
-
return 0;
}
static int baseband_xmm_power2_driver_resume(struct platform_device *device)
{
- pr_debug("%s\n", __func__);
+ struct baseband_power_platform_data *data
+ = (struct baseband_power_platform_data *)
+ device->dev.platform_data;
+
+ pr_debug("%s - nop\n", __func__);
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!data)
return 0;
- /* wake bb */
- gpio_set_value(baseband_power2_driver_data
- ->modem.xmm.ipc_bb_wake, 1);
-
- /* signal bb to resume hsic */
- gpio_set_value(baseband_power2_driver_data
- ->modem.xmm.ipc_hsic_active, 1);
-
return 0;
}
#endif
@@ -355,4 +704,3 @@ static void __exit baseband_xmm_power2_exit(void)
module_init(baseband_xmm_power2_init)
module_exit(baseband_xmm_power2_exit)
-