aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/mdm_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/mdm_device.c')
-rw-r--r--arch/arm/mach-exynos/mdm_device.c184
1 files changed, 170 insertions, 14 deletions
diff --git a/arch/arm/mach-exynos/mdm_device.c b/arch/arm/mach-exynos/mdm_device.c
index 22be1d5..f5af03c 100644
--- a/arch/arm/mach-exynos/mdm_device.c
+++ b/arch/arm/mach-exynos/mdm_device.c
@@ -9,45 +9,181 @@
#include <mach/mdm2.h>
#include "mdm_private.h"
+#include <linux/cpufreq_pegasusq.h>
+#include <mach/cpufreq.h>
+#include <mach/dev.h>
+
static struct resource mdm_resources[] = {
{
- .start = MDM2AP_ERRFATAL,
- .end = MDM2AP_ERRFATAL,
+ .start = GPIO_MDM2AP_ERR_FATAL,
+ .end = GPIO_MDM2AP_ERR_FATAL,
.name = "MDM2AP_ERRFATAL",
.flags = IORESOURCE_IO,
},
{
- .start = AP2MDM_ERRFATAL,
- .end = AP2MDM_ERRFATAL,
+ .start = GPIO_AP2MDM_ERR_FATAL,
+ .end = GPIO_AP2MDM_ERR_FATAL,
.name = "AP2MDM_ERRFATAL",
.flags = IORESOURCE_IO,
},
{
- .start = MDM2AP_STATUS,
- .end = MDM2AP_STATUS,
+ .start = GPIO_MDM2AP_STATUS,
+ .end = GPIO_MDM2AP_STATUS,
.name = "MDM2AP_STATUS",
.flags = IORESOURCE_IO,
},
{
- .start = AP2MDM_STATUS,
- .end = AP2MDM_STATUS,
+ .start = GPIO_AP2MDM_STATUS,
+ .end = GPIO_AP2MDM_STATUS,
.name = "AP2MDM_STATUS",
.flags = IORESOURCE_IO,
},
{
- .start = AP2MDM_PMIC_RESET_N,
- .end = AP2MDM_PMIC_RESET_N,
- .name = "AP2MDM_PMIC_RESET_N",
+ .start = GPIO_AP2MDM_PON_RESET_N,
+ .end = GPIO_AP2MDM_PON_RESET_N,
+ .name = "AP2MDM_SOFT_RESET",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = GPIO_AP2MDM_PMIC_RESET_N,
+ .end = GPIO_AP2MDM_PMIC_RESET_N,
+ .name = "AP2MDM_PMIC_PWR_EN",
.flags = IORESOURCE_IO,
},
+ {
+ .start = GPIO_AP2MDM_WAKEUP,
+ .end = GPIO_AP2MDM_WAKEUP,
+ .name = "AP2MDM_WAKEUP",
+ .flags = IORESOURCE_IO,
+ },
+};
+
+#ifdef CONFIG_MDM_HSIC_PM
+static struct resource mdm_pm_resource[] = {
+ {
+ .start = GPIO_AP2MDM_HSIC_PORT_ACTIVE,
+ .end = GPIO_AP2MDM_HSIC_PORT_ACTIVE,
+ .name = "AP2MDM_HSIC_ACTIVE",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = GPIO_MDM2AP_HSIC_PWR_ACTIVE,
+ .end = GPIO_MDM2AP_HSIC_PWR_ACTIVE,
+ .name = "MDM2AP_DEVICE_PWR_ACTIVE",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = GPIO_MDM2AP_HSIC_RESUME_REQ,
+ .end = GPIO_MDM2AP_HSIC_RESUME_REQ,
+ .name = "MDM2AP_RESUME_REQ",
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static int exynos_frequency_lock(struct device *dev);
+static int exynos_frequency_unlock(struct device *dev);
+
+static struct mdm_hsic_pm_platform_data mdm_hsic_pm_pdata = {
+ .freqlock = ATOMIC_INIT(0),
+ .freq_lock = exynos_frequency_lock,
+ .freq_unlock = exynos_frequency_unlock,
};
+struct platform_device mdm_pm_device = {
+ .name = "mdm_hsic_pm0",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mdm_pm_resource),
+ .resource = mdm_pm_resource,
+};
+#endif
+
static struct mdm_platform_data mdm_platform_data = {
.mdm_version = "3.0",
.ramdump_delay_ms = 2000,
- .peripheral_platform_device = &s5p_device_ehci,
+ .early_power_on = 1,
+ .sfr_query = 0,
+ .vddmin_resource = NULL,
+#ifdef CONFIG_USB_EHCI_S5P
+ .peripheral_platform_device_ehci = &s5p_device_ehci,
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ .peripheral_platform_device_ohci = &s5p_device_ohci,
+#endif
+ .ramdump_timeout_ms = 120000,
};
+static int exynos_frequency_lock(struct device *dev)
+{
+ unsigned int level, cpufreq = 1400; /* 200 ~ 1400 */
+ unsigned int busfreq = 400200; /* 100100 ~ 400200 */
+ int ret = 0;
+ struct device *busdev = dev_get("exynos-busfreq");
+
+ if (atomic_read(&mdm_hsic_pm_pdata.freqlock) == 0) {
+ /* cpu frequency lock */
+ ret = exynos_cpufreq_get_level(cpufreq * 1000, &level);
+ if (ret < 0) {
+ pr_err("ERR: exynos_cpufreq_get_level fail: %d\n",
+ ret);
+ goto exit;
+ }
+
+ ret = exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level);
+ if (ret < 0) {
+ pr_err("ERR: exynos_cpufreq_lock fail: %d\n", ret);
+ goto exit;
+ }
+
+ /* bus frequncy lock */
+ if (!busdev) {
+ pr_err("ERR: busdev is not exist\n");
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ ret = dev_lock(busdev, dev, busfreq);
+ if (ret < 0) {
+ pr_err("ERR: dev_lock error: %d\n", ret);
+ goto exit;
+ }
+
+ /* lock minimum number of cpu cores */
+ cpufreq_pegasusq_min_cpu_lock(2);
+
+ atomic_set(&mdm_hsic_pm_pdata.freqlock, 1);
+ pr_debug("level=%d, cpufreq=%d MHz, busfreq=%06d\n",
+ level, cpufreq, busfreq);
+ }
+exit:
+ return ret;
+}
+
+static int exynos_frequency_unlock(struct device *dev)
+{
+ int ret = 0;
+ struct device *busdev = dev_get("exynos-busfreq");
+
+ if (atomic_read(&mdm_hsic_pm_pdata.freqlock) == 1) {
+ /* cpu frequency unlock */
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF);
+
+ /* bus frequency unlock */
+ ret = dev_unlock(busdev, dev);
+ if (ret < 0) {
+ pr_err("ERR: dev_unlock error: %d\n", ret);
+ goto exit;
+ }
+
+ /* unlock minimum number of cpu cores */
+ cpufreq_pegasusq_min_cpu_unlock();
+
+ atomic_set(&mdm_hsic_pm_pdata.freqlock, 0);
+ pr_debug("success\n");
+ }
+exit:
+ return ret;
+}
+
struct platform_device mdm_device = {
.name = "mdm2_modem",
.id = -1,
@@ -57,8 +193,28 @@ struct platform_device mdm_device = {
static int __init init_mdm_modem(void)
{
- pr_err("%s !!! !!\n", __func__);
+ int ret;
+ pr_info("%s: registering modem dev, pm dev\n", __func__);
+
+ mdm_pm_device.dev.platform_data = &mdm_hsic_pm_pdata;
+ ((struct mdm_hsic_pm_platform_data *)
+ mdm_pm_device.dev.platform_data)->dev =
+ &mdm_pm_device.dev;
+#ifdef CONFIG_MDM_HSIC_PM
+ ret = platform_device_register(&mdm_pm_device);
+ if (ret < 0) {
+ pr_err("%s: fail to register mdm hsic pm dev(err:%d)\n",
+ __func__, ret);
+ return ret;
+ }
+#endif
mdm_device.dev.platform_data = &mdm_platform_data;
- return platform_device_register(&mdm_device);
+ ret = platform_device_register(&mdm_device);
+ if (ret < 0) {
+ pr_err("%s: fail to register mdm modem dev(err:%d)\n",
+ __func__, ret);
+ return ret;
+ }
+ return 0;
}
module_init(init_mdm_modem);