summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorRaj Jayaraman <rjayaraman@nvidia.com>2012-02-13 14:12:04 -0800
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-03-12 08:23:53 -0700
commit527efd9d01dc6c14b9b3ed21ae2165e99cd19ae2 (patch)
treeea815e612d18463eaf22aad8ae7516d851381cb1 /drivers/misc
parentb880eb85f32ff21590cbc814bb060a02b21ebf54 (diff)
misc: tegra-baseband: Add support for L2 and cleanup code.
Bug 886459 Signed-off-by: Raj Jayaraman <rjayaraman@nvidia.com> (cherry picked from commit 9032b38a76d8337ee6b9582265171ca09473a3e9) Change-Id: Ifa5ad5bdb3a782119a2920281bc39ce5f6fd2a5a Reviewed-on: http://git-master/r/88868 Reviewed-by: Rajkumar Jayaraman <rjayaraman@nvidia.com> Tested-by: Rajkumar Jayaraman <rjayaraman@nvidia.com> Reviewed-by: Steve Lin <stlin@nvidia.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/tegra-baseband/bb-m7400.c46
-rw-r--r--drivers/misc/tegra-baseband/bb-power.h24
2 files changed, 63 insertions, 7 deletions
diff --git a/drivers/misc/tegra-baseband/bb-m7400.c b/drivers/misc/tegra-baseband/bb-m7400.c
index 4209151e5f39..5808a6e321cd 100644
--- a/drivers/misc/tegra-baseband/bb-m7400.c
+++ b/drivers/misc/tegra-baseband/bb-m7400.c
@@ -45,6 +45,7 @@ static struct tegra_bb_gpio_data m7400_gpios[] = {
{ { GPIO_INVALID, 0, NULL }, false }, /* End of table */
};
static bool ehci_registered;
+static int modem_status;
static int gpio_awr;
static int gpio_cwr;
static int gpio_arr;
@@ -83,8 +84,9 @@ static int m7400_apup_handshake(bool checkresponse)
{
int retval = 0;
- /* Signal AP ready - Drive AWR high. */
+ /* Signal AP ready - Drive AWR and ARR high. */
gpio_set_value(gpio_awr, 1);
+ gpio_set_value(gpio_arr, 1);
if (checkresponse) {
/* Wait for CP ack - by driving CWR high. */
@@ -106,41 +108,70 @@ static void m7400_apdown_handshake(void)
static int m7400_l2_suspend(void)
{
+ /* Gets called for two cases :
+ a) Port suspend.
+ b) Bus suspend. */
+ if (modem_status == BBSTATE_L2)
+ return 0;
+
/* Post bus suspend: Drive ARR low. */
gpio_set_value(gpio_arr, 0);
+ modem_status = BBSTATE_L2;
return 0;
}
static int m7400_l2_resume(void)
{
+ /* Gets called for two cases :
+ a) L2 resume.
+ b) bus resume phase of L3 resume. */
+ if (modem_status == BBSTATE_L0)
+ return 0;
+
/* Pre bus resume: Drive ARR high. */
gpio_set_value(gpio_arr, 1);
- /* Wait for CP ack - by driving CWR high. */
+ /* If host initiated resume - Wait for CP ack (CWR goes high). */
+ /* If device initiated resume - CWR will be already high. */
if (gpio_wait_timeout(gpio_cwr, 1, 10) != 0) {
pr_info("%s: Error: timeout waiting for modem ack.\n",
__func__);
return -1;
}
+ modem_status = BBSTATE_L0;
return 0;
}
static void m7400_l3_suspend(void)
{
m7400_apdown_handshake();
+ modem_status = BBSTATE_L3;
}
static void m7400_l3_resume(void)
{
m7400_apup_handshake(true);
+ modem_status = BBSTATE_L0;
}
static irqreturn_t m7400_wake_irq(int irq, void *dev_id)
{
- pr_info("%s called.\n", __func__);
-
- /* Resume usb host activity. */
- /* TBD */
+ struct usb_interface *intf;
+
+ switch (modem_status) {
+ case BBSTATE_L2:
+ /* Resume usb host activity. */
+ if (m7400_usb_device) {
+ usb_lock_device(m7400_usb_device);
+ intf = usb_ifnum_to_if(m7400_usb_device, 0);
+ usb_autopm_get_interface(intf);
+ usb_autopm_put_interface(intf);
+ usb_unlock_device(m7400_usb_device);
+ }
+ break;
+ default:
+ break;
+ }
return IRQ_HANDLED;
}
@@ -225,8 +256,8 @@ static int m7400_attrib_write(struct device *dev, int value)
static int m7400_registered(struct usb_device *udev)
{
- pr_info("%s called.\n", __func__);
m7400_usb_device = udev;
+ modem_status = BBSTATE_L0;
return 0;
}
@@ -285,6 +316,7 @@ static void *m7400_init(void *pdata)
}
ehci_registered = false;
+ modem_status = BBSTATE_UNKNOWN;
return (void *) &m7400_data;
}
diff --git a/drivers/misc/tegra-baseband/bb-power.h b/drivers/misc/tegra-baseband/bb-power.h
index 84f9e85994b1..cdd693802031 100644
--- a/drivers/misc/tegra-baseband/bb-power.h
+++ b/drivers/misc/tegra-baseband/bb-power.h
@@ -14,22 +14,41 @@
*
*/
+enum tegra_bb_state {
+ BBSTATE_UNKNOWN,
+ /* Baseband state L0 - Running */
+ BBSTATE_L0,
+ /* Baseband state L2 - Suspended */
+ BBSTATE_L2,
+ /* Baseband state L3 - Suspended and detached */
+ BBSTATE_L3,
+};
+
enum tegra_bb_pwrstate {
+ /* System power state - Entering suspend */
PWRSTATE_L2L3,
+ /* System power state - Resuming from suspend */
PWRSTATE_L3L0,
PWRSTATE_INVALID,
};
struct tegra_bb_gpio_data {
+ /* Baseband gpio data */
struct gpio data;
+ /* Baseband gpio - Should it be exported to sysfs ? */
bool doexport;
};
struct tegra_bb_gpio_irqdata {
+ /* Baseband gpio IRQ - Id */
int id;
+ /* Baseband gpio IRQ - Friendly name */
const char *name;
+ /* Baseband gpio IRQ - IRQ handler */
irq_handler_t handler;
+ /* Baseband gpio IRQ - IRQ trigger flags */
int flags;
+ /* Baseband gpio IRQ - Can the gpio wake system from sleep ? */
bool wake_capable;
void *cookie;
};
@@ -47,10 +66,15 @@ struct tegra_bb_power_gdata {
};
struct tegra_bb_power_mdata {
+ /* Baseband USB vendor ID */
int vid;
+ /* Baseband USB product ID */
int pid;
+ /* Baseband capability - Can it generate a wakeup ? */
bool wake_capable;
+ /* Baseband capability - Can it be auto/runtime suspended ? */
bool autosuspend_ready;
+ /* Baseband callback after a successful registration */
modem_register_cb reg_cb;
};