Merge "ASoc: msm: Fix equalizer ALSA mixer get handlers" into msm-3.0
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 01150aa..255d06e 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -294,6 +294,7 @@
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SX150X=y
+# CONFIG_MPP_PMIC8901 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_MSM is not set
CONFIG_BATTERY_MSM8X60=y
@@ -305,7 +306,6 @@
CONFIG_SENSORS_MSM_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_PM8901=y
CONFIG_THERMAL_TSENS=y
CONFIG_THERMAL_PM8XXX=y
CONFIG_PMIC8058=y
@@ -314,6 +314,7 @@
CONFIG_TIMPANI_CODEC=y
# CONFIG_MFD_PM8XXX_PWM is not set
CONFIG_MFD_PM8XXX_BATT_ALARM=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_DEV=y
# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -333,6 +334,7 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
+CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 7b2fede..0a88039 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -284,6 +284,7 @@
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SX150X=y
+# CONFIG_MPP_PMIC8901 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_MSM is not set
CONFIG_BATTERY_MSM8X60=y
@@ -294,7 +295,6 @@
CONFIG_BATTERY_BQ27541=y
CONFIG_SENSORS_MSM_ADC=y
CONFIG_THERMAL=y
-CONFIG_THERMAL_PM8901=y
CONFIG_THERMAL_TSENS=y
CONFIG_THERMAL_PM8XXX=y
CONFIG_PMIC8058=y
@@ -303,6 +303,7 @@
CONFIG_TIMPANI_CODEC=y
# CONFIG_MFD_PM8XXX_PWM is not set
CONFIG_MFD_PM8XXX_BATT_ALARM=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_DEV=y
# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -320,6 +321,7 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
+CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 83d012c..bb94d2a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -75,6 +75,7 @@
CONFIG_MSM_QDSS=y
CONFIG_MSM_SLEEP_STATS=y
CONFIG_STRICT_MEMORY_RWX=y
+CONFIG_MSM_SHOW_RESUME_IRQ=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
@@ -234,7 +235,7 @@
CONFIG_KS8851=m
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-CONFIG_WCNSS_CORE=m
+CONFIG_WCNSS_CORE=y
CONFIG_USB_USBNET=y
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
@@ -281,6 +282,7 @@
CONFIG_THERMAL_PM8XXX=y
CONFIG_MFD_PM8921_CORE=y
CONFIG_MFD_PM8821_CORE=y
+CONFIG_MFD_PM8038_CORE=y
CONFIG_MFD_PM8XXX_BATT_ALARM=y
CONFIG_WCD9310_CODEC=y
CONFIG_REGULATOR_GPIO=y
@@ -307,6 +309,7 @@
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
+CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index a920c5f..0cd27bc 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -289,7 +289,7 @@
.notifier_call = arch_timer_cpu_notify,
};
-int arch_timer_register(struct resource *res, int res_nr)
+int __init arch_timer_register(struct resource *res, int res_nr)
{
struct irqaction *irqa;
unsigned int cpu = smp_processor_id();
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 143fb86..a332ad1 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -68,7 +68,7 @@
#define STBY_KHZ 1
#define HFPLL_NOMINAL_VDD 1050000
-#define HFPLL_LOW_VDD 945000
+#define HFPLL_LOW_VDD 850000
#define HFPLL_LOW_VDD_PLL_L_MAX 0x28
#define SECCLKAGD BIT(4)
@@ -303,19 +303,35 @@
[11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
};
-static struct acpu_level acpu_freq_tbl_8960_kraitv1[] = {
- { 0, {STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 962500 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 962500 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 987500 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1087500 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1125000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1137500 },
+static struct acpu_level acpu_freq_tbl_8960_kraitv1_slow[] = {
+ { 0, {STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 937500 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 962500 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 987500 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1062500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1062500 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1087500 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_8960_kraitv1_nom_fast[] = {
+ { 0, {STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 862500 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 862500 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 862500 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 887500 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 925000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 937500 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 962500 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1012500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
{ 0, { 0 } }
};
@@ -341,19 +357,46 @@
[16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
};
-static struct acpu_level acpu_freq_tbl_8960_kraitv2[] = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 962500 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 962500 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 987500 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1087500 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1125000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1137500 },
+static struct acpu_level acpu_freq_tbl_8960_kraitv2_slow[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 937500 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 962500 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 987500 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1062500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1062500 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1087500 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1300000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1300000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1300000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1300000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1300000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1300000 },
+ { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1300000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1300000 },
+ { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1300000 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1300000 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1300000 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_8960_kraitv2_nom_fast[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 862500 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 862500 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 862500 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 887500 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 925000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 937500 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 962500 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1012500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
{ 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1300000 },
{ 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1300000 },
{ 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1300000 },
@@ -764,7 +807,9 @@
{
unsigned int pll_vdd_dig;
- if (tgt->l2_level->speed.pll_l_val > HFPLL_LOW_VDD_PLL_L_MAX)
+ if (tgt->l2_level->speed.src != HFPLL)
+ pll_vdd_dig = 0;
+ else if (tgt->l2_level->speed.pll_l_val > HFPLL_LOW_VDD_PLL_L_MAX)
pll_vdd_dig = HFPLL_NOMINAL_VDD;
else
pll_vdd_dig = HFPLL_LOW_VDD;
@@ -776,7 +821,9 @@
{
unsigned int pll_vdd_core;
- if (tgt->speed.pll_l_val > HFPLL_LOW_VDD_PLL_L_MAX)
+ if (tgt->speed.src != HFPLL)
+ pll_vdd_core = 0;
+ else if (tgt->speed.pll_l_val > HFPLL_LOW_VDD_PLL_L_MAX)
pll_vdd_core = HFPLL_NOMINAL_VDD;
else
pll_vdd_core = HFPLL_LOW_VDD;
@@ -1076,6 +1123,7 @@
/* Select frequency tables. */
if (cpu_is_msm8960() || cpu_is_msm8930()) {
uint32_t pte_efuse, pvs;
+ struct acpu_level *v1, *v2;
pte_efuse = readl_relaxed(QFPROM_PTE_EFUSE_ADDR);
pvs = (pte_efuse >> 10) & 0x7;
@@ -1086,26 +1134,33 @@
case 0x0:
case 0x7:
pr_info("ACPU PVS: Slow\n");
+ v1 = acpu_freq_tbl_8960_kraitv1_slow;
+ v2 = acpu_freq_tbl_8960_kraitv2_slow;
break;
case 0x1:
pr_info("ACPU PVS: Nominal\n");
+ v1 = acpu_freq_tbl_8960_kraitv1_nom_fast;
+ v2 = acpu_freq_tbl_8960_kraitv2_nom_fast;
break;
case 0x3:
pr_info("ACPU PVS: Fast\n");
+ v1 = acpu_freq_tbl_8960_kraitv1_nom_fast;
+ v2 = acpu_freq_tbl_8960_kraitv2_nom_fast;
break;
default:
pr_warn("ACPU PVS: Unknown. Defaulting to slow.\n");
+ v1 = acpu_freq_tbl_8960_kraitv1_slow;
+ v2 = acpu_freq_tbl_8960_kraitv2_slow;
break;
}
- /* TODO: Select tables based on PVS data. */
scalable = scalable_8960;
if (cpu_is_krait_v1()) {
- acpu_freq_tbl = acpu_freq_tbl_8960_kraitv1;
+ acpu_freq_tbl = v1;
l2_freq_tbl = l2_freq_tbl_8960_kraitv1;
l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960_kraitv1);
} else {
- acpu_freq_tbl = acpu_freq_tbl_8960_kraitv2;
+ acpu_freq_tbl = v2;
l2_freq_tbl = l2_freq_tbl_8960_kraitv2;
l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960_kraitv2);
}
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index ca21fac..f1103cb 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -22,7 +22,15 @@
#include <mach/gpiomux.h>
#include <mach/socinfo.h>
#include "devices.h"
+
+/* TODO: Remove this once PM8038 physically becomes
+ * available.
+ */
+#ifndef MSM8930_PHASE_2
+#include "board-8960.h"
+#else
#include "board-8930.h"
+#endif
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
@@ -137,6 +145,12 @@
static bool dsi_power_on;
+/*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace mipi_dsi_cdp_panel_power with
+ * appropriate function.
+ */
+#ifndef MSM8930_PHASE_2
static int mipi_dsi_cdp_panel_power(int on)
{
static struct regulator *reg_l8, *reg_l23, *reg_l2;
@@ -258,6 +272,7 @@
}
return 0;
}
+#endif
static int mipi_dsi_panel_power(int on)
{
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index cfb2347..283493d 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -12,10 +12,8 @@
*/
#include <linux/interrupt.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/pm8038.h>
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
-#include <linux/leds.h>
-#include <linux/leds-pm8xxx.h>
#include <linux/msm_ssbi.h>
#include <asm/mach-types.h>
#include <mach/msm_bus_board.h>
@@ -36,7 +34,7 @@
#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
_func, _inv, _disable) \
{ \
- .gpio = PM8921_GPIO_PM_TO_SYS(_gpio), \
+ .gpio = PM8038_GPIO_PM_TO_SYS(_gpio), \
.config = { \
.direction = _dir, \
.output_buffer = _buf, \
@@ -52,7 +50,7 @@
#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
{ \
- .mpp = PM8921_MPP_PM_TO_SYS(_mpp), \
+ .mpp = PM8038_MPP_PM_TO_SYS(_mpp), \
.config = { \
.type = PM8XXX_MPP_TYPE_##_type, \
.level = _level, \
@@ -61,24 +59,24 @@
}
#define PM8XXX_GPIO_DISABLE(_gpio) \
- PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+ PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM8038_GPIO_VIN_L11, \
0, 0, 0, 1)
#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
- PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_PULL_NO, PM8038_GPIO_VIN_L11, \
PM_GPIO_STRENGTH_HIGH, \
PM_GPIO_FUNC_NORMAL, 0, 0)
#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
- _pull, PM_GPIO_VIN_S4, \
+ _pull, PM8038_GPIO_VIN_L11, \
PM_GPIO_STRENGTH_NO, \
PM_GPIO_FUNC_NORMAL, 0, 0)
#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
- PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_PULL_NO, PM8038_GPIO_VIN_L11, \
PM_GPIO_STRENGTH_HIGH, \
_func, 0, 0)
@@ -88,45 +86,32 @@
PM_GPIO_STRENGTH_HIGH, \
PM_GPIO_FUNC_NORMAL, 0, 0)
-/* Initial PM8921 GPIO configurations */
-static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
- PM8XXX_GPIO_DISABLE(6), /* Disable unused */
- PM8XXX_GPIO_DISABLE(7), /* Disable NFC */
- PM8XXX_GPIO_INPUT(16, PM_GPIO_PULL_UP_30), /* SD_CARD_WP */
- /* External regulator shared by display and touchscreen on LiQUID */
- PM8XXX_GPIO_OUTPUT(17, 0), /* DISP 3.3 V Boost */
- PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH), /* Backlight Enable */
- PM8XXX_GPIO_DISABLE(22), /* Disable NFC */
- PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
- PM8XXX_GPIO_INPUT(26, PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
- PM8XXX_GPIO_OUTPUT(43, PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
- PM8XXX_GPIO_OUTPUT(42, 0), /* USB 5V reg enable */
-};
+/* Initial pm8038 GPIO configurations */
+static struct pm8xxx_gpio_init pm8038_gpios[] __initdata = {};
-/* Initial PM8921 MPP configurations */
-static struct pm8xxx_mpp_init pm8921_mpps[] __initdata = {
+/* Initial pm8038 MPP configurations */
+static struct pm8xxx_mpp_init pm8038_mpps[] __initdata = {
/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
- PM8XXX_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
- PM8XXX_MPP_INIT(PM8XXX_AMUX_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
- DOUT_CTRL_LOW),
+ PM8XXX_MPP_INIT(3, D_INPUT, PM8038_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
};
-void __init msm8930_pm8921_gpio_mpp_init(void)
+void __init msm8930_pm8038_gpio_mpp_init(void)
{
int i, rc;
- for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
- rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
- &pm8921_gpios[i].config);
+ for (i = 0; i < ARRAY_SIZE(pm8038_gpios); i++) {
+ rc = pm8xxx_gpio_config(pm8038_gpios[i].gpio,
+ &pm8038_gpios[i].config);
if (rc) {
pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
break;
}
}
- for (i = 0; i < ARRAY_SIZE(pm8921_mpps); i++) {
- rc = pm8xxx_mpp_config(pm8921_mpps[i].mpp,
- &pm8921_mpps[i].config);
+ /* Initial MPP configuration. */
+ for (i = 0; i < ARRAY_SIZE(pm8038_mpps); i++) {
+ rc = pm8xxx_mpp_config(pm8038_mpps[i].mpp,
+ &pm8038_mpps[i].config);
if (rc) {
pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
break;
@@ -134,71 +119,22 @@
}
}
-static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
- {"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
- ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
- {"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
- {"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
- {"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
- {"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
- ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
- {"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
- ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
-};
-
-static struct pm8xxx_adc_properties pm8xxx_adc_data = {
- .adc_vdd_reference = 1800, /* milli-voltage for this adc */
- .bitresolution = 15,
- .bipolar = 0,
-};
-
-static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
- .adc_channel = pm8xxx_adc_channels_data,
- .adc_num_board_channel = ARRAY_SIZE(pm8xxx_adc_channels_data),
- .adc_prop = &pm8xxx_adc_data,
- .adc_mpp_base = PM8921_MPP_PM_TO_SYS(1),
-};
-
-
static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata __devinitdata = {
- .irq_base = PM8921_IRQ_BASE,
+ .irq_base = PM8038_IRQ_BASE,
.devirq = MSM_GPIO_TO_INT(104),
.irq_trigger_flag = IRQF_TRIGGER_LOW,
};
static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata __devinitdata = {
- .gpio_base = PM8921_GPIO_PM_TO_SYS(1),
+ .gpio_base = PM8038_GPIO_PM_TO_SYS(1),
};
static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata __devinitdata = {
- .mpp_base = PM8921_MPP_PM_TO_SYS(1),
+ .mpp_base = PM8038_MPP_PM_TO_SYS(1),
};
static struct pm8xxx_rtc_platform_data pm8xxx_rtc_pdata __devinitdata = {
- .rtc_write_enable = false,
+ .rtc_write_enable = false,
.rtc_alarm_powerup = false,
};
@@ -208,292 +144,30 @@
.wakeup = 1,
};
-/* Rotate lock key is not available so use F1 */
-#define KEY_ROTATE_LOCK KEY_F1
-
-static const unsigned int keymap_liquid[] = {
- KEY(0, 0, KEY_VOLUMEUP),
- KEY(0, 1, KEY_VOLUMEDOWN),
- KEY(1, 3, KEY_ROTATE_LOCK),
- KEY(1, 4, KEY_HOME),
-};
-
-static const unsigned int keymap[] = {
- KEY(0, 0, KEY_VOLUMEUP),
- KEY(0, 1, KEY_VOLUMEDOWN),
- KEY(0, 2, KEY_CAMERA_SNAPSHOT),
- KEY(0, 3, KEY_CAMERA_FOCUS),
-};
-
-static struct matrix_keymap_data keymap_data = {
- .keymap_size = ARRAY_SIZE(keymap),
- .keymap = keymap,
-};
-
-static struct pm8xxx_keypad_platform_data keypad_data = {
- .input_name = "keypad_8960",
- .input_phys_device = "keypad_8960/input0",
- .num_rows = 1,
- .num_cols = 5,
- .rows_gpio_start = PM8921_GPIO_PM_TO_SYS(9),
- .cols_gpio_start = PM8921_GPIO_PM_TO_SYS(1),
- .debounce_ms = 15,
- .scan_delay_ms = 32,
- .row_hold_ns = 91500,
- .wakeup = 1,
- .keymap_data = &keymap_data,
-};
-
-static const unsigned int keymap_sim[] = {
- KEY(0, 0, KEY_7),
- KEY(0, 1, KEY_DOWN),
- KEY(0, 2, KEY_UP),
- KEY(0, 3, KEY_RIGHT),
- KEY(0, 4, KEY_ENTER),
- KEY(0, 5, KEY_L),
- KEY(0, 6, KEY_BACK),
- KEY(0, 7, KEY_M),
-
- KEY(1, 0, KEY_LEFT),
- KEY(1, 1, KEY_SEND),
- KEY(1, 2, KEY_1),
- KEY(1, 3, KEY_4),
- KEY(1, 4, KEY_CLEAR),
- KEY(1, 5, KEY_MSDOS),
- KEY(1, 6, KEY_SPACE),
- KEY(1, 7, KEY_COMMA),
-
- KEY(2, 0, KEY_6),
- KEY(2, 1, KEY_5),
- KEY(2, 2, KEY_8),
- KEY(2, 3, KEY_3),
- KEY(2, 4, KEY_NUMERIC_STAR),
- KEY(2, 5, KEY_UP),
- KEY(2, 6, KEY_DOWN),
- KEY(2, 7, KEY_LEFTSHIFT),
-
- KEY(3, 0, KEY_9),
- KEY(3, 1, KEY_NUMERIC_POUND),
- KEY(3, 2, KEY_0),
- KEY(3, 3, KEY_2),
- KEY(3, 4, KEY_SLEEP),
- KEY(3, 5, KEY_F1),
- KEY(3, 6, KEY_F2),
- KEY(3, 7, KEY_F3),
-
- KEY(4, 0, KEY_BACK),
- KEY(4, 1, KEY_HOME),
- KEY(4, 2, KEY_MENU),
- KEY(4, 3, KEY_VOLUMEUP),
- KEY(4, 4, KEY_VOLUMEDOWN),
- KEY(4, 5, KEY_F4),
- KEY(4, 6, KEY_F5),
- KEY(4, 7, KEY_F6),
-
- KEY(5, 0, KEY_R),
- KEY(5, 1, KEY_T),
- KEY(5, 2, KEY_Y),
- KEY(5, 3, KEY_LEFTALT),
- KEY(5, 4, KEY_KPENTER),
- KEY(5, 5, KEY_Q),
- KEY(5, 6, KEY_W),
- KEY(5, 7, KEY_E),
-
- KEY(6, 0, KEY_F),
- KEY(6, 1, KEY_G),
- KEY(6, 2, KEY_H),
- KEY(6, 3, KEY_CAPSLOCK),
- KEY(6, 4, KEY_PAGEUP),
- KEY(6, 5, KEY_A),
- KEY(6, 6, KEY_S),
- KEY(6, 7, KEY_D),
-
- KEY(7, 0, KEY_V),
- KEY(7, 1, KEY_B),
- KEY(7, 2, KEY_N),
- KEY(7, 3, KEY_MENU),
- KEY(7, 4, KEY_PAGEDOWN),
- KEY(7, 5, KEY_Z),
- KEY(7, 6, KEY_X),
- KEY(7, 7, KEY_C),
-
- KEY(8, 0, KEY_P),
- KEY(8, 1, KEY_J),
- KEY(8, 2, KEY_K),
- KEY(8, 3, KEY_INSERT),
- KEY(8, 4, KEY_LINEFEED),
- KEY(8, 5, KEY_U),
- KEY(8, 6, KEY_I),
- KEY(8, 7, KEY_O),
-
- KEY(9, 0, KEY_4),
- KEY(9, 1, KEY_5),
- KEY(9, 2, KEY_6),
- KEY(9, 3, KEY_7),
- KEY(9, 4, KEY_8),
- KEY(9, 5, KEY_1),
- KEY(9, 6, KEY_2),
- KEY(9, 7, KEY_3),
-
- KEY(10, 0, KEY_F7),
- KEY(10, 1, KEY_F8),
- KEY(10, 2, KEY_F9),
- KEY(10, 3, KEY_F10),
- KEY(10, 4, KEY_FN),
- KEY(10, 5, KEY_9),
- KEY(10, 6, KEY_0),
- KEY(10, 7, KEY_DOT),
-
- KEY(11, 0, KEY_LEFTCTRL),
- KEY(11, 1, KEY_F11),
- KEY(11, 2, KEY_ENTER),
- KEY(11, 3, KEY_SEARCH),
- KEY(11, 4, KEY_DELETE),
- KEY(11, 5, KEY_RIGHT),
- KEY(11, 6, KEY_LEFT),
- KEY(11, 7, KEY_RIGHTSHIFT),
- KEY(0, 0, KEY_VOLUMEUP),
- KEY(0, 1, KEY_VOLUMEDOWN),
- KEY(0, 2, KEY_CAMERA_SNAPSHOT),
- KEY(0, 3, KEY_CAMERA_FOCUS),
-};
-
-static int pm8921_therm_mitigation[] = {
- 1100,
- 700,
- 600,
- 325,
-};
-
-static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
- .safety_time = 180,
- .update_time = 60000,
- .max_voltage = 4200,
- .min_voltage = 3200,
- .resume_voltage_delta = 100,
- .term_current = 100,
- .cool_temp = 10,
- .warm_temp = 40,
- .temp_check_period = 1,
- .max_bat_chg_current = 1100,
- .cool_bat_chg_current = 350,
- .warm_bat_chg_current = 350,
- .cool_bat_voltage = 4100,
- .warm_bat_voltage = 4100,
- .thermal_mitigation = pm8921_therm_mitigation,
- .thermal_levels = ARRAY_SIZE(pm8921_therm_mitigation),
-};
-
static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
.priority = 0,
};
-static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
- .r_sense = 10,
- .i_test = 2500,
- .v_failure = 3000,
- .calib_delay_ms = 600000,
-};
-
-#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
-#define PM8XXX_LED_PWM_PERIOD 1000
-#define PM8XXX_LED_PWM_DUTY_MS 20
-/**
- * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
- * driven using PWM feature.
- */
-#define PM8XXX_PWM_CHANNEL_NONE -1
-
-static struct led_info pm8921_led_info[] = {
- [0] = {
- .name = "led:battery_charging",
- .default_trigger = "battery-charging",
- },
- [1] = {
- .name = "led:battery_full",
- .default_trigger = "battery-full",
- },
-};
-
-static struct led_platform_data pm8921_led_core_pdata = {
- .num_leds = ARRAY_SIZE(pm8921_led_info),
- .leds = pm8921_led_info,
-};
-
-static int pm8921_led0_pwm_duty_pcts[56] = {
- 1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
- 40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
- 80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
- 92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
- 58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
- 14, 10, 6, 4, 1
-};
-
-static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
- .duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
- .num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
- .duty_ms = PM8XXX_LED_PWM_DUTY_MS,
- .start_idx = 0,
-};
-
-static struct pm8xxx_led_config pm8921_led_configs[] = {
- [0] = {
- .id = PM8XXX_ID_LED_0,
- .mode = PM8XXX_LED_MODE_PWM2,
- .max_current = PM8921_LC_LED_MAX_CURRENT,
- .pwm_channel = 5,
- .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
- .pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
- },
- [1] = {
- .id = PM8XXX_ID_LED_1,
- .mode = PM8XXX_LED_MODE_PWM1,
- .max_current = PM8921_LC_LED_MAX_CURRENT,
- .pwm_channel = 4,
- .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
- },
-};
-
-static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
- .led_core = &pm8921_led_core_pdata,
- .configs = pm8921_led_configs,
- .num_configs = ARRAY_SIZE(pm8921_led_configs),
-};
-
-static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
- .r_sense = 10,
-};
-
-static struct pm8921_platform_data pm8921_platform_data __devinitdata = {
+static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
.irq_pdata = &pm8xxx_irq_pdata,
.gpio_pdata = &pm8xxx_gpio_pdata,
.mpp_pdata = &pm8xxx_mpp_pdata,
.rtc_pdata = &pm8xxx_rtc_pdata,
.pwrkey_pdata = &pm8xxx_pwrkey_pdata,
- .keypad_pdata = &keypad_data,
.misc_pdata = &pm8xxx_misc_pdata,
- .regulator_pdatas = msm_pm8921_regulator_pdata,
- .charger_pdata = &pm8921_chg_pdata,
- .bms_pdata = &pm8921_bms_pdata,
- .adc_pdata = &pm8xxx_adc_pdata,
- .leds_pdata = &pm8xxx_leds_pdata,
- .ccadc_pdata = &pm8xxx_ccadc_pdata,
};
-static struct msm_ssbi_platform_data msm8960_ssbi_pm8921_pdata __devinitdata = {
+static struct msm_ssbi_platform_data msm8930_ssbi_pm8038_pdata __devinitdata = {
.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
.slave = {
- .name = "pm8921-core",
- .platform_data = &pm8921_platform_data,
+ .name = "pm8038-core",
+ .platform_data = &pm8038_platform_data,
},
};
void __init msm8930_init_pmic(void)
{
- pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
- msm8960_device_ssbi_pm8921.dev.platform_data =
- &msm8960_ssbi_pm8921_pdata;
- pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
-
- /* Simulator supports a QWERTY keypad */
+ pmic_reset_irq = PM8038_IRQ_BASE + PM8038_RESOUT_IRQ;
+ msm8960_device_ssbi_pmic.dev.platform_data =
+ &msm8930_ssbi_pm8038_pdata;
}
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index 032d3d0..e38f877 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -22,7 +22,15 @@
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include "devices.h"
+
+/* TODO: Remove this once PM8038 physically becomes
+ * available.
+ */
+#ifndef MSM8930_PHASE_2
+#include "board-8960.h"
+#else
#include "board-8930.h"
+#endif
/* MSM8960 has 5 SDCC controllers */
enum sdcc_controllers {
@@ -239,13 +247,19 @@
.sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
.pclk_src_dfab = 1,
#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
+/*TODO: Insert right replacement for PM8038 */
+#ifndef MSM8930_PHASE_2
.wpswitch_gpio = PM8921_GPIO_PM_TO_SYS(16),
#endif
+#endif
.vreg_data = &mmc_slot_vreg_data[SDCC3],
.pin_data = &mmc_slot_pin_data[SDCC3],
#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
+/*TODO: Insert right replacement for PM8038 */
+#ifndef MSM8930_PHASE_2
.status_gpio = PM8921_GPIO_PM_TO_SYS(26),
.status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
+#endif
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
#endif
.xpc_cap = 1,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index cc020b5..d6c6ec8 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -81,7 +81,6 @@
#include "devices.h"
#include "devices-msm8x60.h"
#include "spm.h"
-#include "board-8930.h"
#include "pm.h"
#include "cpuidle.h"
#include "rpm_resources.h"
@@ -91,6 +90,7 @@
#include "smd_private.h"
#include "pm-boot.h"
#include "msm_watchdog.h"
+#include "board-8930.h"
static struct platform_device msm_fm_platform_init = {
.name = "iris_fm",
@@ -428,7 +428,11 @@
.irq = MSM_GPIO_TO_INT(62),
.irq_base = TABLA_INTERRUPT_BASE,
.num_irqs = NR_TABLA_IRQS,
+
+/*TODO: Replace this with right PM8038 gpio */
+#ifndef MSM8930_PHASE_2
.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+#endif
.micbias = {
.ldoh_v = TABLA_LDOH_2P85_V,
.cfilt1_mv = 1800,
@@ -457,7 +461,11 @@
.irq = MSM_GPIO_TO_INT(62),
.irq_base = TABLA_INTERRUPT_BASE,
.num_irqs = NR_TABLA_IRQS,
+
+/*TODO: Replace this with right PM8038 gpio */
+#ifndef MSM8930_PHASE_2
.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+#endif
.micbias = {
.ldoh_v = TABLA_LDOH_2P85_V,
.cfilt1_mv = 1800,
@@ -785,21 +793,25 @@
pr_err("Unable to get mvs_otg_switch\n");
return;
}
-
+ /* TODO: Replace this with appropriate PM8038 alternative */
+#ifndef MSM8930_PHASE_2
rc = gpio_request(PM8921_GPIO_PM_TO_SYS(USB_5V_EN),
"usb_5v_en");
+#endif
if (rc < 0) {
pr_err("failed to request usb_5v_en gpio\n");
goto put_mvs_otg;
}
+ /* TODO: Replace this with appropriate PM8038 alternative */
+#ifndef MSM8930_PHASE_2
rc = gpio_direction_output(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 1);
if (rc) {
pr_err("%s: unable to set_direction for gpio [%d]\n",
__func__, PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
goto free_usb_5v_en;
}
-
+#endif
if (regulator_enable(mvs_otg_switch)) {
pr_err("unable to enable mvs_otg_switch\n");
goto err_ldo_gpio_set_dir;
@@ -809,10 +821,14 @@
return;
}
regulator_disable(mvs_otg_switch);
+
+/* TODO: Replace this with appropriate PM8038 alternative */
+#ifndef MSM8930_PHASE_2
err_ldo_gpio_set_dir:
gpio_set_value(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
free_usb_5v_en:
gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
+#endif
put_mvs_otg:
regulator_put(mvs_otg_switch);
vbus_is_on = false;
@@ -823,7 +839,7 @@
.otg_control = OTG_PMIC_CONTROL,
.phy_type = SNPS_28NM_INTEGRATED_PHY,
.pclk_src_name = "dfab_usb_hs_clk",
- .pmic_id_irq = PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
+ .pmic_id_irq = PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE),
.vbus_power = msm_hsusb_vbus_power,
.power_budget = 750,
};
@@ -1025,8 +1041,13 @@
},
};
+#/* TODO: Remove this once PM8038 physically becomes
+ * available.
+ */
+#ifndef MSM8930_PHASE_2
#define PM_HAP_EN_GPIO PM8921_GPIO_PM_TO_SYS(33)
#define PM_HAP_LEN_GPIO PM8921_GPIO_PM_TO_SYS(20)
+#endif
static struct msm_xo_voter *xo_handle_d1;
@@ -1407,26 +1428,40 @@
};
static struct platform_device msm_device_saw_core0 = {
- .name = "saw-regulator",
- .id = 0,
+ .name = "saw-regulator",
+ .id = 0,
.dev = {
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace msm_saw_regulator_pdata_s5
+ * with 8930 saw regulator object.
+ */
+#ifndef MSM8930_PHASE_2
.platform_data = &msm_saw_regulator_pdata_s5,
+#endif
},
};
static struct platform_device msm_device_saw_core1 = {
- .name = "saw-regulator",
- .id = 1,
+ .name = "saw-regulator",
+ .id = 1,
.dev = {
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace msm_saw_regulator_pdata_s5
+ * with 8930 saw regulator object.
+ */
+#if !defined(MSM8930_PHASE_2)
.platform_data = &msm_saw_regulator_pdata_s6,
+#endif
},
};
static struct tsens_platform_data msm_tsens_pdata = {
- .slope = 910,
- .tsens_factor = 1000,
- .hw_type = MSM_8960,
- .tsens_num_sensor = 5,
+ .slope = 910,
+ .tsens_factor = 1000,
+ .hw_type = MSM_8960,
+ .tsens_num_sensor = 5,
};
static struct platform_device msm_tsens_device = {
@@ -1443,27 +1478,52 @@
};
#endif
-static struct platform_device msm8960_device_ext_5v_vreg __devinitdata = {
+static struct platform_device msm8930_device_ext_5v_vreg __devinitdata = {
.name = GPIO_REGULATOR_DEV_NAME,
+/* TODO: Replace this with right MPP for 8038 */
+#ifndef MSM8930_PHASE_2
.id = PM8921_MPP_PM_TO_SYS(7),
+#endif
.dev = {
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace msm_gpio_regulator_pdata
+ * with 8930 gpio regulator object.
+ */
+#if !defined(MSM8930_PHASE_2)
.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+#endif
},
};
-static struct platform_device msm8960_device_ext_l2_vreg __devinitdata = {
+static struct platform_device msm8930_device_ext_l2_vreg __devinitdata = {
.name = GPIO_REGULATOR_DEV_NAME,
.id = 91,
.dev = {
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace msm_gpio_regulator_pdata
+ * with 8930 gpio regulator object.
+ */
+#if !defined(MSM8930_PHASE_2)
.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_L2],
+#endif
},
};
-static struct platform_device msm8960_device_rpm_regulator __devinitdata = {
+static struct platform_device msm8930_device_rpm_regulator __devinitdata = {
.name = "rpm-regulator",
.id = -1,
.dev = {
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace msm_rpm_regulator_pdata
+ * with 8930 rpm regulator object.
+ */
+#if !defined(MSM8930_PHASE_2)
+
.platform_data = &msm_rpm_regulator_pdata,
+#endif
},
};
@@ -1493,9 +1553,9 @@
&msm_device_uart_dm6,
&msm_device_saw_core0,
&msm_device_saw_core1,
- &msm8960_device_ext_5v_vreg,
- &msm8960_device_ext_l2_vreg,
- &msm8960_device_ssbi_pm8921,
+ &msm8930_device_ext_5v_vreg,
+ &msm8930_device_ext_l2_vreg,
+ &msm8960_device_ssbi_pmic,
&msm8960_device_qup_spi_gsbi1,
&msm8960_device_qup_i2c_gsbi3,
&msm8960_device_qup_i2c_gsbi4,
@@ -1895,7 +1955,7 @@
regulator_suppress_info_printing();
if (msm_xo_init())
pr_err("Failed to initialize XO votes\n");
- platform_device_register(&msm8960_device_rpm_regulator);
+ platform_device_register(&msm8930_device_rpm_regulator);
msm_clock_init(&msm8960_clock_init_data);
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
@@ -1904,7 +1964,16 @@
&msm8960_qup_spi_gsbi1_pdata;
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, remove this block or add the config
+ * option.
+ */
+#ifndef MSM8930_PHASE_2
+ msm8960_init_pmic();
+#else
msm8930_init_pmic();
+#endif
msm8930_i2c_init();
msm8930_gfx_init();
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
@@ -1913,7 +1982,16 @@
platform_add_devices(msm_footswitch_devices,
msm_num_footswitch_devices);
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
- msm8930_pm8921_gpio_mpp_init();
+ /*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, remove this block or add the config
+ * option.
+ */
+#ifndef MSM8930_PHASE_2
+ msm8960_pm8921_gpio_mpp_init();
+#else
+ msm8930_pm8038_gpio_mpp_init();
+#endif
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
msm8930_init_hsic();
msm8930_init_cam();
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index c413061..ec0b867 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -14,39 +14,59 @@
#define __ARCH_ARM_MACH_MSM_BOARD_MSM8930_H
#include <linux/regulator/gpio-regulator.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/pm8038.h>
#include <linux/i2c/sx150x.h>
#include <mach/irqs.h>
#include <mach/rpm-regulator.h>
-/* Macros assume PMIC GPIOs and MPPs start at 1 */
+/*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, remove this block.
+ */
+#ifndef MSM8930_PHASE_2
+#include <linux/mfd/pm8xxx/pm8921.h>
#define PM8921_GPIO_BASE NR_GPIO_IRQS
#define PM8921_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8921_GPIO_BASE)
#define PM8921_MPP_BASE (PM8921_GPIO_BASE + PM8921_NR_GPIOS)
#define PM8921_MPP_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8921_MPP_BASE)
-#define PM8921_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+#endif
+
+/* Macros assume PMIC GPIOs and MPPs start at 1 */
+#define PM8038_GPIO_BASE NR_GPIO_IRQS
+#define PM8038_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8038_GPIO_BASE)
+#define PM8038_MPP_BASE (PM8038_GPIO_BASE + PM8038_NR_GPIOS)
+#define PM8038_MPP_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8038_MPP_BASE)
+#define PM8038_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+/*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, replace this block with 8930/pm8038 regulator
+ * declarations.
+ */
+#ifndef MSM8930_PHASE_2
+extern struct regulator_init_data msm_saw_regulator_pdata_s5;
+extern struct regulator_init_data msm_saw_regulator_pdata_s6;
extern struct pm8921_regulator_platform_data
msm_pm8921_regulator_pdata[] __devinitdata;
extern int msm_pm8921_regulator_pdata_len __devinitdata;
+extern struct gpio_regulator_platform_data
+ msm_gpio_regulator_pdata[] __devinitdata;
+
+extern struct rpm_regulator_platform_data msm_rpm_regulator_pdata __devinitdata;
+#endif
+
#define GPIO_VREG_ID_EXT_5V 0
#define GPIO_VREG_ID_EXT_L2 1
#define GPIO_VREG_ID_EXT_3P3V 2
-extern struct gpio_regulator_platform_data
- msm_gpio_regulator_pdata[] __devinitdata;
-
-extern struct regulator_init_data msm_saw_regulator_pdata_s5;
-extern struct regulator_init_data msm_saw_regulator_pdata_s6;
-
-extern struct rpm_regulator_platform_data msm_rpm_regulator_pdata __devinitdata;
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
enum {
- GPIO_EXPANDER_IRQ_BASE = (PM8921_IRQ_BASE + PM8921_NR_IRQS),
- GPIO_EXPANDER_GPIO_BASE = (PM8921_MPP_BASE + PM8921_NR_MPPS),
+ GPIO_EXPANDER_IRQ_BASE = (PM8038_IRQ_BASE + PM8038_NR_IRQS),
+ GPIO_EXPANDER_GPIO_BASE = (PM8038_MPP_BASE + PM8038_NR_MPPS),
/* CAM Expander */
GPIO_CAM_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
@@ -71,10 +91,21 @@
void msm8930_init_cam(void);
void msm8930_init_fb(void);
void msm8930_init_pmic(void);
+
+/*
+ * TODO: When physical 8930/PM8038 hardware becomes
+ * available, remove this block or add the config
+ * option.
+ */
+#ifndef MSM8930_PHASE_2
+void msm8960_init_pmic(void);
+void msm8960_pm8921_gpio_mpp_init(void);
+#endif
+
void msm8930_init_mmc(void);
int msm8930_init_gpiomux(void);
void msm8930_allocate_fb_region(void);
-void msm8930_pm8921_gpio_mpp_init(void);
+void msm8930_pm8038_gpio_mpp_init(void);
#define PLATFORM_IS_CHARM25() \
(machine_is_msm8930_cdp() && \
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index 9be65bb..ce260e1 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -243,6 +243,20 @@
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_DOWN,
};
+
+static struct gpiomux_setting hdmi_active_3_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ .dir = GPIOMUX_IN,
+};
+
+static struct gpiomux_setting hdmi_active_4_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+ .dir = GPIOMUX_OUT_HIGH,
+};
#endif
#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
@@ -600,6 +614,20 @@
[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
},
},
+ {
+ .gpio = 15,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_3_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 66,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_4_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
};
#endif
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 44f7be6..5e1ea0d 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -529,7 +529,7 @@
void __init msm8960_init_pmic(void)
{
pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
- msm8960_device_ssbi_pm8921.dev.platform_data =
+ msm8960_device_ssbi_pmic.dev.platform_data =
&msm8960_ssbi_pm8921_pdata;
pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 7bc3ca5..f3e4f20 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -449,9 +449,9 @@
/* SAW regulator constraints */
struct regulator_init_data msm_saw_regulator_pdata_s5 =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(S5, "8921_s5", 950000, 1300000);
+ SAW_VREG_INIT(S5, "8921_s5", 850000, 1300000);
struct regulator_init_data msm_saw_regulator_pdata_s6 =
- SAW_VREG_INIT(S6, "8921_s6", 950000, 1300000);
+ SAW_VREG_INIT(S6, "8921_s6", 850000, 1300000);
/* PM8921 regulator constraints */
struct pm8921_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 3d0d0e5..fa607bf 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -814,7 +814,7 @@
}
regulator_disable(mvs_otg_switch);
err_ldo_gpio_set_dir:
- gpio_set_value(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
+ gpio_set_value_cansleep(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
free_usb_5v_en:
gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
put_mvs_otg:
@@ -964,7 +964,7 @@
.reg_base_addr = MSM_SAW0_BASE,
.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
+ .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -981,7 +981,7 @@
.reg_base_addr = MSM_SAW1_BASE,
.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
+ .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1417,6 +1417,14 @@
},
};
+static struct i2c_board_info sii_device_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("Sil-9244", 0x39),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = MSM_GPIO_TO_INT(15),
+ },
+};
+
static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
{
}
@@ -1582,7 +1590,7 @@
&msm_device_saw_core1,
&msm8960_device_ext_5v_vreg,
&msm8960_device_ext_l2_vreg,
- &msm8960_device_ssbi_pm8921,
+ &msm8960_device_ssbi_pmic,
&msm8960_device_qup_spi_gsbi1,
&msm8960_device_qup_i2c_gsbi3,
&msm8960_device_qup_i2c_gsbi4,
@@ -2007,6 +2015,12 @@
{
I2C_LIQUID,
MSM_8960_GSBI10_QUP_I2C_BUS_ID,
+ sii_device_info,
+ ARRAY_SIZE(sii_device_info),
+ },
+ {
+ I2C_LIQUID,
+ MSM_8960_GSBI10_QUP_I2C_BUS_ID,
msm_isa1200_board_info,
ARRAY_SIZE(msm_isa1200_board_info),
},
@@ -2140,6 +2154,8 @@
msm_otg_pdata.phy_init_seq =
liquid_v1_phy_init_seq;
}
+ msm_otg_pdata.swfi_latency =
+ msm_rpmrs_levels[0].latency_us;
#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-9615.c b/arch/arm/mach-msm/board-9615.c
index 0a2e102..5efafae 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -34,6 +34,7 @@
#include "cpuidle.h"
#include "pm.h"
#include "acpuclock.h"
+#include <linux/power/ltc4088-charger.h>
static struct pm8xxx_adc_amux pm8018_adc_channels_data[] = {
{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
@@ -133,6 +134,14 @@
.num_configs = ARRAY_SIZE(pm8018_led_configs),
};
+#ifdef CONFIG_LTC4088_CHARGER
+static struct ltc4088_charger_platform_data ltc4088_chg_pdata = {
+ .gpio_mode_select_d0 = 7,
+ .gpio_mode_select_d1 = 6,
+ .gpio_mode_select_d2 = 4,
+};
+#endif
+
static struct pm8018_platform_data pm8018_platform_data __devinitdata = {
.irq_pdata = &pm8xxx_irq_pdata,
.gpio_pdata = &pm8xxx_gpio_pdata,
@@ -200,6 +209,14 @@
.pull = GPIOMUX_PULL_NONE,
};
+#ifdef CONFIG_LTC4088_CHARGER
+static struct gpiomux_setting ltc4088_chg_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+#endif
+
struct msm_gpiomux_config msm9615_ps_hold_config[] __initdata = {
{
.gpio = 83,
@@ -209,6 +226,30 @@
},
};
+#ifdef CONFIG_LTC4088_CHARGER
+static struct msm_gpiomux_config
+ msm9615_ltc4088_charger_config[] __initdata = {
+ {
+ .gpio = 4,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = <c4088_chg_cfg,
+ },
+ },
+ {
+ .gpio = 6,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = <c4088_chg_cfg,
+ },
+ },
+ {
+ .gpio = 7,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = <c4088_chg_cfg,
+ },
+ },
+};
+#endif
+
struct msm_gpiomux_config msm9615_gsbi_configs[] __initdata = {
{
.gpio = 8, /* GSBI3 QUP SPI_CLK */
@@ -600,6 +641,10 @@
msm_gpiomux_install(msm9615_ps_hold_config,
ARRAY_SIZE(msm9615_ps_hold_config));
+#ifdef CONFIG_LTC4088_CHARGER
+ msm_gpiomux_install(msm9615_ltc4088_charger_config,
+ ARRAY_SIZE(msm9615_ltc4088_charger_config));
+#endif
return 0;
}
@@ -717,9 +762,22 @@
return platform_device_register(&msm_wlan_ar6000_pm_device);
}
+#ifdef CONFIG_LTC4088_CHARGER
+static struct platform_device msm_device_charger = {
+ .name = LTC4088_CHARGER_DEV_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = <c4088_chg_pdata,
+ },
+};
+#endif
+
static struct platform_device *common_devices[] = {
&msm9615_device_dmov,
&msm_device_smd,
+#ifdef CONFIG_LTC4088_CHARGER
+ &msm_device_charger,
+#endif
&msm_device_otg,
&msm_device_gadget_peripheral,
&msm_device_hsusb_host,
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 5de5ea3..f369c6c 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -61,6 +61,15 @@
#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
#define BAHAMA_SLAVE_ID_FM_REG 0x02
#define FM_GPIO 83
+#define BT_PCM_BCLK_MODE 0x88
+#define BT_PCM_DIN_MODE 0x89
+#define BT_PCM_DOUT_MODE 0x8A
+#define BT_PCM_SYNC_MODE 0x8B
+#define FM_I2S_SD_MODE 0x8E
+#define FM_I2S_WS_MODE 0x8F
+#define FM_I2S_SCK_MODE 0x90
+#define I2C_PIN_CTL 0x15
+#define I2C_NORMAL 0x40
enum {
GPIO_EXPANDER_IRQ_BASE = NR_MSM_IRQS + NR_GPIO_IRQS,
@@ -125,6 +134,57 @@
/* FM Platform power and shutdown routines */
#define FPGA_MSM_CNTRL_REG2 0x90008010
+static int switch_pcm_i2s_reg_mode(int mode)
+{
+ unsigned char reg = 0;
+ int rc = -1;
+ unsigned char set = I2C_PIN_CTL; /*SET PIN CTL mode*/
+ unsigned char unset = I2C_NORMAL; /* UNSET PIN CTL MODE*/
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+
+ if (mode == 0) {
+ /* as we need to switch path to FM we need to move
+ BT AUX PCM lines to PIN CONTROL mode then move
+ FM to normal mode.*/
+ for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
+ rc = marimba_write(&config, reg, &set, 1);
+ if (rc < 0) {
+ pr_err("pcm pinctl failed = %d", rc);
+ goto err_all;
+ }
+ }
+ for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
+ rc = marimba_write(&config, reg, &unset, 1);
+ if (rc < 0) {
+ pr_err("i2s normal failed = %d", rc);
+ goto err_all;
+ }
+ }
+ } else {
+ /* as we need to switch path to AUXPCM we need to move
+ FM I2S lines to PIN CONTROL mode then move
+ BT AUX_PCM to normal mode.*/
+ for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
+ rc = marimba_write(&config, reg, &set, 1);
+ if (rc < 0) {
+ pr_err("i2s pinctl failed = %d", rc);
+ goto err_all;
+ }
+ }
+ for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
+ rc = marimba_write(&config, reg, &unset, 1);
+ if (rc < 0) {
+ pr_err("pcm normal failed = %d", rc);
+ goto err_all;
+ }
+ }
+ }
+
+ return 0;
+
+err_all:
+ return rc;
+}
static void config_pcm_i2s_mode(int mode)
{
@@ -220,6 +280,12 @@
if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
config_pcm_i2s_mode(0);
pr_err("%s mode = FM_I2S_ON", __func__);
+
+ rc = switch_pcm_i2s_reg_mode(0);
+ if (rc) {
+ pr_err("switch mode failed");
+ return rc;
+ }
for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_on);
pin++) {
rc = gpio_tlmm_config(
@@ -231,6 +297,11 @@
}
} else if (mode == FM_I2S_OFF) {
pr_err("%s mode = FM_I2S_OFF", __func__);
+ rc = switch_pcm_i2s_reg_mode(1);
+ if (rc) {
+ pr_err("switch mode failed");
+ return rc;
+ }
for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_off);
pin++) {
rc = gpio_tlmm_config(
@@ -251,6 +322,11 @@
if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
config_pcm_i2s_mode(1);
pr_err("%s mode =BT_PCM_ON", __func__);
+ rc = switch_pcm_i2s_reg_mode(1);
+ if (rc) {
+ pr_err("switch mode failed");
+ return rc;
+ }
for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
pin++) {
rc = gpio_tlmm_config(bt_config_pcm_on[pin],
@@ -260,6 +336,11 @@
}
} else if (mode == BT_PCM_OFF) {
pr_err("%s mode =BT_PCM_OFF", __func__);
+ rc = switch_pcm_i2s_reg_mode(0);
+ if (rc) {
+ pr_err("switch mode failed");
+ return rc;
+ }
for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
pin++) {
rc = gpio_tlmm_config(bt_config_pcm_off[pin],
@@ -1069,8 +1150,8 @@
};
#ifdef CONFIG_ARCH_MSM7X27A
-#define MSM_PMEM_MDP_SIZE 0x1900000
-#define MSM7x25A_MSM_PMEM_MDP_SIZE 0x1000000
+#define MSM_PMEM_MDP_SIZE 0x2300000
+#define MSM7x25A_MSM_PMEM_MDP_SIZE 0x1500000
#define MSM_PMEM_ADSP_SIZE 0x1000000
#define MSM7x25A_MSM_PMEM_ADSP_SIZE 0xB91000
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 3038ff0..765f49e 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -22,6 +22,7 @@
#include <linux/leds.h>
#include <linux/pmic8058-othc.h>
#include <linux/mfd/pmic8901.h>
+#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/pmic8901-regulator.h>
#include <linux/bootmem.h>
#include <linux/msm_adc.h>
@@ -54,7 +55,6 @@
#include <asm/setup.h>
#include <mach/dma.h>
-#include <mach/mpp.h>
#include <mach/board.h>
#include <mach/irqs.h>
#include <mach/msm_spi.h>
@@ -83,6 +83,7 @@
#include <mach/rpm.h>
#include <mach/rpm-regulator.h>
#include <mach/restart.h>
+#include <mach/board-msm8660.h>
#include "devices.h"
#include "devices-msm8x60.h"
@@ -104,23 +105,6 @@
#include <mach/ion.h>
#define MSM_SHARED_RAM_PHYS 0x40000000
-
-/* Macros assume PMIC GPIOs start at 0 */
-#define PM8058_GPIO_BASE NR_MSM_GPIOS
-#define PM8058_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_GPIO_BASE)
-#define PM8058_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - PM8058_GPIO_BASE)
-#define PM8058_MPP_BASE (PM8058_GPIO_BASE + PM8058_GPIOS)
-#define PM8058_MPP_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_MPP_BASE)
-#define PM8058_MPP_SYS_TO_PM(sys_gpio) (sys_gpio - PM8058_MPP_BASE)
-#define PM8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
-
-#define PM8901_GPIO_BASE (PM8058_GPIO_BASE + \
- PM8058_GPIOS + PM8058_MPPS)
-#define PM8901_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio + PM8901_GPIO_BASE)
-#define PM8901_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - PM901_GPIO_BASE)
-#define PM8901_IRQ_BASE (PM8058_IRQ_BASE + \
- NR_PMIC8058_IRQS)
-
#define MDM2AP_SYNC 129
#define GPIO_ETHERNET_RESET_N_DRAGON 30
@@ -150,7 +134,7 @@
enum {
GPIO_EXPANDER_IRQ_BASE = PM8901_IRQ_BASE + NR_PMIC8901_IRQS,
- GPIO_EXPANDER_GPIO_BASE = PM8901_GPIO_BASE + PM8901_MPPS,
+ GPIO_EXPANDER_GPIO_BASE = PM8901_MPP_BASE + PM8901_MPPS,
/* CORE expander */
GPIO_CORE_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
GPIO_CLASS_D1_EN = GPIO_CORE_EXPANDER_BASE,
@@ -273,7 +257,7 @@
struct pm8xxx_mpp_config_data config;
};
-#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+#define PM8058_MPP_INIT(_mpp, _type, _level, _control) \
{ \
.mpp = PM8058_MPP_PM_TO_SYS(_mpp), \
.config = { \
@@ -283,6 +267,16 @@
} \
}
+#define PM8901_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+ .mpp = PM8901_MPP_PM_TO_SYS(_mpp), \
+ .config = { \
+ .type = PM8XXX_MPP_TYPE_##_type, \
+ .level = _level, \
+ .control = PM8XXX_MPP_##_control, \
+ } \
+}
+
/*
* The UI_INTx_N lines are pmic gpio lines which connect i2c
* gpio expanders to the pm8058.
@@ -1045,14 +1039,21 @@
{
unsigned ret;
+ struct pm8xxx_mpp_config_data hsusb_phy_mpp = {
+ .type = PM8XXX_MPP_TYPE_D_OUTPUT,
+ .level = PM8901_MPP_DIG_LEVEL_L5,
+ };
+
if (init) {
- ret = pm8901_mpp_config_digital_out(1,
- PM8901_MPP_DIG_LEVEL_L5, 1);
+ hsusb_phy_mpp.control = PM8XXX_MPP_DOUT_CTRL_HIGH;
+ ret = pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(1),
+ &hsusb_phy_mpp);
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);
+ hsusb_phy_mpp.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+ ret = pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(1),
+ &hsusb_phy_mpp);
if (ret < 0)
pr_err("%s:MPP2 un config failed\n", __func__);
}
@@ -4837,23 +4838,20 @@
{
int rc, i;
struct pm8xxx_mpp_init_info xoadc_mpps[] = {
- PM8XXX_MPP_INIT(XOADC_MPP_3, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
+ PM8058_MPP_INIT(XOADC_MPP_3, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
AOUT_CTRL_DISABLE),
- PM8XXX_MPP_INIT(XOADC_MPP_5, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH9,
+ PM8058_MPP_INIT(XOADC_MPP_5, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH9,
AOUT_CTRL_DISABLE),
- PM8XXX_MPP_INIT(XOADC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
+ PM8058_MPP_INIT(XOADC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
AOUT_CTRL_DISABLE),
- PM8XXX_MPP_INIT(XOADC_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
+ PM8058_MPP_INIT(XOADC_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
AOUT_CTRL_DISABLE),
- PM8XXX_MPP_INIT(XOADC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH7,
+ PM8058_MPP_INIT(XOADC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH7,
AOUT_CTRL_DISABLE),
+ PM8901_MPP_INIT(XOADC_MPP_4, D_OUTPUT, PM8901_MPP_DIG_LEVEL_S4,
+ DOUT_CTRL_LOW),
};
- rc = pm8901_mpp_config_digital_out(XOADC_MPP_4,
- PM8901_MPP_DIG_LEVEL_S4, PM_MPP_DOUT_CTL_LOW);
- if (rc)
- pr_err("%s: Config mpp4 on pmic 8901 failed\n", __func__);
-
for (i = 0; i < ARRAY_SIZE(xoadc_mpps); i++) {
rc = pm8xxx_mpp_config(xoadc_mpps[i].mpp,
&xoadc_mpps[i].config);
@@ -4982,6 +4980,75 @@
#endif /* CONFIG_MSM_SDIO_AL */
+#define GPIO_VREG_ID_EXT_5V 0
+
+static struct regulator_consumer_supply vreg_consumers_EXT_5V[] = {
+ REGULATOR_SUPPLY("ext_5v", NULL),
+ REGULATOR_SUPPLY("8901_mpp0", NULL),
+};
+
+#define GPIO_VREG_INIT(_id, _reg_name, _gpio_label, _gpio, _active_low) \
+ [GPIO_VREG_ID_##_id] = { \
+ .init_data = { \
+ .constraints = { \
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS, \
+ }, \
+ .num_consumer_supplies = \
+ ARRAY_SIZE(vreg_consumers_##_id), \
+ .consumer_supplies = vreg_consumers_##_id, \
+ }, \
+ .regulator_name = _reg_name, \
+ .active_low = _active_low, \
+ .gpio_label = _gpio_label, \
+ .gpio = _gpio, \
+ }
+
+/* GPIO regulator constraints */
+static struct gpio_regulator_platform_data msm_gpio_regulator_pdata[] = {
+ GPIO_VREG_INIT(EXT_5V, "ext_5v", "ext_5v_en",
+ PM8901_MPP_PM_TO_SYS(0), 0),
+};
+
+/* GPIO regulator */
+static struct platform_device msm8x60_8901_mpp_vreg __devinitdata = {
+ .name = GPIO_REGULATOR_DEV_NAME,
+ .id = PM8901_MPP_PM_TO_SYS(0),
+ .dev = {
+ .platform_data =
+ &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+ },
+};
+
+static void __init pm8901_vreg_mpp0_init(void)
+{
+ int rc;
+
+ struct pm8xxx_mpp_init_info pm8901_vreg_mpp0 = {
+ .mpp = PM8901_MPP_PM_TO_SYS(0),
+ .config = {
+ .type = PM8XXX_MPP_TYPE_D_OUTPUT,
+ .level = PM8901_MPP_DIG_LEVEL_VPH,
+ },
+ };
+
+ /*
+ * Set PMIC 8901 MPP0 active_high to 0 for surf and charm_surf. This
+ * implies that the regulator connected to MPP0 is enabled when
+ * MPP0 is low.
+ */
+ if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion()) {
+ msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V].active_low = 1;
+ pm8901_vreg_mpp0.config.control = PM8XXX_MPP_DOUT_CTRL_HIGH;
+ } else {
+ msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V].active_low = 0;
+ pm8901_vreg_mpp0.config.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+ }
+
+ rc = pm8xxx_mpp_config(pm8901_vreg_mpp0.mpp, &pm8901_vreg_mpp0.config);
+ if (rc)
+ pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+}
+
static struct platform_device *charm_devices[] __initdata = {
&msm_charm_modem,
#ifdef CONFIG_MSM_SDIO_AL
@@ -5309,9 +5376,9 @@
#define EXT_CHG_VALID_MPP_2 11
static struct pm8xxx_mpp_init_info isl_mpp[] = {
- PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP, D_INPUT,
+ PM8058_MPP_INIT(EXT_CHG_VALID_MPP, D_INPUT,
PM8058_MPP_DIG_LEVEL_S3, DIN_TO_INT),
- PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP_2, D_BI_DIR,
+ PM8058_MPP_INIT(EXT_CHG_VALID_MPP_2, D_BI_DIR,
PM8058_MPP_DIG_LEVEL_S3, BI_PULLUP_10KOHM),
};
@@ -6526,32 +6593,10 @@
#ifdef CONFIG_PMIC8901
#define PM8901_GPIO_INT 91
-
-static struct pm8901_gpio_platform_data pm8901_mpp_data = {
- .gpio_base = PM8901_GPIO_PM_TO_SYS(0),
- .irq_base = PM8901_MPP_IRQ(PM8901_IRQ_BASE, 0),
-};
-
-static struct resource pm8901_temp_alarm[] = {
- {
- .start = PM8901_TEMP_ALARM_IRQ(PM8901_IRQ_BASE),
- .end = PM8901_TEMP_ALARM_IRQ(PM8901_IRQ_BASE),
- .flags = IORESOURCE_IRQ,
- },
- {
- .start = PM8901_TEMP_HI_ALARM_IRQ(PM8901_IRQ_BASE),
- .end = PM8901_TEMP_HI_ALARM_IRQ(PM8901_IRQ_BASE),
- .flags = IORESOURCE_IRQ,
- },
-};
-
/*
* Consumer specific regulator names:
* regulator name consumer dev_name
*/
-static struct regulator_consumer_supply vreg_consumers_8901_MPP0[] = {
- REGULATOR_SUPPLY("8901_mpp0", NULL),
-};
static struct regulator_consumer_supply vreg_consumers_8901_USB_OTG[] = {
REGULATOR_SUPPLY("8901_usb_otg", NULL),
};
@@ -6560,8 +6605,8 @@
};
#define PM8901_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
- _always_on, _active_high) \
- [PM8901_VREG_ID_##_id] = { \
+ _always_on) \
+ { \
.init_data = { \
.constraints = { \
.valid_modes_mask = _modes, \
@@ -6576,53 +6621,33 @@
.num_consumer_supplies = \
ARRAY_SIZE(vreg_consumers_8901_##_id), \
}, \
- .active_high = _active_high, \
+ .id = PM8901_VREG_ID_##_id, \
}
-#define PM8901_VREG_INIT_MPP(_id, _active_high) \
- PM8901_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL, \
- REGULATOR_CHANGE_STATUS, 0, 0, _active_high)
-
#define PM8901_VREG_INIT_VS(_id) \
PM8901_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL, \
- REGULATOR_CHANGE_STATUS, 0, 0, 0)
+ REGULATOR_CHANGE_STATUS, 0, 0)
-static struct pm8901_vreg_pdata pm8901_vreg_init_pdata[PM8901_VREG_MAX] = {
- PM8901_VREG_INIT_MPP(MPP0, 1),
-
+static struct pm8901_vreg_pdata pm8901_vreg_init[] = {
PM8901_VREG_INIT_VS(USB_OTG),
PM8901_VREG_INIT_VS(HDMI_MVS),
};
-#define PM8901_VREG(_id) { \
- .name = "pm8901-regulator", \
- .id = _id, \
- .platform_data = &pm8901_vreg_init_pdata[_id], \
- .pdata_size = sizeof(pm8901_vreg_init_pdata[_id]), \
-}
+static struct pm8xxx_irq_platform_data pm8901_irq_pdata = {
+ .irq_base = PM8901_IRQ_BASE,
+ .devirq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
+ .irq_trigger_flag = IRQF_TRIGGER_LOW,
+};
-static struct mfd_cell pm8901_subdevs[] = {
- { .name = "pm8901-mpp",
- .id = -1,
- .platform_data = &pm8901_mpp_data,
- .pdata_size = sizeof(pm8901_mpp_data),
- },
- { .name = "pm8901-tm",
- .id = -1,
- .num_resources = ARRAY_SIZE(pm8901_temp_alarm),
- .resources = pm8901_temp_alarm,
- },
- PM8901_VREG(PM8901_VREG_ID_MPP0),
- PM8901_VREG(PM8901_VREG_ID_USB_OTG),
- PM8901_VREG(PM8901_VREG_ID_HDMI_MVS),
+static struct pm8xxx_mpp_platform_data pm8901_mpp_pdata = {
+ .mpp_base = PM8901_MPP_PM_TO_SYS(0),
};
static struct pm8901_platform_data pm8901_platform_data = {
- .irq_base = PM8901_IRQ_BASE,
- .irq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
- .num_subdevs = ARRAY_SIZE(pm8901_subdevs),
- .sub_devices = pm8901_subdevs,
- .irq_trigger_flags = IRQF_TRIGGER_LOW,
+ .irq_pdata = &pm8901_irq_pdata,
+ .mpp_pdata = &pm8901_mpp_pdata,
+ .regulator_pdatas = pm8901_vreg_init,
+ .num_regulators = ARRAY_SIZE(pm8901_vreg_init),
};
static struct msm_ssbi_platform_data msm8x60_ssbi_pm8901_pdata __devinitdata = {
@@ -7106,15 +7131,6 @@
sx150x_data[SX150X_CORE_FLUID].irq_summary =
PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT1_N);
#endif
- /*
- * Set PMIC 8901 MPP0 active_high to 0 for surf and charm_surf. This
- * implies that the regulator connected to MPP0 is enabled when
- * MPP0 is low.
- */
- if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion())
- pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 0;
- else
- pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 1;
#endif
}
@@ -9905,7 +9921,13 @@
static void __init msm8x60_init(struct msm_board_data *board_data)
{
uint32_t soc_platform_version;
-
+#ifdef CONFIG_USB_EHCI_MSM_72K
+ struct pm8xxx_mpp_config_data hsusb_phy_mpp = {
+ .type = PM8XXX_MPP_TYPE_D_OUTPUT,
+ .level = PM8901_MPP_DIG_LEVEL_L5,
+ .control = PM8XXX_MPP_DOUT_CTRL_HIGH,
+ };
+#endif
pmic_reset_irq = PM8058_IRQ_BASE + PM8058_RESOUT_IRQ;
/*
@@ -10057,16 +10079,18 @@
}
#endif
+ pm8901_vreg_mpp0_init();
+
+ platform_device_register(&msm8x60_8901_mpp_vreg);
+
#ifdef CONFIG_USB_EHCI_MSM_72K
/*
* Drive MPP2 pin HIGH for PHY to generate ID interrupts on 8660
* fluid
*/
- if (machine_is_msm8x60_fluid()) {
- pm8901_mpp_config_digital_out(1,
- PM8901_MPP_DIG_LEVEL_L5, 1);
- }
- msm_add_host(0, &msm_usb_host_pdata);
+ if (machine_is_msm8x60_fluid())
+ pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(1), &hsusb_phy_mpp);
+ msm_add_host(0, &msm_usb_host_pdata);
#endif
#ifdef CONFIG_SND_SOC_MSM8660_APQ
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index ad803f8..208ed4e 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1286,7 +1286,7 @@
};
#endif
-static struct resource resources_ssbi_pm8921[] = {
+static struct resource resources_ssbi_pmic[] = {
{
.start = MSM_PMIC1_SSBI_CMD_PHYS,
.end = MSM_PMIC1_SSBI_CMD_PHYS + MSM_PMIC_SSBI_SIZE - 1,
@@ -1294,11 +1294,11 @@
},
};
-struct platform_device msm8960_device_ssbi_pm8921 = {
+struct platform_device msm8960_device_ssbi_pmic = {
.name = "msm_ssbi",
.id = 0,
- .resource = resources_ssbi_pm8921,
- .num_resources = ARRAY_SIZE(resources_ssbi_pm8921),
+ .resource = resources_ssbi_pmic,
+ .num_resources = ARRAY_SIZE(resources_ssbi_pmic),
};
static struct resource resources_qup_spi_gsbi1[] = {
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 1ba63c9..2fac2ef 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -51,7 +51,7 @@
extern struct platform_device msm8960_device_uart_gsbi2;
extern struct platform_device msm8960_device_uart_gsbi5;
-extern struct platform_device msm8960_device_ssbi_pm8921;
+extern struct platform_device msm8960_device_ssbi_pmic;
extern struct platform_device msm8960_device_qup_i2c_gsbi3;
extern struct platform_device msm8960_device_qup_i2c_gsbi4;
extern struct platform_device msm8960_device_qup_i2c_gsbi10;
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index a8e2449..5006419 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -151,21 +151,21 @@
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
- goto out;
+ return rc;
/* Un-halt all bus ports in the power domain. */
if (fs->bus_port1) {
rc = msm_bus_axi_portunhalt(fs->bus_port1);
if (rc) {
pr_err("%s: Port 1 unhalt failed.\n", __func__);
- goto out;
+ goto err;
}
}
if (fs->bus_port2) {
rc = msm_bus_axi_portunhalt(fs->bus_port2);
if (rc) {
pr_err("%s: Port 2 unhalt failed.\n", __func__);
- goto out;
+ goto err_port2_halt;
}
}
@@ -209,7 +209,12 @@
restore_clocks(fs);
fs->is_enabled = true;
-out:
+ return 0;
+
+err_port2_halt:
+ msm_bus_axi_porthalt(fs->bus_port1);
+err:
+ restore_clocks(fs);
return rc;
}
@@ -226,14 +231,14 @@
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
- goto out;
+ return rc;
/* Halt all bus ports in the power domain. */
if (fs->bus_port1) {
rc = msm_bus_axi_porthalt(fs->bus_port1);
if (rc) {
pr_err("%s: Port 1 halt failed.\n", __func__);
- goto out;
+ goto err;
}
}
if (fs->bus_port2) {
@@ -275,12 +280,12 @@
writel_relaxed(regval, fs->gfs_ctl_reg);
fs->is_enabled = false;
-
- return rc;
+ return 0;
err_port2_halt:
msm_bus_axi_portunhalt(fs->bus_port1);
-out:
+err:
+ restore_clocks(fs);
return rc;
}
@@ -301,14 +306,14 @@
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
- goto out;
+ return rc;
/* Un-halt all bus ports in the power domain. */
if (fs->bus_port1) {
rc = msm_bus_axi_portunhalt(fs->bus_port1);
if (rc) {
pr_err("%s: Port 1 unhalt failed.\n", __func__);
- goto out;
+ goto err;
}
}
@@ -351,7 +356,10 @@
restore_clocks(fs);
fs->is_enabled = true;
-out:
+ return 0;
+
+err:
+ restore_clocks(fs);
return rc;
}
@@ -368,14 +376,14 @@
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
- goto out;
+ return rc;
/* Halt all bus ports in the power domain. */
if (fs->bus_port1) {
rc = msm_bus_axi_porthalt(fs->bus_port1);
if (rc) {
pr_err("%s: Port 1 halt failed.\n", __func__);
- goto out;
+ goto err;
}
}
@@ -411,8 +419,10 @@
restore_clocks(fs);
fs->is_enabled = false;
+ return 0;
-out:
+err:
+ restore_clocks(fs);
return rc;
}
diff --git a/arch/arm/mach-msm/include/mach/board-msm8660.h b/arch/arm/mach-msm/include/mach/board-msm8660.h
new file mode 100644
index 0000000..b07cc62
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/board-msm8660.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2011, 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 __ARCH_ARM_MACH_MSM_BOARD_MSM8660_H
+#define __ARCH_ARM_MACH_MSM_BOARD_MSM8660_H
+
+#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pmic8901.h>
+#include <mach/irqs.h>
+
+/* Macros assume PMIC GPIOs start at 0 */
+#define PM8058_GPIO_BASE NR_MSM_GPIOS
+#define PM8058_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_GPIO_BASE)
+#define PM8058_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - PM8058_GPIO_BASE)
+#define PM8058_MPP_BASE (PM8058_GPIO_BASE + PM8058_GPIOS)
+#define PM8058_MPP_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_MPP_BASE)
+#define PM8058_MPP_SYS_TO_PM(sys_gpio) (sys_gpio - PM8058_MPP_BASE)
+#define PM8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+#define PM8901_MPP_BASE (PM8058_GPIO_BASE + \
+ PM8058_GPIOS + PM8058_MPPS)
+#define PM8901_MPP_PM_TO_SYS(pm_gpio) (pm_gpio + PM8901_MPP_BASE)
+#define PM8901_MPP_SYS_TO_PM(sys_gpio) (sys_gpio - PM901_MPP_BASE)
+#define PM8901_IRQ_BASE (PM8058_IRQ_BASE + \
+ NR_PMIC8058_IRQS)
+
+#endif
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 7a75bc1..5854a23 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.c
@@ -113,7 +113,7 @@
static int switch_memory_state(int id, int new_state)
{
- int mask;
+ int mask = 0;
int power_down_masks[MAX_NR_REGIONS] = { 0xFFFFFF00, 0xFFFF00FF,
0xFF00FFFF, 0x00FFFFFF };
int self_refresh_masks[MAX_NR_REGIONS] = { 0xFFFFFFF0, 0xFFFFFF0F,
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index bcb777f..5419087 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -40,7 +40,7 @@
#include <mach/subsystem_notif.h>
#define DRV_NAME "msm_dsps"
-#define DRV_VERSION "3.00"
+#define DRV_VERSION "3.01"
#define PPSS_PAUSE_REG 0x1804
@@ -655,11 +655,12 @@
if (dsps_state & SMSM_RESET) {
pr_err("%s: DSPS fatal error detected. Resetting\n",
__func__);
+ panic("DSPS fatal error detected.");
} else {
pr_debug("%s: User-initiated DSPS reset. Resetting\n",
__func__);
+ panic("User-initiated DSPS reset.");
}
- subsystem_restart("dsps");
}
@@ -682,7 +683,7 @@
pr_err
("%s: SMSM_RESET state detected. restarting the DSPS\n",
__func__);
- subsystem_restart("dsps");
+ panic("SMSM_RESET state detected.");
}
}
diff --git a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index 401c759..11687ac 100644
--- a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
+++ b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
@@ -17,19 +17,16 @@
#include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-othc.h>
#include <linux/mfd/pmic8901.h>
#include <linux/mfd/msm-adie-codec.h>
-#include <linux/regulator/pmic8058-regulator.h>
-#include <linux/regulator/pmic8901-regulator.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <mach/qdsp6v2/audio_dev_ctl.h>
-#include <mach/mpp.h>
#include <sound/apr_audio.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>
+#include <mach/board-msm8660.h>
#include "snddev_icodec.h"
#include "snddev_ecodec.h"
@@ -266,10 +263,15 @@
{
int rc;
- if (enable) {
- rc = pm8901_mpp_config_digital_out(PM8901_MPP_3,
- PM8901_MPP_DIG_LEVEL_MSMIO, 1);
+ struct pm8xxx_mpp_config_data class_d0_mpp = {
+ .type = PM8XXX_MPP_TYPE_D_OUTPUT,
+ .level = PM8901_MPP_DIG_LEVEL_MSMIO,
+ };
+ if (enable) {
+ class_d0_mpp.control = PM8XXX_MPP_DOUT_CTRL_HIGH;
+ rc = pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(PM8901_MPP_3),
+ &class_d0_mpp);
if (rc) {
pr_err("%s: CLASS_D0_EN failed\n", __func__);
return rc;
@@ -280,23 +282,48 @@
if (rc) {
pr_err("%s: spkr pamp gpio pm8901 mpp3 request"
"failed\n", __func__);
- pm8901_mpp_config_digital_out(PM8901_MPP_3,
- PM8901_MPP_DIG_LEVEL_MSMIO, 0);
+ class_d0_mpp.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+ pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(PM8901_MPP_3),
+ &class_d0_mpp);
return rc;
}
gpio_direction_output(SNDDEV_GPIO_CLASS_D0_EN, 1);
- gpio_set_value(SNDDEV_GPIO_CLASS_D0_EN, 1);
+ gpio_set_value_cansleep(SNDDEV_GPIO_CLASS_D0_EN, 1);
} else {
- pm8901_mpp_config_digital_out(PM8901_MPP_3,
- PM8901_MPP_DIG_LEVEL_MSMIO, 0);
- gpio_set_value(SNDDEV_GPIO_CLASS_D0_EN, 0);
+ class_d0_mpp.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+ pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(PM8901_MPP_3),
+ &class_d0_mpp);
+ gpio_set_value_cansleep(SNDDEV_GPIO_CLASS_D0_EN, 0);
gpio_free(SNDDEV_GPIO_CLASS_D0_EN);
}
return 0;
}
+static int config_class_d1_gpio(int enable)
+{
+ int rc;
+
+ if (enable) {
+ rc = gpio_request(SNDDEV_GPIO_CLASS_D1_EN, "CLASSD1_EN");
+
+ if (rc) {
+ pr_err("%s: Right Channel spkr gpio request"
+ " failed\n", __func__);
+ return rc;
+ }
+
+ gpio_direction_output(SNDDEV_GPIO_CLASS_D1_EN, 1);
+ gpio_set_value(SNDDEV_GPIO_CLASS_D1_EN, 1);
+
+ } else {
+ gpio_set_value(SNDDEV_GPIO_CLASS_D1_EN, 0);
+ gpio_free(SNDDEV_GPIO_CLASS_D1_EN);
+ }
+ return 0;
+}
+
static atomic_t pamp_ref_cnt;
static int msm_snddev_poweramp_on(void)
@@ -312,6 +339,11 @@
pr_err("%s: d0 gpio configuration failed\n", __func__);
goto config_gpio_fail;
}
+ rc = config_class_d1_gpio(1);
+ if (rc) {
+ pr_err("%s: d1 gpio configuration failed\n", __func__);
+ goto config_gpio_fail;
+ }
config_gpio_fail:
return rc;
}
@@ -321,6 +353,7 @@
if (atomic_dec_return(&pamp_ref_cnt) == 0) {
pr_debug("%s: disable stereo spkr amp\n", __func__);
config_class_d0_gpio(0);
+ config_class_d1_gpio(0);
msleep(30);
}
}
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 37469f8..78a6203 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -445,8 +445,8 @@
return -EINVAL;
}
- pr_info("Restart sequence requested for %s\n",
- subsys_name);
+ pr_info("Restart sequence requested for %s, restart_level = %d.\n",
+ subsys_name, restart_level);
/* List of subsystems is protected by a lock. New subsystems can
* still come in.
@@ -497,7 +497,8 @@
break;
case RESET_SOC:
- panic("subsys-restart: Resetting the SoC");
+ panic("subsys-restart: Resetting the SoC - %s crashed.",
+ subsys->name);
break;
default:
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index f076a10..90a1c7e 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -240,8 +240,8 @@
return t3;
if ((t2-t1) <= 1)
return t2;
- if (((t3-t2) == (t2-t1)) && (t3-t2) <= 8)
- return t3;
+ if ((t2 >= t1) && (t3 >= t2))
+ return t2;
if (++loop_count == 5) {
pr_err("msm_read_timer_count timer %s did not "
"stabilize: %u -> %u -> %u\n",
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 18b7334..af92d22 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -17,6 +17,8 @@
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/wcnss_wlan.h>
#include <mach/irqs.h>
#include <mach/scm.h>
#include <mach/subsystem_restart.h>
@@ -79,14 +81,32 @@
/* Subsystem handlers */
static int riva_shutdown(const struct subsys_data *subsys)
{
+ struct platform_device *pdev = wcnss_get_platform_device();
+ struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();
+ int ret = -1;
+
pil_force_shutdown("wcnss");
- return 0;
+
+ /* proxy vote on behalf of Riva */
+ if (pdev && pwlanconfig)
+ ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
+ WCNSS_WLAN_SWITCH_OFF);
+ return ret;
}
static int riva_powerup(const struct subsys_data *subsys)
{
- pil_force_boot("wcnss");
- return 0;
+ struct platform_device *pdev = wcnss_get_platform_device();
+ struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();
+ int ret = -1;
+
+ if (pdev && pwlanconfig)
+ ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
+ WCNSS_WLAN_SWITCH_ON);
+ if (!ret)
+ pil_force_boot("wcnss");
+
+ return ret;
}
/* RAM segments for Riva SS;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 58c9b9a..c8555cd 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -503,9 +503,11 @@
} else {
if (len > 0) {
if (entry.client_id == MODEM_PROC && driver->ch) {
- if ((cpu_is_msm8960() || cpu_is_msm8930()) &&
+ if ((cpu_is_msm8960() || cpu_is_msm8930() ||
+ cpu_is_msm9615()) &&
(int)(*(char *)buf) == MODE_CMD)
- if ((int)(*(char *)(buf+1)) == RESET_ID)
+ if ((int)(*(char *)(buf+1)) ==
+ RESET_ID)
return;
smd_write(driver->ch, buf, len);
} else if (entry.client_id == QDSP_PROC &&
@@ -542,7 +544,8 @@
temp += 2;
data_type = APPS_DATA;
/* Dont send any command other than mode reset */
- if ((cpu_is_msm8960() || cpu_is_msm8930()) && cmd_code == MODE_CMD) {
+ if ((cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615()) &&
+ cmd_code == MODE_CMD) {
if (subsys_id != RESET_ID)
data_type = MODEM_DATA;
}
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index e659df5..1428315 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1168,6 +1168,7 @@
vma->vm_private_data = NULL;
return;
}
+ ion_handle_get(handle);
mutex_lock(&buffer->lock);
buffer->umap_cnt++;
mutex_unlock(&buffer->lock);
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index eb0c828..8a65df4 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1374,19 +1374,6 @@
cal_req);
}
-static int hci_fm_set_cal_req_dc(struct radio_hci_dev *hdev,
- unsigned long param)
-{
- u16 opcode = 0;
- struct hci_fm_set_cal_req_dc *cal_req =
- (struct hci_fm_set_cal_req_dc *)param;
-
- opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
- HCI_OCF_FM_SET_CALIBRATION);
- return radio_hci_send_cmd(hdev, opcode, sizeof(*cal_req),
- cal_req);
-}
-
static int hci_fm_do_cal_req(struct radio_hci_dev *hdev,
unsigned long param)
{
@@ -1785,12 +1772,12 @@
if (rsp.mode == PROCS_CALIB_MODE) {
memcpy(&rsp.data[0], &skb->data[CALIB_DATA_OFSET],
PROCS_CALIB_SIZE);
- } else if (rsp.mode == DC_CALIB_MODE) {
- memcpy(&rsp.data[PROCS_CALIB_SIZE],
- &skb->data[CALIB_DATA_OFSET], DC_CALIB_SIZE);
- iris_q_evt_data(radio, rsp.data, (PROCS_CALIB_SIZE +
- DC_CALIB_SIZE), IRIS_BUF_CAL_DATA);
+ iris_q_evt_data(radio, rsp.data, PROCS_CALIB_SIZE,
+ IRIS_BUF_CAL_DATA);
+ } else {
+ return;
}
+
radio_hci_req_complete(hdev, rsp.status);
}
static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev,
@@ -1911,17 +1898,10 @@
struct sk_buff *skb)
{
int i;
- int len;
-
struct iris_device *radio = video_get_drvdata(video_get_dev());
- struct hci_fm_station_rsp *rsp;
- len = sizeof(struct hci_fm_station_rsp);
- rsp = (struct hci_fm_station_rsp *)skb_pull(skb, len);
- if (rsp == NULL)
- return;
- memcpy(&radio->fm_st_rsp.station_rsp, rsp, len);
-
+ memcpy(&radio->fm_st_rsp.station_rsp, &skb->data[0],
+ sizeof(struct hci_ev_tune_status));
iris_q_event(radio, IRIS_EVT_TUNE_SUCC);
for (i = 0; i < IRIS_BUF_MAX; i++) {
@@ -2400,13 +2380,6 @@
FMDERR("Do Process calibration failed %x", retval);
return retval;
}
- cal_mode = DC_CALIB_MODE;
- retval = radio_hci_request(radio->fm_hdev, hci_fm_do_cal_req,
- (unsigned long)cal_mode, RADIO_HCI_TIMEOUT);
- if (retval < 0) {
- FMDERR("Do DC calibration failed %x", retval);
- return retval;
- }
retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
radio->fm_hdev);
if (retval < 0)
@@ -2568,7 +2541,6 @@
struct hci_fm_tx_rt tx_rt;
struct hci_fm_def_data_wr_req default_data;
struct hci_fm_set_cal_req_proc proc_cal_req;
- struct hci_fm_set_cal_req_dc dc_cal_req;
struct iris_device *radio = video_get_drvdata(video_devdata(file));
char *data = NULL;
@@ -2624,7 +2596,7 @@
case V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION:
data = (ctrl->controls[0]).string;
bytes_to_copy = (ctrl->controls[0]).size;
- if (bytes_to_copy < (PROCS_CALIB_SIZE + DC_CALIB_SIZE)) {
+ if (bytes_to_copy < PROCS_CALIB_SIZE) {
FMDERR("data is less than required size");
return -EFAULT;
}
@@ -2639,18 +2611,7 @@
RADIO_HCI_TIMEOUT);
if (retval < 0) {
FMDERR("Set Process calibration failed %d", retval);
- return retval;
}
- memset(dc_cal_req.data, 0, DC_CALIB_SIZE);
- if (copy_from_user(&dc_cal_req.data[0], &data[PROCS_CALIB_SIZE],
- sizeof(dc_cal_req.data)))
- return -EFAULT;
- dc_cal_req.mode = DC_CALIB_MODE;
- retval = radio_hci_request(radio->fm_hdev,
- hci_fm_set_cal_req_dc,
- (unsigned long)&dc_cal_req, RADIO_HCI_TIMEOUT);
- if (retval < 0)
- FMDERR("Set DC calibration failed %d", retval);
break;
default:
FMDBG("Shouldn't reach here\n");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b1d808b..9e9bb23 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -805,6 +805,21 @@
Say M here if you want to include support for PM8018 chip as a module.
This will build a module called "pm8018-core".
+config MFD_PM8038_CORE
+ tristate "Qualcomm PM8038 PMIC chip"
+ depends on MSM_SSBI
+ select MFD_CORE
+ select MFD_PM8XXX
+ help
+ If you say yes to this option, support will be included for the
+ built-in PM8038 PMIC chip.
+
+ This is required if your board has a PM8038 and uses its features,
+ such as: MPPs, GPIOs, regulators, interrupts, and PWM.
+
+ Say M here if you want to include support for PM8038 chip as a module.
+ This will build a module called "pm8038-core".
+
config MFD_PM8XXX_IRQ
bool "Support for Qualcomm PM8xxx IRQ features"
depends on MFD_PM8XXX
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5813b86..30192d9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -117,6 +117,7 @@
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
obj-$(CONFIG_MFD_PM8821_CORE) += pm8821-core.o
obj-$(CONFIG_MFD_PM8018_CORE) += pm8018-core.o
+obj-$(CONFIG_MFD_PM8038_CORE) += pm8038-core.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_MFD_PM8XXX_DEBUG) += pm8xxx-debug.o
obj-$(CONFIG_MFD_PM8XXX_PWM) += pm8xxx-pwm.o
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
new file mode 100644
index 0000000..9123067
--- /dev/null
+++ b/drivers/mfd/pm8038-core.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/msm_ssbi.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/pm8xxx/pm8038.h>
+#include <linux/mfd/pm8xxx/core.h>
+
+#define REG_HWREV 0x002 /* PMIC4 revision */
+#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */
+
+#define REG_MPP_BASE 0x050
+#define REG_RTC_BASE 0x11D
+#define REG_IRQ_BASE 0x1BB
+
+#define PM8038_VERSION_MASK 0xFFF0
+#define PM8038_VERSION_VALUE 0x09F0
+#define PM8038_REVISION_MASK 0x000F
+
+#define REG_PM8038_PON_CNTRL_3 0x01D
+#define PM8038_RESTART_REASON_MASK 0x07
+
+#define SINGLE_IRQ_RESOURCE(_name, _irq) \
+{ \
+ .name = _name, \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ, \
+}
+
+struct pm8038 {
+ struct device *dev;
+ struct pm_irq_chip *irq_chip;
+ u32 rev_registers;
+};
+
+static int pm8038_readb(const struct device *dev, u16 addr, u8 *val)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+ return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
+}
+
+static int pm8038_writeb(const struct device *dev, u16 addr, u8 val)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+ return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
+}
+
+static int pm8038_read_buf(const struct device *dev, u16 addr, u8 *buf,
+ int cnt)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+ return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
+}
+
+static int pm8038_write_buf(const struct device *dev, u16 addr, u8 *buf,
+ int cnt)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+ return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
+}
+
+static int pm8038_read_irq_stat(const struct device *dev, int irq)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+ return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
+}
+
+static enum pm8xxx_version pm8038_get_version(const struct device *dev)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+ enum pm8xxx_version version = -ENODEV;
+
+ if ((pmic->rev_registers & PM8038_VERSION_MASK) == PM8038_VERSION_VALUE)
+ version = PM8XXX_VERSION_8038;
+
+ return version;
+}
+
+static int pm8038_get_revision(const struct device *dev)
+{
+ const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+ const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+ return pmic->rev_registers & PM8038_REVISION_MASK;
+}
+
+static struct pm8xxx_drvdata pm8038_drvdata = {
+ .pmic_readb = pm8038_readb,
+ .pmic_writeb = pm8038_writeb,
+ .pmic_read_buf = pm8038_read_buf,
+ .pmic_write_buf = pm8038_write_buf,
+ .pmic_read_irq_stat = pm8038_read_irq_stat,
+ .pmic_get_version = pm8038_get_version,
+ .pmic_get_revision = pm8038_get_revision,
+};
+
+static const struct resource gpio_cell_resources[] __devinitconst = {
+ [0] = {
+ .start = PM8038_IRQ_BLOCK_BIT(PM8038_GPIO_BLOCK_START, 0),
+ .end = PM8038_IRQ_BLOCK_BIT(PM8038_GPIO_BLOCK_START, 0)
+ + PM8038_NR_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell gpio_cell __devinitdata = {
+ .name = PM8XXX_GPIO_DEV_NAME,
+ .id = -1,
+ .resources = gpio_cell_resources,
+ .num_resources = ARRAY_SIZE(gpio_cell_resources),
+};
+
+static const struct resource mpp_cell_resources[] __devinitconst = {
+ {
+ .start = PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, 0),
+ .end = PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, 0)
+ + PM8038_NR_MPPS - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell mpp_cell __devinitdata = {
+ .name = PM8XXX_MPP_DEV_NAME,
+ .id = 1,
+ .resources = mpp_cell_resources,
+ .num_resources = ARRAY_SIZE(mpp_cell_resources),
+};
+
+static const struct resource rtc_cell_resources[] __devinitconst = {
+ [0] = SINGLE_IRQ_RESOURCE(NULL, PM8038_RTC_ALARM_IRQ),
+ [1] = {
+ .name = "pmic_rtc_base",
+ .start = REG_RTC_BASE,
+ .end = REG_RTC_BASE,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mfd_cell rtc_cell __devinitdata = {
+ .name = PM8XXX_RTC_DEV_NAME,
+ .id = -1,
+ .resources = rtc_cell_resources,
+ .num_resources = ARRAY_SIZE(rtc_cell_resources),
+};
+
+static const struct resource resources_pwrkey[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE(NULL, PM8038_PWRKEY_REL_IRQ),
+ SINGLE_IRQ_RESOURCE(NULL, PM8038_PWRKEY_PRESS_IRQ),
+};
+
+static struct mfd_cell pwrkey_cell __devinitdata = {
+ .name = PM8XXX_PWRKEY_DEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_pwrkey),
+ .resources = resources_pwrkey,
+};
+
+static struct mfd_cell pwm_cell __devinitdata = {
+ .name = PM8XXX_PWM_DEV_NAME,
+ .id = -1,
+};
+
+static struct mfd_cell misc_cell __devinitdata = {
+ .name = PM8XXX_MISC_DEV_NAME,
+ .id = -1,
+};
+
+static struct mfd_cell debugfs_cell __devinitdata = {
+ .name = "pm8xxx-debug",
+ .id = 0,
+ .platform_data = "pm8038-dbg",
+ .pdata_size = sizeof("pm8038-dbg"),
+};
+
+
+static int __devinit
+pm8038_add_subdevices(const struct pm8038_platform_data *pdata,
+ struct pm8038 *pmic)
+{
+ int ret = 0, irq_base = 0;
+ struct pm_irq_chip *irq_chip;
+
+ if (pdata->irq_pdata) {
+ pdata->irq_pdata->irq_cdata.nirqs = PM8038_NR_IRQS;
+ pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE;
+ irq_base = pdata->irq_pdata->irq_base;
+ irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+
+ if (IS_ERR(irq_chip)) {
+ pr_err("Failed to init interrupts ret=%ld\n",
+ PTR_ERR(irq_chip));
+ return PTR_ERR(irq_chip);
+ }
+ pmic->irq_chip = irq_chip;
+ }
+
+ if (pdata->gpio_pdata) {
+ pdata->gpio_pdata->gpio_cdata.ngpios = PM8038_NR_GPIOS;
+ gpio_cell.platform_data = pdata->gpio_pdata;
+ gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data);
+ ret = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1,
+ NULL, irq_base);
+ if (ret) {
+ pr_err("Failed to add gpio subdevice ret=%d\n", ret);
+ goto bail;
+ }
+ }
+
+ if (pdata->mpp_pdata) {
+ pdata->mpp_pdata->core_data.nmpps = PM8038_NR_MPPS;
+ pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE;
+ mpp_cell.platform_data = pdata->mpp_pdata;
+ mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data);
+ ret = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL,
+ irq_base);
+ if (ret) {
+ pr_err("Failed to add mpp subdevice ret=%d\n", ret);
+ goto bail;
+ }
+ }
+
+ if (pdata->rtc_pdata) {
+ rtc_cell.platform_data = pdata->rtc_pdata;
+ rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data);
+ ret = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL,
+ irq_base);
+ if (ret) {
+ pr_err("Failed to add rtc subdevice ret=%d\n", ret);
+ goto bail;
+ }
+ }
+
+ if (pdata->pwrkey_pdata) {
+ pwrkey_cell.platform_data = pdata->pwrkey_pdata;
+ pwrkey_cell.pdata_size =
+ sizeof(struct pm8xxx_pwrkey_platform_data);
+ ret = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL,
+ irq_base);
+ if (ret) {
+ pr_err("Failed to add pwrkey subdevice ret=%d\n", ret);
+ goto bail;
+ }
+ }
+
+ ret = mfd_add_devices(pmic->dev, 0, &pwm_cell, 1, NULL, 0);
+ if (ret) {
+ pr_err("Failed to add pwm subdevice ret=%d\n", ret);
+ goto bail;
+ }
+
+ if (pdata->misc_pdata) {
+ misc_cell.platform_data = pdata->misc_pdata;
+ misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
+ ret = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
+ irq_base);
+ if (ret) {
+ pr_err("Failed to add misc subdevice ret=%d\n", ret);
+ goto bail;
+ }
+ }
+
+ ret = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base);
+ if (ret) {
+ pr_err("Failed to add debugfs subdevice ret=%d\n", ret);
+ goto bail;
+ }
+
+ return 0;
+bail:
+ if (pmic->irq_chip) {
+ pm8xxx_irq_exit(pmic->irq_chip);
+ pmic->irq_chip = NULL;
+ }
+ return ret;
+}
+
+static const char * const pm8038_restart_reason[] = {
+ [0] = "Unknown",
+ [1] = "Triggered from CBL (external charger)",
+ [2] = "Triggered from KPD (power key press)",
+ [3] = "Triggered from CHG (usb charger insertion)",
+ [4] = "Triggered from SMPL (sudden momentary power loss)",
+ [5] = "Triggered from RTC (real time clock)",
+ [6] = "Triggered by Hard Reset",
+ [7] = "Triggered by General Purpose Trigger",
+};
+
+static const char * const pm8038_rev_names[] = {
+ [PM8XXX_REVISION_8038_TEST] = "test",
+ [PM8XXX_REVISION_8038_1p0] = "1.0",
+ [PM8XXX_REVISION_8038_2p0] = "2.0",
+ [PM8XXX_REVISION_8038_2p1] = "2.1",
+};
+
+static int __devinit pm8038_probe(struct platform_device *pdev)
+{
+ const struct pm8038_platform_data *pdata = pdev->dev.platform_data;
+ const char *revision_name = "unknown";
+ struct pm8038 *pmic;
+ enum pm8xxx_version version;
+ int revision;
+ int rc;
+ u8 val;
+
+ if (!pdata) {
+ pr_err("missing platform data\n");
+ return -EINVAL;
+ }
+
+ pmic = kzalloc(sizeof(struct pm8038), GFP_KERNEL);
+ if (!pmic) {
+ pr_err("Cannot alloc pm8038 struct\n");
+ return -ENOMEM;
+ }
+
+ /* Read PMIC chip revision */
+ rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
+ if (rc) {
+ pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
+ goto err_read_rev;
+ }
+ pr_info("PMIC revision 1: PM8038 rev %02X\n", val);
+ pmic->rev_registers = val;
+
+ /* Read PMIC chip revision 2 */
+ rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
+ if (rc) {
+ pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
+ REG_HWREV_2, rc);
+ goto err_read_rev;
+ }
+ pr_info("PMIC revision 2: PM8038 rev %02X\n", val);
+ pmic->rev_registers |= val << BITS_PER_BYTE;
+
+ pmic->dev = &pdev->dev;
+ pm8038_drvdata.pm_chip_data = pmic;
+ platform_set_drvdata(pdev, &pm8038_drvdata);
+
+ /* Print out human readable version and revision names. */
+ version = pm8xxx_get_version(pmic->dev);
+ if (version == PM8XXX_VERSION_8038) {
+ revision = pm8xxx_get_revision(pmic->dev);
+ if (revision >= 0 && revision < ARRAY_SIZE(pm8038_rev_names))
+ revision_name = pm8038_rev_names[revision];
+ pr_info("PMIC version: PM8038 ver %s\n", revision_name);
+ } else {
+ WARN_ON(version != PM8XXX_VERSION_8038);
+ }
+
+ /* Log human readable restart reason */
+ rc = msm_ssbi_read(pdev->dev.parent, REG_PM8038_PON_CNTRL_3, &val, 1);
+ if (rc) {
+ pr_err("Cannot read restart reason rc=%d\n", rc);
+ goto err_read_rev;
+ }
+ val &= PM8038_RESTART_REASON_MASK;
+ pr_info("PMIC Restart Reason: %s\n", pm8038_restart_reason[val]);
+
+ rc = pm8038_add_subdevices(pdata, pmic);
+ if (rc) {
+ pr_err("Cannot add subdevices rc=%d\n", rc);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ mfd_remove_devices(pmic->dev);
+ platform_set_drvdata(pdev, NULL);
+err_read_rev:
+ kfree(pmic);
+ return rc;
+}
+
+static int __devexit pm8038_remove(struct platform_device *pdev)
+{
+ struct pm8xxx_drvdata *drvdata;
+ struct pm8038 *pmic = NULL;
+
+ drvdata = platform_get_drvdata(pdev);
+
+ if (drvdata)
+ pmic = drvdata->pm_chip_data;
+
+ if (pmic) {
+ if (pmic->dev)
+ mfd_remove_devices(pmic->dev);
+
+ if (pmic->irq_chip) {
+ pm8xxx_irq_exit(pmic->irq_chip);
+ pmic->irq_chip = NULL;
+ }
+
+ kfree(pmic);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver pm8038_driver = {
+ .probe = pm8038_probe,
+ .remove = __devexit_p(pm8038_remove),
+ .driver = {
+ .name = PM8038_CORE_DEV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pm8038_init(void)
+{
+ return platform_driver_register(&pm8038_driver);
+}
+postcore_initcall(pm8038_init);
+
+static void __exit pm8038_exit(void)
+{
+ platform_driver_unregister(&pm8038_driver);
+}
+module_exit(pm8038_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PMIC 8038 core driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:pm8038-core");
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 3d87f0b..9e8786e 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -11,51 +11,25 @@
*/
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/ratelimit.h>
-#include <linux/gpio.h>
+#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/msm_ssbi.h>
#include <linux/mfd/pmic8901.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
+#include <linux/mfd/pm8xxx/core.h>
/* PMIC8901 Revision */
-#define SSBI_REG_REV 0x002 /* PMIC4 revision */
+#define PM8901_REG_REV 0x002
+#define PM8901_VERSION_MASK 0xF0
+#define PM8901_REVISION_MASK 0x0F
+#define PM8901_VERSION_VALUE 0xF0
-/* PMIC8901 IRQ */
-#define SSBI_REG_ADDR_IRQ_BASE 0xD5
+#define REG_IRQ_BASE 0xD5
+#define REG_MPP_BASE 0x27
-#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0)
-#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
-#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
-#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
-#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
-#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5)
-#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
-#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
-#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
-
-#define PM8901_IRQF_LVL_SEL 0x01 /* level select */
-#define PM8901_IRQF_MASK_FE 0x02 /* mask falling edge */
-#define PM8901_IRQF_MASK_RE 0x04 /* mask rising edge */
-#define PM8901_IRQF_CLR 0x08 /* clear interrupt */
-#define PM8901_IRQF_BITS_MASK 0x70
-#define PM8901_IRQF_BITS_SHIFT 4
-#define PM8901_IRQF_WRITE 0x80
-
-#define PM8901_IRQF_MASK_ALL (PM8901_IRQF_MASK_FE | \
- PM8901_IRQF_MASK_RE)
-#define PM8901_IRQF_W_C_M (PM8901_IRQF_WRITE | \
- PM8901_IRQF_CLR | \
- PM8901_IRQF_MASK_ALL)
-
-#define MAX_PM_IRQ 72
-#define MAX_PM_BLOCKS (MAX_PM_IRQ / 8 + 1)
-#define MAX_PM_MASTERS (MAX_PM_BLOCKS / 8 + 1)
-
-#define MPP_IRQ_BLOCK 1
+#define REG_TEMP_ALRM_CTRL 0x23
+#define REG_TEMP_ALRM_PWM 0x24
/* FTS regulator PMR registers */
#define SSBI_REG_ADDR_S1_PMR (0xA7)
@@ -70,47 +44,24 @@
#define DELAY_AFTER_REG_DISABLE_MS 4
#define DELAY_BEFORE_SHUTDOWN_MS 8
+#define SINGLE_IRQ_RESOURCE(_name, _irq) \
+{ \
+ .name = _name, \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ, \
+}
+
struct pm8901_chip {
struct pm8901_platform_data pdata;
struct device *dev;
-
- u8 irqs_allowed[MAX_PM_BLOCKS];
- u8 blocks_allowed[MAX_PM_MASTERS];
- u8 masters_allowed;
- int pm_max_irq;
- int pm_max_blocks;
- int pm_max_masters;
-
- u8 config[MAX_PM_IRQ];
- u8 wake_enable[MAX_PM_IRQ];
- u16 count_wakeable;
-
- u8 revision;
-
- spinlock_t pm_lock;
+ struct pm_irq_chip *irq_chip;
+ struct mfd_cell *mfd_regulators;
+ u8 revision;
};
-#if defined(CONFIG_DEBUG_FS)
-struct pm8901_dbg_device {
- struct mutex dbg_mutex;
- struct pm8901_chip *pm_chip;
- struct dentry *dent;
- int addr;
-};
-
-static struct pm8901_dbg_device *pmic_dbg_device;
-#endif
-
static struct pm8901_chip *pmic_chip;
-/* Helper Functions */
-DEFINE_RATELIMIT_STATE(pm8901_msg_ratelimit, 60 * HZ, 10);
-
-static inline int pm8901_can_print(void)
-{
- return __ratelimit(&pm8901_msg_ratelimit);
-}
-
static inline int
ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
{
@@ -123,80 +74,6 @@
return msm_ssbi_write(dev->parent, addr, buf, len);
}
-/* External APIs */
-int pm8901_rev(struct pm8901_chip *chip)
-{
- if (chip == NULL) {
- if (pmic_chip != NULL)
- return pmic_chip->revision;
- else
- return -EINVAL;
- }
-
- return chip->revision;
-}
-EXPORT_SYMBOL(pm8901_rev);
-
-int pm8901_read(struct pm8901_chip *chip, u16 addr, u8 *values,
- unsigned int len)
-{
- if (chip == NULL)
- return -EINVAL;
-
- return ssbi_read(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8901_read);
-
-int pm8901_write(struct pm8901_chip *chip, u16 addr, u8 *values,
- unsigned int len)
-{
- if (chip == NULL)
- return -EINVAL;
-
- return ssbi_write(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8901_write);
-
-int pm8901_irq_get_rt_status(struct pm8901_chip *chip, int irq)
-{
- int rc;
- u8 block, bits, bit;
- unsigned long irqsave;
-
- if (chip == NULL || irq < chip->pdata.irq_base ||
- irq >= chip->pdata.irq_base + MAX_PM_IRQ)
- return -EINVAL;
-
- irq -= chip->pdata.irq_base;
-
- block = irq / 8;
- bit = irq % 8;
-
- spin_lock_irqsave(&chip->pm_lock, irqsave);
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
- __func__, rc);
- goto bail_out;
- }
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n",
- __func__, rc);
- goto bail_out;
- }
-
- rc = (bits & (1 << bit)) ? 1 : 0;
-
-bail_out:
- spin_unlock_irqrestore(&chip->pm_lock, irqsave);
-
- return rc;
-}
-EXPORT_SYMBOL(pm8901_irq_get_rt_status);
-
int pm8901_reset_pwr_off(int reset)
{
int rc = 0, i;
@@ -240,673 +117,283 @@
}
EXPORT_SYMBOL(pm8901_reset_pwr_off);
-/* Internal functions */
-static inline int
-pm8901_config_irq(struct pm8901_chip *chip, u8 *bp, u8 *cp)
+static int pm8901_readb(const struct device *dev, u16 addr, u8 *val)
{
- int rc;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
- if (rc) {
- pr_err("%s: ssbi_write: rc=%d (Select block)\n",
- __func__, rc);
- goto bail_out;
- }
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp, 1);
- if (rc)
- pr_err("%s: ssbi_write: rc=%d (Configure IRQ)\n",
- __func__, rc);
-
-bail_out:
- return rc;
+ return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
}
-static void pm8901_irq_mask(struct irq_data *d)
+static int pm8901_writeb(const struct device *dev, u16 addr, u8 val)
{
- int master, irq_bit;
- struct pm8901_chip *chip = irq_data_get_irq_handler_data(d);
- u8 block, config;
- unsigned int irq = d->irq;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
- master = block / 8;
- irq_bit = irq % 8;
-
- chip->irqs_allowed[block] &= ~(1 << irq_bit);
- if (!chip->irqs_allowed[block]) {
- chip->blocks_allowed[master] &= ~(1 << (block % 8));
-
- if (!chip->blocks_allowed[master])
- chip->masters_allowed &= ~(1 << master);
- }
-
- config = PM8901_IRQF_WRITE | chip->config[irq] |
- PM8901_IRQF_MASK_FE | PM8901_IRQF_MASK_RE;
- pm8901_config_irq(chip, &block, &config);
+ return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
}
-static void pm8901_irq_unmask(struct irq_data *d)
+static int pm8901_read_buf(const struct device *dev, u16 addr, u8 *buf,
+ int cnt)
{
- int master, irq_bit;
- struct pm8901_chip *chip = irq_data_get_irq_handler_data(d);
- u8 block, config, old_irqs_allowed, old_blocks_allowed;
- unsigned int irq = d->irq;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
- master = block / 8;
- irq_bit = irq % 8;
-
- old_irqs_allowed = chip->irqs_allowed[block];
- chip->irqs_allowed[block] |= 1 << irq_bit;
- if (!old_irqs_allowed) {
- master = block / 8;
-
- old_blocks_allowed = chip->blocks_allowed[master];
- chip->blocks_allowed[master] |= 1 << (block % 8);
-
- if (!old_blocks_allowed)
- chip->masters_allowed |= 1 << master;
- }
-
- config = PM8901_IRQF_WRITE | chip->config[irq];
- pm8901_config_irq(chip, &block, &config);
+ return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
}
-static void pm8901_irq_ack(struct irq_data *d)
+static int pm8901_write_buf(const struct device *dev, u16 addr, u8 *buf,
+ int cnt)
{
- struct pm8901_chip *chip = irq_data_get_irq_handler_data(d);
- u8 block, config;
- unsigned int irq = d->irq;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
-
- config = PM8901_IRQF_WRITE | chip->config[irq] | PM8901_IRQF_CLR;
- pm8901_config_irq(chip, &block, &config);
+ return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
}
-static int pm8901_irq_set_type(struct irq_data *d, unsigned int flow_type)
+static int pm8901_read_irq_stat(const struct device *dev, int irq)
{
- int master, irq_bit;
- struct pm8901_chip *chip = irq_data_get_irq_handler_data(d);
- u8 block, config;
- unsigned int irq = d->irq;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- if (irq > chip->pm_max_irq) {
- chip->pm_max_irq = irq;
- chip->pm_max_blocks =
- chip->pm_max_irq / 8 + 1;
- chip->pm_max_masters =
- chip->pm_max_blocks / 8 + 1;
- }
- block = irq / 8;
- master = block / 8;
- irq_bit = irq % 8;
-
- chip->config[irq] = (irq_bit << PM8901_IRQF_BITS_SHIFT) |
- PM8901_IRQF_MASK_RE | PM8901_IRQF_MASK_FE;
- if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
- if (flow_type & IRQF_TRIGGER_RISING)
- chip->config[irq] &= ~PM8901_IRQF_MASK_RE;
- if (flow_type & IRQF_TRIGGER_FALLING)
- chip->config[irq] &= ~PM8901_IRQF_MASK_FE;
- } else {
- chip->config[irq] |= PM8901_IRQF_LVL_SEL;
-
- if (flow_type & IRQF_TRIGGER_HIGH)
- chip->config[irq] &= ~PM8901_IRQF_MASK_RE;
- else
- chip->config[irq] &= ~PM8901_IRQF_MASK_FE;
- }
-
- config = PM8901_IRQF_WRITE | chip->config[irq] | PM8901_IRQF_CLR;
- return pm8901_config_irq(chip, &block, &config);
-}
-
-static int pm8901_irq_set_wake(struct irq_data *d, unsigned int on)
-{
- struct pm8901_chip *chip = irq_data_get_irq_handler_data(d);
- unsigned int irq = d->irq;
-
- irq -= chip->pdata.irq_base;
- if (on) {
- if (!chip->wake_enable[irq]) {
- chip->wake_enable[irq] = 1;
- chip->count_wakeable++;
- }
- } else {
- if (chip->wake_enable[irq]) {
- chip->wake_enable[irq] = 0;
- chip->count_wakeable--;
- }
- }
+ return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
return 0;
}
-static inline int
-pm8901_read_root(struct pm8901_chip *chip, u8 *rp)
+static enum pm8xxx_version pm8901_get_version(const struct device *dev)
{
- int rc;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
+ enum pm8xxx_version version = -ENODEV;
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read Root)\n",
- __func__, rc);
- *rp = 0;
- }
+ if ((pmic->revision & PM8901_VERSION_MASK) == PM8901_VERSION_VALUE)
+ version = PM8XXX_VERSION_8901;
- return rc;
+ return version;
}
-static inline int
-pm8901_read_master(struct pm8901_chip *chip, u8 m, u8 *bp)
+static int pm8901_get_revision(const struct device *dev)
{
- int rc;
+ const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+ const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read Master)\n",
- __func__, rc);
- *bp = 0;
- }
-
- return rc;
+ return pmic->revision & PM8901_REVISION_MASK;
}
-static inline int
-pm8901_read_block(struct pm8901_chip *chip, u8 *bp, u8 *ip)
-{
- int rc;
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
- __func__, rc);
- *bp = 0;
- goto bail_out;
- }
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip, 1);
- if (rc)
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read Status)\n",
- __func__, rc);
-
-bail_out:
- return rc;
-}
-
-static irqreturn_t pm8901_isr_thread(int irq_requested, void *data)
-{
- struct pm8901_chip *chip = data;
- int i, j, k;
- u8 root, block, config, bits;
- u8 blocks[MAX_PM_MASTERS];
- int masters = 0, irq, handled = 0, spurious = 0;
- u16 irqs_to_handle[MAX_PM_IRQ];
- unsigned long irqsave;
-
- spin_lock_irqsave(&chip->pm_lock, irqsave);
-
- /* Read root for masters */
- if (pm8901_read_root(chip, &root))
- goto bail_out;
-
- masters = root >> 1;
-
- if (!(masters & chip->masters_allowed) ||
- (masters & ~chip->masters_allowed)) {
- spurious = 1000000;
- }
-
- /* Read allowed masters for blocks. */
- for (i = 0; i < chip->pm_max_masters; i++) {
- if (masters & (1 << i)) {
- if (pm8901_read_master(chip, i, &blocks[i]))
- goto bail_out;
-
- if (!blocks[i]) {
- if (pm8901_can_print())
- pr_err("%s: Spurious master: %d "
- "(blocks=0)", __func__, i);
- spurious += 10000;
- }
- } else
- blocks[i] = 0;
- }
-
- /* Select block, read status and call isr */
- for (i = 0; i < chip->pm_max_masters; i++) {
- if (!blocks[i])
- continue;
-
- for (j = 0; j < 8; j++) {
- if (!(blocks[i] & (1 << j)))
- continue;
-
- block = i * 8 + j; /* block # */
- if (pm8901_read_block(chip, &block, &bits))
- goto bail_out;
-
- if (!bits) {
- if (pm8901_can_print())
- pr_err("%s: Spurious block: "
- "[master, block]=[%d, %d] "
- "(bits=0)\n", __func__, i, j);
- spurious += 100;
- continue;
- }
-
- /* Check IRQ bits */
- for (k = 0; k < 8; k++) {
- if (!(bits & (1 << k)))
- continue;
-
- /* Check spurious interrupts */
- if (((1 << i) & chip->masters_allowed) &&
- (blocks[i] & chip->blocks_allowed[i]) &&
- (bits & chip->irqs_allowed[block])) {
-
- /* Found one */
- irq = block * 8 + k;
- irqs_to_handle[handled] = irq +
- chip->pdata.irq_base;
- handled++;
- } else {
- /* Clear and mask wrong one */
- config = PM8901_IRQF_W_C_M |
- (k < PM8901_IRQF_BITS_SHIFT);
-
- pm8901_config_irq(chip,
- &block, &config);
-
- if (pm8901_can_print())
- pr_err("%s: Spurious IRQ: "
- "[master, block, bit]="
- "[%d, %d (%d), %d]\n",
- __func__,
- i, j, block, k);
- spurious++;
- }
- }
- }
-
- }
-
-bail_out:
-
- spin_unlock_irqrestore(&chip->pm_lock, irqsave);
-
- for (i = 0; i < handled; i++)
- generic_handle_irq(irqs_to_handle[i]);
-
- if (spurious) {
- if (!pm8901_can_print())
- return IRQ_HANDLED;
-
- pr_err("%s: spurious = %d (handled = %d)\n",
- __func__, spurious, handled);
- pr_err(" root = 0x%x (masters_allowed<<1 = 0x%x)\n",
- root, chip->masters_allowed << 1);
- for (i = 0; i < chip->pm_max_masters; i++) {
- if (masters & (1 << i))
- pr_err(" blocks[%d]=0x%x, "
- "allowed[%d]=0x%x\n",
- i, blocks[i],
- i, chip->blocks_allowed[i]);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int check_addr(int addr, const char *func_name)
-{
- if (addr < 0 || addr > 0x3FF) {
- pr_err("%s: PMIC 8901 register address is invalid: %d\n",
- func_name, addr);
- return -EINVAL;
- }
- return 0;
-}
-
-static int data_set(void *data, u64 val)
-{
- struct pm8901_dbg_device *dbgdev = data;
- u8 reg = val;
- int rc;
-
- mutex_lock(&dbgdev->dbg_mutex);
-
- rc = check_addr(dbgdev->addr, __func__);
- if (rc)
- goto done;
-
- rc = pm8901_write(dbgdev->pm_chip, dbgdev->addr, ®, 1);
-
- if (rc)
- pr_err("%s: FAIL pm8901_write(0x%03X)=0x%02X: rc=%d\n",
- __func__, dbgdev->addr, reg, rc);
-done:
- mutex_unlock(&dbgdev->dbg_mutex);
- return rc;
-}
-
-static int data_get(void *data, u64 *val)
-{
- struct pm8901_dbg_device *dbgdev = data;
- int rc;
- u8 reg;
-
- mutex_lock(&dbgdev->dbg_mutex);
-
- rc = check_addr(dbgdev->addr, __func__);
- if (rc)
- goto done;
-
- rc = pm8901_read(dbgdev->pm_chip, dbgdev->addr, ®, 1);
-
- if (rc) {
- pr_err("%s: FAIL pm8901_read(0x%03X)=0x%02X: rc=%d\n",
- __func__, dbgdev->addr, reg, rc);
- goto done;
- }
-
- *val = reg;
-done:
- mutex_unlock(&dbgdev->dbg_mutex);
- return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_data_fops, data_get, data_set, "0x%02llX\n");
-
-static int addr_set(void *data, u64 val)
-{
- struct pm8901_dbg_device *dbgdev = data;
- int rc;
-
- rc = check_addr(val, __func__);
- if (rc)
- return rc;
-
- mutex_lock(&dbgdev->dbg_mutex);
- dbgdev->addr = val;
- mutex_unlock(&dbgdev->dbg_mutex);
-
- return 0;
-}
-
-static int addr_get(void *data, u64 *val)
-{
- struct pm8901_dbg_device *dbgdev = data;
- int rc;
-
- mutex_lock(&dbgdev->dbg_mutex);
-
- rc = check_addr(dbgdev->addr, __func__);
- if (rc) {
- mutex_unlock(&dbgdev->dbg_mutex);
- return rc;
- }
- *val = dbgdev->addr;
-
- mutex_unlock(&dbgdev->dbg_mutex);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_addr_fops, addr_get, addr_set, "0x%03llX\n");
-
-static int __devinit pmic8901_dbg_probe(struct pm8901_chip *chip)
-{
- struct pm8901_dbg_device *dbgdev;
- struct dentry *dent;
- struct dentry *temp;
- int rc;
-
- if (chip == NULL) {
- pr_err("%s: no parent data passed in.\n", __func__);
- return -EINVAL;
- }
-
- dbgdev = kzalloc(sizeof *dbgdev, GFP_KERNEL);
- if (dbgdev == NULL) {
- pr_err("%s: kzalloc() failed.\n", __func__);
- return -ENOMEM;
- }
-
- dbgdev->pm_chip = chip;
- dbgdev->addr = -1;
-
- dent = debugfs_create_dir("pm8901-dbg", NULL);
- if (dent == NULL || IS_ERR(dent)) {
- pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
- __func__, (unsigned)dent);
- rc = PTR_ERR(dent);
- goto dir_error;
- }
-
- temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
- dbgdev, &dbg_addr_fops);
- if (temp == NULL || IS_ERR(temp)) {
- pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
- __func__, (unsigned)temp);
- rc = PTR_ERR(temp);
- goto debug_error;
- }
-
- temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, dent,
- dbgdev, &dbg_data_fops);
- if (temp == NULL || IS_ERR(temp)) {
- pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
- __func__, (unsigned)temp);
- rc = PTR_ERR(temp);
- goto debug_error;
- }
-
- mutex_init(&dbgdev->dbg_mutex);
-
- dbgdev->dent = dent;
-
- pmic_dbg_device = dbgdev;
-
- return 0;
-
-debug_error:
- debugfs_remove_recursive(dent);
-dir_error:
- kfree(dbgdev);
-
- return rc;
-}
-
-static int __devexit pmic8901_dbg_remove(void)
-{
- if (pmic_dbg_device) {
- debugfs_remove_recursive(pmic_dbg_device->dent);
- mutex_destroy(&pmic_dbg_device->dbg_mutex);
- kfree(pmic_dbg_device);
- }
- return 0;
-}
-
-#else
-
-static int __devinit pmic8901_dbg_probe(struct pm8901_chip *chip)
-{
- return 0;
-}
-
-static int __devexit pmic8901_dbg_remove(void)
-{
- return 0;
-}
-
-#endif
-
-static struct irq_chip pm8901_irq_chip = {
- .name = "pm8901",
- .irq_ack = pm8901_irq_ack,
- .irq_mask = pm8901_irq_mask,
- .irq_unmask = pm8901_irq_unmask,
- .irq_set_type = pm8901_irq_set_type,
- .irq_set_wake = pm8901_irq_set_wake,
+static struct pm8xxx_drvdata pm8901_drvdata = {
+ .pmic_readb = pm8901_readb,
+ .pmic_writeb = pm8901_writeb,
+ .pmic_read_buf = pm8901_read_buf,
+ .pmic_write_buf = pm8901_write_buf,
+ .pmic_read_irq_stat = pm8901_read_irq_stat,
+ .pmic_get_version = pm8901_get_version,
+ .pmic_get_revision = pm8901_get_revision,
};
+static struct mfd_cell debugfs_cell = {
+ .name = "pm8xxx-debug",
+ .id = 1,
+ .platform_data = "pm8901-dbg",
+ .pdata_size = sizeof("pm8901-dbg"),
+};
+
+static const struct resource thermal_alarm_cell_resources[] = {
+ SINGLE_IRQ_RESOURCE("pm8901_tempstat_irq", PM8901_TEMPSTAT_IRQ),
+ SINGLE_IRQ_RESOURCE("pm8901_overtemp_irq", PM8901_OVERTEMP_IRQ),
+};
+
+static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
+ .adc_type = PM8XXX_TM_ADC_NONE,
+ .reg_addr_temp_alarm_ctrl = REG_TEMP_ALRM_CTRL,
+ .reg_addr_temp_alarm_pwm = REG_TEMP_ALRM_PWM,
+ .tm_name = "pm8901_tz",
+ .irq_name_temp_stat = "pm8901_tempstat_irq",
+ .irq_name_over_temp = "pm8901_overtemp_irq",
+};
+
+static struct mfd_cell thermal_alarm_cell = {
+ .name = PM8XXX_TM_DEV_NAME,
+ .id = 1,
+ .resources = thermal_alarm_cell_resources,
+ .num_resources = ARRAY_SIZE(thermal_alarm_cell_resources),
+ .platform_data = &thermal_alarm_cdata,
+ .pdata_size = sizeof(struct pm8xxx_tm_core_data),
+};
+
+static const struct resource mpp_cell_resources[] = {
+ {
+ .start = PM8901_IRQ_BLOCK_BIT(PM8901_MPP_BLOCK_START, 0),
+ .end = PM8901_IRQ_BLOCK_BIT(PM8901_MPP_BLOCK_START, 0)
+ + PM8901_MPPS - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell mpp_cell = {
+ .name = PM8XXX_MPP_DEV_NAME,
+ .id = 1,
+ .resources = mpp_cell_resources,
+ .num_resources = ARRAY_SIZE(mpp_cell_resources),
+};
+
+static int __devinit
+pm8901_add_subdevices(const struct pm8901_platform_data *pdata,
+ struct pm8901_chip *pmic)
+{
+ int rc = 0, irq_base = 0, i;
+ struct pm_irq_chip *irq_chip;
+ static struct mfd_cell *mfd_regulators;
+
+ if (pdata->irq_pdata) {
+ pdata->irq_pdata->irq_cdata.nirqs = PM8901_NR_IRQS;
+ pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE;
+ irq_base = pdata->irq_pdata->irq_base;
+ irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+
+ if (IS_ERR(irq_chip)) {
+ pr_err("Failed to init interrupts ret=%ld\n",
+ PTR_ERR(irq_chip));
+ return PTR_ERR(irq_chip);
+ }
+ pmic->irq_chip = irq_chip;
+ }
+
+ if (pdata->mpp_pdata) {
+ pdata->mpp_pdata->core_data.nmpps = PM8901_MPPS;
+ pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE;
+ mpp_cell.platform_data = pdata->mpp_pdata;
+ mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add mpp subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
+ mfd_regulators = kzalloc(sizeof(struct mfd_cell)
+ * (pdata->num_regulators), GFP_KERNEL);
+ if (!mfd_regulators) {
+ pr_err("Cannot allocate %d bytes for pm8901 regulator "
+ "mfd cells\n", sizeof(struct mfd_cell)
+ * (pdata->num_regulators));
+ rc = -ENOMEM;
+ goto bail;
+ }
+ for (i = 0; i < pdata->num_regulators; i++) {
+ mfd_regulators[i].name = "pm8901-regulator";
+ mfd_regulators[i].id = pdata->regulator_pdatas[i].id;
+ mfd_regulators[i].platform_data =
+ &(pdata->regulator_pdatas[i]);
+ mfd_regulators[i].pdata_size =
+ sizeof(struct pm8901_vreg_pdata);
+ }
+ rc = mfd_add_devices(pmic->dev, 0, mfd_regulators,
+ pdata->num_regulators, NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add regulator subdevices ret=%d\n",
+ rc);
+ kfree(mfd_regulators);
+ goto bail;
+ }
+ pmic->mfd_regulators = mfd_regulators;
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add thermal alarm subdevice ret=%d\n",
+ rc);
+ goto bail;
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add debugfs subdevice ret=%d\n", rc);
+ goto bail;
+ }
+
+ return rc;
+
+bail:
+ if (pmic->irq_chip) {
+ pm8xxx_irq_exit(pmic->irq_chip);
+ pmic->irq_chip = NULL;
+ }
+ return rc;
+}
+
static int pm8901_probe(struct platform_device *pdev)
{
- int i, rc;
+ int rc;
struct pm8901_platform_data *pdata = pdev->dev.platform_data;
- struct pm8901_chip *chip;
+ struct pm8901_chip *pmic;
- if (pdata == NULL || pdata->irq <= 0) {
+ if (pdata == NULL) {
pr_err("%s: No platform_data or IRQ.\n", __func__);
return -ENODEV;
}
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
- if (chip == NULL) {
+ pmic = kzalloc(sizeof *pmic, GFP_KERNEL);
+ if (pmic == NULL) {
pr_err("%s: kzalloc() failed.\n", __func__);
return -ENOMEM;
}
- chip->dev = &pdev->dev;
+ pmic->dev = &pdev->dev;
+
+ pm8901_drvdata.pm_chip_data = pmic;
+ platform_set_drvdata(pdev, &pm8901_drvdata);
+ pmic_chip = pmic;
/* Read PMIC chip revision */
- rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
+ rc = pm8901_readb(pmic->dev, PM8901_REG_REV, &pmic->revision);
if (rc)
- pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
+ pr_err("%s: Failed reading version register rc=%d.\n",
__func__, rc);
- pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);
- (void) memcpy((void *)&chip->pdata, (const void *)pdata,
- sizeof(chip->pdata));
+ pr_info("%s: PMIC REVISION = %X\n", __func__, pmic->revision);
- irq_set_handler_data(pdata->irq, (void *)chip);
- irq_set_irq_wake(pdata->irq, 1);
+ (void) memcpy((void *)&pmic->pdata, (const void *)pdata,
+ sizeof(pmic->pdata));
- chip->pm_max_irq = 0;
- chip->pm_max_blocks = 0;
- chip->pm_max_masters = 0;
-
- platform_set_drvdata(pdev, chip);
-
- pmic_chip = chip;
- spin_lock_init(&chip->pm_lock);
-
- /* Register for all reserved IRQs */
- for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
- irq_set_chip(i, &pm8901_irq_chip);
- irq_set_handler(i, handle_edge_irq);
- set_irq_flags(i, IRQF_VALID);
- irq_set_handler_data(i, (void *)chip);
- }
-
- rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
- pdata->num_subdevs, NULL, 0);
+ rc = pm8901_add_subdevices(pdata, pmic);
if (rc) {
- pr_err("%s: could not add devices %d\n", __func__, rc);
- return rc;
+ pr_err("Cannot add subdevices rc=%d\n", rc);
+ goto err;
}
- rc = request_threaded_irq(pdata->irq, NULL, pm8901_isr_thread,
- IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
- "pm8901-irq", chip);
- if (rc)
- pr_err("%s: could not request irq %d: %d\n", __func__,
- pdata->irq, rc);
+ return 0;
- rc = pmic8901_dbg_probe(chip);
- if (rc < 0)
- pr_err("%s: could not set up debugfs: %d\n", __func__, rc);
-
+err:
+ platform_set_drvdata(pdev, NULL);
+ kfree(pmic);
return rc;
}
static int __devexit pm8901_remove(struct platform_device *pdev)
{
- struct pm8901_chip *chip;
+ struct pm8xxx_drvdata *drvdata;
+ struct pm8901_chip *pmic = NULL;
- chip = platform_get_drvdata(pdev);
- if (chip) {
- if (chip->pm_max_irq) {
- irq_set_irq_wake(chip->pdata.irq, 0);
- free_irq(chip->pdata.irq, chip);
- }
-
- mfd_remove_devices(chip->dev);
-
- chip->dev = NULL;
-
- kfree(chip);
+ drvdata = platform_get_drvdata(pdev);
+ if (drvdata)
+ pmic = drvdata->pm_chip_data;
+ if (pmic) {
+ if (pmic->dev)
+ mfd_remove_devices(pmic->dev);
+ if (pmic->irq_chip)
+ pm8xxx_irq_exit(pmic->irq_chip);
+ kfree(pmic->mfd_regulators);
+ kfree(pmic);
}
-
- pmic8901_dbg_remove();
+ platform_set_drvdata(pdev, NULL);
return 0;
}
-#ifdef CONFIG_PM
-static int pm8901_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
- struct pm8901_chip *chip;
- int i;
- unsigned long irqsave;
-
- chip = platform_get_drvdata(pdev);
-
- for (i = 0; i < MAX_PM_IRQ; i++) {
- spin_lock_irqsave(&chip->pm_lock, irqsave);
- if (chip->config[i] && !chip->wake_enable[i]) {
- if (!((chip->config[i] & PM8901_IRQF_MASK_ALL)
- == PM8901_IRQF_MASK_ALL))
- pm8901_irq_mask(irq_get_irq_data(i +
- chip->pdata.irq_base));
- }
- spin_unlock_irqrestore(&chip->pm_lock, irqsave);
- }
-
- if (!chip->count_wakeable)
- disable_irq(chip->pdata.irq);
-
- return 0;
-}
-
-static int pm8901_resume(struct platform_device *pdev)
-{
- struct pm8901_chip *chip;
- int i;
- unsigned long irqsave;
-
- chip = platform_get_drvdata(pdev);
-
- for (i = 0; i < MAX_PM_IRQ; i++) {
- spin_lock_irqsave(&chip->pm_lock, irqsave);
- if (chip->config[i] && !chip->wake_enable[i]) {
- if (!((chip->config[i] & PM8901_IRQF_MASK_ALL)
- == PM8901_IRQF_MASK_ALL))
- pm8901_irq_unmask(irq_get_irq_data(i +
- chip->pdata.irq_base));
- }
- spin_unlock_irqrestore(&chip->pm_lock, irqsave);
- }
-
- if (!chip->count_wakeable)
- enable_irq(chip->pdata.irq);
-
- return 0;
-}
-#else
-#define pm8901_suspend NULL
-#define pm8901_resume NULL
-#endif
-
static struct platform_driver pm8901_driver = {
.probe = pm8901_probe,
.remove = __devexit_p(pm8901_remove),
@@ -914,15 +401,13 @@
.name = "pm8901-core",
.owner = THIS_MODULE,
},
- .suspend = pm8901_suspend,
- .resume = pm8901_resume,
};
static int __init pm8901_init(void)
{
return platform_driver_register(&pm8901_driver);
}
-arch_initcall(pm8901_init);
+postcore_initcall(pm8901_init);
static void __exit pm8901_exit(void)
{
diff --git a/drivers/mfd/timpani-codec.c b/drivers/mfd/timpani-codec.c
index b9ae84e..d2c2eb4 100644
--- a/drivers/mfd/timpani-codec.c
+++ b/drivers/mfd/timpani-codec.c
@@ -2755,6 +2755,7 @@
case TIMPANI_A_CDC_ANC2_CTL1:
case TIMPANI_A_CDC_ANC2_CTL2:
case TIMPANI_A_CDC_ANC2_FF_FB_SHIFT:
+ case TIMPANI_A_AUXPGA_LR_GAIN:
return false;
default:
return true;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 1116ca8..2c7c0a5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -412,7 +412,9 @@
int err;
host->en_dis_recurs = 1;
+ mmc_host_clk_hold(host);
err = host->ops->enable(host);
+ mmc_host_clk_release(host);
host->en_dis_recurs = 0;
if (err) {
@@ -432,7 +434,9 @@
int err;
host->en_dis_recurs = 1;
+ mmc_host_clk_hold(host);
err = host->ops->disable(host, lazy);
+ mmc_host_clk_release(host);
host->en_dis_recurs = 0;
if (err < 0) {
@@ -1003,8 +1007,11 @@
host->ios.signal_voltage = signal_voltage;
- if (host->ops->start_signal_voltage_switch)
+ if (host->ops->start_signal_voltage_switch) {
+ mmc_host_clk_hold(host);
err = host->ops->start_signal_voltage_switch(host, &host->ios);
+ mmc_host_clk_release(host);
+ }
return err;
}
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
index fb8a5cd..08a7852 100644
--- a/drivers/mmc/core/host.h
+++ b/drivers/mmc/core/host.h
@@ -14,27 +14,6 @@
int mmc_register_host_class(void);
void mmc_unregister_host_class(void);
-
-#ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_hold(struct mmc_host *host);
-void mmc_host_clk_release(struct mmc_host *host);
-unsigned int mmc_host_clk_rate(struct mmc_host *host);
-
-#else
-static inline void mmc_host_clk_hold(struct mmc_host *host)
-{
-}
-
-static inline void mmc_host_clk_release(struct mmc_host *host)
-{
-}
-
-static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
-{
- return host->ios.clock;
-}
-#endif
-
void mmc_host_deeper_disable(struct work_struct *work);
#endif
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 8175d9b..71518f6 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -649,8 +649,11 @@
goto out;
/* SPI mode doesn't define CMD19 */
- if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
+ if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
+ mmc_host_clk_hold(card->host);
err = card->host->ops->execute_tuning(card->host);
+ mmc_host_clk_release(card->host);
+ }
out:
kfree(status);
@@ -860,8 +863,11 @@
if (!reinit) {
int ro = -1;
- if (host->ops->get_ro)
+ if (host->ops->get_ro) {
+ mmc_host_clk_hold(host);
ro = host->ops->get_ro(host);
+ mmc_host_clk_release(host);
+ }
if (ro < 0) {
printk(KERN_WARNING "%s: host does not "
@@ -979,8 +985,11 @@
* Since initialization is now complete, enable preset
* value registers for UHS-I cards.
*/
- if (host->ops->enable_preset_value)
+ if (host->ops->enable_preset_value) {
+ mmc_host_clk_hold(host);
host->ops->enable_preset_value(host, true);
+ mmc_host_clk_release(host);
+ }
} else {
/*
* Attempt to change to high-speed (if supported)
@@ -1195,8 +1204,11 @@
return err;
/* Disable preset value enable if already set since last time */
- if (host->ops->enable_preset_value)
+ if (host->ops->enable_preset_value) {
+ mmc_host_clk_hold(host);
host->ops->enable_preset_value(host, false);
+ mmc_host_clk_release(host);
+ }
err = mmc_send_app_op_cond(host, 0, &ocr);
if (err)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 2024824..3237742 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -397,8 +397,11 @@
/*
* Call the optional HC's init_card function to handle quirks.
*/
- if (host->ops->init_card)
+ if (host->ops->init_card) {
+ mmc_host_clk_hold(host);
host->ops->init_card(host, card);
+ mmc_host_clk_release(host);
+ }
/*
* For native busses: set card RCA and quit open drain mode.
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 03ead02..8b250c12 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -145,15 +145,21 @@
}
set_current_state(TASK_INTERRUPTIBLE);
- if (host->caps & MMC_CAP_SDIO_IRQ)
+ if (host->caps & MMC_CAP_SDIO_IRQ) {
+ mmc_host_clk_hold(host);
host->ops->enable_sdio_irq(host, 1);
+ mmc_host_clk_release(host);
+ }
if (!kthread_should_stop())
schedule_timeout(period);
set_current_state(TASK_RUNNING);
} while (!kthread_should_stop());
- if (host->caps & MMC_CAP_SDIO_IRQ)
+ if (host->caps & MMC_CAP_SDIO_IRQ) {
+ mmc_host_clk_hold(host);
host->ops->enable_sdio_irq(host, 0);
+ mmc_host_clk_release(host);
+ }
pr_debug("%s: IRQ thread exiting with code %d\n",
mmc_hostname(host), ret);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index b46bee6..eeca25a 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2501,8 +2501,38 @@
return rc;
}
#else
-#define msmsdcc_enable NULL
-#define msmsdcc_disable NULL
+static int msmsdcc_enable(struct mmc_host *mmc)
+{
+ struct msmsdcc_host *host = mmc_priv(mmc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ if (!host->clks_on) {
+ msmsdcc_setup_clocks(host, true);
+ host->clks_on = 1;
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return 0;
+}
+
+static int msmsdcc_disable(struct mmc_host *mmc, int lazy)
+{
+ struct msmsdcc_host *host = mmc_priv(mmc);
+ unsigned long flags;
+
+ if (mmc->card && mmc_card_sdio(mmc->card))
+ return -ENOTSUPP;
+
+ spin_lock_irqsave(&host->lock, flags);
+ if (host->clks_on) {
+ msmsdcc_setup_clocks(host, false);
+ host->clks_on = 0;
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return 0;
+}
#endif
static int msmsdcc_start_signal_voltage_switch(struct mmc_host *mmc,
@@ -4102,6 +4132,9 @@
pm_runtime_enable(&(pdev)->dev);
}
#endif
+#ifndef CONFIG_PM_RUNTIME
+ mmc_set_disable_delay(mmc, MSM_MMC_DISABLE_TIMEOUT);
+#endif
setup_timer(&host->req_tout_timer, msmsdcc_req_tout_timer_hdlr,
(unsigned long)host);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ca3eed8..a8332e51 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -216,6 +216,7 @@
* bad cards/controller to respond.
*/
#define MSM_MMC_REQ_TIMEOUT 10000 /* msecs */
+#define MSM_MMC_DISABLE_TIMEOUT 200 /* msecs */
/*
* Controller HW limitations
diff --git a/drivers/net/wireless/wcnss/wcnss_riva.c b/drivers/net/wireless/wcnss/wcnss_riva.c
index 9f69f12..b0eac55 100644
--- a/drivers/net/wireless/wcnss/wcnss_riva.c
+++ b/drivers/net/wireless/wcnss/wcnss_riva.c
@@ -18,10 +18,10 @@
#include <linux/regulator/consumer.h>
#include <linux/mfd/pm8xxx/pm8921.h>
#include <linux/mfd/pm8xxx/gpio.h>
+#include <linux/wcnss_wlan.h>
#include <mach/msm_xo.h>
#include <mach/msm_iomap.h>
-#include "wcnss_riva.h"
static void __iomem *msm_riva_base;
static struct msm_xo_voter *wlan_clock;
diff --git a/drivers/net/wireless/wcnss/wcnss_riva.h b/drivers/net/wireless/wcnss/wcnss_riva.h
deleted file mode 100644
index e037f58..0000000
--- a/drivers/net/wireless/wcnss/wcnss_riva.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2011, 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 _WCNSS_RIVA_H_
-#define _WCNSS_RIVA_H_
-
-#include <linux/device.h>
-
-enum wcnss_opcode {
- WCNSS_WLAN_SWITCH_OFF = 0,
- WCNSS_WLAN_SWITCH_ON,
-};
-
-struct wcnss_wlan_config {
- int use_48mhz_xo;
-};
-
-int wcnss_wlan_power(struct device *dev,
- struct wcnss_wlan_config *cfg,
- enum wcnss_opcode opcode);
-
-#endif /* _WCNSS_RIVA_H_ */
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 7453068..7217434 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -22,7 +22,6 @@
#include <linux/jiffies.h>
#include <linux/gpio.h>
#include <mach/peripheral-loader.h>
-#include "wcnss_riva.h"
#define DEVICE "wcnss_wlan"
#define VERSION "1.01"
@@ -128,6 +127,22 @@
}
EXPORT_SYMBOL(wcnss_wlan_get_device);
+struct platform_device *wcnss_get_platform_device(void)
+{
+ if (penv && penv->pdev)
+ return penv->pdev;
+ return NULL;
+}
+EXPORT_SYMBOL(wcnss_get_platform_device);
+
+struct wcnss_wlan_config *wcnss_get_wlan_config(void)
+{
+ if (penv && penv->pdev)
+ return &penv->wlan_config;
+ return NULL;
+}
+EXPORT_SYMBOL(wcnss_get_wlan_config);
+
struct resource *wcnss_wlan_get_memory_map(struct device *dev)
{
if (penv && dev && (dev == &penv->pdev->dev) && penv->smd_channel_ready)
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 6b05643..e908799 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -2783,6 +2783,8 @@
enable_irq_wake(chip->pmic_chg_irq[USBIN_VALID_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[USBIN_OV_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[USBIN_UV_IRQ]);
+ enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
+ enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
/*
* if both the cool_temp and warm_temp are zero the device doesnt
* care for jeita compliance
diff --git a/drivers/regulator/pmic8901-regulator.c b/drivers/regulator/pmic8901-regulator.c
index 5b4b907..6fd0a05 100644
--- a/drivers/regulator/pmic8901-regulator.c
+++ b/drivers/regulator/pmic8901-regulator.c
@@ -16,14 +16,13 @@
#include <linux/init.h>
#include <linux/mfd/pmic8901.h>
#include <linux/regulator/driver.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/regulator/pmic8901-regulator.h>
-#include <mach/mpp.h>
/* Regulator types */
#define REGULATOR_TYPE_LDO 0
#define REGULATOR_TYPE_SMPS 1
#define REGULATOR_TYPE_VS 2
-#define REGULATOR_TYPE_MPP 3
/* Bank select/write macros */
#define REGULATOR_BANK_SEL(n) ((n) << 4)
@@ -140,9 +139,9 @@
#define VS_PULL_DOWN_ENABLE 0x20
struct pm8901_vreg {
+ struct device *dev;
struct pm8901_vreg_pdata *pdata;
struct regulator_dev *rdev;
- struct pm8901_chip *chip;
int hpm_min_load;
unsigned pc_vote;
unsigned optimum;
@@ -159,7 +158,6 @@
u8 pfm_ctrl_reg;
u8 pwr_cnfg_reg;
u8 is_nmos;
- u8 mpp_id;
u8 state;
};
@@ -167,8 +165,8 @@
* These are used to compensate for the PMIC 8901 v1 FTS regulators which
* output ~10% higher than the programmed set point.
*/
-#define IS_PMIC_8901_V1(rev) ((rev) == PM_8901_REV_1p0 || \
- (rev) == PM_8901_REV_1p1)
+#define IS_PMIC_8901_V1(rev) ((rev) == PM8XXX_REVISION_8901_1p0 || \
+ (rev) == PM8XXX_REVISION_8901_1p1)
#define PMIC_8901_V1_SCALE(uV) ((((uV) - 62100) * 23) / 25)
@@ -207,12 +205,6 @@
.type = REGULATOR_TYPE_VS, \
}
-#define MPP(_id, _mpp_id) \
- [_id] = { \
- .mpp_id = _mpp_id, \
- .type = REGULATOR_TYPE_MPP, \
- }
-
static struct pm8901_vreg pm8901_vreg[] = {
/* id ctrl pmr tst n/p */
LDO(PM8901_VREG_ID_L0, 0x02F, 0x0AB, 0x030, 1),
@@ -230,9 +222,6 @@
SMPS(PM8901_VREG_ID_S3, 0x088, 0x0A9, 0x089, 0x0F6),
SMPS(PM8901_VREG_ID_S4, 0x097, 0x0AA, 0x098, 0x0FB),
- /* id MPP ID */
- MPP(PM8901_VREG_ID_MPP0, 0),
-
/* id ctrl pmr */
VS(PM8901_VREG_ID_LVS0, 0x046, 0x0B2),
VS(PM8901_VREG_ID_LVS1, 0x048, 0x0B3),
@@ -246,7 +235,7 @@
static void print_write_error(struct pm8901_vreg *vreg, int rc,
const char *func);
-static int pm8901_vreg_write(struct pm8901_chip *chip,
+static int pm8901_vreg_write(struct pm8901_vreg *vreg,
u16 addr, u8 val, u8 mask, u8 *reg_save)
{
int rc = 0;
@@ -254,7 +243,7 @@
reg = (*reg_save & ~mask) | (val & mask);
if (reg != *reg_save)
- rc = pm8901_write(chip, addr, ®, 1);
+ rc = pm8xxx_writeb(vreg->dev->parent, addr, reg);
if (!rc)
*reg_save = reg;
return rc;
@@ -283,7 +272,6 @@
static int pm8901_vreg_enable(struct regulator_dev *dev)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
u8 val = VREG_PMR_STATE_HPM;
int rc;
@@ -298,7 +286,7 @@
pm8901_vreg_select_pin_ctrl(vreg, &val);
- rc = pm8901_vreg_write(chip, vreg->pmr_addr,
+ rc = pm8901_vreg_write(vreg, vreg->pmr_addr,
val,
VREG_PMR_STATE_MASK | VREG_PMR_PIN_CTRL_ALL_MASK,
&vreg->pmr_reg);
@@ -311,10 +299,9 @@
static int pm8901_vreg_disable(struct regulator_dev *dev)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
int rc;
- rc = pm8901_vreg_write(chip, vreg->pmr_addr,
+ rc = pm8901_vreg_write(vreg, vreg->pmr_addr,
VREG_PMR_STATE_OFF | VREG_PMR_PIN_CTRL_ALL_MASKED,
VREG_PMR_STATE_MASK | VREG_PMR_PIN_CTRL_ALL_MASK,
&vreg->pmr_reg);
@@ -359,11 +346,10 @@
static int pm8901_ldo_disable(struct regulator_dev *dev)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
int rc;
/* Disassert local enable bit in CTRL register. */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr, 0, LDO_LOCAL_ENABLE_MASK,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, 0, LDO_LOCAL_ENABLE_MASK,
&vreg->ctrl_reg);
if (rc)
print_write_error(vreg, rc, __func__);
@@ -374,8 +360,7 @@
return rc;
}
-static int pm8901_pldo_set_voltage(struct pm8901_chip *chip,
- struct pm8901_vreg *vreg, int uV)
+static int pm8901_pldo_set_voltage(struct pm8901_vreg *vreg, int uV)
{
int vmin, rc = 0;
unsigned vprog, fine_step;
@@ -414,7 +399,7 @@
|| ((range_sel ^ vreg->test_reg[2]) & LDO_TEST_RANGE_SEL_MASK)
|| ((fine_step_reg ^ vreg->test_reg[2])
& LDO_TEST_FINE_STEP_MASK))) {
- rc = pm8901_vreg_write(chip, vreg->test_addr,
+ rc = pm8901_vreg_write(vreg, vreg->test_addr,
REGULATOR_BANK_SEL(2) | REGULATOR_BANK_WRITE,
REGULATOR_BANK_MASK | LDO_TEST_VPROG_UPDATE_MASK,
&vreg->test_reg[2]);
@@ -423,13 +408,13 @@
}
/* Write new voltage. */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr, vprog,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, vprog,
LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
if (rc)
goto bail;
/* Write range extension. */
- rc = pm8901_vreg_write(chip, vreg->test_addr,
+ rc = pm8901_vreg_write(vreg, vreg->test_addr,
range_ext | REGULATOR_BANK_SEL(4)
| REGULATOR_BANK_WRITE,
LDO_TEST_RANGE_EXT_MASK | REGULATOR_BANK_MASK,
@@ -438,7 +423,7 @@
goto bail;
/* Write fine step, range select and program voltage update. */
- rc = pm8901_vreg_write(chip, vreg->test_addr,
+ rc = pm8901_vreg_write(vreg, vreg->test_addr,
fine_step_reg | range_sel | REGULATOR_BANK_SEL(2)
| REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
LDO_TEST_FINE_STEP_MASK | LDO_TEST_RANGE_SEL_MASK
@@ -451,8 +436,7 @@
return rc;
}
-static int pm8901_nldo_set_voltage(struct pm8901_chip *chip,
- struct pm8901_vreg *vreg, int uV)
+static int pm8901_nldo_set_voltage(struct pm8901_vreg *vreg, int uV)
{
unsigned vprog, fine_step_reg;
int rc;
@@ -465,13 +449,13 @@
vprog >>= 1;
/* Write new voltage. */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr, vprog,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, vprog,
LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
if (rc)
print_write_error(vreg, rc, __func__);
/* Write fine step. */
- rc = pm8901_vreg_write(chip, vreg->test_addr,
+ rc = pm8901_vreg_write(vreg, vreg->test_addr,
fine_step_reg | REGULATOR_BANK_SEL(2)
| REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
LDO_TEST_FINE_STEP_MASK | REGULATOR_BANK_MASK
@@ -487,12 +471,11 @@
int min_uV, int max_uV, unsigned *selector)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
if (vreg->is_nmos)
- return pm8901_nldo_set_voltage(chip, vreg, min_uV);
+ return pm8901_nldo_set_voltage(vreg, min_uV);
else
- return pm8901_pldo_set_voltage(chip, vreg, min_uV);
+ return pm8901_pldo_set_voltage(vreg, min_uV);
}
static int pm8901_pldo_get_voltage(struct pm8901_vreg *vreg)
@@ -560,7 +543,6 @@
static int pm8901_vreg_set_mode(struct regulator_dev *dev, unsigned int mode)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
unsigned optimum = vreg->optimum;
unsigned pc_vote = vreg->pc_vote;
unsigned mode_initialized = vreg->mode_initialized;
@@ -614,7 +596,7 @@
/* Only apply mode setting to hardware if currently enabled. */
if (pm8901_vreg_is_enabled(dev))
- rc = pm8901_vreg_write(chip, vreg->pmr_addr, val,
+ rc = pm8901_vreg_write(vreg, vreg->pmr_addr, val,
VREG_PMR_STATE_MASK | VREG_PMR_PIN_CTRL_ALL_MASK,
&vreg->pmr_reg);
@@ -678,11 +660,10 @@
int min_uV, int max_uV, unsigned *selector)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
int rc;
u8 val, band;
- if (IS_PMIC_8901_V1(pm8901_rev(chip)))
+ if (IS_PMIC_8901_V1(pm8xxx_get_revision(vreg->dev->parent)))
min_uV = PMIC_8901_V1_SCALE(min_uV);
if (min_uV < SMPS_BAND_1_UV_MIN || min_uV > SMPS_BAND_3_UV_MAX)
@@ -707,13 +688,13 @@
band = SMPS_VCTRL_BAND_3;
}
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr, band | val,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, band | val,
SMPS_VCTRL_BAND_MASK | SMPS_VCTRL_VPROG_MASK,
&vreg->ctrl_reg);
if (rc)
goto bail;
- rc = pm8901_vreg_write(chip, vreg->pfm_ctrl_addr, band | val,
+ rc = pm8901_vreg_write(vreg, vreg->pfm_ctrl_addr, band | val,
SMPS_VCTRL_BAND_MASK | SMPS_VCTRL_VPROG_MASK,
&vreg->pfm_ctrl_reg);
bail:
@@ -726,7 +707,6 @@
static int pm8901_smps_get_voltage(struct regulator_dev *dev)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
u8 vprog, band;
int ret = 0;
@@ -745,7 +725,7 @@
else
ret = vprog * SMPS_BAND_3_UV_STEP + SMPS_BAND_3_UV_MIN;
- if (IS_PMIC_8901_V1(pm8901_rev(chip)))
+ if (IS_PMIC_8901_V1(pm8xxx_get_revision(vreg->dev->parent)))
ret = PMIC_8901_V1_SCALE_INV(ret);
return ret;
@@ -754,14 +734,13 @@
static int pm8901_vs_enable(struct regulator_dev *dev)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
int rc;
/* Assert enable bit in PMR register. */
rc = pm8901_vreg_enable(dev);
/* Make sure that switch is controlled via PMR register */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr, VS_CTRL_USE_PMR,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, VS_CTRL_USE_PMR,
VS_CTRL_ENABLE_MASK, &vreg->ctrl_reg);
if (rc)
print_write_error(vreg, rc, __func__);
@@ -772,14 +751,13 @@
static int pm8901_vs_disable(struct regulator_dev *dev)
{
struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8901_chip *chip = vreg->chip;
int rc;
/* Disassert enable bit in PMR register. */
rc = pm8901_vreg_disable(dev);
/* Make sure that switch is controlled via PMR register */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr, VS_CTRL_USE_PMR,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, VS_CTRL_USE_PMR,
VS_CTRL_ENABLE_MASK, &vreg->ctrl_reg);
if (rc)
print_write_error(vreg, rc, __func__);
@@ -787,52 +765,6 @@
return rc;
}
-static int pm8901_mpp_enable(struct regulator_dev *dev)
-{
- struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- int out_val;
- int rc;
-
- out_val = (vreg->pdata->active_high
- ? PM_MPP_DOUT_CTL_HIGH : PM_MPP_DOUT_CTL_LOW);
-
- rc = pm8901_mpp_config(vreg->mpp_id, PM_MPP_TYPE_D_OUTPUT,
- PM8901_MPP_DIG_LEVEL_VPH, out_val);
-
- if (rc)
- pr_err("%s: pm8901_mpp_config failed, rc=%d\n", __func__, rc);
- else
- vreg->state = 1;
-
- return rc;
-}
-
-static int pm8901_mpp_disable(struct regulator_dev *dev)
-{
- struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- int out_val;
- int rc;
-
- out_val = (vreg->pdata->active_high
- ? PM_MPP_DOUT_CTL_LOW : PM_MPP_DOUT_CTL_HIGH);
-
- rc = pm8901_mpp_config(vreg->mpp_id, PM_MPP_TYPE_D_OUTPUT,
- PM8901_MPP_DIG_LEVEL_VPH, out_val);
-
- if (rc)
- pr_err("%s: pm8901_mpp_config failed, rc=%d\n", __func__, rc);
- else
- vreg->state = 0;
-
- return rc;
-}
-
-static int pm8901_mpp_is_enabled(struct regulator_dev *dev)
-{
- struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
- return vreg->state;
-}
-
static struct regulator_ops pm8901_ldo_ops = {
.enable = pm8901_vreg_enable,
.disable = pm8901_ldo_disable,
@@ -863,12 +795,6 @@
.get_mode = pm8901_vreg_get_mode,
};
-static struct regulator_ops pm8901_mpp_ops = {
- .enable = pm8901_mpp_enable,
- .disable = pm8901_mpp_disable,
- .is_enabled = pm8901_mpp_is_enabled,
-};
-
#define VREG_DESCRIP(_id, _name, _ops) \
[_id] = { \
.name = _name, \
@@ -893,8 +819,6 @@
VREG_DESCRIP(PM8901_VREG_ID_S3, "8901_s3", &pm8901_smps_ops),
VREG_DESCRIP(PM8901_VREG_ID_S4, "8901_s4", &pm8901_smps_ops),
- VREG_DESCRIP(PM8901_VREG_ID_MPP0, "8901_mpp0", &pm8901_mpp_ops),
-
VREG_DESCRIP(PM8901_VREG_ID_LVS0, "8901_lvs0", &pm8901_vs_ops),
VREG_DESCRIP(PM8901_VREG_ID_LVS1, "8901_lvs1", &pm8901_vs_ops),
VREG_DESCRIP(PM8901_VREG_ID_LVS2, "8901_lvs2", &pm8901_vs_ops),
@@ -904,7 +828,7 @@
VREG_DESCRIP(PM8901_VREG_ID_HDMI_MVS, "8901_hdmi_mvs", &pm8901_vs_ops),
};
-static int pm8901_init_ldo(struct pm8901_chip *chip, struct pm8901_vreg *vreg)
+static int pm8901_init_ldo(struct pm8901_vreg *vreg)
{
int rc = 0, i;
u8 bank;
@@ -912,11 +836,12 @@
/* Store current regulator register values. */
for (i = 0; i < LDO_TEST_BANKS; i++) {
bank = REGULATOR_BANK_SEL(i);
- rc = pm8901_write(chip, vreg->test_addr, &bank, 1);
+ rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
if (rc)
goto bail;
- rc = pm8901_read(chip, vreg->test_addr, &vreg->test_reg[i], 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+ &vreg->test_reg[i]);
if (rc)
goto bail;
@@ -924,30 +849,30 @@
}
/* Set pull down enable based on platform data. */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr,
(vreg->pdata->pull_down_enable ? LDO_PULL_DOWN_ENABLE : 0),
LDO_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
bail:
return rc;
}
-static int pm8901_init_smps(struct pm8901_chip *chip, struct pm8901_vreg *vreg)
+static int pm8901_init_smps(struct pm8901_vreg *vreg)
{
int rc;
/* Store current regulator register values. */
- rc = pm8901_read(chip, vreg->pfm_ctrl_addr,
- &vreg->pfm_ctrl_reg, 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->pfm_ctrl_addr,
+ &vreg->pfm_ctrl_reg);
if (rc)
goto bail;
- rc = pm8901_read(chip, vreg->pwr_cnfg_addr,
- &vreg->pwr_cnfg_reg, 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->pwr_cnfg_addr,
+ &vreg->pwr_cnfg_reg);
if (rc)
goto bail;
/* Set pull down enable based on platform data. */
- rc = pm8901_vreg_write(chip, vreg->pwr_cnfg_addr,
+ rc = pm8901_vreg_write(vreg, vreg->pwr_cnfg_addr,
(vreg->pdata->pull_down_enable ? SMPS_PULL_DOWN_ENABLE : 0),
SMPS_PULL_DOWN_ENABLE_MASK, &vreg->pwr_cnfg_reg);
@@ -955,33 +880,30 @@
return rc;
}
-static int pm8901_init_vs(struct pm8901_chip *chip, struct pm8901_vreg *vreg)
+static int pm8901_init_vs(struct pm8901_vreg *vreg)
{
int rc = 0;
/* Set pull down enable based on platform data. */
- rc = pm8901_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8901_vreg_write(vreg, vreg->ctrl_addr,
(vreg->pdata->pull_down_enable ? VS_PULL_DOWN_ENABLE : 0),
VS_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
return rc;
}
-static int pm8901_init_regulator(struct pm8901_chip *chip,
- struct pm8901_vreg *vreg)
+static int pm8901_init_regulator(struct pm8901_vreg *vreg)
{
int rc;
/* Store current regulator register values. */
- if (vreg->type != REGULATOR_TYPE_MPP) {
- rc = pm8901_read(chip, vreg->ctrl_addr, &vreg->ctrl_reg, 1);
- if (rc)
- goto bail;
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->ctrl_addr, &vreg->ctrl_reg);
+ if (rc)
+ goto bail;
- rc = pm8901_read(chip, vreg->pmr_addr, &vreg->pmr_reg, 1);
- if (rc)
- goto bail;
- }
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->pmr_addr, &vreg->pmr_reg);
+ if (rc)
+ goto bail;
/* Set initial mode based on hardware state. */
if ((vreg->pmr_reg & VREG_PMR_STATE_MASK) == VREG_PMR_STATE_LPM)
@@ -992,11 +914,11 @@
vreg->mode_initialized = 0;
if (vreg->type == REGULATOR_TYPE_LDO)
- rc = pm8901_init_ldo(chip, vreg);
+ rc = pm8901_init_ldo(vreg);
else if (vreg->type == REGULATOR_TYPE_SMPS)
- rc = pm8901_init_smps(chip, vreg);
+ rc = pm8901_init_smps(vreg);
else if (vreg->type == REGULATOR_TYPE_VS)
- rc = pm8901_init_vs(chip, vreg);
+ rc = pm8901_init_vs(vreg);
bail:
if (rc)
pr_err("%s: pm8901_read/write failed; initial register states "
@@ -1008,7 +930,6 @@
static int __devinit pm8901_vreg_probe(struct platform_device *pdev)
{
struct regulator_desc *rdesc;
- struct pm8901_chip *chip;
struct pm8901_vreg *vreg;
const char *reg_name = NULL;
int rc = 0;
@@ -1017,14 +938,13 @@
return -EINVAL;
if (pdev->id >= 0 && pdev->id < PM8901_VREG_MAX) {
- chip = dev_get_drvdata(pdev->dev.parent);
rdesc = &pm8901_vreg_descrip[pdev->id];
vreg = &pm8901_vreg[pdev->id];
vreg->pdata = pdev->dev.platform_data;
- vreg->chip = chip;
reg_name = pm8901_vreg_descrip[pdev->id].name;
+ vreg->dev = &pdev->dev;
- rc = pm8901_init_regulator(chip, vreg);
+ rc = pm8901_init_regulator(vreg);
if (rc)
goto bail;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index ec922f1..c55ba6e 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -37,6 +37,7 @@
#include <linux/usb/msm_hsusb_hw.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
+#include <linux/pm_qos_params.h>
#include <mach/clk.h>
#include <mach/msm_xo.h>
@@ -63,6 +64,25 @@
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
+/* Prevent idle power collapse(pc) while operating in peripheral mode */
+static void otg_pm_qos_update_latency(struct msm_otg *dev, int vote)
+{
+ struct msm_otg_platform_data *pdata = dev->pdata;
+ u32 swfi_latency = 0;
+
+ if (!pdata || !pdata->swfi_latency)
+ return;
+
+ swfi_latency = pdata->swfi_latency + 1;
+
+ if (vote)
+ pm_qos_update_request(&dev->pm_qos_req_dma,
+ swfi_latency);
+ else
+ pm_qos_update_request(&dev->pm_qos_req_dma,
+ PM_QOS_DEFAULT_VALUE);
+}
+
static struct regulator *hsusb_3p3;
static struct regulator *hsusb_1p8;
static struct regulator *hsusb_vddcx;
@@ -991,10 +1011,16 @@
*/
if (pdata->setup_gpio)
pdata->setup_gpio(OTG_STATE_B_PERIPHERAL);
+ /*
+ * vote for minimum dma_latency to prevent idle
+ * power collapse(pc) while running in peripheral mode.
+ */
+ otg_pm_qos_update_latency(motg, 1);
usb_gadget_vbus_connect(otg->gadget);
} else {
dev_dbg(otg->dev, "gadget off\n");
usb_gadget_vbus_disconnect(otg->gadget);
+ otg_pm_qos_update_latency(motg, 0);
if (pdata->setup_gpio)
pdata->setup_gpio(OTG_STATE_UNDEFINED);
}
@@ -2240,6 +2266,10 @@
}
clk_set_rate(motg->clk, 60000000);
+ /* pm qos request to prevent apps idle power collapse */
+ if (motg->pdata->swfi_latency)
+ pm_qos_add_request(&motg->pm_qos_req_dma,
+ PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
/*
* If USB Core is running its protocol engine based on CORE CLK,
* CORE CLK must be running at >55Mhz for correct HSUSB
@@ -2460,6 +2490,8 @@
if (!IS_ERR(motg->phy_reset_clk))
clk_put(motg->phy_reset_clk);
free_motg:
+ if (motg->pdata->swfi_latency)
+ pm_qos_remove_request(&motg->pm_qos_req_dma);
kfree(motg);
return ret;
}
@@ -2535,8 +2567,10 @@
if (!IS_ERR(motg->system_clk))
clk_put(motg->system_clk);
- kfree(motg);
+ if (motg->pdata->swfi_latency)
+ pm_qos_remove_request(&motg->pm_qos_req_dma);
+ kfree(motg);
return 0;
}
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 798cd03..462ede1 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -237,8 +237,10 @@
static boolean mdp_is_hist_start = FALSE;
#endif
static DEFINE_MUTEX(mdp_hist_mutex);
+static boolean mdp_is_hist_data = FALSE;
-int mdp_histogram_ctrl(boolean en)
+/*should hold mdp_hist_mutex before calling this function*/
+int _mdp_histogram_ctrl(boolean en)
{
unsigned long flag;
unsigned long hist_base;
@@ -250,6 +252,9 @@
hist_base = 0x94000;
if (en == TRUE) {
+ if (mdp_is_hist_start)
+ return -EINVAL;
+
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
mdp_hist_frame_cnt = 1;
mdp_enable_irq(MDP_HISTOGRAM_TERM);
@@ -262,7 +267,14 @@
MDP_OUTP(MDP_BASE + hist_base + 0x4, mdp_hist_frame_cnt);
MDP_OUTP(MDP_BASE + hist_base, 1);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ mdp_is_hist_data = TRUE;
} else {
+ if (!mdp_is_hist_start && !mdp_is_hist_data)
+ return -EINVAL;
+
+ mdp_is_hist_data = FALSE;
+ complete(&mdp_hist_comp);
+
if (mdp_rev >= MDP_REV_40) {
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
status = inpdw(MDP_BASE + hist_base + 0x1C);
@@ -280,6 +292,15 @@
return 0;
}
+int mdp_histogram_ctrl(boolean en)
+{
+ int ret = 0;
+ mutex_lock(&mdp_hist_mutex);
+ ret = _mdp_histogram_ctrl(en);
+ mutex_unlock(&mdp_hist_mutex);
+ return ret;
+}
+
int mdp_start_histogram(struct fb_info *info)
{
unsigned long flag;
@@ -292,7 +313,7 @@
goto mdp_hist_start_err;
}
- ret = mdp_histogram_ctrl(TRUE);
+ ret = _mdp_histogram_ctrl(TRUE);
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_is_hist_start = TRUE;
@@ -319,21 +340,21 @@
mdp_is_hist_start = FALSE;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- ret = mdp_histogram_ctrl(FALSE);
+ ret = _mdp_histogram_ctrl(FALSE);
mdp_hist_stop_err:
mutex_unlock(&mdp_hist_mutex);
return ret;
}
-static int mdp_copy_hist_data(struct mdp_histogram *hist)
+/*call from within mdp_hist_mutex*/
+static int _mdp_copy_hist_data(struct mdp_histogram *hist)
{
char *mdp_hist_base;
uint32 r_data_offset = 0x100, g_data_offset = 0x200;
uint32 b_data_offset = 0x300;
int ret = 0;
- mutex_lock(&mdp_hist_mutex);
if (mdp_rev >= MDP_REV_42) {
mdp_hist_base = MDP_BASE + 0x95000;
r_data_offset = 0x400;
@@ -374,7 +395,6 @@
MDP_OUTP(mdp_hist_base, 1);
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
- mutex_unlock(&mdp_hist_mutex);
return 0;
hist_err:
@@ -384,6 +404,8 @@
static int mdp_do_histogram(struct fb_info *info, struct mdp_histogram *hist)
{
+ int ret = 0;
+
if (!hist->frame_cnt || (hist->bin_cnt == 0))
return -EINVAL;
@@ -393,18 +415,29 @@
return -EINVAL;
mutex_lock(&mdp_hist_mutex);
+ if (!mdp_is_hist_data) {
+ ret = -EINVAL;
+ goto error;
+ }
+
if (!mdp_is_hist_start) {
printk(KERN_ERR "%s histogram not started\n", __func__);
- mutex_unlock(&mdp_hist_mutex);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
- mutex_unlock(&mdp_hist_mutex);
INIT_COMPLETION(mdp_hist_comp);
mdp_hist_frame_cnt = hist->frame_cnt;
+ mutex_unlock(&mdp_hist_mutex);
+
wait_for_completion_killable(&mdp_hist_comp);
- return mdp_copy_hist_data(hist);
+ mutex_lock(&mdp_hist_mutex);
+ if (mdp_is_hist_data)
+ ret = _mdp_copy_hist_data(hist);
+error:
+ mutex_unlock(&mdp_hist_mutex);
+ return ret;
}
#endif
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 184da27..65f9b54 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -36,14 +36,9 @@
-#if DEBUG
-#define DBG(x...) printk(KERN_DEBUG x)
-#else
-#define DBG(x...)
-#endif
-
-#define INFO(x...) printk(KERN_INFO x)
-#define ERR(x...) printk(KERN_ERR x)
+#define DBG(x...) pr_debug(x)
+#define INFO(x...) pr_info(x)
+#define ERR(x...) pr_err(x)
#define VID_DEC_NAME "msm_vidc_dec"
@@ -359,49 +354,49 @@
switch (event) {
case VCD_EVT_IND_OUTPUT_RECONFIG:
- INFO("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED"
" to client");
vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_CONFIG_CHANGED;
break;
case VCD_EVT_IND_RESOURCES_LOST:
- INFO("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST"
+ DBG("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST"
" to client");
vdec_msg->vdec_msg_info.msgcode = VDEC_EVT_RESOURCES_LOST;
break;
case VCD_EVT_RESP_FLUSH_INPUT_DONE:
- INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE"
" to client");
vdec_msg->vdec_msg_info.msgcode =
VDEC_MSG_RESP_FLUSH_INPUT_DONE;
break;
case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
- INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE"
" to client");
vdec_msg->vdec_msg_info.msgcode =
VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
break;
case VCD_EVT_IND_HWERRFATAL:
- INFO("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR"
" to client");
vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_HW_ERROR;
break;
case VCD_EVT_RESP_START:
- INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE"
" to client");
vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_START_DONE;
break;
case VCD_EVT_RESP_STOP:
- INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE"
" to client");
vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_STOP_DONE;
break;
case VCD_EVT_RESP_PAUSE:
- INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE"
" to client");
vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_PAUSE_DONE;
break;
case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
- INFO("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED"
+ DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED"
" to client");
vdec_msg->vdec_msg_info.msgcode =
VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
@@ -1027,11 +1022,11 @@
}
if (pause) {
- INFO("msm_vidc_dec: PAUSE command from client = %p\n",
+ DBG("msm_vidc_dec: PAUSE command from client = %p\n",
client_ctx);
vcd_status = vcd_pause(client_ctx->vcd_handle);
} else{
- INFO("msm_vidc_dec: RESUME command from client = %p\n",
+ DBG("msm_vidc_dec: RESUME command from client = %p\n",
client_ctx);
vcd_status = vcd_resume(client_ctx->vcd_handle);
}
@@ -1048,7 +1043,7 @@
struct vid_dec_msg *vdec_msg = NULL;
u32 vcd_status;
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
if (!client_ctx) {
ERR("\n Invalid client_ctx");
return false;
@@ -1056,7 +1051,7 @@
if (start) {
if (client_ctx->seq_header_set) {
- INFO("%s(): Seq Hdr set: Send START_DONE to client",
+ DBG("%s(): Seq Hdr set: Send START_DONE to client",
__func__);
vdec_msg = kzalloc(sizeof(*vdec_msg), GFP_KERNEL);
if (!vdec_msg) {
@@ -1078,7 +1073,7 @@
client_ctx);
} else {
- INFO("%s(): Calling decode_start()", __func__);
+ DBG("%s(): Calling decode_start()", __func__);
vcd_status =
vcd_decode_start(client_ctx->vcd_handle, NULL);
@@ -1089,7 +1084,7 @@
}
}
} else {
- INFO("%s(): Calling vcd_stop()", __func__);
+ DBG("%s(): Calling vcd_stop()", __func__);
mutex_lock(&vid_dec_device_p->lock);
vcd_status = VCD_ERR_FAIL;
if (!client_ctx->stop_called) {
@@ -1207,7 +1202,7 @@
{
u32 vcd_status = VCD_ERR_FAIL;
- INFO("msm_vidc_dec: %s() called with dir = %u", __func__,
+ DBG("msm_vidc_dec: %s() called with dir = %u", __func__,
flush_dir);
if (!client_ctx) {
ERR("\n Invalid client_ctx");
@@ -1802,7 +1797,7 @@
struct vid_dec_msg *vdec_msg;
u32 vcd_status;
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
if (!client_ctx || (!client_ctx->vcd_handle)) {
ERR("\n Invalid client_ctx");
return false;
@@ -1849,7 +1844,7 @@
u32 vcd_status = VCD_ERR_FAIL;
u8 client_count = 0;
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
mutex_lock(&vid_dec_device_p->lock);
client_count = vcd_get_num_of_clients();
@@ -1912,13 +1907,13 @@
{
struct video_client_ctx *client_ctx = file->private_data;
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
vid_dec_close_client(client_ctx);
vidc_release_firmware();
#ifndef USE_RES_TRACKER
vidc_disable_clk();
#endif
- INFO("msm_vidc_dec: Return from %s()", __func__);
+ DBG("msm_vidc_dec: Return from %s()", __func__);
return 0;
}
@@ -1953,7 +1948,7 @@
u32 i;
/* init_timer(&hw_timer); */
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
vid_dec_device_p->num_clients = 0;
for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
@@ -1995,7 +1990,7 @@
int rc = 0;
struct device *class_devp;
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
vid_dec_device_p = kzalloc(sizeof(struct vid_dec_dev), GFP_KERNEL);
if (!vid_dec_device_p) {
ERR("%s Unable to allocate memory for vid_dec_dev\n",
@@ -2056,13 +2051,13 @@
static void __exit vid_dec_exit(void)
{
- INFO("msm_vidc_dec: Inside %s()", __func__);
+ DBG("msm_vidc_dec: Inside %s()", __func__);
cdev_del(&(vid_dec_device_p->cdev));
device_destroy(vid_dec_class, vid_dec_dev_num);
class_destroy(vid_dec_class);
unregister_chrdev_region(vid_dec_dev_num, 1);
kfree(vid_dec_device_p);
- INFO("msm_vidc_dec: Return from %s()", __func__);
+ DBG("msm_vidc_dec: Return from %s()", __func__);
}
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h
index 9a46128..5ed615b 100644
--- a/include/linux/mfd/pm8xxx/core.h
+++ b/include/linux/mfd/pm8xxx/core.h
@@ -27,6 +27,7 @@
PM8XXX_VERSION_8821,
PM8XXX_VERSION_8018,
PM8XXX_VERSION_8922,
+ PM8XXX_VERSION_8038,
};
/* PMIC version specific silicon revisions */
@@ -62,6 +63,11 @@
#define PM8XXX_REVISION_8922_1p1 2
#define PM8XXX_REVISION_8922_2p0 3
+#define PM8XXX_REVISION_8038_TEST 0
+#define PM8XXX_REVISION_8038_1p0 1
+#define PM8XXX_REVISION_8038_2p0 2
+#define PM8XXX_REVISION_8038_2p1 3
+
struct pm8xxx_drvdata {
int (*pmic_readb) (const struct device *dev,
u16 addr, u8 *val);
diff --git a/include/linux/mfd/pm8xxx/gpio.h b/include/linux/mfd/pm8xxx/gpio.h
index f2e4a21..9918620 100644
--- a/include/linux/mfd/pm8xxx/gpio.h
+++ b/include/linux/mfd/pm8xxx/gpio.h
@@ -69,6 +69,15 @@
#define PM8058_GPIO_VIN_L5 6
#define PM8058_GPIO_VIN_L2 7
+/* vin_sel: Voltage Input Select on PM8038*/
+#define PM8038_GPIO_VIN_VPH 0
+#define PM8038_GPIO_VIN_BB 1
+#define PM8038_GPIO_VIN_L11 2
+#define PM8038_GPIO_VIN_L15 3
+#define PM8038_GPIO_VIN_L4 4
+#define PM8038_GPIO_VIN_L3 5
+#define PM8038_GPIO_VIN_L17 6
+
/* out_strength */
#define PM_GPIO_STRENGTH_NO 0
#define PM_GPIO_STRENGTH_HIGH 1
diff --git a/include/linux/mfd/pm8xxx/mpp.h b/include/linux/mfd/pm8xxx/mpp.h
index 7086b98..802948b 100644
--- a/include/linux/mfd/pm8xxx/mpp.h
+++ b/include/linux/mfd/pm8xxx/mpp.h
@@ -180,6 +180,14 @@
#define PM8018_MPP_DIG_LEVEL_L5 5
#define PM8018_MPP_DIG_LEVEL_VPH 7
+/* Digital Input/Output: level [PM8038] */
+#define PM8038_MPP_DIG_LEVEL_L20 0
+#define PM8038_MPP_DIG_LEVEL_L11 1
+#define PM8038_MPP_DIG_LEVEL_L5 2
+#define PM8038_MPP_DIG_LEVEL_L15 3
+#define PM8038_MPP_DIG_LEVEL_L17 4
+#define PM8038_MPP_DIG_LEVEL_VPH 7
+
/* Digital Input: control */
#define PM8XXX_MPP_DIN_TO_INT 0
#define PM8XXX_MPP_DIN_TO_DBUS1 1
diff --git a/include/linux/mfd/pm8xxx/pm8038.h b/include/linux/mfd/pm8xxx/pm8038.h
new file mode 100644
index 0000000..2c2bb09
--- /dev/null
+++ b/include/linux/mfd/pm8xxx/pm8038.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+/*
+ * Qualcomm PMIC 8038 driver header file
+ *
+ */
+
+#ifndef __MFD_PM8038_H
+#define __MFD_PM8038_H
+
+#include <linux/device.h>
+#include <linux/mfd/pm8xxx/irq.h>
+#include <linux/mfd/pm8xxx/gpio.h>
+#include <linux/mfd/pm8xxx/mpp.h>
+#include <linux/mfd/pm8xxx/pwm.h>
+#include <linux/mfd/pm8xxx/rtc.h>
+#include <linux/input/pmic8xxx-pwrkey.h>
+#include <linux/mfd/pm8xxx/misc.h>
+
+#define PM8038_CORE_DEV_NAME "pm8038-core"
+
+#define PM8038_NR_IRQS 256
+#define PM8038_NR_GPIOS 12
+#define PM8038_NR_MPPS 6
+
+#define PM8038_GPIO_BLOCK_START 24
+#define PM8038_MPP_BLOCK_START 16
+
+#define PM8038_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
+
+/* GPIO and MPPs [1,N] */
+#define PM8038_GPIO_IRQ(base, gpio) ((base) + \
+ PM8038_IRQ_BLOCK_BIT(PM8038_GPIO_BLOCK_START, (gpio)-1))
+#define PM8038_MPP_IRQ(base, mpp) ((base) + \
+ PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, (mpp)-1))
+
+/* PMIC Interrupts */
+#define PM8038_RTC_ALARM_IRQ PM8038_IRQ_BLOCK_BIT(4, 7)
+#define PM8038_PWRKEY_REL_IRQ PM8038_IRQ_BLOCK_BIT(6, 2)
+#define PM8038_PWRKEY_PRESS_IRQ PM8038_IRQ_BLOCK_BIT(6, 3)
+#define PM8038_KEYPAD_IRQ PM8038_IRQ_BLOCK_BIT(9, 2)
+#define PM8038_KEYSTUCK_IRQ PM8038_IRQ_BLOCK_BIT(9, 3)
+#define PM8038_USB_ID_IN_IRQ(base) (base + PM8921_IRQ_BLOCK_BIT(6, 1))
+
+#define PM8038_RESOUT_IRQ PM8038_IRQ_BLOCK_BIT(6, 4)
+
+struct pm8038_platform_data {
+ int irq_base;
+ struct pm8xxx_gpio_platform_data *gpio_pdata;
+ struct pm8xxx_irq_platform_data *irq_pdata;
+ struct pm8xxx_mpp_platform_data *mpp_pdata;
+ struct pm8xxx_rtc_platform_data *rtc_pdata;
+ struct pm8xxx_pwrkey_platform_data *pwrkey_pdata;
+ struct pm8xxx_misc_platform_data *misc_pdata;
+};
+
+#endif
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index 5d23edc..932f8da 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -19,51 +19,33 @@
#include <linux/irq.h>
#include <linux/mfd/core.h>
-
-/* PM8901 interrupt numbers */
-
-#define PM8901_MPPS 4
+#include <linux/mfd/pm8xxx/irq.h>
+#include <linux/mfd/pm8xxx/mpp.h>
+#include <linux/mfd/pm8xxx/tm.h>
+#include <linux/regulator/pmic8901-regulator.h>
#define PM8901_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
-/* MPPs [0,N) */
-#define PM8901_MPP_IRQ(base, mpp) ((base) + \
- PM8901_IRQ_BLOCK_BIT(6, (mpp)))
+#define PM8901_NR_IRQS 72
-#define PM8901_TEMP_ALARM_IRQ(base) ((base) + PM8901_IRQ_BLOCK_BIT(6, 4))
-#define PM8901_TEMP_HI_ALARM_IRQ(base) ((base) + PM8901_IRQ_BLOCK_BIT(6, 5))
+/* PM8901 MPP */
+#define PM8901_MPP_BLOCK_START 6
+#define PM8901_MPPS 4
+
+/* PM8901 IRQs */
+#define PM8901_MPP_IRQ(mpp) PM8901_IRQ_BLOCK_BIT(6, (mpp))
+#define PM8901_TEMPSTAT_IRQ PM8901_IRQ_BLOCK_BIT(6, 4)
+#define PM8901_OVERTEMP_IRQ PM8901_IRQ_BLOCK_BIT(6, 5)
struct pm8901_chip;
struct pm8901_platform_data {
- /* This table is only needed for misc interrupts. */
- int irq_base;
- int irq;
-
- int num_subdevs;
- struct mfd_cell *sub_devices;
- int irq_trigger_flags;
+ struct pm8xxx_irq_platform_data *irq_pdata;
+ struct pm8xxx_mpp_platform_data *mpp_pdata;
+ struct pm8901_vreg_pdata *regulator_pdatas;
+ int num_regulators;
};
-struct pm8901_gpio_platform_data {
- int gpio_base;
- int irq_base;
-};
-
-/* chip revision */
-#define PM_8901_REV_1p0 0xF1
-#define PM_8901_REV_1p1 0xF2
-#define PM_8901_REV_2p0 0xF3
-
-int pm8901_read(struct pm8901_chip *pm_chip, u16 addr, u8 *values,
- unsigned int len);
-int pm8901_write(struct pm8901_chip *pm_chip, u16 addr, u8 *values,
- unsigned int len);
-
-int pm8901_rev(struct pm8901_chip *pm_chip);
-
-int pm8901_irq_get_rt_status(struct pm8901_chip *pm_chip, int irq);
-
#ifdef CONFIG_PMIC8901
int pm8901_reset_pwr_off(int reset);
#else
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 461192e..d1f478b 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -430,5 +430,25 @@
{
return host->caps & MMC_CAP_CMD23;
}
+
+#ifdef CONFIG_MMC_CLKGATE
+void mmc_host_clk_hold(struct mmc_host *host);
+void mmc_host_clk_release(struct mmc_host *host);
+unsigned int mmc_host_clk_rate(struct mmc_host *host);
+
+#else
+static inline void mmc_host_clk_hold(struct mmc_host *host)
+{
+}
+
+static inline void mmc_host_clk_release(struct mmc_host *host)
+{
+}
+
+static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
+{
+ return host->ios.clock;
+}
+#endif
#endif
diff --git a/include/linux/regulator/pmic8901-regulator.h b/include/linux/regulator/pmic8901-regulator.h
index 953c4ad..ec842bc 100644
--- a/include/linux/regulator/pmic8901-regulator.h
+++ b/include/linux/regulator/pmic8901-regulator.h
@@ -32,23 +32,20 @@
#define PM8901_VREG_ID_S3 10
#define PM8901_VREG_ID_S4 11
-/* External regulator controlled by MPP pin ids */
-#define PM8901_VREG_ID_MPP0 12
-
/* Low voltage switch regulator ids */
-#define PM8901_VREG_ID_LVS0 13
-#define PM8901_VREG_ID_LVS1 14
-#define PM8901_VREG_ID_LVS2 15
-#define PM8901_VREG_ID_LVS3 16
+#define PM8901_VREG_ID_LVS0 12
+#define PM8901_VREG_ID_LVS1 13
+#define PM8901_VREG_ID_LVS2 14
+#define PM8901_VREG_ID_LVS3 15
/* Medium voltage switch regulator ids */
-#define PM8901_VREG_ID_MVS0 17
+#define PM8901_VREG_ID_MVS0 16
/* USB OTG voltage switch regulator ids */
-#define PM8901_VREG_ID_USB_OTG 18
+#define PM8901_VREG_ID_USB_OTG 17
/* HDMI medium voltage switch regulator ids */
-#define PM8901_VREG_ID_HDMI_MVS 19
+#define PM8901_VREG_ID_HDMI_MVS 18
#define PM8901_VREG_MAX (PM8901_VREG_ID_HDMI_MVS + 1)
@@ -70,10 +67,10 @@
struct pm8901_vreg_pdata {
struct regulator_init_data init_data;
+ int id;
unsigned pull_down_enable;
unsigned pin_ctrl;
enum pm8901_vreg_pin_fn pin_fn;
- unsigned active_high; /* For use with MPP. */
};
#endif
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index a2251fe..68fc67c 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -21,6 +21,7 @@
#include <linux/types.h>
#include <linux/usb/otg.h>
#include <linux/wakelock.h>
+#include <linux/pm_qos_params.h>
/**
* Supported USB modes
@@ -145,6 +146,7 @@
* dfab_usb_hs_clk in case of 8660 and 8960.
* @pmic_id_irq: IRQ number assigned for PMIC USB ID line.
* @mhl_enable: indicates MHL connector or not.
+ * @swfi_latency: miminum latency to allow swfi.
*/
struct msm_otg_platform_data {
int *phy_init_seq;
@@ -158,6 +160,7 @@
const char *pclk_src_name;
int pmic_id_irq;
bool mhl_enable;
+ u32 swfi_latency;
};
/**
@@ -188,6 +191,8 @@
* connected. Useful only when ACA_A charger is
* connected.
* @mA_port: The amount of current drawn by the attached B-device.
+ * @pm_qos_req_dma: miminum DMA latency to vote against idle power
+ collapse when cable is connected.
* @id_timer: The timer used for polling ID line to detect ACA states.
* @xo_handle: TCXO buffer handle
*/
@@ -244,6 +249,7 @@
#define PHY_PWR_COLLAPSED BIT(0)
#define PHY_RETENTIONED BIT(1)
#define PHY_OTG_COMP_DISABLED BIT(2)
+ struct pm_qos_request_list pm_qos_req_dma;
};
struct msm_hsic_host_platform_data {
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 3b37f85..02c0b95 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -16,6 +16,15 @@
#include <linux/device.h>
+enum wcnss_opcode {
+ WCNSS_WLAN_SWITCH_OFF = 0,
+ WCNSS_WLAN_SWITCH_ON,
+};
+
+struct wcnss_wlan_config {
+ int use_48mhz_xo;
+};
+
#define WCNSS_WLAN_IRQ_INVALID -1
struct device *wcnss_wlan_get_device(void);
@@ -26,6 +35,11 @@
const struct dev_pm_ops *pm_ops);
void wcnss_wlan_unregister_pm_ops(struct device *dev,
const struct dev_pm_ops *pm_ops);
+struct platform_device *wcnss_get_platform_device(void);
+struct wcnss_wlan_config *wcnss_get_wlan_config(void);
+int wcnss_wlan_power(struct device *dev,
+ struct wcnss_wlan_config *cfg,
+ enum wcnss_opcode opcode);
#define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
#define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index db8f3f5..a3f3563 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1444,6 +1444,9 @@
*/
tx_skb = skb_clone(skb, GFP_ATOMIC);
+ if (!tx_skb)
+ break;
+
sock_hold(sk);
tx_skb->sk = sk;
tx_skb->destructor = l2cap_skb_destructor;
@@ -5830,6 +5833,11 @@
tx_skb = skb_clone(skb, GFP_ATOMIC);
}
+ if (!tx_skb) {
+ l2cap_seq_list_clear(&pi->retrans_list);
+ break;
+ }
+
/* Update skb contents */
if (pi->extended_control) {
put_unaligned_le32(__pack_extended_control(&control),
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index de6f8e1..1f4b2f8 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2784,6 +2784,13 @@
$herecurr);
}
+# MSM - check if a non board-gpiomux file has any gpiomux declarations
+ if ($realfile =~ /\/mach-msm\/board-[0-9]+/ &&
+ $realfile !~ /camera/ && $realfile !~ /gpiomux/ &&
+ $line =~ /\s*struct msm_gpiomux_config\s*/ ) {
+ WARN("Non gpiomux board file cannot have a gpiomux config declarations. Please declare gpiomux configs in board-*-gpiomux.c file.\n" . $herecurr);
+ }
+
# unbounded string functions are overflow risks
my %str_fns = (
"sprintf" => "snprintf",
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index ba59920..5003ab5 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -3358,7 +3358,7 @@
*/
if (priv->mbhc_micbias_switched)
tabla_codec_switch_micbias(codec, 0);
- priv->hph_status &= ~SND_JACK_HEADSET;
+ priv->hph_status &= ~SND_JACK_HEADPHONE;
if (priv->headset_jack) {
pr_debug("%s: Reporting removal\n", __func__);
snd_soc_jack_report(priv->headset_jack,