gpu: host1x: Allow syncpoints without associated client
authorMikko Perttunen <mperttunen@nvidia.com>
Mon, 29 Mar 2021 13:38:28 +0000 (16:38 +0300)
committerThierry Reding <treding@nvidia.com>
Tue, 30 Mar 2021 17:53:24 +0000 (19:53 +0200)
Syncpoints don't need to be associated with any client,
so remove the property, and expose host1x_syncpt_alloc.
This will allow allocating syncpoints without prior knowledge
of the engine that it will be used with.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/host1x/syncpt.c
drivers/gpu/host1x/syncpt.h
include/linux/host1x.h

index fce7892..9a11301 100644 (file)
@@ -42,13 +42,28 @@ static void host1x_syncpt_base_free(struct host1x_syncpt_base *base)
                base->requested = false;
 }
 
-static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
-                                                struct host1x_client *client,
-                                                unsigned long flags)
+/**
+ * host1x_syncpt_alloc() - allocate a syncpoint
+ * @host: host1x device data
+ * @flags: bitfield of HOST1X_SYNCPT_* flags
+ * @name: name for the syncpoint for use in debug prints
+ *
+ * Allocates a hardware syncpoint for the caller's use. The caller then has
+ * the sole authority to mutate the syncpoint's value until it is freed again.
+ *
+ * If no free syncpoints are available, or a NULL name was specified, returns
+ * NULL.
+ */
+struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
+                                         unsigned long flags,
+                                         const char *name)
 {
        struct host1x_syncpt *sp = host->syncpt;
+       char *full_name;
        unsigned int i;
-       char *name;
+
+       if (!name)
+               return NULL;
 
        mutex_lock(&host->syncpt_mutex);
 
@@ -64,13 +79,11 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
                        goto unlock;
        }
 
-       name = kasprintf(GFP_KERNEL, "%02u-%s", sp->id,
-                        client ? dev_name(client->dev) : NULL);
-       if (!name)
+       full_name = kasprintf(GFP_KERNEL, "%u-%s", sp->id, name);
+       if (!full_name)
                goto free_base;
 
-       sp->client = client;
-       sp->name = name;
+       sp->name = full_name;
 
        if (flags & HOST1X_SYNCPT_CLIENT_MANAGED)
                sp->client_managed = true;
@@ -87,6 +100,7 @@ unlock:
        mutex_unlock(&host->syncpt_mutex);
        return NULL;
 }
+EXPORT_SYMBOL(host1x_syncpt_alloc);
 
 /**
  * host1x_syncpt_id() - retrieve syncpoint ID
@@ -401,7 +415,7 @@ int host1x_syncpt_init(struct host1x *host)
        host1x_hw_syncpt_enable_protection(host);
 
        /* Allocate sync point to use for clearing waits for expired fences */
-       host->nop_sp = host1x_syncpt_alloc(host, NULL, 0);
+       host->nop_sp = host1x_syncpt_alloc(host, 0, "reserved-nop");
        if (!host->nop_sp)
                return -ENOMEM;
 
@@ -423,7 +437,7 @@ struct host1x_syncpt *host1x_syncpt_request(struct host1x_client *client,
 {
        struct host1x *host = dev_get_drvdata(client->host->parent);
 
-       return host1x_syncpt_alloc(host, client, flags);
+       return host1x_syncpt_alloc(host, flags, dev_name(client->dev));
 }
 EXPORT_SYMBOL(host1x_syncpt_request);
 
@@ -447,7 +461,6 @@ void host1x_syncpt_free(struct host1x_syncpt *sp)
        host1x_syncpt_base_free(sp->base);
        kfree(sp->name);
        sp->base = NULL;
-       sp->client = NULL;
        sp->name = NULL;
        sp->client_managed = false;
 
index 8e1d04d..3aa6b25 100644 (file)
@@ -33,7 +33,6 @@ struct host1x_syncpt {
        const char *name;
        bool client_managed;
        struct host1x *host;
-       struct host1x_client *client;
        struct host1x_syncpt_base *base;
 
        /* interrupt data */
index 9eb77c8..7137ce0 100644 (file)
@@ -154,6 +154,9 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
 struct host1x_syncpt *host1x_syncpt_request(struct host1x_client *client,
                                            unsigned long flags);
 void host1x_syncpt_free(struct host1x_syncpt *sp);
+struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
+                                         unsigned long flags,
+                                         const char *name);
 
 struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp);
 u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base);