aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-parport-light.c1
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/i2c-thunderx-pcidrv.c6
-rw-r--r--drivers/i2c/i2c-smbus.c41
-rw-r--r--include/linux/i2c-smbus.h1
5 files changed, 17 insertions, 33 deletions
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index faa8fb8f2b8f..fa41ff799533 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -123,7 +123,6 @@ static struct i2c_adapter parport_adapter = {
123 123
124/* SMBus alert support */ 124/* SMBus alert support */
125static struct i2c_smbus_alert_setup alert_data = { 125static struct i2c_smbus_alert_setup alert_data = {
126 .alert_edge_triggered = 1,
127}; 126};
128static struct i2c_client *ara; 127static struct i2c_client *ara;
129static struct lineop parport_ctrl_irq = { 128static struct lineop parport_ctrl_irq = {
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index a8e54df4aed6..319209a07353 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -237,7 +237,6 @@ static void i2c_parport_attach(struct parport *port)
237 237
238 /* Setup SMBus alert if supported */ 238 /* Setup SMBus alert if supported */
239 if (adapter_parm[type].smbus_alert) { 239 if (adapter_parm[type].smbus_alert) {
240 adapter->alert_data.alert_edge_triggered = 1;
241 adapter->ara = i2c_setup_smbus_alert(&adapter->adapter, 240 adapter->ara = i2c_setup_smbus_alert(&adapter->adapter,
242 &adapter->alert_data); 241 &adapter->alert_data);
243 if (adapter->ara) 242 if (adapter->ara)
diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
index df0976f4432a..1a7cad874756 100644
--- a/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+++ b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
@@ -118,8 +118,6 @@ static void thunder_i2c_clock_disable(struct device *dev, struct clk *clk)
118static int thunder_i2c_smbus_setup_of(struct octeon_i2c *i2c, 118static int thunder_i2c_smbus_setup_of(struct octeon_i2c *i2c,
119 struct device_node *node) 119 struct device_node *node)
120{ 120{
121 u32 type;
122
123 if (!node) 121 if (!node)
124 return -EINVAL; 122 return -EINVAL;
125 123
@@ -127,10 +125,6 @@ static int thunder_i2c_smbus_setup_of(struct octeon_i2c *i2c,
127 if (!i2c->alert_data.irq) 125 if (!i2c->alert_data.irq)
128 return -EINVAL; 126 return -EINVAL;
129 127
130 type = irqd_get_trigger_type(irq_get_irq_data(i2c->alert_data.irq));
131 i2c->alert_data.alert_edge_triggered =
132 (type & IRQ_TYPE_LEVEL_MASK) ? 1 : 0;
133
134 i2c->ara = i2c_setup_smbus_alert(&i2c->adap, &i2c->alert_data); 128 i2c->ara = i2c_setup_smbus_alert(&i2c->adap, &i2c->alert_data);
135 if (!i2c->ara) 129 if (!i2c->ara)
136 return -ENODEV; 130 return -ENODEV;
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index f9271c713d20..d4af2701ac6e 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -25,8 +25,6 @@
25#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26 26
27struct i2c_smbus_alert { 27struct i2c_smbus_alert {
28 unsigned int alert_edge_triggered:1;
29 int irq;
30 struct work_struct alert; 28 struct work_struct alert;
31 struct i2c_client *ara; /* Alert response address */ 29 struct i2c_client *ara; /* Alert response address */
32}; 30};
@@ -72,13 +70,12 @@ static int smbus_do_alert(struct device *dev, void *addrp)
72 * The alert IRQ handler needs to hand work off to a task which can issue 70 * The alert IRQ handler needs to hand work off to a task which can issue
73 * SMBus calls, because those sleeping calls can't be made in IRQ context. 71 * SMBus calls, because those sleeping calls can't be made in IRQ context.
74 */ 72 */
75static void smbus_alert(struct work_struct *work) 73static irqreturn_t smbus_alert(int irq, void *d)
76{ 74{
77 struct i2c_smbus_alert *alert; 75 struct i2c_smbus_alert *alert = d;
78 struct i2c_client *ara; 76 struct i2c_client *ara;
79 unsigned short prev_addr = 0; /* Not a valid address */ 77 unsigned short prev_addr = 0; /* Not a valid address */
80 78
81 alert = container_of(work, struct i2c_smbus_alert, alert);
82 ara = alert->ara; 79 ara = alert->ara;
83 80
84 for (;;) { 81 for (;;) {
@@ -115,21 +112,17 @@ static void smbus_alert(struct work_struct *work)
115 prev_addr = data.addr; 112 prev_addr = data.addr;
116 } 113 }
117 114
118 /* We handled all alerts; re-enable level-triggered IRQs */ 115 return IRQ_HANDLED;
119 if (!alert->alert_edge_triggered)
120 enable_irq(alert->irq);
121} 116}
122 117
123static irqreturn_t smbalert_irq(int irq, void *d) 118static void smbalert_work(struct work_struct *work)
124{ 119{
125 struct i2c_smbus_alert *alert = d; 120 struct i2c_smbus_alert *alert;
121
122 alert = container_of(work, struct i2c_smbus_alert, alert);
126 123
127 /* Disable level-triggered IRQs until we handle them */ 124 smbus_alert(0, alert);
128 if (!alert->alert_edge_triggered)
129 disable_irq_nosync(irq);
130 125
131 schedule_work(&alert->alert);
132 return IRQ_HANDLED;
133} 126}
134 127
135/* Setup SMBALERT# infrastructure */ 128/* Setup SMBALERT# infrastructure */
@@ -139,28 +132,28 @@ static int smbalert_probe(struct i2c_client *ara,
139 struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev); 132 struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev);
140 struct i2c_smbus_alert *alert; 133 struct i2c_smbus_alert *alert;
141 struct i2c_adapter *adapter = ara->adapter; 134 struct i2c_adapter *adapter = ara->adapter;
142 int res; 135 int res, irq;
143 136
144 alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert), 137 alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
145 GFP_KERNEL); 138 GFP_KERNEL);
146 if (!alert) 139 if (!alert)
147 return -ENOMEM; 140 return -ENOMEM;
148 141
149 alert->alert_edge_triggered = setup->alert_edge_triggered; 142 irq = setup->irq;
150 alert->irq = setup->irq; 143 INIT_WORK(&alert->alert, smbalert_work);
151 INIT_WORK(&alert->alert, smbus_alert);
152 alert->ara = ara; 144 alert->ara = ara;
153 145
154 if (setup->irq > 0) { 146 if (irq > 0) {
155 res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq, 147 res = devm_request_threaded_irq(&ara->dev, irq,
156 0, "smbus_alert", alert); 148 NULL, smbus_alert,
149 IRQF_SHARED | IRQF_ONESHOT,
150 "smbus_alert", alert);
157 if (res) 151 if (res)
158 return res; 152 return res;
159 } 153 }
160 154
161 i2c_set_clientdata(ara, alert); 155 i2c_set_clientdata(ara, alert);
162 dev_info(&adapter->dev, "supports SMBALERT#, %s trigger\n", 156 dev_info(&adapter->dev, "supports SMBALERT#\n");
163 setup->alert_edge_triggered ? "edge" : "level");
164 157
165 return 0; 158 return 0;
166} 159}
diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h
index a1385023a29b..19efbd14e812 100644
--- a/include/linux/i2c-smbus.h
+++ b/include/linux/i2c-smbus.h
@@ -42,7 +42,6 @@
42 * properly set. 42 * properly set.
43 */ 43 */
44struct i2c_smbus_alert_setup { 44struct i2c_smbus_alert_setup {
45 unsigned int alert_edge_triggered:1;
46 int irq; 45 int irq;
47}; 46};
48 47