diff options
-rw-r--r-- | drivers/i2c/busses/i2c-parport-light.c | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-parport.c | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-thunderx-pcidrv.c | 6 | ||||
-rw-r--r-- | drivers/i2c/i2c-smbus.c | 41 | ||||
-rw-r--r-- | include/linux/i2c-smbus.h | 1 |
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 */ |
125 | static struct i2c_smbus_alert_setup alert_data = { | 125 | static struct i2c_smbus_alert_setup alert_data = { |
126 | .alert_edge_triggered = 1, | ||
127 | }; | 126 | }; |
128 | static struct i2c_client *ara; | 127 | static struct i2c_client *ara; |
129 | static struct lineop parport_ctrl_irq = { | 128 | static 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) | |||
118 | static int thunder_i2c_smbus_setup_of(struct octeon_i2c *i2c, | 118 | static 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 | ||
27 | struct i2c_smbus_alert { | 27 | struct 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 | */ |
75 | static void smbus_alert(struct work_struct *work) | 73 | static 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 | ||
123 | static irqreturn_t smbalert_irq(int irq, void *d) | 118 | static 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 | */ |
44 | struct i2c_smbus_alert_setup { | 44 | struct i2c_smbus_alert_setup { |
45 | unsigned int alert_edge_triggered:1; | ||
46 | int irq; | 45 | int irq; |
47 | }; | 46 | }; |
48 | 47 | ||