Merge changes I2119ba25,I9186b135 into msm-3.4
* changes:
defconfig: msm8974: Enable TSENS
thermal: tsens8974: Support calibrationless sensors
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 66e71fc..795a5a7 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -285,6 +285,8 @@
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
CONFIG_INPUT_UINPUT=y
+CONFIG_STM_LIS3DH=y
+CONFIG_INPUT_MPU3050=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_N_SMUX=y
CONFIG_N_SMUX_LOOPBACK=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 3731845..4674584 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -289,6 +289,8 @@
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
CONFIG_INPUT_UINPUT=y
+CONFIG_STM_LIS3DH=y
+CONFIG_INPUT_MPU3050=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_N_SMUX=y
CONFIG_N_SMUX_LOOPBACK=y
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index fa204c3..62e1521 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -450,6 +450,7 @@
device->state == KGSL_STATE_ACTIVE &&
device->requested_state == KGSL_STATE_NONE) {
kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
+ kgsl_pwrscale_idle(device, 1);
if (kgsl_pwrctrl_sleep(device) != 0)
mod_timer(&device->idle_timer,
jiffies +
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index fbf3bb4..bfe6957 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -640,7 +640,7 @@
mutex_lock(&device->mutex);
if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
- kgsl_pwrscale_idle(device);
+ kgsl_pwrscale_idle(device, 0);
if (kgsl_pwrctrl_sleep(device) != 0) {
mod_timer(&device->idle_timer,
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 6fb9326..f6277b3 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -237,21 +237,18 @@
void kgsl_pwrscale_busy(struct kgsl_device *device)
{
if (PWRSCALE_ACTIVE(device) && device->pwrscale.policy->busy)
- if ((!device->pwrscale.gpu_busy) &&
- (device->requested_state != KGSL_STATE_SLUMBER))
+ if (device->requested_state != KGSL_STATE_SLUMBER)
device->pwrscale.policy->busy(device,
&device->pwrscale);
- device->pwrscale.gpu_busy = 1;
}
-void kgsl_pwrscale_idle(struct kgsl_device *device)
+void kgsl_pwrscale_idle(struct kgsl_device *device, unsigned int ignore_idle)
{
if (PWRSCALE_ACTIVE(device) && device->pwrscale.policy->idle)
if (device->requested_state != KGSL_STATE_SLUMBER &&
device->requested_state != KGSL_STATE_SLEEP)
device->pwrscale.policy->idle(device,
- &device->pwrscale);
- device->pwrscale.gpu_busy = 0;
+ &device->pwrscale, ignore_idle);
}
EXPORT_SYMBOL(kgsl_pwrscale_idle);
diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h
index 34698cd..ba9b1af 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.h
+++ b/drivers/gpu/msm/kgsl_pwrscale.h
@@ -23,7 +23,8 @@
void (*close)(struct kgsl_device *device,
struct kgsl_pwrscale *pwrscale);
void (*idle)(struct kgsl_device *device,
- struct kgsl_pwrscale *pwrscale);
+ struct kgsl_pwrscale *pwrscale,
+ unsigned int ignore_idle);
void (*busy)(struct kgsl_device *device,
struct kgsl_pwrscale *pwrscale);
void (*sleep)(struct kgsl_device *device,
@@ -36,7 +37,6 @@
struct kgsl_pwrscale_policy *policy;
struct kobject kobj;
void *priv;
- int gpu_busy;
int enabled;
};
@@ -64,7 +64,8 @@
struct kgsl_pwrscale_policy *policy);
void kgsl_pwrscale_detach_policy(struct kgsl_device *device);
-void kgsl_pwrscale_idle(struct kgsl_device *device);
+void kgsl_pwrscale_idle(struct kgsl_device *device,
+ unsigned int ignore_idle);
void kgsl_pwrscale_busy(struct kgsl_device *device);
void kgsl_pwrscale_sleep(struct kgsl_device *device);
void kgsl_pwrscale_wake(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
index 4102302..fc58dd1 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
@@ -131,7 +131,7 @@
}
static void idlestats_idle(struct kgsl_device *device,
- struct kgsl_pwrscale *pwrscale)
+ struct kgsl_pwrscale *pwrscale, unsigned int ignore_idle)
{
int i, nr_cpu;
struct idlestats_priv *priv = pwrscale->priv;
diff --git a/drivers/gpu/msm/kgsl_pwrscale_msm.c b/drivers/gpu/msm/kgsl_pwrscale_msm.c
index 61d4b2d..baa0407 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_msm.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_msm.c
@@ -26,6 +26,7 @@
struct msm_dcvs_idle idle_source;
struct msm_dcvs_freq freq_sink;
struct msm_dcvs_core_info *core_info;
+ int gpu_busy;
};
static int msm_idle_enable(struct msm_dcvs_idle *self,
@@ -89,29 +90,37 @@
struct kgsl_pwrscale *pwrscale)
{
struct msm_priv *priv = pwrscale->priv;
- if (priv->enabled)
+ if (priv->enabled && !priv->gpu_busy) {
msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_EXIT, 0);
+ priv->gpu_busy = 1;
+ }
return;
}
static void msm_idle(struct kgsl_device *device,
- struct kgsl_pwrscale *pwrscale)
+ struct kgsl_pwrscale *pwrscale, unsigned int ignore_idle)
{
struct msm_priv *priv = pwrscale->priv;
- unsigned int rb_rptr, rb_wptr;
- kgsl_regread(device, REG_CP_RB_RPTR, &rb_rptr);
- kgsl_regread(device, REG_CP_RB_WPTR, &rb_wptr);
- if (priv->enabled && (rb_rptr == rb_wptr))
- msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_ENTER, 0);
-
+ if (priv->enabled && priv->gpu_busy)
+ if (device->ftbl->isidle(device)) {
+ msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_ENTER, 0);
+ priv->gpu_busy = 0;
+ }
return;
}
static void msm_sleep(struct kgsl_device *device,
struct kgsl_pwrscale *pwrscale)
{
- /* do we need to reset any parameters here? */
+ struct msm_priv *priv = pwrscale->priv;
+
+ if (priv->enabled && priv->gpu_busy) {
+ msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_ENTER, 0);
+ priv->gpu_busy = 0;
+ }
+
+ return;
}
static int msm_init(struct kgsl_device *device,
@@ -159,10 +168,10 @@
ret = msm_dcvs_freq_sink_register(&priv->freq_sink);
if (ret >= 0) {
if (device->ftbl->isidle(device)) {
- device->pwrscale.gpu_busy = 0;
+ priv->gpu_busy = 0;
msm_dcvs_idle(priv->handle, MSM_DCVS_IDLE_ENTER, 0);
} else {
- device->pwrscale.gpu_busy = 1;
+ priv->gpu_busy = 1;
}
return 0;
}
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index d6c5e66..1b029b1 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -119,16 +119,19 @@
device->pwrctrl.default_pwrlevel);
}
-static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
+static void tz_idle(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale,
+ unsigned int ignore_idle)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
struct tz_priv *priv = pwrscale->priv;
struct kgsl_power_stats stats;
int val, idle;
+ if (ignore_idle)
+ return;
+
/* In "performance" mode the clock speed always stays
the same */
-
if (priv->governor == TZ_GOVERNOR_PERFORMANCE)
return;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 790cc10..df71f76 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -685,6 +685,52 @@
}
}
+void dvb_dmx_swfilter_section_packets(struct dvb_demux *demux, const u8 *buf,
+ size_t count)
+{
+ struct dvb_demux_feed *feed;
+ u16 pid = ts_pid(buf);
+ struct timespec pre_time;
+
+ if (dvb_demux_performancecheck)
+ pre_time = current_kernel_time();
+
+ spin_lock(&demux->lock);
+
+ demux->sw_filter_abort = 0;
+
+ while (count--) {
+ if (buf[0] != 0x47) {
+ buf += 188;
+ continue;
+ }
+
+ if (demux->playback_mode == DMX_PB_MODE_PULL)
+ if (dvb_dmx_swfilter_buffer_check(demux, pid) < 0)
+ break;
+
+ list_for_each_entry(feed, &demux->feed_list, list_head) {
+ if (feed->pid != pid)
+ continue;
+
+ if (!feed->feed.sec.is_filtering)
+ continue;
+
+ if (dvb_dmx_swfilter_section_packet(feed, buf) < 0) {
+ feed->feed.sec.seclen = 0;
+ feed->feed.sec.secbufp = 0;
+ }
+ }
+ buf += 188;
+ }
+
+ spin_unlock(&demux->lock);
+
+ if (dvb_demux_performancecheck)
+ demux->total_process_time += dvb_dmx_calc_time_delta(pre_time);
+}
+EXPORT_SYMBOL(dvb_dmx_swfilter_section_packets);
+
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count)
{
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index a663191..5a32363 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -179,6 +179,8 @@
int dvb_dmx_init(struct dvb_demux *dvbdemux);
void dvb_dmx_release(struct dvb_demux *dvbdemux);
+void dvb_dmx_swfilter_section_packets(struct dvb_demux *demux, const u8 *buf,
+ size_t count);
void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
size_t count);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 23cb03d..b22e2f0 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2385,8 +2385,10 @@
struct msm_mmc_reg_data *vreg_table[2];
curr_slot = host->plat->vreg_data;
- if (!curr_slot)
+ if (!curr_slot) {
+ rc = -EINVAL;
goto out;
+ }
vreg_table[0] = curr_slot->vdd_data;
vreg_table[1] = curr_slot->vdd_io_data;
@@ -3988,6 +3990,51 @@
return rc;
}
+/*
+ * Work around of the unavailability of a power_reset functionality in SD cards
+ * by turning the OFF & back ON the regulators supplying the SD card.
+ */
+void msmsdcc_hw_reset(struct mmc_host *mmc)
+{
+ struct mmc_card *card = mmc->card;
+ struct msmsdcc_host *host = mmc_priv(mmc);
+ int rc;
+
+ /* Write-protection bits would be lost on a hardware reset in emmc */
+ if (!card || !mmc_card_sd(card))
+ return;
+
+ /*
+ * Continuing on failing to disable regulator would lead to a panic
+ * anyway, since the commands would fail and console would be flooded
+ * with prints, eventually leading to a watchdog bark
+ */
+ rc = msmsdcc_setup_vreg(host, false, false);
+ if (rc) {
+ pr_err("%s: %s disable regulator: failed: %d\n",
+ mmc_hostname(mmc), __func__, rc);
+ BUG_ON(rc);
+ }
+
+ /* 10ms delay for the supply to reach the desired voltage level */
+ usleep_range(10000, 12000);
+
+ /*
+ * Continuing on failing to enable regulator would lead to a panic
+ * anyway, since the commands would fail and console would be flooded
+ * with prints, eventually leading to a watchdog bark
+ */
+ rc = msmsdcc_setup_vreg(host, true, false);
+ if (rc) {
+ pr_err("%s: %s enable regulator: failed: %d\n",
+ mmc_hostname(mmc), __func__, rc);
+ BUG_ON(rc);
+ }
+
+ /* 10ms delay for the supply to reach the desired voltage level */
+ usleep_range(10000, 12000);
+}
+
static const struct mmc_host_ops msmsdcc_ops = {
.enable = msmsdcc_enable,
.disable = msmsdcc_disable,
@@ -3998,7 +4045,8 @@
.get_ro = msmsdcc_get_ro,
.enable_sdio_irq = msmsdcc_enable_sdio_irq,
.start_signal_voltage_switch = msmsdcc_switch_io_voltage,
- .execute_tuning = msmsdcc_execute_tuning
+ .execute_tuning = msmsdcc_execute_tuning,
+ .hw_reset = msmsdcc_hw_reset,
};
static unsigned int
@@ -5595,7 +5643,7 @@
mmc->caps |= plat->mmc_bus_width;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
-
+ mmc->caps |= MMC_CAP_HW_RESET;
/*
* If we send the CMD23 before multi block write/read command
* then we need not to send CMD12 at the end of the transfer.
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index f84e3ac..85b653d 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -248,6 +248,7 @@
bool ext_charging;
bool ext_charge_done;
bool iusb_fine_res;
+ bool dc_unplug_check;
DECLARE_BITMAP(enabled_irqs, PM_CHG_MAX_INTS);
struct work_struct battery_id_valid_work;
int64_t batt_id_min;
@@ -2447,6 +2448,10 @@
}
} else if (active_path & DC_ACTIVE_BIT) {
pr_debug("DC charger active\n");
+ /* Some board designs are not prone to reverse boost on DC
+ * charging path */
+ if (!chip->dc_unplug_check)
+ return;
} else {
/* No charger active */
if (!(is_usb_chg_plugged_in(chip)
@@ -4000,6 +4005,7 @@
chip->warm_temp_dc = INT_MIN;
chip->temp_check_period = pdata->temp_check_period;
+ chip->dc_unplug_check = pdata->dc_unplug_check;
chip->max_bat_chg_current = pdata->max_bat_chg_current;
chip->cool_bat_chg_current = pdata->cool_bat_chg_current;
chip->warm_bat_chg_current = pdata->warm_bat_chg_current;
diff --git a/drivers/usb/gadget/u_ctrl_hsuart.c b/drivers/usb/gadget/u_ctrl_hsuart.c
index 7102d81..a55960e 100644
--- a/drivers/usb/gadget/u_ctrl_hsuart.c
+++ b/drivers/usb/gadget/u_ctrl_hsuart.c
@@ -289,7 +289,7 @@
void ghsuart_ctrl_disconnect(void *gptr, int port_num)
{
- struct gctrl_port *port;
+ struct ghsuart_ctrl_port *port;
struct grmnet *gr = NULL;
unsigned long flags;
@@ -300,7 +300,7 @@
return;
}
- port = gctrl_ports[port_num].port;
+ port = ghsuart_ctrl_ports[port_num].port;
if (!gptr || !port) {
pr_err("%s: grmnet port is null\n", __func__);
@@ -372,7 +372,7 @@
static void ghsuart_ctrl_port_free(int portno)
{
struct ghsuart_ctrl_port *port = ghsuart_ctrl_ports[portno].port;
- struct platform_driver *pdrv = &gctrl_ports[portno].pdrv;
+ struct platform_driver *pdrv = &ghsuart_ctrl_ports[portno].pdrv;
destroy_workqueue(port->wq);
if (pdrv)
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index fca8700..b00e050 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -89,6 +89,10 @@
* @get_batt_capacity_percent:
* a board specific function to return battery
* capacity. If null - a default one will be used
+ * @dc_unplug_check: enables the reverse boosting fix for the DC_IN line
+ * however, this should only be enabled for devices which
+ * control the DC OVP FETs otherwise this option should
+ * remain disabled
* @trkl_voltage: the trkl voltage in (mV) below which hw controlled
* trkl charging happens with linear charger
* @weak_voltage: the weak voltage (mV) below which hw controlled
@@ -137,6 +141,7 @@
int64_t batt_id_min;
int64_t batt_id_max;
bool keep_btm_on_suspend;
+ bool dc_unplug_check;
int trkl_voltage;
int weak_voltage;
int trkl_current;