Loading drivers/platform/msm/ipa/ipa_rm.c +29 −29 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -42,7 +42,7 @@ static const char *resource_name_to_str[IPA_RM_RESOURCE_MAX] = { struct ipa_rm_context_type { struct ipa_rm_dep_graph *dep_graph; struct workqueue_struct *ipa_rm_wq; rwlock_t lock; spinlock_t ipa_rm_lock; }; static struct ipa_rm_context_type *ipa_rm_ctx; Loading @@ -54,8 +54,8 @@ static struct ipa_rm_context_type *ipa_rm_ctx; * Returns: 0 on success, negative on failure * * This function is called by IPA RM client to initialize client's resources. * This API should be called before any other IPA RM API * on given resource name. * This API should be called before any other IPA RM API on a given resource * name. * */ int ipa_rm_create_resource(struct ipa_rm_create_params *create_params) Loading @@ -69,7 +69,7 @@ int ipa_rm_create_resource(struct ipa_rm_create_params *create_params) } IPA_RM_DBG("%s\n", ipa_rm_resource_str(create_params->name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, create_params->name, &resource) == 0) { Loading @@ -90,7 +90,7 @@ int ipa_rm_create_resource(struct ipa_rm_create_params *create_params) goto bail; } bail: write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -112,7 +112,7 @@ int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name) int result; IPA_RM_DBG("%s\n", ipa_rm_resource_str(resource_name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -132,7 +132,7 @@ int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name) goto bail; } bail: write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -157,12 +157,12 @@ int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); result = ipa_rm_dep_graph_add_dependency( ipa_rm_ctx->dep_graph, resource_name, depends_on_name); write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -188,12 +188,12 @@ int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name, IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); result = ipa_rm_dep_graph_delete_dependency( ipa_rm_ctx->dep_graph, resource_name, depends_on_name); write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -218,7 +218,7 @@ int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name) IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -230,7 +230,7 @@ int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name) (struct ipa_rm_resource_prod *)resource); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return result; } Loading @@ -254,7 +254,7 @@ int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name) IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -266,7 +266,7 @@ int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name) (struct ipa_rm_resource_prod *)resource); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return result; } Loading Loading @@ -294,7 +294,7 @@ int ipa_rm_register(enum ipa_rm_resource_name resource_name, IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -307,7 +307,7 @@ int ipa_rm_register(enum ipa_rm_resource_name resource_name, reg_params, true); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading Loading @@ -336,7 +336,7 @@ int ipa_rm_deregister(enum ipa_rm_resource_name resource_name, IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -348,7 +348,7 @@ int ipa_rm_deregister(enum ipa_rm_resource_name resource_name, (struct ipa_rm_resource_prod *)resource, reg_params); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading Loading @@ -407,35 +407,35 @@ static void ipa_rm_wq_handler(struct work_struct *work) IPA_RM_ERR("resource is not PROD\n"); return; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, ipa_rm_work->resource_name, &resource) != 0){ IPA_RM_ERR("resource does not exists\n"); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return; } ipa_rm_resource_producer_notify_clients( (struct ipa_rm_resource_prod *)resource, ipa_rm_work->event, ipa_rm_work->notify_registered_only); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); break; case IPA_RM_WQ_NOTIFY_CONS: break; case IPA_RM_WQ_RESOURCE_CB: read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, ipa_rm_work->resource_name, &resource) != 0){ IPA_RM_ERR("resource does not exists\n"); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return; } ipa_rm_resource_consumer_handle_cb( (struct ipa_rm_resource_cons *)resource, ipa_rm_work->event); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); break; default: break; Loading Loading @@ -501,7 +501,7 @@ int ipa_rm_initialize(void) IPA_RM_ERR("create dependency graph failed\n"); goto graph_alloc_fail; } rwlock_init(&ipa_rm_ctx->lock); spin_lock_init(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("SUCCESS\n"); return 0; Loading Loading @@ -531,7 +531,7 @@ int ipa_rm_stat(char *buf, int size) if (!buf || size < 0) goto bail; read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); for (i = 0; i < IPA_RM_RESOURCE_PROD_MAX; ++i) { result = ipa_rm_dep_graph_get_resource( ipa_rm_ctx->dep_graph, Loading @@ -548,7 +548,7 @@ int ipa_rm_stat(char *buf, int size) } result = cnt; bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return result; } Loading drivers/platform/msm/ipa/ipa_rm_peers_list.c +8 −16 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -65,7 +65,7 @@ int ipa_rm_peers_list_create(int max_peers, result = -ENOMEM; goto bail; } rwlock_init(&(*peers_list)->peers_lock); (*peers_list)->max_peers = max_peers; (*peers_list)->peers = kzalloc((*peers_list)->max_peers * sizeof(struct ipa_rm_resource *), GFP_KERNEL); Loading Loading @@ -109,11 +109,10 @@ void ipa_rm_peers_list_remove_peer( { if (!peers_list) return; write_lock(&peers_list->peers_lock); peers_list->peers[ipa_rm_peers_list_get_resource_index( resource_name)] = NULL; peers_list->peers_count--; write_unlock(&peers_list->peers_lock); } /** Loading @@ -129,12 +128,11 @@ void ipa_rm_peers_list_add_peer( { if (!peers_list || !resource) return; read_lock(&peers_list->peers_lock); peers_list->peers[ipa_rm_peers_list_get_resource_index( resource->name)] = resource; peers_list->peers_count++; read_unlock(&peers_list->peers_lock); } /** Loading @@ -150,10 +148,9 @@ bool ipa_rm_peers_list_is_empty(struct ipa_rm_peers_list *peers_list) bool result = true; if (!peers_list) goto bail; read_lock(&peers_list->peers_lock); if (peers_list->peers_count > 0) result = false; read_unlock(&peers_list->peers_lock); bail: return result; } Loading @@ -172,10 +169,9 @@ bool ipa_rm_peers_list_has_last_peer( bool result = false; if (!peers_list) goto bail; read_lock(&peers_list->peers_lock); if (peers_list->peers_count == 1) result = true; read_unlock(&peers_list->peers_lock); bail: return result; } Loading @@ -200,17 +196,14 @@ bool ipa_rm_peers_list_check_dependency( bool result = false; if (!resource_peers || !depends_on_peers) return result; read_lock(&resource_peers->peers_lock); if (resource_peers->peers[ipa_rm_peers_list_get_resource_index( depends_on_name)] != NULL) result = true; read_unlock(&resource_peers->peers_lock); read_lock(&depends_on_peers->peers_lock); if (depends_on_peers->peers[ipa_rm_peers_list_get_resource_index( resource_name)] != NULL) result = true; read_unlock(&depends_on_peers->peers_lock); return result; } Loading @@ -229,9 +222,8 @@ struct ipa_rm_resource *ipa_rm_peers_list_get_resource(int resource_index, struct ipa_rm_resource *result = NULL; if (!ipa_rm_peers_list_check_index(resource_index, resource_peers)) goto bail; read_lock(&resource_peers->peers_lock); result = resource_peers->peers[resource_index]; read_unlock(&resource_peers->peers_lock); bail: return result; } Loading drivers/platform/msm/ipa/ipa_rm_peers_list.h +1 −3 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -21,13 +21,11 @@ * in case of producer or list of dependencies in case of consumer * @max_peers: maximum number of peers for this resource * @peers_count: actual number of peers for this resource * @peers_lock: RW lock for peers container */ struct ipa_rm_peers_list { struct ipa_rm_resource **peers; int max_peers; int peers_count; rwlock_t peers_lock; }; int ipa_rm_peers_list_create(int max_peers, Loading drivers/platform/msm/ipa/ipa_rm_resource.c +22 −129 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -80,9 +80,7 @@ static int ipa_rm_resource_consumer_request( { int result = 0; int driver_result; unsigned long flags; spin_lock_irqsave(&consumer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); Loading @@ -93,11 +91,9 @@ static int ipa_rm_resource_consumer_request( enum ipa_rm_resource_state prev_state = consumer->resource.state; consumer->resource.state = IPA_RM_REQUEST_IN_PROGRESS; spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("calling driver CB\n"); driver_result = consumer->request_resource(); IPA_RM_DBG("driver CB returned with %d\n", driver_result); spin_lock_irqsave(&consumer->resource.state_lock, flags); if (driver_result == 0) consumer->resource.state = IPA_RM_GRANTED; else if (driver_result != -EINPROGRESS) { Loading @@ -122,7 +118,6 @@ bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("EXIT with %d\n", result); return result; } Loading @@ -132,10 +127,8 @@ static int ipa_rm_resource_consumer_release( { int result = 0; int driver_result; unsigned long flags; enum ipa_rm_resource_state save_state; spin_lock_irqsave(&consumer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); Loading @@ -149,14 +142,10 @@ static int ipa_rm_resource_consumer_release( if (consumer->usage_count == 0) { save_state = consumer->resource.state; consumer->resource.state = IPA_RM_RELEASE_IN_PROGRESS; spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("calling driver CB\n"); driver_result = consumer->release_resource(); IPA_RM_DBG("driver CB returned with %d\n", driver_result); spin_lock_irqsave(&consumer->resource.state_lock, flags); if (driver_result == 0) consumer->resource.state = IPA_RM_RELEASED; else if (driver_result != -EINPROGRESS) Loading @@ -177,7 +166,6 @@ bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("EXIT with %d\n", result); return result; } Loading @@ -195,50 +183,24 @@ void ipa_rm_resource_producer_notify_clients( enum ipa_rm_event event, bool notify_registered_only) { struct ipa_rm_notification_info *reg_info, *reg_info_cloned; struct list_head *pos, *q; LIST_HEAD(cloned_list); struct ipa_rm_notification_info *reg_info; IPA_RM_DBG("%s event: %d notify_registered_only: %d\n", ipa_rm_resource_str(producer->resource.name), event, notify_registered_only); read_lock(&producer->event_listeners_lock); list_for_each(pos, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, link); list_for_each_entry(reg_info, &(producer->event_listeners), link) { if (notify_registered_only && !reg_info->explicit) continue; reg_info_cloned = kzalloc(sizeof(*reg_info_cloned), GFP_KERNEL); if (!reg_info_cloned) { IPA_RM_ERR("No memory\n"); goto clone_list_failed; } reg_info_cloned->reg_params.notify_cb = reg_info->reg_params.notify_cb; reg_info_cloned->reg_params.user_data = reg_info->reg_params.user_data; list_add(®_info_cloned->link, &cloned_list); } read_unlock(&producer->event_listeners_lock); list_for_each_safe(pos, q, &cloned_list) { reg_info = list_entry(pos, struct ipa_rm_notification_info, link); IPA_RM_DBG("Notifying %s event: %d\n", ipa_rm_resource_str(producer->resource.name), event); reg_info->reg_params.notify_cb( reg_info->reg_params.user_data, reg_info->reg_params.notify_cb(reg_info->reg_params.user_data, event, 0); IPA_RM_DBG("back from client CB\n"); list_del(pos); kfree(reg_info); } return; clone_list_failed: read_unlock(&producer->event_listeners_lock); } static int ipa_rm_resource_producer_create(struct ipa_rm_resource **resource, Loading @@ -253,7 +215,7 @@ static int ipa_rm_resource_producer_create(struct ipa_rm_resource **resource, result = -ENOMEM; goto bail; } rwlock_init(&(*producer)->event_listeners_lock); INIT_LIST_HEAD(&((*producer)->event_listeners)); result = ipa_rm_resource_producer_register(*producer, &(create_params->reg_params), Loading @@ -277,7 +239,7 @@ static void ipa_rm_resource_producer_delete( { struct ipa_rm_notification_info *reg_info; struct list_head *pos, *q; write_lock(&producer->event_listeners_lock); list_for_each_safe(pos, q, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, Loading @@ -285,7 +247,6 @@ static void ipa_rm_resource_producer_delete( list_del(pos); kfree(reg_info); } write_unlock(&producer->event_listeners_lock); } static int ipa_rm_resource_consumer_create(struct ipa_rm_resource **resource, Loading Loading @@ -361,7 +322,6 @@ int ipa_rm_resource_create( } (*resource)->name = create_params->name; (*resource)->state = IPA_RM_RELEASED; spin_lock_init(&((*resource)->state_lock)); goto bail; peers_alloc_fail: ipa_rm_resource_delete(*resource); Loading @@ -378,8 +338,11 @@ bail: */ int ipa_rm_resource_delete(struct ipa_rm_resource *resource) { struct ipa_rm_resource *consumer, *producer; int peers_index, result = 0, list_size; struct ipa_rm_resource *consumer; struct ipa_rm_resource *producer; int peers_index; int result = 0; int list_size; IPA_RM_DBG("ipa_rm_resource_delete ENTER with resource %d\n", resource->name); Loading Loading @@ -452,7 +415,7 @@ int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer, result = -EPERM; goto bail; } read_lock(&producer->event_listeners_lock); list_for_each(pos, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, Loading @@ -461,12 +424,11 @@ int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer, reg_params->notify_cb) { IPA_RM_ERR("already registered\n"); result = -EPERM; read_unlock(&producer->event_listeners_lock); goto bail; } } read_unlock(&producer->event_listeners_lock); reg_info = kzalloc(sizeof(*reg_info), GFP_KERNEL); if (reg_info == NULL) { IPA_RM_ERR("no mem\n"); Loading @@ -477,9 +439,7 @@ int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer, reg_info->reg_params.notify_cb = reg_params->notify_cb; reg_info->explicit = explicit; INIT_LIST_HEAD(®_info->link); write_lock(&producer->event_listeners_lock); list_add(®_info->link, &producer->event_listeners); write_unlock(&producer->event_listeners_lock); bail: return result; } Loading @@ -506,7 +466,7 @@ int ipa_rm_resource_producer_deregister(struct ipa_rm_resource_prod *producer, IPA_RM_ERR("invalid params\n"); return -EINVAL; } write_lock(&producer->event_listeners_lock); list_for_each_safe(pos, q, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, Loading @@ -518,10 +478,8 @@ int ipa_rm_resource_producer_deregister(struct ipa_rm_resource_prod *producer, result = 0; goto bail; } } bail: write_unlock(&producer->event_listeners_lock); return result; } Loading @@ -537,7 +495,6 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, struct ipa_rm_resource *depends_on) { int result = 0; unsigned long flags; int consumer_result; if (!resource || !depends_on) { IPA_RM_ERR("invalid params\n"); Loading @@ -552,7 +509,6 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, } ipa_rm_peers_list_add_peer(resource->peers_list, depends_on); ipa_rm_peers_list_add_peer(depends_on->peers_list, resource); spin_lock_irqsave(&resource->state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(resource->name), resource->state); switch (resource->state) { Loading @@ -566,10 +522,8 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, resource->state = IPA_RM_REQUEST_IN_PROGRESS; ((struct ipa_rm_resource_prod *) resource)->pending_request++; spin_unlock_irqrestore(&resource->state_lock, flags); consumer_result = ipa_rm_resource_consumer_request( (struct ipa_rm_resource_cons *)depends_on); spin_lock_irqsave(&resource->state_lock, flags); if (consumer_result != -EINPROGRESS) { resource->state = prev_state; ((struct ipa_rm_resource_prod *) Loading @@ -586,7 +540,6 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(resource->name), resource->state); spin_unlock_irqrestore(&resource->state_lock, flags); IPA_RM_DBG("EXIT with %d\n", result); return result; } Loading @@ -605,8 +558,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, struct ipa_rm_resource *depends_on) { int result = 0; unsigned long flags; unsigned long consumer_flags; bool state_changed = false; bool release_consumer = false; enum ipa_rm_event evt; Loading @@ -621,7 +572,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, IPA_RM_ERR("dependency does not exist\n"); return -EINVAL; } spin_lock_irqsave(&resource->state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(resource->name), resource->state); switch (resource->state) { Loading @@ -635,7 +585,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, resource)->pending_release > 0) ((struct ipa_rm_resource_prod *) resource)->pending_release--; spin_lock_irqsave(&depends_on->state_lock, consumer_flags); if (depends_on->state == IPA_RM_RELEASE_IN_PROGRESS && ((struct ipa_rm_resource_prod *) resource)->pending_release == 0) { Loading @@ -643,7 +592,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, state_changed = true; evt = IPA_RM_RESOURCE_RELEASED; } spin_unlock_irqrestore(&depends_on->state_lock, consumer_flags); break; case IPA_RM_REQUEST_IN_PROGRESS: release_consumer = true; Loading @@ -651,7 +599,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, resource)->pending_request > 0) ((struct ipa_rm_resource_prod *) resource)->pending_request--; spin_lock_irqsave(&depends_on->state_lock, consumer_flags); if (depends_on->state == IPA_RM_REQUEST_IN_PROGRESS && ((struct ipa_rm_resource_prod *) resource)->pending_request == 0) { Loading @@ -659,11 +606,9 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, state_changed = true; evt = IPA_RM_RESOURCE_GRANTED; } spin_unlock_irqrestore(&depends_on->state_lock, consumer_flags); break; default: result = -EINVAL; spin_unlock_irqrestore(&resource->state_lock, flags); goto bail; } if (state_changed && Loading @@ -676,7 +621,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, } IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(resource->name), resource->state); spin_unlock_irqrestore(&resource->state_lock, flags); ipa_rm_peers_list_remove_peer(resource->peers_list, depends_on->name); ipa_rm_peers_list_remove_peer(depends_on->peers_list, Loading @@ -699,13 +643,11 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) { int peers_index; int result = 0; unsigned long flags; struct ipa_rm_resource *consumer; int consumer_result; enum ipa_rm_resource_state state; if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) { spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; producer->resource.state = IPA_RM_GRANTED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -715,7 +657,6 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) result = 0; goto unlock_and_bail; } spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; switch (producer->resource.state) { case IPA_RM_RELEASED: Loading @@ -732,7 +673,6 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) goto unlock_and_bail; } producer->pending_request = 0; spin_unlock_irqrestore(&producer->resource.state_lock, flags); for (peers_index = 0; peers_index < ipa_rm_peers_list_get_size( producer->resource.peers_list); Loading @@ -740,21 +680,13 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) consumer = ipa_rm_peers_list_get_resource(peers_index, producer->resource.peers_list); if (consumer) { spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_request++; spin_unlock_irqrestore( &producer->resource.state_lock, flags); consumer_result = ipa_rm_resource_consumer_request( (struct ipa_rm_resource_cons *)consumer); if (consumer_result == -EINPROGRESS) { result = -EINPROGRESS; } else { spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_request--; spin_unlock_irqrestore( &producer->resource.state_lock, flags); if (consumer_result != 0) { result = consumer_result; goto bail; Loading @@ -763,7 +695,6 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) } } spin_lock_irqsave(&producer->resource.state_lock, flags); if (producer->pending_request == 0) { producer->resource.state = IPA_RM_GRANTED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -778,7 +709,6 @@ unlock_and_bail: ipa_rm_resource_str(producer->resource.name), state, producer->resource.state); spin_unlock_irqrestore(&producer->resource.state_lock, flags); bail: return result; } Loading @@ -794,13 +724,11 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) { int peers_index; int result = 0; unsigned long flags; struct ipa_rm_resource *consumer; int consumer_result; enum ipa_rm_resource_state state; if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) { spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; producer->resource.state = IPA_RM_RELEASED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -809,7 +737,7 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) true); goto bail; } spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; switch (producer->resource.state) { case IPA_RM_RELEASED: Loading @@ -826,7 +754,6 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) goto bail; } producer->pending_release = 0; spin_unlock_irqrestore(&producer->resource.state_lock, flags); for (peers_index = 0; peers_index < ipa_rm_peers_list_get_size( producer->resource.peers_list); Loading @@ -834,21 +761,13 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) consumer = ipa_rm_peers_list_get_resource(peers_index, producer->resource.peers_list); if (consumer) { spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_release++; spin_unlock_irqrestore( &producer->resource.state_lock, flags); consumer_result = ipa_rm_resource_consumer_release( (struct ipa_rm_resource_cons *)consumer); spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_release--; spin_unlock_irqrestore( &producer->resource.state_lock, flags); } } spin_lock_irqsave(&producer->resource.state_lock, flags); if (producer->pending_release == 0) { producer->resource.state = IPA_RM_RELEASED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -862,7 +781,7 @@ bail: ipa_rm_resource_str(producer->resource.name), state, producer->resource.state); spin_unlock_irqrestore(&producer->resource.state_lock, flags); return result; } Loading @@ -870,8 +789,6 @@ static void ipa_rm_resource_producer_handle_cb( struct ipa_rm_resource_prod *producer, enum ipa_rm_event event) { unsigned long flags; spin_lock_irqsave(&producer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d event: %d pending_request: %d\n", ipa_rm_resource_str(producer->resource.name), producer->resource.state, Loading @@ -886,8 +803,6 @@ static void ipa_rm_resource_producer_handle_cb( if (producer->pending_request == 0) { producer->resource.state = IPA_RM_GRANTED; spin_unlock_irqrestore( &producer->resource.state_lock, flags); ipa_rm_resource_producer_notify_clients( producer, IPA_RM_RESOURCE_GRANTED, Loading @@ -904,8 +819,6 @@ static void ipa_rm_resource_producer_handle_cb( if (producer->pending_release == 0) { producer->resource.state = IPA_RM_RELEASED; spin_unlock_irqrestore( &producer->resource.state_lock, flags); ipa_rm_resource_producer_notify_clients( producer, IPA_RM_RESOURCE_RELEASED, Loading @@ -923,7 +836,6 @@ unlock_and_bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(producer->resource.name), producer->resource.state); spin_unlock_irqrestore(&producer->resource.state_lock, flags); bail: return; } Loading @@ -939,12 +851,10 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer, { int peers_index; struct ipa_rm_resource *producer; unsigned long flags; if (!consumer) { IPA_RM_ERR("invalid params\n"); return; } spin_lock_irqsave(&consumer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d event: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state, Loading @@ -965,7 +875,6 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer, default: goto bail; } spin_unlock_irqrestore(&consumer->resource.state_lock, flags); for (peers_index = 0; peers_index < ipa_rm_peers_list_get_size( consumer->resource.peers_list); Loading @@ -983,7 +892,6 @@ bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); spin_unlock_irqrestore(&consumer->resource.state_lock, flags); return; } Loading @@ -1004,7 +912,6 @@ int ipa_rm_resource_producer_print_stat( int size){ int i, nbytes, cnt = 0; unsigned long flags; struct ipa_rm_resource *consumer; if (!buf || size < 0) Loading @@ -1016,8 +923,6 @@ int ipa_rm_resource_producer_print_stat( "["); cnt += nbytes; spin_lock_irqsave(&resource->state_lock, flags); switch (resource->state) { case IPA_RM_RELEASED: nbytes = scnprintf(buf + cnt, size - cnt, Loading @@ -1040,14 +945,9 @@ int ipa_rm_resource_producer_print_stat( cnt += nbytes; break; default: spin_unlock_irqrestore( &resource->state_lock, flags); return -EPERM; } spin_unlock_irqrestore( &resource->state_lock, flags); for (i = 0; i < resource->peers_list->max_peers; ++i) { consumer = ipa_rm_peers_list_get_resource( Loading @@ -1061,7 +961,6 @@ int ipa_rm_resource_producer_print_stat( "["); cnt += nbytes; spin_lock_irqsave(&consumer->state_lock, flags); switch (consumer->state) { case IPA_RM_RELEASED: nbytes = scnprintf(buf + cnt, size - cnt, Loading @@ -1084,14 +983,8 @@ int ipa_rm_resource_producer_print_stat( cnt += nbytes; break; default: spin_unlock_irqrestore( &consumer->state_lock, flags); return -EPERM; } spin_unlock_irqrestore( &consumer->state_lock, flags); } } nbytes = scnprintf(buf + cnt, size - cnt, Loading drivers/platform/msm/ipa/ipa_rm_resource.h +2 −6 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/platform/msm/ipa/ipa_rm.c +29 −29 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -42,7 +42,7 @@ static const char *resource_name_to_str[IPA_RM_RESOURCE_MAX] = { struct ipa_rm_context_type { struct ipa_rm_dep_graph *dep_graph; struct workqueue_struct *ipa_rm_wq; rwlock_t lock; spinlock_t ipa_rm_lock; }; static struct ipa_rm_context_type *ipa_rm_ctx; Loading @@ -54,8 +54,8 @@ static struct ipa_rm_context_type *ipa_rm_ctx; * Returns: 0 on success, negative on failure * * This function is called by IPA RM client to initialize client's resources. * This API should be called before any other IPA RM API * on given resource name. * This API should be called before any other IPA RM API on a given resource * name. * */ int ipa_rm_create_resource(struct ipa_rm_create_params *create_params) Loading @@ -69,7 +69,7 @@ int ipa_rm_create_resource(struct ipa_rm_create_params *create_params) } IPA_RM_DBG("%s\n", ipa_rm_resource_str(create_params->name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, create_params->name, &resource) == 0) { Loading @@ -90,7 +90,7 @@ int ipa_rm_create_resource(struct ipa_rm_create_params *create_params) goto bail; } bail: write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -112,7 +112,7 @@ int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name) int result; IPA_RM_DBG("%s\n", ipa_rm_resource_str(resource_name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -132,7 +132,7 @@ int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name) goto bail; } bail: write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -157,12 +157,12 @@ int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); result = ipa_rm_dep_graph_add_dependency( ipa_rm_ctx->dep_graph, resource_name, depends_on_name); write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -188,12 +188,12 @@ int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name, IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); write_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); result = ipa_rm_dep_graph_delete_dependency( ipa_rm_ctx->dep_graph, resource_name, depends_on_name); write_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading @@ -218,7 +218,7 @@ int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name) IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -230,7 +230,7 @@ int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name) (struct ipa_rm_resource_prod *)resource); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return result; } Loading @@ -254,7 +254,7 @@ int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name) IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -266,7 +266,7 @@ int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name) (struct ipa_rm_resource_prod *)resource); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return result; } Loading Loading @@ -294,7 +294,7 @@ int ipa_rm_register(enum ipa_rm_resource_name resource_name, IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -307,7 +307,7 @@ int ipa_rm_register(enum ipa_rm_resource_name resource_name, reg_params, true); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading Loading @@ -336,7 +336,7 @@ int ipa_rm_deregister(enum ipa_rm_resource_name resource_name, IPA_RM_ERR("can be called on PROD only\n"); return -EINVAL; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, resource_name, &resource) != 0) { Loading @@ -348,7 +348,7 @@ int ipa_rm_deregister(enum ipa_rm_resource_name resource_name, (struct ipa_rm_resource_prod *)resource, reg_params); bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("EXIT with %d\n", result); return result; Loading Loading @@ -407,35 +407,35 @@ static void ipa_rm_wq_handler(struct work_struct *work) IPA_RM_ERR("resource is not PROD\n"); return; } read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, ipa_rm_work->resource_name, &resource) != 0){ IPA_RM_ERR("resource does not exists\n"); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return; } ipa_rm_resource_producer_notify_clients( (struct ipa_rm_resource_prod *)resource, ipa_rm_work->event, ipa_rm_work->notify_registered_only); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); break; case IPA_RM_WQ_NOTIFY_CONS: break; case IPA_RM_WQ_RESOURCE_CB: read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, ipa_rm_work->resource_name, &resource) != 0){ IPA_RM_ERR("resource does not exists\n"); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return; } ipa_rm_resource_consumer_handle_cb( (struct ipa_rm_resource_cons *)resource, ipa_rm_work->event); read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); break; default: break; Loading Loading @@ -501,7 +501,7 @@ int ipa_rm_initialize(void) IPA_RM_ERR("create dependency graph failed\n"); goto graph_alloc_fail; } rwlock_init(&ipa_rm_ctx->lock); spin_lock_init(&ipa_rm_ctx->ipa_rm_lock); IPA_RM_DBG("SUCCESS\n"); return 0; Loading Loading @@ -531,7 +531,7 @@ int ipa_rm_stat(char *buf, int size) if (!buf || size < 0) goto bail; read_lock(&ipa_rm_ctx->lock); spin_lock(&ipa_rm_ctx->ipa_rm_lock); for (i = 0; i < IPA_RM_RESOURCE_PROD_MAX; ++i) { result = ipa_rm_dep_graph_get_resource( ipa_rm_ctx->dep_graph, Loading @@ -548,7 +548,7 @@ int ipa_rm_stat(char *buf, int size) } result = cnt; bail: read_unlock(&ipa_rm_ctx->lock); spin_unlock(&ipa_rm_ctx->ipa_rm_lock); return result; } Loading
drivers/platform/msm/ipa/ipa_rm_peers_list.c +8 −16 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -65,7 +65,7 @@ int ipa_rm_peers_list_create(int max_peers, result = -ENOMEM; goto bail; } rwlock_init(&(*peers_list)->peers_lock); (*peers_list)->max_peers = max_peers; (*peers_list)->peers = kzalloc((*peers_list)->max_peers * sizeof(struct ipa_rm_resource *), GFP_KERNEL); Loading Loading @@ -109,11 +109,10 @@ void ipa_rm_peers_list_remove_peer( { if (!peers_list) return; write_lock(&peers_list->peers_lock); peers_list->peers[ipa_rm_peers_list_get_resource_index( resource_name)] = NULL; peers_list->peers_count--; write_unlock(&peers_list->peers_lock); } /** Loading @@ -129,12 +128,11 @@ void ipa_rm_peers_list_add_peer( { if (!peers_list || !resource) return; read_lock(&peers_list->peers_lock); peers_list->peers[ipa_rm_peers_list_get_resource_index( resource->name)] = resource; peers_list->peers_count++; read_unlock(&peers_list->peers_lock); } /** Loading @@ -150,10 +148,9 @@ bool ipa_rm_peers_list_is_empty(struct ipa_rm_peers_list *peers_list) bool result = true; if (!peers_list) goto bail; read_lock(&peers_list->peers_lock); if (peers_list->peers_count > 0) result = false; read_unlock(&peers_list->peers_lock); bail: return result; } Loading @@ -172,10 +169,9 @@ bool ipa_rm_peers_list_has_last_peer( bool result = false; if (!peers_list) goto bail; read_lock(&peers_list->peers_lock); if (peers_list->peers_count == 1) result = true; read_unlock(&peers_list->peers_lock); bail: return result; } Loading @@ -200,17 +196,14 @@ bool ipa_rm_peers_list_check_dependency( bool result = false; if (!resource_peers || !depends_on_peers) return result; read_lock(&resource_peers->peers_lock); if (resource_peers->peers[ipa_rm_peers_list_get_resource_index( depends_on_name)] != NULL) result = true; read_unlock(&resource_peers->peers_lock); read_lock(&depends_on_peers->peers_lock); if (depends_on_peers->peers[ipa_rm_peers_list_get_resource_index( resource_name)] != NULL) result = true; read_unlock(&depends_on_peers->peers_lock); return result; } Loading @@ -229,9 +222,8 @@ struct ipa_rm_resource *ipa_rm_peers_list_get_resource(int resource_index, struct ipa_rm_resource *result = NULL; if (!ipa_rm_peers_list_check_index(resource_index, resource_peers)) goto bail; read_lock(&resource_peers->peers_lock); result = resource_peers->peers[resource_index]; read_unlock(&resource_peers->peers_lock); bail: return result; } Loading
drivers/platform/msm/ipa/ipa_rm_peers_list.h +1 −3 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -21,13 +21,11 @@ * in case of producer or list of dependencies in case of consumer * @max_peers: maximum number of peers for this resource * @peers_count: actual number of peers for this resource * @peers_lock: RW lock for peers container */ struct ipa_rm_peers_list { struct ipa_rm_resource **peers; int max_peers; int peers_count; rwlock_t peers_lock; }; int ipa_rm_peers_list_create(int max_peers, Loading
drivers/platform/msm/ipa/ipa_rm_resource.c +22 −129 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -80,9 +80,7 @@ static int ipa_rm_resource_consumer_request( { int result = 0; int driver_result; unsigned long flags; spin_lock_irqsave(&consumer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); Loading @@ -93,11 +91,9 @@ static int ipa_rm_resource_consumer_request( enum ipa_rm_resource_state prev_state = consumer->resource.state; consumer->resource.state = IPA_RM_REQUEST_IN_PROGRESS; spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("calling driver CB\n"); driver_result = consumer->request_resource(); IPA_RM_DBG("driver CB returned with %d\n", driver_result); spin_lock_irqsave(&consumer->resource.state_lock, flags); if (driver_result == 0) consumer->resource.state = IPA_RM_GRANTED; else if (driver_result != -EINPROGRESS) { Loading @@ -122,7 +118,6 @@ bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("EXIT with %d\n", result); return result; } Loading @@ -132,10 +127,8 @@ static int ipa_rm_resource_consumer_release( { int result = 0; int driver_result; unsigned long flags; enum ipa_rm_resource_state save_state; spin_lock_irqsave(&consumer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); Loading @@ -149,14 +142,10 @@ static int ipa_rm_resource_consumer_release( if (consumer->usage_count == 0) { save_state = consumer->resource.state; consumer->resource.state = IPA_RM_RELEASE_IN_PROGRESS; spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("calling driver CB\n"); driver_result = consumer->release_resource(); IPA_RM_DBG("driver CB returned with %d\n", driver_result); spin_lock_irqsave(&consumer->resource.state_lock, flags); if (driver_result == 0) consumer->resource.state = IPA_RM_RELEASED; else if (driver_result != -EINPROGRESS) Loading @@ -177,7 +166,6 @@ bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); spin_unlock_irqrestore(&consumer->resource.state_lock, flags); IPA_RM_DBG("EXIT with %d\n", result); return result; } Loading @@ -195,50 +183,24 @@ void ipa_rm_resource_producer_notify_clients( enum ipa_rm_event event, bool notify_registered_only) { struct ipa_rm_notification_info *reg_info, *reg_info_cloned; struct list_head *pos, *q; LIST_HEAD(cloned_list); struct ipa_rm_notification_info *reg_info; IPA_RM_DBG("%s event: %d notify_registered_only: %d\n", ipa_rm_resource_str(producer->resource.name), event, notify_registered_only); read_lock(&producer->event_listeners_lock); list_for_each(pos, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, link); list_for_each_entry(reg_info, &(producer->event_listeners), link) { if (notify_registered_only && !reg_info->explicit) continue; reg_info_cloned = kzalloc(sizeof(*reg_info_cloned), GFP_KERNEL); if (!reg_info_cloned) { IPA_RM_ERR("No memory\n"); goto clone_list_failed; } reg_info_cloned->reg_params.notify_cb = reg_info->reg_params.notify_cb; reg_info_cloned->reg_params.user_data = reg_info->reg_params.user_data; list_add(®_info_cloned->link, &cloned_list); } read_unlock(&producer->event_listeners_lock); list_for_each_safe(pos, q, &cloned_list) { reg_info = list_entry(pos, struct ipa_rm_notification_info, link); IPA_RM_DBG("Notifying %s event: %d\n", ipa_rm_resource_str(producer->resource.name), event); reg_info->reg_params.notify_cb( reg_info->reg_params.user_data, reg_info->reg_params.notify_cb(reg_info->reg_params.user_data, event, 0); IPA_RM_DBG("back from client CB\n"); list_del(pos); kfree(reg_info); } return; clone_list_failed: read_unlock(&producer->event_listeners_lock); } static int ipa_rm_resource_producer_create(struct ipa_rm_resource **resource, Loading @@ -253,7 +215,7 @@ static int ipa_rm_resource_producer_create(struct ipa_rm_resource **resource, result = -ENOMEM; goto bail; } rwlock_init(&(*producer)->event_listeners_lock); INIT_LIST_HEAD(&((*producer)->event_listeners)); result = ipa_rm_resource_producer_register(*producer, &(create_params->reg_params), Loading @@ -277,7 +239,7 @@ static void ipa_rm_resource_producer_delete( { struct ipa_rm_notification_info *reg_info; struct list_head *pos, *q; write_lock(&producer->event_listeners_lock); list_for_each_safe(pos, q, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, Loading @@ -285,7 +247,6 @@ static void ipa_rm_resource_producer_delete( list_del(pos); kfree(reg_info); } write_unlock(&producer->event_listeners_lock); } static int ipa_rm_resource_consumer_create(struct ipa_rm_resource **resource, Loading Loading @@ -361,7 +322,6 @@ int ipa_rm_resource_create( } (*resource)->name = create_params->name; (*resource)->state = IPA_RM_RELEASED; spin_lock_init(&((*resource)->state_lock)); goto bail; peers_alloc_fail: ipa_rm_resource_delete(*resource); Loading @@ -378,8 +338,11 @@ bail: */ int ipa_rm_resource_delete(struct ipa_rm_resource *resource) { struct ipa_rm_resource *consumer, *producer; int peers_index, result = 0, list_size; struct ipa_rm_resource *consumer; struct ipa_rm_resource *producer; int peers_index; int result = 0; int list_size; IPA_RM_DBG("ipa_rm_resource_delete ENTER with resource %d\n", resource->name); Loading Loading @@ -452,7 +415,7 @@ int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer, result = -EPERM; goto bail; } read_lock(&producer->event_listeners_lock); list_for_each(pos, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, Loading @@ -461,12 +424,11 @@ int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer, reg_params->notify_cb) { IPA_RM_ERR("already registered\n"); result = -EPERM; read_unlock(&producer->event_listeners_lock); goto bail; } } read_unlock(&producer->event_listeners_lock); reg_info = kzalloc(sizeof(*reg_info), GFP_KERNEL); if (reg_info == NULL) { IPA_RM_ERR("no mem\n"); Loading @@ -477,9 +439,7 @@ int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer, reg_info->reg_params.notify_cb = reg_params->notify_cb; reg_info->explicit = explicit; INIT_LIST_HEAD(®_info->link); write_lock(&producer->event_listeners_lock); list_add(®_info->link, &producer->event_listeners); write_unlock(&producer->event_listeners_lock); bail: return result; } Loading @@ -506,7 +466,7 @@ int ipa_rm_resource_producer_deregister(struct ipa_rm_resource_prod *producer, IPA_RM_ERR("invalid params\n"); return -EINVAL; } write_lock(&producer->event_listeners_lock); list_for_each_safe(pos, q, &(producer->event_listeners)) { reg_info = list_entry(pos, struct ipa_rm_notification_info, Loading @@ -518,10 +478,8 @@ int ipa_rm_resource_producer_deregister(struct ipa_rm_resource_prod *producer, result = 0; goto bail; } } bail: write_unlock(&producer->event_listeners_lock); return result; } Loading @@ -537,7 +495,6 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, struct ipa_rm_resource *depends_on) { int result = 0; unsigned long flags; int consumer_result; if (!resource || !depends_on) { IPA_RM_ERR("invalid params\n"); Loading @@ -552,7 +509,6 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, } ipa_rm_peers_list_add_peer(resource->peers_list, depends_on); ipa_rm_peers_list_add_peer(depends_on->peers_list, resource); spin_lock_irqsave(&resource->state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(resource->name), resource->state); switch (resource->state) { Loading @@ -566,10 +522,8 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, resource->state = IPA_RM_REQUEST_IN_PROGRESS; ((struct ipa_rm_resource_prod *) resource)->pending_request++; spin_unlock_irqrestore(&resource->state_lock, flags); consumer_result = ipa_rm_resource_consumer_request( (struct ipa_rm_resource_cons *)depends_on); spin_lock_irqsave(&resource->state_lock, flags); if (consumer_result != -EINPROGRESS) { resource->state = prev_state; ((struct ipa_rm_resource_prod *) Loading @@ -586,7 +540,6 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource, bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(resource->name), resource->state); spin_unlock_irqrestore(&resource->state_lock, flags); IPA_RM_DBG("EXIT with %d\n", result); return result; } Loading @@ -605,8 +558,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, struct ipa_rm_resource *depends_on) { int result = 0; unsigned long flags; unsigned long consumer_flags; bool state_changed = false; bool release_consumer = false; enum ipa_rm_event evt; Loading @@ -621,7 +572,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, IPA_RM_ERR("dependency does not exist\n"); return -EINVAL; } spin_lock_irqsave(&resource->state_lock, flags); IPA_RM_DBG("%s state: %d\n", ipa_rm_resource_str(resource->name), resource->state); switch (resource->state) { Loading @@ -635,7 +585,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, resource)->pending_release > 0) ((struct ipa_rm_resource_prod *) resource)->pending_release--; spin_lock_irqsave(&depends_on->state_lock, consumer_flags); if (depends_on->state == IPA_RM_RELEASE_IN_PROGRESS && ((struct ipa_rm_resource_prod *) resource)->pending_release == 0) { Loading @@ -643,7 +592,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, state_changed = true; evt = IPA_RM_RESOURCE_RELEASED; } spin_unlock_irqrestore(&depends_on->state_lock, consumer_flags); break; case IPA_RM_REQUEST_IN_PROGRESS: release_consumer = true; Loading @@ -651,7 +599,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, resource)->pending_request > 0) ((struct ipa_rm_resource_prod *) resource)->pending_request--; spin_lock_irqsave(&depends_on->state_lock, consumer_flags); if (depends_on->state == IPA_RM_REQUEST_IN_PROGRESS && ((struct ipa_rm_resource_prod *) resource)->pending_request == 0) { Loading @@ -659,11 +606,9 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, state_changed = true; evt = IPA_RM_RESOURCE_GRANTED; } spin_unlock_irqrestore(&depends_on->state_lock, consumer_flags); break; default: result = -EINVAL; spin_unlock_irqrestore(&resource->state_lock, flags); goto bail; } if (state_changed && Loading @@ -676,7 +621,6 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource, } IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(resource->name), resource->state); spin_unlock_irqrestore(&resource->state_lock, flags); ipa_rm_peers_list_remove_peer(resource->peers_list, depends_on->name); ipa_rm_peers_list_remove_peer(depends_on->peers_list, Loading @@ -699,13 +643,11 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) { int peers_index; int result = 0; unsigned long flags; struct ipa_rm_resource *consumer; int consumer_result; enum ipa_rm_resource_state state; if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) { spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; producer->resource.state = IPA_RM_GRANTED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -715,7 +657,6 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) result = 0; goto unlock_and_bail; } spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; switch (producer->resource.state) { case IPA_RM_RELEASED: Loading @@ -732,7 +673,6 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) goto unlock_and_bail; } producer->pending_request = 0; spin_unlock_irqrestore(&producer->resource.state_lock, flags); for (peers_index = 0; peers_index < ipa_rm_peers_list_get_size( producer->resource.peers_list); Loading @@ -740,21 +680,13 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) consumer = ipa_rm_peers_list_get_resource(peers_index, producer->resource.peers_list); if (consumer) { spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_request++; spin_unlock_irqrestore( &producer->resource.state_lock, flags); consumer_result = ipa_rm_resource_consumer_request( (struct ipa_rm_resource_cons *)consumer); if (consumer_result == -EINPROGRESS) { result = -EINPROGRESS; } else { spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_request--; spin_unlock_irqrestore( &producer->resource.state_lock, flags); if (consumer_result != 0) { result = consumer_result; goto bail; Loading @@ -763,7 +695,6 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer) } } spin_lock_irqsave(&producer->resource.state_lock, flags); if (producer->pending_request == 0) { producer->resource.state = IPA_RM_GRANTED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -778,7 +709,6 @@ unlock_and_bail: ipa_rm_resource_str(producer->resource.name), state, producer->resource.state); spin_unlock_irqrestore(&producer->resource.state_lock, flags); bail: return result; } Loading @@ -794,13 +724,11 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) { int peers_index; int result = 0; unsigned long flags; struct ipa_rm_resource *consumer; int consumer_result; enum ipa_rm_resource_state state; if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) { spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; producer->resource.state = IPA_RM_RELEASED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -809,7 +737,7 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) true); goto bail; } spin_lock_irqsave(&producer->resource.state_lock, flags); state = producer->resource.state; switch (producer->resource.state) { case IPA_RM_RELEASED: Loading @@ -826,7 +754,6 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) goto bail; } producer->pending_release = 0; spin_unlock_irqrestore(&producer->resource.state_lock, flags); for (peers_index = 0; peers_index < ipa_rm_peers_list_get_size( producer->resource.peers_list); Loading @@ -834,21 +761,13 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer) consumer = ipa_rm_peers_list_get_resource(peers_index, producer->resource.peers_list); if (consumer) { spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_release++; spin_unlock_irqrestore( &producer->resource.state_lock, flags); consumer_result = ipa_rm_resource_consumer_release( (struct ipa_rm_resource_cons *)consumer); spin_lock_irqsave( &producer->resource.state_lock, flags); producer->pending_release--; spin_unlock_irqrestore( &producer->resource.state_lock, flags); } } spin_lock_irqsave(&producer->resource.state_lock, flags); if (producer->pending_release == 0) { producer->resource.state = IPA_RM_RELEASED; (void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD, Loading @@ -862,7 +781,7 @@ bail: ipa_rm_resource_str(producer->resource.name), state, producer->resource.state); spin_unlock_irqrestore(&producer->resource.state_lock, flags); return result; } Loading @@ -870,8 +789,6 @@ static void ipa_rm_resource_producer_handle_cb( struct ipa_rm_resource_prod *producer, enum ipa_rm_event event) { unsigned long flags; spin_lock_irqsave(&producer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d event: %d pending_request: %d\n", ipa_rm_resource_str(producer->resource.name), producer->resource.state, Loading @@ -886,8 +803,6 @@ static void ipa_rm_resource_producer_handle_cb( if (producer->pending_request == 0) { producer->resource.state = IPA_RM_GRANTED; spin_unlock_irqrestore( &producer->resource.state_lock, flags); ipa_rm_resource_producer_notify_clients( producer, IPA_RM_RESOURCE_GRANTED, Loading @@ -904,8 +819,6 @@ static void ipa_rm_resource_producer_handle_cb( if (producer->pending_release == 0) { producer->resource.state = IPA_RM_RELEASED; spin_unlock_irqrestore( &producer->resource.state_lock, flags); ipa_rm_resource_producer_notify_clients( producer, IPA_RM_RESOURCE_RELEASED, Loading @@ -923,7 +836,6 @@ unlock_and_bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(producer->resource.name), producer->resource.state); spin_unlock_irqrestore(&producer->resource.state_lock, flags); bail: return; } Loading @@ -939,12 +851,10 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer, { int peers_index; struct ipa_rm_resource *producer; unsigned long flags; if (!consumer) { IPA_RM_ERR("invalid params\n"); return; } spin_lock_irqsave(&consumer->resource.state_lock, flags); IPA_RM_DBG("%s state: %d event: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state, Loading @@ -965,7 +875,6 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer, default: goto bail; } spin_unlock_irqrestore(&consumer->resource.state_lock, flags); for (peers_index = 0; peers_index < ipa_rm_peers_list_get_size( consumer->resource.peers_list); Loading @@ -983,7 +892,6 @@ bail: IPA_RM_DBG("%s new state: %d\n", ipa_rm_resource_str(consumer->resource.name), consumer->resource.state); spin_unlock_irqrestore(&consumer->resource.state_lock, flags); return; } Loading @@ -1004,7 +912,6 @@ int ipa_rm_resource_producer_print_stat( int size){ int i, nbytes, cnt = 0; unsigned long flags; struct ipa_rm_resource *consumer; if (!buf || size < 0) Loading @@ -1016,8 +923,6 @@ int ipa_rm_resource_producer_print_stat( "["); cnt += nbytes; spin_lock_irqsave(&resource->state_lock, flags); switch (resource->state) { case IPA_RM_RELEASED: nbytes = scnprintf(buf + cnt, size - cnt, Loading @@ -1040,14 +945,9 @@ int ipa_rm_resource_producer_print_stat( cnt += nbytes; break; default: spin_unlock_irqrestore( &resource->state_lock, flags); return -EPERM; } spin_unlock_irqrestore( &resource->state_lock, flags); for (i = 0; i < resource->peers_list->max_peers; ++i) { consumer = ipa_rm_peers_list_get_resource( Loading @@ -1061,7 +961,6 @@ int ipa_rm_resource_producer_print_stat( "["); cnt += nbytes; spin_lock_irqsave(&consumer->state_lock, flags); switch (consumer->state) { case IPA_RM_RELEASED: nbytes = scnprintf(buf + cnt, size - cnt, Loading @@ -1084,14 +983,8 @@ int ipa_rm_resource_producer_print_stat( cnt += nbytes; break; default: spin_unlock_irqrestore( &consumer->state_lock, flags); return -EPERM; } spin_unlock_irqrestore( &consumer->state_lock, flags); } } nbytes = scnprintf(buf + cnt, size - cnt, Loading
drivers/platform/msm/ipa/ipa_rm_resource.h +2 −6 File changed.Preview size limit exceeded, changes collapsed. Show changes