arm: tegra: xmm: baseband modem pm code cleanup
Vinayak Pane [Thu, 3 May 2012 01:22:12 +0000 (18:22 -0700)]
- Platform data is treated as const and not modified in driver.
- Driver specific data is stored and used from a new structure.
- Remove support for older firmware version of XMM modem (<1130).
- Shortening of names for compliance and to fit in 80 characters.
- Organize irq function to reduce indentation.

Change-Id: I269401aa0a2efc685d7a630b4952cb31cbca6a4f
Signed-off-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-on: http://git-master/r/101587
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Steve Lin <stlin@nvidia.com>

arch/arm/mach-tegra/baseband-xmm-power.c
arch/arm/mach-tegra/baseband-xmm-power.h
arch/arm/mach-tegra/baseband-xmm-power2.c

index 7659d4f..32d46d4 100644 (file)
@@ -89,12 +89,12 @@ static enum {
        IPC_AP_WAKE_H,
 } ipc_ap_wake_state;
 
-enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
+static enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
 static struct workqueue_struct *workqueue;
 static struct work_struct init1_work;
 static struct work_struct init2_work;
 static struct work_struct L2_resume_work;
-static struct baseband_power_platform_data *baseband_power_driver_data;
+static struct work_struct autopm_resume_work;
 static bool register_hsic_device;
 static struct wake_lock wakelock;
 static struct usb_device *usbdev;
@@ -102,7 +102,6 @@ static bool CP_initiated_L2toL0;
 static bool modem_power_on;
 static int power_onoff;
 static int reenable_autosuspend;
-static struct work_struct autopm_resume_work;
 static bool wakeup_pending;
 static bool modem_sleep_flag;
 static spinlock_t xmm_lock;
@@ -111,8 +110,14 @@ static bool system_suspending;
 static struct regulator *enterprise_hsic_reg;
 static bool _hsic_reg_status;
 
-static void baseband_xmm_power_L2_resume(void);
-static int baseband_xmm_power_driver_handle_resume(
+/* driver specific data - same structure is used for flashless
+ * & flashed modem drivers i.e. baseband-xmm-power2.c
+ */
+struct xmm_power_data xmm_power_drv_data;
+EXPORT_SYMBOL(xmm_power_drv_data);
+
+static void xmm_power_L2_resume(void);
+static int xmm_power_driver_handle_resume(
                        struct baseband_power_platform_data *data);
 
 static int tegra_baseband_rail_on(void)
@@ -175,8 +180,7 @@ static int tegra_baseband_rail_off(void)
 static int baseband_modem_power_on(struct baseband_power_platform_data *data)
 {
        /* set IPC_HSIC_ACTIVE active */
-       gpio_set_value(baseband_power_driver_data->
-               modem.xmm.ipc_hsic_active, 1);
+       gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
 
        /* reset / power on sequence */
        msleep(40);
@@ -189,18 +193,18 @@ static int baseband_modem_power_on(struct baseband_power_platform_data *data)
        return 0;
 }
 
-static int baseband_xmm_power_on(struct platform_device *device)
+static int xmm_power_on(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
+       struct baseband_power_platform_data *pdata =
                        device->dev.platform_data;
+       struct xmm_power_data *data = &xmm_power_drv_data;
        int ret;
 
        pr_debug("%s {\n", __func__);
 
        /* check for platform data */
-       if (!data) {
-               pr_err("%s: !data\n", __func__);
+       if (!pdata) {
+               pr_err("%s: !pdata\n", __func__);
                return -EINVAL;
        }
        if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
@@ -211,11 +215,7 @@ static int baseband_xmm_power_on(struct platform_device *device)
        /* reset the state machine */
        baseband_xmm_powerstate = BBXMM_PS_INIT;
        modem_sleep_flag = false;
-
-       if (modem_ver < XMM_MODEM_VER_1130)
-               ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
-       else
-               ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
+       ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
 
        pr_debug("%s wake_st(%d) modem version %lu\n", __func__,
                                ipc_ap_wake_state, modem_ver);
@@ -228,24 +228,22 @@ static int baseband_xmm_power_on(struct platform_device *device)
                        pr_debug("%s: register usb host controller\n",
                                __func__);
                        modem_power_on = true;
-                       if (data->hsic_register)
-                               data->modem.xmm.hsic_device =
-                                               data->hsic_register();
+                       if (pdata->hsic_register)
+                               data->hsic_device = pdata->hsic_register();
                        else
                                pr_err("%s: hsic_register is missing\n",
                                        __func__);
                        register_hsic_device = false;
                } else {
                        /* register usb host controller */
-                       if (data->hsic_register)
-                               data->modem.xmm.hsic_device =
-                                                       data->hsic_register();
+                       if (pdata->hsic_register)
+                               data->hsic_device = pdata->hsic_register();
                        /* turn on modem */
                        pr_debug("%s call baseband_modem_power_on\n", __func__);
-                       baseband_modem_power_on(data);
+                       baseband_modem_power_on(pdata);
                }
        }
-       ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+       ret = enable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
        if (ret < 0)
                pr_err("%s: enable_irq_wake error\n", __func__);
        pr_debug("%s }\n", __func__);
@@ -253,9 +251,12 @@ static int baseband_xmm_power_on(struct platform_device *device)
        return 0;
 }
 
-static int baseband_xmm_power_off(struct platform_device *device)
+static int xmm_power_off(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data;
+       struct baseband_power_platform_data *pdata =
+                       device->dev.platform_data;
+       struct xmm_power_data *data = &xmm_power_drv_data;
+
        int ret;
        unsigned long flags;
 
@@ -268,34 +269,31 @@ static int baseband_xmm_power_off(struct platform_device *device)
                pr_err("%s: !device\n", __func__);
                return -EINVAL;
        }
-       data = (struct baseband_power_platform_data *)
-               device->dev.platform_data;
-       if (!data) {
-               pr_err("%s: !data\n", __func__);
+       if (!pdata) {
+               pr_err("%s: !pdata\n", __func__);
                return -EINVAL;
        }
 
        ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
-       ret = disable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+       ret = disable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
        if (ret < 0)
                pr_err("%s: disable_irq_wake error\n", __func__);
 
        /* unregister usb host controller */
-       if (data->hsic_unregister)
-               data->hsic_unregister(data->modem.xmm.hsic_device);
+       if (pdata->hsic_unregister)
+               pdata->hsic_unregister(data->hsic_device);
        else
                pr_err("%s: hsic_unregister is missing\n", __func__);
 
 
        /* set IPC_HSIC_ACTIVE low */
-       gpio_set_value(baseband_power_driver_data->
-               modem.xmm.ipc_hsic_active, 0);
+       gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
 
        /* wait 20 ms */
        mdelay(20);
 
        /* drive bb_rst low */
-       gpio_set_value(data->modem.xmm.bb_rst, 0);
+       gpio_set_value(pdata->modem.xmm.bb_rst, 0);
        mdelay(1);
 
        baseband_xmm_powerstate = BBXMM_PS_UNINIT;
@@ -314,9 +312,8 @@ static int baseband_xmm_power_off(struct platform_device *device)
        return 0;
 }
 
