drm/amdkfd: Fix doorbell initialization and finalization
Handle errors in doorbell aperture initialization instead of BUG_ON. iounmap doorbell aperture during finalization. Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
parent
4f52f2256e
commit
735df2ba1d
@ -260,7 +260,11 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||||||
goto kfd_gtt_sa_init_error;
|
goto kfd_gtt_sa_init_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfd_doorbell_init(kfd);
|
if (kfd_doorbell_init(kfd)) {
|
||||||
|
dev_err(kfd_device,
|
||||||
|
"Error initializing doorbell aperture\n");
|
||||||
|
goto kfd_doorbell_error;
|
||||||
|
}
|
||||||
|
|
||||||
if (kfd_topology_add_device(kfd)) {
|
if (kfd_topology_add_device(kfd)) {
|
||||||
dev_err(kfd_device, "Error adding device to topology\n");
|
dev_err(kfd_device, "Error adding device to topology\n");
|
||||||
@ -315,6 +319,8 @@ device_iommu_pasid_error:
|
|||||||
kfd_interrupt_error:
|
kfd_interrupt_error:
|
||||||
kfd_topology_remove_device(kfd);
|
kfd_topology_remove_device(kfd);
|
||||||
kfd_topology_add_device_error:
|
kfd_topology_add_device_error:
|
||||||
|
kfd_doorbell_fini(kfd);
|
||||||
|
kfd_doorbell_error:
|
||||||
kfd_gtt_sa_fini(kfd);
|
kfd_gtt_sa_fini(kfd);
|
||||||
kfd_gtt_sa_init_error:
|
kfd_gtt_sa_init_error:
|
||||||
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
|
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
|
||||||
@ -332,6 +338,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
|
|||||||
amd_iommu_free_device(kfd->pdev);
|
amd_iommu_free_device(kfd->pdev);
|
||||||
kfd_interrupt_exit(kfd);
|
kfd_interrupt_exit(kfd);
|
||||||
kfd_topology_remove_device(kfd);
|
kfd_topology_remove_device(kfd);
|
||||||
|
kfd_doorbell_fini(kfd);
|
||||||
kfd_gtt_sa_fini(kfd);
|
kfd_gtt_sa_fini(kfd);
|
||||||
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
|
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ static inline size_t doorbell_process_allocation(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Doorbell calculations for device init. */
|
/* Doorbell calculations for device init. */
|
||||||
void kfd_doorbell_init(struct kfd_dev *kfd)
|
int kfd_doorbell_init(struct kfd_dev *kfd)
|
||||||
{
|
{
|
||||||
size_t doorbell_start_offset;
|
size_t doorbell_start_offset;
|
||||||
size_t doorbell_aperture_size;
|
size_t doorbell_aperture_size;
|
||||||
@ -95,7 +95,8 @@ void kfd_doorbell_init(struct kfd_dev *kfd)
|
|||||||
kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
|
kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
|
||||||
doorbell_process_allocation());
|
doorbell_process_allocation());
|
||||||
|
|
||||||
BUG_ON(!kfd->doorbell_kernel_ptr);
|
if (!kfd->doorbell_kernel_ptr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
pr_debug("Doorbell initialization:\n");
|
pr_debug("Doorbell initialization:\n");
|
||||||
pr_debug("doorbell base == 0x%08lX\n",
|
pr_debug("doorbell base == 0x%08lX\n",
|
||||||
@ -115,6 +116,14 @@ void kfd_doorbell_init(struct kfd_dev *kfd)
|
|||||||
|
|
||||||
pr_debug("doorbell kernel address == 0x%08lX\n",
|
pr_debug("doorbell kernel address == 0x%08lX\n",
|
||||||
(uintptr_t)kfd->doorbell_kernel_ptr);
|
(uintptr_t)kfd->doorbell_kernel_ptr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kfd_doorbell_fini(struct kfd_dev *kfd)
|
||||||
|
{
|
||||||
|
if (kfd->doorbell_kernel_ptr)
|
||||||
|
iounmap(kfd->doorbell_kernel_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
|
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
|
||||||
|
@ -576,7 +576,8 @@ unsigned int kfd_pasid_alloc(void);
|
|||||||
void kfd_pasid_free(unsigned int pasid);
|
void kfd_pasid_free(unsigned int pasid);
|
||||||
|
|
||||||
/* Doorbells */
|
/* Doorbells */
|
||||||
void kfd_doorbell_init(struct kfd_dev *kfd);
|
int kfd_doorbell_init(struct kfd_dev *kfd);
|
||||||
|
void kfd_doorbell_fini(struct kfd_dev *kfd);
|
||||||
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
|
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
|
||||||
u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
|
u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
|
||||||
unsigned int *doorbell_off);
|
unsigned int *doorbell_off);
|
||||||
|
Loading…
Reference in New Issue
Block a user