diff options
| -rw-r--r-- | drivers/gpu/msm/adreno.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno_a5xx.c | 19 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_device.h | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/cnss2/pci.c | 9 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c | 44 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c | 45 |
8 files changed, 147 insertions, 30 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 7af2af483f10..9cb65033ed13 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2800,6 +2800,27 @@ static void adreno_gpu_model(struct kgsl_device *device, char *str, ADRENO_CHIPID_PATCH(adreno_dev->chipid) + 1); } +static void adreno_suspend_device(struct kgsl_device *device, + pm_message_t pm_state) +{ + struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); + int pm_event = pm_state.event; + + adreno_dispatcher_halt(device); + + if ((pm_event == PM_EVENT_FREEZE) || + (pm_event == PM_EVENT_QUIESCE) || + (pm_event == PM_EVENT_HIBERNATE)) + if (gpudev->zap_shader_unload != NULL) + gpudev->zap_shader_unload(adreno_dev); +} + +static void adreno_resume_device(struct kgsl_device *device) +{ + adreno_dispatcher_unhalt(device); +} + static const struct kgsl_functable adreno_functable = { /* Mandatory functions */ .regread = adreno_regread, @@ -2839,8 +2860,8 @@ static const struct kgsl_functable adreno_functable = { .clk_set_options = adreno_clk_set_options, .gpu_model = adreno_gpu_model, .stop_fault_timer = adreno_dispatcher_stop_fault_timer, - .dispatcher_halt = adreno_dispatcher_halt, - .dispatcher_unhalt = adreno_dispatcher_unhalt, + .suspend_device = adreno_suspend_device, + .resume_device = adreno_resume_device, }; static struct platform_driver adreno_platform_driver = { diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 9ea50007ec38..1f598bf3d9f8 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -794,6 +794,7 @@ struct adreno_gpudev { void (*enable_64bit)(struct adreno_device *); void (*clk_set_options)(struct adreno_device *, const char *, struct clk *, bool on); + void (*zap_shader_unload)(struct adreno_device *); }; /** diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 4daf1fad6ee1..e3381bca2586 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -31,6 +31,7 @@ #include "adreno_a5xx_packets.h" static int zap_ucode_loaded; +static void *zap_handle_ptr; static int critical_packet_constructed; static struct kgsl_memdesc crit_pkts; @@ -2236,7 +2237,6 @@ static int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev, */ static int a5xx_microcode_load(struct adreno_device *adreno_dev) { - void *ptr; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); uint64_t gpuaddr; @@ -2276,11 +2276,12 @@ static int a5xx_microcode_load(struct adreno_device *adreno_dev) /* Load the zap shader firmware through PIL if its available */ if (adreno_dev->gpucore->zap_name && !zap_ucode_loaded) { - ptr = subsystem_get(adreno_dev->gpucore->zap_name); + zap_handle_ptr = subsystem_get(adreno_dev->gpucore->zap_name); /* Return error if the zap shader cannot be loaded */ - if (IS_ERR_OR_NULL(ptr)) - return (ptr == NULL) ? -ENODEV : PTR_ERR(ptr); + if (IS_ERR_OR_NULL(zap_handle_ptr)) + return (zap_handle_ptr == NULL) ? + -ENODEV : PTR_ERR(zap_handle_ptr); zap_ucode_loaded = 1; } @@ -2288,6 +2289,15 @@ static int a5xx_microcode_load(struct adreno_device *adreno_dev) return 0; } +static void a5xx_zap_shader_unload(struct adreno_device *adreno_dev) +{ + if (!IS_ERR_OR_NULL(zap_handle_ptr)) { + subsystem_put(zap_handle_ptr); + zap_handle_ptr = NULL; + zap_ucode_loaded = 0; + } +} + static int _me_init_ucode_workarounds(struct adreno_device *adreno_dev) { switch (ADRENO_GPUREV(adreno_dev)) { @@ -3698,4 +3708,5 @@ struct adreno_gpudev adreno_a5xx_gpudev = { .preemption_schedule = a5xx_preemption_schedule, .enable_64bit = a5xx_enable_64bit, .clk_set_options = a5xx_clk_set_options, + .zap_shader_unload = a5xx_zap_shader_unload, }; diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 4eed26b64577..02f0cb7eb16c 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -746,7 +746,7 @@ static int kgsl_suspend_device(struct kgsl_device *device, pm_message_t state) mutex_lock(&device->mutex); status = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); if (status == 0) - device->ftbl->dispatcher_halt(device); + device->ftbl->suspend_device(device, state); mutex_unlock(&device->mutex); return status; @@ -759,7 +759,7 @@ static int kgsl_resume_device(struct kgsl_device *device) mutex_lock(&device->mutex); if (device->state == KGSL_STATE_SUSPEND) { - device->ftbl->dispatcher_unhalt(device); + device->ftbl->resume_device(device); kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); } else if (device->state != KGSL_STATE_INIT) { /* @@ -782,10 +782,23 @@ static int kgsl_resume_device(struct kgsl_device *device) static int kgsl_suspend(struct device *dev) { + struct kgsl_device *device = dev_get_drvdata(dev); + + return kgsl_suspend_device(device, PMSG_SUSPEND); +} + +static int kgsl_freeze(struct device *dev) +{ + struct kgsl_device *device = dev_get_drvdata(dev); + + return kgsl_suspend_device(device, PMSG_FREEZE); +} - pm_message_t arg = {0}; +static int kgsl_poweroff(struct device *dev) +{ struct kgsl_device *device = dev_get_drvdata(dev); - return kgsl_suspend_device(device, arg); + + return kgsl_suspend_device(device, PMSG_HIBERNATE); } static int kgsl_resume(struct device *dev) @@ -805,7 +818,12 @@ static int kgsl_runtime_resume(struct device *dev) } const struct dev_pm_ops kgsl_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(kgsl_suspend, kgsl_resume) + .suspend = kgsl_suspend, + .resume = kgsl_resume, + .freeze = kgsl_freeze, + .thaw = kgsl_resume, + .poweroff = kgsl_poweroff, + .restore = kgsl_resume, .runtime_suspend = kgsl_runtime_suspend, .runtime_resume = kgsl_runtime_resume, }; diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 57d4fe4d9120..078109af99fe 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/idr.h> +#include <linux/pm.h> #include <linux/pm_qos.h> #include <linux/sched.h> @@ -171,8 +172,9 @@ struct kgsl_functable { void (*gpu_model)(struct kgsl_device *device, char *str, size_t bufsz); void (*stop_fault_timer)(struct kgsl_device *device); - void (*dispatcher_halt)(struct kgsl_device *device); - void (*dispatcher_unhalt)(struct kgsl_device *device); + void (*suspend_device)(struct kgsl_device *device, + pm_message_t pm_state); + void (*resume_device)(struct kgsl_device *device); }; struct kgsl_ioctl { diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 0f4ef3712dd7..4869b33c8526 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -131,6 +131,7 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv) cnss_pr_dbg("Suspending PCI link\n"); if (!pci_priv->pci_link_state) { cnss_pr_info("PCI link is already suspended!\n"); + ret = -EINVAL; goto out; } @@ -393,13 +394,13 @@ static int cnss_qca6174_shutdown(struct cnss_pci_data *pci_priv) cnss_pci_set_auto_suspended(pci_priv, 0); ret = cnss_suspend_pci_link(pci_priv); - if (ret) + if (ret) { cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret); + return -EINVAL; + } cnss_power_off_device(plat_priv); - clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); - return ret; } @@ -516,7 +517,6 @@ static int cnss_qca6290_shutdown(struct cnss_pci_data *pci_priv) clear_bit(CNSS_FW_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); - clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); return ret; } @@ -757,6 +757,7 @@ int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv) set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); cnss_pci_dev_shutdown(pci_priv); pci_priv->driver_ops = NULL; + clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); return 0; } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c index 15c8f923d4f4..e0868ad83bf4 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c @@ -1249,7 +1249,8 @@ int ipa2_reset_hdr(bool user_only) struct ipa_hdr_offset_entry *off_next; struct ipa_hdr_proc_ctx_offset_entry *ctx_off_entry; struct ipa_hdr_proc_ctx_offset_entry *ctx_off_next; - int i; + int i, end = 0; + bool user_rule = false; /* * issue a reset on the routing module since routing rules point to @@ -1287,6 +1288,9 @@ int ipa2_reset_hdr(bool user_only) return -EFAULT; } + if (entry->ipacm_installed) + user_rule = true; + if (!user_only || entry->ipacm_installed) { if (entry->is_hdr_proc_ctx) { dma_unmap_single(ipa_ctx->pdev, @@ -1296,6 +1300,7 @@ int ipa2_reset_hdr(bool user_only) entry->proc_ctx = NULL; } list_del(&entry->link); + ipa_ctx->hdr_tbl.hdr_cnt--; entry->ref_cnt = 0; entry->cookie = 0; @@ -1321,6 +1326,13 @@ int ipa2_reset_hdr(bool user_only) list_del(&off_entry->link); kmem_cache_free(ipa_ctx->hdr_offset_cache, off_entry); + } else { + if (off_entry->offset + + ipa_hdr_bin_sz[off_entry->bin] > end) { + end = off_entry->offset + + ipa_hdr_bin_sz[off_entry->bin]; + IPADBG("replace end = %d\n", end); + } } } list_for_each_entry_safe(off_entry, off_next, @@ -1335,11 +1347,15 @@ int ipa2_reset_hdr(bool user_only) } } } - /* there is one header of size 8 */ - ipa_ctx->hdr_tbl.end = 8; - ipa_ctx->hdr_tbl.hdr_cnt = 1; + IPADBG("hdr_tbl.end = %d\n", end); + if (user_rule) { + ipa_ctx->hdr_tbl.end = end; + IPADBG("hdr_tbl.end = %d\n", end); + } IPADBG("reset hdr proc ctx\n"); + user_rule = false; + end = 0; list_for_each_entry_safe( ctx_entry, ctx_next, @@ -1352,9 +1368,13 @@ int ipa2_reset_hdr(bool user_only) return -EFAULT; } + if (entry->ipacm_installed) + user_rule = true; + if (!user_only || ctx_entry->ipacm_installed) { list_del(&ctx_entry->link); + ipa_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt--; ctx_entry->ref_cnt = 0; ctx_entry->cookie = 0; @@ -1375,6 +1395,14 @@ int ipa2_reset_hdr(bool user_only) kmem_cache_free( ipa_ctx->hdr_proc_ctx_offset_cache, ctx_off_entry); + } else { + if (ctx_off_entry->offset + + ipa_hdr_bin_sz[ctx_off_entry->bin] + > end) { + end = ctx_off_entry->offset + + ipa_hdr_bin_sz[ctx_off_entry->bin]; + IPADBG("replace hdr_proc as %d\n", end); + } } } list_for_each_entry_safe(ctx_off_entry, ctx_off_next, @@ -1390,8 +1418,12 @@ int ipa2_reset_hdr(bool user_only) } } } - ipa_ctx->hdr_proc_ctx_tbl.end = 0; - ipa_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt = 0; + + IPADBG("hdr_proc_tbl.end = %d\n", end); + if (user_rule) { + ipa_ctx->hdr_proc_ctx_tbl.end = end; + IPADBG("hdr_proc_tbl.end = %d\n", end); + } mutex_unlock(&ipa_ctx->lock); return 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index f10b2929916e..63e3f8578219 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -654,7 +654,6 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, return 0; } - int __ipa3_del_hdr(u32 hdr_hdl, bool by_user) { struct ipa3_hdr_entry *entry; @@ -994,7 +993,8 @@ int ipa3_reset_hdr(bool user_only) struct ipa_hdr_offset_entry *off_next; struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_entry; struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_next; - int i; + int i, end = 0; + bool user_rule = false; /* * issue a reset on the routing module since routing rules point to @@ -1032,6 +1032,9 @@ int ipa3_reset_hdr(bool user_only) return -EFAULT; } + if (entry->ipacm_installed) + user_rule = true; + if (!user_only || entry->ipacm_installed) { if (entry->is_hdr_proc_ctx) { dma_unmap_single(ipa3_ctx->pdev, @@ -1041,6 +1044,7 @@ int ipa3_reset_hdr(bool user_only) entry->proc_ctx = NULL; } list_del(&entry->link); + ipa3_ctx->hdr_tbl.hdr_cnt--; entry->ref_cnt = 0; entry->cookie = 0; @@ -1066,6 +1070,13 @@ int ipa3_reset_hdr(bool user_only) list_del(&off_entry->link); kmem_cache_free(ipa3_ctx->hdr_offset_cache, off_entry); + } else { + if (off_entry->offset + + ipa_hdr_bin_sz[off_entry->bin] > end) { + end = off_entry->offset + + ipa_hdr_bin_sz[off_entry->bin]; + IPADBG("replace end = %d\n", end); + } } } list_for_each_entry_safe(off_entry, off_next, @@ -1080,11 +1091,15 @@ int ipa3_reset_hdr(bool user_only) } } } - /* there is one header of size 8 */ - ipa3_ctx->hdr_tbl.end = 8; - ipa3_ctx->hdr_tbl.hdr_cnt = 1; + IPADBG("hdr_tbl.end = %d\n", end); + if (user_rule) { + ipa3_ctx->hdr_tbl.end = end; + IPADBG("hdr_tbl.end = %d\n", end); + } IPADBG("reset hdr proc ctx\n"); + user_rule = false; + end = 0; list_for_each_entry_safe( ctx_entry, ctx_next, @@ -1097,9 +1112,13 @@ int ipa3_reset_hdr(bool user_only) return -EFAULT; } + if (entry->ipacm_installed) + user_rule = true; + if (!user_only || ctx_entry->ipacm_installed) { list_del(&ctx_entry->link); + ipa3_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt--; ctx_entry->ref_cnt = 0; ctx_entry->cookie = 0; @@ -1120,6 +1139,14 @@ int ipa3_reset_hdr(bool user_only) kmem_cache_free( ipa3_ctx->hdr_proc_ctx_offset_cache, ctx_off_entry); + } else { + if (ctx_off_entry->offset + + ipa_hdr_bin_sz[ctx_off_entry->bin] + > end) { + end = ctx_off_entry->offset + + ipa_hdr_bin_sz[ctx_off_entry->bin]; + IPADBG("replace hdr_proc as %d\n", end); + } } } list_for_each_entry_safe(ctx_off_entry, ctx_off_next, @@ -1135,8 +1162,12 @@ int ipa3_reset_hdr(bool user_only) } } } - ipa3_ctx->hdr_proc_ctx_tbl.end = 0; - ipa3_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt = 0; + + IPADBG("hdr_proc_tbl.end = %d\n", end); + if (user_rule) { + ipa3_ctx->hdr_proc_ctx_tbl.end = end; + IPADBG("hdr_proc_tbl.end = %d\n", end); + } mutex_unlock(&ipa3_ctx->lock); return 0; |
