Merge branch 'i2c/for-current-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "I2C has three driver bugfixes for you. We agreed on the Mac regression to go in via I2C" * 'i2c/for-current-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: macintosh: therm_windtunnel: fix regression when instantiating devices i2c: altera: Fix potential integer overflow i2c: jz4780: silence log flood on txabrt
This commit is contained in:
Коммит
fb279f4e23
|
@ -171,7 +171,7 @@ static void altr_i2c_init(struct altr_i2c_dev *idev)
|
|||
/* SCL Low Time */
|
||||
writel(t_low, idev->base + ALTR_I2C_SCL_LOW);
|
||||
/* SDA Hold Time, 300ns */
|
||||
writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD);
|
||||
writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD);
|
||||
|
||||
/* Mask all master interrupt bits */
|
||||
altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false);
|
||||
|
|
|
@ -78,25 +78,6 @@
|
|||
|
||||
#define X1000_I2C_DC_STOP BIT(9)
|
||||
|
||||
static const char * const jz4780_i2c_abrt_src[] = {
|
||||
"ABRT_7B_ADDR_NOACK",
|
||||
"ABRT_10ADDR1_NOACK",
|
||||
"ABRT_10ADDR2_NOACK",
|
||||
"ABRT_XDATA_NOACK",
|
||||
"ABRT_GCALL_NOACK",
|
||||
"ABRT_GCALL_READ",
|
||||
"ABRT_HS_ACKD",
|
||||
"SBYTE_ACKDET",
|
||||
"ABRT_HS_NORSTRT",
|
||||
"SBYTE_NORSTRT",
|
||||
"ABRT_10B_RD_NORSTRT",
|
||||
"ABRT_MASTER_DIS",
|
||||
"ARB_LOST",
|
||||
"SLVFLUSH_TXFIFO",
|
||||
"SLV_ARBLOST",
|
||||
"SLVRD_INTX",
|
||||
};
|
||||
|
||||
#define JZ4780_I2C_INTST_IGC BIT(11)
|
||||
#define JZ4780_I2C_INTST_ISTT BIT(10)
|
||||
#define JZ4780_I2C_INTST_ISTP BIT(9)
|
||||
|
@ -576,21 +557,8 @@ done:
|
|||
|
||||
static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src)
|
||||
{
|
||||
int i;
|
||||
|
||||
dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src);
|
||||
dev_err(&i2c->adap.dev, "device addr=%x\n",
|
||||
jz4780_i2c_readw(i2c, JZ4780_I2C_TAR));
|
||||
dev_err(&i2c->adap.dev, "send cmd count:%d %d\n",
|
||||
i2c->cmd, i2c->cmd_buf[i2c->cmd]);
|
||||
dev_err(&i2c->adap.dev, "receive data count:%d %d\n",
|
||||
i2c->cmd, i2c->data_buf[i2c->cmd]);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (src & BIT(i))
|
||||
dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n",
|
||||
i, jz4780_i2c_abrt_src[i]);
|
||||
}
|
||||
dev_dbg(&i2c->adap.dev, "txabrt: 0x%08x, cmd: %d, send: %d, recv: %d\n",
|
||||
src, i2c->cmd, i2c->cmd_buf[i2c->cmd], i2c->data_buf[i2c->cmd]);
|
||||
}
|
||||
|
||||
static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
|
||||
|
|
|
@ -300,9 +300,11 @@ static int control_loop(void *dummy)
|
|||
/* i2c probing and setup */
|
||||
/************************************************************************/
|
||||
|
||||
static int
|
||||
do_attach( struct i2c_adapter *adapter )
|
||||
static void do_attach(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct i2c_board_info info = { };
|
||||
struct device_node *np;
|
||||
|
||||
/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
|
||||
static const unsigned short scan_ds1775[] = {
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
|
@ -313,25 +315,24 @@ do_attach( struct i2c_adapter *adapter )
|
|||
I2C_CLIENT_END
|
||||
};
|
||||
|
||||
if( strncmp(adapter->name, "uni-n", 5) )
|
||||
return 0;
|
||||
if (x.running || strncmp(adapter->name, "uni-n", 5))
|
||||
return;
|
||||
|
||||
if( !x.running ) {
|
||||
struct i2c_board_info info;
|
||||
|
||||
memset(&info, 0, sizeof(struct i2c_board_info));
|
||||
strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE);
|
||||
np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775");
|
||||
if (np) {
|
||||
of_node_put(np);
|
||||
} else {
|
||||
strlcpy(info.type, "MAC,ds1775", I2C_NAME_SIZE);
|
||||
i2c_new_probed_device(adapter, &info, scan_ds1775, NULL);
|
||||
|
||||
strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE);
|
||||
i2c_new_probed_device(adapter, &info, scan_adm1030, NULL);
|
||||
|
||||
if( x.thermostat && x.fan ) {
|
||||
x.running = 1;
|
||||
x.poll_task = kthread_run(control_loop, NULL, "g4fand");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030");
|
||||
if (np) {
|
||||
of_node_put(np);
|
||||
} else {
|
||||
strlcpy(info.type, "MAC,adm1030", I2C_NAME_SIZE);
|
||||
i2c_new_probed_device(adapter, &info, scan_adm1030, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -404,8 +405,8 @@ out:
|
|||
enum chip { ds1775, adm1030 };
|
||||
|
||||
static const struct i2c_device_id therm_windtunnel_id[] = {
|
||||
{ "therm_ds1775", ds1775 },
|
||||
{ "therm_adm1030", adm1030 },
|
||||
{ "MAC,ds1775", ds1775 },
|
||||
{ "MAC,adm1030", adm1030 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id);
|
||||
|
@ -414,6 +415,7 @@ static int
|
|||
do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adapter = cl->adapter;
|
||||
int ret = 0;
|
||||
|
||||
if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA
|
||||
| I2C_FUNC_SMBUS_WRITE_BYTE) )
|
||||
|
@ -421,11 +423,19 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
|
||||
switch (id->driver_data) {
|
||||
case adm1030:
|
||||
return attach_fan( cl );
|
||||
ret = attach_fan(cl);
|
||||
break;
|
||||
case ds1775:
|
||||
return attach_thermostat(cl);
|
||||
ret = attach_thermostat(cl);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (!x.running && x.thermostat && x.fan) {
|
||||
x.running = 1;
|
||||
x.poll_task = kthread_run(control_loop, NULL, "g4fand");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct i2c_driver g4fan_driver = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче