Loading drivers/platform/msm/ipa/ipa.c +137 −17 Original line number Original line Diff line number Diff line Loading @@ -65,6 +65,8 @@ #define IPA_Q6_CLEANUP_EXP_AGGR_MAX_CMDS \ #define IPA_Q6_CLEANUP_EXP_AGGR_MAX_CMDS \ (IPA_NUM_PIPES*2) \ (IPA_NUM_PIPES*2) \ #define IPA_SPS_PROD_TIMEOUT_MSEC 1000 #ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT #define IPA_IOC_ADD_HDR32 _IOWR(IPA_IOC_MAGIC, \ #define IPA_IOC_ADD_HDR32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_ADD_HDR, \ IPA_IOCTL_ADD_HDR, \ Loading Loading @@ -165,6 +167,13 @@ struct ipa_ioc_nat_alloc_mem32 { static void ipa_start_tag_process(struct work_struct *work); static void ipa_start_tag_process(struct work_struct *work); static DECLARE_WORK(ipa_tag_work, ipa_start_tag_process); static DECLARE_WORK(ipa_tag_work, ipa_start_tag_process); static void ipa_sps_process_irq(struct work_struct *work); static DECLARE_WORK(ipa_sps_process_irq_work, ipa_sps_process_irq); static void ipa_dec_clients_delayed(struct work_struct *work); static DECLARE_DELAYED_WORK(ipa_dec_clients_delayed_work, ipa_dec_clients_delayed); static struct ipa_plat_drv_res ipa_res = {0, }; static struct ipa_plat_drv_res ipa_res = {0, }; static struct of_device_id ipa_plat_drv_match[] = { static struct of_device_id ipa_plat_drv_match[] = { { { Loading Loading @@ -2444,6 +2453,37 @@ void ipa_suspend_handler(enum ipa_irq_type interrupt, } } } } static void ipa_sps_process_irq_schedule_rel(void) { ipa_ctx->sps_pm.res_rel_in_prog = true; queue_delayed_work(ipa_ctx->power_mgmt_wq, &ipa_dec_clients_delayed_work, msecs_to_jiffies(IPA_SPS_PROD_TIMEOUT_MSEC)); } static void ipa_sps_process_irq(struct work_struct *work) { unsigned long flags; int ret; /* request IPA clocks */ ipa_inc_client_enable_clks(); /* mark SPS resource as granted */ spin_lock_irqsave(&ipa_ctx->sps_pm.lock, flags); ipa_ctx->sps_pm.res_granted = true; IPADBG("IPA is ON, calling sps driver\n"); /* process bam irq */ ret = sps_bam_process_irq(ipa_ctx->bam_handle); if (ret) IPAERR("sps_process_eot_event failed %d\n", ret); /* release IPA clocks */ ipa_sps_process_irq_schedule_rel(); spin_unlock_irqrestore(&ipa_ctx->sps_pm.lock, flags); } static int apps_cons_release_resource(void) static int apps_cons_release_resource(void) { { return 0; return 0; Loading @@ -2454,7 +2494,24 @@ static int apps_cons_request_resource(void) return 0; return 0; } } static int ipa_create_apps_resource(void) static void ipa_dec_clients_delayed(struct work_struct *work) { unsigned long flags; bool dec_clients = false; spin_lock_irqsave(&ipa_ctx->sps_pm.lock, flags); /* check whether still need to decrease client usage */ if (ipa_ctx->sps_pm.res_rel_in_prog) { dec_clients = true; ipa_ctx->sps_pm.res_rel_in_prog = false; ipa_ctx->sps_pm.res_granted = false; } spin_unlock_irqrestore(&ipa_ctx->sps_pm.lock, flags); if (dec_clients) ipa_dec_client_disable_clks(); } int ipa_create_apps_resource(void) { { struct ipa_rm_create_params apps_cons_create_params; struct ipa_rm_create_params apps_cons_create_params; struct ipa_rm_perf_profile profile; struct ipa_rm_perf_profile profile; Loading @@ -2476,6 +2533,63 @@ static int ipa_create_apps_resource(void) return result; return result; } } /** * sps_event_cb() - Handles SPS events * @event: event to handle * @param: event-specific paramer * * This callback support the following events: * - SPS_CALLBACK_BAM_RES_REQ: request resource * Try to increase IPA active client counter. * In case this can be done synchronously then * return in *param true. Otherwise return false in *param * and request IPA clocks. Later call to * sps_bam_process_irq to process the pending irq. * - SPS_CALLBACK_BAM_RES_REL: release resource * schedule a delayed work for decreasing IPA active client * counter. In case that during this time another request arrives, * this work will be canceled. */ static void sps_event_cb(enum sps_callback_case event, void *param) { unsigned long flags; spin_lock_irqsave(&ipa_ctx->sps_pm.lock, flags); switch (event) { case SPS_CALLBACK_BAM_RES_REQ: { bool *ready = (bool *)param; /* make sure no release will happen */ cancel_delayed_work(&ipa_dec_clients_delayed_work); ipa_ctx->sps_pm.res_rel_in_prog = false; if (ipa_ctx->sps_pm.res_granted) { *ready = true; } else { if (ipa_inc_client_enable_clks_no_block() == 0) { ipa_ctx->sps_pm.res_granted = true; *ready = true; } else { queue_work(ipa_ctx->power_mgmt_wq, &ipa_sps_process_irq_work); *ready = false; } } break; } case SPS_CALLBACK_BAM_RES_REL: ipa_sps_process_irq_schedule_rel(); break; default: IPADBG("unsupported event %d\n", event); } spin_unlock_irqrestore(&ipa_ctx->sps_pm.lock, flags); } /** /** * ipa_init() - Initialize the IPA Driver * ipa_init() - Initialize the IPA Driver * @resource_p: contain platform specific values from DST file * @resource_p: contain platform specific values from DST file Loading Loading @@ -2617,6 +2731,23 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, goto fail_init_hw; goto fail_init_hw; } } mutex_init(&ipa_ctx->ipa_active_clients.mutex); spin_lock_init(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.cnt = 1; /* Create workqueue for power management */ ipa_ctx->power_mgmt_wq = create_singlethread_workqueue("ipa_power_mgmt"); if (!ipa_ctx->power_mgmt_wq) { IPAERR("failed to create wq\n"); result = -ENOMEM; goto fail_init_hw; } spin_lock_init(&ipa_ctx->sps_pm.lock); ipa_ctx->sps_pm.res_granted = false; ipa_ctx->sps_pm.res_rel_in_prog = false; /* register IPA with SPS driver */ /* register IPA with SPS driver */ bam_props.phys_addr = resource_p->bam_mem_base; bam_props.phys_addr = resource_p->bam_mem_base; bam_props.virt_size = resource_p->bam_mem_size; bam_props.virt_size = resource_p->bam_mem_size; Loading @@ -2626,13 +2757,15 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, bam_props.event_threshold = IPA_EVENT_THRESHOLD; bam_props.event_threshold = IPA_EVENT_THRESHOLD; bam_props.options |= (SPS_BAM_NO_LOCAL_CLK_GATING | bam_props.options |= (SPS_BAM_NO_LOCAL_CLK_GATING | SPS_BAM_OPT_IRQ_WAKEUP); SPS_BAM_OPT_IRQ_WAKEUP); bam_props.options |= SPS_BAM_RES_CONFIRM; bam_props.ee = resource_p->ee; bam_props.ee = resource_p->ee; bam_props.callback = sps_event_cb; result = sps_register_bam_device(&bam_props, &ipa_ctx->bam_handle); result = sps_register_bam_device(&bam_props, &ipa_ctx->bam_handle); if (result) { if (result) { IPAERR(":bam register err.\n"); IPAERR(":bam register err.\n"); result = -EPROBE_DEFER; result = -EPROBE_DEFER; goto fail_init_hw; goto fail_register_bam_device; } } IPADBG("IPA BAM is registered\n"); IPADBG("IPA BAM is registered\n"); Loading Loading @@ -2756,10 +2889,6 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, idr_init(&ipa_ctx->ipa_idr); idr_init(&ipa_ctx->ipa_idr); spin_lock_init(&ipa_ctx->idr_lock); spin_lock_init(&ipa_ctx->idr_lock); mutex_init(&ipa_ctx->ipa_active_clients.mutex); spin_lock_init(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.cnt = 1; /* wlan related member */ /* wlan related member */ memset(&ipa_ctx->wc_memb, 0, sizeof(ipa_ctx->wc_memb)); memset(&ipa_ctx->wc_memb, 0, sizeof(ipa_ctx->wc_memb)); spin_lock_init(&ipa_ctx->wc_memb.wlan_spinlock); spin_lock_init(&ipa_ctx->wc_memb.wlan_spinlock); Loading Loading @@ -2837,15 +2966,6 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, MAJOR(ipa_ctx->dev_num), MAJOR(ipa_ctx->dev_num), MINOR(ipa_ctx->dev_num)); MINOR(ipa_ctx->dev_num)); /* Create workqueue for power management */ ipa_ctx->power_mgmt_wq = create_singlethread_workqueue("ipa_power_mgmt"); if (!ipa_ctx->power_mgmt_wq) { IPAERR("failed to create wq\n"); result = -ENOMEM; goto fail_power_mgmt_wq; } /* Initialize IPA RM (resource manager) */ /* Initialize IPA RM (resource manager) */ result = ipa_rm_initialize(); result = ipa_rm_initialize(); if (result) { if (result) { Loading Loading @@ -2918,8 +3038,6 @@ fail_ipa_interrupts_init: fail_create_apps_resource: fail_create_apps_resource: ipa_rm_exit(); ipa_rm_exit(); fail_ipa_rm_init: fail_ipa_rm_init: destroy_workqueue(ipa_ctx->power_mgmt_wq); fail_power_mgmt_wq: cdev_del(&ipa_ctx->cdev); cdev_del(&ipa_ctx->cdev); fail_cdev_add: fail_cdev_add: device_destroy(ipa_ctx->class, ipa_ctx->dev_num); device_destroy(ipa_ctx->class, ipa_ctx->dev_num); Loading Loading @@ -2957,6 +3075,8 @@ fail_rt_rule_cache: kmem_cache_destroy(ipa_ctx->flt_rule_cache); kmem_cache_destroy(ipa_ctx->flt_rule_cache); fail_flt_rule_cache: fail_flt_rule_cache: sps_deregister_bam_device(ipa_ctx->bam_handle); sps_deregister_bam_device(ipa_ctx->bam_handle); fail_register_bam_device: destroy_workqueue(ipa_ctx->power_mgmt_wq); fail_init_hw: fail_init_hw: iounmap(ipa_ctx->mmio); iounmap(ipa_ctx->mmio); fail_remap: fail_remap: Loading drivers/platform/msm/ipa/ipa_i.h +14 −0 Original line number Original line Diff line number Diff line Loading @@ -664,6 +664,18 @@ struct ipa_uc_ctx { struct IpaHwStatsWDIInfoData_t *wdi_uc_stats_mmio; struct IpaHwStatsWDIInfoData_t *wdi_uc_stats_mmio; }; }; /** * struct ipa_sps_pm - SPS power management related members * @lock: lock for ensuring atomic operations * @res_granted: true if SPS requested IPA resource and IPA granted it * @res_rel_in_prog: true if releasing IPA resource is in progress */ struct ipa_sps_pm { spinlock_t lock; bool res_granted; bool res_rel_in_prog; }; /** /** * struct ipa_context - IPA context * struct ipa_context - IPA context * @class: pointer to the struct class * @class: pointer to the struct class Loading Loading @@ -711,6 +723,7 @@ struct ipa_uc_ctx { * @power_mgmt_wq: workqueue for power management * @power_mgmt_wq: workqueue for power management * @tag_process_before_gating: indicates whether to start tag process before * @tag_process_before_gating: indicates whether to start tag process before * gating IPA clocks * gating IPA clocks * @sps_pm: sps power management related information * @pipe_mem_pool: pipe memory pool * @pipe_mem_pool: pipe memory pool * @dma_pool: special purpose DMA pool * @dma_pool: special purpose DMA pool * @ipa_active_clients: structure for reference counting connected IPA clients * @ipa_active_clients: structure for reference counting connected IPA clients Loading Loading @@ -772,6 +785,7 @@ struct ipa_context { struct ipa_active_clients ipa_active_clients; struct ipa_active_clients ipa_active_clients; struct workqueue_struct *power_mgmt_wq; struct workqueue_struct *power_mgmt_wq; bool tag_process_before_gating; bool tag_process_before_gating; struct ipa_sps_pm sps_pm; u32 clnt_hdl_cmd; u32 clnt_hdl_cmd; u32 clnt_hdl_data_in; u32 clnt_hdl_data_in; u32 clnt_hdl_data_out; u32 clnt_hdl_data_out; Loading Loading
drivers/platform/msm/ipa/ipa.c +137 −17 Original line number Original line Diff line number Diff line Loading @@ -65,6 +65,8 @@ #define IPA_Q6_CLEANUP_EXP_AGGR_MAX_CMDS \ #define IPA_Q6_CLEANUP_EXP_AGGR_MAX_CMDS \ (IPA_NUM_PIPES*2) \ (IPA_NUM_PIPES*2) \ #define IPA_SPS_PROD_TIMEOUT_MSEC 1000 #ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT #define IPA_IOC_ADD_HDR32 _IOWR(IPA_IOC_MAGIC, \ #define IPA_IOC_ADD_HDR32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_ADD_HDR, \ IPA_IOCTL_ADD_HDR, \ Loading Loading @@ -165,6 +167,13 @@ struct ipa_ioc_nat_alloc_mem32 { static void ipa_start_tag_process(struct work_struct *work); static void ipa_start_tag_process(struct work_struct *work); static DECLARE_WORK(ipa_tag_work, ipa_start_tag_process); static DECLARE_WORK(ipa_tag_work, ipa_start_tag_process); static void ipa_sps_process_irq(struct work_struct *work); static DECLARE_WORK(ipa_sps_process_irq_work, ipa_sps_process_irq); static void ipa_dec_clients_delayed(struct work_struct *work); static DECLARE_DELAYED_WORK(ipa_dec_clients_delayed_work, ipa_dec_clients_delayed); static struct ipa_plat_drv_res ipa_res = {0, }; static struct ipa_plat_drv_res ipa_res = {0, }; static struct of_device_id ipa_plat_drv_match[] = { static struct of_device_id ipa_plat_drv_match[] = { { { Loading Loading @@ -2444,6 +2453,37 @@ void ipa_suspend_handler(enum ipa_irq_type interrupt, } } } } static void ipa_sps_process_irq_schedule_rel(void) { ipa_ctx->sps_pm.res_rel_in_prog = true; queue_delayed_work(ipa_ctx->power_mgmt_wq, &ipa_dec_clients_delayed_work, msecs_to_jiffies(IPA_SPS_PROD_TIMEOUT_MSEC)); } static void ipa_sps_process_irq(struct work_struct *work) { unsigned long flags; int ret; /* request IPA clocks */ ipa_inc_client_enable_clks(); /* mark SPS resource as granted */ spin_lock_irqsave(&ipa_ctx->sps_pm.lock, flags); ipa_ctx->sps_pm.res_granted = true; IPADBG("IPA is ON, calling sps driver\n"); /* process bam irq */ ret = sps_bam_process_irq(ipa_ctx->bam_handle); if (ret) IPAERR("sps_process_eot_event failed %d\n", ret); /* release IPA clocks */ ipa_sps_process_irq_schedule_rel(); spin_unlock_irqrestore(&ipa_ctx->sps_pm.lock, flags); } static int apps_cons_release_resource(void) static int apps_cons_release_resource(void) { { return 0; return 0; Loading @@ -2454,7 +2494,24 @@ static int apps_cons_request_resource(void) return 0; return 0; } } static int ipa_create_apps_resource(void) static void ipa_dec_clients_delayed(struct work_struct *work) { unsigned long flags; bool dec_clients = false; spin_lock_irqsave(&ipa_ctx->sps_pm.lock, flags); /* check whether still need to decrease client usage */ if (ipa_ctx->sps_pm.res_rel_in_prog) { dec_clients = true; ipa_ctx->sps_pm.res_rel_in_prog = false; ipa_ctx->sps_pm.res_granted = false; } spin_unlock_irqrestore(&ipa_ctx->sps_pm.lock, flags); if (dec_clients) ipa_dec_client_disable_clks(); } int ipa_create_apps_resource(void) { { struct ipa_rm_create_params apps_cons_create_params; struct ipa_rm_create_params apps_cons_create_params; struct ipa_rm_perf_profile profile; struct ipa_rm_perf_profile profile; Loading @@ -2476,6 +2533,63 @@ static int ipa_create_apps_resource(void) return result; return result; } } /** * sps_event_cb() - Handles SPS events * @event: event to handle * @param: event-specific paramer * * This callback support the following events: * - SPS_CALLBACK_BAM_RES_REQ: request resource * Try to increase IPA active client counter. * In case this can be done synchronously then * return in *param true. Otherwise return false in *param * and request IPA clocks. Later call to * sps_bam_process_irq to process the pending irq. * - SPS_CALLBACK_BAM_RES_REL: release resource * schedule a delayed work for decreasing IPA active client * counter. In case that during this time another request arrives, * this work will be canceled. */ static void sps_event_cb(enum sps_callback_case event, void *param) { unsigned long flags; spin_lock_irqsave(&ipa_ctx->sps_pm.lock, flags); switch (event) { case SPS_CALLBACK_BAM_RES_REQ: { bool *ready = (bool *)param; /* make sure no release will happen */ cancel_delayed_work(&ipa_dec_clients_delayed_work); ipa_ctx->sps_pm.res_rel_in_prog = false; if (ipa_ctx->sps_pm.res_granted) { *ready = true; } else { if (ipa_inc_client_enable_clks_no_block() == 0) { ipa_ctx->sps_pm.res_granted = true; *ready = true; } else { queue_work(ipa_ctx->power_mgmt_wq, &ipa_sps_process_irq_work); *ready = false; } } break; } case SPS_CALLBACK_BAM_RES_REL: ipa_sps_process_irq_schedule_rel(); break; default: IPADBG("unsupported event %d\n", event); } spin_unlock_irqrestore(&ipa_ctx->sps_pm.lock, flags); } /** /** * ipa_init() - Initialize the IPA Driver * ipa_init() - Initialize the IPA Driver * @resource_p: contain platform specific values from DST file * @resource_p: contain platform specific values from DST file Loading Loading @@ -2617,6 +2731,23 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, goto fail_init_hw; goto fail_init_hw; } } mutex_init(&ipa_ctx->ipa_active_clients.mutex); spin_lock_init(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.cnt = 1; /* Create workqueue for power management */ ipa_ctx->power_mgmt_wq = create_singlethread_workqueue("ipa_power_mgmt"); if (!ipa_ctx->power_mgmt_wq) { IPAERR("failed to create wq\n"); result = -ENOMEM; goto fail_init_hw; } spin_lock_init(&ipa_ctx->sps_pm.lock); ipa_ctx->sps_pm.res_granted = false; ipa_ctx->sps_pm.res_rel_in_prog = false; /* register IPA with SPS driver */ /* register IPA with SPS driver */ bam_props.phys_addr = resource_p->bam_mem_base; bam_props.phys_addr = resource_p->bam_mem_base; bam_props.virt_size = resource_p->bam_mem_size; bam_props.virt_size = resource_p->bam_mem_size; Loading @@ -2626,13 +2757,15 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, bam_props.event_threshold = IPA_EVENT_THRESHOLD; bam_props.event_threshold = IPA_EVENT_THRESHOLD; bam_props.options |= (SPS_BAM_NO_LOCAL_CLK_GATING | bam_props.options |= (SPS_BAM_NO_LOCAL_CLK_GATING | SPS_BAM_OPT_IRQ_WAKEUP); SPS_BAM_OPT_IRQ_WAKEUP); bam_props.options |= SPS_BAM_RES_CONFIRM; bam_props.ee = resource_p->ee; bam_props.ee = resource_p->ee; bam_props.callback = sps_event_cb; result = sps_register_bam_device(&bam_props, &ipa_ctx->bam_handle); result = sps_register_bam_device(&bam_props, &ipa_ctx->bam_handle); if (result) { if (result) { IPAERR(":bam register err.\n"); IPAERR(":bam register err.\n"); result = -EPROBE_DEFER; result = -EPROBE_DEFER; goto fail_init_hw; goto fail_register_bam_device; } } IPADBG("IPA BAM is registered\n"); IPADBG("IPA BAM is registered\n"); Loading Loading @@ -2756,10 +2889,6 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, idr_init(&ipa_ctx->ipa_idr); idr_init(&ipa_ctx->ipa_idr); spin_lock_init(&ipa_ctx->idr_lock); spin_lock_init(&ipa_ctx->idr_lock); mutex_init(&ipa_ctx->ipa_active_clients.mutex); spin_lock_init(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.cnt = 1; /* wlan related member */ /* wlan related member */ memset(&ipa_ctx->wc_memb, 0, sizeof(ipa_ctx->wc_memb)); memset(&ipa_ctx->wc_memb, 0, sizeof(ipa_ctx->wc_memb)); spin_lock_init(&ipa_ctx->wc_memb.wlan_spinlock); spin_lock_init(&ipa_ctx->wc_memb.wlan_spinlock); Loading Loading @@ -2837,15 +2966,6 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, MAJOR(ipa_ctx->dev_num), MAJOR(ipa_ctx->dev_num), MINOR(ipa_ctx->dev_num)); MINOR(ipa_ctx->dev_num)); /* Create workqueue for power management */ ipa_ctx->power_mgmt_wq = create_singlethread_workqueue("ipa_power_mgmt"); if (!ipa_ctx->power_mgmt_wq) { IPAERR("failed to create wq\n"); result = -ENOMEM; goto fail_power_mgmt_wq; } /* Initialize IPA RM (resource manager) */ /* Initialize IPA RM (resource manager) */ result = ipa_rm_initialize(); result = ipa_rm_initialize(); if (result) { if (result) { Loading Loading @@ -2918,8 +3038,6 @@ fail_ipa_interrupts_init: fail_create_apps_resource: fail_create_apps_resource: ipa_rm_exit(); ipa_rm_exit(); fail_ipa_rm_init: fail_ipa_rm_init: destroy_workqueue(ipa_ctx->power_mgmt_wq); fail_power_mgmt_wq: cdev_del(&ipa_ctx->cdev); cdev_del(&ipa_ctx->cdev); fail_cdev_add: fail_cdev_add: device_destroy(ipa_ctx->class, ipa_ctx->dev_num); device_destroy(ipa_ctx->class, ipa_ctx->dev_num); Loading Loading @@ -2957,6 +3075,8 @@ fail_rt_rule_cache: kmem_cache_destroy(ipa_ctx->flt_rule_cache); kmem_cache_destroy(ipa_ctx->flt_rule_cache); fail_flt_rule_cache: fail_flt_rule_cache: sps_deregister_bam_device(ipa_ctx->bam_handle); sps_deregister_bam_device(ipa_ctx->bam_handle); fail_register_bam_device: destroy_workqueue(ipa_ctx->power_mgmt_wq); fail_init_hw: fail_init_hw: iounmap(ipa_ctx->mmio); iounmap(ipa_ctx->mmio); fail_remap: fail_remap: Loading
drivers/platform/msm/ipa/ipa_i.h +14 −0 Original line number Original line Diff line number Diff line Loading @@ -664,6 +664,18 @@ struct ipa_uc_ctx { struct IpaHwStatsWDIInfoData_t *wdi_uc_stats_mmio; struct IpaHwStatsWDIInfoData_t *wdi_uc_stats_mmio; }; }; /** * struct ipa_sps_pm - SPS power management related members * @lock: lock for ensuring atomic operations * @res_granted: true if SPS requested IPA resource and IPA granted it * @res_rel_in_prog: true if releasing IPA resource is in progress */ struct ipa_sps_pm { spinlock_t lock; bool res_granted; bool res_rel_in_prog; }; /** /** * struct ipa_context - IPA context * struct ipa_context - IPA context * @class: pointer to the struct class * @class: pointer to the struct class Loading Loading @@ -711,6 +723,7 @@ struct ipa_uc_ctx { * @power_mgmt_wq: workqueue for power management * @power_mgmt_wq: workqueue for power management * @tag_process_before_gating: indicates whether to start tag process before * @tag_process_before_gating: indicates whether to start tag process before * gating IPA clocks * gating IPA clocks * @sps_pm: sps power management related information * @pipe_mem_pool: pipe memory pool * @pipe_mem_pool: pipe memory pool * @dma_pool: special purpose DMA pool * @dma_pool: special purpose DMA pool * @ipa_active_clients: structure for reference counting connected IPA clients * @ipa_active_clients: structure for reference counting connected IPA clients Loading Loading @@ -772,6 +785,7 @@ struct ipa_context { struct ipa_active_clients ipa_active_clients; struct ipa_active_clients ipa_active_clients; struct workqueue_struct *power_mgmt_wq; struct workqueue_struct *power_mgmt_wq; bool tag_process_before_gating; bool tag_process_before_gating; struct ipa_sps_pm sps_pm; u32 clnt_hdl_cmd; u32 clnt_hdl_cmd; u32 clnt_hdl_data_in; u32 clnt_hdl_data_in; u32 clnt_hdl_data_out; u32 clnt_hdl_data_out; Loading