diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-parport.c')
-rw-r--r-- | drivers/i2c/busses/i2c-parport.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 0eb1515541e7..2dbba163b102 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* ------------------------------------------------------------------------ * | 1 | /* ------------------------------------------------------------------------ * |
2 | * i2c-parport.c I2C bus over parallel port * | 2 | * i2c-parport.c I2C bus over parallel port * |
3 | * ------------------------------------------------------------------------ * | 3 | * ------------------------------------------------------------------------ * |
4 | Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> | 4 | Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org> |
5 | 5 | ||
6 | Based on older i2c-philips-par.c driver | 6 | Based on older i2c-philips-par.c driver |
7 | Copyright (C) 1995-2000 Simon G. Vogl | 7 | Copyright (C) 1995-2000 Simon G. Vogl |
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/i2c-algo-bit.h> | 33 | #include <linux/i2c-algo-bit.h> |
34 | #include <linux/i2c-smbus.h> | 34 | #include <linux/i2c-smbus.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/list.h> | ||
37 | #include <linux/mutex.h> | ||
36 | #include "i2c-parport.h" | 38 | #include "i2c-parport.h" |
37 | 39 | ||
38 | /* ----- Device list ------------------------------------------------------ */ | 40 | /* ----- Device list ------------------------------------------------------ */ |
@@ -43,10 +45,11 @@ struct i2c_par { | |||
43 | struct i2c_algo_bit_data algo_data; | 45 | struct i2c_algo_bit_data algo_data; |
44 | struct i2c_smbus_alert_setup alert_data; | 46 | struct i2c_smbus_alert_setup alert_data; |
45 | struct i2c_client *ara; | 47 | struct i2c_client *ara; |
46 | struct i2c_par *next; | 48 | struct list_head node; |
47 | }; | 49 | }; |
48 | 50 | ||
49 | static struct i2c_par *adapter_list; | 51 | static LIST_HEAD(adapter_list); |
52 | static DEFINE_MUTEX(adapter_list_lock); | ||
50 | 53 | ||
51 | /* ----- Low-level parallel port access ----------------------------------- */ | 54 | /* ----- Low-level parallel port access ----------------------------------- */ |
52 | 55 | ||
@@ -228,8 +231,9 @@ static void i2c_parport_attach (struct parport *port) | |||
228 | } | 231 | } |
229 | 232 | ||
230 | /* Add the new adapter to the list */ | 233 | /* Add the new adapter to the list */ |
231 | adapter->next = adapter_list; | 234 | mutex_lock(&adapter_list_lock); |
232 | adapter_list = adapter; | 235 | list_add_tail(&adapter->node, &adapter_list); |
236 | mutex_unlock(&adapter_list_lock); | ||
233 | return; | 237 | return; |
234 | 238 | ||
235 | ERROR1: | 239 | ERROR1: |
@@ -241,11 +245,11 @@ ERROR0: | |||
241 | 245 | ||
242 | static void i2c_parport_detach (struct parport *port) | 246 | static void i2c_parport_detach (struct parport *port) |
243 | { | 247 | { |
244 | struct i2c_par *adapter, *prev; | 248 | struct i2c_par *adapter, *_n; |
245 | 249 | ||
246 | /* Walk the list */ | 250 | /* Walk the list */ |
247 | for (prev = NULL, adapter = adapter_list; adapter; | 251 | mutex_lock(&adapter_list_lock); |
248 | prev = adapter, adapter = adapter->next) { | 252 | list_for_each_entry_safe(adapter, _n, &adapter_list, node) { |
249 | if (adapter->pdev->port == port) { | 253 | if (adapter->pdev->port == port) { |
250 | if (adapter->ara) { | 254 | if (adapter->ara) { |
251 | parport_disable_irq(port); | 255 | parport_disable_irq(port); |
@@ -259,14 +263,11 @@ static void i2c_parport_detach (struct parport *port) | |||
259 | 263 | ||
260 | parport_release(adapter->pdev); | 264 | parport_release(adapter->pdev); |
261 | parport_unregister_device(adapter->pdev); | 265 | parport_unregister_device(adapter->pdev); |
262 | if (prev) | 266 | list_del(&adapter->node); |
263 | prev->next = adapter->next; | ||
264 | else | ||
265 | adapter_list = adapter->next; | ||
266 | kfree(adapter); | 267 | kfree(adapter); |
267 | return; | ||
268 | } | 268 | } |
269 | } | 269 | } |
270 | mutex_unlock(&adapter_list_lock); | ||
270 | } | 271 | } |
271 | 272 | ||
272 | static struct parport_driver i2c_parport_driver = { | 273 | static struct parport_driver i2c_parport_driver = { |