Merge "msm: camera: Convert CSIPHY into platform device" into msm-3.0
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index be98991..ce15b0d 100755
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -336,6 +336,7 @@
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_QUALCOMM=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_QCOM_DIAG_BRIDGE=y
CONFIG_USB_QCOM_DUN_BRIDGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
diff --git a/arch/arm/mach-msm/board-apq8064-regulator.c b/arch/arm/mach-msm/board-apq8064-regulator.c
index f8984f8..8448600 100644
--- a/arch/arm/mach-msm/board-apq8064-regulator.c
+++ b/arch/arm/mach-msm/board-apq8064-regulator.c
@@ -158,6 +158,12 @@
VREG_CONSUMERS(NCP) = {
REGULATOR_SUPPLY("8921_ncp", NULL),
};
+VREG_CONSUMERS(8821_S0) = {
+ REGULATOR_SUPPLY("8821_s0", NULL),
+};
+VREG_CONSUMERS(8821_S1) = {
+ REGULATOR_SUPPLY("8821_s1", NULL),
+};
#define PM8921_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
_pull_down, _always_on, _supply_regulator, \
@@ -262,11 +268,17 @@
}
/* SAW regulator constraints */
-struct regulator_init_data msm8064_saw_regulator_pdata_s5 =
+struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(S5, "8921_s5", 1050000, 1150000);
-struct regulator_init_data msm8064_saw_regulator_pdata_s6 =
- SAW_VREG_INIT(S6, "8921_s6", 1050000, 1150000);
+ SAW_VREG_INIT(S5, "8921_s5", 950000, 1150000);
+struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6 =
+ SAW_VREG_INIT(S6, "8921_s6", 950000, 1150000);
+
+struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0 =
+ /* ID vreg_name min_uV max_uV */
+ SAW_VREG_INIT(8821_S0, "8821_s0", 950000, 1150000);
+struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1 =
+ SAW_VREG_INIT(8821_S1, "8821_s1", 950000, 1150000);
/* PM8921 regulator constraints */
struct pm8921_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index 153fce8..5ae388f 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -481,6 +481,38 @@
}
}
+static struct platform_device msm8064_device_saw_regulator_core0 = {
+ .name = "saw-regulator",
+ .id = 0,
+ .dev = {
+ .platform_data = &msm8064_saw_regulator_pdata_8921_s5,
+ },
+};
+
+static struct platform_device msm8064_device_saw_regulator_core1 = {
+ .name = "saw-regulator",
+ .id = 1,
+ .dev = {
+ .platform_data = &msm8064_saw_regulator_pdata_8921_s6,
+ },
+};
+
+static struct platform_device msm8064_device_saw_regulator_core2 = {
+ .name = "saw-regulator",
+ .id = 2,
+ .dev = {
+ .platform_data = &msm8064_saw_regulator_pdata_8821_s0,
+ },
+};
+
+static struct platform_device msm8064_device_saw_regulator_core3 = {
+ .name = "saw-regulator",
+ .id = 3,
+ .dev = {
+ .platform_data = &msm8064_saw_regulator_pdata_8821_s1,
+ },
+};
+
static struct platform_device *common_devices[] __initdata = {
&apq8064_device_dmov,
&apq8064_device_qup_i2c_gsbi4,
@@ -496,6 +528,10 @@
&android_pmem_adsp_device,
&android_pmem_audio_device,
&msm8064_device_watchdog,
+ &msm8064_device_saw_regulator_core0,
+ &msm8064_device_saw_regulator_core1,
+ &msm8064_device_saw_regulator_core2,
+ &msm8064_device_saw_regulator_core3,
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-apq8064.h b/arch/arm/mach-msm/board-apq8064.h
index 1d2109a..0928a58 100644
--- a/arch/arm/mach-msm/board-apq8064.h
+++ b/arch/arm/mach-msm/board-apq8064.h
@@ -32,6 +32,11 @@
extern int msm8064_pm8921_regulator_pdata_len __devinitdata;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1;
+
struct mmc_platform_data;
int __init apq8064_add_sdcc(unsigned int controller,
struct mmc_platform_data *plat);
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 38c9e85..1745f26 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -42,7 +42,7 @@
#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
#define NUM_STAT_OUTPUT_BUFFERS 3
#define NUM_AF_STAT_OUTPUT_BUFFERS 3
-#define max_control_command_size 260
+#define max_control_command_size 512
#define CROP_LEN 36
enum vfe_mode_of_operation{
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index 962371b..53128ad 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -198,8 +198,8 @@
return NULL;
}
- strncpy(rd_dev->name, "ramdump_", 256);
- strncat(rd_dev->name, dev_name, 256);
+ snprintf(rd_dev->name, ARRAY_SIZE(rd_dev->name), "ramdump_%s",
+ dev_name);
init_completion(&rd_dev->ramdump_complete);
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index ff699e2..54607d0 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -252,6 +252,8 @@
goto out;
r_log = kmalloc(sizeof(struct restart_log), GFP_KERNEL);
+ if (!r_log)
+ goto out;
r_log->subsys = subsys;
do_gettimeofday(&r_log->time);
curr_time = &r_log->time;
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 77f9c79..118bbb3 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -443,6 +443,9 @@
smd_close(hs.event_channel);
smd_close(hs.data_channel);
+ if (wake_lock_active(&hs.wake_lock_rx))
+ wake_unlock(&hs.wake_lock_rx);
+
/*Destroy the timer used to monitor the Rx queue for emptiness */
del_timer_sync(&hs.rx_q_timer);
tasklet_kill(&hs.hci_event_task);
diff --git a/drivers/hwmon/pm8xxx-adc-scale.c b/drivers/hwmon/pm8xxx-adc-scale.c
index 40ade69..7b27f72 100644
--- a/drivers/hwmon/pm8xxx-adc-scale.c
+++ b/drivers/hwmon/pm8xxx-adc-scale.c
@@ -34,81 +34,89 @@
};
static const struct pm8xxx_adc_map_pt adcmap_btm_threshold[] = {
- {-30, 41001},
- {-20, 40017},
- {-10, 38721},
- {0, 37186},
- {10, 35554},
- {11, 35392},
- {12, 35230},
- {13, 35070},
- {14, 34910},
- {15, 34751},
- {16, 34594},
- {17, 34438},
- {18, 34284},
- {19, 34131},
- {20, 33980},
- {21, 33830},
- {22, 33683},
- {23, 33538},
- {24, 33394},
- {25, 33253},
- {26, 33114},
- {27, 32977},
- {28, 32842},
- {29, 32710},
- {30, 32580},
- {31, 32452},
- {32, 32327},
- {33, 32204},
- {34, 32084},
- {35, 31966},
- {36, 31850},
- {37, 31737},
- {38, 31627},
- {39, 31518},
- {40, 31412},
- {41, 31309},
- {42, 31208},
- {43, 31109},
- {44, 31013},
- {45, 30918},
- {46, 30827},
- {47, 30737},
- {48, 30649},
- {49, 30564},
- {50, 30481},
- {51, 30400},
- {52, 30321},
- {53, 30244},
- {54, 30169},
- {55, 30096},
- {56, 30025},
- {57, 29956},
- {58, 29889},
- {59, 29823},
- {60, 29759},
- {61, 29697},
- {62, 29637},
- {63, 29578},
- {64, 29521},
- {65, 29465},
- {66, 29411},
- {67, 29359},
- {68, 29308},
- {69, 29258},
- {70, 29209},
- {71, 29162},
- {72, 29117},
- {73, 29072},
- {74, 29029},
- {75, 28987},
- {76, 28946},
- {77, 28906},
- {78, 28868},
- {79, 28830},
- {80, 28794}
+ {-30, 1642},
+ {-20, 1544},
+ {-10, 1414},
+ {0, 1260},
+ {1, 1244},
+ {2, 1228},
+ {3, 1212},
+ {4, 1195},
+ {5, 1179},
+ {6, 1162},
+ {7, 1146},
+ {8, 1129},
+ {9, 1113},
+ {10, 1097},
+ {11, 1080},
+ {12, 1064},
+ {13, 1048},
+ {14, 1032},
+ {15, 1016},
+ {16, 1000},
+ {17, 985},
+ {18, 969},
+ {19, 954},
+ {20, 939},
+ {21, 924},
+ {22, 909},
+ {23, 894},
+ {24, 880},
+ {25, 866},
+ {26, 852},
+ {27, 838},
+ {28, 824},
+ {29, 811},
+ {30, 798},
+ {31, 785},
+ {32, 773},
+ {33, 760},
+ {34, 748},
+ {35, 736},
+ {36, 725},
+ {37, 713},
+ {38, 702},
+ {39, 691},
+ {40, 681},
+ {41, 670},
+ {42, 660},
+ {43, 650},
+ {44, 640},
+ {45, 631},
+ {46, 622},
+ {47, 613},
+ {48, 604},
+ {49, 595},
+ {50, 587},
+ {51, 579},
+ {52, 571},
+ {53, 563},
+ {54, 556},
+ {55, 548},
+ {56, 541},
+ {57, 534},
+ {58, 527},
+ {59, 521},
+ {60, 514},
+ {61, 508},
+ {62, 502},
+ {63, 496},
+ {64, 490},
+ {65, 485},
+ {66, 281},
+ {67, 274},
+ {68, 267},
+ {69, 260},
+ {70, 254},
+ {71, 247},
+ {72, 241},
+ {73, 235},
+ {74, 229},
+ {75, 224},
+ {76, 218},
+ {77, 213},
+ {78, 208},
+ {79, 203}
};
static const struct pm8xxx_adc_map_pt adcmap_pa_therm[] = {
@@ -597,7 +605,9 @@
}
EXPORT_SYMBOL_GPL(pm8xxx_adc_tdkntcg_therm);
-int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *btm_param)
+int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *btm_param,
+ const struct pm8xxx_adc_properties *adc_properties,
+ const struct pm8xxx_adc_chan_properties *chan_properties)
{
int rc;
@@ -606,14 +616,29 @@
ARRAY_SIZE(adcmap_btm_threshold),
btm_param->low_thr_temp,
&btm_param->low_thr_voltage);
+ if (rc)
+ return rc;
- if (!rc) {
- rc = pm8xxx_adc_map_linear(
- adcmap_btm_threshold,
- ARRAY_SIZE(adcmap_btm_threshold),
- btm_param->high_thr_temp,
- &btm_param->high_thr_voltage);
- }
+ btm_param->low_thr_voltage *=
+ chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
+ do_div(btm_param->low_thr_voltage, adc_properties->adc_vdd_reference);
+ btm_param->low_thr_voltage +=
+ chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
+
+ rc = pm8xxx_adc_map_linear(
+ adcmap_btm_threshold,
+ ARRAY_SIZE(adcmap_btm_threshold),
+ btm_param->high_thr_temp,
+ &btm_param->high_thr_voltage);
+ if (rc)
+ return rc;
+
+ btm_param->high_thr_voltage *=
+ chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
+ do_div(btm_param->high_thr_voltage, adc_properties->adc_vdd_reference);
+ btm_param->high_thr_voltage +=
+ chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
+
return rc;
}
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 152eb40..5da80d9 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -121,6 +121,7 @@
#define PM8XXX_ADC_PA_THERM_VREG_UV_MIN 1800000
#define PM8XXX_ADC_PA_THERM_VREG_UV_MAX 1800000
#define PM8XXX_ADC_PA_THERM_VREG_UA_LOAD 100000
+#define PM8XXX_ADC_HWMON_NAME_LENGTH 32
struct pm8xxx_adc {
struct device *dev;
@@ -654,6 +655,10 @@
(calib_read_1 - calib_read_2);
adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dx =
adc_pmic->adc_prop->adc_vdd_reference;
+ adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].adc_vref =
+ calib_read_1;
+ adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd =
+ calib_read_2;
calib_fail:
rc = pm8xxx_adc_arb_cntrl(0, CHANNEL_NONE);
if (rc < 0) {
@@ -694,11 +699,12 @@
if (channel < PM8XXX_CHANNEL_MPP_SCALE1_IDX) {
mpp_scale = PREMUX_MPP_SCALE_0;
adc_pmic->conv->amux_channel = channel;
- } else if (channel >= PM8XXX_CHANNEL_MPP_SCALE1_IDX) {
+ } else if (channel >= PM8XXX_CHANNEL_MPP_SCALE1_IDX &&
+ channel < PM8XXX_CHANNEL_MPP_SCALE3_IDX) {
mpp_scale = PREMUX_MPP_SCALE_1;
adc_pmic->conv->amux_channel = channel %
PM8XXX_CHANNEL_MPP_SCALE1_IDX;
- } else if (channel >= PM8XXX_CHANNEL_MPP_SCALE3_IDX) {
+ } else {
mpp_scale = PREMUX_MPP_SCALE_1_DIV3;
adc_pmic->conv->amux_channel = channel %
PM8XXX_CHANNEL_MPP_SCALE3_IDX;
@@ -830,7 +836,8 @@
return -EINVAL;
}
- rc = pm8xxx_adc_batt_scaler(btm_param);
+ rc = pm8xxx_adc_batt_scaler(btm_param, adc_pmic->adc_prop,
+ adc_pmic->conv->chan_prop);
if (rc < 0) {
pr_err("Failed to lookup the BTM thresholds\n");
return rc;
@@ -1014,9 +1021,8 @@
if (rc)
return 0;
- return snprintf(buf, sizeof(struct pm8xxx_adc_chan_result),
- "Result:%lld Raw:%d\n",
- result.physical, result.adc_code);
+ return snprintf(buf, PM8XXX_ADC_HWMON_NAME_LENGTH,
+ "Result:%lld Raw:%d\n", result.physical, result.adc_code);
}
static int get_adc(void *data, u64 *val)
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 4b4d235..8ef0de9 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -774,11 +774,21 @@
}
if (!pb->count) {
/* Deallocation. free buf_offset array */
- D("%s freeing buffer offsets array ", __func__);
+ D("%s Inst %p freeing buffer offsets array",
+ __func__, pcam_inst);
for (j = 0 ; j < pcam_inst->buf_count ; j++)
kfree(pcam_inst->buf_offset[j]);
kfree(pcam_inst->buf_offset);
+ pcam_inst->buf_offset = NULL;
+ /* If the userspace has deallocated all the
+ * buffers, then release the vb2 queue */
+ if (pcam_inst->vbqueue_initialized) {
+ vb2_queue_release(&pcam_inst->vid_bufq);
+ pcam_inst->vbqueue_initialized = 0;
+ }
} else {
+ D("%s Inst %p Allocating buf_offset array",
+ __func__, pcam_inst);
/* Allocation. allocate buf_offset array */
pcam_inst->buf_offset = (struct msm_cam_buf_offset **)
kzalloc(pb->count * sizeof(struct msm_cam_buf_offset *),
@@ -796,6 +806,7 @@
for (j = i-1 ; j >= 0; j--)
kfree(pcam_inst->buf_offset[j]);
kfree(pcam_inst->buf_offset);
+ pcam_inst->buf_offset = NULL;
return -ENOMEM;
}
}
@@ -828,7 +839,18 @@
D("%s Inst = %p\n", __func__, pcam_inst);
WARN_ON(pctx != f->private_data);
+
+ if (!pcam_inst->buf_offset) {
+ pr_err("%s Buffer is already released. Returning. ", __func__);
+ return -EINVAL;
+ }
+
if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ /* Reject the buffer if planes array was not allocated */
+ if (pb->m.planes == NULL) {
+ pr_err("%s Planes array is null ", __func__);
+ return -EINVAL;
+ }
for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
D("%s stored offsets for plane %d as"
"addr offset %d, data offset %d",
@@ -1093,7 +1115,7 @@
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
- D("%s\n", __func__);
+ D("%s Inst %p\n", __func__, pcam_inst);
WARN_ON(pctx != f->private_data);
if (!pcam_inst->vbqueue_initialized) {
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index f7e5479..aed70bc 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -100,7 +100,7 @@
buf_type = (vb->num_planes == 1) ? VIDEOBUF2_SINGLE_PLANE
: VIDEOBUF2_MULTIPLE_PLANES;
if (buf_type == VIDEOBUF2_SINGLE_PLANE) {
- offset.sp_off.y_off = 0;
+ offset.sp_off.y_off = pcam_inst->plane_info.sp_y_offset;
offset.sp_off.cbcr_off =
pcam_inst->plane_info.plane[0].offset;
}
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 439cefe..ce6a016 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -16,14 +16,13 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/mfd/pm8xxx/core.h>
#include <linux/mfd/pm8xxx/misc.h>
/* PON CTRL 1 register */
-#define REG_PM8058_PON_CTRL_1 0x01C
-#define REG_PM8921_PON_CTRL_1 0x01C
-#define REG_PM8018_PON_CTRL_1 0x01C
+#define REG_PM8XXX_PON_CTRL_1 0x01C
#define PON_CTRL_1_PULL_UP_MASK 0xE0
#define PON_CTRL_1_USB_PWR_EN 0x10
@@ -83,6 +82,10 @@
#define SLEEP_CTRL_SMPL_EN_RESET 0x04
#define SLEEP_CTRL_SMPL_EN_PWR_OFF 0x00
+#define SLEEP_CTRL_SMPL_SEL_MASK 0x03
+#define SLEEP_CTRL_SMPL_SEL_MIN 0
+#define SLEEP_CTRL_SMPL_SEL_MAX 3
+
/* FTS regulator PMR registers */
#define REG_PM8901_REGULATOR_S1_PMR 0xA7
#define REG_PM8901_REGULATOR_S2_PMR 0xA8
@@ -92,6 +95,13 @@
#define PM8901_REGULATOR_PMR_STATE_MASK 0x60
#define PM8901_REGULATOR_PMR_STATE_OFF 0x20
+/* COINCELL CHG registers */
+#define REG_PM8058_COIN_CHG 0x02F
+#define REG_PM8921_COIN_CHG 0x09C
+#define REG_PM8018_COIN_CHG 0x09C
+
+#define COINCELL_RESISTOR_SHIFT 0x2
+
/* GPIO UART MUX CTRL registers */
#define REG_PM8XXX_GPIO_MUX_CTRL 0x1CC
@@ -103,6 +113,7 @@
struct pm8xxx_misc_platform_data pdata;
struct device *dev;
enum pm8xxx_version version;
+ u64 osc_halt_count;
};
static LIST_HEAD(pm8xxx_misc_chips);
@@ -294,7 +305,7 @@
* Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
* USB charging is enabled.
*/
- rc = pm8xxx_misc_masked_write(chip, REG_PM8018_PON_CTRL_1,
+ rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
| PON_CTRL_1_WD_EN_MASK,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -351,7 +362,7 @@
* Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
* USB charging is enabled.
*/
- rc = pm8xxx_misc_masked_write(chip, REG_PM8058_PON_CTRL_1,
+ rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
| PON_CTRL_1_WD_EN_MASK,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -411,7 +422,7 @@
* Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
* USB charging is enabled.
*/
- rc = pm8xxx_misc_masked_write(chip, REG_PM8921_PON_CTRL_1,
+ rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
| PON_CTRL_1_WD_EN_MASK,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -472,6 +483,262 @@
EXPORT_SYMBOL_GPL(pm8xxx_reset_pwr_off);
/**
+ * pm8xxx_smpl_control - enables/disables SMPL detection
+ * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
+ *
+ * This function enables or disables the Sudden Momentary Power Loss detection
+ * module. If SMPL detection is enabled, then when a sufficiently long power
+ * loss event occurs, the PMIC will automatically reset itself. If SMPL
+ * detection is disabled, then the PMIC will shutdown when power loss occurs.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_control(int enable)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ int rc = 0;
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8018:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8018_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
+ (enable ? SLEEP_CTRL_SMPL_EN_PWR_OFF
+ : SLEEP_CTRL_SMPL_EN_PWR_OFF));
+ break;
+ case PM8XXX_VERSION_8058:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8058_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
+ (enable ? SLEEP_CTRL_SMPL_EN_RESET
+ : SLEEP_CTRL_SMPL_EN_PWR_OFF));
+ break;
+ case PM8XXX_VERSION_8921:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
+ (enable ? SLEEP_CTRL_SMPL_EN_PWR_OFF
+ : SLEEP_CTRL_SMPL_EN_PWR_OFF));
+ break;
+ default:
+ /* PMIC doesn't have reset_pwr_off; do nothing. */
+ break;
+ }
+ if (rc) {
+ pr_err("setting smpl control failed, rc=%d\n", rc);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_smpl_control);
+
+
+/**
+ * pm8xxx_smpl_set_delay - sets the SMPL detection time delay
+ * @delay: enum value corresponding to delay time
+ *
+ * This function sets the time delay of the SMPL detection module. If power
+ * is reapplied within this interval, then the PMIC reset automatically. The
+ * SMPL detection module must be enabled for this delay time to take effect.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ int rc = 0;
+
+ if (delay < SLEEP_CTRL_SMPL_SEL_MIN
+ || delay > SLEEP_CTRL_SMPL_SEL_MAX) {
+ pr_err("%s: invalid delay specified: %d\n", __func__, delay);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8018:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8018_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
+ delay);
+ break;
+ case PM8XXX_VERSION_8058:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8058_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
+ delay);
+ break;
+ case PM8XXX_VERSION_8921:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
+ delay);
+ break;
+ default:
+ /* PMIC doesn't have reset_pwr_off; do nothing. */
+ break;
+ }
+ if (rc) {
+ pr_err("setting smpl delay failed, rc=%d\n", rc);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_smpl_set_delay);
+
+/**
+ * pm8xxx_coincell_chg_config - Disables or enables the coincell charger, and
+ * configures its voltage and resistor settings.
+ * @chg_config: Holds both voltage and resistor values, and a
+ * switch to change the state of charger.
+ * If state is to disable the charger then
+ * both voltage and resistor are disregarded.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_coincell_chg_config(struct pm8xxx_coincell_chg *chg_config)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ u8 reg = 0, voltage, resistor;
+ int rc = 0;
+
+ if (chg_config == NULL) {
+ pr_err("chg_config is NULL\n");
+ return -EINVAL;
+ }
+
+ voltage = chg_config->voltage;
+ resistor = chg_config->resistor;
+
+ if (resistor < PM8XXX_COINCELL_RESISTOR_2100_OHMS ||
+ resistor > PM8XXX_COINCELL_RESISTOR_800_OHMS) {
+ pr_err("Invalid resistor value provided\n");
+ return -EINVAL;
+ }
+
+ if (voltage < PM8XXX_COINCELL_VOLTAGE_3p2V ||
+ (voltage > PM8XXX_COINCELL_VOLTAGE_3p0V &&
+ voltage != PM8XXX_COINCELL_VOLTAGE_2p5V)) {
+ pr_err("Invalid voltage value provided\n");
+ return -EINVAL;
+ }
+
+ if (chg_config->state == PM8XXX_COINCELL_CHG_DISABLE) {
+ reg = 0;
+ } else {
+ reg |= voltage;
+ reg |= (resistor << COINCELL_RESISTOR_SHIFT);
+ }
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8018:
+ rc = pm8xxx_writeb(chip->dev->parent,
+ REG_PM8018_COIN_CHG, reg);
+ break;
+ case PM8XXX_VERSION_8058:
+ rc = pm8xxx_writeb(chip->dev->parent,
+ REG_PM8058_COIN_CHG, reg);
+ break;
+ case PM8XXX_VERSION_8921:
+ rc = pm8xxx_writeb(chip->dev->parent,
+ REG_PM8921_COIN_CHG, reg);
+ break;
+ default:
+ /* PMIC doesn't have reset_pwr_off; do nothing. */
+ break;
+ }
+ if (rc) {
+ pr_err("coincell chg. config failed, rc=%d\n", rc);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_coincell_chg_config);
+
+/**
+ * pm8xxx_watchdog_reset_control - enables/disables watchdog reset detection
+ * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
+ *
+ * This function enables or disables the PMIC watchdog reset detection feature.
+ * If watchdog reset detection is enabled, then the PMIC will reset itself
+ * when PS_HOLD goes low. If it is not enabled, then the PMIC will shutdown
+ * when PS_HOLD goes low.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_watchdog_reset_control(int enable)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ int rc = 0;
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8018:
+ case PM8XXX_VERSION_8058:
+ case PM8XXX_VERSION_8921:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8XXX_PON_CTRL_1, PON_CTRL_1_WD_EN_MASK,
+ (enable ? PON_CTRL_1_WD_EN_RESET
+ : PON_CTRL_1_WD_EN_PWR_OFF));
+ break;
+ default:
+ /* WD reset control not supported */
+ break;
+ }
+ if (rc) {
+ pr_err("setting WD reset control failed, rc=%d\n", rc);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_watchdog_reset_control);
+
+/* Handle the OSC_HALT interrupt: 32 kHz XTAL oscillator has stopped. */
+static irqreturn_t pm8xxx_osc_halt_isr(int irq, void *data)
+{
+ struct pm8xxx_misc_chip *chip = data;
+ u64 count = 0;
+
+ if (chip) {
+ chip->osc_halt_count++;
+ count = chip->osc_halt_count;
+ }
+
+ pr_crit("%s: OSC_HALT interrupt has triggered, 32 kHz XTAL oscillator"
+ " has halted (%llu)!\n", __func__, count);
+
+ return IRQ_HANDLED;
+}
+
+/**
* pm8xxx_uart_gpio_mux_ctrl - Mux configuration to select the UART
*
* @uart_path_sel: Input argument to select either UART1/2/3
@@ -519,7 +786,7 @@
struct pm8xxx_misc_chip *sibling;
struct list_head *prev;
unsigned long flags;
- int rc = 0;
+ int rc = 0, irq;
if (!pdata) {
pr_err("missing platform data\n");
@@ -537,6 +804,18 @@
chip->version = pm8xxx_get_version(chip->dev->parent);
memcpy(&(chip->pdata), pdata, sizeof(struct pm8xxx_misc_platform_data));
+ irq = platform_get_irq_byname(pdev, "pm8xxx_osc_halt_irq");
+ if (irq > 0) {
+ rc = request_any_context_irq(irq, pm8xxx_osc_halt_isr,
+ IRQF_TRIGGER_RISING | IRQF_DISABLED,
+ "pm8xxx_osc_halt_irq", chip);
+ if (rc < 0) {
+ pr_err("%s: request_any_context_irq(%d) FAIL: %d\n",
+ __func__, irq, rc);
+ goto fail_irq;
+ }
+ }
+
/* Insert PMICs in priority order (lowest value first). */
spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
prev = &pm8xxx_misc_chips;
@@ -552,12 +831,20 @@
platform_set_drvdata(pdev, chip);
return rc;
+
+fail_irq:
+ platform_set_drvdata(pdev, NULL);
+ kfree(chip);
+ return rc;
}
static int __devexit pm8xxx_misc_remove(struct platform_device *pdev)
{
struct pm8xxx_misc_chip *chip = platform_get_drvdata(pdev);
unsigned long flags;
+ int irq = platform_get_irq_byname(pdev, "pm8xxx_osc_halt_irq");
+ if (irq > 0)
+ free_irq(irq, chip);
spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
list_del(&chip->link);
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index e617aa5..3b3758e 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -374,8 +374,11 @@
if (!p->device_up) {
r = msm_bam_dmux_open(p->ch_id, dev, bam_notify);
- if (r < 0)
+ if (r < 0) {
+ DBG0("%s: ch=%d failed with rc %d\n",
+ __func__, p->ch_id, r);
return -ENODEV;
+ }
}
p->device_up = DEVICE_ACTIVE;
@@ -688,8 +691,10 @@
dev = alloc_netdev(sizeof(struct rmnet_private),
"rmnet%d", rmnet_setup);
- if (!dev)
+ if (!dev) {
+ pr_err("%s: no memory for netdev %d\n", __func__, n);
return -ENOMEM;
+ }
netdevs[n] = dev;
d = &(dev->dev);
@@ -707,6 +712,8 @@
ret = register_netdev(dev);
if (ret) {
+ pr_err("%s: unable to register netdev"
+ " %d rc=%d\n", __func__, n, ret);
free_netdev(dev);
return ret;
}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3a5af71..d16fcda 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -74,7 +74,7 @@
#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */
#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */
-#define USB_PHY_VDD_DIG_VOL_MIN 945000 /* uV */
+#define USB_PHY_VDD_DIG_VOL_MIN 1045000 /* uV */
#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
static struct msm_otg *the_msm_otg;
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index 2374d11..2bd2850 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -35,6 +35,38 @@
UART_TX3_RX3,
};
+enum pm8xxx_coincell_chg_voltage {
+ PM8XXX_COINCELL_VOLTAGE_3p2V = 1,
+ PM8XXX_COINCELL_VOLTAGE_3p1V,
+ PM8XXX_COINCELL_VOLTAGE_3p0V,
+ PM8XXX_COINCELL_VOLTAGE_2p5V = 16
+};
+
+enum pm8xxx_coincell_chg_resistor {
+ PM8XXX_COINCELL_RESISTOR_2100_OHMS,
+ PM8XXX_COINCELL_RESISTOR_1700_OHMS,
+ PM8XXX_COINCELL_RESISTOR_1200_OHMS,
+ PM8XXX_COINCELL_RESISTOR_800_OHMS
+};
+
+enum pm8xxx_coincell_chg_state {
+ PM8XXX_COINCELL_CHG_DISABLE,
+ PM8XXX_COINCELL_CHG_ENABLE
+};
+
+struct pm8xxx_coincell_chg {
+ enum pm8xxx_coincell_chg_state state;
+ enum pm8xxx_coincell_chg_voltage voltage;
+ enum pm8xxx_coincell_chg_resistor resistor;
+};
+
+enum pm8xxx_smpl_delay {
+ PM8XXX_SMPL_DELAY_0p5,
+ PM8XXX_SMPL_DELAY_1p0,
+ PM8XXX_SMPL_DELAY_1p5,
+ PM8XXX_SMPL_DELAY_2p0,
+};
+
#if defined(CONFIG_MFD_PM8XXX_MISC) || defined(CONFIG_MFD_PM8XXX_MISC_MODULE)
/**
@@ -48,18 +80,84 @@
int pm8xxx_uart_gpio_mux_ctrl(enum pm8xxx_uart_path_sel uart_path_sel);
+/**
+ * pm8xxx_coincell_chg_config - Disables or enables the coincell charger, and
+ * configures its voltage and resistor settings.
+ * @chg_config: Holds both voltage and resistor values, and a
+ * switch to change the state of charger.
+ * If state is to disable the charger then
+ * both voltage and resistor are disregarded.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_coincell_chg_config(struct pm8xxx_coincell_chg *chg_config);
+
+/**
+ * pm8xxx_smpl_control - enables/disables SMPL detection
+ * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
+ *
+ * This function enables or disables the Sudden Momentary Power Loss detection
+ * module. If SMPL detection is enabled, then when a sufficiently long power
+ * loss event occurs, the PMIC will automatically reset itself. If SMPL
+ * detection is disabled, then the PMIC will shutdown when power loss occurs.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_control(int enable);
+
+/**
+ * pm8xxx_smpl_set_delay - sets the SMPL detection time delay
+ * @delay: enum value corresponding to delay time
+ *
+ * This function sets the time delay of the SMPL detection module. If power
+ * is reapplied within this interval, then the PMIC reset automatically. The
+ * SMPL detection module must be enabled for this delay time to take effect.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay);
+
+/**
+ * pm8xxx_watchdog_reset_control - enables/disables watchdog reset detection
+ * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
+ *
+ * This function enables or disables the PMIC watchdog reset detection feature.
+ * If watchdog reset detection is enabled, then the PMIC will reset itself
+ * when PS_HOLD goes low. If it is not enabled, then the PMIC will shutdown
+ * when PS_HOLD goes low.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_watchdog_reset_control(int enable);
+
#else
static inline int pm8xxx_reset_pwr_off(int reset)
{
return -ENODEV;
}
-
static inline int
pm8xxx_uart_gpio_mux_ctrl(enum pm8xxx_uart_path_sel uart_path_sel)
{
return -ENODEV;
}
+static inline int
+pm8xxx_coincell_chg_config(struct pm8xxx_coincell_chg *chg_config)
+{
+ return -ENODEV;
+}
+static inline int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay)
+{
+ return -ENODEV;
+}
+static inline int pm8xxx_smpl_control(int enable)
+{
+ return -ENODEV;
+}
+static inline int pm8xxx_watchdog_reset_control(int enable)
+{
+ return -ENODEV;
+}
#endif
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index aa642cc..ba4b29c 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -221,6 +221,8 @@
* @offset: Offset with respect to the actual curve
* @dy: Numerator slope to calculate the gain
* @dx: Denominator slope to calculate the gain
+ * @adc_vref: A/D word of the voltage reference used for the channel
+ * @adc_gnd: A/D word of the ground reference used for the channel
*
* Each ADC device has different offset and gain parameters which are computed
* to calibrate the device.
@@ -229,6 +231,8 @@
int32_t offset;
int32_t dy;
int32_t dx;
+ int32_t adc_vref;
+ int32_t adc_gnd;
};
/**
@@ -453,8 +457,8 @@
* levels once the thresholds are reached
*/
struct pm8xxx_adc_arb_btm_param {
- uint32_t low_thr_temp;
- uint32_t high_thr_temp;
+ int32_t low_thr_temp;
+ int32_t high_thr_temp;
uint64_t low_thr_voltage;
uint64_t high_thr_voltage;
int32_t interval;
@@ -462,8 +466,9 @@
void (*btm_cool_fn) (bool);
};
-int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *);
-
+int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *,
+ const struct pm8xxx_adc_properties *adc_prop,
+ const struct pm8xxx_adc_chan_properties *chan_prop);
/**
* struct pm8xxx_adc_platform_data - PM8XXX ADC platform data
* @adc_prop: ADC specific parameters, voltage and channel setup
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index fa19613..384c3ca 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1094,6 +1094,7 @@
uint32_t ext_mode;
uint8_t num_planes;
struct plane_data plane[MAX_PLANES];
+ uint32_t sp_y_offset;
uint8_t vpe_can_use;
};