Commit d5f3435a authored by Albert Cranford's avatar Albert Cranford Committed by Linus Torvalds

i2c core/dev/proc cleanups, and a proc-related fix

parent 2ce067b0
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> */ SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> */
/* $Id: i2c-core.c,v 1.83 2002/07/08 01:37:15 mds Exp $ */ /* $Id: i2c-core.c,v 1.86 2002/09/12 06:47:26 ac9410 Exp $ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/init.h> #include <linux/init.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
#endif
#include <asm/uaccess.h> #include <asm/uaccess.h>
/* ----- global defines ---------------------------------------------------- */ /* ----- global defines ---------------------------------------------------- */
...@@ -72,7 +68,7 @@ static struct i2c_driver *drivers[I2C_DRIVER_MAX]; ...@@ -72,7 +68,7 @@ static struct i2c_driver *drivers[I2C_DRIVER_MAX];
static int driver_count; static int driver_count;
/**** debug level */ /**** debug level */
static int i2c_debug=1; static int i2c_debug;
/* --------------------------------------------------- /* ---------------------------------------------------
* /proc entry declarations * /proc entry declarations
...@@ -84,10 +80,6 @@ static int i2c_debug=1; ...@@ -84,10 +80,6 @@ static int i2c_debug=1;
static int i2cproc_init(void); static int i2cproc_init(void);
static int i2cproc_cleanup(void); static int i2cproc_cleanup(void);
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27))
static void monitor_bus_i2c(struct inode *inode, int fill);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
loff_t *ppos); loff_t *ppos);
static int read_bus_i2c(char *buf, char **start, off_t offset, int len, static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
...@@ -99,12 +91,6 @@ static struct file_operations i2cproc_operations = { ...@@ -99,12 +91,6 @@ static struct file_operations i2cproc_operations = {
read: i2cproc_bus_read, read: i2cproc_bus_read,
}; };
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48))
static struct inode_operations i2cproc_inode_operations = {
&i2cproc_operations
};
#endif
static int i2cproc_initialized = 0; static int i2cproc_initialized = 0;
#else /* undef CONFIG_PROC_FS */ #else /* undef CONFIG_PROC_FS */
...@@ -164,16 +150,8 @@ int i2c_add_adapter(struct i2c_adapter *adap) ...@@ -164,16 +150,8 @@ int i2c_add_adapter(struct i2c_adapter *adap)
goto ERROR1; goto ERROR1;
} }
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,48))
proc_entry->proc_fops = &i2cproc_operations; proc_entry->proc_fops = &i2cproc_operations;
#else
proc_entry->ops = &i2cproc_inode_operations;
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
proc_entry->owner = THIS_MODULE; proc_entry->owner = THIS_MODULE;
#else
proc_entry->fill_inode = &monitor_bus_i2c;
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
adap->inode = proc_entry->low_ino; adap->inode = proc_entry->low_ino;
} }
...@@ -611,18 +589,6 @@ int i2c_release_client(struct i2c_client *client) ...@@ -611,18 +589,6 @@ int i2c_release_client(struct i2c_client *client)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27))
/* Monitor access to /proc/bus/i2c*; make unloading i2c-proc impossible
if some process still uses it or some file in it */
void monitor_bus_i2c(struct inode *inode, int fill)
{
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
}
#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,37)) */
/* This function generates the output for /proc/bus/i2c */ /* This function generates the output for /proc/bus/i2c */
int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
void *private) void *private)
...@@ -658,18 +624,19 @@ ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, ...@@ -658,18 +624,19 @@ ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
struct i2c_client *client; struct i2c_client *client;
int i,j,k,order_nr,len=0,len_total; int i,j,k,order_nr,len=0,len_total;
int order[I2C_CLIENT_MAX]; int order[I2C_CLIENT_MAX];
#define OUTPUT_LENGTH_PER_LINE 70
if (count > 4096)
return -EINVAL;
len_total = file->f_pos + count; len_total = file->f_pos + count;
/* Too bad if this gets longer (unlikely) */ if (len_total > (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE) )
if (len_total > 4096) /* adjust to maximum file size */
len_total = 4096; len_total = (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE);
for (i = 0; i < I2C_ADAP_MAX; i++) for (i = 0; i < I2C_ADAP_MAX; i++)
if (adapters[i]->inode == inode->i_ino) { if (adapters[i]->inode == inode->i_ino) {
/* We need a bit of slack in the kernel buffer; this makes the /* We need a bit of slack in the kernel buffer; this makes the
sprintf safe. */ sprintf safe. */
if (! (kbuf = kmalloc(count + 80,GFP_KERNEL))) if (! (kbuf = kmalloc(len_total +
OUTPUT_LENGTH_PER_LINE,
GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
/* Order will hold the indexes of the clients /* Order will hold the indexes of the clients
sorted by address */ sorted by address */
...@@ -731,11 +698,7 @@ int i2cproc_init(void) ...@@ -731,11 +698,7 @@ int i2cproc_init(void)
return -ENOENT; return -ENOENT;
} }
proc_bus_i2c->read_proc = &read_bus_i2c; proc_bus_i2c->read_proc = &read_bus_i2c;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
proc_bus_i2c->owner = THIS_MODULE; proc_bus_i2c->owner = THIS_MODULE;
#else
proc_bus_i2c->fill_inode = &monitor_bus_i2c;
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */
i2cproc_initialized += 2; i2cproc_initialized += 2;
return 0; return 0;
} }
...@@ -1492,6 +1455,11 @@ static int __init i2c_init(void) ...@@ -1492,6 +1455,11 @@ static int __init i2c_init(void)
return 0; return 0;
} }
static void __exit i2c_exit(void)
{
i2cproc_cleanup();
}
#ifndef MODULE #ifndef MODULE
#ifdef CONFIG_I2C_CHARDEV #ifdef CONFIG_I2C_CHARDEV
extern int i2c_dev_init(void); extern int i2c_dev_init(void);
...@@ -1622,20 +1590,11 @@ EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); ...@@ -1622,20 +1590,11 @@ EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
EXPORT_SYMBOL(i2c_get_functionality); EXPORT_SYMBOL(i2c_get_functionality);
EXPORT_SYMBOL(i2c_check_functionality); EXPORT_SYMBOL(i2c_check_functionality);
#ifdef MODULE
MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
MODULE_DESCRIPTION("I2C-Bus main module"); MODULE_DESCRIPTION("I2C-Bus main module");
MODULE_PARM(i2c_debug, "i"); MODULE_PARM(i2c_debug, "i");
MODULE_PARM_DESC(i2c_debug,"debug level"); MODULE_PARM_DESC(i2c_debug,"debug level");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
int init_module(void) module_init(i2c_init);
{ module_exit(i2c_exit);
return i2c_init();
}
void cleanup_module(void)
{
i2cproc_cleanup();
}
#endif
...@@ -36,9 +36,7 @@ ...@@ -36,9 +36,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/version.h> #include <linux/version.h>
#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
#ifdef CONFIG_DEVFS_FS #ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#endif #endif
...@@ -52,16 +50,8 @@ ...@@ -52,16 +50,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-dev.h> #include <linux/i2c-dev.h>
#ifdef MODULE
extern int init_module(void);
extern int cleanup_module(void);
#endif /* def MODULE */
/* struct file_operations changed too often in the 2.1 series for nice code */ /* struct file_operations changed too often in the 2.1 series for nice code */
#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin);
#endif
static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
loff_t *offset); loff_t *offset);
static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
...@@ -78,23 +68,9 @@ static int i2cdev_detach_client(struct i2c_client *client); ...@@ -78,23 +68,9 @@ static int i2cdev_detach_client(struct i2c_client *client);
static int i2cdev_command(struct i2c_client *client, unsigned int cmd, static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
void *arg); void *arg);
#ifdef MODULE
static
#else
extern
#endif
int __init i2c_dev_init(void);
static int i2cdev_cleanup(void);
static struct file_operations i2cdev_fops = { static struct file_operations i2cdev_fops = {
#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
owner: THIS_MODULE, owner: THIS_MODULE,
#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
llseek: i2cdev_lseek,
#else
llseek: no_llseek, llseek: no_llseek,
#endif
read: i2cdev_read, read: i2cdev_read,
write: i2cdev_write, write: i2cdev_write,
ioctl: i2cdev_ioctl, ioctl: i2cdev_ioctl,
...@@ -132,20 +108,6 @@ static struct i2c_client i2cdev_client_template = { ...@@ -132,20 +108,6 @@ static struct i2c_client i2cdev_client_template = {
static int i2cdev_initialized; static int i2cdev_initialized;
#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
/* Note that the lseek function is called llseek in 2.1 kernels. But things
are complicated enough as is. */
loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin)
{
#ifdef DEBUG
struct inode *inode = file->f_dentry->d_inode;
printk(KERN_DEBUG "i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n",
minor(inode->i_rdev),(long) offset,origin);
#endif /* DEBUG */
return -ESPIPE;
}
#endif
static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
loff_t *offset) loff_t *offset)
{ {
...@@ -411,9 +373,6 @@ int i2cdev_open (struct inode *inode, struct file *file) ...@@ -411,9 +373,6 @@ int i2cdev_open (struct inode *inode, struct file *file)
if (i2cdev_adaps[minor]->inc_use) if (i2cdev_adaps[minor]->inc_use)
i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]);
#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0)
MOD_INC_USE_COUNT;
#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */
#ifdef DEBUG #ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor); printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor);
...@@ -429,16 +388,10 @@ static int i2cdev_release (struct inode *inode, struct file *file) ...@@ -429,16 +388,10 @@ static int i2cdev_release (struct inode *inode, struct file *file)
#ifdef DEBUG #ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor); printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor);
#endif #endif
#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0)
MOD_DEC_USE_COUNT;
#else /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
lock_kernel(); lock_kernel();
#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */
if (i2cdev_adaps[minor]->dec_use) if (i2cdev_adaps[minor]->dec_use)
i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]);
#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
unlock_kernel(); unlock_kernel();
#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
return 0; return 0;
} }
...@@ -491,6 +444,30 @@ static int i2cdev_command(struct i2c_client *client, unsigned int cmd, ...@@ -491,6 +444,30 @@ static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
return -1; return -1;
} }
static void i2cdev_cleanup(void)
{
int res;
if (i2cdev_initialized >= 2) {
if ((res = i2c_del_driver(&i2cdev_driver))) {
printk(KERN_ERR "i2c-dev.o: Driver deregistration failed, "
"module not removed.\n");
}
i2cdev_initialized --;
}
if (i2cdev_initialized >= 1) {
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_handle);
#endif
if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
printk(KERN_ERR "i2c-dev.o: unable to release major %d for i2c bus\n",
I2C_MAJOR);
}
i2cdev_initialized --;
}
}
int __init i2c_dev_init(void) int __init i2c_dev_init(void)
{ {
int res; int res;
...@@ -517,50 +494,11 @@ int __init i2c_dev_init(void) ...@@ -517,50 +494,11 @@ int __init i2c_dev_init(void)
return 0; return 0;
} }
int i2cdev_cleanup(void)
{
int res;
if (i2cdev_initialized >= 2) {
if ((res = i2c_del_driver(&i2cdev_driver))) {
printk(KERN_ERR "i2c-dev.o: Driver deregistration failed, "
"module not removed.\n");
return res;
}
i2cdev_initialized --;
}
if (i2cdev_initialized >= 1) {
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_handle);
#endif
if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
printk(KERN_ERR "i2c-dev.o: unable to release major %d for i2c bus\n",
I2C_MAJOR);
return res;
}
i2cdev_initialized --;
}
return 0;
}
EXPORT_NO_SYMBOLS; EXPORT_NO_SYMBOLS;
#ifdef MODULE
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>");
MODULE_DESCRIPTION("I2C /dev entries driver"); MODULE_DESCRIPTION("I2C /dev entries driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
int init_module(void) module_init(i2c_dev_init);
{ module_exit(i2cdev_cleanup);
return i2c_dev_init();
}
int cleanup_module(void)
{
return i2cdev_cleanup();
}
#endif /* def MODULE */
...@@ -54,8 +54,6 @@ static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen, ...@@ -54,8 +54,6 @@ static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
void *newval, size_t newlen, void *newval, size_t newlen,
void **context); void **context);
int __init sensors_init(void);
#define SENSORS_ENTRY_MAX 20 #define SENSORS_ENTRY_MAX 20
static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX]; static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
...@@ -815,35 +813,23 @@ int __init sensors_init(void) ...@@ -815,35 +813,23 @@ int __init sensors_init(void)
return 0; return 0;
} }
static void __exit i2c_cleanup(void)
{
if (i2c_initialized >= 1) {
unregister_sysctl_table(i2c_proc_header);
i2c_initialized--;
}
}
EXPORT_SYMBOL(i2c_deregister_entry); EXPORT_SYMBOL(i2c_deregister_entry);
EXPORT_SYMBOL(i2c_detect); EXPORT_SYMBOL(i2c_detect);
EXPORT_SYMBOL(i2c_proc_real); EXPORT_SYMBOL(i2c_proc_real);
EXPORT_SYMBOL(i2c_register_entry); EXPORT_SYMBOL(i2c_register_entry);
EXPORT_SYMBOL(i2c_sysctl_real); EXPORT_SYMBOL(i2c_sysctl_real);
#ifdef MODULE
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
MODULE_DESCRIPTION("i2c-proc driver"); MODULE_DESCRIPTION("i2c-proc driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
int i2c_cleanup(void) module_init(sensors_init);
{ module_exit(i2c_cleanup);
if (i2c_initialized >= 1) {
unregister_sysctl_table(i2c_proc_header);
i2c_initialized--;
}
return 0;
}
int init_module(void)
{
return sensors_init();
}
int cleanup_module(void)
{
return i2c_cleanup();
}
#endif /* MODULE */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment