mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-13 14:14:37 +00:00
drm/amdgpu: Implement irq interfaces for CGS
This implements the irq src registrar. Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com> Signed-off-by: Chunming Zhou <David1.Zhou@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
97cb7f6e6c
commit
0cf3be2178
5 changed files with 84 additions and 6 deletions
|
@ -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 */
|
CGS_FUNC_ADEV;
|
||||||
return 0;
|
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 */
|
CGS_FUNC_ADEV;
|
||||||
return 0;
|
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 */
|
CGS_FUNC_ADEV;
|
||||||
return 0;
|
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 = {
|
||||||
|
|
|
@ -206,6 +206,8 @@ int amdgpu_ih_process(struct amdgpu_device *adev)
|
||||||
amdgpu_amdkfd_interrupt(adev,
|
amdgpu_amdkfd_interrupt(adev,
|
||||||
(const void *) &adev->irq.ih.ring[ring_index]);
|
(const void *) &adev->irq.ih.ring[ring_index]);
|
||||||
|
|
||||||
|
entry.iv_entry = (const uint32_t *)
|
||||||
|
&adev->irq.ih.ring[ring_index];
|
||||||
amdgpu_ih_decode_iv(adev, &entry);
|
amdgpu_ih_decode_iv(adev, &entry);
|
||||||
adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
|
adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct amdgpu_iv_entry {
|
||||||
unsigned ring_id;
|
unsigned ring_id;
|
||||||
unsigned vm_id;
|
unsigned vm_id;
|
||||||
unsigned pas_id;
|
unsigned pas_id;
|
||||||
|
const uint32_t *iv_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
|
int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
|
||||||
|
|
|
@ -272,6 +272,11 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
|
||||||
|
|
||||||
kfree(src->enabled_types);
|
kfree(src->enabled_types);
|
||||||
src->enabled_types = NULL;
|
src->enabled_types = NULL;
|
||||||
|
if (src->data) {
|
||||||
|
kfree(src->data);
|
||||||
|
kfree(src);
|
||||||
|
adev->irq.sources[i] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct amdgpu_irq_src {
|
||||||
unsigned num_types;
|
unsigned num_types;
|
||||||
atomic_t *enabled_types;
|
atomic_t *enabled_types;
|
||||||
const struct amdgpu_irq_src_funcs *funcs;
|
const struct amdgpu_irq_src_funcs *funcs;
|
||||||
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* provided by interrupt generating IP blocks */
|
/* provided by interrupt generating IP blocks */
|
||||||
|
|
Loading…
Reference in a new issue