aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/baseband-xmm-power.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/baseband-xmm-power.c')
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.c1063
1 files changed, 1063 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c
new file mode 100644
index 00000000000..7d5c527cab8
--- /dev/null
+++ b/arch/arm/mach-tegra/baseband-xmm-power.c
@@ -0,0 +1,1063 @@
1/*
2 * arch/arm/mach-tegra/baseband-xmm-power.c
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/platform_device.h>
22#include <linux/gpio.h>
23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/fs.h>
28#include <linux/uaccess.h>
29#include <linux/wakelock.h>
30#include <linux/spinlock.h>
31#include <linux/usb.h>
32#include <linux/pm_runtime.h>
33#include <mach/usb_phy.h>
34#include "board.h"
35#include "devices.h"
36#include "gpio-names.h"
37#include "baseband-xmm-power.h"
38
39MODULE_LICENSE("GPL");
40
41unsigned long modem_ver = XMM_MODEM_VER_1130;
42EXPORT_SYMBOL(modem_ver);
43
44unsigned long modem_flash;
45EXPORT_SYMBOL(modem_flash);
46
47unsigned long modem_pm = 1;
48EXPORT_SYMBOL(modem_pm);
49
50unsigned long enum_delay_ms = 1000; /* ignored if !modem_flash */
51
52module_param(modem_ver, ulong, 0644);
53MODULE_PARM_DESC(modem_ver,
54 "baseband xmm power - modem software version");
55module_param(modem_flash, ulong, 0644);
56MODULE_PARM_DESC(modem_flash,
57 "baseband xmm power - modem flash (1 = flash, 0 = flashless)");
58module_param(modem_pm, ulong, 0644);
59MODULE_PARM_DESC(modem_pm,
60 "baseband xmm power - modem power management (1 = pm, 0 = no pm)");
61module_param(enum_delay_ms, ulong, 0644);
62MODULE_PARM_DESC(enum_delay_ms,
63 "baseband xmm power - delay in ms between modem on and enumeration");
64
65static struct usb_device_id xmm_pm_ids[] = {
66 { USB_DEVICE(VENDOR_ID, PRODUCT_ID),
67 .driver_info = 0 },
68 {}
69};
70
71
72static struct gpio tegra_baseband_gpios[] = {
73 { -1, GPIOF_OUT_INIT_LOW, "BB_RSTn" },
74 { -1, GPIOF_OUT_INIT_LOW, "BB_ON" },
75 { -1, GPIOF_OUT_INIT_LOW, "IPC_BB_WAKE" },
76 { -1, GPIOF_IN, "IPC_AP_WAKE" },
77 { -1, GPIOF_OUT_INIT_HIGH, "IPC_HSIC_ACTIVE" },
78 { -1, GPIOF_IN, "IPC_HSIC_SUS_REQ" },
79};
80
81static enum {
82 IPC_AP_WAKE_UNINIT,
83 IPC_AP_WAKE_IRQ_READY,
84 IPC_AP_WAKE_INIT1,
85 IPC_AP_WAKE_INIT2,
86 IPC_AP_WAKE_L,
87 IPC_AP_WAKE_H,
88} ipc_ap_wake_state;
89
90enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
91static struct workqueue_struct *workqueue;
92static struct work_struct init1_work;
93static struct work_struct init2_work;
94static struct work_struct L2_resume_work;
95static struct baseband_power_platform_data *baseband_power_driver_data;
96static bool register_hsic_device;
97static struct wake_lock wakelock;
98static struct usb_device *usbdev;
99static bool CP_initiated_L2toL0;
100static bool modem_power_on;
101static int power_onoff;
102static int reenable_autosuspend;
103static struct work_struct autopm_resume_work;
104static bool wakeup_pending;
105static bool modem_sleep_flag;
106static spinlock_t xmm_lock;
107static DEFINE_MUTEX(xmm_onoff_mutex);
108
109static void baseband_xmm_power_L2_resume(void);
110static int baseband_xmm_power_driver_handle_resume(
111 struct baseband_power_platform_data *data);
112
113static int baseband_modem_power_on(struct baseband_power_platform_data *data)
114{
115 /* set IPC_HSIC_ACTIVE active */
116 gpio_set_value(baseband_power_driver_data->
117 modem.xmm.ipc_hsic_active, 1);
118
119 /* wait 20 ms */
120 mdelay(20);
121
122 /* reset / power on sequence */
123 mdelay(40);
124 gpio_set_value(data->modem.xmm.bb_rst, 1);
125 mdelay(1);
126 gpio_set_value(data->modem.xmm.bb_on, 1);
127 udelay(40);
128 gpio_set_value(data->modem.xmm.bb_on, 0);
129
130 return 0;
131}
132
133static int baseband_xmm_power_on(struct platform_device *device)
134{
135 struct baseband_power_platform_data *data
136 = (struct baseband_power_platform_data *)
137 device->dev.platform_data;
138 int ret;
139
140 pr_debug("%s {\n", __func__);
141
142 /* check for platform data */
143 if (!data) {
144 pr_err("%s: !data\n", __func__);
145 return -EINVAL;
146 }
147 if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
148 return -EINVAL;
149
150 /* reset the state machine */
151 baseband_xmm_powerstate = BBXMM_PS_INIT;
152 modem_sleep_flag = false;
153
154 if (modem_ver < XMM_MODEM_VER_1130)
155 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
156 else
157 ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
158
159 pr_debug("%s wake_st(%d) modem version %d\n", __func__,
160 ipc_ap_wake_state, modem_ver);
161
162 /* register usb host controller */
163 if (!modem_flash) {
164 pr_debug("%s - %d\n", __func__, __LINE__);
165 /* register usb host controller only once */
166 if (register_hsic_device) {
167 pr_debug("%s: register usb host controller\n",
168 __func__);
169 modem_power_on = true;
170 if (data->hsic_register)
171 data->modem.xmm.hsic_device =
172 data->hsic_register();
173 else
174 pr_err("%s: hsic_register is missing\n",
175 __func__);
176 register_hsic_device = false;
177 } else {
178 /* register usb host controller */
179 if (data->hsic_register)
180 data->modem.xmm.hsic_device =
181 data->hsic_register();
182 /* turn on modem */
183 pr_debug("%s call baseband_modem_power_on\n", __func__);
184 baseband_modem_power_on(data);
185 }
186 }
187 ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
188 if (ret < 0)
189 pr_err("%s: enable_irq_wake error\n", __func__);
190
191 pr_debug("%s }\n", __func__);
192
193 return 0;
194}
195
196static int baseband_xmm_power_off(struct platform_device *device)
197{
198 struct baseband_power_platform_data *data;
199 int ret;
200 unsigned long flags;
201
202 pr_debug("%s {\n", __func__);
203
204 if (baseband_xmm_powerstate == BBXMM_PS_UNINIT)
205 return -EINVAL;
206 /* check for device / platform data */
207 if (!device) {
208 pr_err("%s: !device\n", __func__);
209 return -EINVAL;
210 }
211 data = (struct baseband_power_platform_data *)
212 device->dev.platform_data;
213 if (!data) {
214 pr_err("%s: !data\n", __func__);
215 return -EINVAL;
216 }
217
218 ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
219 ret = disable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
220 if (ret < 0)
221 pr_err("%s: disable_irq_wake error\n", __func__);
222
223 /* unregister usb host controller */
224 if (data->hsic_unregister)
225 data->hsic_unregister(data->modem.xmm.hsic_device);
226 else
227 pr_err("%s: hsic_unregister is missing\n", __func__);
228
229
230 /* set IPC_HSIC_ACTIVE low */
231 gpio_set_value(baseband_power_driver_data->
232 modem.xmm.ipc_hsic_active, 0);
233
234 /* wait 20 ms */
235 mdelay(20);
236
237 /* drive bb_rst low */
238 gpio_set_value(data->modem.xmm.bb_rst, 0);
239 mdelay(1);
240
241 spin_lock_irqsave(&xmm_lock, flags);
242 baseband_xmm_powerstate = BBXMM_PS_UNINIT;
243 wakeup_pending = false;
244 modem_sleep_flag = false;
245 spin_unlock_irqrestore(&xmm_lock, flags);
246 /* start registration process once again on xmm on */
247 register_hsic_device = true;
248 pr_debug("%s }\n", __func__);
249
250 return 0;
251}
252
253static ssize_t baseband_xmm_onoff(struct device *dev,
254 struct device_attribute *attr,
255 const char *buf, size_t count)
256{
257 int pwr;
258 int size;
259 struct platform_device *device = to_platform_device(dev);
260
261 mutex_lock(&xmm_onoff_mutex);
262
263 pr_debug("%s\n", __func__);
264
265 /* check input */
266 if (buf == NULL) {
267 pr_err("%s: buf NULL\n", __func__);
268 mutex_unlock(&xmm_onoff_mutex);
269 return -EINVAL;
270 }
271 pr_debug("%s: count=%d\n", __func__, count);
272
273 /* parse input */
274 size = sscanf(buf, "%d", &pwr);
275 if (size != 1) {
276 pr_err("%s: size=%d -EINVAL\n", __func__, size);
277 mutex_unlock(&xmm_onoff_mutex);
278 return -EINVAL;
279 }
280
281 if (power_onoff == pwr) {
282 pr_err("%s: Ignored, due to same CP power state(%d)\n",
283 __func__, power_onoff);
284 mutex_unlock(&xmm_onoff_mutex);
285 return -EINVAL;
286 }
287 power_onoff = pwr;
288 pr_debug("%s power_onoff=%d\n", __func__, power_onoff);
289
290 if (power_onoff == 0)
291 baseband_xmm_power_off(device);
292 else if (power_onoff == 1)
293 baseband_xmm_power_on(device);
294
295 mutex_unlock(&xmm_onoff_mutex);
296
297 return count;
298}
299
300static DEVICE_ATTR(xmm_onoff, S_IRUSR | S_IWUSR | S_IRGRP,
301 NULL, baseband_xmm_onoff);
302
303
304void baseband_xmm_set_power_status(unsigned int status)
305{
306 struct baseband_power_platform_data *data = baseband_power_driver_data;
307 int value = 0;
308 unsigned long flags;
309
310 pr_debug("%s\n", __func__);
311
312 if (baseband_xmm_powerstate == status)
313 return;
314
315 switch (status) {
316 case BBXMM_PS_L0:
317 if (modem_sleep_flag) {
318 pr_info("%s Resume from L3 without calling resume"
319 "function\n", __func__);
320 baseband_xmm_power_driver_handle_resume(data);
321 }
322 pr_info("L0\n");
323 value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
324 pr_debug("before L0 ipc_hsic_active=%d\n", value);
325 if (!value) {
326 pr_debug("before L0 gpio set ipc_hsic_active=1 ->\n");
327 gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
328 }
329 if (modem_power_on) {
330 modem_power_on = false;
331 baseband_modem_power_on(data);
332 }
333
334 if (!wake_lock_active(&wakelock))
335 wake_lock(&wakelock);
336
337 pr_debug("gpio host active high->\n");
338 break;
339 case BBXMM_PS_L2:
340 pr_info("L2\n");
341 wake_unlock(&wakelock);
342 modem_sleep_flag = true;
343 break;
344 case BBXMM_PS_L3:
345 if (baseband_xmm_powerstate == BBXMM_PS_L2TOL0) {
346 if (!data->modem.xmm.ipc_ap_wake) {
347 spin_lock_irqsave(&xmm_lock, flags);
348 wakeup_pending = true;
349 spin_unlock_irqrestore(&xmm_lock, flags);
350 pr_info("%s: L2 race condition-CP wakeup"
351 " pending\n", __func__);
352 }
353 }
354 pr_info("L3\n");
355 if (wake_lock_active(&wakelock)) {
356 pr_info("%s: releasing wakelock before L3\n",
357 __func__);
358 wake_unlock(&wakelock);
359 }
360 gpio_set_value(data->modem.xmm.ipc_hsic_active, 0);
361 pr_debug("gpio host active low->\n");
362 break;
363 case BBXMM_PS_L2TOL0:
364 /* do this only from L2 state */
365 if (baseband_xmm_powerstate == BBXMM_PS_L2) {
366 baseband_xmm_powerstate = status;
367 pr_debug("BB XMM POWER STATE = %d\n", status);
368 baseband_xmm_power_L2_resume();
369 }
370 default:
371 break;
372 }
373 baseband_xmm_powerstate = status;
374 pr_debug("BB XMM POWER STATE = %d\n", status);
375}
376EXPORT_SYMBOL_GPL(baseband_xmm_set_power_status);
377
378irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
379{
380 int value;
381
382 value = gpio_get_value(baseband_power_driver_data->
383 modem.xmm.ipc_ap_wake);
384
385 pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);
386
387 if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
388 pr_err("%s - spurious irq\n", __func__);
389 } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
390 if (!value) {
391 pr_debug("%s - IPC_AP_WAKE_INIT1"
392 " - got falling edge\n",
393 __func__);
394 /* go to IPC_AP_WAKE_INIT1 state */
395 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
396 /* queue work */
397 queue_work(workqueue, &init1_work);
398 } else {
399 pr_debug("%s - IPC_AP_WAKE_INIT1"
400 " - wait for falling edge\n",
401 __func__);
402 }
403 } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
404 if (!value) {
405 pr_debug("%s - IPC_AP_WAKE_INIT2"
406 " - wait for rising edge\n",
407 __func__);
408 } else {
409 pr_debug("%s - IPC_AP_WAKE_INIT2"
410 " - got rising edge\n",
411 __func__);
412 /* go to IPC_AP_WAKE_INIT2 state */
413 ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
414 /* queue work */
415 queue_work(workqueue, &init2_work);
416 }
417 } else {
418 if (!value) {
419 pr_debug("%s - falling\n", __func__);
420 /* [ver < 1130] gpio protocol falling edge */
421 if (modem_ver < XMM_MODEM_VER_1130) {
422 pr_debug("gpio host wakeup done <-\n");
423 value = gpio_get_value
424 (baseband_power_driver_data->
425 modem.xmm.ipc_bb_wake);
426 if (value) {
427 /* Clear the slave wakeup request */
428 gpio_set_value
429 (baseband_power_driver_data->
430 modem.xmm.ipc_bb_wake, 0);
431 pr_debug("gpio slave wakeup done ->\n");
432 }
433 }
434 /* [ver >= 1130] gpio protocol falling edge */
435 if (modem_ver >= XMM_MODEM_VER_1130) {
436 if (baseband_xmm_powerstate == BBXMM_PS_L2) {
437 CP_initiated_L2toL0 = true;
438 baseband_xmm_set_power_status
439 (BBXMM_PS_L2TOL0);
440 } else if (baseband_xmm_powerstate ==
441 BBXMM_PS_L3) {
442 spin_lock(&xmm_lock);
443 wakeup_pending = true;
444 spin_unlock(&xmm_lock);
445 pr_info("CP L3 -> L0\n");
446 }
447 }
448 /* save gpio state */
449 ipc_ap_wake_state = IPC_AP_WAKE_L;
450 } else {
451 pr_debug("%s - rising\n", __func__);
452 /* [ver >= 1130] gpio protocol rising edge */
453 if (modem_ver >= XMM_MODEM_VER_1130) {
454 pr_debug("gpio host wakeup done <-\n");
455 value = gpio_get_value
456 (baseband_power_driver_data->
457 modem.xmm.ipc_bb_wake);
458 if (value) {
459 /* Clear the slave wakeup request */
460 gpio_set_value
461 (baseband_power_driver_data->
462 modem.xmm.ipc_bb_wake, 0);
463 pr_debug("gpio slave wakeup done ->\n");
464 if (reenable_autosuspend && usbdev) {
465 reenable_autosuspend = false;
466 queue_work(workqueue,
467 &autopm_resume_work);
468 }
469 }
470 if ((baseband_xmm_powerstate ==
471 BBXMM_PS_L2TOL0) ||
472 (baseband_xmm_powerstate ==
473 BBXMM_PS_L3TOL0))
474 baseband_xmm_set_power_status(
475 BBXMM_PS_L0);
476 else
477 pr_info("%s:no state"
478 "change required\n", __func__);
479 }
480 /* save gpio state */
481 ipc_ap_wake_state = IPC_AP_WAKE_H;
482 }
483 }
484
485 return IRQ_HANDLED;
486}
487EXPORT_SYMBOL(baseband_xmm_power_ipc_ap_wake_irq);
488
489static void baseband_xmm_power_init1_work(struct work_struct *work)
490{
491 int value;
492
493 pr_debug("%s {\n", __func__);
494
495 /* check if IPC_HSIC_ACTIVE high */
496 value = gpio_get_value(baseband_power_driver_data->
497 modem.xmm.ipc_hsic_active);
498 if (value != 1) {
499 pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
500 return;
501 }
502
503 /* wait 100 ms */
504 mdelay(100);
505
506 /* set IPC_HSIC_ACTIVE low */
507 gpio_set_value(baseband_power_driver_data->
508 modem.xmm.ipc_hsic_active, 0);
509
510 /* wait 10 ms */
511 mdelay(10);
512
513 /* set IPC_HSIC_ACTIVE high */
514 gpio_set_value(baseband_power_driver_data->
515 modem.xmm.ipc_hsic_active, 1);
516
517 /* wait 20 ms */
518 mdelay(20);
519
520 pr_debug("%s }\n", __func__);
521}
522
523static void baseband_xmm_power_init2_work(struct work_struct *work)
524{
525 struct baseband_power_platform_data *data = baseband_power_driver_data;
526
527 pr_debug("%s\n", __func__);
528
529 /* check input */
530 if (!data)
531 return;
532
533 /* register usb host controller only once */
534 if (register_hsic_device) {
535 if (data->hsic_register)
536 data->modem.xmm.hsic_device = data->hsic_register();
537 else
538 pr_err("%s: hsic_register is missing\n", __func__);
539 register_hsic_device = false;
540 }
541
542}
543
544static void baseband_xmm_power_autopm_resume(struct work_struct *work)
545{
546 struct usb_interface *intf;
547
548 pr_debug("%s\n", __func__);
549 if (usbdev) {
550 usb_lock_device(usbdev);
551 intf = usb_ifnum_to_if(usbdev, 0);
552 usb_autopm_get_interface(intf);
553 usb_autopm_put_interface(intf);
554 usb_unlock_device(usbdev);
555 }
556}
557
558
559/* Do the work for AP/CP initiated L2->L0 */
560static void baseband_xmm_power_L2_resume(void)
561{
562 struct baseband_power_platform_data *data = baseband_power_driver_data;
563 int value;
564 int delay = 1000; /* maxmum delay in msec */
565
566 pr_debug("%s\n", __func__);
567
568 if (!baseband_power_driver_data)
569 return;
570
571 modem_sleep_flag = false;
572
573 if (CP_initiated_L2toL0) {
574 pr_info("CP L2->L0\n");
575 CP_initiated_L2toL0 = false;
576 queue_work(workqueue, &L2_resume_work);
577 } else {
578 /* set the slave wakeup request */
579 pr_info("AP L2->L0\n");
580 gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
581 pr_debug("waiting for host wakeup from CP...\n");
582 do {
583 mdelay(1);
584 value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
585 delay--;
586 } while ((value) && (delay));
587 if (delay)
588 pr_debug("gpio host wakeup low <-\n");
589 else
590 pr_info("!!AP L2->L0 Failed\n");
591 }
592}
593
594/* Do the work for CP initiated L2->L0 */
595static void baseband_xmm_power_L2_resume_work(struct work_struct *work)
596{
597 struct usb_interface *intf;
598
599 pr_debug("%s {\n", __func__);
600
601 if (!usbdev)
602 return;
603 usb_lock_device(usbdev);
604 intf = usb_ifnum_to_if(usbdev, 0);
605 if (usb_autopm_get_interface(intf) == 0)
606 usb_autopm_put_interface(intf);
607 usb_unlock_device(usbdev);
608
609 pr_debug("} %s\n", __func__);
610}
611
612static void baseband_xmm_power_reset_on(void)
613{
614 /* reset / power on sequence */
615 mdelay(40);
616 gpio_set_value(baseband_power_driver_data->modem.xmm.bb_rst, 1);
617 mdelay(1);
618 gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 1);
619 udelay(40);
620 gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 0);
621}
622
623static struct baseband_xmm_power_work_t *baseband_xmm_power_work;
624
625static void baseband_xmm_power_work_func(struct work_struct *work)
626{
627 struct baseband_xmm_power_work_t *bbxmm_work
628 = (struct baseband_xmm_power_work_t *) work;
629
630 pr_debug("%s\n", __func__);
631
632 switch (bbxmm_work->state) {
633 case BBXMM_WORK_UNINIT:
634 pr_debug("BBXMM_WORK_UNINIT\n");
635 break;
636 case BBXMM_WORK_INIT:
637 pr_debug("BBXMM_WORK_INIT\n");
638 /* go to next state */
639 bbxmm_work->state = (modem_flash && !modem_pm)
640 ? BBXMM_WORK_INIT_FLASH_STEP1
641 : (modem_flash && modem_pm)
642 ? BBXMM_WORK_INIT_FLASH_PM_STEP1
643 : (!modem_flash && modem_pm)
644 ? BBXMM_WORK_INIT_FLASHLESS_PM_STEP1
645 : BBXMM_WORK_UNINIT;
646 pr_debug("Go to next state %d\n", bbxmm_work->state);
647 queue_work(workqueue, work);
648 break;
649 case BBXMM_WORK_INIT_FLASH_STEP1:
650 pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
651 /* register usb host controller */
652 pr_debug("%s: register usb host controller\n", __func__);
653 if (baseband_power_driver_data->hsic_register)
654 baseband_power_driver_data->modem.xmm.hsic_device =
655 baseband_power_driver_data->hsic_register();
656 else
657 pr_err("%s: hsic_register is missing\n", __func__);
658 break;
659 case BBXMM_WORK_INIT_FLASH_PM_STEP1:
660 pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
661 /* [modem ver >= 1130] start with IPC_HSIC_ACTIVE low */
662 if (modem_ver >= XMM_MODEM_VER_1130) {
663 pr_debug("%s: ver > 1130:"
664 " ipc_hsic_active -> 0\n", __func__);
665 gpio_set_value(baseband_power_driver_data->
666 modem.xmm.ipc_hsic_active, 0);
667 }
668 /* reset / power on sequence */
669 baseband_xmm_power_reset_on();
670 /* set power status as on */
671 power_onoff = 1;
672 /* optional delay
673 * 0 = flashless
674 * ==> causes next step to enumerate modem boot rom
675 * (058b / 0041)
676 * some delay > boot rom timeout
677 * ==> causes next step to enumerate modem software
678 * (1519 / 0020)
679 * (requires modem to be flash version, not flashless
680 * version)
681 */
682 if (enum_delay_ms)
683 mdelay(enum_delay_ms);
684 /* register usb host controller */
685 pr_debug("%s: register usb host controller\n", __func__);
686 if (baseband_power_driver_data->hsic_register)
687 baseband_power_driver_data->modem.xmm.hsic_device =
688 baseband_power_driver_data->hsic_register();
689 else
690 pr_err("%s: hsic_register is missing\n", __func__);
691 /* go to next state */
692 bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
693 ? BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1
694 : BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1;
695 queue_work(workqueue, work);
696 pr_debug("Go to next state %d\n", bbxmm_work->state);
697 break;
698 case BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1:
699 pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1\n");
700 break;
701 case BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1:
702 pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1\n");
703 break;
704 case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
705 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
706 /* go to next state */
707 bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
708 ? BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ
709 : BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
710 queue_work(workqueue, work);
711 break;
712 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1:
713 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
714 break;
715 case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
716 pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
717 break;
718 default:
719 break;
720 }
721
722}
723
724static void baseband_xmm_device_add_handler(struct usb_device *udev)
725{
726 struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
727 const struct usb_device_id *id;
728
729 if (intf == NULL)
730 return;
731
732 id = usb_match_id(intf, xmm_pm_ids);
733
734 if (id) {
735 pr_debug("persist_enabled: %u\n", udev->persist_enabled);
736 pr_info("Add device %d <%s %s>\n", udev->devnum,
737 udev->manufacturer, udev->product);
738 usbdev = udev;
739 usb_enable_autosuspend(udev);
740 pr_info("enable autosuspend\n");
741 }
742}
743
744static void baseband_xmm_device_remove_handler(struct usb_device *udev)
745{
746 if (usbdev == udev) {
747 pr_info("Remove device %d <%s %s>\n", udev->devnum,
748 udev->manufacturer, udev->product);
749 usbdev = 0;
750 }
751
752}
753
754static int usb_xmm_notify(struct notifier_block *self, unsigned long action,
755 void *blob)
756{
757 switch (action) {
758 case USB_DEVICE_ADD:
759 baseband_xmm_device_add_handler(blob);
760 break;
761 case USB_DEVICE_REMOVE:
762 baseband_xmm_device_remove_handler(blob);
763 break;
764 }
765
766 return NOTIFY_OK;
767}
768
769
770static struct notifier_block usb_xmm_nb = {
771 .notifier_call = usb_xmm_notify,
772};
773
774static int baseband_xmm_power_driver_probe(struct platform_device *device)
775{
776 struct baseband_power_platform_data *data
777 = (struct baseband_power_platform_data *)
778 device->dev.platform_data;
779 struct device *dev = &device->dev;
780 unsigned long flags;
781 int err;
782
783 pr_debug("%s\n", __func__);
784 pr_debug("[XMM] enum_delay_ms=%ld\n", enum_delay_ms);
785
786 /* check for platform data */
787 if (!data)
788 return -ENODEV;
789
790 /* check if supported modem */
791 if (data->baseband_type != BASEBAND_XMM) {
792 pr_err("unsuppported modem\n");
793 return -ENODEV;
794 }
795
796 /* save platform data */
797 baseband_power_driver_data = data;
798
799 /* create device file */
800 err = device_create_file(dev, &dev_attr_xmm_onoff);
801 if (err < 0) {
802 pr_err("%s - device_create_file failed\n", __func__);
803 return -ENODEV;
804 }
805
806 /* init wake lock */
807 wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "baseband_xmm_power");
808
809 /* init spin lock */
810 spin_lock_init(&xmm_lock);
811 /* request baseband gpio(s) */
812 tegra_baseband_gpios[0].gpio = baseband_power_driver_data
813 ->modem.xmm.bb_rst;
814 tegra_baseband_gpios[1].gpio = baseband_power_driver_data
815 ->modem.xmm.bb_on;
816 tegra_baseband_gpios[2].gpio = baseband_power_driver_data
817 ->modem.xmm.ipc_bb_wake;
818 tegra_baseband_gpios[3].gpio = baseband_power_driver_data
819 ->modem.xmm.ipc_ap_wake;
820 tegra_baseband_gpios[4].gpio = baseband_power_driver_data
821 ->modem.xmm.ipc_hsic_active;
822 tegra_baseband_gpios[5].gpio = baseband_power_driver_data
823 ->modem.xmm.ipc_hsic_sus_req;
824 err = gpio_request_array(tegra_baseband_gpios,
825 ARRAY_SIZE(tegra_baseband_gpios));
826 if (err < 0) {
827 pr_err("%s - request gpio(s) failed\n", __func__);
828 return -ENODEV;
829 }
830
831 /* request baseband irq(s) */
832 if (modem_flash && modem_pm) {
833 pr_debug("%s: request_irq IPC_AP_WAKE_IRQ\n", __func__);
834 ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
835 err = request_threaded_irq(
836 gpio_to_irq(data->modem.xmm.ipc_ap_wake),
837 NULL,
838 baseband_xmm_power_ipc_ap_wake_irq,
839 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
840 "IPC_AP_WAKE_IRQ",
841 NULL);
842 if (err < 0) {
843 pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
844 __func__);
845 return err;
846 }
847 err = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
848 if (err < 0)
849 pr_err("%s: enable_irq_wake error\n", __func__);
850 ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
851 if (modem_ver >= XMM_MODEM_VER_1130) {
852 pr_debug("%s: ver > 1130: AP_WAKE_INIT1\n", __func__);
853 /* ver 1130 or later starts in INIT1 state */
854 ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
855 }
856 }
857
858 /* init work queue */
859 workqueue = create_singlethread_workqueue
860 ("baseband_xmm_power_workqueue");
861 if (!workqueue) {
862 pr_err("cannot create workqueue\n");
863 return -1;
864 }
865 baseband_xmm_power_work = (struct baseband_xmm_power_work_t *)
866 kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
867 if (!baseband_xmm_power_work) {
868 pr_err("cannot allocate baseband_xmm_power_work\n");
869 return -1;
870 }
871 INIT_WORK((struct work_struct *) baseband_xmm_power_work,
872 baseband_xmm_power_work_func);
873 baseband_xmm_power_work->state = BBXMM_WORK_INIT;
874 queue_work(workqueue,
875 (struct work_struct *) baseband_xmm_power_work);
876
877 /* init work objects */
878 INIT_WORK(&init1_work, baseband_xmm_power_init1_work);
879 INIT_WORK(&init2_work, baseband_xmm_power_init2_work);
880 INIT_WORK(&L2_resume_work, baseband_xmm_power_L2_resume_work);
881 INIT_WORK(&autopm_resume_work, baseband_xmm_power_autopm_resume);
882
883 /* init state variables */
884 register_hsic_device = true;
885 CP_initiated_L2toL0 = false;
886 spin_lock_irqsave(&xmm_lock, flags);
887 baseband_xmm_powerstate = BBXMM_PS_UNINIT;
888 wakeup_pending = false;
889 spin_unlock_irqrestore(&xmm_lock, flags);
890
891 usb_register_notify(&usb_xmm_nb);
892
893 pr_debug("%s }\n", __func__);
894 return 0;
895}
896
897static int baseband_xmm_power_driver_remove(struct platform_device *device)
898{
899 struct baseband_power_platform_data *data
900 = (struct baseband_power_platform_data *)
901 device->dev.platform_data;
902 struct device *dev = &device->dev;
903
904 pr_debug("%s\n", __func__);
905
906 /* check for platform data */
907 if (!data)
908 return 0;
909
910 usb_unregister_notify(&usb_xmm_nb);
911
912 /* free work structure */
913 kfree(baseband_xmm_power_work);
914 baseband_xmm_power_work = (struct baseband_xmm_power_work_t *) 0;
915
916 /* free baseband irq(s) */
917 if (modem_flash && modem_pm) {
918 free_irq(gpio_to_irq(baseband_power_driver_data
919 ->modem.xmm.ipc_ap_wake), NULL);
920 }
921
922 /* free baseband gpio(s) */
923 gpio_free_array(tegra_baseband_gpios,
924 ARRAY_SIZE(tegra_baseband_gpios));
925
926 /* destroy wake lock */
927 wake_lock_destroy(&wakelock);
928
929 /* delete device file */
930 device_remove_file(dev, &dev_attr_xmm_onoff);
931
932 /* unregister usb host controller */
933 if (data->hsic_unregister)
934 data->hsic_unregister(data->modem.xmm.hsic_device);
935 else
936 pr_err("%s: hsic_unregister is missing\n", __func__);
937
938 return 0;
939}
940
941static int baseband_xmm_power_driver_handle_resume(
942 struct baseband_power_platform_data *data)
943{
944 int value;
945 int delay = 1000; /* maxmum delay in msec */
946 unsigned long flags;
947
948 pr_debug("%s\n", __func__);
949 if (!data)
950 return 0;
951
952 /* check if modem is on */
953 if (power_onoff == 0) {
954 pr_debug("%s - flight mode - nop\n", __func__);
955 return 0;
956 }
957
958 modem_sleep_flag = false;
959
960 /* L3->L0 */
961 baseband_xmm_set_power_status(BBXMM_PS_L3TOL0);
962 value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
963 if (value) {
964 pr_info("AP L3 -> L0\n");
965 /* wake bb */
966 gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
967
968 pr_debug("waiting for host wakeup...\n");
969 do {
970 mdelay(1);
971 value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
972 delay--;
973 } while ((value) && (delay));
974 if (delay)
975 pr_debug("gpio host wakeup low <-\n");
976 } else {
977 pr_info("CP L3 -> L0\n");
978 spin_lock_irqsave(&xmm_lock, flags);
979 /* Clear wakeup pending flag */
980 wakeup_pending = false;
981 spin_unlock_irqrestore(&xmm_lock, flags);
982 }
983 reenable_autosuspend = true;
984
985 return 0;
986
987}
988
989#ifdef CONFIG_PM
990static int baseband_xmm_power_driver_suspend(struct device *dev)
991{
992 pr_debug("%s\n", __func__);
993 return 0;
994}
995
996static int baseband_xmm_power_driver_resume(struct device *dev)
997{
998 struct platform_device *pdev = to_platform_device(dev);
999 struct baseband_power_platform_data *data
1000 = (struct baseband_power_platform_data *)
1001 pdev->dev.platform_data;
1002
1003 pr_debug("%s\n", __func__);
1004 baseband_xmm_power_driver_handle_resume(data);
1005
1006 return 0;
1007}
1008
1009static int baseband_xmm_power_suspend_noirq(struct device *dev)
1010{
1011 unsigned long flags;
1012
1013 pr_debug("%s\n", __func__);
1014 spin_lock_irqsave(&xmm_lock, flags);
1015 if (wakeup_pending) {
1016 wakeup_pending = false;
1017 spin_unlock_irqrestore(&xmm_lock, flags);
1018 pr_info("%s:**Abort Suspend: reason CP WAKEUP**\n", __func__);
1019 return -EBUSY;
1020 }
1021 spin_unlock_irqrestore(&xmm_lock, flags);
1022 return 0;
1023}
1024
1025static int baseband_xmm_power_resume_noirq(struct device *dev)
1026{
1027 pr_debug("%s\n", __func__);
1028 return 0;
1029}
1030
1031static const struct dev_pm_ops baseband_xmm_power_dev_pm_ops = {
1032 .suspend_noirq = baseband_xmm_power_suspend_noirq,
1033 .resume_noirq = baseband_xmm_power_resume_noirq,
1034 .suspend = baseband_xmm_power_driver_suspend,
1035 .resume = baseband_xmm_power_driver_resume,
1036};
1037#endif
1038
1039static struct platform_driver baseband_power_driver = {
1040 .probe = baseband_xmm_power_driver_probe,
1041 .remove = baseband_xmm_power_driver_remove,
1042 .driver = {
1043 .name = "baseband_xmm_power",
1044#ifdef CONFIG_PM
1045 .pm = &baseband_xmm_power_dev_pm_ops,
1046#endif
1047 },
1048};
1049
1050static int __init baseband_xmm_power_init(void)
1051{
1052 pr_debug("%s\n", __func__);
1053 return platform_driver_register(&baseband_power_driver);
1054}
1055
1056static void __exit baseband_xmm_power_exit(void)
1057{
1058 pr_debug("%s\n", __func__);
1059 platform_driver_unregister(&baseband_power_driver);
1060}
1061
1062module_init(baseband_xmm_power_init)
1063module_exit(baseband_xmm_power_exit)