-static ssize_t baseband_xmm_onoff(struct device *dev,
-       struct device_attribute *attr,
-       const char *buf, size_t count)
+static ssize_t xmm_onoff(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
 {
        int pwr;
        int size;
@@ -352,9 +349,9 @@ static ssize_t baseband_xmm_onoff(struct device *dev,
        pr_debug("%s power_onoff=%d\n", __func__, power_onoff);
 
        if (power_onoff == 0)
-               baseband_xmm_power_off(device);
+               xmm_power_off(device);
        else if (power_onoff == 1)
-               baseband_xmm_power_on(device);
+               xmm_power_on(device);
 
        mutex_unlock(&xmm_onoff_mutex);
 
@@ -362,12 +359,12 @@ static ssize_t baseband_xmm_onoff(struct device *dev,
 }
 
 static DEVICE_ATTR(xmm_onoff, S_IRUSR | S_IWUSR | S_IRGRP,
-               NULL, baseband_xmm_onoff);
+               NULL, xmm_onoff);
 
 
 void baseband_xmm_set_power_status(unsigned int status)
 {
-       struct baseband_power_platform_data *data = baseband_power_driver_data;
+       struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
        int value = 0;
        unsigned long flags;
 
@@ -379,7 +376,7 @@ void baseband_xmm_set_power_status(unsigned int status)
                if (modem_sleep_flag) {
                        pr_info("%s Resume from L3 without calling resume"
                                                "function\n",  __func__);
-                       baseband_xmm_power_driver_handle_resume(data);
+                       xmm_power_driver_handle_resume(data);
                }
                pr_info("L0\n");
                baseband_xmm_powerstate = status;
@@ -403,7 +400,7 @@ void baseband_xmm_set_power_status(unsigned int status)
                spin_lock_irqsave(&xmm_lock, flags);
                if (wakeup_pending) {
                        spin_unlock_irqrestore(&xmm_lock, flags);
-                       baseband_xmm_power_L2_resume();
+                       xmm_power_L2_resume();
                 } else {
                        spin_unlock_irqrestore(&xmm_lock, flags);
                        if (wake_lock_active(&wakelock))
@@ -447,7 +444,7 @@ void baseband_xmm_set_power_status(unsigned int status)
                if (baseband_xmm_powerstate == BBXMM_PS_L2) {
                        baseband_xmm_powerstate = status;
                        pr_debug("BB XMM POWER STATE = %d\n", status);
-                       baseband_xmm_power_L2_resume();
+                       xmm_power_L2_resume();
                }
                baseband_xmm_powerstate = status;
                break;
@@ -465,122 +462,111 @@ void baseband_xmm_set_power_status(unsigned int status)
 }
 EXPORT_SYMBOL_GPL(baseband_xmm_set_power_status);
 
-irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
+irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
 {
+       struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
        int value;
-       struct baseband_power_platform_data *data = baseband_power_driver_data;
 
        value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
        pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);
 
-       if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
+       /* modem initialization/bootup part*/
+       if (unlikely(ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY)) {
                pr_err("%s - spurious irq\n", __func__);
+               return IRQ_HANDLED;
        } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
                if (!value) {
                        pr_debug("%s - IPC_AP_WAKE_INIT1"
-                               " - got falling edge\n",
-                               __func__);
+                                       " - 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 {
+               } else
                        pr_debug("%s - IPC_AP_WAKE_INIT1"
-                               " - wait for falling edge\n",
-                               __func__);
-               }
+                               " - wait for falling edge\n", __func__);
+               return IRQ_HANDLED;
        } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
                if (!value) {
                        pr_debug("%s - IPC_AP_WAKE_INIT2"
-                               " - wait for rising edge\n",
-                               __func__);
+                               " - wait for rising edge\n", __func__);
                } else {
                        pr_debug("%s - IPC_AP_WAKE_INIT2"
-                               " - got rising edge\n",
-                               __func__);
+                                       " - got rising 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);
                }
