Merge tag 'drm-amdkfd-next-2016-02-27' of git://people.freedesktop.org/~gabbayo/linux into drm-next

Here are a few amdkfd patches for 4.6.
These patches defer radeon/amdgpu loading in case amdkfd is not yet loaded,
by returning -EPROBE_DEFER during their probing stage.

* tag 'drm-amdkfd-next-2016-02-27' of git://people.freedesktop.org/~gabbayo/linux:
  drm/amdgpu: Return -EPROBE_DEFER when amdkfd not loaded
  drm/radeon: Return -EPROBE_DEFER when amdkfd not loaded
  drm/amdkfd: Track when module's init is complete
This commit is contained in:
Dave Airlie 2016-03-01 12:33:33 +10:00
commit 9d5d6752c7
8 changed files with 64 additions and 59 deletions

View file

@ -30,25 +30,38 @@ const struct kfd2kgd_calls *kfd2kgd;
const struct kgd2kfd_calls *kgd2kfd; const struct kgd2kfd_calls *kgd2kfd;
bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
bool amdgpu_amdkfd_init(void) int amdgpu_amdkfd_init(void)
{ {
int ret;
#if defined(CONFIG_HSA_AMD_MODULE) #if defined(CONFIG_HSA_AMD_MODULE)
bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); int (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
kgd2kfd_init_p = symbol_request(kgd2kfd_init); kgd2kfd_init_p = symbol_request(kgd2kfd_init);
if (kgd2kfd_init_p == NULL) if (kgd2kfd_init_p == NULL)
return false; return -ENOENT;
ret = kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd);
if (ret) {
symbol_put(kgd2kfd_init);
kgd2kfd = NULL;
}
#elif defined(CONFIG_HSA_AMD)
ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd);
if (ret)
kgd2kfd = NULL;
#else
ret = -ENOENT;
#endif #endif
return true;
return ret;
} }
bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev) bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev)
{ {
#if defined(CONFIG_HSA_AMD_MODULE)
bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
#endif
switch (rdev->asic_type) { switch (rdev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_CIK #ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_KAVERI: case CHIP_KAVERI:
@ -62,35 +75,7 @@ bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev)
return false; return false;
} }
#if defined(CONFIG_HSA_AMD_MODULE)
kgd2kfd_init_p = symbol_request(kgd2kfd_init);
if (kgd2kfd_init_p == NULL) {
kfd2kgd = NULL;
return false;
}
if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd)) {
symbol_put(kgd2kfd_init);
kfd2kgd = NULL;
kgd2kfd = NULL;
return false;
}
return true; return true;
#elif defined(CONFIG_HSA_AMD)
if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd)) {
kfd2kgd = NULL;
kgd2kfd = NULL;
return false;
}
return true;
#else
kfd2kgd = NULL;
return false;
#endif
} }
void amdgpu_amdkfd_fini(void) void amdgpu_amdkfd_fini(void)

View file

@ -36,7 +36,7 @@ struct kgd_mem {
void *cpu_ptr; void *cpu_ptr;
}; };
bool amdgpu_amdkfd_init(void); int amdgpu_amdkfd_init(void);
void amdgpu_amdkfd_fini(void); void amdgpu_amdkfd_fini(void);
bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev); bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev);

View file

@ -310,6 +310,14 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
return -ENODEV; return -ENODEV;
} }
/*
* Initialize amdkfd before starting radeon. If it was not loaded yet,
* defer radeon probing
*/
ret = amdgpu_amdkfd_init();
if (ret == -EPROBE_DEFER)
return ret;
/* Get rid of things like offb */ /* Get rid of things like offb */
ret = amdgpu_kick_out_firmware_fb(pdev); ret = amdgpu_kick_out_firmware_fb(pdev);
if (ret) if (ret)
@ -552,8 +560,6 @@ static int __init amdgpu_init(void)
driver->num_ioctls = amdgpu_max_kms_ioctl; driver->num_ioctls = amdgpu_max_kms_ioctl;
amdgpu_register_atpx_handler(); amdgpu_register_atpx_handler();
amdgpu_amdkfd_init();
/* let modprobe override vga console setting */ /* let modprobe override vga console setting */
return drm_pci_init(driver, pdriver); return drm_pci_init(driver, pdriver);
} }

View file

