Commit 11f16971 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6: (78 commits)
  commit e97b81dd
  Author: Mark M. Hoffman <mhoffman@lightlink.com>
  Date:   Thu Mar 23 16:50:25 2006 +0100
  
      [PATCH] i2c-parport: Make type parameter mandatory
      
      This patch forces the user to specify what type of adapter is present when
      loading i2c-parport or i2c-parport-light.  If none is specified, the driver
      init simply fails - instead of assuming adapter type 0.
      
      This alleviates the sometimes lengthy boot time delays which can be caused
      by accidentally building one of these into a kernel along with several i2c
      slave drivers that have lengthy probe routines (e.g. hwmon drivers).
      
      Kconfig and documentation updated accordingly.
Signed-off-by: default avatarMark M. Hoffman <mhoffman@lightlink.com>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
  
  ...
parents bcdc0842 e97b81dd
...@@ -12,18 +12,22 @@ meant as a replacement for the older, individual drivers: ...@@ -12,18 +12,22 @@ meant as a replacement for the older, individual drivers:
teletext adapters) teletext adapters)
It currently supports the following devices: It currently supports the following devices:
* Philips adapter * (type=0) Philips adapter
* home brew teletext adapter * (type=1) home brew teletext adapter
* Velleman K8000 adapter * (type=2) Velleman K8000 adapter
* ELV adapter * (type=3) ELV adapter
* Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032) * (type=4) Analog Devices ADM1032 evaluation board
* Barco LPT->DVI (K5800236) adapter * (type=5) Analog Devices evaluation boards: ADM1025, ADM1030, ADM1031
* (type=6) Barco LPT->DVI (K5800236) adapter
These devices use different pinout configurations, so you have to tell These devices use different pinout configurations, so you have to tell
the driver what you have, using the type module parameter. There is no the driver what you have, using the type module parameter. There is no
way to autodetect the devices. Support for different pinout configurations way to autodetect the devices. Support for different pinout configurations
can be easily added when needed. can be easily added when needed.
Earlier kernels defaulted to type=0 (Philips). But now, if the type
parameter is missing, the driver will simply fail to initialize.
Building your own adapter Building your own adapter
------------------------- -------------------------
......
...@@ -1161,7 +1161,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1161,7 +1161,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
bank. */ bank. */
if (kind < 0) { if (kind < 0) {
if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) { if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) {
dev_warn(dev, "Detection failed at step 3\n"); dev_dbg(dev, "Detection failed at step 1\n");
goto ERROR1; goto ERROR1;
} }
val1 = w83792d_read_value(client, W83792D_REG_BANK); val1 = w83792d_read_value(client, W83792D_REG_BANK);
...@@ -1170,6 +1170,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1170,6 +1170,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
if (!(val1 & 0x07)) { /* is Bank0 */ if (!(val1 & 0x07)) { /* is Bank0 */
if (((!(val1 & 0x80)) && (val2 != 0xa3)) || if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
((val1 & 0x80) && (val2 != 0x5c))) { ((val1 & 0x80) && (val2 != 0x5c))) {
dev_dbg(dev, "Detection failed at step 2\n");
goto ERROR1; goto ERROR1;
} }
} }
...@@ -1177,7 +1178,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1177,7 +1178,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
should match */ should match */
if (w83792d_read_value(client, if (w83792d_read_value(client,
W83792D_REG_I2C_ADDR) != address) { W83792D_REG_I2C_ADDR) != address) {
dev_warn(dev, "Detection failed at step 5\n"); dev_dbg(dev, "Detection failed at step 3\n");
goto ERROR1; goto ERROR1;
} }
} }
......
...@@ -287,6 +287,9 @@ config I2C_PARPORT ...@@ -287,6 +287,9 @@ config I2C_PARPORT
driver named i2c-philips-par. The new driver supports more devices, driver named i2c-philips-par. The new driver supports more devices,
and makes it easier to add support for new devices. and makes it easier to add support for new devices.
An adapter type parameter is now mandatory. Please read the file
Documentation/i2c/busses/i2c-parport for details.
Another driver exists, named i2c-parport-light, which doesn't depend Another driver exists, named i2c-parport-light, which doesn't depend
on the parport driver. This is meant for embedded systems. Don't say on the parport driver. This is meant for embedded systems. Don't say
Y here if you intend to say Y or M there. Y here if you intend to say Y or M there.
......
...@@ -121,9 +121,14 @@ static struct i2c_adapter parport_adapter = { ...@@ -121,9 +121,14 @@ static struct i2c_adapter parport_adapter = {
static int __init i2c_parport_init(void) static int __init i2c_parport_init(void)
{ {
if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { if (type < 0) {
printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
return -ENODEV;
}
if (type >= ARRAY_SIZE(adapter_parm)) {
printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
type = 0; return -ENODEV;
} }
if (base == 0) { if (base == 0) {
......
...@@ -241,9 +241,14 @@ static struct parport_driver i2c_parport_driver = { ...@@ -241,9 +241,14 @@ static struct parport_driver i2c_parport_driver = {
static int __init i2c_parport_init(void) static int __init i2c_parport_init(void)
{ {
if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { if (type < 0) {
printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
return -ENODEV;
}
if (type >= ARRAY_SIZE(adapter_parm)) {
printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
type = 0; return -ENODEV;
} }
return parport_register_driver(&i2c_parport_driver); return parport_register_driver(&i2c_parport_driver);
......
...@@ -90,7 +90,7 @@ static struct adapter_parm adapter_parm[] = { ...@@ -90,7 +90,7 @@ static struct adapter_parm adapter_parm[] = {
}, },
}; };
static int type; static int type = -1;
module_param(type, int, 0); module_param(type, int, 0);
MODULE_PARM_DESC(type, MODULE_PARM_DESC(type,
"Type of adapter:\n" "Type of adapter:\n"
......
...@@ -43,13 +43,6 @@ ...@@ -43,13 +43,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
/*
HISTORY:
2003-05-11 1.0.0 Updated from lm_sensors project for kernel 2.5
(was i2c-sis645.c from lm_sensors 2.7.0)
*/
#define SIS96x_VERSION "1.0.0"
/* base address register in PCI config space */ /* base address register in PCI config space */
#define SIS96x_BAR 0x04 #define SIS96x_BAR 0x04
...@@ -337,7 +330,6 @@ static struct pci_driver sis96x_driver = { ...@@ -337,7 +330,6 @@ static struct pci_driver sis96x_driver = {
static int __init i2c_sis96x_init(void) static int __init i2c_sis96x_init(void)
{ {
printk(KERN_INFO "i2c-sis96x version %s\n", SIS96x_VERSION);
return pci_register_driver(&sis96x_driver); return pci_register_driver(&sis96x_driver);
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/workqueue.h>
#define DS1374_REG_TOD0 0x00 #define DS1374_REG_TOD0 0x00
#define DS1374_REG_TOD1 0x01 #define DS1374_REG_TOD1 0x01
...@@ -139,7 +140,7 @@ ulong ds1374_get_rtc_time(void) ...@@ -139,7 +140,7 @@ ulong ds1374_get_rtc_time(void)
return t1; return t1;
} }
static void ds1374_set_tlet(ulong arg) static void ds1374_set_work(void *arg)
{ {
ulong t1, t2; ulong t1, t2;
int limit = 10; /* arbitrary retry limit */ int limit = 10; /* arbitrary retry limit */
...@@ -168,17 +169,18 @@ static void ds1374_set_tlet(ulong arg) ...@@ -168,17 +169,18 @@ static void ds1374_set_tlet(ulong arg)
static ulong new_time; static ulong new_time;
static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, static struct workqueue_struct *ds1374_workqueue;
(ulong) & new_time);
static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time);
int ds1374_set_rtc_time(ulong nowtime) int ds1374_set_rtc_time(ulong nowtime)
{ {
new_time = nowtime; new_time = nowtime;
if (in_interrupt()) if (in_interrupt())
tasklet_schedule(&ds1374_tasklet); queue_work(ds1374_workqueue, &ds1374_work);
else else
ds1374_set_tlet((ulong) & new_time); ds1374_set_work(&new_time);
return 0; return 0;
} }
...@@ -204,6 +206,8 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind) ...@@ -204,6 +206,8 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
client->adapter = adap; client->adapter = adap;
client->driver = &ds1374_driver; client->driver = &ds1374_driver;
ds1374_workqueue = create_singlethread_workqueue("ds1374");
if ((rc = i2c_attach_client(client)) != 0) { if ((rc = i2c_attach_client(client)) != 0) {
kfree(client); kfree(client);
return rc; return rc;
...@@ -227,7 +231,7 @@ static int ds1374_detach(struct i2c_client *client) ...@@ -227,7 +231,7 @@ static int ds1374_detach(struct i2c_client *client)
if ((rc = i2c_detach_client(client)) == 0) { if ((rc = i2c_detach_client(client)) == 0) {
kfree(i2c_get_clientdata(client)); kfree(i2c_get_clientdata(client));
tasklet_kill(&ds1374_tasklet); destroy_workqueue(ds1374_workqueue);
} }
return rc; return rc;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/workqueue.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/rtc.h> #include <asm/rtc.h>
...@@ -111,7 +112,7 @@ m41t00_get_rtc_time(void) ...@@ -111,7 +112,7 @@ m41t00_get_rtc_time(void)
} }
static void static void
m41t00_set_tlet(ulong arg) m41t00_set(void *arg)
{ {
struct rtc_time tm; struct rtc_time tm;
ulong nowtime = *(ulong *)arg; ulong nowtime = *(ulong *)arg;
...@@ -146,8 +147,8 @@ m41t00_set_tlet(ulong arg) ...@@ -146,8 +147,8 @@ m41t00_set_tlet(ulong arg)
} }
static ulong new_time; static ulong new_time;
static struct workqueue_struct *m41t00_wq;
DECLARE_TASKLET_DISABLED(m41t00_tasklet, m41t00_set_tlet, (ulong)&new_time); static DECLARE_WORK(m41t00_work, m41t00_set, &new_time);
int int
m41t00_set_rtc_time(ulong nowtime) m41t00_set_rtc_time(ulong nowtime)
...@@ -155,9 +156,9 @@ m41t00_set_rtc_time(ulong nowtime) ...@@ -155,9 +156,9 @@ m41t00_set_rtc_time(ulong nowtime)
new_time = nowtime; new_time = nowtime;
if (in_interrupt()) if (in_interrupt())
tasklet_schedule(&m41t00_tasklet); queue_work(m41t00_wq, &m41t00_work);
else else
m41t00_set_tlet((ulong)&new_time); m41t00_set(&new_time);
return 0; return 0;
} }
...@@ -189,6 +190,7 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) ...@@ -189,6 +190,7 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
return rc; return rc;
} }
m41t00_wq = create_singlethread_workqueue("m41t00");
save_client = client; save_client = client;
return 0; return 0;
} }
...@@ -206,7 +208,7 @@ m41t00_detach(struct i2c_client *client) ...@@ -206,7 +208,7 @@ m41t00_detach(struct i2c_client *client)
if ((rc = i2c_detach_client(client)) == 0) { if ((rc = i2c_detach_client(client)) == 0) {
kfree(client); kfree(client);
tasklet_kill(&m41t00_tasklet); destroy_workqueue(m41t00_wq);
} }
return rc; return rc;
} }
......
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