Merge "camera: Mercury hardware JPEG decoder driver support." into msm-3.0
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index d450ba2..67b5fa0 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -265,9 +265,6 @@
 	REGULATOR_SUPPLY("ext_ts_sw",		NULL),
 	REGULATOR_SUPPLY("vdd_ana",		"3-005b"),
 };
-VREG_CONSUMERS(FRC_5V) = {
-	REGULATOR_SUPPLY("frc_5v",	NULL),
-};
 VREG_CONSUMERS(AVC_1P2V) = {
 	REGULATOR_SUPPLY("avc_1p2v",	NULL),
 };
@@ -519,7 +516,6 @@
 
 struct gpio_regulator_platform_data
 mpq8064_gpio_regulator_pdata[] __devinitdata = {
-	GPIO_VREG(FRC_5V, "frc_5v", "frc_5v_en", SX150X_GPIO(4, 10), NULL),
 	GPIO_VREG(AVC_1P2V, "avc_1p2v", "avc_1p2v_en", SX150X_GPIO(4, 2), NULL),
 	GPIO_VREG(AVC_1P8V, "avc_1p8v", "avc_1p8v_en", SX150X_GPIO(4, 4), NULL),
 	GPIO_VREG(AVC_2P2V, "avc_2p2v", "avc_2p2v_en",
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 12d67a9..ee7eb23 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2245,16 +2245,6 @@
 };
 
 static struct platform_device
-mpq8064_device_ext_5v_frc_vreg __devinitdata = {
-	.name	= GPIO_REGULATOR_DEV_NAME,
-	.id	= SX150X_GPIO(4, 10),
-	.dev	= {
-		.platform_data =
-			&mpq8064_gpio_regulator_pdata[GPIO_VREG_ID_FRC_5V],
-	},
-};
-
-static struct platform_device
 mpq8064_device_ext_1p2_buck_vreg __devinitdata = {
 	.name	= GPIO_REGULATOR_DEV_NAME,
 	.id	= SX150X_GPIO(4, 2),
@@ -2343,7 +2333,6 @@
 	&msm_rotator_device,
 #endif
 	&gpio_ir_recv_pdev,
-	&mpq8064_device_ext_5v_frc_vreg,
 	&mpq8064_device_ext_1p2_buck_vreg,
 	&mpq8064_device_ext_1p8_buck_vreg,
 	&mpq8064_device_ext_2p2_buck_vreg,
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index c992865..7cef156 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -45,12 +45,11 @@
 #define GPIO_VREG_ID_EXT_TS_SW		2
 #define GPIO_VREG_ID_EXT_MPP8		3
 
-#define GPIO_VREG_ID_FRC_5V		0
-#define GPIO_VREG_ID_AVC_1P2V		1
-#define GPIO_VREG_ID_AVC_1P8V		2
-#define GPIO_VREG_ID_AVC_2P2V		3
-#define GPIO_VREG_ID_AVC_5V		4
-#define GPIO_VREG_ID_AVC_3P3V		5
+#define GPIO_VREG_ID_AVC_1P2V		0
+#define GPIO_VREG_ID_AVC_1P8V		1
+#define GPIO_VREG_ID_AVC_2P2V		2
+#define GPIO_VREG_ID_AVC_5V		3
+#define GPIO_VREG_ID_AVC_3P3V		4
 
 #define APQ8064_EXT_3P3V_REG_EN_GPIO	77
 
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index 3b52a9f..f7c651e 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -45,7 +45,7 @@
 #include "timer.h"
 
 #define DRV_NAME	"msm_dsps"
-#define DRV_VERSION	"4.00"
+#define DRV_VERSION	"4.01"
 
 #define PPSS_PAUSE_REG	0x1804
 
@@ -68,7 +68,6 @@
  *  @is_on - DSPS is on.
  *  @ref_count - open/close reference count.
  *  @wdog_irq - DSPS Watchdog IRQ
- *  @wd_crash - Watchdog ISR fired
  *  @crash_in_progress - 1 if crash recovery is in progress
  *  @ppss_base - ppss registers virtual base address.
  */
@@ -93,7 +92,6 @@
 	int ref_count;
 	int wdog_irq;
 
-	atomic_t wd_crash;
 	atomic_t crash_in_progress;
 	void __iomem *ppss_base;
 };
@@ -108,7 +106,7 @@
  */
 static int dsps_crash_shutdown_g;
 
-static void dsps_restart_handler(struct work_struct *work);
+static void dsps_restart_handler(void);
 
 /**
  *  Load DSPS Firmware.
@@ -378,7 +376,28 @@
 	return 0;
 }
 
-static DECLARE_WORK(dsps_fatal_work, dsps_restart_handler);
+/**
+ *
+ * Log subsystem restart failure reason
+ */
+static void dsps_log_sfr(void)
+{
+	const char dflt_reason[] = "Died too early due to unknown reason";
+	char *smem_reset_reason;
+	unsigned smem_reset_size;
+
+	smem_reset_reason = smem_get_entry(SMEM_SSR_REASON_DSPS0,
+		&smem_reset_size);
+	if (smem_reset_reason != NULL && smem_reset_reason[0] != 0) {
+		smem_reset_reason[smem_reset_size-1] = 0;
+		pr_err("%s: DSPS failure: %s\nResetting DSPS\n",
+			__func__, smem_reset_reason);
+		memset(smem_reset_reason, 0, smem_reset_size);
+		wmb();
+	} else
+		pr_err("%s: DSPS failure: %s\nResetting DSPS\n",
+			__func__, dflt_reason);
+}
 
 /**
  *  Watchdog interrupt handler
@@ -386,10 +405,9 @@
  */
 static irqreturn_t dsps_wdog_bite_irq(int irq, void *dev_id)
 {
-	pr_debug("%s\n", __func__);
-	atomic_set(&drv->wd_crash, 1);
-	(void)schedule_work(&dsps_fatal_work);
-	disable_irq_nosync(irq);
+	pr_err("%s\n", __func__);
+	dsps_log_sfr();
+	dsps_restart_handler();
 	return IRQ_HANDLED;
 }
 
@@ -425,7 +443,9 @@
 		ret = put_user(val, (u32 __user *) arg);
 		break;
 	case DSPS_IOCTL_RESET:
-		dsps_restart_handler(NULL);
+		pr_err("%s: User-initiated DSPS reset.\nResetting DSPS\n",
+		       __func__);
+		dsps_restart_handler();
 		ret = 0;
 		break;
 	default:
@@ -698,36 +718,10 @@
  *  Fatal error handler
  *  Resets DSPS.
  */
-static void dsps_restart_handler(struct work_struct *work)
+static void dsps_restart_handler(void)
 {
-	uint32_t dsps_state;
-	int restart_level;
-	char *smem_reset_reason;
-	unsigned smem_reset_size;
-	const char dflt_reason[] = "Died too early due to unknown reason";
-
-	dsps_state = smsm_get_state(SMSM_DSPS_STATE);
-	restart_level = get_restart_level();
-
-	pr_debug("%s: DSPS state 0x%x. Restart lvl %d\n",
-		__func__, dsps_state, restart_level);
-
-	if ((dsps_state & SMSM_RESET) ||
-	    (atomic_read(&drv->wd_crash) == 1)) {
-		smem_reset_reason = smem_get_entry(SMEM_SSR_REASON_DSPS0,
-			&smem_reset_size);
-		if (smem_reset_reason != NULL && smem_reset_reason[0] != 0) {
-			smem_reset_reason[smem_reset_size-1] = 0;
-			pr_err("%s: DSPS failure: %s\nResetting DSPS\n",
-				__func__, smem_reset_reason);
-			memset(smem_reset_reason, 0, smem_reset_size);
-			wmb();
-		} else
-			pr_err("%s: DSPS failure: %s\nResetting DSPS\n",
-				__func__, dflt_reason);
-	} else
-		pr_err("%s: User-initiated DSPS reset.\nResetting DSPS\n",
-		       __func__);
+	pr_debug("%s: Restart lvl %d\n",
+		__func__, get_restart_level());
 
 	if (atomic_add_return(1, &drv->crash_in_progress) > 1) {
 		pr_err("%s: DSPS already resetting. Count %d\n", __func__,
@@ -752,8 +746,10 @@
 		dsps_crash_shutdown_g = 0;
 		return;
 	}
-	if (new_state & SMSM_RESET)
-		dsps_restart_handler(NULL);
+	if (new_state & SMSM_RESET) {
+		dsps_log_sfr();
+		dsps_restart_handler();
+	}
 }
 
 /**
@@ -764,6 +760,7 @@
 static int dsps_shutdown(const struct subsys_data *subsys)
 {
 	pr_debug("%s\n", __func__);
+	disable_irq_nosync(drv->wdog_irq);
 	dsps_suspend();
 	pil_force_shutdown(drv->pdata->pil_name);
 	dsps_power_off_handler();
@@ -781,10 +778,7 @@
 	dsps_power_on_handler();
 	pil_force_boot(drv->pdata->pil_name);
 	atomic_set(&drv->crash_in_progress, 0);
-	if (atomic_read(&drv->wd_crash) > 0) {
-		atomic_set(&drv->wd_crash, 0);
-		enable_irq(drv->wdog_irq);
-	}
+	enable_irq(drv->wdog_irq);
 	dsps_resume();
 	return 0;
 }
@@ -866,7 +860,6 @@
 		pr_err("%s: kzalloc fail.\n", __func__);
 		goto alloc_err;
 	}
-	atomic_set(&drv->wd_crash, 0);
 	atomic_set(&drv->crash_in_progress, 0);
 
 	drv->pdata = pdev->dev.platform_data;