forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
i2c-parport: Fix adapter list handling
Use a standard list with proper locking to handle the list of adapters. Thankfully it only matters on systems with more than one parallel port, which are very rare. Thanks to Lukasz Kapiec for reporting the problem to me. Signed-off-by: Jean Delvare <[email protected]> Cc: [email protected]
- Loading branch information
Jean Delvare
authored and
Jean Delvare
committed
May 1, 2011
1 parent
a6e5e2b
commit 56acc7a
Showing
1 changed file
with
14 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/* ------------------------------------------------------------------------ * | ||
* i2c-parport.c I2C bus over parallel port * | ||
* ------------------------------------------------------------------------ * | ||
Copyright (C) 2003-2010 Jean Delvare <[email protected]> | ||
Copyright (C) 2003-2011 Jean Delvare <[email protected]> | ||
Based on older i2c-philips-par.c driver | ||
Copyright (C) 1995-2000 Simon G. Vogl | ||
|
@@ -33,6 +33,8 @@ | |
#include <linux/i2c-algo-bit.h> | ||
#include <linux/i2c-smbus.h> | ||
#include <linux/slab.h> | ||
#include <linux/list.h> | ||
#include <linux/mutex.h> | ||
#include "i2c-parport.h" | ||
|
||
/* ----- Device list ------------------------------------------------------ */ | ||
|
@@ -43,10 +45,11 @@ struct i2c_par { | |
struct i2c_algo_bit_data algo_data; | ||
struct i2c_smbus_alert_setup alert_data; | ||
struct i2c_client *ara; | ||
struct i2c_par *next; | ||
struct list_head node; | ||
}; | ||
|
||
static struct i2c_par *adapter_list; | ||
static LIST_HEAD(adapter_list); | ||
static DEFINE_MUTEX(adapter_list_lock); | ||
|
||
/* ----- Low-level parallel port access ----------------------------------- */ | ||
|
||
|
@@ -228,8 +231,9 @@ static void i2c_parport_attach (struct parport *port) | |
} | ||
|
||
/* Add the new adapter to the list */ | ||
adapter->next = adapter_list; | ||
adapter_list = adapter; | ||
mutex_lock(&adapter_list_lock); | ||
list_add_tail(&adapter->node, &adapter_list); | ||
mutex_unlock(&adapter_list_lock); | ||
return; | ||
|
||
ERROR1: | ||
|
@@ -241,11 +245,11 @@ static void i2c_parport_attach (struct parport *port) | |
|
||
static void i2c_parport_detach (struct parport *port) | ||
{ | ||
struct i2c_par *adapter, *prev; | ||
struct i2c_par *adapter, *_n; | ||
|
||
/* Walk the list */ | ||
for (prev = NULL, adapter = adapter_list; adapter; | ||
prev = adapter, adapter = adapter->next) { | ||
mutex_lock(&adapter_list_lock); | ||
list_for_each_entry_safe(adapter, _n, &adapter_list, node) { | ||
if (adapter->pdev->port == port) { | ||
if (adapter->ara) { | ||
parport_disable_irq(port); | ||
|
@@ -259,14 +263,11 @@ static void i2c_parport_detach (struct parport *port) | |
|
||
parport_release(adapter->pdev); | ||
parport_unregister_device(adapter->pdev); | ||
if (prev) | ||
prev->next = adapter->next; | ||
else | ||
adapter_list = adapter->next; | ||
list_del(&adapter->node); | ||
kfree(adapter); | ||
return; | ||
} | ||
} | ||
mutex_unlock(&adapter_list_lock); | ||
} | ||
|
||
static struct parport_driver i2c_parport_driver = { | ||
|