diff options
author | Thierry Reding <treding@nvidia.com> | 2021-03-26 15:51:37 +0100 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2021-03-31 17:42:14 +0200 |
commit | 933deb8c7b8e3f83e3dbd0b08e3cad51350d44c4 (patch) | |
tree | bdd54dfae367ef43c934c7073ffada9d63f77dd7 /drivers/gpu/host1x | |
parent | gpu: host1x: Fix Tegra194 syncpt interrupt threshold (diff) | |
download | linux-933deb8c7b8e3f83e3dbd0b08e3cad51350d44c4.tar.xz linux-933deb8c7b8e3f83e3dbd0b08e3cad51350d44c4.zip |
gpu: host1x: Add early init and late exit callbacks
These callbacks can be used by client drivers to run code during early
init and during late exit. Early init callbacks are run prior to the
regular init callbacks while late exit callbacks run after the regular
exit callbacks.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/host1x')
-rw-r--r-- | drivers/gpu/host1x/bus.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 68a766ff0e9d..46f69c532b6b 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -197,6 +197,17 @@ int host1x_device_init(struct host1x_device *device) mutex_lock(&device->clients_lock); list_for_each_entry(client, &device->clients, list) { + if (client->ops && client->ops->early_init) { + err = client->ops->early_init(client); + if (err < 0) { + dev_err(&device->dev, "failed to early initialize %s: %d\n", + dev_name(client->dev), err); + goto teardown_late; + } + } + } + + list_for_each_entry(client, &device->clients, list) { if (client->ops && client->ops->init) { err = client->ops->init(client); if (err < 0) { @@ -217,6 +228,14 @@ teardown: if (client->ops->exit) client->ops->exit(client); + /* reset client to end of list for late teardown */ + client = list_entry(&device->clients, struct host1x_client, list); + +teardown_late: + list_for_each_entry_continue_reverse(client, &device->clients, list) + if (client->ops->late_exit) + client->ops->late_exit(client); + mutex_unlock(&device->clients_lock); return err; } @@ -251,6 +270,18 @@ int host1x_device_exit(struct host1x_device *device) } } + list_for_each_entry_reverse(client, &device->clients, list) { + if (client->ops && client->ops->late_exit) { + err = client->ops->late_exit(client); + if (err < 0) { + dev_err(&device->dev, "failed to late cleanup %s: %d\n", + dev_name(client->dev), err); + mutex_unlock(&device->clients_lock); + return err; + } + } + } + mutex_unlock(&device->clients_lock); return 0; |