-       } else {
-               if (!value) {
-                       pr_debug("%s - falling\n", __func__);
-                       /* First check it a CP ack or CP wake  */
-                       value = gpio_get_value
-                               (data->modem.xmm.ipc_bb_wake);
-                       if (value) {
-                               pr_debug("cp ack for bb_wake\n");
-                               ipc_ap_wake_state = IPC_AP_WAKE_L;
-                               return IRQ_HANDLED;
-                       }
-                       spin_lock(&xmm_lock);
-                       wakeup_pending = true;
-                       if (system_suspending) {
-                               spin_unlock(&xmm_lock);
-                               pr_info("Set wakeup_pending = 1 in system_"
-                                       " suspending!!!\n");
-                       } else {
-                               if (baseband_xmm_powerstate ==
-                                                       BBXMM_PS_L3) {
-                                       spin_unlock(&xmm_lock);
-                                       pr_info(" CP L3 -> L0\n");
-                               } else if (baseband_xmm_powerstate ==
-                                                       BBXMM_PS_L2) {
-                                       CP_initiated_L2toL0 = true;
-                                       spin_unlock(&xmm_lock);
-                                       baseband_xmm_set_power_status
-                                       (BBXMM_PS_L2TOL0);
-                               } else {
-                                       CP_initiated_L2toL0 = true;
-                                       spin_unlock(&xmm_lock);
-                               }
-                       }
-                       /* save gpio state */
+               return IRQ_HANDLED;
+       }
+
+       /* modem wakeup part */
+       if (!value) {
+               pr_debug("%s - falling\n", __func__);
+               /* First check it a CP ack or CP wake  */
+               value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
+               if (value) {
+                       pr_debug("cp ack for bb_wake\n");
                        ipc_ap_wake_state = IPC_AP_WAKE_L;
+                       return IRQ_HANDLED;
+               }
+               spin_lock(&xmm_lock);
+               wakeup_pending = true;
+               if (system_suspending) {
+                       spin_unlock(&xmm_lock);
+                       pr_info("Set wakeup_pending = 1 in system_"
+                                       " suspending!!!\n");
                } else {
-                       pr_debug("%s - rising\n", __func__);
-                       value = gpio_get_value
-                               (data->modem.xmm.ipc_hsic_active);
-                       if (!value) {
-                               pr_info("host active low: ignore request\n");
-                               ipc_ap_wake_state = IPC_AP_WAKE_H;
-                               return IRQ_HANDLED;
-                       }
-                       value = gpio_get_value
-                               (data->modem.xmm.ipc_bb_wake);
-                       if (value) {
-                               /* Clear the slave wakeup request */
-                               gpio_set_value
-                               (data->modem.xmm.ipc_bb_wake, 0);
-                               pr_debug("gpio slave wakeup done ->\n");
-                       }
-                       if (reenable_autosuspend && usbdev) {
-                                       reenable_autosuspend = false;
-                               queue_work(workqueue,
-                                       &autopm_resume_work);
+                       if (baseband_xmm_powerstate == BBXMM_PS_L3) {
+                               spin_unlock(&xmm_lock);
+                               pr_info(" CP L3 -> L0\n");
+                       } else if (baseband_xmm_powerstate == BBXMM_PS_L2) {
+                               CP_initiated_L2toL0 = true;
+                               spin_unlock(&xmm_lock);
+                               baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
+                       } else {
+                               CP_initiated_L2toL0 = true;
+                               spin_unlock(&xmm_lock);
                        }
-                       modem_sleep_flag = false;
-                       baseband_xmm_set_power_status(
-                                       BBXMM_PS_L0);
-                       /* save gpio state */
+               }
+               /* save gpio state */
+               ipc_ap_wake_state = IPC_AP_WAKE_L;
+       } else {
+               pr_debug("%s - rising\n", __func__);
+               value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
+               if (!value) {
+                       pr_info("host active low: ignore request\n");
                        ipc_ap_wake_state = IPC_AP_WAKE_H;
+                       return IRQ_HANDLED;
+               }
+               value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
+               if (value) {
+                       /* Clear the slave wakeup request */
+                       gpio_set_value(data->modem.xmm.ipc_bb_wake, 0);
+                       pr_debug("gpio slave wakeup done ->\n");
+               }
+               if (reenable_autosuspend && usbdev) {
+                       reenable_autosuspend = false;
+                       queue_work(workqueue, &autopm_resume_work);
                }
+               modem_sleep_flag = false;
+               baseband_xmm_set_power_status(BBXMM_PS_L0);
+               /* save gpio state */
+               ipc_ap_wake_state = IPC_AP_WAKE_H;
        }
 
        return IRQ_HANDLED;
 }
-EXPORT_SYMBOL(baseband_xmm_power_ipc_ap_wake_irq);
+EXPORT_SYMBOL(xmm_power_ipc_ap_wake_irq);
 
-static void baseband_xmm_power_init1_work(struct work_struct *work)
+static void xmm_power_init1_work(struct work_struct *work)
 {
+       struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
        int value;
 
        pr_debug("%s {\n", __func__);
 
        /* check if IPC_HSIC_ACTIVE high */
-       value = gpio_get_value(baseband_power_driver_data->
-               modem.xmm.ipc_hsic_active);
+       value = gpio_get_value(pdata->modem.xmm.ipc_hsic_active);
        if (value != 1) {
                pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
                return;
@@ -590,15 +576,13 @@ static void baseband_xmm_power_init1_work(struct work_struct *work)
        mdelay(100);
 
        /* set IPC_HSIC_ACTIVE low */
-       gpio_set_value(baseband_power_driver_data->
-               modem.xmm.ipc_hsic_active, 0);
+       gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
 
        /* wait 10 ms */
        mdelay(10);
 
        /* set IPC_HSIC_ACTIVE high */
-       gpio_set_value(baseband_power_driver_data->
-               modem.xmm.ipc_hsic_active, 1);
+       gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
 
        /* wait 20 ms */
        mdelay(20);
@@ -606,20 +590,20 @@ static void baseband_xmm_power_init1_work(struct work_struct *work)
        pr_debug("%s }\n", __func__);
 }
 
-static void baseband_xmm_power_init2_work(struct work_struct *work)
+static void xmm_power_init2_work(struct work_struct *work)
 {
-       struct baseband_power_platform_data *data = baseband_power_driver_data;
+       struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
 
        pr_debug("%s\n", __func__);
 
        /* check input */
-       if (!data)
+       if (!pdata)
                return;
 
        /* register usb host controller only once */
        if (register_hsic_device) {
-               if (data->hsic_register)
-                       data->modem.xmm.hsic_device = data->hsic_register();
+               if (pdata->hsic_register)
+                       xmm_power_drv_data.hsic_device = pdata->hsic_register();
                else
                        pr_err("%s: hsic_register is missing\n", __func__);
                register_hsic_device = false;
@@ -627,7 +611,7 @@ static void baseband_xmm_power_init2_work(struct work_struct *work)
 
 }
 
-static void baseband_xmm_power_autopm_resume(struct work_struct *work)
+static void xmm_power_autopm_resume(struct work_struct *work)
 {
        struct usb_interface *intf;
 
@@ -647,16 +631,16 @@ static void baseband_xmm_power_autopm_resume(struct work_struct *work)
 
 
 /* Do the work for AP/CP initiated L2->L0 */
-static void baseband_xmm_power_L2_resume(void)
+static void xmm_power_L2_resume(void)
 {
-       struct baseband_power_platform_data *data = baseband_power_driver_data;
+       struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
        int value;
        int delay = 10000; /* maxmum delay in msec */
        unsigned long flags;
 
        pr_debug("%s\n", __func__);
 
-       if (!baseband_power_driver_data)
+       if (!pdata)
                return;
 
        /* claim the wakelock here to avoid any system suspend */
@@ -674,15 +658,15 @@ static void baseband_xmm_power_L2_resume(void)
        } else {
                /* set the slave wakeup request */
                pr_info("AP L2->L0\n");
-               value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
+               value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
                if (value) {
                        pr_debug("waiting for host wakeup from CP...\n");
                        /* wake bb */
-                       gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
+                       gpio_set_value(pdata->modem.xmm.ipc_bb_wake, 1);
                        do {
                                mdelay(1);
                                value = gpio_get_value(
-                                       data->modem.xmm.ipc_ap_wake);
+                                               pdata->modem.xmm.ipc_ap_wake);
                                delay--;
                        } while ((value) && (delay));
                        if (delay)
@@ -696,7 +680,7 @@ static void baseband_xmm_power_L2_resume(void)
 }
 
 /* Do the work for CP initiated L2->L0 */
-static void baseband_xmm_power_L2_resume_work(struct work_struct *work)
+static void xmm_power_L2_resume_work(struct work_struct *work)
 {
        struct usb_interface *intf;
 
@@ -713,120 +697,77 @@ static void baseband_xmm_power_L2_resume_work(struct work_struct *work)
        pr_debug("} %s\n", __func__);
 }
 
-static void baseband_xmm_power_reset_on(void)
+static void xmm_power_reset_on(struct baseband_power_platform_data *pdata)
 {
        /* reset / power on sequence */
-       gpio_set_value(baseband_power_driver_data->modem.xmm.bb_rst, 0);
+       gpio_set_value(pdata->modem.xmm.bb_rst, 0);
        msleep(40);
-       gpio_set_value(baseband_power_driver_data->modem.xmm.bb_rst, 1);
+       gpio_set_value(pdata->modem.xmm.bb_rst, 1);
        mdelay(1);
-       gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 1);
+       gpio_set_value(pdata->modem.xmm.bb_on, 1);
        udelay(70);
-       gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 0);
+       gpio_set_value(pdata->modem.xmm.bb_on, 0);
 }
 
-static struct baseband_xmm_power_work_t *baseband_xmm_power_work;
 
-static void baseband_xmm_power_work_func(struct work_struct *work)
+static void xmm_power_work_func(struct work_struct *work)
 {
-       struct baseband_xmm_power_work_t *bbxmm_work
-               = (struct baseband_xmm_power_work_t *) work;
+       struct xmm_power_data *data =
+                       container_of(work, struct xmm_power_data, work);
+       struct baseband_power_platform_data *pdata = data->pdata;
 
        pr_debug("%s\n", __func__);
 
-       switch (bbxmm_work->state) {
+       switch (data->state) {
        case BBXMM_WORK_UNINIT:
                pr_debug("BBXMM_WORK_UNINIT\n");
                break;
        case BBXMM_WORK_INIT:
                pr_debug("BBXMM_WORK_INIT\n");
                /* go to next state */
-               bbxmm_work->state = (modem_flash && !modem_pm)
+               data->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;
-               pr_debug("Go to next state %d\n", bbxmm_work->state);
+               pr_debug("Go to next state %d\n", data->state);
                queue_work(workqueue, work);
                break;
        case BBXMM_WORK_INIT_FLASH_STEP1:
                pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
                /* register usb host controller */
                pr_debug("%s: register usb host controller\n", __func__);
-               if (baseband_power_driver_data->hsic_register)
-                       baseband_power_driver_data->modem.xmm.hsic_device =
-                               baseband_power_driver_data->hsic_register();
+               if (pdata->hsic_register)
+                       data->hsic_device = pdata->hsic_register();
                else
                        pr_err("%s: hsic_register is missing\n", __func__);
                break;
        case BBXMM_WORK_INIT_FLASH_PM_STEP1:
                pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
-               /* [modem ver >= 1130] start with IPC_HSIC_ACTIVE low */
-               if (modem_ver >= XMM_MODEM_VER_1130) {
-                       pr_debug("%s: ver > 1130:"
-                               " ipc_hsic_active -> 0\n", __func__);
-                       gpio_set_value(baseband_power_driver_data->
-                               modem.xmm.ipc_hsic_active, 0);
-               }
+               pr_debug("%s: ipc_hsic_active -> 0\n", __func__);
+               gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
                /* reset / power on sequence */
-               baseband_xmm_power_reset_on();
+               xmm_power_reset_on(pdata);
                /* set power status as on */
                power_onoff = 1;
-               /* optional delay
-                * 0 = flashless
-                *   ==> causes next step to enumerate modem boot rom
-                *       (058b / 0041)
-                * some delay > boot rom timeout
-                *   ==> causes next step to enumerate modem software
-                *       (1519 / 0020)
-                *       (requires modem to be flash version, not flashless
-                *       version)
+               gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
+
+               /* expecting init2 performs register hsic to enumerate modem
+                * software directly.
                 */
-               if (enum_delay_ms)
-                       mdelay(enum_delay_ms);
-               /* register usb host controller */
-               pr_debug("%s: register usb host controller\n", __func__);
-               if (baseband_power_driver_data->hsic_register)
-                       baseband_power_driver_data->modem.xmm.hsic_device =
-                               baseband_power_driver_data->hsic_register();
-               else
-                       pr_err("%s: hsic_register is missing\n", __func__);
-               /* 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);
-               pr_debug("Go to next state %d\n", bbxmm_work->state);
-               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_STEP1:
-               pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
-               break;
-       case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
-               pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
+               pr_info("%s: flashless is not supported here\n", __func__);
                break;
        default:
                break;
        }
-
 }
 
-static void baseband_xmm_device_add_handler(struct usb_device *udev)
+static void xmm_device_add_handler(struct usb_device *udev)
 {
        struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
        const struct usb_device_id *id;
@@ -846,7 +787,7 @@ static void baseband_xmm_device_add_handler(struct usb_device *udev)
        }
 }
 
-static void baseband_xmm_device_remove_handler(struct usb_device *udev)
+static void xmm_device_remove_handler(struct usb_device *udev)
 {
        if (usbdev == udev) {
                pr_info("Remove device %d <%s %s>\n", udev->devnum,
@@ -861,10 +802,10 @@ static int usb_xmm_notify(struct notifier_block *self, unsigned long action,
 {
        switch (action) {
        case USB_DEVICE_ADD:
-               baseband_xmm_device_add_handler(blob);
+               xmm_device_add_handler(blob);
                break;
        case USB_DEVICE_REMOVE:
-               baseband_xmm_device_remove_handler(blob);
+               xmm_device_remove_handler(blob);
                break;
        }
 
@@ -876,13 +817,13 @@ static struct notifier_block usb_xmm_nb = {
        .notifier_call = usb_xmm_notify,
 };
 
-static int baseband_xmm_power_pm_notifier_event(struct notifier_block *this,
+static int xmm_power_pm_notifier_event(struct notifier_block *this,
                                        unsigned long event, void *ptr)
 {
-       struct baseband_power_platform_data *data = baseband_power_driver_data;
+       struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
        unsigned long flags;
 
-       if (!data)
+       if (!pdata)
                return NOTIFY_DONE;
 
        pr_debug("%s: event %ld\n", __func__, event);
@@ -914,11 +855,9 @@ static int baseband_xmm_power_pm_notifier_event(struct notifier_block *this,
                        (baseband_xmm_powerstate == BBXMM_PS_L2)) {
                        wakeup_pending = false;
                        spin_unlock_irqrestore(&xmm_lock, flags);
-                       pr_info("%s : Service Pending CP wakeup\n",
-                               __func__);
+                       pr_info("%s : Service Pending CP wakeup\n", __func__);
                        CP_initiated_L2toL0 = true;
-                       baseband_xmm_set_power_status
-                               (BBXMM_PS_L2TOL0);
+                       baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
                        return NOTIFY_OK;
                }
                wakeup_pending = false;
@@ -928,16 +867,14 @@ static int baseband_xmm_power_pm_notifier_event(struct notifier_block *this,
        return NOTIFY_DONE;
 }
 
-static struct notifier_block baseband_xmm_power_pm_notifier = {
-       .notifier_call = baseband_xmm_power_pm_notifier_event,
+static struct notifier_block xmm_power_pm_notifier = {
+       .notifier_call = xmm_power_pm_notifier_event,
 };
 
 
-static int baseband_xmm_power_driver_probe(struct platform_device *device)
+static int xmm_power_driver_probe(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
-                       device->dev.platform_data;
+       struct baseband_power_platform_data *pdata = device->dev.platform_data;
        struct device *dev = &device->dev;
        unsigned long flags;
        int err;
@@ -946,17 +883,17 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
        pr_debug("[XMM] enum_delay_ms=%ld\n", enum_delay_ms);
 
        /* check for platform data */
-       if (!data)
+       if (!pdata)
                return -ENODEV;
 
        /* check if supported modem */
-       if (data->baseband_type != BASEBAND_XMM) {
+       if (pdata->baseband_type != BASEBAND_XMM) {
                pr_err("unsuppported modem\n");
                return -ENODEV;
        }
 
        /* save platform data */
-       baseband_power_driver_data = data;
+       xmm_power_drv_data.pdata = pdata;
 
        /* create device file */
        err = device_create_file(dev, &dev_attr_xmm_onoff);
@@ -971,20 +908,14 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
        /* init spin lock */
        spin_lock_init(&xmm_lock);
        /* request baseband gpio(s) */
-       tegra_baseband_gpios[0].gpio = baseband_power_driver_data
-               ->modem.xmm.bb_rst;
-       tegra_baseband_gpios[1].gpio = baseband_power_driver_data
-               ->modem.xmm.bb_on;
-       tegra_baseband_gpios[2].gpio = baseband_power_driver_data
-               ->modem.xmm.ipc_bb_wake;
-       tegra_baseband_gpios[3].gpio = baseband_power_driver_data
-               ->modem.xmm.ipc_ap_wake;
-       tegra_baseband_gpios[4].gpio = baseband_power_driver_data
-               ->modem.xmm.ipc_hsic_active;
-       tegra_baseband_gpios[5].gpio = baseband_power_driver_data
-               ->modem.xmm.ipc_hsic_sus_req;
+       tegra_baseband_gpios[0].gpio = pdata->modem.xmm.bb_rst;
+       tegra_baseband_gpios[1].gpio = pdata->modem.xmm.bb_on;
+       tegra_baseband_gpios[2].gpio = pdata->modem.xmm.ipc_bb_wake;
+       tegra_baseband_gpios[3].gpio = pdata->modem.xmm.ipc_ap_wake;
+       tegra_baseband_gpios[4].gpio = pdata->modem.xmm.ipc_hsic_active;
+       tegra_baseband_gpios[5].gpio = pdata->modem.xmm.ipc_hsic_sus_req;
        err = gpio_request_array(tegra_baseband_gpios,
-               ARRAY_SIZE(tegra_baseband_gpios));
+                               ARRAY_SIZE(tegra_baseband_gpios));
        if (err < 0) {
                pr_err("%s - request gpio(s) failed\n", __func__);
                return -ENODEV;
@@ -995,52 +926,41 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
                pr_debug("%s: request_irq IPC_AP_WAKE_IRQ\n", __func__);
                ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
                err = request_threaded_irq(
-                       gpio_to_irq(data->modem.xmm.ipc_ap_wake),
-                       NULL,
-                       baseband_xmm_power_ipc_ap_wake_irq,
-                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                       "IPC_AP_WAKE_IRQ",
-                       NULL);
+                               gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
+                               NULL, xmm_power_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;
                }
-               err = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+               err = enable_irq_wake(gpio_to_irq(
+                                       pdata->modem.xmm.ipc_ap_wake));
                if (err < 0)
                        pr_err("%s: enable_irq_wake error\n", __func__);
-               ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
-               if (modem_ver >= XMM_MODEM_VER_1130) {
-                       pr_debug("%s: ver > 1130: AP_WAKE_INIT1\n", __func__);
-                       /* ver 1130 or later starts in INIT1 state */
-                       ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
-               }
+
+               pr_debug("%s: AP_WAKE_INIT1\n", __func__);
+               /* ver 1130 or later starts in INIT1 state */
+               ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
        }
 
        /* init work queue */
-       workqueue = create_singlethread_workqueue
-               ("baseband_xmm_power_workqueue");
+       workqueue = create_singlethread_workqueue("xmm_power_wq");
        if (!workqueue) {
                pr_err("cannot create workqueue\n");
-               return -1;
+               return -ENOMEM;
        }
-       baseband_xmm_power_work = (struct baseband_xmm_power_work_t *)
-               kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
-       if (!baseband_xmm_power_work) {
-               pr_err("cannot allocate baseband_xmm_power_work\n");
-               return -1;
-       }
-       INIT_WORK((struct work_struct *) baseband_xmm_power_work,
-               baseband_xmm_power_work_func);
-       baseband_xmm_power_work->state = BBXMM_WORK_INIT;
-       queue_work(workqueue,
-               (struct work_struct *) baseband_xmm_power_work);
+
+       INIT_WORK(&xmm_power_drv_data.work, xmm_power_work_func);
+       xmm_power_drv_data.state = BBXMM_WORK_INIT;
+       queue_work(workqueue, &xmm_power_drv_data.work);
 
        /* init work objects */
-       INIT_WORK(&init1_work, baseband_xmm_power_init1_work);
-       INIT_WORK(&init2_work, baseband_xmm_power_init2_work);
-       INIT_WORK(&L2_resume_work, baseband_xmm_power_L2_resume_work);
-       INIT_WORK(&autopm_resume_work, baseband_xmm_power_autopm_resume);
+       INIT_WORK(&init1_work, xmm_power_init1_work);
+       INIT_WORK(&init2_work, xmm_power_init2_work);
+       INIT_WORK(&L2_resume_work, xmm_power_L2_resume_work);
+       INIT_WORK(&autopm_resume_work, xmm_power_autopm_resume);
 
        /* init state variables */
        register_hsic_device = true;
@@ -1052,36 +972,30 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
        spin_unlock_irqrestore(&xmm_lock, flags);
 
        usb_register_notify(&usb_xmm_nb);
-       register_pm_notifier(&baseband_xmm_power_pm_notifier);
+       register_pm_notifier(&xmm_power_pm_notifier);
 
        pr_debug("%s }\n", __func__);
        return 0;
 }
 
-static int baseband_xmm_power_driver_remove(struct platform_device *device)
+static int xmm_power_driver_remove(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
-                       device->dev.platform_data;
+       struct baseband_power_platform_data *pdata = device->dev.platform_data;
+       struct xmm_power_data *data = &xmm_power_drv_data;
        struct device *dev = &device->dev;
 
        pr_debug("%s\n", __func__);
 
        /* check for platform data */
-       if (!data)
+       if (!pdata)
                return 0;
 
-       unregister_pm_notifier(&baseband_xmm_power_pm_notifier);
+       unregister_pm_notifier(&xmm_power_pm_notifier);
        usb_unregister_notify(&usb_xmm_nb);
 
-       /* free work structure */
-       kfree(baseband_xmm_power_work);
-       baseband_xmm_power_work = (struct baseband_xmm_power_work_t *) 0;
-
        /* free baseband irq(s) */
        if (modem_flash && modem_pm) {
-               free_irq(gpio_to_irq(baseband_power_driver_data
-                       ->modem.xmm.ipc_ap_wake), NULL);
+               free_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake), NULL);
        }
 
        /* free baseband gpio(s) */
@@ -1095,23 +1009,23 @@ static int baseband_xmm_power_driver_remove(struct platform_device *device)
        device_remove_file(dev, &dev_attr_xmm_onoff);
 
        /* unregister usb host controller */
-       if (data->hsic_unregister)
-               data->hsic_unregister(data->modem.xmm.hsic_device);
+       if (pdata->hsic_unregister)
+               pdata->hsic_unregister(data->hsic_device);
        else
                pr_err("%s: hsic_unregister is missing\n", __func__);
 
        return 0;
 }
 
-static int baseband_xmm_power_driver_handle_resume(
-                       struct baseband_power_platform_data *data)
+static int xmm_power_driver_handle_resume(
+                       struct baseband_power_platform_data *pdata)
 {
        int value;
        int delay = 1000; /* maxmum delay in msec */
        unsigned long flags;
 
        pr_debug("%s\n", __func__);
-       if (!data)
+       if (!pdata)
                return 0;
 
        /* check if modem is on */
@@ -1127,16 +1041,15 @@ static int baseband_xmm_power_driver_handle_resume(
 
        /* L3->L0 */
        baseband_xmm_set_power_status(BBXMM_PS_L3TOL0);
-       value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
+       value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
        if (value) {
                pr_info("AP L3 -> L0\n");
                pr_debug("waiting for host wakeup...\n");
                /* wake bb */
-               gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
+               gpio_set_value(pdata->modem.xmm.ipc_bb_wake, 1);
                do {
                        mdelay(1);
-                       value = gpio_get_value(
-                               data->modem.xmm.ipc_ap_wake);
+                       value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
                        delay--;
                } while ((value) && (delay));
                if (delay)
@@ -1155,26 +1068,24 @@ static int baseband_xmm_power_driver_handle_resume(
 
 
 #ifdef CONFIG_PM
-static int baseband_xmm_power_driver_suspend(struct device *dev)
+static int xmm_power_driver_suspend(struct device *dev)
 {
        pr_debug("%s\n", __func__);
        return 0;
 }
 
-static int baseband_xmm_power_driver_resume(struct device *dev)
+static int xmm_power_driver_resume(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
-                       pdev->dev.platform_data;
+       struct baseband_power_platform_data *pdata = pdev->dev.platform_data;
 
        pr_debug("%s\n", __func__);
-       baseband_xmm_power_driver_handle_resume(data);
+       xmm_power_driver_handle_resume(pdata);
 
        return 0;
 }
 
-static int baseband_xmm_power_suspend_noirq(struct device *dev)
+static int xmm_power_suspend_noirq(struct device *dev)
 {
        unsigned long flags;
 
@@ -1191,57 +1102,55 @@ static int baseband_xmm_power_suspend_noirq(struct device *dev)
        return 0;
 }
 
-static int baseband_xmm_power_resume_noirq(struct device *dev)
+static int xmm_power_resume_noirq(struct device *dev)
 {
        pr_debug("%s\n", __func__);
        return 0;
 }
 
-static const struct dev_pm_ops baseband_xmm_power_dev_pm_ops = {
-       .suspend_noirq = baseband_xmm_power_suspend_noirq,
-       .resume_noirq = baseband_xmm_power_resume_noirq,
-       .suspend = baseband_xmm_power_driver_suspend,
-       .resume = baseband_xmm_power_driver_resume,
+static const struct dev_pm_ops xmm_power_dev_pm_ops = {
+       .suspend_noirq = xmm_power_suspend_noirq,
+       .resume_noirq = xmm_power_resume_noirq,
+       .suspend = xmm_power_driver_suspend,
+       .resume = xmm_power_driver_resume,
 };
 #endif
 
-static int baseband_xmm_power_driver_shutdown(struct platform_device *device)
+static void xmm_power_driver_shutdown(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data =
-               (struct baseband_power_platform_data *)
-                       device->dev.platform_data;
+       struct baseband_power_platform_data *pdata = device->dev.platform_data;
 
        pr_debug("%s\n", __func__);
-       disable_irq(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+       disable_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
        /* bb_on is already down, to make sure set 0 again */
-       gpio_set_value(data->modem.xmm.bb_on, 0);
-       gpio_set_value(data->modem.xmm.bb_rst, 0);
-       return 0;
+       gpio_set_value(pdata->modem.xmm.bb_on, 0);
+       gpio_set_value(pdata->modem.xmm.bb_rst, 0);
+       return;
 }
 
 static struct platform_driver baseband_power_driver = {
-       .probe = baseband_xmm_power_driver_probe,
-       .remove = baseband_xmm_power_driver_remove,
-       .shutdown = baseband_xmm_power_driver_shutdown,
+       .probe = xmm_power_driver_probe,
+       .remove = xmm_power_driver_remove,
+       .shutdown = xmm_power_driver_shutdown,
        .driver = {
                .name = "baseband_xmm_power",
 #ifdef CONFIG_PM
-               .pm   = &baseband_xmm_power_dev_pm_ops,
+               .pm   = &xmm_power_dev_pm_ops,
 #endif
        },
 };
 
-static int __init baseband_xmm_power_init(void)
+static int __init xmm_power_init(void)
 {
        pr_debug("%s\n", __func__);
        return platform_driver_register(&baseband_power_driver);
 }
 
-static void __exit baseband_xmm_power_exit(void)
+static void __exit xmm_power_exit(void)
 {
        pr_debug("%s\n", __func__);
        platform_driver_unregister(&baseband_power_driver);
 }
 
-module_init(baseband_xmm_power_init)
-module_exit(baseband_xmm_power_exit)
+module_init(xmm_power_init)
+module_exit(xmm_power_exit)
index 0768ed1..1f08e3b 100644 (file)
@@ -71,24 +71,19 @@ enum baseband_xmm_power_work_state_t {
        BBXMM_WORK_INIT_FLASH_STEP1,
        /* initialize flash (with power management support) modem */
        BBXMM_WORK_INIT_FLASH_PM_STEP1,
-       BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1,
-       BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1,
        /* initialize flashless (with power management support) modem */
        BBXMM_WORK_INIT_FLASHLESS_PM_STEP1,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3,
-       BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4,
+       BBXMM_WORK_INIT_FLASHLESS_PM_STEP2,
+       BBXMM_WORK_INIT_FLASHLESS_PM_STEP3,
+       BBXMM_WORK_INIT_FLASHLESS_PM_STEP4,
 };
 
-struct baseband_xmm_power_work_t {
-       /* work structure must be first structure member */
-       struct work_struct work;
+struct xmm_power_data {
        /* xmm modem state */
        enum baseband_xmm_power_work_state_t state;
+       struct baseband_power_platform_data *pdata;
+       struct work_struct work;
+       struct platform_device *hsic_device;
 };
 
 enum baseband_xmm_powerstate_t {
@@ -104,8 +99,9 @@ enum baseband_xmm_powerstate_t {
        BBXMM_PS_LAST   = -1,
 };
 
-irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id);
+irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id);
 
 void baseband_xmm_set_power_status(unsigned int status);
+extern struct xmm_power_data xmm_power_drv_data;
 
 #endif  /* BASREBAND_XMM_POWER_H */
index 4295b39..3c6285c 100644 (file)
@@ -32,8 +32,6 @@
 #include "board.h"
 #include "devices.h"
 
-MODULE_LICENSE("GPL");
-
 static unsigned long XYZ = 1000 * 1000000 + 800 * 1000 + 500;
 
 module_param(modem_ver, ulong, 0644);
@@ -49,9 +47,8 @@ module_param(XYZ, ulong, 0644);
 MODULE_PARM_DESC(XYZ,
        "baseband xmm power2 - timing parameters X/Y/Z delay in ms");
 
-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 bool free_ipc_ap_wake_irq;
 
 static enum {
        IPC_AP_WAKE_UNINIT,
@@ -62,105 +59,37 @@ static enum {
        IPC_AP_WAKE_H,
 } ipc_ap_wake_state;
 
-static irqreturn_t baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
-       (int irq, void *dev_id)
-{
-       int value;
-
-       pr_debug("%s\n", __func__);
-
-       /* check for platform data */
-       if (!baseband_power2_driver_data)
-               return IRQ_HANDLED;
 
-       value = gpio_get_value(baseband_power2_driver_data->
-                   modem.xmm.ipc_ap_wake);
-
-       /* 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) {
-               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) {
-               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 {
-               if (!value) {
-                       pr_debug("%s - falling\n", __func__);
-                       ipc_ap_wake_state = IPC_AP_WAKE_L;
-               } else {
-                       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 irqreturn_t baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2
-       (int irq, void *dev_id)
+static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
 {
        int value;
+       struct xmm_power_data *data = dev_id;
+       struct baseband_power_platform_data *pdata = data->pdata;
 
        pr_debug("%s\n", __func__);
 
        /* check for platform data */
-       if (!baseband_power2_driver_data)
+       if (!pdata)
                return IRQ_HANDLED;
 
-       value = gpio_get_value(baseband_power2_driver_data->
-                   modem.xmm.ipc_ap_wake);
+       value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
 
        /* IPC_AP_WAKE state machine */
-       if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
+       if (unlikely(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) {
+       else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
                if (!value) {
-                       pr_debug("%s - IPC_AP_WAKE_INIT1"
-                               " - got falling 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 */
-                       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__);
-               }
+                       data->state =
+                               BBXMM_WORK_INIT_FLASHLESS_PM_STEP2;
+                       queue_work(workqueue, &data->work);
+               } else
+                       pr_debug("%s: IPC_AP_WAKE_INIT1"
+                               " wait for falling edge\n", __func__);
        } else {
                if (!value) {
                        pr_debug("%s - falling\n", __func__);
@@ -169,260 +98,154 @@ static irqreturn_t baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2
                        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 xmm_power_ipc_ap_wake_irq(irq, dev_id);
        }
 
        return IRQ_HANDLED;
 }
 
-static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step1
-       (struct work_struct *work)
-{
-       int value;
-
-       pr_debug("%s {\n", __func__);
-
-       /* check for platform data */
-       if (!baseband_power2_driver_data)
-               return;
-
-       /* check if IPC_HSIC_ACTIVE high */
-       value = gpio_get_value(baseband_power2_driver_data->
-               modem.xmm.ipc_hsic_active);
-       if (value != 1) {
-               pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
-               return;
-       }
-
-       /* wait 30 ms */
-       mdelay(30);
-
-       /* set IPC_HSIC_ACTIVE low */
-       gpio_set_value(baseband_power2_driver_data->
-               modem.xmm.ipc_hsic_active, 0);
-
-       pr_debug("%s }\n", __func__);
-}
-
-static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step2
-       (struct work_struct *work)
-{
-       int value;
-
-       pr_debug("%s {\n", __func__);
-
-       /* check for platform data */
-       if (!baseband_power2_driver_data)
-               return;
-
-       /* check if IPC_HSIC_ACTIVE low */
-       value = gpio_get_value(baseband_power2_driver_data->
-               modem.xmm.ipc_hsic_active);
-       if (value != 0) {
-               pr_err("%s - expected IPC_HSIC_ACTIVE low!\n", __func__);
-               return;
-       }
-
-       /* wait 1 ms */
-       mdelay(1);
-
-       /* unregister usb host controller */
-       if (baseband_power2_driver_data->hsic_unregister)
-               baseband_power2_driver_data->hsic_unregister(
-                       baseband_power2_driver_data->modem.xmm.hsic_device);
-       else
-               pr_err("%s: hsic_unregister is missing\n", __func__);
-
-       /* set IPC_HSIC_ACTIVE high */
-       gpio_set_value(baseband_power2_driver_data->
-               modem.xmm.ipc_hsic_active, 1);
-
-       /* 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);
-
-       pr_debug("%s }\n", __func__);
-}
-
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step1
-       (struct work_struct *work)
+static void xmm_power2_step1(struct work_struct *work)
 {
+       struct xmm_power_data *data =
+                       container_of(work, struct xmm_power_data, work);
+       struct baseband_power_platform_data *pdata = data->pdata;
        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)
+       if (!pdata)
                return;
 
        /* unregister usb host controller */
-       if (baseband_power2_driver_data->hsic_unregister)
-               baseband_power2_driver_data->hsic_unregister(
-                       baseband_power2_driver_data->modem.xmm.hsic_device);
+       if (pdata->hsic_unregister)
+               pdata->hsic_unregister(data->hsic_device);
        else
                pr_err("%s: hsic_unregister is missing\n", __func__);
 
        /* wait X ms */
-       mdelay(X);
+       msleep(X);
 
        /* set IPC_HSIC_ACTIVE low */
-       gpio_set_value(baseband_power2_driver_data->
-               modem.xmm.ipc_hsic_active, 0);
+       gpio_set_value(pdata->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)
+static void xmm_power2_step2(struct work_struct *work)
 {
+       struct xmm_power_data *data =
+                       container_of(work, struct xmm_power_data, work);
+       struct baseband_power_platform_data *pdata = data->pdata;
        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)
+       if (!data || !pdata)
                return;
 
        /* wait Y ms */
-       mdelay(Y);
+       msleep(Y);
 
        /* register usb host controller */
-       if (baseband_power2_driver_data->hsic_register)
-               baseband_power2_driver_data->modem.xmm.hsic_device =
-                       baseband_power2_driver_data->hsic_register();
+       if (pdata->hsic_register)
+               data->hsic_device = pdata->hsic_register();
        else
                pr_err("%s: hsic_register is missing\n", __func__);
 
        /* wait Z ms */
-       mdelay(Z);
+       msleep(Z);
 
        /* set IPC_HSIC_ACTIVE high */
-       gpio_set_value(baseband_power2_driver_data->
-               modem.xmm.ipc_hsic_active, 1);
+       gpio_set_value(pdata->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);
+       data->state = BBXMM_WORK_INIT_FLASHLESS_PM_STEP3;
+       queue_work(workqueue, &data->work);
 
        pr_info("%s }\n", __func__);
 }
 
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step3
-       (struct work_struct *work)
+static void xmm_power2_step3(struct work_struct *work)
 {
-       int X = XYZ / 1000000;
-       int Y = XYZ / 1000 - X * 1000;
-       int Z = XYZ % 1000;
+       struct xmm_power_data *data =
+                       container_of(work, struct xmm_power_data, work);
+       struct baseband_power_platform_data *pdata = data->pdata;
        int enum_success = 0;
+       mm_segment_t oldfs;
+       struct file *filp;
 
        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)
+       if (!data || !pdata)
                return;
 
-       /* wait 500 ms */
-       mdelay(500);
+       /* wait 1 sec */
+       msleep(1000);
 
        /* check if enumeration succeeded */
-       {
-               mm_segment_t oldfs;
-               struct file *filp;
-               oldfs = get_fs();
-               set_fs(KERNEL_DS);
-               filp = filp_open("/dev/ttyACM0",
-                       O_RDONLY, 0);
-               if (IS_ERR(filp) || (filp == NULL)) {
-                       pr_err("/dev/ttyACM0 %ld\n",
-                               PTR_ERR(filp));
-               } else {
-                       filp_close(filp, NULL);
-                       enum_success = 1;
-               }
-               set_fs(oldfs);
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+       filp = filp_open("/dev/ttyACM0", O_RDONLY, 0);
+       if (IS_ERR(filp) || (filp == NULL))
+               pr_err("failed to open /dev/ttyACM0 %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);
+               msleep(20);
                /* set IPC_HSIC_ACTIVE low */
-               gpio_set_value(baseband_power2_driver_data->
-                       modem.xmm.ipc_hsic_active, 0);
+               gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
                /* wait 20 ms */
-               mdelay(20);
+               msleep(20);
                /* set IPC_HSIC_ACTIVE high */
-               gpio_set_value(baseband_power2_driver_data->
-                       modem.xmm.ipc_hsic_active, 1);
+               gpio_set_value(pdata->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);
+               data->state = BBXMM_WORK_INIT_FLASHLESS_PM_STEP4;
+               queue_work(workqueue, &data->work);
        }
 
        pr_info("%s }\n", __func__);
 }
 
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step4
-       (struct work_struct *work)
+static void xmm_power2_step4(struct work_struct *work)
 {
-       int X = XYZ / 1000000;
-       int Y = XYZ / 1000 - X * 1000;
-       int Z = XYZ % 1000;
+       struct xmm_power_data *data =
+                       container_of(work, struct xmm_power_data, work);
+       mm_segment_t oldfs;
+       struct file *filp;
        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)
+       if (!data)
                return;
 
        /* wait 500 ms */
-       mdelay(500);
+       msleep(500);
 
        /* check if enumeration succeeded */
-       {
-               mm_segment_t oldfs;
-               struct file *filp;
-               oldfs = get_fs();
-               set_fs(KERNEL_DS);
-               filp = filp_open("/dev/ttyACM0",
-                       O_RDONLY, 0);
-               if (IS_ERR(filp) || (filp == NULL)) {
-                       pr_err("open /dev/ttyACM0 failed %ld\n",
-                               PTR_ERR(filp));
-               } else {
-                       filp_close(filp, NULL);
-                       enum_success = 1;
-               }
-               set_fs(oldfs);
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+       filp = filp_open("/dev/ttyACM0", O_RDONLY, 0);
+       if (IS_ERR(filp) || (filp == NULL))
+               pr_err("failed to open /dev/ttyACM0 %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) {
@@ -438,34 +261,31 @@ static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step4
                                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);
+                       data->state = BBXMM_WORK_INIT_FLASHLESS_PM_STEP1;
+                       queue_work(workqueue, &data->work);
                }
        }
 
        pr_info("%s }\n", __func__);
 }
 
-static int free_ipc_ap_wake_irq;
-
-static void baseband_xmm_power2_work_func(struct work_struct *work)
+static void xmm_power2_work_func(struct work_struct *work)
 {
-       struct baseband_xmm_power_work_t *bbxmm_work
-               = (struct baseband_xmm_power_work_t *) work;
+       struct xmm_power_data *data =
+                       container_of(work, struct xmm_power_data, work);
+       struct baseband_power_platform_data *pdata = data->pdata;
        int err;
 
-       pr_debug("%s bbxmm_work->state=%d\n", __func__, bbxmm_work->state);
+       pr_debug("%s pdata->state=%d\n", __func__, data->state);
 
-       switch (bbxmm_work->state) {
+       switch (data->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;
+                       free_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
+                                       data);
+                       free_ipc_ap_wake_irq = false;
                }
                break;
        case BBXMM_WORK_INIT:
@@ -473,24 +293,20 @@ static void baseband_xmm_power2_work_func(struct work_struct *work)
                /* request baseband irq(s) */
                ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
                err = request_threaded_irq(
-                       gpio_to_irq(baseband_power2_driver_data->
-                           modem.xmm.ipc_ap_wake),
-                       NULL,
-                       (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);
+                               gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
+                               NULL, xmm_power2_ipc_ap_wake_irq,
+                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                               "xmm_power2_ipc_ap_wake_irq", data);
                if (err < 0) {
                        pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
                                __func__);
                        return;
                }
-               free_ipc_ap_wake_irq = 1;
+               free_ipc_ap_wake_irq = true;
                ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
+
                /* go to next state */
-               bbxmm_work->state = (modem_flash && !modem_pm)
+               data->state = (modem_flash && !modem_pm)
                        ? BBXMM_WORK_INIT_FLASH_STEP1
                        : (modem_flash && modem_pm)
                        ? BBXMM_WORK_INIT_FLASH_PM_STEP1
@@ -501,130 +317,93 @@ static void baseband_xmm_power2_work_func(struct work_struct *work)
                break;
        case BBXMM_WORK_INIT_FLASH_STEP1:
                pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
+               pr_info("%s: flashed modem is not supported here\n", __func__);
                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");
+               pr_info("%s: flashed modem is not supported here\n", __func__);
                break;
        case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
+               /* start flashless modem enum process */
                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);
+               xmm_power2_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);
+       case BBXMM_WORK_INIT_FLASHLESS_PM_STEP2:
+               pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP2\n");
+               xmm_power2_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);
+       case BBXMM_WORK_INIT_FLASHLESS_PM_STEP3:
+               pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP3\n");
+               xmm_power2_step3(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);
+       case BBXMM_WORK_INIT_FLASHLESS_PM_STEP4:
+               pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP4\n");
+               xmm_power2_step4(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);
+       default:
                break;
        }
-
 }
 
-static int baseband_xmm_power2_driver_probe(struct platform_device *device)
+static int xmm_power2_probe(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
-                       device->dev.platform_data;
-
        pr_debug("%s\n", __func__);
+       if (!device->dev.platform_data) {
+               pr_err("%s: no platform data found\n", __func__);
+               return -ENOMEM;
+       }
 
-       /* save platform data */
-       baseband_power2_driver_data = data;
+       xmm_power_drv_data.pdata = device->dev.platform_data;
 
-       /* init work queue */
+       /* create workqueue */
        pr_debug("%s: init work queue\n", __func__);
-       workqueue = create_singlethread_workqueue
-               ("baseband_xmm_power2_workqueue");
-       if (!workqueue) {
-               pr_err("cannot create workqueue\n");
-               return -1;
-       }
-       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;
+       workqueue = create_singlethread_workqueue("xmm_power2_wq");
+       if (unlikely(!workqueue)) {
+               pr_err("%s: cannot create workqueue\n", __func__);
+               return -ENOMEM;
        }
+
+       /* init work */
        pr_debug("%s: BBXMM_WORK_INIT\n", __func__);
-       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);
+       INIT_WORK(&xmm_power_drv_data.work, xmm_power2_work_func);
+       xmm_power_drv_data.state = BBXMM_WORK_INIT;
+       queue_work(workqueue, &xmm_power_drv_data.work);
+
        return 0;
 }
 
-static int baseband_xmm_power2_driver_remove(struct platform_device *device)
+static int xmm_power2_remove(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
+       struct baseband_power_platform_data *pdata =
                        device->dev.platform_data;
+       struct xmm_power_data *data = &xmm_power_drv_data;
 
        pr_debug("%s\n", __func__);
 
        /* check for platform data */
        if (!data)
-               return 0;
-
-       /* 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;
-       }
+               return -ENODEV;
 
-       /* free work structure */
+       /* free work queue */
        if (workqueue) {
-               cancel_work_sync(baseband_xmm_power2_work);
+               cancel_work_sync(&data->work);
                destroy_workqueue(workqueue);
        }
-       kfree(baseband_xmm_power2_work);
-       baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *) 0;
+
+       /* free irq */
+       if (free_ipc_ap_wake_irq) {
+               free_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake), data);
+               free_ipc_ap_wake_irq = false;
+       }
 
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int baseband_xmm_power2_driver_suspend(struct platform_device *device,
+static int xmm_power2_suspend(struct platform_device *device,
        pm_message_t state)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
+       struct baseband_power_platform_data *data =
                        device->dev.platform_data;
 
        pr_debug("%s - nop\n", __func__);
@@ -636,10 +415,9 @@ static int baseband_xmm_power2_driver_suspend(struct platform_device *device,
        return 0;
 }
 
-static int baseband_xmm_power2_driver_resume(struct platform_device *device)
+static int xmm_power2_resume(struct platform_device *device)
 {
-       struct baseband_power_platform_data *data
-               = (struct baseband_power_platform_data *)
+       struct baseband_power_platform_data *data =
                        device->dev.platform_data;
 
        pr_debug("%s - nop\n", __func__);
@@ -653,29 +431,32 @@ static int baseband_xmm_power2_driver_resume(struct platform_device *device)
 #endif
 
 static struct platform_driver baseband_power2_driver = {
-       .probe = baseband_xmm_power2_driver_probe,
-       .remove = baseband_xmm_power2_driver_remove,
+       .probe = xmm_power2_probe,
+       .remove = xmm_power2_remove,
 #ifdef CONFIG_PM
-       .suspend = baseband_xmm_power2_driver_suspend,
-       .resume = baseband_xmm_power2_driver_resume,
+       .suspend = xmm_power2_suspend,
+       .resume = xmm_power2_resume,
 #endif
        .driver = {
                .name = "baseband_xmm_power2",
        },
 };
 
-static int __init baseband_xmm_power2_init(void)
+static int __init xmm_power2_init(void)
 {
        pr_debug("%s\n", __func__);
 
        return platform_driver_register(&baseband_power2_driver);
 }
 
-static void __exit baseband_xmm_power2_exit(void)
+static void __exit xmm_power2_exit(void)
 {
        pr_debug("%s\n", __func__);
+
        platform_driver_unregister(&baseband_power2_driver);
 }
 
-module_init(baseband_xmm_power2_init)
-module_exit(baseband_xmm_power2_exit)
+module_init(xmm_power2_init)
+module_exit(xmm_power2_exit)
+
+MODULE_LICENSE("GPL");