diff options
Diffstat (limited to 'arch/arm/mach-tegra/baseband-xmm-power2.c')
-rw-r--r-- | arch/arm/mach-tegra/baseband-xmm-power2.c | 525 |
1 files changed, 153 insertions, 372 deletions
diff --git a/arch/arm/mach-tegra/baseband-xmm-power2.c b/arch/arm/mach-tegra/baseband-xmm-power2.c index 4295b3958202..3c6285c0a070 100644 --- a/arch/arm/mach-tegra/baseband-xmm-power2.c +++ b/arch/arm/mach-tegra/baseband-xmm-power2.c @@ -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"); |