+Author: Andreas Beckmann <anbe@debian.org>
+Bug-Debian: http://bugs.debian.org/717361
+Description: adjust for kernel 3.10 procfs interface changes
+ backported from 304.108
+
+diff --git a/kernel/nv-procfs.c b/kernel/nv-procfs.c
+index 3e05ef5..7a9fb70 100644
+--- a/kernel/nv-procfs.c
++++ b/kernel/nv-procfs.c
+@@ -51,69 +51,106 @@ static char nv_registry_keys[NV_MAX_REGISTRY_KEYS_LENGTH];
+ #define NV_SET_PROC_ENTRY_OWNER(entry)
+ #endif
+
+-#define NV_CREATE_PROC_ENTRY(name,mode,parent) \
+- ({ \
+- struct proc_dir_entry *__entry; \
+- __entry = create_proc_entry(name, mode, parent); \
+- if (__entry != NULL) \
+- NV_SET_PROC_ENTRY_OWNER(__entry); \
+- __entry; \
++#if defined(NV_PROC_CREATE_DATA_PRESENT)
++# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \
++ proc_create_data(name, __mode, parent, fops, __data)
++#else
++# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \
++ ({ \
++ struct proc_dir_entry *__entry; \
++ __entry = create_proc_entry(name, mode, parent); \
++ if (__entry != NULL) \
++ { \
++ NV_SET_PROC_ENTRY_OWNER(__entry); \
++ __entry->proc_fops = fops; \
++ __entry->data = (__data); \
++ } \
++ __entry; \
++ })
++#endif
++
++#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
++ ({ \
++ struct proc_dir_entry *__entry; \
++ int __mode = (S_IFREG | S_IRUGO); \
++ const struct file_operations *fops = &nv_procfs_##__name##_fops; \
++ if (fops->write != 0) \
++ __mode |= S_IWUSR; \
++ __entry = NV_CREATE_PROC_ENTRY(filename, __mode, parent, fops, \
++ __data); \
++ __entry; \
+ })
+
+-#define NV_CREATE_PROC_FILE(name,parent,__read_proc, \
+- __write_proc,__fops,__data) \
++/*
++ * proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0.
++ * Use the older interface instead unless the newer interface is necessary.
++ */
++#if defined(NV_PROC_REMOVE_PRESENT)
++# define NV_PROC_MKDIR_MODE(name, mode, parent) \
++ proc_mkdir_mode(name, mode, parent)
++#else
++# define NV_PROC_MKDIR_MODE(name, mode, parent) \
+ ({ \
+ struct proc_dir_entry *__entry; \
+- int __mode = (S_IFREG | S_IRUGO); \
+- if ((NvUPtr)(__write_proc) != 0) \
+- __mode |= S_IWUSR; \
+- __entry = NV_CREATE_PROC_ENTRY(name, __mode, parent); \
++ __entry = create_proc_entry(name, mode, parent); \
+ if (__entry != NULL) \
+- { \
+- if ((NvUPtr)(__read_proc) != 0) \
+- __entry->read_proc = (__read_proc); \
+- if ((NvUPtr)(__write_proc) != 0) \
+- { \
+- __entry->write_proc = (__write_proc); \
+- __entry->proc_fops = (__fops); \
+- } \
+- __entry->data = (__data); \
+- } \
++ NV_SET_PROC_ENTRY_OWNER(__entry); \
+ __entry; \
+ })
++#endif
+
+ #define NV_CREATE_PROC_DIR(name,parent) \
+ ({ \
+ struct proc_dir_entry *__entry; \
+ int __mode = (S_IFDIR | S_IRUGO | S_IXUGO); \
+- __entry = NV_CREATE_PROC_ENTRY(name, __mode, parent); \
++ __entry = NV_PROC_MKDIR_MODE(name, __mode, parent); \
+ __entry; \
+ })
+
++#if defined(NV_PDE_DATA_PRESENT)
++# define NV_PDE_DATA(inode) PDE_DATA(inode)
++#else
++# define NV_PDE_DATA(inode) PDE(inode)->data
++#endif
++
++#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 file_operations nv_procfs_##__name##_fops = { \
++ .owner = THIS_MODULE, \
++ .open = nv_procfs_open_##__name, \
++ .read = seq_read, \
++ .llseek = seq_lseek, \
++ .release = single_release, \
++ };
++
++static int nv_procfs_read_registry(struct seq_file *s, void *v);
++
+ #define NV_PROC_WRITE_BUFFER_SIZE (64 * RM_PAGE_SIZE)
+
+ static int
+ nv_procfs_read_gpu_info(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+- nv_state_t *nv = data;
++ nv_state_t *nv = s->private;
+ nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv);
+ struct pci_dev *dev = nvl->dev;
+ char *type, *fmt, tmpstr[NV_DEVICE_NAME_LENGTH];
+- int len = 0, status;
++ int status;
+ NvU8 *uuid;
+ NvU32 vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4, vbios_rev5;
+ NvU32 fpga_rev1, fpga_rev2, fpga_rev3;
+ nv_stack_t *sp = NULL;
+
+- *eof = 1;
+-
+ NV_KMEM_CACHE_ALLOC_STACK(sp);
+ if (sp == NULL)
+ {
+@@ -139,26 +176,26 @@ nv_procfs_read_gpu_info(
+ }
+ }
+
+- len += sprintf(page+len, "Model: \t\t %s\n", tmpstr);
+- len += sprintf(page+len, "IRQ: \t\t %d\n", nv->interrupt_line);
++ seq_printf(s, "Model: \t\t %s\n", tmpstr);
++ seq_printf(s, "IRQ: \t\t %d\n", nv->interrupt_line);
+
+ if (NV_IS_GVI_DEVICE(nv))
+ {
+ status = rm_gvi_get_firmware_version(sp, nv, &fpga_rev1, &fpga_rev2,
+ &fpga_rev3);
+ if (status != RM_OK)
+- len += sprintf(page+len, "Firmware: \t ????.??.??\n");
++ seq_printf(s, "Firmware: \t ????.??.??\n");
+ else
+ {
+ fmt = "Firmware: \t %x.%x.%x\n";
+- len += sprintf(page+len, fmt, fpga_rev1, fpga_rev2, fpga_rev3);
++ seq_printf(s, fmt, fpga_rev1, fpga_rev2, fpga_rev3);
+ }
+ }
+ else
+ {
+ if (rm_get_gpu_uuid(sp, nv, &uuid, NULL) == RM_OK)
+ {
+- len += sprintf(page+len, "GPU UUID: \t %s\n", (char *)uuid);
++ seq_printf(s, "GPU UUID: \t %s\n", (char *)uuid);
+ os_free_mem(uuid);
+ }
+
+@@ -166,65 +203,62 @@ nv_procfs_read_gpu_info(
+ &vbios_rev3, &vbios_rev4,
+ &vbios_rev5) != RM_OK)
+ {
+- len += sprintf(page+len, "Video BIOS: \t ??.??.??.??.??\n");
++ seq_printf(s, "Video BIOS: \t ??.??.??.??.??\n");
+ }
+ else
+ {
+ fmt = "Video BIOS: \t %02x.%02x.%02x.%02x.%02x\n";
+- len += sprintf(page+len, fmt, vbios_rev1, vbios_rev2, vbios_rev3,
+- vbios_rev4, vbios_rev5);
++ seq_printf(s, fmt, vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4,
++ vbios_rev5);
+ }
+ }
+
+ if (nv_find_pci_capability(dev, PCI_CAP_ID_AGP))
+ type = "AGP";
+ else if (nv_find_pci_capability(dev, PCI_CAP_ID_EXP))
+- type = "PCI-E";
++ type = "PCIe";
+ else
+ type = "PCI";
+- len += sprintf(page+len, "Bus Type: \t %s\n", type);
++ seq_printf(s, "Bus Type: \t %s\n", type);
+
+- len += sprintf(page+len, "DMA Size: \t %d bits\n",
++ seq_printf(s, "DMA Size: \t %d bits\n",
+ nv_count_bits(dev->dma_mask));
+- len += sprintf(page+len, "DMA Mask: \t 0x%llx\n", dev->dma_mask);
+- len += sprintf(page+len, "Bus Location: \t %04x:%02x.%02x.%x\n",
+- nv->domain, nv->bus, nv->slot, PCI_FUNC(dev->devfn));
++ seq_printf(s, "DMA Mask: \t 0x%llx\n", dev->dma_mask);
++ seq_printf(s, "Bus Location: \t %04x:%02x.%02x.%x\n",
++ nv->domain, nv->bus, nv->slot, PCI_FUNC(dev->devfn));
+ #if defined(DEBUG)
+ do
+ {
+ int j;
+ for (j = 0; j < NV_GPU_NUM_BARS; j++)
+ {
+- len += sprintf(page+len, "BAR%u: \t\t 0x%llx (%lluMB)\n",
+- j, nv->bars[j].address, (nv->bars[j].size >> 20));
++ seq_printf(s, "BAR%u: \t\t 0x%llx (%lluMB)\n",
++ j, nv->bars[j].address, (nv->bars[j].size >> 20));
+ }
+ } while (0);
+ #endif
+
+ NV_KMEM_CACHE_FREE_STACK(sp);
+
+- return len;
++ return 0;
+ }
+
++NV_DEFINE_PROCFS_SINGLE_FILE(gpu_info);
++
+ static int
+ nv_procfs_read_version(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+- int len = 0;
+- *eof = 1;
++ seq_printf(s, "NVRM version: %s\n", pNVRM_ID);
++ seq_printf(s, "GCC version: %s\n", NV_COMPILER);
+
+- len += sprintf(page+len, "NVRM version: %s\n", pNVRM_ID);
+- len += sprintf(page+len, "GCC version: %s\n", NV_COMPILER);
+-
+- return len;
++ return 0;
+ }
+
++NV_DEFINE_PROCFS_SINGLE_FILE(version);
++
+ static struct pci_dev *nv_get_agp_device_by_class(unsigned int class)
+ {
+ struct pci_dev *dev, *fdev;
+@@ -256,23 +290,16 @@ static struct pci_dev *nv_get_agp_device_by_class(unsigned int class)
+
+ static int
+ nv_procfs_read_agp_info(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+- nv_state_t *nv = data;
++ nv_state_t *nv = s->private;
+ nv_linux_state_t *nvl = NULL;
+ struct pci_dev *dev;
+ char *fw, *sba;
+ u8 cap_ptr;
+ u32 status, command, agp_rate;
+- int len = 0;
+-
+- *eof = 1;
+
+ if (nv != NULL)
+ {
+@@ -285,13 +312,12 @@ nv_procfs_read_agp_info(
+ if (!dev)
+ return 0;
+
+- len += sprintf(page+len, "Host Bridge: \t ");
++ seq_printf(s, "Host Bridge: \t ");
+
+ #if defined(CONFIG_PCI_NAMES)
+- len += sprintf(page+len, "%s\n", NV_PCI_DEVICE_NAME(dev));
++ seq_printf(s, "%s\n", NV_PCI_DEVICE_NAME(dev));
+ #else
+- len += sprintf(page+len, "PCI device %04x:%04x\n",
+- dev->vendor, dev->device);
++ seq_printf(s, "PCI device %04x:%04x\n", dev->vendor, dev->device);
+ #endif
+ }
+
+@@ -303,48 +329,43 @@ nv_procfs_read_agp_info(
+ fw = (status & 0x00000010) ? "Supported" : "Not Supported";
+ sba = (status & 0x00000200) ? "Supported" : "Not Supported";
+
+- len += sprintf(page+len, "Fast Writes: \t %s\n", fw);
+- len += sprintf(page+len, "SBA: \t\t %s\n", sba);
++ seq_printf(s, "Fast Writes: \t %s\n", fw);
++ seq_printf(s, "SBA: \t\t %s\n", sba);
+
+ agp_rate = status & 0x7;
+ if (status & 0x8)
+ agp_rate <<= 2;
+
+- len += sprintf(page+len, "AGP Rates: \t %s%s%s%s\n",
+- (agp_rate & 0x00000008) ? "8x " : "",
+- (agp_rate & 0x00000004) ? "4x " : "",
+- (agp_rate & 0x00000002) ? "2x " : "",
+- (agp_rate & 0x00000001) ? "1x " : "");
++ seq_printf(s, "AGP Rates: \t %s%s%s%s\n",
++ (agp_rate & 0x00000008) ? "8x " : "",
++ (agp_rate & 0x00000004) ? "4x " : "",
++ (agp_rate & 0x00000002) ? "2x " : "",
++ (agp_rate & 0x00000001) ? "1x " : "");
+
+- len += sprintf(page+len, "Registers: \t 0x%08x:0x%08x\n", status, command);
++ seq_printf(s, "Registers: \t 0x%08x:0x%08x\n", status, command);
+
+ if (nvl == NULL)
+ NV_PCI_DEV_PUT(dev);
+
+- return len;
++ return 0;
+ }
+
++NV_DEFINE_PROCFS_SINGLE_FILE(agp_info);
++
+ static int
+ nv_procfs_read_agp_status(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+- nv_state_t *nv = data;
++ nv_state_t *nv = s->private;
+ struct pci_dev *dev;
+ char *fw, *sba, *drv;
+- int len = 0;
+ u8 cap_ptr;
+ u32 scratch;
+ u32 status, command, agp_rate;
+ nv_stack_t *sp = NULL;
+
+- *eof = 1;
+-
+ dev = nv_get_agp_device_by_class(PCI_CLASS_BRIDGE_HOST);
+ if (!dev)
+ return 0;
+@@ -366,22 +387,22 @@ nv_procfs_read_agp_status(
+
+ if (NV_AGP_ENABLED(nv) && (command & 0x100))
+ {
+- len += sprintf(page+len, "Status: \t Enabled\n");
++ seq_printf(s, "Status: \t Enabled\n");
+
+ drv = NV_OSAGP_ENABLED(nv) ? "AGPGART" : "NVIDIA";
+- len += sprintf(page+len, "Driver: \t %s\n", drv);
++ seq_printf(s, "Driver: \t %s\n", drv);
+
+ agp_rate = command & 0x7;
+ if (status & 0x8)
+ agp_rate <<= 2;
+
+- len += sprintf(page+len, "AGP Rate: \t %dx\n", agp_rate);
++ seq_printf(s, "AGP Rate: \t %dx\n", agp_rate);
+
+ fw = (command & 0x00000010) ? "Enabled" : "Disabled";
+- len += sprintf(page+len, "Fast Writes: \t %s\n", fw);
++ seq_printf(s, "Fast Writes: \t %s\n", fw);
+
+ sba = (command & 0x00000200) ? "Enabled" : "Disabled";
+- len += sprintf(page+len, "SBA: \t\t %s\n", sba);
++ seq_printf(s, "SBA: \t\t %s\n", sba);
+ }
+ else
+ {
+@@ -394,7 +415,7 @@ nv_procfs_read_agp_status(
+ return 0;
+ }
+
+- len += sprintf(page+len, "Status: \t Disabled\n\n");
++ seq_printf(s, "Status: \t Disabled\n\n");
+
+ /*
+ * If we find AGP is disabled, but the RM registry indicates it
+@@ -409,7 +430,7 @@ nv_procfs_read_agp_status(
+
+ if (agp_config != NVOS_AGP_CONFIG_DISABLE_AGP && NV_AGP_FAILED(nv))
+ {
+- len += sprintf(page+len,
++ seq_printf(s,
+ "AGP initialization failed, please check the ouput \n"
+ "of the 'dmesg' command and/or your system log file \n"
+ "for additional information on this problem. \n");
+@@ -419,9 +440,11 @@ nv_procfs_read_agp_status(
+ }
+
+ NV_PCI_DEV_PUT(dev);
+- return len;
++ return 0;
+ }
+
++NV_DEFINE_PROCFS_SINGLE_FILE(agp_status);
++
+ static int
+ nv_procfs_open_registry(
+ struct inode *inode,
+@@ -431,9 +454,6 @@ nv_procfs_open_registry(
+ nv_file_private_t *nvfp = NULL;
+ nv_stack_t *sp = NULL;
+
+- if (0 == (file->f_mode & FMODE_WRITE))
+- return 0;
+-
+ nvfp = nv_alloc_file_private();
+ if (nvfp == NULL)
+ {
+@@ -441,6 +461,11 @@ nv_procfs_open_registry(
+ return -ENOMEM;
+ }
+
++ nvfp->proc_data = NV_PDE_DATA(inode);
++
++ if (0 == (file->f_mode & FMODE_WRITE))
++ goto done;
++
+ NV_KMEM_CACHE_ALLOC_STACK(sp);
+ if (sp == NULL)
+ {
+@@ -449,19 +474,19 @@ nv_procfs_open_registry(
+ return -ENOMEM;
+ }
+
+- NV_SET_FILE_PRIVATE(file, nvfp);
+-
+ if (RM_OK != os_alloc_mem((void **)&nvfp->data, NV_PROC_WRITE_BUFFER_SIZE))
+ {
+ nv_free_file_private(nvfp);
+ NV_KMEM_CACHE_FREE_STACK(sp);
+- NV_SET_FILE_PRIVATE(file, NULL);
+ return -ENOMEM;
+ }
+
+ os_mem_set((void *)nvfp->data, 0, NV_PROC_WRITE_BUFFER_SIZE);
+ nvfp->fops_sp[NV_FOPS_STACK_INDEX_PROCFS] = sp;
+
++done:
++ single_open(file, nv_procfs_read_registry, nvfp);
++
+ return 0;
+ }
+
+@@ -471,6 +496,7 @@ nv_procfs_close_registry(
+ struct file *file
+ )
+ {
++ struct seq_file *s = file->private_data;
+ nv_file_private_t *nvfp;
+ nv_state_t *nv;
+ nv_linux_state_t *nvl = NULL;
+@@ -481,9 +507,8 @@ nv_procfs_close_registry(
+ RM_STATUS rm_status;
+ int rc = 0;
+
+- nvfp = NV_GET_FILE_PRIVATE(file);
+- if (nvfp == NULL)
+- return 0;
++ nvfp = s->private;
++ single_release(inode, file);
+
+ sp = nvfp->fops_sp[NV_FOPS_STACK_INDEX_PROCFS];
+
+@@ -538,56 +563,42 @@ done:
+ os_free_mem(nvfp->data);
+
+ nv_free_file_private(nvfp);
+- NV_SET_FILE_PRIVATE(file, NULL);
+
+- NV_KMEM_CACHE_FREE_STACK(sp);
++ if (sp != NULL)
++ NV_KMEM_CACHE_FREE_STACK(sp);
+
+ return rc;
+ }
+
+-static struct file_operations nv_procfs_registry_fops = {
+- .open = nv_procfs_open_registry,
+- .release = nv_procfs_close_registry,
+-};
+-
+ static int
+ nv_procfs_read_params(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+ unsigned int i;
+- int len = 0;
+ nv_parm_t *entry;
+
+- *eof = 1;
+-
+ for (i = 0; (entry = &nv_parms[i])->name != NULL; i++)
+- len += sprintf(page+len, "%s: %u\n", entry->name, *entry->data);
++ seq_printf(s, "%s: %u\n", entry->name, *entry->data);
+
+- len += sprintf(page+len, "RegistryDwords: \"%s\"\n",
++ seq_printf(s, "RegistryDwords: \"%s\"\n",
+ (NVreg_RegistryDwords != NULL) ? NVreg_RegistryDwords : "");
+- len += sprintf(page+len, "RmMsg: \"%s\"\n",
+- (NVreg_RmMsg != NULL) ? NVreg_RmMsg : "");
++ seq_printf(s, "RmMsg: \"%s\"\n", (NVreg_RmMsg != NULL) ? NVreg_RmMsg : "");
+
+- return len;
++ return 0;
+ }
+
++NV_DEFINE_PROCFS_SINGLE_FILE(params);
++
+ static int
+ nv_procfs_read_registry(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+- nv_state_t *nv = data;
++ nv_file_private_t *nvfp = s->private;
++ nv_state_t *nv = nvfp->proc_data;
+ nv_linux_state_t *nvl = NULL;
+ char *registry_keys;
+
+@@ -596,20 +607,20 @@ nv_procfs_read_registry(
+ registry_keys = ((nvl != NULL) ?
+ nvl->registry_keys : nv_registry_keys);
+
+- *eof = 1;
+- return sprintf(page, "Binary: \"%s\"\n", registry_keys);
++ return seq_printf(s, "Binary: \"%s\"\n", registry_keys);
+ }
+
+-static int
++static ssize_t
+ nv_procfs_write_registry(
+ struct file *file,
+- const char *buffer,
+- unsigned long count,
+- void *data
++ const char *buffer,
++ size_t count,
++ loff_t *pos
+ )
+ {
+ int status = 0;
+- nv_file_private_t *nvfp = NV_GET_FILE_PRIVATE(file);
++ struct seq_file *s = file->private_data;
++ nv_file_private_t *nvfp = s->private;
+ char *proc_buffer;
+ unsigned long bytes_left;
+
+@@ -637,30 +648,37 @@ nv_procfs_write_registry(
+ }
+ else
+ {
+- nvfp->proc_data = data;
+ nvfp->off += count;
+ }
+
++ *pos = nvfp->off;
++
+ done:
+ up(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]);
+
+ return ((status < 0) ? status : (int)count);
+ }
+
++static struct file_operations nv_procfs_registry_fops = {
++ .owner = THIS_MODULE,
++ .open = nv_procfs_open_registry,
++ .read = seq_read,
++ .write = nv_procfs_write_registry,
++ .llseek = seq_lseek,
++ .release = nv_procfs_close_registry,
++};
++
+ static int
+ nv_procfs_read_text_file(
+- char *page,
+- char **start,
+- off_t off,
+- int count,
+- int *eof,
+- void *data
++ struct seq_file *s,
++ void *v
+ )
+ {
+- *eof = 1;
+- return sprintf(page, "%s", (char *)data);
++ return seq_puts(s, s->private);
+ }
+
++NV_DEFINE_PROCFS_SINGLE_FILE(text_file);
++
+ static void
+ nv_procfs_add_text_file(
+ struct proc_dir_entry *parent,
+@@ -668,12 +686,14 @@ nv_procfs_add_text_file(
+ const char *text
+ )
+ {
+- NV_CREATE_PROC_FILE(filename, parent,
+- nv_procfs_read_text_file, NULL, NULL, (void *)text);
++ NV_CREATE_PROC_FILE(filename, parent, text_file, (void *)text);
+ }
+
+ static void nv_procfs_unregister_all(struct proc_dir_entry *entry)
+ {
++#if defined(NV_PROC_REMOVE_PRESENT)
++ proc_remove(entry);
++#else
+ while (entry)
+ {
+ struct proc_dir_entry *next = entry->next;
+@@ -684,6 +704,7 @@ static void nv_procfs_unregister_all(struct proc_dir_entry *entry)
+ break;
+ entry = next;
+ }
++#endif
+ }
+ #endif
+
+@@ -713,26 +734,11 @@ int nv_register_procfs(void)
+ if (!proc_nvidia)
+ goto failed;
+
+- entry = NV_CREATE_PROC_FILE("params", proc_nvidia,
+- nv_procfs_read_params, NULL, NULL, NULL);
++ entry = NV_CREATE_PROC_FILE("params", proc_nvidia, params, NULL);
+ if (!entry)
+ goto failed;
+
+- /*
+- * entry->proc_fops originally points to a constant
+- * structure, so to add more methods for the
+- * binary registry write path, we need to replace the
+- * said entry->proc_fops with a new fops structure.
+- * However, in preparation for this, we need to preserve
+- * the procfs read() and write() operations.
+- */
+- nv_procfs_registry_fops.read = entry->proc_fops->read;
+- nv_procfs_registry_fops.write = entry->proc_fops->write;
+-
+- entry = NV_CREATE_PROC_FILE("registry", proc_nvidia,
+- nv_procfs_read_registry,
+- nv_procfs_write_registry,
+- &nv_procfs_registry_fops, NULL);
++ entry = NV_CREATE_PROC_FILE("registry", proc_nvidia, registry, NULL);
+ if (!entry)
+ goto failed;
+
+@@ -753,8 +759,7 @@ int nv_register_procfs(void)
+
+ nv_procfs_add_text_file(proc_nvidia_patches, "README", __README_patches);
+
+- entry = NV_CREATE_PROC_FILE("version", proc_nvidia,
+- nv_procfs_read_version, NULL, NULL, NULL);
++ entry = NV_CREATE_PROC_FILE("version", proc_nvidia, version, NULL);
+ if (!entry)
+ goto failed;
+
+@@ -771,15 +776,12 @@ int nv_register_procfs(void)
+ if (!proc_nvidia_gpu)
+ goto failed;
+
+- entry = NV_CREATE_PROC_FILE("information", proc_nvidia_gpu,
+- nv_procfs_read_gpu_info, NULL, NULL, nv);
++ entry = NV_CREATE_PROC_FILE("information", proc_nvidia_gpu, gpu_info,
++ nv);
+ if (!entry)
+ goto failed;
+
+- entry = NV_CREATE_PROC_FILE("registry", proc_nvidia_gpu,
+- nv_procfs_read_registry,
+- nv_procfs_write_registry,
+- &nv_procfs_registry_fops, nv);
++ entry = NV_CREATE_PROC_FILE("registry", proc_nvidia_gpu, registry, nv);
+ if (!entry)
+ goto failed;
+
+@@ -789,18 +791,17 @@ int nv_register_procfs(void)
+ if (!proc_nvidia_agp)
+ goto failed;
+
+- entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp,
+- nv_procfs_read_agp_status, NULL, NULL, nv);
++ entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp, agp_status,
++ nv);
+ if (!entry)
+ goto failed;
+
+ entry = NV_CREATE_PROC_FILE("host-bridge", proc_nvidia_agp,
+- nv_procfs_read_agp_info, NULL, NULL, NULL);
++ agp_info, NULL);
+ if (!entry)
+ goto failed;
+
+- entry = NV_CREATE_PROC_FILE("gpu", proc_nvidia_agp,
+- nv_procfs_read_agp_info, NULL, NULL, nv);
++ entry = NV_CREATE_PROC_FILE("gpu", proc_nvidia_agp, agp_info, nv);
+ if (!entry)
+ goto failed;
+ }