@ -59,18 +59,23 @@ module_param(send_sigterm, int, 0444);
MODULE_PARM_DESC(send_sigterm, MODULE_PARM_DESC(send_sigterm,
"Send sigterm to HSA process on unhandled exception (0 = disable, 1 = enable)"); "Send sigterm to HSA process on unhandled exception (0 = disable, 1 = enable)");
bool kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f) static int amdkfd_init_completed;
int kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f)
{ {
if (!amdkfd_init_completed)
return -EPROBE_DEFER;
/* /*
* Only one interface version is supported, * Only one interface version is supported,
* no kfd/kgd version skew allowed. * no kfd/kgd version skew allowed.
*/ */
if (interface_version != KFD_INTERFACE_VERSION) if (interface_version != KFD_INTERFACE_VERSION)
return false; return -EINVAL;
*g2f = &kgd2kfd; *g2f = &kgd2kfd;
return true; return 0;
} }
EXPORT_SYMBOL(kgd2kfd_init); EXPORT_SYMBOL(kgd2kfd_init);
@ -111,6 +116,8 @@ static int __init kfd_module_init(void)
kfd_process_create_wq(); kfd_process_create_wq();
amdkfd_init_completed = 1;
dev_info(kfd_device, "Initialized module\n"); dev_info(kfd_device, "Initialized module\n");
return 0; return 0;
@ -125,6 +132,8 @@ err_pasid:
static void __exit kfd_module_exit(void) static void __exit kfd_module_exit(void)
{ {
amdkfd_init_completed = 0;
kfd_process_destroy_wq(); kfd_process_destroy_wq();
kfd_topology_shutdown(); kfd_topology_shutdown();
kfd_chardev_exit(); kfd_chardev_exit();

View file

@ -221,7 +221,7 @@ struct kgd2kfd_calls {
int (*resume)(struct kfd_dev *kfd); int (*resume)(struct kfd_dev *kfd);
}; };
bool kgd2kfd_init(unsigned interface_version, int kgd2kfd_init(unsigned interface_version,
const struct kgd2kfd_calls **g2f); const struct kgd2kfd_calls **g2f);
#endif /* KGD_KFD_INTERFACE_H_INCLUDED */ #endif /* KGD_KFD_INTERFACE_H_INCLUDED */

View file

@ -321,6 +321,14 @@ static int radeon_pci_probe(struct pci_dev *pdev,
{ {
int ret; int ret;
/*
* Initialize amdkfd before starting radeon. If it was not loaded yet,
* defer radeon probing
*/
ret = radeon_kfd_init();
if (ret == -EPROBE_DEFER)
return ret;
/* /*
* apple-gmux is needed on dual GPU MacBook Pro * apple-gmux is needed on dual GPU MacBook Pro
* to probe the panel if we're the inactive GPU. * to probe the panel if we're the inactive GPU.
@ -581,8 +589,6 @@ static int __init radeon_init(void)
return -EINVAL; return -EINVAL;
} }
radeon_kfd_init();
/* let modprobe override vga console setting */ /* let modprobe override vga console setting */
return drm_pci_init(driver, pdriver); return drm_pci_init(driver, pdriver);
} }

View file

@ -132,35 +132,34 @@ static const struct kfd2kgd_calls kfd2kgd = {
static const struct kgd2kfd_calls *kgd2kfd; static const struct kgd2kfd_calls *kgd2kfd;
bool radeon_kfd_init(void) int radeon_kfd_init(void)
{ {
int ret;
#if defined(CONFIG_HSA_AMD_MODULE) #if defined(CONFIG_HSA_AMD_MODULE)
bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); int (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
kgd2kfd_init_p = symbol_request(kgd2kfd_init); kgd2kfd_init_p = symbol_request(kgd2kfd_init);
if (kgd2kfd_init_p == NULL) if (kgd2kfd_init_p == NULL)
return false; return -ENOENT;
if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd)) { ret = kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd);
if (ret) {
symbol_put(kgd2kfd_init); symbol_put(kgd2kfd_init);
kgd2kfd = NULL; kgd2kfd = NULL;
return false;
} }
return true;
#elif defined(CONFIG_HSA_AMD) #elif defined(CONFIG_HSA_AMD)
if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd)) { ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd);
if (ret)
kgd2kfd = NULL; kgd2kfd = NULL;
return false;
}
return true;
#else #else
return false; ret = -ENOENT;
#endif #endif
return ret;
} }
void radeon_kfd_fini(void) void radeon_kfd_fini(void)

View file

@ -33,7 +33,7 @@
struct radeon_device; struct radeon_device;
bool radeon_kfd_init(void); int radeon_kfd_init(void);
void radeon_kfd_fini(void); void radeon_kfd_fini(void);
void radeon_kfd_suspend(struct radeon_device *rdev); void radeon_kfd_suspend(struct radeon_device *rdev);