diff options
author | sbrissen <sbrissen@hotmail.com> | 2015-03-27 08:15:56 -0400 |
---|---|---|
committer | sbrissen <sbrissen@hotmail.com> | 2015-03-27 08:20:09 -0400 |
commit | a0d78f86e338f28cf8e658563feba990cccdf5a1 (patch) | |
tree | 351dd3e9b6d05270c75d1776d6c57d0246b181ac /arch/arm/mach-exynos | |
parent | a82e2f1d427b0c45388e3901104a189bb28161bd (diff) | |
download | kernel_samsung_smdk4412-a0d78f86e338f28cf8e658563feba990cccdf5a1.tar.gz kernel_samsung_smdk4412-a0d78f86e338f28cf8e658563feba990cccdf5a1.tar.bz2 kernel_samsung_smdk4412-a0d78f86e338f28cf8e658563feba990cccdf5a1.zip |
smdk4412: update mdm from KK source
Change-Id: If01d4a165b4b6bdc26a20fb449104e7bcb0c9403
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r-- | arch/arm/mach-exynos/include/mach/sec_modem.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mdm2.c | 59 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mdm_common.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mdm_device.c | 39 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mdm_hsic_pm.c | 249 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mdm_private.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos/setup-usb-phy.c | 73 |
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 4a7fbe8deb0..535cbb52e40 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 09b2a0f16fe..f5b23a18e82 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 f47a122a2df..294772dfc1f 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 620936eedfd..20cf6645fae 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 a8dd1530ebe..0ec7531964d 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 d632c8fc52c..37df78243a6 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 22621c5a0f4..815be578083 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; |