aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r--arch/arm/mach-exynos/include/mach/sec_modem.h3
-rw-r--r--arch/arm/mach-exynos/mdm2.c59
-rw-r--r--arch/arm/mach-exynos/mdm_common.c60
-rw-r--r--arch/arm/mach-exynos/mdm_device.c39
-rw-r--r--arch/arm/mach-exynos/mdm_hsic_pm.c249
-rw-r--r--arch/arm/mach-exynos/mdm_private.h2
-rw-r--r--arch/arm/mach-exynos/setup-usb-phy.c73
7 files changed, 364 insertions, 121 deletions
diff --git a/arch/arm/mach-exynos/include/mach/sec_modem.h b/arch/arm/mach-exynos/include/mach/sec_modem.h
index 4a7fbe8..535cbb5 100644
--- a/arch/arm/mach-exynos/include/mach/sec_modem.h
+++ b/arch/arm/mach-exynos/include/mach/sec_modem.h
@@ -6,15 +6,18 @@ enum hsic_lpa_states {
STATE_HSIC_LPA_WAKE,
STATE_HSIC_LPA_PHY_INIT,
STATE_HSIC_LPA_CHECK,
+ STATE_HSIC_LPA_ENABLE,
};
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
void set_host_states(struct platform_device *pdev, int type);
void set_hsic_lpa_states(int states);
int get_cp_active_state(void);
+int get_hostwake_state(void);
#elif defined(CONFIG_MDM_HSIC_PM)
int set_hsic_lpa_states(int states);
#else
+static inline int get_hostwake_state(void) { return 0; }
#define set_hsic_lpa_states(states) do {} while (0);
#endif
diff --git a/arch/arm/mach-exynos/mdm2.c b/arch/arm/mach-exynos/mdm2.c
index 09b2a0f..f5b23a1 100644
--- a/arch/arm/mach-exynos/mdm2.c
+++ b/arch/arm/mach-exynos/mdm2.c
@@ -200,16 +200,6 @@ static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
usleep_range(10000, 15000);
gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
-#ifdef CONFIG_HSIC_EURONLY_APPLY
- for (i = 0; i < MDM_PBLRDY_CNT; i++) {
- pblrdy = gpio_get_value(mdm_drv->mdm2ap_pblrdy);
- if (pblrdy)
- break;
- usleep_range(5000, 5000);
- }
-
- pr_err("%s: i:%d\n", __func__, i);
-#else
if (!mdm_drv->mdm2ap_pblrdy)
goto start_mdm_peripheral;
@@ -221,7 +211,6 @@ static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
}
pr_debug("%s: i:%d\n", __func__, i);
-#endif
start_mdm_peripheral:
mdm_peripheral_connect(mdm_drv);
@@ -237,17 +226,6 @@ static void mdm_do_soft_power_on(struct mdm_modem_drv *mdm_drv)
mdm_peripheral_disconnect(mdm_drv);
mdm_toggle_soft_reset(mdm_drv);
-#ifdef CONFIG_HSIC_EURONLY_APPLY
-
- for (i = 0; i < MDM_PBLRDY_CNT; i++) {
- pblrdy = gpio_get_value(mdm_drv->mdm2ap_pblrdy);
- if (pblrdy)
- break;
- usleep_range(5000, 5000);
- }
-
- pr_err("%s: i:%d\n", __func__, i);
-#else
if (!mdm_drv->mdm2ap_pblrdy)
goto start_mdm_peripheral;
@@ -259,7 +237,6 @@ static void mdm_do_soft_power_on(struct mdm_modem_drv *mdm_drv)
}
pr_debug("%s: i:%d\n", __func__, i);
-#endif
start_mdm_peripheral:
mdm_peripheral_connect(mdm_drv);
@@ -270,14 +247,6 @@ static void mdm_power_on_common(struct mdm_modem_drv *mdm_drv)
{
power_on_count++;
-#ifdef CONFIG_HSIC_EURONLY_APPLY
- if(0==(power_on_count%5))
- {
- mdm_power_down_common(mdm_drv);
- pr_err("%s : power_on_count reset!\n", __func__);
- }
-#endif
-
/* this gpio will be used to indicate apq readiness,
* de-assert it now so that it can be asserted later.
* May not be used.
@@ -357,6 +326,31 @@ static void mdm_modem_shutdown(struct platform_device *pdev)
mdm_common_modem_shutdown(pdev);
}
+#ifdef CONFIG_FAST_BOOT
+static void modem_complete(struct device *pdev)
+{
+ struct mdm_platform_data *pdata;
+
+ if (!pdev) {
+ pr_err("pdev is null!!\n");
+ return;
+ }
+ pdata = pdev->platform_data;
+
+ if (!pdata) {
+ pr_err("pdata is null!!\n");
+ return;
+ }
+
+ if (pdata->modem_complete)
+ pdata->modem_complete(pdev);
+}
+
+static const struct dev_pm_ops mdm2_pm_ops = {
+ .complete = modem_complete,
+};
+#endif
+
static struct platform_driver mdm_modem_driver = {
.remove = mdm_modem_remove,
/**
@@ -365,6 +359,9 @@ static struct platform_driver mdm_modem_driver = {
*/
.driver = {
.name = "mdm2_modem",
+#ifdef CONFIG_FAST_BOOT
+ .pm = &mdm2_pm_ops,
+#endif
.owner = THIS_MODULE
},
};
diff --git a/arch/arm/mach-exynos/mdm_common.c b/arch/arm/mach-exynos/mdm_common.c
index f47a122..294772d 100644
--- a/arch/arm/mach-exynos/mdm_common.c
+++ b/arch/arm/mach-exynos/mdm_common.c
@@ -58,6 +58,10 @@ static const char rmnet_pm_dev[] = "mdm_hsic_pm0";
#include <linux/poll.h>
#endif
+#ifdef CONFIG_FAST_BOOT
+#include <linux/reboot.h>
+#endif
+
#define MDM_MODEM_TIMEOUT 6000
#define MDM_MODEM_DELTA 100
#define MDM_BOOT_TIMEOUT 60000L
@@ -223,6 +227,9 @@ static void mdm_silent_reset(void)
{
pr_info("mdm: silent reset!!\n");
+
+ set_shutdown();
+ mdm_drv->mdm_ready = 0;
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
complete(&mdm_needs_reload);
if (!wait_for_completion_timeout(&mdm_boot,
@@ -374,6 +381,18 @@ static void mdm_fatal_fn(struct work_struct *work)
static DECLARE_WORK(mdm_fatal_work, mdm_fatal_fn);
+static void mdm_reconnect_fn(struct work_struct *work)
+{
+ pr_info("mdm: check 2nd enumeration\n");
+
+ if (mdm_check_main_connect(rmnet_pm_dev))
+ return;
+
+ mdm_silent_reset();
+}
+
+static DECLARE_DELAYED_WORK(mdm_reconnect_work, mdm_reconnect_fn);
+
static void mdm_status_fn(struct work_struct *work)
{
int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
@@ -385,6 +404,8 @@ static void mdm_status_fn(struct work_struct *work)
if (value) {
request_boot_lock_release(rmnet_pm_dev);
request_active_lock_set(rmnet_pm_dev);
+ queue_delayed_work(mdm_queue, &mdm_reconnect_work,
+ msecs_to_jiffies(3000));
}
#endif
}
@@ -465,6 +486,10 @@ static void sim_status_check(struct work_struct *work)
mdm_drv->sim_changed = 1;
pr_info("sim state = %s\n",
mdm_drv->sim_state == 1 ? "Attach" : "Detach");
+#ifdef CONFIG_FAST_BOOT
+ if (fake_shut_down)
+ mdm_drv->sim_shutdown_req = true;
+#endif
wake_up_interruptible(&mdm_drv->wq);
} else
mdm_drv->sim_changed = 0;
@@ -639,6 +664,9 @@ static int mdm_subsys_shutdown(const struct subsys_data *crashed_subsys)
msleep(mdm_drv->pdata->ramdump_delay_ms);
}
+ /* close silent log */
+ silent_log_panic_handler();
+
#if 0
if (!mdm_drv->mdm_unexpected_reset_occurred)
mdm_drv->ops->reset_mdm_cb(mdm_drv);
@@ -738,6 +766,18 @@ static int mdm_debugfs_init(void)
}
#endif
+#ifdef CONFIG_FAST_BOOT
+static void sim_detect_complete(struct device *dev)
+{
+ if (!mdm_drv->sim_irq && mdm_drv->sim_shutdown_req) {
+ pr_info("fake shutdown sim changed shutdown\n");
+ kernel_power_off();
+ /*kernel_restart(NULL);*/
+ mdm_drv->sim_shutdown_req = false;
+ }
+}
+#endif
+
static void mdm_modem_initialize_data(struct platform_device *pdev,
struct mdm_ops *mdm_ops)
{
@@ -797,15 +837,9 @@ static void mdm_modem_initialize_data(struct platform_device *pdev,
if (pres)
mdm_drv->ap2mdm_pmic_pwr_en_gpio = pres->start;
-#ifdef CONFIG_HSIC_EURONLY_APPLY
- /* MDM2AP_HSIC_READY */
- pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
- "MDM2AP_HSIC_READY");
-#else
/* MDM2AP_PBLRDY */
pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
"MDM2AP_PBLRDY");
-#endif
if (pres)
mdm_drv->mdm2ap_pblrdy = pres->start;
#ifdef CONFIG_SIM_DETECT
@@ -826,6 +860,10 @@ static void mdm_modem_initialize_data(struct platform_device *pdev,
mdm_drv->pdata = pdev->dev.platform_data;
dump_timeout_ms = mdm_drv->pdata->ramdump_timeout_ms > 0 ?
mdm_drv->pdata->ramdump_timeout_ms : MDM_RDUMP_TIMEOUT;
+#ifdef CONFIG_FAST_BOOT
+ mdm_drv->pdata->modem_complete = sim_detect_complete;
+ mdm_drv->sim_shutdown_req = false;
+#endif
}
int mdm_common_create(struct platform_device *pdev,
@@ -853,12 +891,8 @@ int mdm_common_create(struct platform_device *pdev,
#ifdef CONFIG_SIM_DETECT
gpio_request(mdm_drv->sim_detect_gpio, "SIM_DETECT");
#endif
-#ifdef CONFIG_HSIC_EURONLY_APPLY
- gpio_request(mdm_drv->mdm2ap_pblrdy, "MDM2AP_HSIC_READY");
-#else
if (mdm_drv->mdm2ap_pblrdy > 0)
gpio_request(mdm_drv->mdm2ap_pblrdy, "MDM2AP_PBLRDY");
-#endif
if (mdm_drv->ap2mdm_pmic_pwr_en_gpio > 0) {
gpio_request(mdm_drv->ap2mdm_pmic_pwr_en_gpio,
@@ -1029,11 +1063,7 @@ status_err:
simdetect_err:
#endif
-#ifndef CONFIG_HSIC_EURONLY_APPLY
- if (mdm_drv->mdm2ap_pblrdy > 0)
-#endif
- {
-
+ if (mdm_drv->mdm2ap_pblrdy > 0) {
#ifdef CONFIG_ARCH_EXYNOS
s3c_gpio_cfgpin(mdm_drv->mdm2ap_pblrdy, S3C_GPIO_SFN(0xf));
s3c_gpio_setpull(mdm_drv->mdm2ap_pblrdy, S3C_GPIO_PULL_NONE);
diff --git a/arch/arm/mach-exynos/mdm_device.c b/arch/arm/mach-exynos/mdm_device.c
index 620936e..20cf664 100644
--- a/arch/arm/mach-exynos/mdm_device.c
+++ b/arch/arm/mach-exynos/mdm_device.c
@@ -56,14 +56,6 @@ static struct resource mdm_resources[] = {
.name = "AP2MDM_WAKEUP",
.flags = IORESOURCE_IO,
},
-#ifdef CONFIG_HSIC_EURONLY_APPLY
- {
- .start = GPIO_MDM2AP_HSIC_READY,
- .end = GPIO_MDM2AP_HSIC_READY,
- .name = "MDM2AP_HSIC_READY",
- .flags = IORESOURCE_IO,
- },
-#endif
#ifdef CONFIG_SIM_DETECT
{
.start = GPIO_SIM_DETECT,
@@ -127,9 +119,14 @@ static struct mdm_platform_data mdm_platform_data = {
.peripheral_platform_device_ohci = &s5p_device_ohci,
#endif
.ramdump_timeout_ms = 120000,
-#if defined(CONFIG_SIM_DETECT)
+#if (defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_SP7160LTE) || defined(CONFIG_MACH_TAB3)) && defined(CONFIG_QC_MODEM) \
+ && defined(CONFIG_SIM_DETECT)
.sim_polarity = 0,
#endif
+#if (defined(CONFIG_MACH_GC1_USA_VZW) || defined(CONFIG_TARGET_LOCALE_EUR)) \
+ && defined(CONFIG_QC_MODEM) && defined(CONFIG_SIM_DETECT)
+ .sim_polarity = 1,
+#endif
};
static int exynos_frequency_lock(struct device *dev)
@@ -228,30 +225,16 @@ static int __init init_mdm_modem(void)
return ret;
}
#endif
-
#if defined(CONFIG_MACH_P4NOTE) && defined(CONFIG_QC_MODEM) \
&& defined(CONFIG_SIM_DETECT)
mdm_platform_data.sim_polarity = 0;
#endif
-
-#if (defined(CONFIG_MACH_GC1_USA_VZW) || defined(CONFIG_TARGET_LOCALE_EUR)) \
- && defined(CONFIG_QC_MODEM) && defined(CONFIG_SIM_DETECT)
- mdm_platform_data.sim_polarity = 1;
-#endif
-
-#if defined(CONFIG_MACH_KONA) && defined(CONFIG_QC_MODEM) \
+#if defined(CONFIG_MACH_KONALTE_USA_ATT) && defined(CONFIG_QC_MODEM) \
&& defined(CONFIG_SIM_DETECT)
-#if defined(CONFIG_MACH_KONALTE_USA_ATT)
- if (system_rev >= 1)
- mdm_platform_data.sim_polarity = 0;
- else
- mdm_platform_data.sim_polarity = 1;
-#else
- if (system_rev >= 1)
- mdm_platform_data.sim_polarity = 1;
- else
- mdm_platform_data.sim_polarity = 0;
-#endif
+ if (system_rev != 9 && system_rev >= 1)
+ mdm_platform_data.sim_polarity = 0;
+ else
+ mdm_platform_data.sim_polarity = 1;
#endif
mdm_device.dev.platform_data = &mdm_platform_data;
ret = platform_device_register(&mdm_device);
diff --git a/arch/arm/mach-exynos/mdm_hsic_pm.c b/arch/arm/mach-exynos/mdm_hsic_pm.c
index a8dd153..0ec7531 100644
--- a/arch/arm/mach-exynos/mdm_hsic_pm.c
+++ b/arch/arm/mach-exynos/mdm_hsic_pm.c
@@ -35,16 +35,24 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/ehci_def.h>
-#include <mach/mdm2.h>
-#include <linux/kernel.h>
#ifdef CONFIG_CPU_FREQ_TETHERING
+#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <mach/mdm2.h>
#endif
-
#ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
#include <linux/usb/android_composite.h>
#endif
+#ifdef CONFIG_USBIRQ_BALANCING_LTE_HIGHTP
+#include <mach/mdm2.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq_pegasusq.h>
+#define dev_put devput
+#include <linux/netdevice.h>
+#undef dev_put
+#include <mach/dev.h>
+#endif
#define EXTERNAL_MODEM "external_modem"
#define EHCI_REG_DUMP
@@ -96,6 +104,12 @@ struct mdm_hsic_pm_data {
#ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
struct notifier_block usb_composite_notifier;
#endif
+#ifdef CONFIG_USBIRQ_BALANCING_LTE_HIGHTP
+ struct notifier_block rndis_notifier;
+ struct notifier_block cpu_hotplug_notifier;
+ struct delayed_work hotplug_work;
+ bool is_rndis_running;
+#endif
bool block_request;
bool state_busy;
@@ -126,6 +140,9 @@ struct mdm_hsic_pm_data {
struct delayed_work fast_dormancy_work;
struct mdm_hsic_pm_platform_data *mdm_pdata;
+
+ /* QMICM mode value */
+ bool qmicm_mode;
};
/* indicate wakeup from lpa state */
@@ -288,16 +305,30 @@ int pm_dev_wait_lpa_wake(void)
return 0;
}
+void set_shutdown(void)
+{
+ struct mdm_hsic_pm_data *pm_data =
+ get_pm_data_by_dev_name("mdm_hsic_pm0");
+
+ pm_data->shutdown = true;
+}
+
void notify_modem_fatal(void)
{
struct mdm_hsic_pm_data *pm_data =
get_pm_data_by_dev_name("mdm_hsic_pm0");
pr_info("%s or shutdown\n", __func__);
+ print_mdm_gpio_state();
if (!pm_data || !pm_data->intf_cnt || !pm_data->udev)
return;
+ if (pm_data->shutdown == true) {
+ pr_info("During shutdown, return %s\n", __func__);
+ return;
+ }
+
pm_data->shutdown = true;
/* crash from sleep, ehci is in waking up, so do not control ehci */
@@ -373,7 +404,6 @@ void request_active_lock_release(const char *name)
pr_info("%s\n", __func__);
if (pm_data)
wake_unlock(&pm_data->l2_wake);
-
}
void request_boot_lock_set(const char *name)
@@ -411,13 +441,22 @@ void set_host_stat(const char *name, enum pwr_stat status)
return;
}
+ /* crash during kernel suspend/resume, do not control host ready pin */
+ /* and it has to be controlled when host driver initialized again */
+ if (pm_data->block_request && pm_data->shutdown)
+ return;
+
if (pm_data->gpio_host_ready) {
pr_info("dev rdy val = %d\n",
gpio_get_value(pm_data->gpio_device_ready));
pr_info("%s:set host port power status to [%d]\n",
__func__, status);
- /*10ms delay location moved*/
+ /*
+ * need get some delay for MDM9x15 suspend
+ * if L3 drive goes out to modem in suspending
+ * modem goes to unstable PM state. now 10 ms is enough
+ */
if(status == POWER_OFF)
mdelay(10);
@@ -438,6 +477,10 @@ int wait_dev_pwr_stat(const char *name, enum pwr_stat status)
return -ENODEV;
}
+ /* in shutdown(including modem fatal) do not need to wait dev ready */
+ if (pm_data->shutdown)
+ return 0;
+
pr_info("%s:[%s]...\n", __func__, status ? "PWR ON" : "PWR OFF");
if (pm_data->gpio_device_ready) {
@@ -452,8 +495,10 @@ int wait_dev_pwr_stat(const char *name, enum pwr_stat status)
if (gpio_get_value(pm_data->gpio_device_ready) == status)
pr_info(" done\n");
- else
+ else {
subsystem_restart(EXTERNAL_MODEM);
+ return -ETIMEDOUT;
+ }
return 0;
}
@@ -488,30 +533,23 @@ int check_udev_suspend_allowed(const char *name)
int set_hsic_lpa_states(int states)
{
+ struct mdm_hsic_pm_data *pm_data =
+ get_pm_data_by_dev_name("mdm_hsic_pm0");
/* if modem need to check survive, get status in variable */
int val = 1;
+ int ret = 0;
/* set state for LPA enter */
if (val) {
switch (states) {
case STATE_HSIC_LPA_ENTER:
- /*
- * need get some delay for MDM9x15 suspend
- * if L3 drive goes out to modem in suspending
- * modem goes to unstable PM state. now 10 ms is enough
- */
- /*10ms delay location moved*/
- //mdelay(10);
set_host_stat("mdm_hsic_pm0", POWER_OFF);
- wait_dev_pwr_stat("mdm_hsic_pm0", POWER_OFF);
+ ret = wait_dev_pwr_stat("mdm_hsic_pm0", POWER_OFF);
+ if (ret)
+ return ret;
pr_info("set hsic lpa enter\n");
break;
case STATE_HSIC_LPA_WAKE:
- /* host control is done by ehci runtime resume code */
- #if 0
- set_host_stat("mdm_hsic_pm0", POWER_ON);
- wait_dev_pwr_stat("mdm_hsic_pm0", POWER_ON);
- #endif
lpa_handling = true;
pr_info("%s: set lpa handling to true\n", __func__);
request_active_lock_set("mdm_hsic_pm0");
@@ -528,6 +566,13 @@ int set_hsic_lpa_states(int states)
return 1;
else
return 0;
+ case STATE_HSIC_LPA_ENABLE:
+ if (lpcharge)
+ return 0;
+ else if (pm_data)
+ return pm_data->shutdown;
+ else
+ return 1;
default:
pr_info("unknown lpa state\n");
break;
@@ -536,6 +581,24 @@ int set_hsic_lpa_states(int states)
return 0;
}
+bool mdm_check_main_connect(const char *name)
+{
+ /* find pm device from list by name */
+ struct mdm_hsic_pm_data *pm_data = get_pm_data_by_dev_name(name);
+
+ if (!pm_data) {
+ pr_err("%s:no pm device(%s)\n", __func__, name);
+ return false;
+ }
+
+ print_pm_dev_info(pm_data);
+
+ if (pm_data->intf_cnt >= 3)
+ return true;
+ else
+ return false;
+}
+
#define PM_START_DELAY_MS 3000
int register_udev_to_pm_dev(const char *name, struct usb_device *udev)
{
@@ -556,6 +619,7 @@ int register_udev_to_pm_dev(const char *name, struct usb_device *udev)
pm_data->udev = udev;
atomic_set(&pm_data->pmlock_cnt, 0);
usb_disable_autosuspend(udev);
+ pm_data->shutdown = false;
#ifdef CONFIG_SIM_DETECT
get_sim_state_at_boot();
#endif
@@ -574,6 +638,22 @@ int register_udev_to_pm_dev(const char *name, struct usb_device *udev)
return 0;
}
+int set_qmicm_mode(const char *name)
+{
+ /* find pm device from list by name */
+ struct mdm_hsic_pm_data *pm_data = get_pm_data_by_dev_name(name);
+
+ if (!pm_data) {
+ pr_err("%s:no pm device(%s) exist\n", __func__, name);
+ return -ENODEV;
+ }
+
+ pm_data->qmicm_mode = true;
+ pr_info("%s: set QMICM mode\n", __func__);
+
+ return 0;
+}
+
/* force fatal for debug when HSIC disconnect */
extern void mdm_force_fatal(void);
@@ -986,9 +1066,7 @@ static int link_pm_netdev_event(struct notifier_block *this,
}
return NOTIFY_DONE;
}
-#endif
-#ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
static int usb_composite_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -1014,7 +1092,123 @@ static int usb_composite_notifier_event(struct notifier_block *this,
return NOTIFY_DONE;
}
#endif
+#ifdef CONFIG_USBIRQ_BALANCING_LTE_HIGHTP
+int boost_busfreq(struct device *dev, int enable)
+{
+ int ret = 0;
+ unsigned int busfreq = 440220; // T0
+ struct device *busdev = NULL;
+
+ if (dev == NULL)
+ return -ENODEV;
+
+ busdev = dev_get("exynos-busfreq");
+ if (busdev == NULL)
+ return -ENODEV;
+
+ if (enable)
+ ret = dev_lock(busdev, dev, busfreq);
+ else
+ ret = dev_unlock(busdev, dev);
+
+ return ret;
+}
+
+// only for T0 USB HOST
+int clear_cpu0_from_usbhost_irq(int enable)
+{
+ unsigned int irq = IRQ_USB_HOST;
+// unsigned int irq = IRQ_USB_HSOTG;
+
+ cpumask_var_t new_value;
+ int err = 0;
+
+ if (!irq_can_set_affinity(irq))
+ return -EIO;
+
+ if (!alloc_cpumask_var(&new_value, GFP_KERNEL))
+ return -ENOMEM;
+
+ cpumask_setall(new_value);
+
+ if (enable) {
+ cpumask_and(new_value, new_value, cpu_online_mask);
+ cpumask_clear_cpu(0, new_value);
+ }
+
+ if (cpumask_intersects(new_value, cpu_online_mask)) {
+ err = irq_set_affinity(irq, new_value);
+ }
+
+ free_cpumask:
+ free_cpumask_var(new_value);
+ return err;
+}
+
+static int link_pm_rndis_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct mdm_hsic_pm_data *pm_data =
+ container_of(this, struct mdm_hsic_pm_data, rndis_notifier);
+ struct mdm_hsic_pm_platform_data *mdm_pdata = pm_data->mdm_pdata;
+ struct net_device *dev = ptr;
+
+ if (!net_eq(dev_net(dev), &init_net))
+ return NOTIFY_DONE;
+ if (!strncmp(dev->name, "rndis", 5)) {
+ switch (event) {
+ case NETDEV_UP:
+ if (mdm_pdata && mdm_pdata->dev)
+ boost_busfreq(mdm_pdata->dev, 1);
+ cpufreq_pegasusq_min_cpu_lock(2);
+ clear_cpu0_from_usbhost_irq(1);
+ pm_data->is_rndis_running = true;
+ pr_info("%s: %s UP\n", __func__, dev->name);
+ break;
+ case NETDEV_DOWN:
+ pm_data->is_rndis_running = false;
+ clear_cpu0_from_usbhost_irq(0);
+ cpufreq_pegasusq_min_cpu_unlock();
+ if (mdm_pdata && mdm_pdata->dev)
+ boost_busfreq(mdm_pdata->dev, 0);
+ pr_info("%s: %s DOWN\n", __func__, dev->name);
+ break;
+ }
+ }
+ return NOTIFY_DONE;
+}
+
+static void hotplug_work_start(struct work_struct *work)
+{
+ struct mdm_hsic_pm_data *pm_data =
+ container_of(work, struct mdm_hsic_pm_data,
+ hotplug_work.work);
+ clear_cpu0_from_usbhost_irq(1);
+}
+
+static int hotplug_notify_callback(struct notifier_block *this,
+ unsigned long action, void *hcpu)
+{
+ struct mdm_hsic_pm_data *pm_data =
+ container_of(this, struct mdm_hsic_pm_data, cpu_hotplug_notifier);
+
+ if (pm_data->is_rndis_running) {
+ switch (action) {
+
+ case CPU_POST_DEAD:
+ if (1 == num_online_cpus())
+ {
+ cpufreq_pegasusq_min_cpu_lock(2);
+ queue_delayed_work(pm_data->wq, &pm_data->hotplug_work,
+ msecs_to_jiffies(100));
+ }
+ break;
+ }
+ }
+ return NOTIFY_OK;
+}
+#endif
static int mdm_hsic_pm_probe(struct platform_device *pdev)
{
int ret;
@@ -1077,18 +1271,27 @@ static int mdm_hsic_pm_probe(struct platform_device *pdev)
#ifdef CONFIG_CPU_FREQ_TETHERING
pm_data->netdev_notifier.notifier_call = link_pm_netdev_event;
register_netdevice_notifier(&pm_data->netdev_notifier);
-#endif
-#ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
pm_data->usb_composite_notifier.notifier_call =
usb_composite_notifier_event;
register_usb_composite_notifier(&pm_data->usb_composite_notifier);
#endif
+#ifdef CONFIG_USBIRQ_BALANCING_LTE_HIGHTP
+ pm_data->is_rndis_running = false;
+ INIT_DELAYED_WORK(&pm_data->hotplug_work, hotplug_work_start);
+
+ pm_data->rndis_notifier.notifier_call = link_pm_rndis_event;
+ register_netdevice_notifier(&pm_data->rndis_notifier);
+
+ pm_data->cpu_hotplug_notifier.notifier_call = hotplug_notify_callback;
+ register_cpu_notifier(&pm_data->cpu_hotplug_notifier);
+#endif
wake_lock_init(&pm_data->l2_wake, WAKE_LOCK_SUSPEND, pm_data->name);
wake_lock_init(&pm_data->boot_wake, WAKE_LOCK_SUSPEND, "mdm_boot");
wake_lock_init(&pm_data->fd_wake, WAKE_LOCK_SUSPEND, "fast_dormancy");
pm_data->fd_wake_time = DEFAULT_RAW_WAKE_TIME;
+ pm_data->qmicm_mode = false;
print_pm_dev_info(pm_data);
list_add(&pm_data->list, &hsic_pm_dev_list);
diff --git a/arch/arm/mach-exynos/mdm_private.h b/arch/arm/mach-exynos/mdm_private.h
index d632c8f..37df782 100644
--- a/arch/arm/mach-exynos/mdm_private.h
+++ b/arch/arm/mach-exynos/mdm_private.h
@@ -68,6 +68,7 @@ void mdm_common_modem_shutdown(struct platform_device *pdev);
void mdm_common_set_debug_state(int value);
void mdm_peripheral_disconnect(struct mdm_modem_drv *mdm_drv);
+void set_shutdown(void);
void notify_modem_fatal(void);
void request_autopm_lock(int status);
bool mdm_check_main_connect(const char *);
@@ -77,5 +78,6 @@ void get_sim_state_at_boot(void);
extern unsigned int lpcharge;
extern void ctrl_bridge_stop_all(void);
extern void rmnet_usb_ctrl_stop_all(void);
+extern void silent_log_panic_handler(void);
#endif
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index 22621c5..815be57 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -68,6 +68,10 @@ struct exynos_usb_phy {
unsigned long usage;
};
+#if defined(CONFIG_KONA_00_BD)
+extern int current_cable_type;
+#endif
+
static struct exynos_usb_phy usb_phy_control;
static atomic_t host_usage;
@@ -357,10 +361,13 @@ static int exynos4_usb_phy1_resume(struct platform_device *pdev)
if (usb_phy_control.lpa_entered) {
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) \
|| defined(CONFIG_MDM_HSIC_PM)
- if (!strcmp(pdev->name, "s5p-ehci"))
+ if (!strcmp(pdev->name, "s5p-ehci")) {
set_hsic_lpa_states(STATE_HSIC_LPA_WAKE);
-#endif
+ usb_phy_control.lpa_entered = 0;
+ }
+#else
usb_phy_control.lpa_entered = 0;
+#endif
err = 1;
} else {
err = 0;
@@ -422,10 +429,13 @@ static int exynos4_usb_phy1_resume(struct platform_device *pdev)
}
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) \
|| defined(CONFIG_MDM_HSIC_PM)
- if (!strcmp(pdev->name, "s5p-ehci"))
+ if (!strcmp(pdev->name, "s5p-ehci")) {
set_hsic_lpa_states(STATE_HSIC_LPA_WAKE);
-#endif
+ usb_phy_control.lpa_entered = 0;
+ }
+#else
usb_phy_control.lpa_entered = 0;
+#endif
err = 1;
}
udelay(80);
@@ -469,11 +479,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
/* set clock frequency for PLL */
phyclk = readl(EXYNOS4_PHYCLK) & ~(EXYNOS4210_CLKSEL_MASK);
phyclk |= exynos_usb_phy_set_clock(pdev);
-#ifdef CONFIG_USB_OHCI_S5P
- phyclk |= PHY1_COMMON_ON_N;
-#else
phyclk &= ~(PHY1_COMMON_ON_N);
-#endif
writel(phyclk, EXYNOS4_PHYCLK);
/* set to normal HSIC 0 and 1 of PHY1 */
@@ -1003,6 +1009,9 @@ int exynos4_check_usb_op(void)
int ret;
#if defined(CONFIG_MDM_HSIC_PM)
+ if (set_hsic_lpa_states(STATE_HSIC_LPA_ENABLE))
+ return 1;
+
/* if it is normal boot, block lpa till modem boot */
if (set_hsic_lpa_states(STATE_HSIC_LPA_CHECK))
return 1;
@@ -1014,14 +1023,29 @@ int exynos4_check_usb_op(void)
local_irq_save(flags);
phypwr = readl(EXYNOS4_PHYPWR);
- /*If USB Device is power on, */
- if (exynos_usb_device_phy_is_on()) {
- op = 1;
- goto done;
- } else if (!exynos4_usb_host_phy_is_on()) {
- op = 0;
- goto done;
- }
+#if defined(CONFIG_KONA_00_BD)
+ /*If USB Device is power on, */
+ if (current_cable_type != 3) // 3 is TA (POWER_SUPPLY_TYPE_MAINS)
+ {
+// printk("[USB] current_cable_type is %d !!!!!! ",current_cable_type);
+ if (exynos_usb_device_phy_is_on()) {
+ op = 1;
+ goto done;
+ } else if (!exynos4_usb_host_phy_is_on()) {
+ op = 0;
+ goto done;
+ }
+ }
+#else
+ /*If USB Device is power on, */
+ if (exynos_usb_device_phy_is_on()) {
+ op = 1;
+ goto done;
+ } else if (!exynos4_usb_host_phy_is_on()) {
+ op = 0;
+ goto done;
+ }
+#endif
/*If USB Device & Host is suspended, */
if (soc_is_exynos4210()) {
@@ -1044,6 +1068,8 @@ int exynos4_check_usb_op(void)
if (phypwr & (PHY1_STD_FORCE_SUSPEND
| EXYNOS4212_HSIC0_FORCE_SUSPEND
| EXYNOS4212_HSIC1_FORCE_SUSPEND)) {
+ /* HSIC LPA: LPA USB phy retention reume call the usb
+ * reset resume, so we should let CP to HSIC L3 mode. */
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
set_hsic_lpa_states(STATE_HSIC_LPA_ENTER);
#elif defined(CONFIG_MDM_HSIC_PM)
@@ -1176,15 +1202,13 @@ int s5p_usb_phy_suspend(struct platform_device *pdev, int type)
if (soc_is_exynos4210() ||
soc_is_exynos4212() ||
soc_is_exynos4412()) {
+ dev_info(&pdev->dev, "host_phy_susp\n");
#ifdef CONFIG_USB_OHCI_S5P
- /* Set OHCI clock off when ohci_hcd is suspended */
- if (ohci_hcd->state == HC_STATE_SUSPENDED) {
- phyclk = readl(EXYNOS4_PHYCLK);
- phyclk &= ~(PHY1_COMMON_ON_N);
- writel(phyclk, EXYNOS4_PHYCLK);
- }
- dev_info(&pdev->dev, "host_phy_susp:%d\n",
- ohci_hcd->state);
+ if (ohci_hcd->state == HC_STATE_SUSPENDED) {
+ phyclk = readl(EXYNOS4_PHYCLK);
+ phyclk &= ~(PHY1_COMMON_ON_N);
+ writel(phyclk, EXYNOS4_PHYCLK);
+ }
#endif
ret = exynos4_usb_phy1_suspend(pdev);
} else
@@ -1214,6 +1238,7 @@ int s5p_usb_phy_resume(struct platform_device *pdev, int type)
if (soc_is_exynos4210() ||
soc_is_exynos4212() ||
soc_is_exynos4412()) {
+ dev_info(&pdev->dev, "host_phy_resume\n");
#ifdef CONFIG_USB_OHCI_S5P
phyclk = readl(EXYNOS4_PHYCLK);
phyclk |= PHY1_COMMON_ON_N;