Merge "msm_fb: display: enable MDP interrupts base on panel interface" into msm-3.0
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 3421fa1..a708fbc 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -33,6 +33,7 @@
CONFIG_ARCH_MSMCOPPER=y
CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_KERNEL_PMEM_EBI_REGION=y
CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
@@ -99,6 +100,8 @@
# CONFIG_BATTERY_MSM is not set
# CONFIG_HWMON is not set
# CONFIG_MFD_SUPPORT is not set
+CONFIG_ION=y
+CONFIG_ION_MSM=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_CI13XXX_MSM=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index a872cdc..07aeb32 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -257,6 +257,7 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_PMIC8XXX=y
CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 3337d06..47736ea 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -258,6 +258,7 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_PMIC8XXX=y
CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 32b4a99..0cec5f2 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -222,6 +222,7 @@
select MSM_SCM if SMP
select MSM_GPIOMUX
select MULTI_IRQ_HANDLER
+ select MSM_MULTIMEDIA_USE_ION
config ARCH_FSM9XXX
bool "FSM9XXX"
@@ -763,7 +764,7 @@
config KERNEL_PMEM_EBI_REGION
bool "Enable in-kernel PMEM region for EBI"
default y if ARCH_MSM8X60
- depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960)
+ depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSMCOPPER)
help
Enable the in-kernel PMEM allocator to use EBI memory.
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index a3ed7ab..6581619 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -222,11 +222,11 @@
obj-$(CONFIG_MACH_MSM7X27_SURF) += board-msm7x27.o devices-msm7x27.o
obj-$(CONFIG_MACH_MSM7X27_FFA) += board-msm7x27.o devices-msm7x27.o
obj-$(CONFIG_ARCH_MSM7X27A) += clock-pcom-lookup.o devices-msm7x27a.o
-obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
+obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 02fff0b..29b8afb 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1159,10 +1159,10 @@
static void __init apq8064_clock_init(void)
{
- if (machine_is_apq8064_sim())
- msm_clock_init(&apq8064_clock_init_data);
- else
+ if (machine_is_apq8064_rumi3())
msm_clock_init(&apq8064_dummy_clock_init_data);
+ else
+ msm_clock_init(&apq8064_clock_init_data);
}
static void __init apq8064_common_init(void)
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index c89aee5..1bfb759 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -19,14 +19,192 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
+#ifdef CONFIG_ION_MSM
+#include <linux/ion.h>
+#endif
+#include <linux/memory.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include <mach/msm_iomap.h>
+#ifdef CONFIG_ION_MSM
+#include <mach/ion.h>
+#endif
+#include <mach/msm_memtypes.h>
#include "clock.h"
+#define MSM_KERNEL_EBI1_MEM_SIZE 0x280000
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_ION_SF_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_ION_SF_SIZE 0x2800000 /* 40 Mbytes */
+#endif
+#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE 0x7800000 /* (120MB) */
+#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
+#define MSM_ION_MFC_SIZE SZ_8K
+#define MSM_ION_AUDIO_SIZE 0x2B4000
+#define MSM_ION_HEAP_NUM 8
+
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned kernel_ebi1_mem_size = MSM_KERNEL_EBI1_MEM_SIZE;
+static int __init kernel_ebi1_mem_size_setup(char *p)
+{
+ kernel_ebi1_mem_size = memparse(p, NULL);
+ return 0;
+}
+early_param("kernel_ebi1_mem_size", kernel_ebi1_mem_size_setup);
+#endif
+
+static struct memtype_reserve msm_copper_reserve_table[] __initdata = {
+ [MEMTYPE_SMI] = {
+ },
+ [MEMTYPE_EBI0] = {
+ .flags = MEMTYPE_FLAGS_1M_ALIGN,
+ },
+ [MEMTYPE_EBI1] = {
+ .flags = MEMTYPE_FLAGS_1M_ALIGN,
+ },
+};
+
+static int msm_copper_paddr_to_memtype(unsigned int paddr)
+{
+ return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+ .permission_type = IPT_TYPE_MM_CARVEOUT,
+ .align = PAGE_SIZE,
+};
+
+static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+ .permission_type = IPT_TYPE_MFC_SHAREDMEM,
+ .align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata co_ion_pdata = {
+ .adjacent_mem_id = INVALID_HEAP_ID,
+ .align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+ .adjacent_mem_id = ION_CP_MM_HEAP_ID,
+ .align = SZ_128K,
+};
+
+static struct ion_platform_data ion_pdata = {
+ .nr = MSM_ION_HEAP_NUM,
+ .heaps = {
+ {
+ .id = ION_SYSTEM_HEAP_ID,
+ .type = ION_HEAP_TYPE_SYSTEM,
+ .name = ION_VMALLOC_HEAP_NAME,
+ },
+ {
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
+ .id = ION_CP_MM_HEAP_ID,
+ .type = ION_HEAP_TYPE_CP,
+ .name = ION_MM_HEAP_NAME,
+ .size = MSM_ION_MM_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &cp_mm_ion_pdata,
+ },
+ {
+ .id = ION_MM_FIRMWARE_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_MM_FIRMWARE_HEAP_NAME,
+ .size = MSM_ION_MM_FW_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &fw_co_ion_pdata,
+ },
+ {
+ .id = ION_CP_MFC_HEAP_ID,
+ .type = ION_HEAP_TYPE_CP,
+ .name = ION_MFC_HEAP_NAME,
+ .size = MSM_ION_MFC_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &cp_mfc_ion_pdata,
+ },
+ {
+ .id = ION_IOMMU_HEAP_ID,
+ .type = ION_HEAP_TYPE_IOMMU,
+ .name = ION_IOMMU_HEAP_NAME,
+ },
+ {
+ .id = ION_QSECOM_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_QSECOM_HEAP_NAME,
+ .size = MSM_ION_QSECOM_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
+ .id = ION_AUDIO_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_AUDIO_HEAP_NAME,
+ .size = MSM_ION_AUDIO_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ }
+};
+
+static struct platform_device ion_dev = {
+ .name = "ion-msm",
+ .id = 1,
+ .dev = { .platform_data = &ion_pdata },
+};
+
+static void reserve_ion_memory(void)
+{
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+ msm_copper_reserve_table[MEMTYPE_EBI1].size += kernel_ebi1_mem_size;
+#endif
+}
+#endif
+
+static void __init msm_copper_calculate_reserve_sizes(void)
+{
+#ifdef CONFIG_ION_MSM
+ reserve_ion_memory();
+#endif
+}
+
+static struct reserve_info msm_copper_reserve_info __initdata = {
+ .memtype_reserve_table = msm_copper_reserve_table,
+ .calculate_reserve_sizes = msm_copper_calculate_reserve_sizes,
+ .paddr_to_memtype = msm_copper_paddr_to_memtype,
+};
+
+static void __init msm_copper_early_memory(void)
+{
+ reserve_info = &msm_copper_reserve_info;
+}
+
+void __init msm_copper_reserve(void)
+{
+ msm_reserve();
+}
+
static int __init gpiomux_init(void)
{
int rc;
@@ -42,6 +220,9 @@
void __init msm_copper_add_devices(void)
{
+#ifdef CONFIG_ION_MSM
+ platform_device_register(&ion_dev);
+#endif
}
static struct of_device_id irq_match[] __initdata = {
@@ -102,3 +283,8 @@
*adata = msm_copper_auxdata_lookup;
}
+
+void __init msm_copper_very_early(void)
+{
+ msm_copper_early_memory();
+}
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 6c5f74a..51ca29d 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -90,6 +90,18 @@
NULL
};
+static void __init msm_dt_reserve(void)
+{
+ if (early_machine_is_copper())
+ msm_copper_reserve();
+}
+
+static void __init msm_dt_init_very_early(void)
+{
+ if (early_machine_is_copper())
+ msm_copper_very_early();
+}
+
DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
.map_io = msm_dt_map_io,
.init_irq = msm_dt_init_irq,
@@ -98,4 +110,6 @@
.timer = &msm_dt_timer,
.dt_compat = msm_dt_match,
.nr_irqs = -1,
+ .reserve = msm_dt_reserve,
+ .init_very_early = msm_dt_init_very_early,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
new file mode 100644
index 0000000..6df7626
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -0,0 +1,368 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_pmapp.h>
+#include "board-msm7627a.h"
+#include "devices-msm7x2xa.h"
+#include "timer.h"
+
+#define GPIO_WLAN_3V3_EN 119
+static const char *id = "WLAN";
+
+enum {
+ WLAN_VREG_S3 = 0,
+ WLAN_VREG_L17,
+ WLAN_VREG_L19
+};
+
+struct wlan_vreg_info {
+ const char *vreg_id;
+ unsigned int level_min;
+ unsigned int level_max;
+ unsigned int pmapp_id;
+ unsigned int is_vreg_pin_controlled;
+ struct regulator *reg;
+};
+
+static struct wlan_vreg_info vreg_info[] = {
+ {"msme1", 1800000, 1800000, 2, 0, NULL},
+ {"bt", 3300000, 3300000, 21, 1, NULL},
+ {"wlan4", 1800000, 1800000, 23, 1, NULL}
+};
+
+int gpio_wlan_sys_rest_en = 134;
+static void gpio_wlan_config(void)
+{
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+ gpio_wlan_sys_rest_en = 124;
+}
+
+static unsigned int qrf6285_init_regs(void)
+{
+ struct regulator_bulk_data regs[ARRAY_SIZE(vreg_info)];
+ int i = 0, rc = 0;
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ regs[i].supply = vreg_info[i].vreg_id;
+ regs[i].min_uV = vreg_info[i].level_min;
+ regs[i].max_uV = vreg_info[i].level_max;
+ }
+
+ rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs);
+ if (rc) {
+ pr_err("%s: could not get regulators: %d\n", __func__, rc);
+ goto out;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++)
+ vreg_info[i].reg = regs[i].consumer;
+
+out:
+ return rc;
+}
+
+static unsigned int setup_wlan_gpio(bool on)
+{
+ int rc = 0;
+
+ if (on) {
+ rc = gpio_direction_output(gpio_wlan_sys_rest_en, 1);
+ msleep(100);
+ } else {
+ gpio_set_value_cansleep(gpio_wlan_sys_rest_en, 0);
+ rc = gpio_direction_input(gpio_wlan_sys_rest_en);
+ msleep(100);
+ }
+
+ if (rc)
+ pr_err("%s: WLAN sys_reset_en GPIO: Error", __func__);
+
+ return rc;
+}
+
+static unsigned int setup_wlan_clock(bool on)
+{
+ int rc = 0;
+
+ if (on) {
+ /* Vote for A0 clock */
+ rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+ PMAPP_CLOCK_VOTE_ON);
+ } else {
+ /* Vote against A0 clock */
+ rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+ PMAPP_CLOCK_VOTE_OFF);
+ }
+
+ if (rc)
+ pr_err("%s: Configuring A0 clock for WLAN: Error", __func__);
+
+ return rc;
+}
+
+static unsigned int wlan_switch_regulators(int on)
+{
+ int rc = 0, index = 0;
+
+ if (machine_is_msm7627a_qrd1())
+ index = 2;
+
+ for ( ; index < ARRAY_SIZE(vreg_info); index++) {
+ if (on) {
+ rc = regulator_set_voltage(vreg_info[index].reg,
+ vreg_info[index].level_min,
+ vreg_info[index].level_max);
+ if (rc) {
+ pr_err("%s:%s set voltage failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
+ goto reg_disable;
+ }
+
+ rc = regulator_enable(vreg_info[index].reg);
+ if (rc) {
+ pr_err("%s:%s vreg enable failed %d\n",
+ __func__, vreg_info[index].vreg_id, rc);
+ goto reg_disable;
+ }
+
+ if (vreg_info[index].is_vreg_pin_controlled) {
+ rc = pmapp_vreg_lpm_pincntrl_vote(id,
+ vreg_info[index].pmapp_id,
+ PMAPP_CLOCK_ID_A0, 1);
+ if (rc) {
+ pr_err("%s:%s pincntrl failed %d\n",
+ __func__,
+ vreg_info[index].vreg_id, rc);
+ goto pin_cnt_fail;
+ }
+ }
+ } else {
+ if (vreg_info[index].is_vreg_pin_controlled) {
+ rc = pmapp_vreg_lpm_pincntrl_vote(id,
+ vreg_info[index].pmapp_id,
+ PMAPP_CLOCK_ID_A0, 0);
+ if (rc) {
+ pr_err("%s:%s pincntrl failed %d\n",
+ __func__,
+ vreg_info[index].vreg_id, rc);
+ goto pin_cnt_fail;
+ }
+ }
+
+ rc = regulator_disable(vreg_info[index].reg);
+ if (rc) {
+ pr_err("%s:%s vreg disable failed %d\n",
+ __func__,
+ vreg_info[index].vreg_id, rc);
+ goto reg_disable;
+ }
+ }
+ }
+ return 0;
+pin_cnt_fail:
+ if (on)
+ regulator_disable(vreg_info[index].reg);
+reg_disable:
+ if (!machine_is_msm7627a_qrd1()) {
+ while (index) {
+ if (on) {
+ index--;
+ regulator_disable(vreg_info[index].reg);
+ regulator_put(vreg_info[index].reg);
+ }
+ }
+ }
+ return rc;
+}
+
+static unsigned int msm_AR600X_setup_power(bool on)
+{
+ int rc = 0;
+ static bool init_done;
+
+ if (unlikely(!init_done)) {
+ gpio_wlan_config();
+ rc = qrf6285_init_regs();
+ if (rc) {
+ pr_err("%s: qrf6285 init failed = %d\n", __func__, rc);
+ return rc;
+ } else {
+ init_done = true;
+ }
+ }
+
+ rc = wlan_switch_regulators(on);
+ if (rc) {
+ pr_err("%s: wlan_switch_regulators error = %d\n", __func__, rc);
+ goto out;
+ }
+
+ /* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+ if (machine_is_msm7627a_qrd1()) {
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto reg_disable;
+ }
+ gpio_set_value(GPIO_WLAN_3V3_EN, 1);
+ }
+
+ /*
+ * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
+ * EVB1.0 and QRD8625,so the below step is required for those devices.
+ */
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto qrd_gpio_fail;
+ }
+ gpio_set_value(gpio_wlan_sys_rest_en, 1);
+ } else {
+ rc = gpio_request(gpio_wlan_sys_rest_en, "WLAN_DEEP_SLEEP_N");
+ if (rc) {
+ pr_err("%s: WLAN sys_rest_en GPIO %d request failed %d\n",
+ __func__,
+ gpio_wlan_sys_rest_en, rc);
+ goto qrd_gpio_fail;
+ }
+ rc = setup_wlan_gpio(on);
+ if (rc) {
+ pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+ goto gpio_fail;
+ }
+ }
+
+ /* Enable the A0 clock */
+ rc = setup_wlan_clock(on);
+ if (rc) {
+ pr_err("%s: setup_wlan_clock = %d\n", __func__, rc);
+ goto set_gpio_fail;
+ }
+
+ /* Configure A0 clock to be slave to WLAN_CLK_PWR_REQ */
+ rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+ PMAPP_CLOCK_VOTE_PIN_CTRL);
+ if (rc) {
+ pr_err("%s: Configuring A0 to Pin controllable failed %d\n",
+ __func__, rc);
+ goto set_clock_fail;
+ }
+
+ pr_info("WLAN power-up success\n");
+ return 0;
+set_clock_fail:
+ setup_wlan_clock(0);
+set_gpio_fail:
+ setup_wlan_gpio(0);
+gpio_fail:
+ gpio_free(gpio_wlan_sys_rest_en);
+qrd_gpio_fail:
+ gpio_free(GPIO_WLAN_3V3_EN);
+reg_disable:
+ wlan_switch_regulators(0);
+out:
+ pr_info("WLAN power-up failed\n");
+ return rc;
+}
+
+static unsigned int msm_AR600X_shutdown_power(bool on)
+{
+ int rc = 0;
+
+ /* Disable the A0 clock */
+ rc = setup_wlan_clock(on);
+ if (rc) {
+ pr_err("%s: setup_wlan_clock = %d\n", __func__, rc);
+ goto set_clock_fail;
+ }
+
+ /*
+ * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
+ * EVB1.0 and QRD8625,so the below step is required for those devices.
+ */
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto gpio_fail;
+ }
+ gpio_set_value(gpio_wlan_sys_rest_en, 0);
+ } else {
+ rc = setup_wlan_gpio(on);
+ if (rc) {
+ pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+ goto set_gpio_fail;
+ }
+ gpio_free(gpio_wlan_sys_rest_en);
+ }
+
+ /* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+ if (machine_is_msm7627a_qrd1()) {
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+ __func__, rc);
+ goto qrd_gpio_fail;
+ }
+ gpio_set_value(GPIO_WLAN_3V3_EN, 0);
+ }
+
+ rc = wlan_switch_regulators(on);
+ if (rc) {
+ pr_err("%s: wlan_switch_regulators error = %d\n",
+ __func__, rc);
+ goto reg_disable;
+ }
+
+ pr_info("WLAN power-down success\n");
+ return 0;
+set_clock_fail:
+ setup_wlan_clock(0);
+set_gpio_fail:
+ setup_wlan_gpio(0);
+gpio_fail:
+ gpio_free(gpio_wlan_sys_rest_en);
+qrd_gpio_fail:
+ gpio_free(GPIO_WLAN_3V3_EN);
+reg_disable:
+ wlan_switch_regulators(0);
+ pr_info("WLAN power-down failed\n");
+ return rc;
+}
+
+int ar600x_wlan_power(bool on)
+{
+ if (on)
+ msm_AR600X_setup_power(on);
+ else
+ msm_AR600X_shutdown_power(on);
+
+ return 0;
+}
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 8b50c53..118798b 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1071,6 +1071,7 @@
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
static int __init msm7x27a_init_ar6000pm(void)
{
+ msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
return platform_device_register(&msm_wlan_ar6000_pm_device);
}
#else
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index f7e908b..5052bb0 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -679,7 +679,6 @@
#ifdef CONFIG_BT
&msm_bt_power_device,
#endif
- &msm_wlan_ar6000_pm_device,
&asoc_msm_pcm,
&asoc_msm_dai0,
&asoc_msm_dai1,
@@ -1011,6 +1010,12 @@
}
}
+static int __init msm_qrd_init_ar6000pm(void)
+{
+ msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
+ return platform_device_register(&msm_wlan_ar6000_pm_device);
+}
+
#define UART1DM_RX_GPIO 45
static void __init msm_qrd_init(void)
{
@@ -1033,6 +1038,8 @@
platform_add_devices(qrd_common_devices,
ARRAY_SIZE(qrd_common_devices));
+ /* Ensure ar6000pm device is registered before MMC/SDC */
+ msm_qrd_init_ar6000pm();
msm7627a_init_mmc();
#ifdef CONFIG_USB_EHCI_MSM_72K
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index e16cac5..a2abb25 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4812,13 +4812,16 @@
};
static struct clk_lookup msm_clocks_8064[] = {
- CLK_LOOKUP("cxo", cxo_clk.c, NULL),
- CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
- CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
- CLK_LOOKUP("pll2", pll2_clk.c, NULL),
- CLK_LOOKUP("pll8", pll8_clk.c, NULL),
- CLK_LOOKUP("pll4", pll4_clk.c, NULL),
- CLK_LOOKUP("measure", measure_clk.c, "debug"),
+ CLK_LOOKUP("cxo", cxo_clk.c, NULL),
+ CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
+ CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
+ CLK_LOOKUP("xo", pxo_clk.c, "pil_qdsp6v4.0"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
+ CLK_LOOKUP("pll2", pll2_clk.c, NULL),
+ CLK_LOOKUP("pll8", pll8_clk.c, NULL),
+ CLK_LOOKUP("pll4", pll4_clk.c, NULL),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
CLK_DUMMY("bus_clk", AFAB_CLK, "msm_apps_fab", 0),
CLK_DUMMY("bus_a_clk", AFAB_A_CLK, "msm_apps_fab", 0),
@@ -5051,13 +5054,16 @@
};
static struct clk_lookup msm_clocks_8960_v1[] __initdata = {
- CLK_LOOKUP("cxo", cxo_clk.c, NULL),
- CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
- CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
- CLK_LOOKUP("pll2", pll2_clk.c, NULL),
- CLK_LOOKUP("pll8", pll8_clk.c, NULL),
- CLK_LOOKUP("pll4", pll4_clk.c, NULL),
- CLK_LOOKUP("measure", measure_clk.c, "debug"),
+ CLK_LOOKUP("cxo", cxo_clk.c, NULL),
+ CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
+ CLK_LOOKUP("cxo", cxo_clk.c, "pil_riva"),
+ CLK_LOOKUP("xo", pxo_clk.c, "pil_qdsp6v4.0"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
+ CLK_LOOKUP("pll2", pll2_clk.c, NULL),
+ CLK_LOOKUP("pll8", pll8_clk.c, NULL),
+ CLK_LOOKUP("pll4", pll4_clk.c, NULL),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
CLK_LOOKUP("bus_clk", afab_clk.c, "msm_apps_fab"),
CLK_LOOKUP("bus_a_clk", afab_a_clk.c, "msm_apps_fab"),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 94fafda..17f5d01 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3520,6 +3520,7 @@
static struct clk_lookup msm_clocks_8x60[] = {
CLK_LOOKUP("cxo", cxo_clk.c, NULL),
+ CLK_LOOKUP("xo", pxo_clk.c, "pil_modem"),
CLK_LOOKUP("pll4", pll4_clk.c, "pil_qdsp6v3"),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 0ced722..872d9d4 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -30,7 +30,6 @@
#include <mach/rpm.h>
#include <mach/msm_bus_board.h>
#include <mach/msm_memtypes.h>
-#include <mach/msm_xo.h>
#include <sound/msm-dai-q6.h>
#include <sound/apr_audio.h>
#include "clock.h"
@@ -843,7 +842,6 @@
.strap_ahb_upper = 0x00290000,
.strap_ahb_lower = 0x00000280,
.aclk_reg = SFAB_LPASS_Q6_ACLK_CTL,
- .xo_id = MSM_XO_PXO,
.name = "q6",
.pas_id = PAS_Q6,
.bus_port = MSM_BUS_MASTER_LPASS_PROC,
@@ -881,7 +879,6 @@
.strap_ahb_lower = 0x00000080,
.aclk_reg = SFAB_MSS_Q6_FW_ACLK_CTL,
.jtag_clk_reg = MSS_Q6FW_JTAG_CLK_CTL,
- .xo_id = MSM_XO_CXO,
.name = "modem_fw",
.depends = "q6",
.pas_id = PAS_MODEM_FW,
@@ -919,7 +916,6 @@
.strap_ahb_lower = 0x00000080,
.aclk_reg = SFAB_MSS_Q6_SW_ACLK_CTL,
.jtag_clk_reg = MSS_Q6SW_JTAG_CLK_CTL,
- .xo_id = MSM_XO_CXO,
.name = "modem",
.depends = "modem_fw",
.pas_id = PAS_MODEM_SW,
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index a59ade3..be6a645 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -25,4 +25,5 @@
extern struct platform_device msm7x27a_device_clkctl;
void __init msm8625_init_irq(void);
void __init msm8625_map_io(void);
+int ar600x_wlan_power(bool on);
#endif
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 76b7dac..c7ef271 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -470,6 +470,8 @@
void msm_init_irq(void);
void msm_copper_init_irq(void);
void vic_handle_irq(struct pt_regs *regs);
+void msm_copper_reserve(void);
+void msm_copper_very_early(void);
struct mmc_platform_data;
int msm_add_sdcc(unsigned int controller,
diff --git a/arch/arm/mach-msm/include/mach/qpnp-int.h b/arch/arm/mach-msm/include/mach/qpnp-int.h
new file mode 100644
index 0000000..a79d2fc
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qpnp-int.h
@@ -0,0 +1,83 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef QPNPINT_H
+#define QPNPINT_H
+
+#include <linux/spmi.h>
+
+struct qpnp_irq_spec {
+ uint8_t slave; /* 0-15 */
+ uint8_t per; /* 0-255 */
+ uint8_t irq; /* 0-7 */
+};
+
+struct qpnp_local_int {
+ /* mask - Invoke PMIC Arbiter local mask handler */
+ int (*mask)(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec,
+ uint32_t priv_d);
+ /* unmask - Invoke PMIC Arbiter local unmask handler */
+ int (*unmask)(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec,
+ uint32_t priv_d);
+ /* register_priv_data - Return per irq priv data */
+ int (*register_priv_data)(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec,
+ uint32_t *priv_d);
+};
+
+#ifdef CONFIG_MSM_QPNP_INT
+/**
+ * qpnpint_of_init() - Device Tree irq initialization
+ *
+ * Standard Device Tree init routine to be called from
+ * of_irq_init().
+ */
+int __init qpnpint_of_init(struct device_node *node,
+ struct device_node *parent);
+
+/**
+ * qpnpint_register_controller() - Register local interrupt callbacks
+ *
+ * Used by the PMIC Arbiter driver or equivalent to register
+ * callbacks for interrupt events.
+ */
+int qpnpint_register_controller(unsigned int busno,
+ struct qpnp_local_int *li_cb);
+
+/**
+ * qpnpint_handle_irq - Main interrupt handling routine
+ *
+ * Pass a PMIC Arbiter interrupt to Linux.
+ */
+int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec);
+#else
+static inline int __init qpnpint_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return -ENXIO;
+}
+static inline int qpnpint_register_controller(unsigned int busno,
+ struct qpnp_local_int *li_cb)
+{
+ return -ENXIO;
+}
+
+static inline int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
+ struct qpnp_irq_spec *spec)
+{
+ return -ENXIO;
+}
+#endif /* CONFIG_MSM_QPNP_INT */
+#endif /* QPNPINT_H */
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 093d044..4b0d26a 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -27,6 +27,7 @@
#include <net/sock.h>
#include <mach/peripheral-loader.h>
+#include <mach/socinfo.h>
#include "ipc_router.h"
@@ -46,11 +47,18 @@
static void *msm_ipc_router_load_modem(void)
{
- void *pil;
+ void *pil = NULL;
int rc;
- pil = pil_get("modem");
- if (IS_ERR(pil)) {
+ /* Load GNSS for Standalone 8064 but not for Fusion 3 */
+ if (cpu_is_apq8064()) {
+ if (socinfo_get_platform_subtype() == 0x0)
+ pil = pil_get("gnss");
+ } else {
+ pil = pil_get("modem");
+ }
+
+ if (IS_ERR(pil) || !pil) {
pr_debug("%s: modem load failed\n", __func__);
pil = NULL;
} else {
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 11b9092..5eccf06 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -66,6 +66,28 @@
.notifier_call = riva_notifier_cb,
};
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+ void *ss_handle)
+{
+ int ret;
+ switch (code) {
+ case SUBSYS_BEFORE_SHUTDOWN:
+ pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+ ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+ SUBSYS_BEFORE_SHUTDOWN);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event error %d", __func__,
+ ret);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+ .notifier_call = modem_notifier_cb,
+};
+
static void lpass_fatal_fn(struct work_struct *work)
{
pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
@@ -213,6 +235,18 @@
goto out;
}
+ ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+ &mnb);
+ if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+ ret = PTR_ERR(ssr_modem_notif_hdle);
+ pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+ __func__, ret);
+ subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ iounmap(q6_wakeup_intr);
+ free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+ goto out;
+ }
+
pr_info("%s: lpass SSR driver init'ed.\n", __func__);
out:
return ret;
@@ -221,6 +255,7 @@
static void __exit lpass_fatal_exit(void)
{
subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
iounmap(q6_wakeup_intr);
free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
}
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 5aa3834..1d13508 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -18,9 +18,10 @@
#include <linux/elf.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
#include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -52,8 +53,8 @@
struct modem_data {
void __iomem *base;
unsigned long start_addr;
- struct msm_xo_voter *pxo;
- struct timer_list timer;
+ struct clk *xo;
+ struct delayed_work work;
};
static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
@@ -61,28 +62,30 @@
return 0;
}
-static void remove_proxy_votes(unsigned long data)
-{
- struct modem_data *drv = (struct modem_data *)data;
- msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_OFF);
-}
-
-static void make_modem_proxy_votes(struct device *dev)
+static int make_modem_proxy_votes(struct device *dev)
{
int ret;
struct modem_data *drv = dev_get_drvdata(dev);
- ret = msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_ON);
- if (ret)
- dev_err(dev, "Failed to enable PXO\n");
- mod_timer(&drv->timer, jiffies + msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(dev, "Failed to enable XO\n");
+ return ret;
+ }
+ schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+}
+
+static void remove_modem_proxy_votes(struct work_struct *work)
+{
+ struct modem_data *drv;
+ drv = container_of(work, struct modem_data, work.work);
+ clk_disable_unprepare(drv->xo);
}
static void remove_modem_proxy_votes_now(struct modem_data *drv)
{
- /* If the proxy vote hasn't been removed yet, remove it immediately. */
- if (del_timer(&drv->timer))
- remove_proxy_votes((unsigned long)drv);
+ flush_delayed_work(&drv->work);
}
static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -97,9 +100,12 @@
static int modem_reset(struct pil_desc *pil)
{
u32 reg;
+ int ret;
const struct modem_data *drv = dev_get_drvdata(pil->dev);
- make_modem_proxy_votes(pil->dev);
+ ret = make_modem_proxy_votes(pil->dev);
+ if (ret)
+ return ret;
/* Put modem AHB0,1,2 clocks into reset */
writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
@@ -235,7 +241,9 @@
int ret;
struct modem_data *drv = dev_get_drvdata(pil->dev);
- make_modem_proxy_votes(pil->dev);
+ ret = make_modem_proxy_votes(pil->dev);
+ if (ret)
+ return ret;
ret = pas_auth_and_reset(PAS_MODEM);
if (ret)
@@ -269,6 +277,7 @@
struct modem_data *drv;
struct resource *res;
struct pil_desc *desc;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -283,15 +292,14 @@
if (!drv->base)
return -ENOMEM;
- drv->pxo = msm_xo_get(MSM_XO_PXO, dev_name(&pdev->dev));
- if (IS_ERR(drv->pxo))
- return PTR_ERR(drv->pxo);
+ drv->xo = clk_get(&pdev->dev, "xo");
+ if (IS_ERR(drv->xo))
+ return PTR_ERR(drv->xo);
desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
- setup_timer(&drv->timer, remove_proxy_votes, (unsigned long)drv);
desc->name = "modem";
desc->depends_on = "q6";
desc->dev = &pdev->dev;
@@ -303,19 +311,21 @@
desc->ops = &pil_modem_ops;
dev_info(&pdev->dev, "using non-secure boot\n");
}
+ INIT_DELAYED_WORK(&drv->work, remove_modem_proxy_votes);
- if (msm_pil_register(desc)) {
- msm_xo_put(drv->pxo);
- return -EINVAL;
+ ret = msm_pil_register(desc);
+ if (ret) {
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
}
- return 0;
+ return ret;
}
static int __devexit pil_modem_driver_exit(struct platform_device *pdev)
{
struct modem_data *drv = platform_get_drvdata(pdev);
- del_timer_sync(&drv->timer);
- msm_xo_put(drv->pxo);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
return 0;
}
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index cdbfc48..511377d 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -20,10 +20,10 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/workqueue.h>
+#include <linux/clk.h>
#include <mach/msm_bus.h>
#include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
#include "peripheral-loader.h"
#include "pil-q6v4.h"
@@ -71,7 +71,7 @@
struct regulator *vreg;
struct regulator *pll_supply;
bool vreg_enabled;
- struct msm_xo_voter *xo;
+ struct clk *xo;
struct delayed_work work;
};
@@ -89,18 +89,29 @@
return 0;
}
-static void pil_q6v4_make_proxy_votes(struct device *dev)
+static int pil_q6v4_make_proxy_votes(struct device *dev)
{
struct q6v4_data *drv = dev_get_drvdata(dev);
int ret;
- msm_xo_mode_vote(drv->xo, MSM_XO_MODE_ON);
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(dev, "Failed to enable XO\n");
+ goto err;
+ }
if (drv->pll_supply) {
ret = regulator_enable(drv->pll_supply);
- if (ret)
- dev_err(dev, "failed to enable pll supply\n");
+ if (ret) {
+ dev_err(dev, "Failed to enable pll supply\n");
+ goto err_regulator;
+ }
}
schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+err_regulator:
+ clk_disable_unprepare(drv->xo);
+err:
+ return ret;
}
static void pil_q6v4_remove_proxy_votes(struct work_struct *work)
@@ -108,7 +119,7 @@
struct q6v4_data *drv = container_of(work, struct q6v4_data, work.work);
if (drv->pll_supply)
regulator_disable(drv->pll_supply);
- msm_xo_mode_vote(drv->xo, MSM_XO_MODE_OFF);
+ clk_disable_unprepare(drv->xo);
}
static void pil_q6v4_remove_proxy_votes_now(struct device *dev)
@@ -191,7 +202,9 @@
const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
- pil_q6v4_make_proxy_votes(pil->dev);
+ err = pil_q6v4_make_proxy_votes(pil->dev);
+ if (err)
+ return err;
err = pil_q6v4_power_up(pil->dev);
if (err)
@@ -331,7 +344,9 @@
const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
int err;
- pil_q6v4_make_proxy_votes(pil->dev);
+ err = pil_q6v4_make_proxy_votes(pil->dev);
+ if (err)
+ return err;
err = pil_q6v4_power_up(pil->dev);
if (err)
@@ -442,7 +457,7 @@
goto err;
}
- drv->xo = msm_xo_get(pdata->xo_id, pdata->name);
+ drv->xo = clk_get(&pdev->dev, "xo");
if (IS_ERR(drv->xo)) {
ret = PTR_ERR(drv->xo);
goto err_xo;
@@ -454,8 +469,8 @@
goto err_pil;
return 0;
err_pil:
- cancel_delayed_work_sync(&drv->work);
- msm_xo_put(drv->xo);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
err_xo:
regulator_put(drv->vreg);
err:
@@ -466,8 +481,8 @@
static int __devexit pil_q6v4_driver_exit(struct platform_device *pdev)
{
struct q6v4_data *drv = platform_get_drvdata(pdev);
- cancel_delayed_work_sync(&drv->work);
- msm_xo_put(drv->xo);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
regulator_put(drv->vreg);
regulator_put(drv->pll_supply);
return 0;
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
index 54bdf88..b0b97d0 100644
--- a/arch/arm/mach-msm/pil-q6v4.h
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -18,7 +18,6 @@
const unsigned long strap_ahb_lower;
void __iomem *aclk_reg;
void __iomem *jtag_clk_reg;
- const int xo_id;
const char *name;
const char *depends;
const unsigned pas_id;
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 7e78a15..29a9df9 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -88,20 +88,29 @@
struct regulator *pll_supply;
};
-static void pil_riva_make_proxy_votes(struct device *dev)
+static int pil_riva_make_proxy_votes(struct device *dev)
{
struct riva_data *drv = dev_get_drvdata(dev);
int ret;
+ ret = regulator_enable(drv->pll_supply);
+ if (ret) {
+ dev_err(dev, "failed to enable pll supply\n");
+ goto err;
+ }
if (drv->use_cxo) {
ret = clk_prepare_enable(drv->xo);
- if (ret)
+ if (ret) {
dev_err(dev, "failed to enable xo\n");
+ goto err_clk;
+ }
}
- ret = regulator_enable(drv->pll_supply);
- if (ret)
- dev_err(dev, "failed to enable pll supply\n");
schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+err_clk:
+ regulator_disable(drv->pll_supply);
+err:
+ return ret;
}
static void pil_riva_remove_proxy_votes(struct work_struct *work)
@@ -156,7 +165,14 @@
writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
drv->use_cxo = cxo_is_needed(drv);
- pil_riva_make_proxy_votes(pil->dev);
+ ret = pil_riva_make_proxy_votes(pil->dev);
+ if (ret) {
+ reg &= ~RIVA_PMU_A2XB_CFG_EN;
+ writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
+ mb();
+ clk_disable_unprepare(drv->xo);
+ return ret;
+ }
/* Program PLL 13 to 960 MHz */
reg = readl_relaxed(RIVA_PLL_MODE);
@@ -298,8 +314,9 @@
if (ret)
return ret;
/* Proxy-vote for resources RIVA needs */
- pil_riva_make_proxy_votes(pil->dev);
- ret = pas_auth_and_reset(PAS_RIVA);
+ ret = pil_riva_make_proxy_votes(pil->dev);
+ if (!ret)
+ ret = pas_auth_and_reset(PAS_RIVA);
clk_disable_unprepare(drv->xo);
return ret;
}
@@ -390,7 +407,7 @@
goto err_register;
return 0;
err_register:
- cancel_delayed_work_sync(&drv->work);
+ flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
err:
regulator_put(drv->pll_supply);
@@ -400,7 +417,7 @@
static int __devexit pil_riva_remove(struct platform_device *pdev)
{
struct riva_data *drv = platform_get_drvdata(pdev);
- cancel_delayed_work_sync(&drv->work);
+ flush_delayed_work_sync(&drv->work);
clk_put(drv->xo);
regulator_put(drv->pll_supply);
return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 2e61e90..ce5d084 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -783,6 +783,7 @@
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
store_audvol_cal(TX_CAL, data);
+ break;
case AUDIO_SET_AUDPROC_RX_VOL_CAL:
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
diff --git a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
index 7096669..f02e0a0 100644
--- a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
+++ b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
@@ -1906,6 +1906,7 @@
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0xAC)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0xAC)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x24)}, \
+ {ADIE_CODEC_ACTION_DELAY_WAIT, 0x4E1F}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \
{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 523d3b6..b5e2092 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -152,29 +152,31 @@
#define CLK_PERIOD_MIN NSEC_19P2MHZ
#define CLK_PERIOD_MAX NSEC_1024HZ
-#define NUM_LPG_PRE_DIVIDE 3 /* No default support for pre-divide = 6 */
+#define NUM_LPG_PRE_DIVIDE 4
#define NUM_PWM_PRE_DIVIDE 2
-#define PRE_DIVIDE_0 2
-#define PRE_DIVIDE_1 3
-#define PRE_DIVIDE_2 5
-
-#define PRE_DIVIDE_MIN PRE_DIVIDE_0
-#define PRE_DIVIDE_MAX PRE_DIVIDE_2
+#define PRE_DIVIDE_2 2
+#define PRE_DIVIDE_3 3
+#define PRE_DIVIDE_5 5
+#define PRE_DIVIDE_6 6
static unsigned int pt_t[NUM_LPG_PRE_DIVIDE][NUM_CLOCKS] = {
- { PRE_DIVIDE_0 * NSEC_1024HZ,
- PRE_DIVIDE_0 * NSEC_32768HZ,
- PRE_DIVIDE_0 * NSEC_19P2MHZ,
- },
- { PRE_DIVIDE_1 * NSEC_1024HZ,
- PRE_DIVIDE_1 * NSEC_32768HZ,
- PRE_DIVIDE_1 * NSEC_19P2MHZ,
- },
{ PRE_DIVIDE_2 * NSEC_1024HZ,
PRE_DIVIDE_2 * NSEC_32768HZ,
PRE_DIVIDE_2 * NSEC_19P2MHZ,
},
+ { PRE_DIVIDE_3 * NSEC_1024HZ,
+ PRE_DIVIDE_3 * NSEC_32768HZ,
+ PRE_DIVIDE_3 * NSEC_19P2MHZ,
+ },
+ { PRE_DIVIDE_5 * NSEC_1024HZ,
+ PRE_DIVIDE_5 * NSEC_32768HZ,
+ PRE_DIVIDE_5 * NSEC_19P2MHZ,
+ },
+ { PRE_DIVIDE_6 * NSEC_1024HZ,
+ PRE_DIVIDE_6 * NSEC_32768HZ,
+ PRE_DIVIDE_6 * NSEC_19P2MHZ,
+ },
};
/* Private data */
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 1ac301f..6733396 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -25,6 +25,8 @@
#define SLIM_HDL_TO_FLOW(hdl) (((u32)(hdl) & 0xFF0000) >> 16)
#define SLIM_HDL_TO_PORT(hdl) ((u32)(hdl) & 0xFF)
+#define SLIM_HDL_TO_CHIDX(hdl) ((u16)(hdl) & 0xFF)
+
#define SLIM_SLAVE_PORT(p, la) (((la)<<16) | (p))
#define SLIM_MGR_PORT(p) ((0xFF << 16) | (p))
#define SLIM_LA_MANAGER 0xFF
@@ -1104,75 +1106,117 @@
}
/*
- * slim_connect_ports: Connect port(s) to channel.
+ * slim_connect_src: Connect source port to channel.
* @sb: client handle
- * @srch: source handles to be connected to this channel
- * @nrsc: number of source ports
- * @sinkh: sink handle to be connected to this channel
+ * @srch: source handle to be connected to this channel
* @chanh: Channel with which the ports need to be associated with.
- * Per slimbus specification, a channel may have multiple source-ports and 1
- * sink port.Channel specified in chanh needs to be allocated first.
+ * Per slimbus specification, a channel may have 1 source port.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if source is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
*/
-int slim_connect_ports(struct slim_device *sb, u32 *srch, int nsrc, u32 sinkh,
- u16 chanh)
+int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh)
+{
+ struct slim_controller *ctrl = sb->ctrl;
+ int ret;
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+ struct slim_ich *slc = &ctrl->chans[chan];
+ enum slim_port_flow flow = SLIM_HDL_TO_FLOW(srch);
+
+ if (flow != SLIM_SRC)
+ return -EINVAL;
+
+ mutex_lock(&ctrl->m_ctrl);
+
+ if (slc->state == SLIM_CH_FREE) {
+ ret = -ENOTCONN;
+ goto connect_src_err;
+ }
+ /*
+ * Once channel is removed, its ports can be considered disconnected
+ * So its ports can be reassigned. Source port is zeroed
+ * when channel is deallocated.
+ */
+ if (slc->srch) {
+ ret = -EALREADY;
+ goto connect_src_err;
+ }
+
+ ret = connect_port_ch(ctrl, chan, srch, SLIM_SRC);
+
+ if (!ret)
+ slc->srch = srch;
+
+connect_src_err:
+ mutex_unlock(&ctrl->m_ctrl);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(slim_connect_src);
+
+/*
+ * slim_connect_sink: Connect sink port(s) to channel.
+ * @sb: client handle
+ * @sinkh: sink handle(s) to be connected to this channel
+ * @nsink: number of sinks
+ * @chanh: Channel with which the ports need to be associated with.
+ * Per slimbus specification, a channel may have multiple sink-ports.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if sink is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
+ */
+int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink, u16 chanh)
{
struct slim_controller *ctrl = sb->ctrl;
int j;
int ret = 0;
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
struct slim_ich *slc = &ctrl->chans[chan];
+ if (!sinkh || !nsink)
+ return -EINVAL;
+
mutex_lock(&ctrl->m_ctrl);
- /* Make sure the channel is not already pending reconf. or active */
- if (slc->state >= SLIM_CH_PENDING_ACTIVE) {
- dev_err(&ctrl->dev, "Channel %d already active", chan);
- ret = -EISCONN;
- goto connect_port_err;
- }
/*
* Once channel is removed, its ports can be considered disconnected
- * So its ports can be reassigned. Source port array is freed
- * when channel is deallocated.
+ * So its ports can be reassigned. Sink ports are freed when channel
+ * is deallocated.
*/
- slc->srch = krealloc(slc->srch, (sizeof(u32) * nsrc), GFP_KERNEL);
- if (!slc->srch) {
- ret = -ENOMEM;
- goto connect_port_err;
+ if (slc->state == SLIM_CH_FREE) {
+ ret = -ENOTCONN;
+ goto connect_sink_err;
}
- /* connect source */
- for (j = 0; j < nsrc; j++) {
- ret = connect_port_ch(ctrl, chan, srch[j], SLIM_SRC);
+ for (j = 0; j < nsink; j++) {
+ enum slim_port_flow flow = SLIM_HDL_TO_FLOW(sinkh[j]);
+ if (flow != SLIM_SINK)
+ ret = -EINVAL;
+ else
+ ret = connect_port_ch(ctrl, chan, sinkh[j], SLIM_SINK);
if (ret) {
- for ( ; j >= 0 ; j--)
- disconnect_port_ch(ctrl,
- srch[j]);
- kfree(slc->srch);
- slc->srch = NULL;
- goto connect_port_err;
+ for (j = j - 1; j >= 0; j--)
+ disconnect_port_ch(ctrl, sinkh[j]);
+ goto connect_sink_err;
}
}
- /* connect sink */
- ret = connect_port_ch(ctrl, chan, sinkh, SLIM_SINK);
- if (ret) {
- for (j = 0; j < nsrc; j++)
- disconnect_port_ch(ctrl, srch[j]);
- kfree(slc->srch);
- slc->srch = NULL;
- goto connect_port_err;
+
+ slc->sinkh = krealloc(slc->sinkh, (sizeof(u32) * (slc->nsink + nsink)),
+ GFP_KERNEL);
+ if (!slc->sinkh) {
+ ret = -ENOMEM;
+ for (j = 0; j < nsink; j++)
+ disconnect_port_ch(ctrl, sinkh[j]);
+ goto connect_sink_err;
}
- memcpy(slc->srch, srch, (sizeof(u32) * nsrc));
- slc->nsrc = nsrc;
- if (sinkh)
- slc->sinkh = sinkh;
+ memcpy(slc->sinkh + slc->nsink, sinkh, (sizeof(u32) * nsink));
+ slc->nsink += nsink;
-connect_port_err:
+connect_sink_err:
mutex_unlock(&ctrl->m_ctrl);
return ret;
}
-EXPORT_SYMBOL_GPL(slim_connect_ports);
+EXPORT_SYMBOL_GPL(slim_connect_sink);
/*
* slim_disconnect_ports: Disconnect port(s) from channel
@@ -1332,8 +1376,8 @@
slc->state = SLIM_CH_ALLOCATED;
slc->newintr = 0;
slc->newoff = 0;
- for (i = 0; i < slc->nsrc; i++) {
- ph = slc->srch[i];
+ for (i = 0; i < slc->nsink; i++) {
+ ph = slc->sinkh[i];
la = SLIM_HDL_TO_LA(ph);
/*
* For ports managed by manager's ported device, no need to send
@@ -1344,11 +1388,15 @@
ctrl->ports[SLIM_HDL_TO_PORT(ph)].state = SLIM_P_UNCFG;
}
- ph = slc->sinkh;
+ ph = slc->srch;
la = SLIM_HDL_TO_LA(ph);
if (la == SLIM_LA_MANAGER)
ctrl->ports[SLIM_HDL_TO_PORT(ph)].state = SLIM_P_UNCFG;
+ kfree(slc->sinkh);
+ slc->sinkh = NULL;
+ slc->srch = 0;
+ slc->nsink = 0;
return 0;
}
@@ -1608,7 +1656,7 @@
int slim_dealloc_ch(struct slim_device *sb, u16 chanh)
{
struct slim_controller *ctrl = sb->ctrl;
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
struct slim_ich *slc = &ctrl->chans[chan];
if (!ctrl)
return -EINVAL;
@@ -1631,8 +1679,6 @@
return -EISCONN;
}
slc->ref--;
- kfree(slc->srch);
- slc->srch = NULL;
slc->state = SLIM_CH_FREE;
mutex_unlock(&ctrl->m_ctrl);
dev_dbg(&ctrl->dev, "remove chan:%d,hdl:%d,ref:%d",
@@ -1647,7 +1693,7 @@
*/
enum slim_ch_state slim_get_ch_state(struct slim_device *sb, u16 chanh)
{
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
struct slim_ich *slc = &sb->ctrl->chans[chan];
return slc->state;
}
@@ -1678,7 +1724,7 @@
return -EINVAL;
mutex_lock(&ctrl->m_ctrl);
for (i = 0; i < nchan; i++) {
- u8 chan = (u8)(chanh[i] & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
struct slim_ich *slc = &ctrl->chans[chan];
dev_dbg(&ctrl->dev, "define_ch: ch:%d, state:%d", chan,
(int)ctrl->chans[chan].state);
@@ -1713,7 +1759,7 @@
if (grp)
*grph = chanh[0];
for (i = 0; i < nchan; i++) {
- u8 chan = (u8)(chanh[i] & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
struct slim_ich *slc = &ctrl->chans[chan];
if (slc->state == SLIM_CH_ALLOCATED)
slc->state = SLIM_CH_DEFINED;
@@ -2265,7 +2311,7 @@
for (; last > 0; last--) {
struct slim_ich *slc1 = slc;
struct slim_ich *slc2;
- u8 next = (u8)(slc1->nextgrp & 0xFF);
+ u8 next = SLIM_HDL_TO_CHIDX(slc1->nextgrp);
slc2 = &ctrl->chans[next];
for (second = 1; second <= last && slc2 &&
(slc2->state == SLIM_CH_ACTIVE ||
@@ -2280,7 +2326,7 @@
break;
}
slc1 = slc2;
- next = (u8)(slc1->nextgrp & 0xFF);
+ next = SLIM_HDL_TO_CHIDX(slc1->nextgrp);
slc2 = &ctrl->chans[next];
}
if (slc2 == NULL)
@@ -2692,7 +2738,7 @@
struct slim_ich *slc;
int ret = 0;
/* Get rid of the group flag in MSB if any */
- u8 chan = (u8)(chanh & 0xFF);
+ u8 chan = SLIM_HDL_TO_CHIDX(chanh);
mutex_lock(&sb->sldev_reconf);
mutex_lock(&ctrl->m_ctrl);
do {
@@ -2729,7 +2775,7 @@
}
if (!(slc->nextgrp & SLIM_END_GRP))
- chan = (u8)(slc->nextgrp & 0xFF);
+ chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
} while (!(slc->nextgrp & SLIM_END_GRP));
mutex_unlock(&ctrl->m_ctrl);
if (!ret && commit == true)
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index ee7a2a9..c0c6c1e 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1493,6 +1493,7 @@
}
static struct platform_driver android_platform_driver = {
+ .probe = android_probe,
.driver = { .name = "android_usb"},
};
@@ -1527,7 +1528,7 @@
composite_driver.setup = android_setup;
composite_driver.disconnect = android_disconnect;
- ret = platform_driver_probe(&android_platform_driver, android_probe);
+ ret = platform_driver_register(&android_platform_driver);
if (ret) {
pr_err("%s(): Failed to register android"
"platform driver\n", __func__);
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index edba510..a55fc77 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -59,7 +59,7 @@
struct grmnet *port_usb;
spinlock_t port_lock;
- struct work_struct connect_w;
+ struct delayed_work connect_w;
};
static struct rmnet_ctrl_ports {
@@ -320,7 +320,7 @@
static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
{
struct rmnet_ctrl_port *port =
- container_of(w, struct rmnet_ctrl_port, connect_w);
+ container_of(w, struct rmnet_ctrl_port, connect_w.work);
struct smd_ch_info *c = &port->ctrl_ch;
unsigned long flags;
int ret;
@@ -332,8 +332,16 @@
ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
if (ret) {
- pr_err("%s: Unable to open smd ch:%s err:%d\n",
- __func__, c->name, ret);
+ if (ret == -EAGAIN) {
+ /* port not ready - retry */
+ pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
+ __func__, c->name, ret);
+ queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
+ msecs_to_jiffies(250));
+ } else {
+ pr_err("%s: unable to open smd port:%s err:%d\n",
+ __func__, c->name, ret);
+ }
return;
}
@@ -370,7 +378,7 @@
gr->notify_modem = gsmd_ctrl_send_cbits_tomodem;
spin_unlock_irqrestore(&port->port_lock, flags);
- queue_work(grmnet_ctrl_wq, &port->connect_w);
+ queue_delayed_work(grmnet_ctrl_wq, &port->connect_w, 0);
return 0;
}
@@ -442,7 +450,8 @@
/* if usb is online, try opening smd_ch */
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_usb)
- queue_work(grmnet_ctrl_wq, &port->connect_w);
+ queue_delayed_work(grmnet_ctrl_wq,
+ &port->connect_w, 0);
spin_unlock_irqrestore(&port->port_lock, flags);
break;
@@ -503,7 +512,7 @@
port->port_num = portno;
spin_lock_init(&port->port_lock);
- INIT_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
+ INIT_DELAYED_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
c = &port->ctrl_ch;
c->name = rmnet_ctrl_names[portno];
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 795d1e3..c32ac81 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -255,11 +255,11 @@
VCDRES_MSG_LOW("%s(): Enabling the clocks\n", __func__);
if (resource_context.vcodec_clk &&
resource_context.vcodec_pclk) {
- if (clk_enable(resource_context.vcodec_pclk)) {
+ if (clk_prepare_enable(resource_context.vcodec_pclk)) {
VCDRES_MSG_ERROR("vidc pclk Enable fail\n");
goto bail_out;
}
- if (clk_enable(resource_context.vcodec_clk)) {
+ if (clk_prepare_enable(resource_context.vcodec_clk)) {
VCDRES_MSG_ERROR("vidc core clk Enable fail\n");
goto vidc_disable_pclk;
}
@@ -275,7 +275,7 @@
mutex_unlock(&resource_context.lock);
return true;
vidc_disable_pclk:
- clk_disable(resource_context.vcodec_pclk);
+ clk_disable_unprepare(resource_context.vcodec_pclk);
bail_out:
mutex_unlock(&resource_context.lock);
return false;
@@ -322,9 +322,9 @@
VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__);
resource_context.clock_enabled = 0;
if (resource_context.vcodec_clk)
- clk_disable(resource_context.vcodec_clk);
+ clk_disable_unprepare(resource_context.vcodec_clk);
if (resource_context.vcodec_pclk)
- clk_disable(resource_context.vcodec_pclk);
+ clk_disable_unprepare(resource_context.vcodec_pclk);
status = true;
}
mutex_unlock(&resource_context.lock);
@@ -696,7 +696,7 @@
ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk);
}
if (!ret) {
- ret = clk_enable(vidc_mmu_clks[i].mmu_clk);
+ ret = clk_prepare_enable(vidc_mmu_clks[i].mmu_clk);
if (ret) {
clk_put(vidc_mmu_clks[i].mmu_clk);
vidc_mmu_clks[i].mmu_clk = NULL;
@@ -704,7 +704,7 @@
}
if (ret) {
for (i--; i >= 0; i--) {
- clk_disable(vidc_mmu_clks[i].mmu_clk);
+ clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk);
clk_put(vidc_mmu_clks[i].mmu_clk);
vidc_mmu_clks[i].mmu_clk = NULL;
}
@@ -725,7 +725,7 @@
}
resource_context.mmu_clks_on = 0;
for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
- clk_disable(vidc_mmu_clks[i].mmu_clk);
+ clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk);
clk_put(vidc_mmu_clks[i].mmu_clk);
vidc_mmu_clks[i].mmu_clk = NULL;
}
diff --git a/include/linux/mfd/pm8xxx/pwm.h b/include/linux/mfd/pm8xxx/pwm.h
index be3ec65..9169e90 100644
--- a/include/linux/mfd/pm8xxx/pwm.h
+++ b/include/linux/mfd/pm8xxx/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -17,8 +17,8 @@
#define PM8XXX_PWM_DEV_NAME "pm8xxx-pwm"
-#define PM8XXX_PWM_PERIOD_MAX (327 * USEC_PER_SEC)
-#define PM8XXX_PWM_PERIOD_MIN 7 /* micro seconds */
+#define PM8XXX_PWM_PERIOD_MIN 7 /* usec: 19.2M, n=6, m=0, pre=2 */
+#define PM8XXX_PWM_PERIOD_MAX (384 * USEC_PER_SEC) /* 1K, n=9, m=7, pre=6 */
#define PM_PWM_LUT_SIZE 64
#define PM_PWM_LUT_DUTY_TIME_MAX 512 /* ms */
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index d161d41..448d9ab 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -378,9 +378,9 @@
* @seglen: Segment length of this channel.
* @rootexp: root exponent of this channel. Rate can be found using rootexp and
* coefficient. Used during scheduling.
- * @srch: Source ports used by this channel.
- * @nsrc: number of source ports used by this channel.
- * @sinkh: Sink port used by this channel.
+ * @srch: Source port used by this channel.
+ * @sinkh: Sink ports used by this channel.
+ * @nsink: number of sink ports used by this channel.
* @chan: Channel number sent on hardware lines for this channel. May not be
* equal to array-index into chans if client requested to use number beyond
* channel-array for the controller.
@@ -404,9 +404,9 @@
u32 newintr;
u32 seglen;
u8 rootexp;
- u32 *srch;
- int nsrc;
- u32 sinkh;
+ u32 srch;
+ u32 *sinkh;
+ int nsink;
u8 chan;
int ref;
int def;
@@ -760,19 +760,31 @@
u32 ph, u8 **done_buf, u32 *done_len);
/*
- * slim_connect_ports: Connect port(s) to channel.
+ * slim_connect_src: Connect source port to channel.
* @sb: client handle
- * @srch: source handles to be connected to this channel
- * @nrsc: number of source ports
- * @sinkh: sink handle to be connected to this channel
+ * @srch: source handle to be connected to this channel
* @chanh: Channel with which the ports need to be associated with.
- * Per slimbus specification, a channel may have multiple source-ports and 1
- * sink port.Channel specified in chanh needs to be allocated first.
+ * Per slimbus specification, a channel may have 1 source port.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if source is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
*/
-extern int slim_connect_ports(struct slim_device *sb, u32 *srch, int nsrc,
- u32 sinkh, u16 chanh);
+extern int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh);
/*
+ * slim_connect_sink: Connect sink port(s) to channel.
+ * @sb: client handle
+ * @sinkh: sink handle(s) to be connected to this channel
+ * @nsink: number of sinks
+ * @chanh: Channel with which the ports need to be associated with.
+ * Per slimbus specification, a channel may have multiple sink-ports.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if sink is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
+ */
+extern int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink,
+ u16 chanh);
+/*
* slim_disconnect_ports: Disconnect port(s) from channel
* @sb: client handle
* @ph: ports to be disconnected