Loading drivers/platform/msm/ipa/ipa_rm.c +56 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,62 @@ int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, } EXPORT_SYMBOL(ipa_rm_add_dependency); /** * ipa_rm_add_dependency_sync() - Create a dependency between 2 resources * in a synchronized fashion. In case a producer resource is in GRANTED state * and the newly added consumer resource is in RELEASED state, the consumer * entity will be requested and the function will block until the consumer * is granted. * @resource_name: name of dependent resource * @depends_on_name: name of its dependency * * Returns: 0 on success, negative on failure * * Side effects: May block. See documentation above. */ int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name) { int result; struct ipa_rm_resource *consumer; unsigned long time; unsigned long flags; IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); spin_lock_irqsave(&ipa_rm_ctx->ipa_rm_lock, flags); result = ipa_rm_dep_graph_add_dependency( ipa_rm_ctx->dep_graph, resource_name, depends_on_name); spin_unlock_irqrestore(&ipa_rm_ctx->ipa_rm_lock, flags); if (result == -EINPROGRESS) { ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, depends_on_name, &consumer); IPA_RM_DBG("%s waits for GRANT of %s.\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); time = wait_for_completion_timeout( &((struct ipa_rm_resource_cons *)consumer)-> request_consumer_in_progress, HZ); result = 0; if (!time) { IPA_RM_ERR("TIMEOUT waiting for %s GRANT event.", ipa_rm_resource_str(depends_on_name)); result = -ETIME; } IPA_RM_DBG("%s waited for %s GRANT %lu time.\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name), time); } IPA_RM_DBG("EXIT with %d\n", result); return result; } EXPORT_SYMBOL(ipa_rm_add_dependency_sync); /** * ipa_rm_delete_dependency() - create dependency Loading drivers/platform/msm/ipa/ipa_rm_resource.c +4 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ int ipa_rm_resource_consumer_release_work( else consumer->resource.state = IPA_RM_RELEASED; } complete_all(&consumer->request_consumer_in_progress); ipa_rm_perf_profile_change(consumer->resource.name); bail: Loading Loading @@ -156,6 +157,7 @@ int ipa_rm_resource_consumer_request( switch (consumer->resource.state) { case IPA_RM_RELEASED: case IPA_RM_RELEASE_IN_PROGRESS: reinit_completion(&consumer->request_consumer_in_progress); consumer->resource.state = IPA_RM_REQUEST_IN_PROGRESS; if (prev_state == IPA_RM_RELEASE_IN_PROGRESS || ipa_inc_client_enable_clks_no_block() != 0) { Loading Loading @@ -353,6 +355,7 @@ static int ipa_rm_resource_consumer_create(struct ipa_rm_resource **resource, (*consumer)->release_resource = create_params->release_resource; (*resource) = (struct ipa_rm_resource *) (*consumer); (*resource)->type = IPA_RM_CONSUMER; init_completion(&((*consumer)->request_consumer_in_progress)); *max_peers = IPA_RM_RESOURCE_PROD_MAX; bail: return result; Loading Loading @@ -973,6 +976,7 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer, consumer->resource.state = IPA_RM_GRANTED; ipa_rm_perf_profile_change(consumer->resource.name); ipa_resume_resource(consumer->resource.name); complete_all(&consumer->request_consumer_in_progress); break; case IPA_RM_RELEASE_IN_PROGRESS: if (event == IPA_RM_RESOURCE_GRANTED) Loading drivers/platform/msm/ipa/ipa_rm_resource.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 @@ -72,6 +72,8 @@ struct ipa_rm_resource { * @resource: resource * @usage_count: number of producers in GRANTED / REQUESTED state * using this consumer * @request_consumer_in_progress: when set, the consumer is during its request * phase * @request_resource: function which should be called to request resource * from resource manager * @release_resource: function which should be called to release resource Loading @@ -81,6 +83,7 @@ struct ipa_rm_resource { struct ipa_rm_resource_cons { struct ipa_rm_resource resource; int usage_count; struct completion request_consumer_in_progress; int (*request_resource)(void); int (*release_resource)(void); }; Loading include/linux/ipa.h +10 −0 Original line number Diff line number Diff line Loading @@ -1289,6 +1289,9 @@ int ipa_rm_set_perf_profile(enum ipa_rm_resource_name resource_name, int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name); int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name); int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name); Loading Loading @@ -1845,6 +1848,13 @@ static inline int ipa_rm_add_dependency( return -EPERM; } static inline int ipa_rm_add_dependency_sync( enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name) { return -EPERM; } static inline int ipa_rm_delete_dependency( enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name) Loading Loading
drivers/platform/msm/ipa/ipa_rm.c +56 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,62 @@ int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, } EXPORT_SYMBOL(ipa_rm_add_dependency); /** * ipa_rm_add_dependency_sync() - Create a dependency between 2 resources * in a synchronized fashion. In case a producer resource is in GRANTED state * and the newly added consumer resource is in RELEASED state, the consumer * entity will be requested and the function will block until the consumer * is granted. * @resource_name: name of dependent resource * @depends_on_name: name of its dependency * * Returns: 0 on success, negative on failure * * Side effects: May block. See documentation above. */ int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name) { int result; struct ipa_rm_resource *consumer; unsigned long time; unsigned long flags; IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); spin_lock_irqsave(&ipa_rm_ctx->ipa_rm_lock, flags); result = ipa_rm_dep_graph_add_dependency( ipa_rm_ctx->dep_graph, resource_name, depends_on_name); spin_unlock_irqrestore(&ipa_rm_ctx->ipa_rm_lock, flags); if (result == -EINPROGRESS) { ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph, depends_on_name, &consumer); IPA_RM_DBG("%s waits for GRANT of %s.\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name)); time = wait_for_completion_timeout( &((struct ipa_rm_resource_cons *)consumer)-> request_consumer_in_progress, HZ); result = 0; if (!time) { IPA_RM_ERR("TIMEOUT waiting for %s GRANT event.", ipa_rm_resource_str(depends_on_name)); result = -ETIME; } IPA_RM_DBG("%s waited for %s GRANT %lu time.\n", ipa_rm_resource_str(resource_name), ipa_rm_resource_str(depends_on_name), time); } IPA_RM_DBG("EXIT with %d\n", result); return result; } EXPORT_SYMBOL(ipa_rm_add_dependency_sync); /** * ipa_rm_delete_dependency() - create dependency Loading
drivers/platform/msm/ipa/ipa_rm_resource.c +4 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ int ipa_rm_resource_consumer_release_work( else consumer->resource.state = IPA_RM_RELEASED; } complete_all(&consumer->request_consumer_in_progress); ipa_rm_perf_profile_change(consumer->resource.name); bail: Loading Loading @@ -156,6 +157,7 @@ int ipa_rm_resource_consumer_request( switch (consumer->resource.state) { case IPA_RM_RELEASED: case IPA_RM_RELEASE_IN_PROGRESS: reinit_completion(&consumer->request_consumer_in_progress); consumer->resource.state = IPA_RM_REQUEST_IN_PROGRESS; if (prev_state == IPA_RM_RELEASE_IN_PROGRESS || ipa_inc_client_enable_clks_no_block() != 0) { Loading Loading @@ -353,6 +355,7 @@ static int ipa_rm_resource_consumer_create(struct ipa_rm_resource **resource, (*consumer)->release_resource = create_params->release_resource; (*resource) = (struct ipa_rm_resource *) (*consumer); (*resource)->type = IPA_RM_CONSUMER; init_completion(&((*consumer)->request_consumer_in_progress)); *max_peers = IPA_RM_RESOURCE_PROD_MAX; bail: return result; Loading Loading @@ -973,6 +976,7 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer, consumer->resource.state = IPA_RM_GRANTED; ipa_rm_perf_profile_change(consumer->resource.name); ipa_resume_resource(consumer->resource.name); complete_all(&consumer->request_consumer_in_progress); break; case IPA_RM_RELEASE_IN_PROGRESS: if (event == IPA_RM_RESOURCE_GRANTED) Loading
drivers/platform/msm/ipa/ipa_rm_resource.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 @@ -72,6 +72,8 @@ struct ipa_rm_resource { * @resource: resource * @usage_count: number of producers in GRANTED / REQUESTED state * using this consumer * @request_consumer_in_progress: when set, the consumer is during its request * phase * @request_resource: function which should be called to request resource * from resource manager * @release_resource: function which should be called to release resource Loading @@ -81,6 +83,7 @@ struct ipa_rm_resource { struct ipa_rm_resource_cons { struct ipa_rm_resource resource; int usage_count; struct completion request_consumer_in_progress; int (*request_resource)(void); int (*release_resource)(void); }; Loading
include/linux/ipa.h +10 −0 Original line number Diff line number Diff line Loading @@ -1289,6 +1289,9 @@ int ipa_rm_set_perf_profile(enum ipa_rm_resource_name resource_name, int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name); int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name); int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name); Loading Loading @@ -1845,6 +1848,13 @@ static inline int ipa_rm_add_dependency( return -EPERM; } static inline int ipa_rm_add_dependency_sync( enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name) { return -EPERM; } static inline int ipa_rm_delete_dependency( enum ipa_rm_resource_name resource_name, enum ipa_rm_resource_name depends_on_name) Loading