diff --git a/Makefile b/Makefile index 125a690..7575e44 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,7 @@ COMPILE_TESTS = \ nvmap_support \ acpi_evaluate_integer \ ioremap_cache \ + ioremap_nocache \ ioremap_wc \ proc_dir_entry \ INIT_WORK \ @@ -132,6 +133,7 @@ COMPILE_TESTS = \ proc_create_data \ pde_data \ proc_remove \ + proc_ops \ sg_table \ pm_vt_switch_required \ pci_save_state \ @@ -148,8 +150,10 @@ COMPILE_TESTS = \ vm_fault_has_address \ drm_driver_unload_has_int_return_type \ drm_legacy_pci_init \ + drm_pci_init \ timer_setup \ do_gettimeofday \ + timeval \ drm_gem_object_put_unlocked \ drm_driver_legacy_feature_bit_present \ drm_driver_prime_flag_present diff --git a/conftest.sh b/conftest.sh index b7a85f0..08b20cd 100755 --- a/conftest.sh +++ b/conftest.sh @@ -1188,6 +1188,19 @@ compile_test() { compile_check_conftest "$CODE" "NV_IOREMAP_CACHE_PRESENT" "" "functions" ;; + ioremap_nocache) + # + # Determine if the ioremap_nocache() function is present. + # + CODE=" + #include + void conftest_ioremap_nocache(void) { + ioremap_nocache(); + }" + + compile_check_conftest "$CODE" "NV_IOREMAP_NOCACHE_PRESENT" "" "functions" + ;; + ioremap_wc) # # Determine if the ioremap_wc() function is present. @@ -1607,6 +1620,19 @@ compile_test() { compile_check_conftest "$CODE" "NV_PROC_REMOVE_PRESENT" "" "functions" ;; + proc_ops) + # + # Determine if struct proc_ops is present. + # + CODE=" + #include + void conftest_proc_ops(void) { + struct proc_ops pops; + }" + + compile_check_conftest "$CODE" "NV_PROC_OPS_PRESENT" "" "types" + ;; + vm_operations_struct) # # Determine if the 'vm_operations_struct' structure has @@ -2066,6 +2092,28 @@ compile_test() { compile_check_conftest "$CODE" "NV_DRM_LEGACY_PCI_INIT_PRESENT" "" "functions" ;; + drm_pci_init) + # + # Determine if drm_pci_init() is present. drm_pci_init() was + # deprecated and renamed to drm_legacy_pci_init by: + # + # 2017-05-24 10631d724deff712343d96dd3017cd323349f761 + # + CODE=" + #if defined(NV_DRM_DRMP_H_PRESENT) + #include + #endif + + #if defined(NV_DRM_DRM_PCI_H_PRESENT) + #include + #endif + void conftest_drm_pci_init(void) { + drm_pci_init(); + }" + + compile_check_conftest "$CODE" "NV_DRM_PCI_INIT_PRESENT" "" "functions" + ;; + timer_setup) # # Determine if the function timer_setup() is present. @@ -2109,6 +2157,22 @@ compile_test() { compile_check_conftest "$CODE" "NV_DO_GETTIMEOFDAY_PRESENT" "" "functions" ;; + timeval) + # + # Determine if timeval is present. + # + CODE=" + #include + #if defined(NV_LINUX_KTIME_H_PRESENT) + #include + #endif + void conftest_timeval(void) { + struct timeval tv; + }" + + compile_check_conftest "$CODE" "NV_TIMEVAL_PRESENT" "" "types" + ;; + drm_gem_object_put_unlocked) # # Determine if the function drm_gem_object_put_unlocked() is present. diff --git a/nv-drm.c b/nv-drm.c index 0d1cdbf..4e6fa48 100644 --- a/nv-drm.c +++ b/nv-drm.c @@ -47,7 +47,61 @@ #include #endif -#if defined(NV_DRM_LEGACY_PCI_INIT_PRESENT) +#if !defined(NV_DRM_LEGACY_PCI_INIT_PRESENT) && !defined(NV_DRM_PCI_INIT_PRESENT) +static int nv_drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) +{ + struct pci_dev *pdev = NULL; + const struct pci_device_id *pid; + int i; + + DRM_DEBUG("\n"); + + if (WARN_ON(!(driver->driver_features & DRIVER_LEGACY))) + return -EINVAL; + + /* If not using KMS, fall back to stealth mode manual scanning. */ + INIT_LIST_HEAD(&driver->legacy_dev_list); + for (i = 0; pdriver->id_table[i].vendor != 0; i++) { + pid = &pdriver->id_table[i]; + + /* Loop around setting up a DRM device for each PCI device + * matching our ID and device class. If we had the internal + * function that pci_get_subsys and pci_get_class used, we'd + * be able to just pass pid in instead of doing a two-stage + * thing. + */ + pdev = NULL; + while ((pdev = + pci_get_subsys(pid->vendor, pid->device, pid->subvendor, + pid->subdevice, pdev)) != NULL) { + if ((pdev->class & pid->class_mask) != pid->class) + continue; + + /* stealth mode requires a manual probe */ + pci_dev_get(pdev); + drm_get_pci_dev(pdev, pid, driver); + } + } + return 0; +} + +static void nv_drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) +{ + struct drm_device *dev, *tmp; + DRM_DEBUG("\n"); + + if (!(driver->driver_features & DRIVER_LEGACY)) { + WARN_ON(1); + } else { + list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, + legacy_dev_list) { + list_del(&dev->legacy_dev_list); + drm_put_dev(dev); + } + } + DRM_INFO("Module unloaded\n"); +} +#elif defined(NV_DRM_LEGACY_PCI_INIT_PRESENT) #define nv_drm_pci_init drm_legacy_pci_init #define nv_drm_pci_exit drm_legacy_pci_exit #else diff --git a/nv-linux.h b/nv-linux.h index b90eb95..1d709a3 100644 --- a/nv-linux.h +++ b/nv-linux.h @@ -688,11 +688,15 @@ extern nv_spinlock_t km_lock; VM_ALLOC_RECORD(ptr, size, "vm_ioremap"); \ } +#if defined(NV_IOREMAP_NOCACHE_PRESENT) #define NV_IOREMAP_NOCACHE(ptr, physaddr, size) \ { \ (ptr) = ioremap_nocache(physaddr, size); \ VM_ALLOC_RECORD(ptr, size, "vm_ioremap_nocache"); \ } +#else +#define NV_IOREMAP_NOCACHE NV_IOREMAP +#endif #if defined(NV_IOREMAP_CACHE_PRESENT) #define NV_IOREMAP_CACHE(ptr, physaddr, size) \ @@ -1989,6 +1993,19 @@ extern NvU32 nv_assign_gpu_count; }) #endif +#if defined(NV_PROC_OPS_PRESENT) +#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \ + ({ \ + struct proc_dir_entry *__entry; \ + int mode = (S_IFREG | S_IRUGO); \ + const struct proc_ops *fops = &nv_procfs_##__name##_fops; \ + if (fops->proc_write != 0) \ + mode |= S_IWUSR; \ + __entry = NV_CREATE_PROC_ENTRY(filename, mode, parent, fops, \ + __data); \ + __entry; \ + }) +#else #define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \ ({ \ struct proc_dir_entry *__entry; \ @@ -2000,6 +2017,7 @@ extern NvU32 nv_assign_gpu_count; __data); \ __entry; \ }) +#endif /* * proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0. @@ -2041,6 +2059,24 @@ extern NvU32 nv_assign_gpu_count; remove_proc_entry(entry->name, entry->parent); #endif +#if defined(NV_PROC_OPS_PRESENT) +#define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \ + static int nv_procfs_open_##__name( \ + struct inode *inode, \ + struct file *filep \ + ) \ + { \ + return single_open(filep, nv_procfs_read_##__name, \ + NV_PDE_DATA(inode)); \ + } \ + \ + static const struct proc_ops nv_procfs_##__name##_fops = { \ + .proc_open = nv_procfs_open_##__name, \ + .proc_read = seq_read, \ + .proc_lseek = seq_lseek, \ + .proc_release = single_release, \ + }; +#else #define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \ static int nv_procfs_open_##__name( \ struct inode *inode, \ @@ -2058,6 +2094,7 @@ extern NvU32 nv_assign_gpu_count; .llseek = seq_lseek, \ .release = single_release, \ }; +#endif #endif /* CONFIG_PROC_FS */ diff --git a/nv-procfs.c b/nv-procfs.c index ebca3e8..110cce1 100644 --- a/nv-procfs.c +++ b/nv-procfs.c @@ -409,6 +409,15 @@ done: return ((status < 0) ? status : (int)count); } +#if defined(NV_PROC_OPS_PRESENT) +static struct proc_ops nv_procfs_registry_fops = { + .proc_open = nv_procfs_open_registry, + .proc_read = seq_read, + .proc_write = nv_procfs_write_file, + .proc_lseek = seq_lseek, + .proc_release = nv_procfs_close_registry, +}; +#else static struct file_operations nv_procfs_registry_fops = { .owner = THIS_MODULE, .open = nv_procfs_open_registry, @@ -417,6 +426,7 @@ static struct file_operations nv_procfs_registry_fops = { .llseek = seq_lseek, .release = nv_procfs_close_registry, }; +#endif static int nv_procfs_read_unbind_lock( @@ -538,6 +548,15 @@ done: return rc; } +#if defined(NV_PROC_OPS_PRESENT) +static struct proc_ops nv_procfs_unbind_lock_fops = { + .proc_open = nv_procfs_open_unbind_lock, + .proc_read = seq_read, + .proc_write = nv_procfs_write_file, + .proc_lseek = seq_lseek, + .proc_release = nv_procfs_close_unbind_lock, +}; +#else static struct file_operations nv_procfs_unbind_lock_fops = { .owner = THIS_MODULE, .open = nv_procfs_open_unbind_lock, @@ -546,6 +565,7 @@ static struct file_operations nv_procfs_unbind_lock_fops = { .llseek = seq_lseek, .release = nv_procfs_close_unbind_lock, }; +#endif static int nv_procfs_read_text_file( diff --git a/nv-time.h b/nv-time.h index a34ceb2..c904913 100644 --- a/nv-time.h +++ b/nv-time.h @@ -28,6 +28,10 @@ #include #endif +#if !defined(NV_TIMEVAL_PRESENT) +#define timeval __kernel_old_timeval +#endif + static inline void nv_gettimeofday(struct timeval *tv) { #ifdef NV_DO_GETTIMEOFDAY_PRESENT