File Index
Files and directories
Sign in
FILE

device.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c C
  1/*
  2 * Copyright 2023 Red Hat Inc.
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 20 * OTHER DEALINGS IN THE SOFTWARE.
 21 */
 22#include <rm/rm.h>
 23
 24#include "nvrm/device.h"
 25#include "nvrm/event.h"
 26
 27static void
 28r535_gsp_event_dtor(struct nvkm_gsp_event *event)
 29{
 30	struct nvkm_gsp_device *device = event->device;
 31	struct nvkm_gsp_client *client = device->object.client;
 32	struct nvkm_gsp *gsp = client->gsp;
 33
 34	mutex_lock(&gsp->client_id.mutex);
 35	if (event->func) {
 36		list_del(&event->head);
 37		event->func = NULL;
 38	}
 39	mutex_unlock(&gsp->client_id.mutex);
 40
 41	nvkm_gsp_rm_free(&event->object);
 42	event->device = NULL;
 43}
 44
 45static int
 46r535_gsp_device_event_get(struct nvkm_gsp_event *event)
 47{
 48	struct nvkm_gsp_device *device = event->device;
 49	NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS *ctrl;
 50
 51	ctrl = nvkm_gsp_rm_ctrl_get(&device->subdevice,
 52				    NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION, sizeof(*ctrl));
 53	if (IS_ERR(ctrl))
 54		return PTR_ERR(ctrl);
 55
 56	ctrl->event = event->id;
 57	ctrl->action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT;
 58	return nvkm_gsp_rm_ctrl_wr(&device->subdevice, ctrl);
 59}
 60
 61static int
 62r535_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id,
 63			   nvkm_gsp_event_func func, struct nvkm_gsp_event *event)
 64{
 65	struct nvkm_gsp_client *client = device->object.client;
 66	struct nvkm_gsp *gsp = client->gsp;
 67	NV0005_ALLOC_PARAMETERS *args;
 68	int ret;
 69
 70	args = nvkm_gsp_rm_alloc_get(&device->subdevice, handle,
 71				     NV01_EVENT_KERNEL_CALLBACK_EX, sizeof(*args),
 72				     &event->object);
 73	if (IS_ERR(args))
 74		return PTR_ERR(args);
 75
 76	args->hParentClient = client->object.handle;
 77	args->hSrcResource = 0;
 78	args->hClass = NV01_EVENT_KERNEL_CALLBACK_EX;
 79	args->notifyIndex = NV01_EVENT_CLIENT_RM | id;
 80	args->data = NULL;
 81
 82	ret = nvkm_gsp_rm_alloc_wr(&event->object, args);
 83	if (ret)
 84		return ret;
 85
 86	event->device = device;
 87	event->id = id;
 88
 89	ret = r535_gsp_device_event_get(event);
 90	if (ret) {
 91		nvkm_gsp_event_dtor(event);
 92		return ret;
 93	}
 94
 95	mutex_lock(&gsp->client_id.mutex);
 96	event->func = func;
 97	list_add(&event->head, &client->events);
 98	mutex_unlock(&gsp->client_id.mutex);
 99	return 0;
100}
101
102static void
103r535_gsp_device_dtor(struct nvkm_gsp_device *device)
104{
105	nvkm_gsp_rm_free(&device->subdevice);
106	nvkm_gsp_rm_free(&device->object);
107}
108
109static int
110r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device)
111{
112	NV2080_ALLOC_PARAMETERS *args;
113
114	return nvkm_gsp_rm_alloc(&device->object, NVKM_RM_SUBDEVICE, NV20_SUBDEVICE_0,
115				 sizeof(*args), &device->subdevice);
116}
117
118static int
119r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
120{
121	NV0080_ALLOC_PARAMETERS *args;
122	int ret;
123
124	args = nvkm_gsp_rm_alloc_get(&client->object, NVKM_RM_DEVICE, NV01_DEVICE_0, sizeof(*args),
125				     &device->object);
126	if (IS_ERR(args))
127		return PTR_ERR(args);
128
129	args->hClientShare = client->object.handle;
130
131	ret = nvkm_gsp_rm_alloc_wr(&device->object, args);
132	if (ret)
133		return ret;
134
135	ret = r535_gsp_subdevice_ctor(device);
136	if (ret)
137		nvkm_gsp_rm_free(&device->object);
138
139	return ret;
140}
141
142const struct nvkm_rm_api_device
143r535_device = {
144	.ctor = r535_gsp_device_ctor,
145	.dtor = r535_gsp_device_dtor,
146	.event.ctor = r535_gsp_device_event_ctor,
147	.event.dtor = r535_gsp_event_dtor,
148};
~/ Read-only file preview.