aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-parport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-parport.c')
-rw-r--r--drivers/i2c/busses/i2c-parport.c27
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
49static struct i2c_par *adapter_list; 51static LIST_HEAD(adapter_list);
52static 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
235ERROR1: 239ERROR1:
@@ -241,11 +245,11 @@ ERROR0:
241 245
242static void i2c_parport_detach (struct parport *port) 246static 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
272static struct parport_driver i2c_parport_driver = { 273static struct parport_driver i2c_parport_driver = {