Merge "msm: timer: read timer twice on 9615" into msm-3.0
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 162fc04..83d0828 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -273,6 +273,7 @@
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
CONFIG_MMC_PARANOID_SD_INIT=y
CONFIG_MMC_BLOCK_MINORS=32
# CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index d19fa3d..dcbca79 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -268,6 +268,7 @@
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
CONFIG_MMC_PARANOID_SD_INIT=y
CONFIG_MMC_BLOCK_MINORS=32
# CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 4275140..67d0057 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -44,6 +44,10 @@
CONFIG_MSM_BAM_DMUX=y
CONFIG_MSM_IPC_ROUTER=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+# CONFIG_MSM_SYSMON_COMM is not set
+CONFIG_MSM_MODEM_8960=y
+CONFIG_MSM_LPASS_8960=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_WATCHDOG=y
CONFIG_MSM_DLOAD_MODE=y
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 62509b4..0543a1f 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -365,7 +365,7 @@
static struct arm_pmu krait_pmu = {
.handle_irq = armv7pmu_handle_irq,
-#ifdef CONFIG_MSM_SMP
+#ifdef CONFIG_SMP
.secondary_enable = scorpion_secondary_enable,
.secondary_disable = scorpion_secondary_disable,
#endif
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index db2eda5..304a4dd 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1518,7 +1518,7 @@
config MSM_SUBSYSTEM_RESTART
bool "MSM Subsystem Restart Driver"
- depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+ depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM9615)
default n
help
This option enables the MSM subsystem restart driver, which provides
@@ -1535,19 +1535,19 @@
config MSM_MODEM_8960
bool "MSM 8960 Modem driver"
- depends on (ARCH_MSM8960)
+ depends on (ARCH_MSM8960 || ARCH_MSM9615)
help
- This option enables the modem driver for the MSM8960, which monitors
+ This option enables the modem driver for the MSM8960 and MSM9615, which monitors
modem hardware watchdog interrupt lines and plugs into the subsystem
- restart and PIL drivers.
+ restart and PIL drivers. For MSM9615, it only supports a full chip reset.
config MSM_LPASS_8960
tristate "MSM 8960 Lpass driver"
- depends on (ARCH_MSM8960)
+ depends on (ARCH_MSM8960 || ARCH_MSM9615)
help
- This option enables the lpass driver for the MSM8960, which monitors
+ This option enables the lpass driver for the MSM8960 and MSM9615. This monitors
lpass hardware watchdog interrupt lines and plugs into the subsystem
- restart and PIL drivers.
+ restart and PIL drivers. For MSM9615, it only supports a full chip reset.
config MSM_WCNSS_SSR_8960
tristate "MSM 8960 WCNSS restart module"
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index d82a6bf..cb0406f 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -523,12 +523,18 @@
int rc = 0;
DBG("%s: opening ch %d\n", __func__, id);
- if (!bam_mux_initialized)
+ if (!bam_mux_initialized) {
+ DBG("%s: not inititialized\n", __func__);
return -ENODEV;
- if (id >= BAM_DMUX_NUM_CHANNELS)
+ }
+ if (id >= BAM_DMUX_NUM_CHANNELS) {
+ pr_err("%s: invalid channel id %d\n", __func__, id);
return -EINVAL;
- if (notify == NULL)
+ }
+ if (notify == NULL) {
+ pr_err("%s: notify function is NULL\n", __func__);
return -EINVAL;
+ }
hdr = kmalloc(sizeof(struct bam_mux_hdr), GFP_KERNEL);
if (hdr == NULL) {
@@ -546,8 +552,7 @@
DBG("%s: Remote not open; ch: %d\n", __func__, id);
spin_unlock_irqrestore(&bam_ch[id].lock, flags);
kfree(hdr);
- rc = -ENODEV;
- goto open_done;
+ return -ENODEV;
}
bam_ch[id].notify = notify;
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 7ee30ef..bce026d 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -701,7 +701,6 @@
pm8018_platform_data.num_regulators = msm_pm8018_regulator_pdata_len;
msm_device_otg.dev.platform_data = &msm_otg_pdata;
- msm_device_gadget_peripheral.dev.parent = &msm_device_otg.dev;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
msm_clock_init(&msm9615_clock_init_data);
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index 5ae388f..bc06870 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -760,7 +760,6 @@
apq8064_device_ssbi_pmic2.dev.platform_data =
&apq8064_ssbi_pm8821_pdata;
apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
- apq8064_device_gadget_peripheral.dev.parent = &apq8064_device_otg.dev;
apq8064_pm8921_platform_data.num_regulators =
msm8064_pm8921_regulator_pdata_len;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index cf74c66..7403da9 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -4739,8 +4739,6 @@
pm8921_platform_data.keypad_pdata = &keypad_data_sim;
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
- msm8960_device_gadget_peripheral.dev.parent = &msm8960_device_otg.dev;
- msm_device_hsusb_host.dev.parent = &msm8960_device_otg.dev;
gpiomux_init();
msm8960_i2c_init();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
@@ -4817,8 +4815,6 @@
if (machine_is_msm8960_liquid())
msm_otg_pdata.mhl_enable = true;
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
- msm8960_device_gadget_peripheral.dev.parent = &msm8960_device_otg.dev;
- msm_device_hsusb_host.dev.parent = &msm8960_device_otg.dev;
#ifdef CONFIG_USB_EHCI_MSM_HSIC
if (machine_is_msm8960_liquid()) {
if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b217b41..b394710 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -993,6 +993,7 @@
static struct regulator *ldo7_1p8;
static struct regulator *vdd_cx;
#define PMICID_INT PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 36)
+#define PMIC_ID_GPIO 36
notify_vbus_state notify_vbus_state_func_ptr;
static int usb_phy_susp_dig_vol = 750000;
static int pmic_id_notif_supported;
@@ -1031,10 +1032,42 @@
return IRQ_HANDLED;
}
+static int msm_hsusb_phy_id_setup_init(int init)
+{
+ unsigned ret;
+
+ if (init) {
+ ret = pm8901_mpp_config_digital_out(1,
+ PM8901_MPP_DIG_LEVEL_L5, 1);
+ if (ret < 0)
+ pr_err("%s:MPP2 configuration failed\n", __func__);
+ } else {
+ ret = pm8901_mpp_config_digital_out(1,
+ PM8901_MPP_DIG_LEVEL_L5, 0);
+ if (ret < 0)
+ pr_err("%s:MPP2 un config failed\n", __func__);
+ }
+ return ret;
+}
+
static int msm_hsusb_pmic_id_notif_init(void (*callback)(int online), int init)
{
unsigned ret = -ENODEV;
+ struct pm8058_gpio pmic_id_cfg = {
+ .direction = PM_GPIO_DIR_IN,
+ .pull = PM_GPIO_PULL_UP_1P5,
+ .function = PM_GPIO_FUNC_NORMAL,
+ .vin_sel = 2,
+ .inv_int_pol = 0,
+ };
+ struct pm8058_gpio pmic_id_uncfg = {
+ .direction = PM_GPIO_DIR_IN,
+ .pull = PM_GPIO_PULL_NO,
+ .function = PM_GPIO_FUNC_NORMAL,
+ .vin_sel = 2,
+ .inv_int_pol = 0,
+ };
if (!callback)
return -EINVAL;
@@ -1058,37 +1091,34 @@
if (init) {
notify_vbus_state_func_ptr = callback;
- ret = pm8901_mpp_config_digital_out(1,
- PM8901_MPP_DIG_LEVEL_L5, 1);
- if (ret) {
- pr_err("%s: MPP2 configuration failed\n", __func__);
- return -ENODEV;
- }
INIT_DELAYED_WORK(&pmic_id_det, pmic_id_detect);
+ ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_cfg);
+ if (ret) {
+ pr_err("%s:return val of pm8058_gpio_config: %d\n",
+ __func__, ret);
+ return ret;
+ }
ret = request_threaded_irq(PMICID_INT, NULL, pmic_id_on_irq,
(IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING),
"msm_otg_id", NULL);
if (ret) {
- pm8901_mpp_config_digital_out(1,
- PM8901_MPP_DIG_LEVEL_L5, 0);
pr_err("%s:pmic_usb_id interrupt registration failed",
__func__);
return ret;
}
- /* Notify the initial Id status */
- pmic_id_detect(&pmic_id_det.work);
msm_otg_pdata.pmic_id_irq = PMICID_INT;
} else {
+ usb_phy_susp_dig_vol = 750000;
free_irq(PMICID_INT, 0);
+ ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_uncfg);
+ if (ret) {
+ pr_err("%s: return val of pm8058_gpio_config: %d\n",
+ __func__, ret);
+ return ret;
+ }
msm_otg_pdata.pmic_id_irq = 0;
cancel_delayed_work_sync(&pmic_id_det);
notify_vbus_state_func_ptr = NULL;
- ret = pm8901_mpp_config_digital_out(1,
- PM8901_MPP_DIG_LEVEL_L5, 0);
- if (ret) {
- pr_err("%s:MPP2 configuration failed\n", __func__);
- return -ENODEV;
- }
}
return 0;
}
@@ -1393,6 +1423,7 @@
.bam_disable = 1,
#ifdef CONFIG_USB_EHCI_MSM_72K
.pmic_id_notif_init = msm_hsusb_pmic_id_notif_init,
+ .phy_id_setup_init = msm_hsusb_phy_id_setup_init,
#endif
#ifdef CONFIG_USB_EHCI_MSM_72K
.vbus_power = msm_hsusb_vbus_power,
@@ -5429,7 +5460,7 @@
36,
{
.direction = PM_GPIO_DIR_IN,
- .pull = PM_GPIO_PULL_UP_1P5,
+ .pull = PM_GPIO_PULL_NO,
.function = PM_GPIO_FUNC_NORMAL,
.vin_sel = 2,
.inv_int_pol = 0,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index dbceae8..95b69e6 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -51,6 +51,7 @@
#include "devices-msm7x2xa.h"
#include "pm.h"
#include "timer.h"
+#include "pm-boot.h"
#define PMEM_KERNEL_EBI1_SIZE 0x3A000
#define MSM_PMEM_AUDIO_SIZE 0x5B000
@@ -2531,6 +2532,9 @@
#endif
msm_pm_set_platform_data(msm7627a_pm_data,
ARRAY_SIZE(msm7627a_pm_data));
+ BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_RESET_VECTOR,
+ ioremap(0, PAGE_SIZE)));
+
msm_fb_add_devices();
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 8ff9725..cd028e4 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1277,6 +1277,7 @@
static DEFINE_CLK_VOTER(dfab_sdc1_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(dfab_sdc2_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(dfab_sps_clk, &dfab_clk.c);
+static DEFINE_CLK_VOTER(dfab_bam_dmux_clk, &dfab_clk.c);
static DEFINE_CLK_VOTER(ebi1_msmbus_clk, &ebi1_clk.c);
/*
@@ -1585,7 +1586,7 @@
CLK_LOOKUP("bus_clk", dfab_sdc1_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("bus_clk", dfab_sdc2_clk.c, "msm_sdcc.2"),
CLK_LOOKUP("dfab_clk", dfab_sps_clk.c, "msm_sps"),
-
+ CLK_LOOKUP("bus_clk", dfab_bam_dmux_clk.c, "BAM_RMNT"),
CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
CLK_LOOKUP("mem_clk", ebi1_adm_clk.c, "msm_dmov"),
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 5cd7013..d5a2ed4 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -17,15 +17,7 @@
#include <linux/clk.h>
#include <mach/socinfo.h>
-/* Sharability attributes of MSM IOMMU mappings */
-#define MSM_IOMMU_ATTR_NON_SH 0x0
-#define MSM_IOMMU_ATTR_SH 0x4
-
-/* Cacheability attributes of MSM IOMMU mappings */
-#define MSM_IOMMU_ATTR_NONCACHED 0x0
-#define MSM_IOMMU_ATTR_CACHED_WB_WA 0x1
-#define MSM_IOMMU_ATTR_CACHED_WB_NWA 0x2
-#define MSM_IOMMU_ATTR_CACHED_WT 0x3
+extern pgprot_t pgprot_kernel;
/* Domain attributes */
#define MSM_IOMMU_DOMAIN_PT_CACHEABLE 0x1
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index 8b62632..74e5847 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -71,8 +71,8 @@
#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32)
#define SLIMBUS0_CORE_EE1_IRQ (GIC_SPI_START + 33)
#define SLIMBUS0_BAM_EE1_IRQ (GIC_SPI_START + 34)
-#define Q6FW_WDOG_EXPIRED (GIC_SPI_START + 35)
-#define Q6SW_WDOG_EXPIRED (GIC_SPI_START + 36)
+#define Q6FW_WDOG_EXPIRED_IRQ (GIC_SPI_START + 35)
+#define Q6SW_WDOG_EXPIRED_IRQ (GIC_SPI_START + 36)
#define MSS_TO_APPS_IRQ_0 (GIC_SPI_START + 37)
#define MSS_TO_APPS_IRQ_1 (GIC_SPI_START + 38)
#define MSS_TO_APPS_IRQ_2 (GIC_SPI_START + 39)
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 43f487a..4509dad 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -25,6 +25,7 @@
#define OTGSC_BSVIE (1 << 27)
#define OTGSC_IDIE (1 << 24)
+#define OTGSC_IDPU (1 << 5)
#define OTGSC_BSVIS (1 << 19)
#define OTGSC_ID (1 << 8)
#define OTGSC_IDIS (1 << 16)
@@ -148,7 +149,6 @@
struct wake_lock wlock;
unsigned long b_last_se0_sess; /* SRP initial condition check */
unsigned long inputs;
- int pmic_id_status;
unsigned long tmouts;
u8 active_tmout;
struct hrtimer timer;
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 26f1cdd..3e8ab55 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -158,6 +158,7 @@
/* pmic notfications apis */
int (*pmic_vbus_notif_init) (void (*callback)(int online), int init);
int (*pmic_id_notif_init) (void (*callback)(int online), int init);
+ int (*phy_id_setup_init) (int init);
int (*pmic_register_vbus_sn) (void (*callback)(int online));
void (*pmic_unregister_vbus_sn) (void (*callback)(int online));
int (*pmic_enable_ldo) (int);
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index 1514497..34729b3 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -1135,4 +1135,36 @@
struct sps_timer_ctrl *timer_ctrl,
struct sps_timer_result *timer_result);
+/**
+ * Find the handle of a BAM device based on the physical address
+ *
+ * This function finds a BAM device in the BAM registration list that
+ * matches the specified physical address, and returns its handle.
+ *
+ * @phys_addr - physical address of the BAM
+ *
+ * @h - device handle of the BAM
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_phy2h(u32 phys_addr, u32 *handle);
+
+/**
+ * Setup desc/data FIFO for bam-to-bam connection
+ *
+ * @mem_buffer - Pointer to struct for allocated memory properties.
+ *
+ * @addr - address of FIFO
+ *
+ * @size - FIFO size
+ *
+ * @use_offset - use address offset instead of absolute address
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_setup_bam2bam_fifo(struct sps_mem_buffer *mem_buffer,
+ u32 addr, u32 size, int use_offset);
+
#endif /* _SPS_H_ */
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index e874663..16c0790 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -38,6 +38,17 @@
#define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)
#define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)
+/* Sharability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NON_SH 0x0
+#define MSM_IOMMU_ATTR_SH 0x4
+
+/* Cacheability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NONCACHED 0x0
+#define MSM_IOMMU_ATTR_CACHED_WB_WA 0x1
+#define MSM_IOMMU_ATTR_CACHED_WB_NWA 0x2
+#define MSM_IOMMU_ATTR_CACHED_WT 0x3
+
+
static inline void clean_pte(unsigned long *start, unsigned long *end)
{
dmac_flush_range(start, end);
@@ -407,21 +418,23 @@
static int __get_pgprot(int prot, int len)
{
unsigned int pgprot;
- int tex, sh;
+ int tex;
- sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0;
- tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK];
+ if (prot & IOMMU_CACHE)
+ tex = (pgprot_kernel >> 2) & 0x07;
+ else
+ tex = msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED];
if (tex < 0 || tex > NUM_TEX_CLASS - 1)
return 0;
if (len == SZ_16M || len == SZ_1M) {
- pgprot = sh ? FL_SHARED : 0;
+ pgprot = FL_SHARED;
pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
pgprot |= tex & 0x04 ? FL_TEX0 : 0;
} else {
- pgprot = sh ? SL_SHARED : 0;
+ pgprot = SL_SHARED;
pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
pgprot |= tex & 0x04 ? SL_TEX0 : 0;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 0f2559e..294e9c0 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -178,7 +178,7 @@
ret = -ENOMEM;
goto out;
}
- pr_info("%s: 8960 lpass SSR driver init'ed.\n", __func__);
+ pr_info("%s: lpass SSR driver init'ed.\n", __func__);
out:
return ret;
}
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index 7bcd844..f0aa13c 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -26,7 +26,6 @@
#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include <mach/subsystem_notif.h>
-#include <mach/irqs-8960.h>
#include <mach/socinfo.h>
#include "smd_private.h"
@@ -227,7 +226,7 @@
{
int ret;
- if (!cpu_is_msm8960() && !cpu_is_msm8930())
+ if (!cpu_is_msm8960() && !cpu_is_msm8930() && !cpu_is_msm9615())
return -ENODEV;
ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
@@ -266,7 +265,7 @@
ret = modem_debugfs_init();
- pr_info("%s: 8960 modem fatal driver init'ed.\n", __func__);
+ pr_info("%s: modem fatal driver init'ed.\n", __func__);
out:
return ret;
}
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 54607d0..37469f8 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -139,6 +139,11 @@
int ret;
int old_val = restart_level;
+ if (cpu_is_msm9615()) {
+ pr_err("Only Phase 1 subsystem restart is supported\n");
+ return -EINVAL;
+ }
+
ret = param_set_int(val, kp);
if (ret)
return ret;
@@ -571,7 +576,7 @@
n_restart_orders = ARRAY_SIZE(orders_8x60_all);
}
- if (cpu_is_msm8960() || cpu_is_msm8930()) {
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615()) {
restart_orders = restart_orders_8960;
n_restart_orders = ARRAY_SIZE(restart_orders_8960);
}
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 30365a3..e4e561c 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -262,12 +262,12 @@
iommu_virt_addr = memdesc->gpuaddr;
ret = iommu_map_range(domain, iommu_virt_addr, memdesc->sg,
- memdesc->size, MSM_IOMMU_ATTR_NONCACHED);
+ memdesc->size, 0);
if (ret) {
KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) "
"failed with err: %d\n", domain,
iommu_virt_addr, memdesc->sg, memdesc->size,
- MSM_IOMMU_ATTR_NONCACHED, ret);
+ 0, ret);
return ret;
}
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 565c724..7f43136 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -34,6 +34,7 @@
#include <mach/camera.h>
#include <linux/syscalls.h>
#include <linux/hrtimer.h>
+#include <linux/ion.h>
DEFINE_MUTEX(ctrl_cmd_lock);
#define CAMERA_STOP_VIDEO 58
@@ -56,6 +57,8 @@
static enum msm_camera_type camera_type[MSM_MAX_CAMERA_SENSORS];
static uint32_t sensor_mount_angle[MSM_MAX_CAMERA_SENSORS];
+struct ion_client *client_for_ion;
+
static const char *vfe_config_cmd[] = {
"CMD_GENERAL", /* 0 */
"CMD_AXI_CFG_OUT1",
@@ -293,29 +296,41 @@
struct msm_pmem_info *info, spinlock_t* pmem_spinlock,
struct msm_sync *sync)
{
- struct file *file;
unsigned long paddr;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+ struct file *file;
unsigned long kvstart;
+#endif
unsigned long len;
- int rc;
+ int rc = -ENOMEM;
struct msm_pmem_region *region;
unsigned long flags;
-
+ region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
+ if (!region)
+ goto out;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ region->handle = ion_import_fd(client_for_ion, info->fd);
+ if (IS_ERR_OR_NULL(region->handle))
+ goto out1;
+ ion_phys(client_for_ion, region->handle,
+ &paddr, (size_t *)&len);
+#else
rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
if (rc < 0) {
pr_err("%s: get_pmem_file fd %d error %d\n",
__func__,
info->fd, rc);
- return rc;
+ goto out1;
}
-
+ region->file = file;
+#endif
if (!info->len)
info->len = len;
rc = check_pmem_info(info, len);
if (rc < 0)
- return rc;
+ goto out2;
paddr += info->offset;
len = info->len;
@@ -323,29 +338,33 @@
spin_lock_irqsave(pmem_spinlock, flags);
if (check_overlap(ptype, paddr, len) < 0) {
spin_unlock_irqrestore(pmem_spinlock, flags);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out2;
}
spin_unlock_irqrestore(pmem_spinlock, flags);
-
- region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
- if (!region)
- return -ENOMEM;
-
spin_lock_irqsave(pmem_spinlock, flags);
INIT_HLIST_NODE(®ion->list);
region->paddr = paddr;
region->len = len;
- region->file = file;
memcpy(®ion->info, info, sizeof(region->info));
hlist_add_head(&(region->list), ptype);
spin_unlock_irqrestore(pmem_spinlock, flags);
CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx\n",
__func__, info->type, paddr, (unsigned long)info->vaddr);
-
return 0;
+out2:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_free(client_for_ion, region->handle);
+#else
+ put_pmem_file(region->file);
+#endif
+out1:
+ kfree(region);
+out:
+ return rc;
}
/* return of 0 means failure */
@@ -616,7 +635,11 @@
pinfo->vaddr == region->info.vaddr &&
pinfo->fd == region->info.fd) {
hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_free(client_for_ion, region->handle);
+#else
put_pmem_file(region->file);
+#endif
kfree(region);
CDBG("%s: type %d, vaddr 0x%p\n",
__func__, pinfo->type, pinfo->vaddr);
@@ -636,7 +659,11 @@
pinfo->vaddr == region->info.vaddr &&
pinfo->fd == region->info.fd) {
hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_free(client_for_ion, region->handle);
+#else
put_pmem_file(region->file);
+#endif
kfree(region);
CDBG("%s: type %d, vaddr 0x%p\n",
__func__, pinfo->type, pinfo->vaddr);
@@ -655,7 +682,11 @@
pinfo->vaddr == region->info.vaddr &&
pinfo->fd == region->info.fd) {
hlist_del(node);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_free(client_for_ion, region->handle);
+#else
put_pmem_file(region->file);
+#endif
kfree(region);
CDBG("%s: type %d, vaddr 0x%p\n",
__func__, pinfo->type, pinfo->vaddr);
@@ -3013,14 +3044,22 @@
hlist_for_each_entry_safe(region, hnode, n,
&sync->pmem_frames, list) {
hlist_del(hnode);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_free(client_for_ion, region->handle);
+#else
put_pmem_file(region->file);
+#endif
kfree(region);
}
CDBG("%s, free stats pmem region\n", __func__);
hlist_for_each_entry_safe(region, hnode, n,
&sync->pmem_stats, list) {
hlist_del(hnode);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_free(client_for_ion, region->handle);
+#else
put_pmem_file(region->file);
+#endif
kfree(region);
}
msm_queue_drain(&sync->pict_q, list_pict);
@@ -3031,6 +3070,7 @@
sync->core_powered_on = 0;
}
mutex_unlock(&sync->lock);
+ ion_client_destroy(client_for_ion);
return 0;
}
@@ -3733,6 +3773,7 @@
sync->core_powered_on = 1;
}
sync->opencnt++;
+ client_for_ion = msm_ion_client_create(-1, "camera");
msm_open_done:
mutex_unlock(&sync->lock);
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index cb453e0..e43166e 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -425,6 +425,85 @@
}
/**
+ * Find the handle of a BAM device based on the physical address
+ *
+ * This function finds a BAM device in the BAM registration list that
+ * matches the specified physical address, and returns its handle.
+ *
+ * @phys_addr - physical address of the BAM
+ *
+ * @h - device handle of the BAM
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_phy2h(u32 phys_addr, u32 *handle)
+{
+ struct sps_bam *bam;
+
+ list_for_each_entry(bam, &sps->bams_q, list) {
+ if (bam->props.phys_addr == phys_addr) {
+ *handle = (u32) bam;
+ return 0;
+ }
+ }
+
+ SPS_INFO("sps: BAM device 0x%x is not registered yet.\n", phys_addr);
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(sps_phy2h);
+
+/**
+ * Setup desc/data FIFO for bam-to-bam connection
+ *
+ * @mem_buffer - Pointer to struct for allocated memory properties.
+ *
+ * @addr - address of FIFO
+ *
+ * @size - FIFO size
+ *
+ * @use_offset - use address offset instead of absolute address
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_setup_bam2bam_fifo(struct sps_mem_buffer *mem_buffer,
+ u32 addr, u32 size, int use_offset)
+{
+ if ((mem_buffer == NULL) || (size == 0))
+ return SPS_ERROR;
+
+ if (use_offset) {
+ if ((addr + size) <= sps->pipemem_size)
+ mem_buffer->phys_base = sps->pipemem_phys_base + addr;
+ else {
+ SPS_ERR("sps: requested mem is out of "
+ "pipe mem range.\n");
+ return SPS_ERROR;
+ }
+ } else {
+ if (addr >= sps->pipemem_phys_base &&
+ (addr + size) <= (sps->pipemem_phys_base
+ + sps->pipemem_size))
+ mem_buffer->phys_base = addr;
+ else {
+ SPS_ERR("sps: requested mem is out of "
+ "pipe mem range.\n");
+ return SPS_ERROR;
+ }
+ }
+
+ mem_buffer->base = spsi_get_mem_ptr(mem_buffer->phys_base);
+ mem_buffer->size = size;
+
+ memset(mem_buffer->base, 0, mem_buffer->size);
+
+ return 0;
+}
+EXPORT_SYMBOL(sps_setup_bam2bam_fifo);
+
+/**
* Find the BAM device from the handle
*
* This function finds a BAM device in the BAM registration list that
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 2d0f7cd..e498c03 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -89,6 +89,9 @@
DECLARE_BITMAP(enabled_irqs, PM_BMS_MAX_INTS);
spinlock_t bms_output_lock;
struct single_row_lut *adjusted_fcc_temp_lut;
+ unsigned int charging_began;
+ unsigned int start_percent;
+ unsigned int end_percent;
};
static struct pm8921_bms_chip *the_chip;
@@ -1102,9 +1105,23 @@
update_userspace = 0;
}
- if (update_userspace) {
- last_soc = soc;
+ if (last_soc == -EINVAL || soc <= last_soc) {
+ last_soc = update_userspace ? soc : last_soc;
+ return soc;
}
+
+ /*
+ * soc > last_soc
+ * the device must be charging for reporting a higher soc, if not ignore
+ * this soc and continue reporting the last_soc
+ */
+ if (the_chip->start_percent != 0) {
+ last_soc = soc;
+ } else {
+ pr_debug("soc = %d reporting last_soc = %d\n", soc, last_soc);
+ soc = last_soc;
+ }
+
return soc;
}
@@ -1645,12 +1662,10 @@
}
EXPORT_SYMBOL_GPL(pm8921_bms_get_fcc);
-static int start_percent;
-static int end_percent;
void pm8921_bms_charging_began(void)
{
- start_percent = pm8921_bms_get_percent_charge();
- pr_debug("start_percent = %u%%\n", start_percent);
+ the_chip->start_percent = pm8921_bms_get_percent_charge();
+ pr_debug("start_percent = %u%%\n", the_chip->start_percent);
}
EXPORT_SYMBOL_GPL(pm8921_bms_charging_began);
@@ -1676,9 +1691,10 @@
}
charge_cycle_calculation:
- end_percent = pm8921_bms_get_percent_charge();
- if (end_percent > start_percent) {
- last_charge_increase = end_percent - start_percent;
+ the_chip->end_percent = pm8921_bms_get_percent_charge();
+ if (the_chip->end_percent > the_chip->start_percent) {
+ last_charge_increase =
+ the_chip->end_percent - the_chip->start_percent;
if (last_charge_increase > 100) {
last_chargecycles++;
last_charge_increase = last_charge_increase % 100;
@@ -1686,9 +1702,11 @@
}
pr_debug("end_percent = %u%% last_charge_increase = %d"
"last_chargecycles = %d\n",
- end_percent,
+ the_chip->end_percent,
last_charge_increase,
last_chargecycles);
+ the_chip->start_percent = 0;
+ the_chip->end_percent = 0;
}
EXPORT_SYMBOL_GPL(pm8921_bms_charging_end);
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 6f0fb07..7686bf2 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -487,7 +487,7 @@
}
spin_lock_irqsave(&dev->lock, flags);
- list_add(&cpkt->list, &dev->cpkt_resp_q);
+ list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
spin_unlock_irqrestore(&dev->lock, flags);
frmnet_ctrl_response_available(dev);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 350f286..ec303b9 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -400,8 +400,6 @@
dev_err(mehci->dev, "Unable to suspend PHY\n");
msm_hsic_config_gpios(mehci, 0);
msm_hsic_reset(mehci);
- enable_irq(hcd->irq);
- return -ETIMEDOUT;
}
/*
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 411fa97..f45f257 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -177,11 +177,6 @@
}
device_init_wakeup(&pdev->dev, 1);
- /*
- * OTG device parent of HCD takes care of putting
- * hardware into low power mode.
- */
- pm_runtime_no_callbacks(&pdev->dev);
pm_runtime_enable(&pdev->dev);
return 0;
@@ -212,7 +207,31 @@
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_RUNTIME
+static int ehci_msm_runtime_idle(struct device *dev)
+{
+ dev_dbg(dev, "ehci runtime idle\n");
+ return 0;
+}
+
+static int ehci_msm_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "ehci runtime suspend\n");
+ /*
+ * Notify OTG about suspend. It takes care of
+ * putting the hardware in LPM.
+ */
+ return otg_set_suspend(otg, 1);
+}
+
+static int ehci_msm_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "ehci runtime resume\n");
+ return otg_set_suspend(otg, 0);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
static int ehci_msm_pm_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -236,7 +255,7 @@
wakeup);
}
- return 0;
+ return otg_set_suspend(otg, 1);
}
static int ehci_msm_pm_resume(struct device *dev)
@@ -250,16 +269,14 @@
ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd));
- return 0;
+ return otg_set_suspend(otg, 0);
}
-#else
-#define ehci_msm_pm_suspend NULL
-#define ehci_msm_pm_resume NULL
#endif
static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
- .suspend = ehci_msm_pm_suspend,
- .resume = ehci_msm_pm_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(ehci_msm_pm_suspend, ehci_msm_pm_resume)
+ SET_RUNTIME_PM_OPS(ehci_msm_runtime_suspend, ehci_msm_runtime_resume,
+ ehci_msm_runtime_idle)
};
static struct platform_driver ehci_msm_driver = {
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index fccd357..714099a 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -37,7 +37,13 @@
#define DRIVER_NAME "msm_otg"
static void otg_reset(struct otg_transceiver *xceiv, int phy_reset);
static void msm_otg_set_vbus_state(int online);
-static void msm_otg_set_id_state(int online);
+#ifdef CONFIG_USB_EHCI_MSM_72K
+static void msm_otg_set_id_state(int id);
+#else
+static void msm_otg_set_id_state(int id)
+{
+}
+#endif
struct msm_otg *the_msm_otg;
@@ -45,9 +51,7 @@
{
struct msm_otg *dev = the_msm_otg;
- if (dev->pmic_id_notif_supp)
- return dev->pmic_id_status ? 0 : 1;
- else if (dev->pdata->otg_mode == OTG_ID)
+ if (dev->pdata->otg_mode == OTG_ID)
return (OTGSC_ID & readl(USB_OTGSC)) ? 0 : 1;
else
return !test_bit(ID, &dev->inputs);
@@ -135,24 +139,38 @@
#ifdef CONFIG_USB_EHCI_MSM_72K
static void enable_idgnd(struct msm_otg *dev)
{
+ unsigned temp;
+
/* Do nothing if instead of ID pin, USER controls mode switch */
if (dev->pdata->otg_mode == OTG_USER_CONTROL)
return;
ulpi_write(dev, (1<<4), 0x0E);
ulpi_write(dev, (1<<4), 0x11);
- writel_relaxed(readl_relaxed(USB_OTGSC) | OTGSC_IDIE, USB_OTGSC);
+ ulpi_write(dev, (1<<0), 0x0B);
+ temp = OTGSC_IDIE | OTGSC_IDPU;
+ writel_relaxed(readl_relaxed(USB_OTGSC) | temp, USB_OTGSC);
}
static void disable_idgnd(struct msm_otg *dev)
{
+ unsigned temp;
+
/* Do nothing if instead of ID pin, USER controls mode switch */
if (dev->pdata->otg_mode == OTG_USER_CONTROL)
return;
-
+ temp = OTGSC_IDIE | OTGSC_IDPU;
+ writel_relaxed(readl_relaxed(USB_OTGSC) & ~temp, USB_OTGSC);
ulpi_write(dev, (1<<4), 0x0F);
ulpi_write(dev, (1<<4), 0x12);
- writel_relaxed(readl_relaxed(USB_OTGSC) & ~OTGSC_IDIE, USB_OTGSC);
+ ulpi_write(dev, (1<<0), 0x0C);
+}
+#else
+static void enable_idgnd(struct msm_otg *dev)
+{
+}
+static void disable_idgnd(struct msm_otg *dev)
+{
}
#endif
@@ -224,6 +242,9 @@
#define get_aca_bmaxpower(dev) (dev->b_max_power)
#define set_aca_bmaxpower(dev, power) (dev->b_max_power = power)
#else
+static void set_aca_id_inputs(struct msm_otg *dev)
+{
+}
#define get_aca_bmaxpower(dev) 0
#define set_aca_bmaxpower(dev, power)
#endif
@@ -692,6 +713,31 @@
* 4. peripheral is supported, but, vbus is not routed to pmic
*/
host_bus_suspend = dev->otg.host && is_host();
+
+ /*
+ * Configure the PMIC ID only in case of cable disconnect.
+ * PMIC doesn't generate interrupt for ID_GND to ID_A
+ * transistion. hence use the PHY ID cricuit.
+ */
+ if (dev->pdata->pmic_id_notif_init && !host_bus_suspend &&
+ !test_bit(ID_A, &dev->inputs)) {
+ disable_idgnd(dev);
+ ret = dev->pdata->pmic_id_notif_init(
+ &msm_otg_set_id_state, 1);
+ if (!ret) {
+ dev->pmic_id_notif_supp = 1;
+ if (dev->pdata->pmic_id_irq)
+ dev->id_irq = dev->pdata->pmic_id_irq;
+ } else if (ret == -ENOTSUPP) {
+ pr_debug("%s:USB ID is not routed to pmic",
+ __func__);
+ enable_idgnd(dev);
+ } else {
+ pr_err("%s: pmic_id_ notif_init failed err:%d",
+ __func__, ret);
+ }
+ }
+
if ((dev->otg.gadget && chg_type == USB_CHG_TYPE__WALLCHARGER) ||
host_bus_suspend ||
(dev->otg.host && !dev->pmic_id_notif_supp) ||
@@ -760,7 +806,8 @@
* that there is no harm with this. Till hw folks confirms this
* put regulators in lpm.
*/
- if (!host_bus_suspend && dev->pmic_vbus_notif_supp) {
+ if (!host_bus_suspend && dev->pmic_vbus_notif_supp &&
+ !test_bit(ID_A, &dev->inputs)) {
pr_debug("phy can power collapse: (%d)\n",
can_phy_power_collapse(dev));
if (can_phy_power_collapse(dev) && dev->pdata->ldo_enable) {
@@ -881,9 +928,35 @@
}
phy_resumed:
+ /*
+ * It is observed that BSVIS may get set immediatly
+ * after PHY becomes active upon micro-B cable connect.
+ * But BSVIS might get cleared by below enable_idgnd
+ * function which causes hw to not generate the BSV interrupt.
+ * Hence check for BSV interrupt explictly and schedule the
+ * work.
+ */
+ if (readl_relaxed(USB_OTGSC) & OTGSC_BSVIS) {
+ set_bit(B_SESS_VLD, &dev->inputs);
+ queue_work(dev->wq, &dev->sm_work);
+ }
+ if (dev->pmic_id_notif_supp) {
+ dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
+ dev->pmic_id_notif_supp = 0;
+ enable_idgnd(dev);
+ }
+
/* Enable Idabc interrupts as these were disabled before entering LPM */
enable_idabc(dev);
+ /*
+ * There is corner case where host won't be resumed
+ * while transitioning from ID_GND to ID_A. In that
+ * IDGND might have cleared and ID_A might not have updated
+ * yet. Hence update the ACA states explicitly.
+ */
+ set_aca_id_inputs(dev);
+
/* If resume signalling finishes before lpm exit, PCD is not set in
* USBSTS register. Drive resume signal to the downstream device now
* so that host driver can process the upcoming port change interrupt.*/
@@ -996,6 +1069,12 @@
}
udelay(10);
}
+ if (dev->pmic_id_notif_supp) {
+ dev->pdata->pmic_id_notif_init(
+ &msm_otg_set_id_state, 0);
+ dev->pmic_id_notif_supp = 0;
+ enable_idgnd(dev);
+ }
out:
enable_idabc(dev);
enable_irq(dev->irq);
@@ -1119,23 +1198,20 @@
#endif
return 0;
}
-#endif
-void msm_otg_set_id_state(int id)
+static void msm_otg_set_id_state(int id)
{
struct msm_otg *dev = the_msm_otg;
unsigned long flags;
- if (id == dev->pmic_id_status)
+ if (!atomic_read(&dev->in_lpm))
return;
if (id) {
set_bit(ID, &dev->inputs);
- dev->pmic_id_status = 1;
} else {
clear_bit(ID, &dev->inputs);
set_bit(A_BUS_REQ, &dev->inputs);
- dev->pmic_id_status = 0;
}
spin_lock_irqsave(&dev->lock, flags);
if (dev->otg.state != OTG_STATE_UNDEFINED) {
@@ -1144,6 +1220,7 @@
}
spin_unlock_irqrestore(&dev->lock, flags);
}
+#endif
void msm_otg_set_vbus_state(int online)
{
@@ -1973,6 +2050,7 @@
} else if (test_bit(ID_A, &dev->inputs)) {
dev->pdata->vbus_power(USB_PHY_INTEGRATED, 0);
} else if (!test_bit(ID, &dev->inputs)) {
+ msm_otg_set_power(&dev->otg, 0);
dev->pdata->vbus_power(USB_PHY_INTEGRATED, 1);
}
break;
@@ -2687,12 +2765,10 @@
}
}
- if (dev->pdata->pmic_id_notif_init) {
- ret = dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 1);
- if (!ret) {
- dev->pmic_id_notif_supp = 1;
- } else if (ret != -ENOTSUPP) {
- pr_err("%s: pmic_id_ notif_init failed err:%d",
+ if (dev->pdata->phy_id_setup_init) {
+ ret = dev->pdata->phy_id_setup_init(1);
+ if (ret) {
+ pr_err("%s: phy_id_setup_init failed err:%d",
__func__, ret);
goto free_pmic_vbus_notif;
}
@@ -2700,8 +2776,6 @@
if (dev->pdata->pmic_vbus_irq)
dev->vbus_on_irq = dev->pdata->pmic_vbus_irq;
- if (dev->pdata->pmic_id_irq)
- dev->id_irq = dev->pdata->pmic_id_irq;
/* vote for vddcx, as PHY cannot tolerate vddcx below 1.0V */
if (dev->pdata->init_vddcx) {
@@ -2709,7 +2783,7 @@
if (ret) {
pr_err("%s: unable to enable vddcx digital core:%d\n",
__func__, ret);
- goto free_pmic_id_notif;
+ goto free_phy_id_setup;
}
}
@@ -2819,9 +2893,9 @@
free_config_vddcx:
if (dev->pdata->init_vddcx)
dev->pdata->init_vddcx(0);
-free_pmic_id_notif:
- if (dev->pdata->pmic_id_notif_init && dev->pmic_id_notif_supp)
- dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
+free_phy_id_setup:
+ if (dev->pdata->phy_id_setup_init)
+ dev->pdata->phy_id_setup_init(0);
free_pmic_vbus_notif:
if (dev->pdata->pmic_vbus_notif_init && dev->pmic_vbus_notif_supp)
dev->pdata->pmic_vbus_notif_init(&msm_otg_set_vbus_state, 0);
@@ -2890,6 +2964,9 @@
if (dev->pmic_vbus_notif_supp)
dev->pdata->pmic_vbus_notif_init(&msm_otg_set_vbus_state, 0);
+ if (dev->pdata->phy_id_setup_init)
+ dev->pdata->phy_id_setup_init(0);
+
if (dev->pmic_id_notif_supp)
dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index d16fcda..04c1449 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -535,6 +535,24 @@
return 0;
}
+static int msm_otg_set_suspend(struct otg_transceiver *otg, int suspend)
+{
+ struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
+
+ /*
+ * Allow bus suspend only for host mode. Device mode bus suspend
+ * is not implemented yet.
+ */
+ if (!test_bit(ID, &motg->inputs) || test_bit(ID_A, &motg->inputs)) {
+ if (suspend)
+ pm_runtime_put(otg->dev);
+ else
+ pm_runtime_resume(otg->dev);
+ }
+
+ return 0;
+}
+
#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000)
#define PHY_RESUME_TIMEOUT_USEC (100 * 1000)
@@ -745,7 +763,6 @@
if (motg->async_int) {
motg->async_int = 0;
- pm_runtime_put(otg->dev);
enable_irq(motg->irq);
}
@@ -1329,7 +1346,6 @@
dev_dbg(otg->dev, "chg detection work\n");
switch (motg->chg_state) {
case USB_CHG_STATE_UNDEFINED:
- pm_runtime_get_sync(otg->dev);
msm_chg_block_on(motg);
msm_chg_enable_dcd(motg);
msm_chg_enable_aca_det(motg);
@@ -1462,6 +1478,7 @@
struct msm_otg *motg = container_of(w, struct msm_otg, sm_work);
struct otg_transceiver *otg = &motg->otg;
+ pm_runtime_resume(otg->dev);
switch (otg->state) {
case OTG_STATE_UNDEFINED:
dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n");
@@ -1494,6 +1511,8 @@
case USB_ACA_B_CHARGER:
msm_otg_notify_charger(motg,
IDEV_CHG_MAX);
+ pm_runtime_put_noidle(otg->dev);
+ pm_runtime_suspend(otg->dev);
break;
case USB_CDP_CHARGER:
case USB_ACA_C_CHARGER:
@@ -1515,20 +1534,14 @@
break;
}
} else {
- /*
- * If charger detection work is pending, decrement
- * the pm usage counter to balance with the one that
- * is incremented in charger detection work.
- */
- if (cancel_delayed_work_sync(&motg->chg_work)) {
- pm_runtime_put_sync(otg->dev);
+ if (cancel_delayed_work_sync(&motg->chg_work))
msm_otg_reset(otg);
- }
msm_otg_notify_charger(motg, 0);
motg->chg_state = USB_CHG_STATE_UNDEFINED;
motg->chg_type = USB_INVALID_CHARGER;
+ pm_runtime_put_noidle(otg->dev);
+ pm_runtime_suspend(otg->dev);
}
- pm_runtime_put_sync(otg->dev);
break;
case OTG_STATE_B_PERIPHERAL:
dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n");
@@ -1547,7 +1560,6 @@
schedule_work(w);
} else if (test_bit(ID_C, &motg->inputs)) {
msm_otg_notify_charger(motg, IDEV_CHG_MAX);
- pm_runtime_put_sync(otg->dev);
}
break;
case OTG_STATE_A_HOST:
@@ -1569,7 +1581,6 @@
motg->pdata->vbus_power(0);
msm_otg_notify_charger(motg,
IDEV_CHG_MIN - motg->mA_port);
- pm_runtime_put_sync(otg->dev);
} else if (!test_bit(ID, &motg->inputs)) {
motg->chg_state = USB_CHG_STATE_UNDEFINED;
motg->chg_type = USB_INVALID_CHARGER;
@@ -1577,7 +1588,6 @@
writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
if (motg->pdata->vbus_power)
motg->pdata->vbus_power(1);
- pm_runtime_put_sync(otg->dev);
}
break;
default:
@@ -1594,17 +1604,15 @@
if (atomic_read(&motg->in_lpm)) {
disable_irq_nosync(irq);
motg->async_int = 1;
- pm_runtime_get(otg->dev);
+ pm_request_resume(otg->dev);
return IRQ_HANDLED;
}
usbsts = readl(USB_USBSTS);
if ((usbsts & PHY_ALT_INT)) {
writel(PHY_ALT_INT, USB_USBSTS);
- if (msm_chg_check_aca_intr(motg)) {
- pm_runtime_get_noresume(otg->dev);
+ if (msm_chg_check_aca_intr(motg))
schedule_work(&motg->sm_work);
- }
return IRQ_HANDLED;
}
@@ -1619,7 +1627,6 @@
clear_bit(ID, &motg->inputs);
dev_dbg(otg->dev, "ID set/clear\n");
schedule_work(&motg->sm_work);
- pm_runtime_get_noresume(otg->dev);
} else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) {
if (otgsc & OTGSC_BSV)
set_bit(B_SESS_VLD, &motg->inputs);
@@ -1627,7 +1634,6 @@
clear_bit(B_SESS_VLD, &motg->inputs);
dev_dbg(otg->dev, "BSV set/clear\n");
schedule_work(&motg->sm_work);
- pm_runtime_get_noresume(otg->dev);
}
writel(otgsc, USB_OTGSC);
@@ -1749,7 +1755,7 @@
goto out;
}
- pm_runtime_get_sync(otg->dev);
+ pm_runtime_resume(otg->dev);
schedule_work(&motg->sm_work);
out:
return status;
@@ -1973,6 +1979,7 @@
otg->set_host = msm_otg_set_host;
otg->set_peripheral = msm_otg_set_peripheral;
otg->set_power = msm_otg_set_power;
+ otg->set_suspend = msm_otg_set_suspend;
otg->io_ops = &msm_otg_io_ops;
@@ -2145,16 +2152,10 @@
dev_dbg(dev, "OTG runtime idle\n");
- /*
- * It is observed some times that a spurious interrupt
- * comes when PHY is put into LPM immediately after PHY reset.
- * This 1 sec delay also prevents entering into LPM immediately
- * after asynchronous interrupt.
- */
- if (otg->state != OTG_STATE_UNDEFINED)
- pm_schedule_suspend(dev, 1000);
-
- return -EAGAIN;
+ if (otg->state == OTG_STATE_UNDEFINED)
+ return -EAGAIN;
+ else
+ return 0;
}
static int msm_otg_runtime_suspend(struct device *dev)
@@ -2170,6 +2171,7 @@
struct msm_otg *motg = dev_get_drvdata(dev);
dev_dbg(dev, "OTG runtime resume\n");
+ pm_runtime_get_noresume(dev);
return msm_otg_resume(motg);
}
#endif
@@ -2177,10 +2179,18 @@
#ifdef CONFIG_PM_SLEEP
static int msm_otg_pm_suspend(struct device *dev)
{
- struct msm_otg *motg = dev_get_drvdata(dev);
+ int ret;
dev_dbg(dev, "OTG PM suspend\n");
- return msm_otg_suspend(motg);
+
+#ifdef CONFIG_PM_RUNTIME
+ ret = pm_runtime_suspend(dev);
+ if (ret > 0)
+ ret = 0;
+#else
+ ret = msm_otg_suspend(dev_get_drvdata(dev));
+#endif
+ return ret;
}
static int msm_otg_pm_resume(struct device *dev)
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
index c388407..e5a5a84 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -195,6 +195,7 @@
struct vcd_buffer_requirement actual_output_buf_req;
struct vcd_buffer_requirement min_output_buf_req;
struct vcd_buffer_requirement client_output_buf_req;
+ u32 idr_only_decoding;
};
union ddl_codec_data {
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
index ad2fd37..e17107e 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
@@ -356,6 +356,11 @@
case ACTIVE_SPS_NOT_PRESENT:
case ACTIVE_PPS_NOT_PRESENT:
{
+ if (ddl->codec_data.decoder.idr_only_decoding) {
+ DBG("Consider warnings as errors in idr mode");
+ ddl_client_fatal_cb(ddl_context);
+ return true;
+ }
vcd_status = VCD_ERR_BITSTREAM_ERR;
break;
}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
index 6343202..f09bd71 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -807,8 +807,13 @@
}
case VCD_CODEC_H264:
{
- comv_buf_no =
- decoder->client_output_buf_req.actual_count;
+ if (decoder->idr_only_decoding)
+ comv_buf_no = decoder->min_dpb_num;
+ else
+ comv_buf_no =
+ decoder->
+ client_output_buf_req.
+ actual_count;
break;
}
}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
index 2899df6..2ec8419 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
@@ -124,6 +124,7 @@
u32 loopc;
struct ddl_frame_data_tag *found_frame = NULL;
struct ddl_mask *dpb_mask = &decoder->dpb_mask;
+ u32 temp_mask;
switch (operation) {
case DDL_DPB_OP_MARK_BUSY:
@@ -145,13 +146,17 @@
if (found_frame) {
if (operation == DDL_DPB_OP_MARK_BUSY) {
- dpb_mask->hw_mask &=
- (~(0x1 << loopc));
+ temp_mask = (~(0x1 << loopc));
+ if (decoder->idr_only_decoding)
+ temp_mask = ~(0xffffffff);
+ dpb_mask->hw_mask &= temp_mask;
*in_out_frame = *found_frame;
} else if (operation ==
DDL_DPB_OP_MARK_FREE) {
- dpb_mask->client_mask |=
- (0x1 << loopc);
+ temp_mask = (0x1 << loopc);
+ if (decoder->idr_only_decoding)
+ temp_mask = 0xffffffff;
+ dpb_mask->client_mask |= temp_mask;
*found_frame = *in_out_frame;
}
} else {
@@ -172,29 +177,35 @@
}
case DDL_DPB_OP_INIT:
{
- u32 dpb_size;
+ u32 dpb_size, index, num_dpb;
dpb_size = (!decoder->meta_data_offset) ?
decoder->dp_buf.dec_pic_buffers[0].vcd_frm.
alloc_len : decoder->meta_data_offset;
- vidc_720p_decode_set_dpb_details(decoder->dp_buf.
- no_of_dec_pic_buf,
+ if (decoder->idr_only_decoding)
+ num_dpb = decoder->min_dpb_num;
+ else
+ num_dpb = decoder->dp_buf.no_of_dec_pic_buf;
+ vidc_720p_decode_set_dpb_details(
+ num_dpb,
dpb_size,
decoder->ref_buffer.
align_physical_addr);
- for (loopc = 0;
- loopc < decoder->dp_buf.no_of_dec_pic_buf;
- ++loopc) {
+ for (loopc = 0; loopc < num_dpb; ++loopc) {
+ if (decoder->idr_only_decoding)
+ index = 0;
+ else
+ index = loopc;
vidc_720p_decode_set_dpb_buffers(loopc,
(u32 *)
decoder->
dp_buf.
dec_pic_buffers
- [loopc].
+ [index].
vcd_frm.
physical);
- VIDC_LOG1("DEC_DPB_BUFn_SIZE",
+ VIDC_LOG1("DEC_DPB_BUFn_SIZE=%d",
decoder->dp_buf.
- dec_pic_buffers[loopc].vcd_frm.
+ dec_pic_buffers[index].vcd_frm.
alloc_len);
}
break;
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
index 17c2028..d1b1952 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -365,6 +365,18 @@
}
break;
}
+ case VCD_I_DEC_PICTYPE:
+ {
+ if ((sizeof(u32) == property_hdr->sz) &&
+ DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+ decoder->idr_only_decoding =
+ *(u32 *)property_value;
+ ddl_set_default_decoder_buffer_req(
+ decoder, true);
+ vcd_status = VCD_S_SUCCESS;
+ }
+ }
+ break;
case VCD_I_FRAME_RATE:
{
vcd_status = VCD_S_SUCCESS;
@@ -1462,6 +1474,7 @@
decoder->client_frame_size.stride = 176;
decoder->client_frame_size.scan_lines = 144;
decoder->progressive_only = 1;
+ decoder->idr_only_decoding = 0;
decoder->profile.profile = VCD_PROFILE_UNKNOWN;
decoder->level.level = VCD_LEVEL_UNKNOWN;
decoder->output_order = VCD_DEC_ORDER_DISPLAY;
@@ -1689,18 +1702,24 @@
min_dpb = decoder->min_dpb_num;
}
+ if (decoder->idr_only_decoding)
+ min_dpb = 1;
+
memset(output_buf_req, 0, sizeof(struct vcd_buffer_requirement));
output_buf_req->min_count = min_dpb;
num_mb = DDL_NO_OF_MB(frame_size->width, frame_size->height);
- if (num_mb >= DDL_WVGA_MBS) {
- output_buf_req->actual_count = min_dpb + 2;
- if (output_buf_req->actual_count < 10)
- output_buf_req->actual_count = 10;
- } else
- output_buf_req->actual_count = min_dpb + 5;
-
+ if (decoder->idr_only_decoding) {
+ output_buf_req->actual_count = output_buf_req->min_count;
+ } else {
+ if (num_mb >= DDL_WVGA_MBS) {
+ output_buf_req->actual_count = min_dpb + 2;
+ if (output_buf_req->actual_count < 10)
+ output_buf_req->actual_count = 10;
+ } else
+ output_buf_req->actual_count = min_dpb + 5;
+ }
output_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
output_buf_req->sz = y_cb_cr_size;
if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12)
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 384c3ca..65ca534 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -13,6 +13,9 @@
#include <linux/time.h>
#endif
+#ifdef __KERNEL__
+#include <linux/ion.h>
+#endif
#define MSM_CAM_IOCTL_MAGIC 'm'
#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
@@ -522,6 +525,9 @@
uint32_t frame_id;
int stcam_quality_ind;
uint32_t stcam_conv_value;
+
+ struct ion_allocation_data ion_alloc;
+ struct ion_fd_data fd_data;
};
enum msm_st_frame_packing {
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index a34b774..01b8463 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -149,8 +149,6 @@
}
case AFE_EVENT_RTPORT_STOP:
pr_debug("%s: event!=0\n", __func__);
- prtd->start = 0;
- snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
break;
case AFE_EVENT_RTPORT_LOW_WM:
pr_debug("%s: Underrun\n", __func__);
@@ -215,8 +213,6 @@
}
case AFE_EVENT_RTPORT_STOP:
pr_debug("%s: event!=0\n", __func__);
- prtd->start = 0;
- snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
break;
case AFE_EVENT_RTPORT_LOW_WM:
pr_debug("%s: Underrun\n", __func__);