]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: support syncpoint refcounting
authorDeepak Nibade <dnibade@nvidia.com>
Wed, 20 May 2015 13:26:44 +0000 (18:56 +0530)
committerArto Merilainen <amerilainen@nvidia.com>
Mon, 1 Jun 2015 06:40:46 +0000 (23:40 -0700)
Support syncpoint refcounting by adding atomic variable
"ref" to struct nvhost_syncpt to track refcounts of
each syncpoint

Also, expose below APIs for refcount handling :

- int nvhost_syncpt_get_ref(struct nvhost_syncpt *sp, u32 id)
API to increment syncpoint refcount

- void nvhost_syncpt_put_ref(struct nvhost_syncpt *sp, u32 id)
API to decrement syncpoint refcount

- int nvhost_syncpt_read_ref(struct nvhost_syncpt *sp, u32 id)
API to read current refcount of syncpoint

- void nvhost_syncpt_put_ref_ext(u32 id)
Global API for clients to drop syncpoint refcount

Bug 1646883

Change-Id: I398a263050798356c2ed6e4b6081d0e9401b0469
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/745614
GVS: Gerrit_Virtual_Submit
Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
drivers/video/tegra/host/nvhost_syncpt.c
drivers/video/tegra/host/nvhost_syncpt.h
include/linux/nvhost.h

index 6bdbd9fedba1a08d242f8e2f90dca51d3b0f53ad..29f238c40f1b52e1d4d4a103253de700aa1629b8 100644 (file)
@@ -966,6 +966,29 @@ int nvhost_syncpt_mark_unused(struct nvhost_syncpt *sp, u32 syncptid)
        return 0;
 }
 
+int nvhost_syncpt_get_ref(struct nvhost_syncpt *sp, u32 id)
+{
+       return atomic_inc_return(&sp->ref[id]);
+}
+
+int nvhost_syncpt_read_ref(struct nvhost_syncpt *sp, u32 id)
+{
+       return atomic_read(&sp->ref[id]);
+}
+
+void nvhost_syncpt_put_ref(struct nvhost_syncpt *sp, u32 id)
+{
+       WARN_ON(nvhost_syncpt_read_ref(sp, id) == 0);
+       if (atomic_dec_and_test(&sp->ref[id]))
+               nvhost_free_syncpt(id);
+}
+
+void nvhost_syncpt_put_ref_ext(u32 id)
+{
+       nvhost_syncpt_put_ref(&nvhost->syncpt, id);
+}
+EXPORT_SYMBOL_GPL(nvhost_syncpt_put_ref_ext);
+
 int nvhost_syncpt_init(struct platform_device *dev,
                struct nvhost_syncpt *sp)
 {
@@ -984,6 +1007,7 @@ int nvhost_syncpt_init(struct platform_device *dev,
        sp->lock_counts =
                kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_mlocks(sp),
                        GFP_KERNEL);
+       sp->ref = kzalloc(sizeof(atomic_t) * nb_pts, GFP_KERNEL);
 #ifdef CONFIG_TEGRA_GRHOST_SYNC
        sp->timeline = kzalloc(sizeof(struct nvhost_sync_timeline *) *
                        nb_pts, GFP_KERNEL);
@@ -1059,6 +1083,7 @@ int nvhost_syncpt_init(struct platform_device *dev,
                        sp->client_managed[i] = true;
                sp->syncpt_names[i] = NULL;
                sp->last_used_by[i] = NULL;
+               atomic_set(&sp->ref[i], 0);
 
 #ifdef CONFIG_TEGRA_GRHOST_SYNC
                sp->timeline[i] = nvhost_sync_timeline_create(sp, i);
@@ -1128,6 +1153,9 @@ void nvhost_syncpt_deinit(struct nvhost_syncpt *sp)
        kfree(sp->max_val);
        sp->max_val = NULL;
 
+       kfree(sp->ref);
+       sp->ref = NULL;
+
        kfree(sp->lock_counts);
        sp->lock_counts = NULL;
 
index e548837ad9a439f53331b5e11aa40141943073bf..fb6a5443c0c369ff719a1abe4b354195eac8b381 100644 (file)
@@ -50,6 +50,7 @@ struct nvhost_syncpt {
        atomic_t *min_val;
        atomic_t *max_val;
        atomic_t *lock_counts;
+       atomic_t *ref;
        const char **syncpt_names;
        const char **last_used_by;
        struct nvhost_syncpt_attr *syncpt_attrs;
@@ -176,4 +177,8 @@ int nvhost_syncpt_mark_unused(struct nvhost_syncpt *sp, u32 syncptid);
 int nvhost_syncpt_mark_used(struct nvhost_syncpt *sp,
                            u32 chid, u32 syncptid);
 
+int nvhost_syncpt_get_ref(struct nvhost_syncpt *sp, u32 id);
+void nvhost_syncpt_put_ref(struct nvhost_syncpt *sp, u32 id);
+int nvhost_syncpt_read_ref(struct nvhost_syncpt *sp, u32 id);
+
 #endif
index a874b235f588ead899a34eb2a481997b9ea2c86c..fe77af94a1d88ba1e093011b1fd792ae4c11e4d5 100644 (file)
@@ -395,6 +395,7 @@ u32 nvhost_get_syncpt_host_managed(struct platform_device *pdev,
                                   u32 param);
 u32 nvhost_get_syncpt_host_managed_by_name(const char *syncpt_name);
 void nvhost_free_syncpt(u32 id);
+void nvhost_syncpt_put_ref_ext(u32 id);
 const char *nvhost_syncpt_get_name(struct platform_device *dev, int id);
 u32 nvhost_syncpt_incr_max_ext(struct platform_device *dev, u32 id, u32 incrs);
 void nvhost_syncpt_cpu_incr_ext(struct platform_device *dev, u32 id);