Merge with Linus' kernel.
This commit is contained in:
@@ -468,8 +468,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hwpec)
|
||||
outb_p(1, SMBAUXCTL); /* enable hardware PEC */
|
||||
outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */
|
||||
|
||||
if(block)
|
||||
ret = i801_block_transaction(data, read_write, size, hwpec);
|
||||
@@ -478,9 +477,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
|
||||
ret = i801_transaction();
|
||||
}
|
||||
|
||||
if (hwpec)
|
||||
outb_p(0, SMBAUXCTL); /* disable hardware PEC */
|
||||
|
||||
if(block)
|
||||
return ret;
|
||||
if(ret)
|
||||
|
@@ -725,6 +725,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
|
||||
strcpy(adap->name, "IBM IIC");
|
||||
i2c_set_adapdata(adap, dev);
|
||||
adap->id = I2C_HW_OCP;
|
||||
adap->class = I2C_CLASS_HWMON;
|
||||
adap->algo = &iic_algo;
|
||||
adap->client_register = NULL;
|
||||
adap->client_unregister = NULL;
|
||||
|
@@ -92,15 +92,13 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
|
||||
int res;
|
||||
|
||||
/* Add the driver to the list of i2c drivers in the driver core */
|
||||
driver->driver.name = driver->name;
|
||||
driver->driver.owner = driver->owner;
|
||||
driver->driver.bus = &i2c_bus_type;
|
||||
driver->driver.probe = i2c_isa_device_probe;
|
||||
driver->driver.remove = i2c_isa_device_remove;
|
||||
res = driver_register(&driver->driver);
|
||||
if (res)
|
||||
return res;
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->name);
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name);
|
||||
|
||||
/* Now look for clients */
|
||||
driver->attach_adapter(&isa_adapter);
|
||||
@@ -124,14 +122,14 @@ int i2c_isa_del_driver(struct i2c_driver *driver)
|
||||
if ((res = driver->detach_client(client))) {
|
||||
dev_err(&isa_adapter.dev, "Failed, driver "
|
||||
"%s not unregistered!\n",
|
||||
driver->name);
|
||||
driver->driver.name);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the driver off the core list */
|
||||
driver_unregister(&driver->driver);
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->name);
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -176,7 +174,7 @@ static void __exit i2c_isa_exit(void)
|
||||
list_for_each_safe(item, _n, &isa_adapter.clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
dev_err(&isa_adapter.dev, "Driver %s still has an active "
|
||||
"ISA client at 0x%x\n", client->driver->name,
|
||||
"ISA client at 0x%x\n", client->driver->driver.name,
|
||||
client->addr);
|
||||
}
|
||||
if (client != NULL)
|
||||
|
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* drivers/i2c/busses/i2c-mv64xxx.c
|
||||
*
|
||||
* Driver for the i2c controller on the Marvell line of host bridges for MIPS
|
||||
* and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0).
|
||||
*
|
||||
@@ -65,7 +63,6 @@ enum {
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
|
||||
MV64XXX_I2C_STATE_ABORTING,
|
||||
};
|
||||
|
||||
/* Driver actions */
|
||||
@@ -85,6 +82,7 @@ struct mv64xxx_i2c_data {
|
||||
int irq;
|
||||
u32 state;
|
||||
u32 action;
|
||||
u32 aborting;
|
||||
u32 cntl_bits;
|
||||
void __iomem *reg_base;
|
||||
u32 reg_base_p;
|
||||
@@ -122,12 +120,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
||||
return;
|
||||
}
|
||||
|
||||
if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* The status from the ctlr [mostly] tells us what to do next */
|
||||
switch (status) {
|
||||
/* Start condition interrupt */
|
||||
@@ -148,14 +140,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
||||
/* FALLTHRU */
|
||||
case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
|
||||
case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
|
||||
if (drv_data->bytes_left > 0) {
|
||||
if ((drv_data->bytes_left == 0)
|
||||
|| (drv_data->aborting
|
||||
&& (drv_data->byte_posn != 0))) {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
} else {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
|
||||
drv_data->state =
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
|
||||
drv_data->bytes_left--;
|
||||
} else {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -184,7 +178,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
||||
}
|
||||
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
|
||||
|
||||
if (drv_data->bytes_left == 1)
|
||||
if ((drv_data->bytes_left == 1) || drv_data->aborting)
|
||||
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
|
||||
break;
|
||||
|
||||
@@ -320,6 +314,7 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
|
||||
drv_data->msg = msg;
|
||||
drv_data->byte_posn = 0;
|
||||
drv_data->bytes_left = msg->len;
|
||||
drv_data->aborting = 0;
|
||||
drv_data->rc = 0;
|
||||
drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
|
||||
MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
|
||||
@@ -359,17 +354,19 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
|
||||
}
|
||||
|
||||
if (abort && drv_data->block) {
|
||||
drv_data->state = MV64XXX_I2C_STATE_ABORTING;
|
||||
drv_data->aborting = 1;
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
|
||||
time_left = wait_event_timeout(drv_data->waitq,
|
||||
!drv_data->block,
|
||||
msecs_to_jiffies(drv_data->adapter.timeout));
|
||||
|
||||
if (time_left <= 0) {
|
||||
if ((time_left <= 0) && drv_data->block) {
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
dev_err(&drv_data->adapter.dev,
|
||||
"mv64xxx: I2C bus locked\n");
|
||||
"mv64xxx: I2C bus locked, block: %d, "
|
||||
"time_left: %d\n", drv_data->block,
|
||||
(int)time_left);
|
||||
}
|
||||
} else
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
@@ -510,7 +507,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
|
||||
goto exit_kfree;
|
||||
}
|
||||
|
||||
strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
|
||||
strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
|
||||
I2C_NAME_SIZE);
|
||||
|
||||
init_waitqueue_head(&drv_data->waitq);
|
||||
|
@@ -30,6 +30,7 @@
|
||||
nForce3 Pro150 MCP 00D4
|
||||
nForce3 250Gb MCP 00E4
|
||||
nForce4 MCP 0052
|
||||
nForce4 MCP-04 0034
|
||||
|
||||
This driver supports the 2 SMBuses that are included in the MCP of the
|
||||
nForce2/3/4 chipsets.
|
||||
@@ -257,6 +258,7 @@ static struct pci_device_id nforce2_ids[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@@ -80,6 +80,14 @@ static struct adapter_parm adapter_parm[] = {
|
||||
.setscl = { 0x01, DATA, 1 },
|
||||
.getsda = { 0x10, STAT, 1 },
|
||||
},
|
||||
/* type 6: Barco LPT->DVI (K5800236) adapter */
|
||||
{
|
||||
.setsda = { 0x02, DATA, 1 },
|
||||
.setscl = { 0x01, DATA, 1 },
|
||||
.getsda = { 0x20, STAT, 0 },
|
||||
.getscl = { 0x40, STAT, 0 },
|
||||
.init = { 0xfc, DATA, 0 },
|
||||
},
|
||||
};
|
||||
|
||||
static int type;
|
||||
@@ -91,4 +99,6 @@ MODULE_PARM_DESC(type,
|
||||
" 2 = Velleman K8000 adapter\n"
|
||||
" 3 = ELV adapter\n"
|
||||
" 4 = ADM1032 evaluation board\n"
|
||||
" 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n");
|
||||
" 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
|
||||
" 6 = Barco LPT->DVI (K5800236) adapter\n"
|
||||
);
|
||||
|
@@ -52,9 +52,9 @@ static int ds1337_command(struct i2c_client *client, unsigned int cmd,
|
||||
* Driver data (common to all clients)
|
||||
*/
|
||||
static struct i2c_driver ds1337_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ds1337",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "ds1337",
|
||||
},
|
||||
.attach_adapter = ds1337_attach_adapter,
|
||||
.detach_client = ds1337_detach_client,
|
||||
.command = ds1337_command,
|
||||
@@ -337,13 +337,38 @@ exit:
|
||||
|
||||
static void ds1337_init_client(struct i2c_client *client)
|
||||
{
|
||||
s32 val;
|
||||
u8 status, control;
|
||||
|
||||
/* Ensure that device is set in 24-hour mode */
|
||||
val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
|
||||
if ((val >= 0) && (val & (1 << 6)))
|
||||
i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
|
||||
val & 0x3f);
|
||||
/* On some boards, the RTC isn't configured by boot firmware.
|
||||
* Handle that case by starting/configuring the RTC now.
|
||||
*/
|
||||
status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
|
||||
control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
|
||||
|
||||
if ((status & 0x80) || (control & 0x80)) {
|
||||
/* RTC not running */
|
||||
u8 buf[16];
|
||||
struct i2c_msg msg[1];
|
||||
|
||||
dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
|
||||
|
||||
/* Initialize all, including STATUS and CONTROL to zero */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = sizeof(buf);
|
||||
msg[0].buf = &buf[0];
|
||||
|
||||
i2c_transfer(client->adapter, msg, 1);
|
||||
} else {
|
||||
/* Running: ensure that device is set in 24-hour mode */
|
||||
s32 val;
|
||||
|
||||
val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
|
||||
if ((val >= 0) && (val & (1 << 6)))
|
||||
i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
|
||||
val & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
static int ds1337_detach_client(struct i2c_client *client)
|
||||
|
@@ -232,10 +232,10 @@ static int ds1374_detach(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static struct i2c_driver ds1374_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DS1374_DRV_NAME,
|
||||
.driver = {
|
||||
.name = DS1374_DRV_NAME,
|
||||
},
|
||||
.id = I2C_DRIVERID_DS1374,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = ds1374_attach,
|
||||
.detach_client = ds1374_detach,
|
||||
};
|
||||
|
@@ -68,10 +68,10 @@ static int eeprom_detach_client(struct i2c_client *client);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver eeprom_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "eeprom",
|
||||
.driver = {
|
||||
.name = "eeprom",
|
||||
},
|
||||
.id = I2C_DRIVERID_EEPROM,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = eeprom_attach_adapter,
|
||||
.detach_client = eeprom_detach_client,
|
||||
};
|
||||
|
@@ -1632,11 +1632,11 @@ static int isp1301_scan_bus(struct i2c_adapter *bus)
|
||||
}
|
||||
|
||||
static struct i2c_driver isp1301_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "isp1301_omap",
|
||||
.driver = {
|
||||
.name = "isp1301_omap",
|
||||
},
|
||||
.id = 1301, /* FIXME "official", i2c-ids.h */
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = isp1301_scan_bus,
|
||||
.detach_client = isp1301_detach_client,
|
||||
};
|
||||
|
@@ -211,10 +211,10 @@ m41t00_detach(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static struct i2c_driver m41t00_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = M41T00_DRV_NAME,
|
||||
.driver = {
|
||||
.name = M41T00_DRV_NAME,
|
||||
},
|
||||
.id = I2C_DRIVERID_STM41T00,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = m41t00_attach,
|
||||
.detach_client = m41t00_detach,
|
||||
};
|
||||
|
@@ -67,9 +67,9 @@ static int max6875_detach_client(struct i2c_client *client);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver max6875_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "max6875",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "max6875",
|
||||
},
|
||||
.attach_adapter = max6875_attach_adapter,
|
||||
.detach_client = max6875_detach_client,
|
||||
};
|
||||
|
@@ -38,9 +38,9 @@ static int pca9539_detach_client(struct i2c_client *client);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pca9539_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pca9539",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "pca9539",
|
||||
},
|
||||
.attach_adapter = pca9539_attach_adapter,
|
||||
.detach_client = pca9539_detach_client,
|
||||
};
|
||||
|
@@ -65,10 +65,10 @@ static void pcf8574_init_client(struct i2c_client *client);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pcf8574_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pcf8574",
|
||||
.driver = {
|
||||
.name = "pcf8574",
|
||||
},
|
||||
.id = I2C_DRIVERID_PCF8574,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = pcf8574_attach_adapter,
|
||||
.detach_client = pcf8574_detach_client,
|
||||
};
|
||||
|
@@ -88,10 +88,10 @@ static int pcf8591_read_channel(struct device *dev, int channel);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pcf8591_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pcf8591",
|
||||
.driver = {
|
||||
.name = "pcf8591",
|
||||
},
|
||||
.id = I2C_DRIVERID_PCF8591,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = pcf8591_attach_adapter,
|
||||
.detach_client = pcf8591_detach_client,
|
||||
};
|
||||
|
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
@@ -52,9 +53,6 @@ static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
|
||||
#define CTRL1(c) _rtc8564_ctrl1(c)
|
||||
#define CTRL2(c) _rtc8564_ctrl2(c)
|
||||
|
||||
#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
|
||||
#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
|
||||
|
||||
static int debug;;
|
||||
module_param(debug, int, S_IRUGO | S_IWUSR);
|
||||
|
||||
@@ -157,7 +155,6 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
|
||||
strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
|
||||
i2c_set_clientdata(new_client, d);
|
||||
new_client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
new_client->addr = addr;
|
||||
new_client->adapter = adap;
|
||||
new_client->driver = &rtc8564_driver;
|
||||
@@ -224,16 +221,16 @@ static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
|
||||
return ret;
|
||||
|
||||
/* century stored in minute alarm reg */
|
||||
dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
|
||||
dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
|
||||
dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
|
||||
dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
|
||||
dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
|
||||
dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]);
|
||||
dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
|
||||
dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f);
|
||||
dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7);
|
||||
dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
|
||||
|
||||
dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
|
||||
dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f);
|
||||
dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
|
||||
dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
|
||||
dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
|
||||
dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f);
|
||||
dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f);
|
||||
|
||||
_DBGRTCTM(2, *dt);
|
||||
|
||||
@@ -255,18 +252,18 @@ rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
|
||||
|
||||
buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
|
||||
buf[RTC8564_REG_CTRL2] = CTRL2(client);
|
||||
buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs);
|
||||
buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins);
|
||||
buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours);
|
||||
buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs);
|
||||
buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins);
|
||||
buf[RTC8564_REG_HR] = BIN2BCD(dt->hours);
|
||||
|
||||
if (datetoo) {
|
||||
len += 5;
|
||||
buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday);
|
||||
buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday);
|
||||
buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f;
|
||||
buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday);
|
||||
buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday);
|
||||
buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f;
|
||||
/* century stored in minute alarm reg */
|
||||
buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100);
|
||||
buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100);
|
||||
buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100);
|
||||
buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100);
|
||||
}
|
||||
|
||||
ret = rtc8564_write(client, 0, buf, len);
|
||||
@@ -361,10 +358,10 @@ rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
}
|
||||
|
||||
static struct i2c_driver rtc8564_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "RTC8564",
|
||||
.driver = {
|
||||
.name = "RTC8564",
|
||||
},
|
||||
.id = I2C_DRIVERID_RTC8564,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = rtc8564_probe,
|
||||
.detach_client = rtc8564_detach,
|
||||
.command = rtc8564_command
|
||||
|
@@ -637,9 +637,9 @@ static int __init tps65010_scan_bus(struct i2c_adapter *bus)
|
||||
}
|
||||
|
||||
static struct i2c_driver tps65010_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "tps65010",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "tps65010",
|
||||
},
|
||||
.attach_adapter = tps65010_scan_bus,
|
||||
.detach_client = __exit_p(tps65010_detach_client),
|
||||
};
|
||||
|
@@ -105,9 +105,9 @@ static int x1205_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg);
|
||||
|
||||
static struct i2c_driver x1205_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "x1205",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "x1205",
|
||||
},
|
||||
.attach_adapter = &x1205_attach,
|
||||
.detach_client = &x1205_detach,
|
||||
};
|
||||
|
@@ -197,7 +197,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
|
||||
/* inform drivers of new adapters */
|
||||
list_for_each(item,&drivers) {
|
||||
driver = list_entry(item, struct i2c_driver, list);
|
||||
if (driver->flags & I2C_DF_NOTIFY)
|
||||
if (driver->attach_adapter)
|
||||
/* We ignore the return code; if it fails, too bad */
|
||||
driver->attach_adapter(adap);
|
||||
}
|
||||
@@ -235,7 +235,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
||||
if (driver->detach_adapter)
|
||||
if ((res = driver->detach_adapter(adap))) {
|
||||
dev_err(&adap->dev, "detach_adapter failed "
|
||||
"for driver [%s]\n", driver->name);
|
||||
"for driver [%s]\n",
|
||||
driver->driver.name);
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
@@ -245,10 +246,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
||||
list_for_each_safe(item, _n, &adap->clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
|
||||
/* detaching devices is unconditional of the set notify
|
||||
* flag, as _all_ clients that reside on the adapter
|
||||
* must be deleted, as this would cause invalid states.
|
||||
*/
|
||||
if ((res=client->driver->detach_client(client))) {
|
||||
dev_err(&adap->dev, "detach_client failed for client "
|
||||
"[%s] at address 0x%02x\n", client->name,
|
||||
@@ -286,7 +283,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
||||
* chips.
|
||||
*/
|
||||
|
||||
int i2c_add_driver(struct i2c_driver *driver)
|
||||
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
|
||||
{
|
||||
struct list_head *item;
|
||||
struct i2c_adapter *adapter;
|
||||
@@ -295,8 +292,7 @@ int i2c_add_driver(struct i2c_driver *driver)
|
||||
down(&core_lists);
|
||||
|
||||
/* add the driver to the list of i2c drivers in the driver core */
|
||||
driver->driver.owner = driver->owner;
|
||||
driver->driver.name = driver->name;
|
||||
driver->driver.owner = owner;
|
||||
driver->driver.bus = &i2c_bus_type;
|
||||
driver->driver.probe = i2c_device_probe;
|
||||
driver->driver.remove = i2c_device_remove;
|
||||
@@ -306,10 +302,10 @@ int i2c_add_driver(struct i2c_driver *driver)
|
||||
goto out_unlock;
|
||||
|
||||
list_add_tail(&driver->list,&drivers);
|
||||
pr_debug("i2c-core: driver [%s] registered\n", driver->name);
|
||||
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
|
||||
|
||||
/* now look for instances of driver on our adapters */
|
||||
if (driver->flags & I2C_DF_NOTIFY) {
|
||||
if (driver->attach_adapter) {
|
||||
list_for_each(item,&adapters) {
|
||||
adapter = list_entry(item, struct i2c_adapter, list);
|
||||
driver->attach_adapter(adapter);
|
||||
@@ -320,6 +316,7 @@ int i2c_add_driver(struct i2c_driver *driver)
|
||||
up(&core_lists);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_register_driver);
|
||||
|
||||
int i2c_del_driver(struct i2c_driver *driver)
|
||||
{
|
||||
@@ -334,17 +331,14 @@ int i2c_del_driver(struct i2c_driver *driver)
|
||||
/* Have a look at each adapter, if clients of this driver are still
|
||||
* attached. If so, detach them to be able to kill the driver
|
||||
* afterwards.
|
||||
*
|
||||
* Removing clients does not depend on the notify flag, else
|
||||
* invalid operation might (will!) result, when using stale client
|
||||
* pointers.
|
||||
*/
|
||||
list_for_each(item1,&adapters) {
|
||||
adap = list_entry(item1, struct i2c_adapter, list);
|
||||
if (driver->detach_adapter) {
|
||||
if ((res = driver->detach_adapter(adap))) {
|
||||
dev_err(&adap->dev, "detach_adapter failed "
|
||||
"for driver [%s]\n", driver->name);
|
||||
"for driver [%s]\n",
|
||||
driver->driver.name);
|
||||
goto out_unlock;
|
||||
}
|
||||
} else {
|
||||
@@ -368,7 +362,7 @@ int i2c_del_driver(struct i2c_driver *driver)
|
||||
|
||||
driver_unregister(&driver->driver);
|
||||
list_del(&driver->list);
|
||||
pr_debug("i2c-core: driver [%s] unregistered\n", driver->name);
|
||||
pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
|
||||
|
||||
out_unlock:
|
||||
up(&core_lists);
|
||||
@@ -419,8 +413,7 @@ int i2c_attach_client(struct i2c_client *client)
|
||||
}
|
||||
}
|
||||
|
||||
if (client->flags & I2C_CLIENT_ALLOW_USE)
|
||||
client->usage_count = 0;
|
||||
client->usage_count = 0;
|
||||
|
||||
client->dev.parent = &client->adapter->dev;
|
||||
client->dev.driver = &client->driver->driver;
|
||||
@@ -443,8 +436,7 @@ int i2c_detach_client(struct i2c_client *client)
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int res = 0;
|
||||
|
||||
if ((client->flags & I2C_CLIENT_ALLOW_USE)
|
||||
&& (client->usage_count > 0)) {
|
||||
if (client->usage_count > 0) {
|
||||
dev_warn(&client->dev, "Client [%s] still busy, "
|
||||
"can't detach\n", client->name);
|
||||
return -EBUSY;
|
||||
@@ -475,10 +467,10 @@ int i2c_detach_client(struct i2c_client *client)
|
||||
static int i2c_inc_use_client(struct i2c_client *client)
|
||||
{
|
||||
|
||||
if (!try_module_get(client->driver->owner))
|
||||
if (!try_module_get(client->driver->driver.owner))
|
||||
return -ENODEV;
|
||||
if (!try_module_get(client->adapter->owner)) {
|
||||
module_put(client->driver->owner);
|
||||
module_put(client->driver->driver.owner);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -487,7 +479,7 @@ static int i2c_inc_use_client(struct i2c_client *client)
|
||||
|
||||
static void i2c_dec_use_client(struct i2c_client *client)
|
||||
{
|
||||
module_put(client->driver->owner);
|
||||
module_put(client->driver->driver.owner);
|
||||
module_put(client->adapter->owner);
|
||||
}
|
||||
|
||||
@@ -499,33 +491,20 @@ int i2c_use_client(struct i2c_client *client)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (client->flags & I2C_CLIENT_ALLOW_USE) {
|
||||
if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
|
||||
client->usage_count++;
|
||||
else if (client->usage_count > 0)
|
||||
goto busy;
|
||||
else
|
||||
client->usage_count++;
|
||||
}
|
||||
client->usage_count++;
|
||||
|
||||
return 0;
|
||||
busy:
|
||||
i2c_dec_use_client(client);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
int i2c_release_client(struct i2c_client *client)
|
||||
{
|
||||
if(client->flags & I2C_CLIENT_ALLOW_USE) {
|
||||
if(client->usage_count>0)
|
||||
client->usage_count--;
|
||||
else {
|
||||
pr_debug("i2c-core: %s used one too many times\n",
|
||||
__FUNCTION__);
|
||||
return -EPERM;
|
||||
}
|
||||
if (!client->usage_count) {
|
||||
pr_debug("i2c-core: %s used one too many times\n",
|
||||
__FUNCTION__);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
client->usage_count--;
|
||||
i2c_dec_use_client(client);
|
||||
|
||||
return 0;
|
||||
@@ -539,14 +518,14 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
|
||||
down(&adap->clist_lock);
|
||||
list_for_each(item,&adap->clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
if (!try_module_get(client->driver->owner))
|
||||
if (!try_module_get(client->driver->driver.owner))
|
||||
continue;
|
||||
if (NULL != client->driver->command) {
|
||||
up(&adap->clist_lock);
|
||||
client->driver->command(client,cmd,arg);
|
||||
down(&adap->clist_lock);
|
||||
}
|
||||
module_put(client->driver->owner);
|
||||
module_put(client->driver->driver.owner);
|
||||
}
|
||||
up(&adap->clist_lock);
|
||||
}
|
||||
@@ -1147,7 +1126,6 @@ EXPORT_SYMBOL_GPL(i2c_bus_type);
|
||||
|
||||
EXPORT_SYMBOL(i2c_add_adapter);
|
||||
EXPORT_SYMBOL(i2c_del_adapter);
|
||||
EXPORT_SYMBOL(i2c_add_driver);
|
||||
EXPORT_SYMBOL(i2c_del_driver);
|
||||
EXPORT_SYMBOL(i2c_attach_client);
|
||||
EXPORT_SYMBOL(i2c_detach_client);
|
||||
|
@@ -42,8 +42,7 @@ static struct i2c_client i2cdev_client_template;
|
||||
struct i2c_dev {
|
||||
int minor;
|
||||
struct i2c_adapter *adap;
|
||||
struct class_device class_dev;
|
||||
struct completion released; /* FIXME, we need a class_device_unregister() */
|
||||
struct class_device *class_dev;
|
||||
};
|
||||
#define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
|
||||
|
||||
@@ -105,7 +104,10 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
|
||||
|
||||
static ssize_t show_adapter_name(struct class_device *class_dev, char *buf)
|
||||
{
|
||||
struct i2c_dev *i2c_dev = to_i2c_dev(class_dev);
|
||||
struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt));
|
||||
|
||||
if (!i2c_dev)
|
||||
return -ENODEV;
|
||||
return sprintf(buf, "%s\n", i2c_dev->adap->name);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
|
||||
@@ -408,21 +410,12 @@ static struct file_operations i2cdev_fops = {
|
||||
.release = i2cdev_release,
|
||||
};
|
||||
|
||||
static void release_i2c_dev(struct class_device *dev)
|
||||
{
|
||||
struct i2c_dev *i2c_dev = to_i2c_dev(dev);
|
||||
complete(&i2c_dev->released);
|
||||
}
|
||||
|
||||
static struct class i2c_dev_class = {
|
||||
.name = "i2c-dev",
|
||||
.release = &release_i2c_dev,
|
||||
};
|
||||
static struct class *i2c_dev_class;
|
||||
|
||||
static int i2cdev_attach_adapter(struct i2c_adapter *adap)
|
||||
{
|
||||
struct i2c_dev *i2c_dev;
|
||||
int retval;
|
||||
struct device *dev;
|
||||
|
||||
i2c_dev = get_free_i2c_dev(adap);
|
||||
if (IS_ERR(i2c_dev))
|
||||
@@ -434,21 +427,20 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
|
||||
/* register this i2c device with the driver core */
|
||||
i2c_dev->adap = adap;
|
||||
if (adap->dev.parent == &platform_bus)
|
||||
i2c_dev->class_dev.dev = &adap->dev;
|
||||
dev = &adap->dev;
|
||||
else
|
||||
i2c_dev->class_dev.dev = adap->dev.parent;
|
||||
i2c_dev->class_dev.class = &i2c_dev_class;
|
||||
i2c_dev->class_dev.devt = MKDEV(I2C_MAJOR, i2c_dev->minor);
|
||||
snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor);
|
||||
retval = class_device_register(&i2c_dev->class_dev);
|
||||
if (retval)
|
||||
dev = adap->dev.parent;
|
||||
i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL,
|
||||
MKDEV(I2C_MAJOR, i2c_dev->minor),
|
||||
dev, "i2c-%d", i2c_dev->minor);
|
||||
if (!i2c_dev->class_dev)
|
||||
goto error;
|
||||
class_device_create_file(&i2c_dev->class_dev, &class_device_attr_name);
|
||||
class_device_create_file(i2c_dev->class_dev, &class_device_attr_name);
|
||||
return 0;
|
||||
error:
|
||||
return_i2c_dev(i2c_dev);
|
||||
kfree(i2c_dev);
|
||||
return retval;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int i2cdev_detach_adapter(struct i2c_adapter *adap)
|
||||
@@ -459,10 +451,8 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap)
|
||||
if (!i2c_dev)
|
||||
return -ENODEV;
|
||||
|
||||
init_completion(&i2c_dev->released);
|
||||
return_i2c_dev(i2c_dev);
|
||||
class_device_unregister(&i2c_dev->class_dev);
|
||||
wait_for_completion(&i2c_dev->released);
|
||||
class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor));
|
||||
kfree(i2c_dev);
|
||||
|
||||
pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
|
||||
@@ -474,21 +464,14 @@ static int i2cdev_detach_client(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct i2c_driver i2cdev_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dev_driver",
|
||||
.driver = {
|
||||
.name = "dev_driver",
|
||||
},
|
||||
.id = I2C_DRIVERID_I2CDEV,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = i2cdev_attach_adapter,
|
||||
.detach_adapter = i2cdev_detach_adapter,
|
||||
.detach_client = i2cdev_detach_client,
|
||||
.command = i2cdev_command,
|
||||
};
|
||||
|
||||
static struct i2c_client i2cdev_client_template = {
|
||||
@@ -507,8 +490,8 @@ static int __init i2c_dev_init(void)
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
res = class_register(&i2c_dev_class);
|
||||
if (res)
|
||||
i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
|
||||
if (IS_ERR(i2c_dev_class))
|
||||
goto out_unreg_chrdev;
|
||||
|
||||
res = i2c_add_driver(&i2cdev_driver);
|
||||
@@ -518,7 +501,7 @@ static int __init i2c_dev_init(void)
|
||||
return 0;
|
||||
|
||||
out_unreg_class:
|
||||
class_unregister(&i2c_dev_class);
|
||||
class_destroy(i2c_dev_class);
|
||||
out_unreg_chrdev:
|
||||
unregister_chrdev(I2C_MAJOR, "i2c");
|
||||
out:
|
||||
@@ -529,7 +512,7 @@ out:
|
||||
static void __exit i2c_dev_exit(void)
|
||||
{
|
||||
i2c_del_driver(&i2cdev_driver);
|
||||
class_unregister(&i2c_dev_class);
|
||||
class_destroy(i2c_dev_class);
|
||||
unregister_chrdev(I2C_MAJOR,"i2c");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user