|
@@ -290,26 +290,95 @@ static int amdgpu_cgs_set_camera_voltages(void *cgs_device, uint32_t mask,
|
|
return -EPERM;
|
|
return -EPERM;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct cgs_irq_params {
|
|
|
|
+ unsigned src_id;
|
|
|
|
+ cgs_irq_source_set_func_t set;
|
|
|
|
+ cgs_irq_handler_func_t handler;
|
|
|
|
+ void *private_data;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static int cgs_set_irq_state(struct amdgpu_device *adev,
|
|
|
|
+ struct amdgpu_irq_src *src,
|
|
|
|
+ unsigned type,
|
|
|
|
+ enum amdgpu_interrupt_state state)
|
|
|
|
+{
|
|
|
|
+ struct cgs_irq_params *irq_params =
|
|
|
|
+ (struct cgs_irq_params *)src->data;
|
|
|
|
+ if (!irq_params)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (!irq_params->set)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ return irq_params->set(irq_params->private_data,
|
|
|
|
+ irq_params->src_id,
|
|
|
|
+ type,
|
|
|
|
+ (int)state);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int cgs_process_irq(struct amdgpu_device *adev,
|
|
|
|
+ struct amdgpu_irq_src *source,
|
|
|
|
+ struct amdgpu_iv_entry *entry)
|
|
|
|
+{
|
|
|
|
+ struct cgs_irq_params *irq_params =
|
|
|
|
+ (struct cgs_irq_params *)source->data;
|
|
|
|
+ if (!irq_params)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (!irq_params->handler)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ return irq_params->handler(irq_params->private_data,
|
|
|
|
+ irq_params->src_id,
|
|
|
|
+ entry->iv_entry);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const struct amdgpu_irq_src_funcs cgs_irq_funcs = {
|
|
|
|
+ .set = cgs_set_irq_state,
|
|
|
|
+ .process = cgs_process_irq,
|
|
|
|
+};
|
|
|
|
+
|
|
static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id,
|
|
static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id,
|
|
unsigned num_types,
|
|
unsigned num_types,
|
|
cgs_irq_source_set_func_t set,
|
|
cgs_irq_source_set_func_t set,
|
|
cgs_irq_handler_func_t handler,
|
|
cgs_irq_handler_func_t handler,
|
|
void *private_data)
|
|
void *private_data)
|
|
{
|
|
{
|
|
- /* TODO */
|
|
|
|
- return 0;
|
|
|
|
|
|
+ CGS_FUNC_ADEV;
|
|
|
|
+ int ret = 0;
|
|
|
|
+ struct cgs_irq_params *irq_params;
|
|
|
|
+ struct amdgpu_irq_src *source =
|
|
|
|
+ kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
|
|
|
|
+ if (!source)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ irq_params =
|
|
|
|
+ kzalloc(sizeof(struct cgs_irq_params), GFP_KERNEL);
|
|
|
|
+ if (!irq_params) {
|
|
|
|
+ kfree(source);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ source->num_types = num_types;
|
|
|
|
+ source->funcs = &cgs_irq_funcs;
|
|
|
|
+ irq_params->src_id = src_id;
|
|
|
|
+ irq_params->set = set;
|
|
|
|
+ irq_params->handler = handler;
|
|
|
|
+ irq_params->private_data = private_data;
|
|
|
|
+ source->data = (void *)irq_params;
|
|
|
|
+ ret = amdgpu_irq_add_id(adev, src_id, source);
|
|
|
|
+ if (ret) {
|
|
|
|
+ kfree(irq_params);
|
|
|
|
+ kfree(source);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type)
|
|
static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type)
|
|
{
|
|
{
|
|
- /* TODO */
|
|
|
|
- return 0;
|
|
|
|
|
|
+ CGS_FUNC_ADEV;
|
|
|
|
+ return amdgpu_irq_get(adev, adev->irq.sources[src_id], type);
|
|
}
|
|
}
|
|
|
|
|
|
static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type)
|
|
static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type)
|
|
{
|
|
{
|
|
- /* TODO */
|
|
|
|
- return 0;
|
|
|
|
|
|
+ CGS_FUNC_ADEV;
|
|
|
|
+ return amdgpu_irq_put(adev, adev->irq.sources[src_id], type);
|
|
}
|
|
}
|
|
|
|
|
|
static const struct cgs_ops amdgpu_cgs_ops = {
|
|
static const struct cgs_ops amdgpu_cgs_ops = {
|