Merge "msm: change the pr_err to CDBG to reduce the log output" 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 9f3d72b..bb94d2a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -235,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
@@ -282,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
@@ -308,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/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index be8c31c..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 },
@@ -1080,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;
@@ -1090,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 2492a2e..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,
@@ -1590,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,
@@ -2154,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-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..8c251ba 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -564,6 +564,7 @@
.memtype = MEMTYPE_EBI1,
.enable_ion = 0,
#endif
+ .disable_dmx = 0,
};
struct platform_device msm_device_vidc = {
@@ -1286,7 +1287,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 +1295,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-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 41136d2..2c21f57 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -790,7 +790,8 @@
struct msm_vidc_platform_data vidc_platform_data = {
.memtype = MEMTYPE_EBI0,
- .enable_ion = 0
+ .enable_ion = 0,
+ .disable_dmx = 0
};
struct platform_device msm_device_vidc_720p = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index b9ff604..72fdcf7 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -2129,6 +2129,7 @@
.memtype = MEMTYPE_SMI_KERNEL,
.enable_ion = 0,
#endif
+ .disable_dmx = 0
};
struct platform_device msm_device_vidc = {
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/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 2116ee7..06a389e 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -405,6 +405,7 @@
struct msm_vidc_platform_data {
int memtype;
u32 enable_ion;
+ int disable_dmx;
#ifdef CONFIG_MSM_BUS_SCALING
struct msm_bus_scale_pdata *vidc_bus_client_pdata;
#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/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index 135dd03..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,18 +282,20 @@
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;
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/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/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/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index d8003bf..a541d8b 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1876,7 +1876,7 @@
*ctrlw = maxctrlw1;
}
} else {
- struct slim_ich *slc1;
+ struct slim_ich *slc1 = NULL;
struct slim_ich *slc3 = ctrl->sched.chc3[coeff3];
u32 expshft = SLIM_MAX_CLK_GEAR - clkgear;
int curexp, finalexp, exp1;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index ec922f1..2466246 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);
}
@@ -1824,7 +1850,7 @@
struct msm_otg *motg = the_msm_otg;
/* We depend on PMIC for only VBUS ON interrupt */
- if (!atomic_read(&motg->in_lpm) || !online)
+ if (!atomic_read(&motg->in_lpm) || !online || motg->async_int)
return;
/*
@@ -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/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index a8aa44a..29f178d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -901,6 +901,9 @@
property_value);
vcd_status = VCD_S_SUCCESS;
break;
+ case VCD_I_META_BUFFER_MODE:
+ vcd_status = VCD_S_SUCCESS;
+ break;
default:
DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id);
vcd_status = VCD_ERR_ILLEGAL_OP;
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/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 1435b86..5ee315f 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1540,6 +1540,29 @@
return -EFAULT;
break;
}
+ case VEN_IOCTL_SET_METABUFFER_MODE:
+ {
+ u32 metabuffer_mode, vcd_status;
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_live live_mode;
+
+ if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+ return -EFAULT;
+ if (copy_from_user(&metabuffer_mode, venc_msg.in,
+ sizeof(metabuffer_mode)))
+ return -EFAULT;
+ vcd_property_hdr.prop_id = VCD_I_META_BUFFER_MODE;
+ vcd_property_hdr.sz =
+ sizeof(struct vcd_property_live);
+ live_mode.live = metabuffer_mode;
+ vcd_status = vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &live_mode);
+ if (vcd_status) {
+ pr_err(" Setting metabuffer mode failed");
+ return -EIO;
+ }
+ break;
+ }
case VEN_IOCTL_SET_AC_PREDICTION:
case VEN_IOCTL_GET_AC_PREDICTION:
case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 973ed48..e00e85f 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -90,13 +90,13 @@
return VCD_ERR_ILLEGAL_OP;
}
- if (!cctxt->in_buf_pool.entries ||
+ if ((!cctxt->meta_mode && !cctxt->in_buf_pool.entries) ||
!cctxt->out_buf_pool.entries ||
- cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count ||
+ (!cctxt->meta_mode &&
+ cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count) ||
cctxt->out_buf_pool.validated !=
cctxt->out_buf_pool.count) {
VCD_MSG_ERROR("Buffer pool is not completely setup yet");
-
return VCD_ERR_BAD_STATE;
}
@@ -495,6 +495,13 @@
rc = ddl_set_property(cctxt->ddl_handle, prop_hdr, prop_val);
VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
switch (prop_hdr->prop_id) {
+ case VCD_I_META_BUFFER_MODE:
+ {
+ struct vcd_property_live *live =
+ (struct vcd_property_live *)prop_val;
+ cctxt->meta_mode = live->live;
+ break;
+ }
case VCD_I_LIVE:
{
struct vcd_property_live *live =
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index b424059..64dec2d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -208,6 +208,7 @@
struct ion_client *vcd_ion_client;
u32 vcd_enable_ion;
struct vcd_clnt_ctxt *next;
+ u32 meta_mode;
};
#define VCD_BUFFERPOOL_INUSE_DECREMENT(val) \
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_property.h b/drivers/video/msm/vidc/common/vcd/vcd_property.h
index f51d226..3f7b131 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_property.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_property.h
@@ -47,6 +47,7 @@
#define VCD_I_GET_H264_MV_SIZE (VCD_START_BASE + 0x1F)
#define VCD_I_DEC_PICTYPE (VCD_START_BASE + 0x20)
#define VCD_I_CONT_ON_RECONFIG (VCD_START_BASE + 0x21)
+#define VCD_I_META_BUFFER_MODE (VCD_START_BASE + 0x22)
#define VCD_START_REQ (VCD_START_BASE + 0x1000)
#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1)
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 75e0acf..217030f 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -653,7 +653,7 @@
VCD_FAILED_RETURN(rc, "Invalid buffer type provided");
first_frm_recvd &= cctxt->status.mask;
- if (first_frm_recvd) {
+ if (first_frm_recvd && !cctxt->meta_mode) {
VCD_MSG_ERROR(
"VCD free buffer called when data path is active");
return VCD_ERR_BAD_STATE;
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 150107b..c22f9b0 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -95,6 +95,7 @@
* @flags: flags (see IRQF_* above)
* @name: name of the device
* @dev_id: cookie to identify the device
+ * @percpu_dev_id: cookie to identify the device
* @next: pointer to the next irqaction for shared interrupts
* @irq: interrupt number
* @dir: pointer to the proc/irq/NN/name entry
@@ -104,17 +105,18 @@
* @thread_mask: bitmask for keeping track of @thread activity
*/
struct irqaction {
- irq_handler_t handler;
- unsigned long flags;
- void *dev_id;
- struct irqaction *next;
- int irq;
- irq_handler_t thread_fn;
- struct task_struct *thread;
- unsigned long thread_flags;
- unsigned long thread_mask;
- const char *name;
- struct proc_dir_entry *dir;
+ irq_handler_t handler;
+ unsigned long flags;
+ void *dev_id;
+ void __percpu *percpu_dev_id;
+ struct irqaction *next;
+ int irq;
+ irq_handler_t thread_fn;
+ struct task_struct *thread;
+ unsigned long thread_flags;
+ unsigned long thread_mask;
+ const char *name;
+ struct proc_dir_entry *dir;
} ____cacheline_internodealigned_in_smp;
extern irqreturn_t no_action(int cpl, void *dev_id);
@@ -136,6 +138,10 @@
request_any_context_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev_id);
+extern int __must_check
+request_percpu_irq(unsigned int irq, irq_handler_t handler,
+ const char *devname, void __percpu *percpu_dev_id);
+
extern void exit_irq_thread(void);
#else
@@ -164,10 +170,18 @@
return request_irq(irq, handler, flags, name, dev_id);
}
+static inline int __must_check
+request_percpu_irq(unsigned int irq, irq_handler_t handler,
+ const char *devname, void __percpu *percpu_dev_id)
+{
+ return request_irq(irq, handler, 0, devname, percpu_dev_id);
+}
+
static inline void exit_irq_thread(void) { }
#endif
extern void free_irq(unsigned int, void *);
+extern void free_percpu_irq(unsigned int, void __percpu *);
struct device;
@@ -207,7 +221,9 @@
extern void disable_irq_nosync(unsigned int irq);
extern void disable_irq(unsigned int irq);
+extern void disable_percpu_irq(unsigned int irq);
extern void enable_irq(unsigned int irq);
+extern void enable_percpu_irq(unsigned int irq, unsigned int type);
/* The following three functions are for the core kernel use only. */
#ifdef CONFIG_GENERIC_HARDIRQS
diff --git a/include/linux/irq.h b/include/linux/irq.h
index d03bc09..93c601f 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -23,6 +23,7 @@
#include <linux/errno.h>
#include <linux/topology.h>
#include <linux/wait.h>
+#include <linux/module.h>
#include <asm/irq.h>
#include <asm/ptrace.h>
@@ -65,6 +66,7 @@
* IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
* IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
* IRQ_NESTED_TRHEAD - Interrupt nests into another thread
+ * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
*/
enum {
IRQ_TYPE_NONE = 0x00000000,
@@ -87,12 +89,13 @@
IRQ_MOVE_PCNTXT = (1 << 14),
IRQ_NESTED_THREAD = (1 << 15),
IRQ_NOTHREAD = (1 << 16),
+ IRQ_PER_CPU_DEVID = (1 << 17),
};
#define IRQF_MODIFY_MASK \
(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
- IRQ_PER_CPU | IRQ_NESTED_THREAD)
+ IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID)
#define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
@@ -371,6 +374,8 @@
struct irqaction;
extern int setup_irq(unsigned int irq, struct irqaction *new);
extern void remove_irq(unsigned int irq, struct irqaction *act);
+extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
+extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
extern void irq_cpu_online(void);
extern void irq_cpu_offline(void);
@@ -398,6 +403,7 @@
extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
+extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_nested_irq(unsigned int irq);
@@ -428,6 +434,8 @@
irq_set_chip_and_handler_name(irq, chip, handle, NULL);
}
+extern int irq_set_percpu_devid(unsigned int irq);
+
extern void
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name);
@@ -489,6 +497,13 @@
irq_clear_status_flags(irq, IRQ_NESTED_THREAD);
}
+static inline void irq_set_percpu_devid_flags(unsigned int irq)
+{
+ irq_set_status_flags(irq,
+ IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD |
+ IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
+}
+
/* Handle dynamic irq creation and destruction */
extern unsigned int create_irq_nr(unsigned int irq_want, int node);
extern int create_irq(void);
@@ -556,7 +571,15 @@
return d->msi_desc;
}
-int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node);
+int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
+ struct module *owner);
+
+static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt,
+ int node)
+{
+ return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE);
+}
+
void irq_free_descs(unsigned int irq, unsigned int cnt);
int irq_reserve_irqs(unsigned int from, unsigned int cnt);
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 2d921b3..6b69c2c 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -53,6 +53,7 @@
unsigned long last_unhandled; /* Aging timer for unhandled count */
unsigned int irqs_unhandled;
raw_spinlock_t lock;
+ struct cpumask *percpu_enabled;
#ifdef CONFIG_SMP
const struct cpumask *affinity_hint;
struct irq_affinity_notify *affinity_notify;
@@ -66,6 +67,7 @@
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
+ struct module *owner;
const char *name;
} ____cacheline_internodealigned_in_smp;
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/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 12c7afd..45199cb 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -435,6 +435,9 @@
#define VEN_IOCTL_GET_NUMBER_INSTANCES \
_IOR(VEN_IOCTLBASE_ENC, 46, struct venc_ioctl_msg)
+#define VEN_IOCTL_SET_METABUFFER_MODE \
+ _IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg)
+
struct venc_switch{
unsigned char status;
};
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/kernel/irq/chip.c b/kernel/irq/chip.c
index 2adc6b5..fe1f47a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -26,7 +26,7 @@
int irq_set_chip(unsigned int irq, struct irq_chip *chip)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
if (!desc)
return -EINVAL;
@@ -54,7 +54,7 @@
int irq_set_irq_type(unsigned int irq, unsigned int type)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
int ret = 0;
if (!desc)
@@ -78,7 +78,7 @@
int irq_set_handler_data(unsigned int irq, void *data)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
if (!desc)
return -EINVAL;
@@ -98,7 +98,7 @@
int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
if (!desc)
return -EINVAL;
@@ -119,7 +119,7 @@
int irq_set_chip_data(unsigned int irq, void *data)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
if (!desc)
return -EINVAL;
@@ -204,6 +204,24 @@
}
}
+void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu)
+{
+ if (desc->irq_data.chip->irq_enable)
+ desc->irq_data.chip->irq_enable(&desc->irq_data);
+ else
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ cpumask_set_cpu(cpu, desc->percpu_enabled);
+}
+
+void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
+{
+ if (desc->irq_data.chip->irq_disable)
+ desc->irq_data.chip->irq_disable(&desc->irq_data);
+ else
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+ cpumask_clear_cpu(cpu, desc->percpu_enabled);
+}
+
static inline void mask_ack_irq(struct irq_desc *desc)
{
if (desc->irq_data.chip->irq_mask_ack)
@@ -553,12 +571,44 @@
chip->irq_eoi(&desc->irq_data);
}
+/**
+ * handle_percpu_devid_irq - Per CPU local irq handler with per cpu dev ids
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ *
+ * Per CPU interrupts on SMP machines without locking requirements. Same as
+ * handle_percpu_irq() above but with the following extras:
+ *
+ * action->percpu_dev_id is a pointer to percpu variables which
+ * contain the real device id for the cpu on which this handler is
+ * called
+ */
+void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irqaction *action = desc->action;
+ void *dev_id = __this_cpu_ptr(action->percpu_dev_id);
+ irqreturn_t res;
+
+ kstat_incr_irqs_this_cpu(irq, desc);
+
+ if (chip->irq_ack)
+ chip->irq_ack(&desc->irq_data);
+
+ trace_irq_handler_entry(irq, action);
+ res = action->handler(irq, dev_id);
+ trace_irq_handler_exit(irq, action, res);
+
+ if (chip->irq_eoi)
+ chip->irq_eoi(&desc->irq_data);
+}
+
void
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
if (!desc)
return;
@@ -602,7 +652,7 @@
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
if (!desc)
return;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 6546431..a73dd6c 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -71,6 +71,8 @@
extern void irq_shutdown(struct irq_desc *desc);
extern void irq_enable(struct irq_desc *desc);
extern void irq_disable(struct irq_desc *desc);
+extern void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu);
+extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
extern void mask_irq(struct irq_desc *desc);
extern void unmask_irq(struct irq_desc *desc);
@@ -114,14 +116,21 @@
desc->irq_data.chip->irq_bus_sync_unlock(&desc->irq_data);
}
+#define _IRQ_DESC_CHECK (1 << 0)
+#define _IRQ_DESC_PERCPU (1 << 1)
+
+#define IRQ_GET_DESC_CHECK_GLOBAL (_IRQ_DESC_CHECK)
+#define IRQ_GET_DESC_CHECK_PERCPU (_IRQ_DESC_CHECK | _IRQ_DESC_PERCPU)
+
struct irq_desc *
-__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus);
+__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
+ unsigned int check);
void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus);
static inline struct irq_desc *
-irq_get_desc_buslock(unsigned int irq, unsigned long *flags)
+irq_get_desc_buslock(unsigned int irq, unsigned long *flags, unsigned int check)
{
- return __irq_get_desc_lock(irq, flags, true);
+ return __irq_get_desc_lock(irq, flags, true, check);
}
static inline void
@@ -131,9 +140,9 @@
}
static inline struct irq_desc *
-irq_get_desc_lock(unsigned int irq, unsigned long *flags)
+irq_get_desc_lock(unsigned int irq, unsigned long *flags, unsigned int check)
{
- return __irq_get_desc_lock(irq, flags, false);
+ return __irq_get_desc_lock(irq, flags, false, check);
}
static inline void
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 4c60a50..028e377 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -70,7 +70,8 @@
static inline int desc_node(struct irq_desc *desc) { return 0; }
#endif
-static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
+static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
+ struct module *owner)
{
int cpu;
@@ -86,6 +87,7 @@
desc->irq_count = 0;
desc->irqs_unhandled = 0;
desc->name = NULL;
+ desc->owner = owner;
for_each_possible_cpu(cpu)
*per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
desc_smp_init(desc, node);
@@ -128,7 +130,7 @@
static inline void free_masks(struct irq_desc *desc) { }
#endif
-static struct irq_desc *alloc_desc(int irq, int node)
+static struct irq_desc *alloc_desc(int irq, int node, struct module *owner)
{
struct irq_desc *desc;
gfp_t gfp = GFP_KERNEL;
@@ -147,7 +149,7 @@
raw_spin_lock_init(&desc->lock);
lockdep_set_class(&desc->lock, &irq_desc_lock_class);
- desc_set_defaults(irq, desc, node);
+ desc_set_defaults(irq, desc, node, owner);
return desc;
@@ -173,13 +175,14 @@
kfree(desc);
}
-static int alloc_descs(unsigned int start, unsigned int cnt, int node)
+static int alloc_descs(unsigned int start, unsigned int cnt, int node,
+ struct module *owner)
{
struct irq_desc *desc;
int i;
for (i = 0; i < cnt; i++) {
- desc = alloc_desc(start + i, node);
+ desc = alloc_desc(start + i, node, owner);
if (!desc)
goto err;
mutex_lock(&sparse_irq_lock);
@@ -227,7 +230,7 @@
nr_irqs = initcnt;
for (i = 0; i < initcnt; i++) {
- desc = alloc_desc(i, node);
+ desc = alloc_desc(i, node, NULL);
set_bit(i, allocated_irqs);
irq_insert_desc(i, desc);
}
@@ -261,7 +264,7 @@
alloc_masks(&desc[i], GFP_KERNEL, node);
raw_spin_lock_init(&desc[i].lock);
lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
- desc_set_defaults(i, &desc[i], node);
+ desc_set_defaults(i, &desc[i], node, NULL);
}
return arch_early_irq_init();
}
@@ -276,8 +279,16 @@
dynamic_irq_cleanup(irq);
}
-static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
+static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
+ struct module *owner)
{
+ u32 i;
+
+ for (i = 0; i < cnt; i++) {
+ struct irq_desc *desc = irq_to_desc(start + i);
+
+ desc->owner = owner;
+ }
return start;
}
@@ -337,7 +348,8 @@
* Returns the first irq number or error code
*/
int __ref
-irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
+__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
+ struct module *owner)
{
int start, ret;
@@ -366,13 +378,13 @@
bitmap_set(allocated_irqs, start, cnt);
mutex_unlock(&sparse_irq_lock);
- return alloc_descs(start, cnt, node);
+ return alloc_descs(start, cnt, node, owner);
err:
mutex_unlock(&sparse_irq_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(irq_alloc_descs);
+EXPORT_SYMBOL_GPL(__irq_alloc_descs);
/**
* irq_reserve_irqs - mark irqs allocated
@@ -411,11 +423,22 @@
}
struct irq_desc *
-__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus)
+__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
+ unsigned int check)
{
struct irq_desc *desc = irq_to_desc(irq);
if (desc) {
+ if (check & _IRQ_DESC_CHECK) {
+ if ((check & _IRQ_DESC_PERCPU) &&
+ !irq_settings_is_per_cpu_devid(desc))
+ return NULL;
+
+ if (!(check & _IRQ_DESC_PERCPU) &&
+ irq_settings_is_per_cpu_devid(desc))
+ return NULL;
+ }
+
if (bus)
chip_bus_lock(desc);
raw_spin_lock_irqsave(&desc->lock, *flags);
@@ -430,6 +453,25 @@
chip_bus_sync_unlock(desc);
}
+int irq_set_percpu_devid(unsigned int irq)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ if (!desc)
+ return -EINVAL;
+
+ if (desc->percpu_enabled)
+ return -EINVAL;
+
+ desc->percpu_enabled = kzalloc(sizeof(*desc->percpu_enabled), GFP_KERNEL);
+
+ if (!desc->percpu_enabled)
+ return -ENOMEM;
+
+ irq_set_percpu_devid_flags(irq);
+ return 0;
+}
+
/**
* dynamic_irq_cleanup - cleanup a dynamically allocated irq
* @irq: irq number to initialize
@@ -440,7 +482,7 @@
unsigned long flags;
raw_spin_lock_irqsave(&desc->lock, flags);
- desc_set_defaults(irq, desc, desc_node(desc));
+ desc_set_defaults(irq, desc, desc_node(desc), NULL);
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b495711..1db1dc6 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -195,7 +195,7 @@
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
if (!desc)
return -EINVAL;
@@ -356,7 +356,7 @@
static int __disable_irq_nosync(unsigned int irq)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
if (!desc)
return -EINVAL;
@@ -448,7 +448,7 @@
void enable_irq(unsigned int irq)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
if (!desc)
return;
@@ -488,7 +488,7 @@
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
int ret = 0;
if (!desc)
@@ -555,7 +555,7 @@
int can_request_irq(unsigned int irq, unsigned long irqflags)
{
unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
int canrequest = 0;
if (!desc)
@@ -909,6 +909,8 @@
if (desc->irq_data.chip == &no_irq_chip)
return -ENOSYS;
+ if (!try_module_get(desc->owner))
+ return -ENODEV;
/*
* Some drivers like serial.c use request_irq() heavily,
* so we have to be careful not to interfere with a
@@ -932,8 +934,10 @@
*/
nested = irq_settings_is_nested_thread(desc);
if (nested) {
- if (!new->thread_fn)
- return -EINVAL;
+ if (!new->thread_fn) {
+ ret = -EINVAL;
+ goto out_mput;
+ }
/*
* Replace the primary handler which was provided from
* the driver for non nested interrupt handling by the
@@ -955,8 +959,10 @@
t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
new->name);
- if (IS_ERR(t))
- return PTR_ERR(t);
+ if (IS_ERR(t)) {
+ ret = PTR_ERR(t);
+ goto out_mput;
+ }
/*
* We keep the reference to the task struct even if
* the thread dies to avoid that the interrupt code
@@ -1121,6 +1127,8 @@
kthread_stop(t);
put_task_struct(t);
}
+out_mput:
+ module_put(desc->owner);
return ret;
}
@@ -1136,6 +1144,8 @@
int retval;
struct irq_desc *desc = irq_to_desc(irq);
+ if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
+ return -EINVAL;
chip_bus_lock(desc);
retval = __setup_irq(irq, desc, act);
chip_bus_sync_unlock(desc);
@@ -1144,7 +1154,7 @@
}
EXPORT_SYMBOL_GPL(setup_irq);
- /*
+/*
* Internal function to unregister an irqaction - used to free
* regular and special interrupts that are part of the architecture.
*/
@@ -1236,6 +1246,7 @@
put_task_struct(action->thread);
}
+ module_put(desc->owner);
return action;
}
@@ -1248,7 +1259,10 @@
*/
void remove_irq(unsigned int irq, struct irqaction *act)
{
- __free_irq(irq, act->dev_id);
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ if (desc && !WARN_ON(irq_settings_is_per_cpu_devid(desc)))
+ __free_irq(irq, act->dev_id);
}
EXPORT_SYMBOL_GPL(remove_irq);
@@ -1270,7 +1284,7 @@
{
struct irq_desc *desc = irq_to_desc(irq);
- if (!desc)
+ if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
return;
#ifdef CONFIG_SMP
@@ -1348,7 +1362,8 @@
if (!desc)
return -EINVAL;
- if (!irq_settings_can_request(desc))
+ if (!irq_settings_can_request(desc) ||
+ WARN_ON(irq_settings_is_per_cpu_devid(desc)))
return -EINVAL;
if (!handler) {
@@ -1446,3 +1461,194 @@
}
}
EXPORT_SYMBOL_GPL(irq_set_pending);
+
+void enable_percpu_irq(unsigned int irq, unsigned int type)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned long flags;
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
+
+ if (!desc)
+ return;
+
+ type &= IRQ_TYPE_SENSE_MASK;
+ if (type != IRQ_TYPE_NONE) {
+ int ret;
+
+ ret = __irq_set_trigger(desc, irq, type);
+
+ if (ret) {
+ WARN(1, "failed to set type for IRQ%d\n", irq);
+ goto out;
+ }
+ }
+
+ irq_percpu_enable(desc, cpu);
+out:
+ irq_put_desc_unlock(desc, flags);
+}
+
+void disable_percpu_irq(unsigned int irq)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned long flags;
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
+
+ if (!desc)
+ return;
+
+ irq_percpu_disable(desc, cpu);
+ irq_put_desc_unlock(desc, flags);
+}
+
+/*
+ * Internal function to unregister a percpu irqaction.
+ */
+static struct irqaction *__free_percpu_irq(unsigned int irq, void __percpu *dev_id)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irqaction *action;
+ unsigned long flags;
+
+ WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
+
+ if (!desc)
+ return NULL;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+
+ action = desc->action;
+ if (!action || action->percpu_dev_id != dev_id) {
+ WARN(1, "Trying to free already-free IRQ %d\n", irq);
+ goto bad;
+ }
+
+ if (!cpumask_empty(desc->percpu_enabled)) {
+ WARN(1, "percpu IRQ %d still enabled on CPU%d!\n",
+ irq, cpumask_first(desc->percpu_enabled));
+ goto bad;
+ }
+
+ /* Found it - now remove it from the list of entries: */
+ desc->action = NULL;
+
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+ unregister_handler_proc(irq, action);
+
+ module_put(desc->owner);
+ return action;
+
+bad:
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ return NULL;
+}
+
+/**
+ * remove_percpu_irq - free a per-cpu interrupt
+ * @irq: Interrupt line to free
+ * @act: irqaction for the interrupt
+ *
+ * Used to remove interrupts statically setup by the early boot process.
+ */
+void remove_percpu_irq(unsigned int irq, struct irqaction *act)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ if (desc && irq_settings_is_per_cpu_devid(desc))
+ __free_percpu_irq(irq, act->percpu_dev_id);
+}
+
+/**
+ * free_percpu_irq - free an interrupt allocated with request_percpu_irq
+ * @irq: Interrupt line to free
+ * @dev_id: Device identity to free
+ *
+ * Remove a percpu interrupt handler. The handler is removed, but
+ * the interrupt line is not disabled. This must be done on each
+ * CPU before calling this function. The function does not return
+ * until any executing interrupts for this IRQ have completed.
+ *
+ * This function must not be called from interrupt context.
+ */
+void free_percpu_irq(unsigned int irq, void __percpu *dev_id)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ if (!desc || !irq_settings_is_per_cpu_devid(desc))
+ return;
+
+ chip_bus_lock(desc);
+ kfree(__free_percpu_irq(irq, dev_id));
+ chip_bus_sync_unlock(desc);
+}
+
+/**
+ * setup_percpu_irq - setup a per-cpu interrupt
+ * @irq: Interrupt line to setup
+ * @act: irqaction for the interrupt
+ *
+ * Used to statically setup per-cpu interrupts in the early boot process.
+ */
+int setup_percpu_irq(unsigned int irq, struct irqaction *act)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ int retval;
+
+ if (!desc || !irq_settings_is_per_cpu_devid(desc))
+ return -EINVAL;
+ chip_bus_lock(desc);
+ retval = __setup_irq(irq, desc, act);
+ chip_bus_sync_unlock(desc);
+
+ return retval;
+}
+
+/**
+ * request_percpu_irq - allocate a percpu interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * @devname: An ascii name for the claiming device
+ * @dev_id: A percpu cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources, but doesn't
+ * automatically enable the interrupt. It has to be done on each
+ * CPU using enable_percpu_irq().
+ *
+ * Dev_id must be globally unique. It is a per-cpu variable, and
+ * the handler gets called with the interrupted CPU's instance of
+ * that variable.
+ */
+int request_percpu_irq(unsigned int irq, irq_handler_t handler,
+ const char *devname, void __percpu *dev_id)
+{
+ struct irqaction *action;
+ struct irq_desc *desc;
+ int retval;
+
+ if (!dev_id)
+ return -EINVAL;
+
+ desc = irq_to_desc(irq);
+ if (!desc || !irq_settings_can_request(desc) ||
+ !irq_settings_is_per_cpu_devid(desc))
+ return -EINVAL;
+
+ action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+
+ action->handler = handler;
+ action->flags = IRQF_PERCPU;
+ action->name = devname;
+ action->percpu_dev_id = dev_id;
+
+ chip_bus_lock(desc);
+ retval = __setup_irq(irq, desc, action);
+ chip_bus_sync_unlock(desc);
+
+ if (retval)
+ kfree(action);
+
+ return retval;
+}
diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
index f166783..1162f10 100644
--- a/kernel/irq/settings.h
+++ b/kernel/irq/settings.h
@@ -13,6 +13,7 @@
_IRQ_MOVE_PCNTXT = IRQ_MOVE_PCNTXT,
_IRQ_NO_BALANCING = IRQ_NO_BALANCING,
_IRQ_NESTED_THREAD = IRQ_NESTED_THREAD,
+ _IRQ_PER_CPU_DEVID = IRQ_PER_CPU_DEVID,
_IRQF_MODIFY_MASK = IRQF_MODIFY_MASK,
};
@@ -24,6 +25,7 @@
#define IRQ_NOTHREAD GOT_YOU_MORON
#define IRQ_NOAUTOEN GOT_YOU_MORON
#define IRQ_NESTED_THREAD GOT_YOU_MORON
+#define IRQ_PER_CPU_DEVID GOT_YOU_MORON
#undef IRQF_MODIFY_MASK
#define IRQF_MODIFY_MASK GOT_YOU_MORON
@@ -39,6 +41,11 @@
return desc->status_use_accessors & _IRQ_PER_CPU;
}
+static inline bool irq_settings_is_per_cpu_devid(struct irq_desc *desc)
+{
+ return desc->status_use_accessors & _IRQ_PER_CPU_DEVID;
+}
+
static inline void irq_settings_set_per_cpu(struct irq_desc *desc)
{
desc->status_use_accessors |= _IRQ_PER_CPU;
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 3573169..b254cd8 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -518,9 +518,11 @@
int eq_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->reg;
+ ucontrol->value.integer.value[0] = eq_data[eq_idx].enable;
+
pr_debug("%s: EQ #%d enable %d\n", __func__,
eq_idx, eq_data[eq_idx].enable);
- return eq_data[eq_idx].enable;
+ return 0;
}
static int msm_routing_put_eq_enable_mixer(struct snd_kcontrol *kcontrol,
@@ -545,6 +547,8 @@
int eq_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->reg;
+ ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands;
+
pr_debug("%s: EQ #%d bands %d\n", __func__,
eq_idx, eq_data[eq_idx].num_bands);
return eq_data[eq_idx].num_bands;
@@ -558,7 +562,6 @@
kcontrol->private_value)->reg;
int value = ucontrol->value.integer.value[0];
-
pr_debug("%s: EQ #%d bands %d\n", __func__,
eq_idx, value);
eq_data[eq_idx].num_bands = value;
@@ -573,6 +576,17 @@
int band_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
+ ucontrol->value.integer.value[0] =
+ eq_data[eq_idx].eq_bands[band_idx].band_idx;
+ ucontrol->value.integer.value[1] =
+ eq_data[eq_idx].eq_bands[band_idx].filter_type;
+ ucontrol->value.integer.value[2] =
+ eq_data[eq_idx].eq_bands[band_idx].center_freq_hz;
+ ucontrol->value.integer.value[3] =
+ eq_data[eq_idx].eq_bands[band_idx].filter_gain;
+ ucontrol->value.integer.value[4] =
+ eq_data[eq_idx].eq_bands[band_idx].q_factor;
+
pr_debug("%s: band_idx = %d\n", __func__,
eq_data[eq_idx].eq_bands[band_idx].band_idx);
pr_debug("%s: filter_type = %d\n", __func__,