From 0cf3be21782f8d5b74cce98a2b934e14ef418ef3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 28 Jul 2015 14:24:53 -0400 Subject: drm/amdgpu: Implement irq interfaces for CGS This implements the irq src registrar. Reviewed-by: Jammy Zhou Signed-off-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 81 ++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 6ac3df856b49..93fbf3551111 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -290,26 +290,95 @@ static int amdgpu_cgs_set_camera_voltages(void *cgs_device, uint32_t mask, 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, unsigned num_types, cgs_irq_source_set_func_t set, cgs_irq_handler_func_t handler, 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) { - /* 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) { - /* 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 = { -- cgit v1.2.3-59-g8ed1b