Merge "NFC: add hw reset before testing hw presence."
diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt
index e98ee05..32f6a24 100644
--- a/Documentation/devicetree/bindings/memory.txt
+++ b/Documentation/devicetree/bindings/memory.txt
@@ -36,6 +36,7 @@
reg = <(baseaddr) (size)>;
(linux,contiguous-region);
(linux,default-contiguous-region);
+ (linux,memory-limit);
label = (unique_name);
};
@@ -48,6 +49,11 @@
linux,default-contiguous-region: property indicating that the region
is the default region for all contiguous memory
allocations, Linux specific (optional)
+linux,memory-limit: property specifying an upper bound on the physical address
+ of the region if the region is placed dynamically. If no limit
+ is specificed, the region may be placed anywhere in the physical
+ address space. 0 may be used to specify lowmem (i.e. the region
+ will be placed in the direct mapped lowmem region)
label: an internal name used for automatically associating the
cma region with a given device. The label is optional;
if the label is not given the client is responsible for
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index e866286..394f4a9 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -22,6 +22,11 @@
/ {
model = "Qualcomm MSM 8926";
compatible = "qcom,msm8926";
+
+};
+
+&qsecom_mem {
+ linux,memory-limit = <0x0>;
};
&soc {
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 606383a..adac211 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -212,6 +212,7 @@
unsigned long len;
__be32 *prop;
char *name;
+ phys_addr_t limit = MEMBLOCK_ALLOC_ANYWHERE;
if (!of_get_flat_dt_prop(node, "linux,contiguous-region", NULL))
return 0;
@@ -225,9 +226,13 @@
name = of_get_flat_dt_prop(node, "label", NULL);
- pr_info("Found %s, memory base %lx, size %ld MiB\n", uname,
- (unsigned long)base, (unsigned long)size / SZ_1M);
- dma_contiguous_reserve_area(size, &base, MEMBLOCK_ALLOC_ANYWHERE, name);
+ prop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
+ if (prop)
+ limit = be32_to_cpu(prop[0]);
+
+ pr_info("Found %s, memory base %lx, size %ld MiB, limit %pa\n", uname,
+ (unsigned long)base, (unsigned long)size / SZ_1M, &limit);
+ dma_contiguous_reserve_area(size, &base, limit, name);
return 0;
}
diff --git a/drivers/nfc/nfc-nci.c b/drivers/nfc/nfc-nci.c
index 5ac93b6..9d8b780 100644
--- a/drivers/nfc/nfc-nci.c
+++ b/drivers/nfc/nfc-nci.c
@@ -728,7 +728,7 @@
int r = 0;
unsigned short slave_addr = 0xE;
unsigned short curr_addr;
-
+ unsigned char raw_nci_wake[] = {0x10, 0x0F};
unsigned char raw_chip_version_addr = 0x00;
unsigned char raw_chip_rev_id_addr = 0x9C;
unsigned char raw_chip_version = 0xFF;
@@ -738,9 +738,22 @@
platform_data = qca199x_dev->client->dev.platform_data;
+ /*
+ * Always wake up chip when reading 0x9C, otherwise this
+ * register is not updated
+ */
+ curr_addr = qca199x_dev->client->addr;
+ qca199x_dev->client->addr = slave_addr;
+ r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0],
+ sizeof(raw_nci_wake));
+ r = sizeof(raw_nci_wake);
+ if (r != sizeof(raw_nci_wake))
+ goto invalid_wake_up;
+ qca199x_dev->state = NFCC_STATE_NORMAL_WAKE;
+
+ /* sleep to ensure the NFCC has time to wake up */
+ usleep(100);
if (arg == 0) {
- curr_addr = qca199x_dev->client->addr;
- qca199x_dev->client->addr = slave_addr;
r = nfc_i2c_write(qca199x_dev->client,
&raw_chip_version_addr, 1);
if (r < 0)
@@ -749,10 +762,7 @@
r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1);
/* Restore original NFCC slave I2C address */
qca199x_dev->client->addr = curr_addr;
- }
- if (arg == 1) {
- curr_addr = qca199x_dev->client->addr;
- qca199x_dev->client->addr = slave_addr;
+ } else if (arg == 1) {
r = nfc_i2c_write(qca199x_dev->client,
&raw_chip_rev_id_addr, 1);
if (r < 0)
@@ -762,8 +772,9 @@
/* Restore original NFCC slave I2C address */
qca199x_dev->client->addr = curr_addr;
}
-
return raw_chip_version;
+invalid_wake_up:
+ raw_chip_version = 0xFE;
invalid_wr:
raw_chip_version = 0xFF;
dev_err(&qca199x_dev->client->dev,
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index bf294fc..6301724 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -650,24 +650,23 @@
return (batfet_closed_rt_sts & BAT_FET_ON_IRQ) ? 1 : 0;
}
-#define USB_VALID_BIT BIT(7)
static int
qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip)
{
- u8 usbin_valid_rt_sts;
+ u8 usb_chgpth_rt_sts;
int rc;
- rc = qpnp_chg_read(chip, &usbin_valid_rt_sts,
- chip->usb_chgpth_base + CHGR_STATUS , 1);
+ rc = qpnp_chg_read(chip, &usb_chgpth_rt_sts,
+ INT_RT_STS(chip->usb_chgpth_base), 1);
if (rc) {
pr_err("spmi read failed: addr=%03X, rc=%d\n",
- chip->usb_chgpth_base + CHGR_STATUS, rc);
+ INT_RT_STS(chip->usb_chgpth_base), rc);
return rc;
}
- pr_debug("chgr usb sts 0x%x\n", usbin_valid_rt_sts);
+ pr_debug("chgr usb sts 0x%x\n", usb_chgpth_rt_sts);
- return (usbin_valid_rt_sts & USB_VALID_BIT) ? 1 : 0;
+ return (usb_chgpth_rt_sts & USBIN_VALID_IRQ) ? 1 : 0;
}
static bool
@@ -686,10 +685,10 @@
return !!(buck_sts & IBAT_LOOP_IRQ);
}
-#define USB_VALID_MASK 0xC0
-#define USB_COARSE_DET 0x10
-#define USB_VALID_UVP_VALUE 0x00
-#define USB_VALID_OVP_VALUE 0x40
+#define USB_VALID_MASK 0xC0
+#define USB_VALID_IN_MASK BIT(7)
+#define USB_COARSE_DET 0x10
+#define USB_VALID_OVP_VALUE 0x40
static int
qpnp_chg_check_usb_coarse_det(struct qpnp_chg_chip *chip)
{
@@ -708,7 +707,8 @@
static int
qpnp_chg_check_usbin_health(struct qpnp_chg_chip *chip)
{
- u8 usbin_chg_rt_sts, usbin_health = 0;
+ u8 usbin_chg_rt_sts, usb_chgpth_rt_sts;
+ u8 usbin_health = 0;
int rc;
rc = qpnp_chg_read(chip, &usbin_chg_rt_sts,
@@ -720,13 +720,23 @@
return rc;
}
- pr_debug("chgr usb sts 0x%x\n", usbin_chg_rt_sts);
+ rc = qpnp_chg_read(chip, &usb_chgpth_rt_sts,
+ INT_RT_STS(chip->usb_chgpth_base) , 1);
+
+ if (rc) {
+ pr_err("spmi read failed: addr=%03X, rc=%d\n",
+ INT_RT_STS(chip->usb_chgpth_base), rc);
+ return rc;
+ }
+
+ pr_debug("chgr usb sts 0x%x, chgpth rt sts 0x%x\n",
+ usbin_chg_rt_sts, usb_chgpth_rt_sts);
if ((usbin_chg_rt_sts & USB_COARSE_DET) == USB_COARSE_DET) {
if ((usbin_chg_rt_sts & USB_VALID_MASK)
== USB_VALID_OVP_VALUE) {
usbin_health = USBIN_OVP;
pr_err("Over voltage charger inserted\n");
- } else if ((usbin_chg_rt_sts & USB_VALID_BIT) != 0) {
+ } else if ((usb_chgpth_rt_sts & USBIN_VALID_IRQ) != 0) {
usbin_health = USBIN_OK;
pr_debug("Valid charger inserted\n");
}
diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c
index 06749b9..fb97329 100644
--- a/drivers/rtc/alarm.c
+++ b/drivers/rtc/alarm.c
@@ -71,9 +71,11 @@
static bool suspended;
static long power_on_alarm;
+static void alarm_shutdown(struct platform_device *dev);
void set_power_on_alarm(long secs)
{
power_on_alarm = secs;
+ alarm_shutdown(NULL);
}
diff --git a/drivers/video/msm/mdss/mdss_dsi_status.c b/drivers/video/msm/mdss/mdss_dsi_status.c
index f0c4f4c..fd7f3fd 100644
--- a/drivers/video/msm/mdss/mdss_dsi_status.c
+++ b/drivers/video/msm/mdss/mdss_dsi_status.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -86,6 +86,15 @@
mutex_lock(ctl->shared_lock);
mutex_lock(&mdp5_data->ov_lock);
+ if (pdsi_status->mfd->shutdown_pending) {
+ mutex_unlock(&mdp5_data->ov_lock);
+ if (ctl->shared_lock)
+ mutex_unlock(ctl->shared_lock);
+ pr_err("%s: DSI turning off, avoiding BTA status check\n",
+ __func__);
+ return;
+ }
+
/*
* For the command mode panels, we return pan display
* IOCTL on vsync interrupt. So, after vsync interrupt comes
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index cfa594c..bc4e1dc 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1001,8 +1001,9 @@
writel_relaxed(1, offset + 16);
}
- mdata->nmax_concurrent_ad_hw = (mdata->mdp_rev <= MDSS_MDP_HW_REV_102) ?
- 1 : 2;
+ mdata->nmax_concurrent_ad_hw =
+ (mdata->mdp_rev < MDSS_MDP_HW_REV_103) ? 1 : 2;
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
pr_debug("MDP hw init done\n");
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index f3b7ce1..7dab8b2 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -543,7 +543,8 @@
struct mdss_mdp_pipe **left_plist, int left_cnt,
struct mdss_mdp_pipe **right_plist, int right_cnt);
int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe,
- struct mdss_mdp_perf_params *perf, struct mdss_mdp_img_rect *roi);
+ struct mdss_mdp_perf_params *perf, struct mdss_mdp_img_rect *roi,
+ bool apply_fudge);
int mdss_mdp_ctl_notify(struct mdss_mdp_ctl *ctl, int event);
void mdss_mdp_ctl_notifier_register(struct mdss_mdp_ctl *ctl,
struct notifier_block *notifier);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index fe42669..d807083 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -303,6 +303,7 @@
* @pipe: Source pipe struct containing updated pipe params
* @perf: Structure containing values that should be updated for
* performance tuning
+ * @apply_fudge: Boolean to determine if mdp clock fudge is applicable
*
* Function calculates the minimum required performance calculations in order
* to avoid MDP underflow. The calculations are based on the way MDP
@@ -310,7 +311,8 @@
* (MDP clock requirement) based on frame size and scaling requirements.
*/
int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe,
- struct mdss_mdp_perf_params *perf, struct mdss_mdp_img_rect *roi)
+ struct mdss_mdp_perf_params *perf, struct mdss_mdp_img_rect *roi,
+ bool apply_fudge)
{
struct mdss_mdp_mixer *mixer;
int fps = DEFAULT_FRAME_RATE;
@@ -384,7 +386,10 @@
perf->bw_overlap = (quota / dst.h) * v_total;
}
- perf->mdp_clk_rate = mdss_mdp_clk_fudge_factor(mixer, rate);
+ if (apply_fudge)
+ perf->mdp_clk_rate = mdss_mdp_clk_fudge_factor(mixer, rate);
+ else
+ perf->mdp_clk_rate = rate;
prefill_params.smp_bytes = mdss_mdp_smp_get_size(pipe);
prefill_params.xres = xres;
@@ -440,6 +445,8 @@
u64 bw_overlap[MDSS_MDP_MAX_STAGE] = { 0 };
u32 v_region[MDSS_MDP_MAX_STAGE * 2] = { 0 };
u32 prefill_bytes = 0;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ bool apply_fudge = true;
BUG_ON(num_pipes > MDSS_MDP_MAX_STAGE);
@@ -469,13 +476,36 @@
memset(bw_overlap, 0, sizeof(u64) * MDSS_MDP_MAX_STAGE);
memset(v_region, 0, sizeof(u32) * MDSS_MDP_MAX_STAGE * 2);
+ /*
+ * Apply this logic only for 8x26 to reduce clock rate
+ * for single video playback use case
+ */
+ if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_101)
+ && mixer->type == MDSS_MDP_MIXER_TYPE_INTF) {
+ u32 npipes = 0;
+ for (i = 0; i < MDSS_MDP_MAX_STAGE; i++) {
+ pipe = mixer->stage_pipe[i];
+ if (pipe) {
+ if (npipes) {
+ apply_fudge = true;
+ break;
+ }
+ npipes++;
+ apply_fudge = !(pipe->src_fmt->is_yuv)
+ || !(pipe->flags
+ & MDP_SOURCE_ROTATED_90);
+ }
+ }
+ }
+
for (i = 0; i < num_pipes; i++) {
struct mdss_mdp_perf_params tmp;
pipe = pipe_list[i];
if (pipe == NULL)
continue;
- if (mdss_mdp_perf_calc_pipe(pipe, &tmp, &mixer->roi))
+ if (mdss_mdp_perf_calc_pipe(pipe, &tmp, &mixer->roi,
+ apply_fudge))
continue;
prefill_bytes += tmp.prefill_bytes;
bw_overlap[i] = tmp.bw_overlap;
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index bff56d2..4b9ea20 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -21,10 +21,6 @@
#define ENHIST_LUT_ENTRIES 256
#define HIST_V_SIZE 256
-#define MDSS_MDP_HW_REV_100 0x10000000
-#define MDSS_MDP_HW_REV_102 0x10020000
-#define MDSS_MDP_HW_REV_103 0x10030000
-
#define MDSS_MDP_FETCH_CONFIG_RESET_VALUE 0x00000087
#define MDSS_REG_HW_VERSION 0x0
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 34cfe23..8acbd35 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -268,7 +268,7 @@
int rc;
for (;;) {
- rc = mdss_mdp_perf_calc_pipe(pipe, &perf, NULL);
+ rc = mdss_mdp_perf_calc_pipe(pipe, &perf, NULL, true);
if (!rc && (perf.mdp_clk_rate <= mdata->max_mdp_clk_rate))
break;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index e332368..3ec92e6 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -85,6 +85,30 @@
#define MDP_IMGTYPE2_START 0x10000
#define MSMFB_DRIVER_VERSION 0xF9E8D701
+/* HW Revisions for different MDSS targets */
+#define MDSS_GET_MAJOR(rev) ((rev) >> 28)
+#define MDSS_GET_MINOR(rev) (((rev) >> 16) & 0xFFF)
+#define MDSS_GET_STEP(rev) ((rev) & 0xFFFF)
+#define MDSS_GET_MAJOR_MINOR(rev) ((rev) >> 16)
+
+#define IS_MDSS_MAJOR_MINOR_SAME(rev1, rev2) \
+ (MDSS_GET_MAJOR_MINOR((rev1)) == MDSS_GET_MAJOR_MINOR((rev2)))
+
+#define MDSS_MDP_REV(major, minor, step) \
+ ((((major) & 0x000F) << 28) | \
+ (((minor) & 0x0FFF) << 16) | \
+ ((step) & 0xFFFF))
+
+#define MDSS_MDP_HW_REV_100 MDSS_MDP_REV(1, 0, 0) /* 8974 v1.0 */
+#define MDSS_MDP_HW_REV_101 MDSS_MDP_REV(1, 1, 0) /* 8x26 v1.0 */
+#define MDSS_MDP_HW_REV_101_1 MDSS_MDP_REV(1, 1, 1) /* 8x26 v2.0, 8926 v1.0 */
+#define MDSS_MDP_HW_REV_101_2 MDSS_MDP_REV(1, 1, 2) /* 8926 v2.0 */
+#define MDSS_MDP_HW_REV_102 MDSS_MDP_REV(1, 2, 0) /* 8974 v2.0 */
+#define MDSS_MDP_HW_REV_102_1 MDSS_MDP_REV(1, 2, 1) /* 8974 v3.0 (Pro) */
+#define MDSS_MDP_HW_REV_103 MDSS_MDP_REV(1, 3, 0) /* 8084 v1.0 */
+#define MDSS_MDP_HW_REV_103_1 MDSS_MDP_REV(1, 3, 1) /* 8084 v1.1 */
+#define MDSS_MDP_HW_REV_200 MDSS_MDP_REV(2, 0, 0) /* 8092 v1.0 */
+
enum {
NOTIFY_UPDATE_START,
NOTIFY_UPDATE_STOP,
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b28b7eb..c868a74 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3816,6 +3816,11 @@
struct lsm_network_audit net = {0,};
u32 tsid = task_sid(task);
+ if (unlikely(!sksec)) {
+ pr_warn("SELinux: sksec is NULL, socket is already freed\n");
+ return -EINVAL;
+ }
+
if (sksec->sid == SECINITSID_KERNEL)
return 0;