[PATCH linux dev-4.7] drivers: fsi: i2c: Change fsi irq enable behavior
Eddie James
eajames at linux.vnet.ibm.com
Fri Feb 17 09:26:23 AEDT 2017
From: "Edward A. James" <eajames at us.ibm.com>
Only enable fsi interrupt polling during an i2c operation. This will
help with busy FSI bus.
Signed-off-by: Edward A. James <eajames at us.ibm.com>
---
drivers/fsi/i2c/iic-fsi.c | 30 +++++++++++++++++-------------
drivers/fsi/i2c/iic-int.h | 2 ++
drivers/fsi/i2c/iic-mstr.c | 10 ++++++++++
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/drivers/fsi/i2c/iic-fsi.c b/drivers/fsi/i2c/iic-fsi.c
index 9c70e38..97c8939 100644
--- a/drivers/fsi/i2c/iic-fsi.c
+++ b/drivers/fsi/i2c/iic-fsi.c
@@ -127,6 +127,20 @@ int writew_wrap(iic_eng_t* eng, unsigned int addr, unsigned long val,
return rc;
};
+int iic_enable_irq(iic_eng_t *eng)
+{
+ struct fsi_device *dev = to_fsi_dev(eng->dev);
+
+ return fsi_enable_irq(dev);
+}
+
+void iic_disable_irq(iic_eng_t *eng)
+{
+ struct fsi_device *dev = to_fsi_dev(eng->dev);
+
+ fsi_disable_irq(dev);
+}
+
struct iic_reg_access fsi_reg_access =
{
.bus_readb = readb_wrap,
@@ -135,6 +149,8 @@ struct iic_reg_access fsi_reg_access =
.bus_writeb = writeb_wrap,
.bus_writeh = writeh_wrap,
.bus_writew = writew_wrap,
+ .bus_enable_irq = iic_enable_irq,
+ .bus_disable_irq = iic_disable_irq,
};
static const struct fsi_device_id i2c_ids[] = {
@@ -450,10 +466,7 @@ int iic_fsi_suspend(struct device *dev)
set_bit(IIC_NO_ACCESS, &eng->flags);
/* disable interrupt handler if not already done */
- if(test_and_clear_bit(IIC_ENG_RESUMED, &eng->flags))
- {
- fsi_disable_irq(to_fsi_dev(dev));
- }
+ fsi_disable_irq(to_fsi_dev(dev));
error:
IEXIT(rc);
@@ -505,15 +518,6 @@ int iic_fsi_resume(struct device *dev)
goto error;
}
- /* Enable interrupt handler in the kernel */
- IDBGd(0, "enabling irq\n");
- rc = fsi_enable_irq(dp);
- if(rc)
- {
- IFLDe(1, "fsi_enable_irq failed rc=%d\n", rc);
- goto error;
- }
-
set_bit(IIC_ENG_RESUMED, &eng->flags);
/* allow operations to be submitted */
diff --git a/drivers/fsi/i2c/iic-int.h b/drivers/fsi/i2c/iic-int.h
index b29ece6..65b336f 100644
--- a/drivers/fsi/i2c/iic-int.h
+++ b/drivers/fsi/i2c/iic-int.h
@@ -171,6 +171,8 @@ struct iic_reg_access
int (*bus_writeb)(iic_eng_t*, unsigned int, unsigned char, iic_ffdc_t**);
int (*bus_writeh)(iic_eng_t*, unsigned int, unsigned short, iic_ffdc_t**);
int (*bus_writew)(iic_eng_t*, unsigned int, unsigned long, iic_ffdc_t**);
+ int (*bus_enable_irq)(iic_eng_t *);
+ void (*bus_disable_irq)(iic_eng_t *);
};
struct iic_eng_ops
diff --git a/drivers/fsi/i2c/iic-mstr.c b/drivers/fsi/i2c/iic-mstr.c
index 5501b22..a12cf7fc 100644
--- a/drivers/fsi/i2c/iic-mstr.c
+++ b/drivers/fsi/i2c/iic-mstr.c
@@ -1079,6 +1079,7 @@ ssize_t iic_common_read(iic_client_t * client, void * buf, size_t count,
{
ssize_t rc = count;
iic_xfr_t *xfr;
+ iic_eng_t *eng = client->bus->eng;
IENTER();
@@ -1103,6 +1104,8 @@ ssize_t iic_common_read(iic_client_t * client, void * buf, size_t count,
goto exit;
}
+ rc = eng->ra->bus_enable_irq(eng);
+
/* enqueue or start the xfr */
rc = iic_enq_xfr(xfr);
if(rc != -EIOCBQUEUED)
@@ -1113,6 +1116,8 @@ ssize_t iic_common_read(iic_client_t * client, void * buf, size_t count,
/* wait for xfr to complete */
iic_wait_xfr(xfr);
+ eng->ra->bus_disable_irq(eng);
+
/* set rc appropriately */
if(xfr->status)
{
@@ -1200,6 +1205,7 @@ ssize_t iic_common_write(iic_client_t * client, void * buf, size_t count,
{
ssize_t rc = count;
iic_xfr_t *xfr;
+ iic_eng_t *eng = client->bus->eng;
IENTER();
@@ -1223,6 +1229,8 @@ ssize_t iic_common_write(iic_client_t * client, void * buf, size_t count,
goto exit;
}
+ rc = eng->ra->bus_enable_irq(eng);
+
/* enqueue or start the xfr */
rc = iic_enq_xfr(xfr);
if(rc != -EIOCBQUEUED)
@@ -1233,6 +1241,8 @@ ssize_t iic_common_write(iic_client_t * client, void * buf, size_t count,
/* wait for xfr to complete */
iic_wait_xfr(xfr);
+ eng->ra->bus_disable_irq(eng);
+
/* set rc appropriately */
if(xfr->status)
{
--
1.8.3.1
More information about the openbmc
mailing list