aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1_int.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1/w1_int.c')
-rw-r--r--drivers/w1/w1_int.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 590bd8a7cd1b..9b084db739c7 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -75,8 +75,10 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
75 atomic_set(&dev->refcnt, 2); 75 atomic_set(&dev->refcnt, 2);
76 76
77 INIT_LIST_HEAD(&dev->slist); 77 INIT_LIST_HEAD(&dev->slist);
78 INIT_LIST_HEAD(&dev->async_list);
78 mutex_init(&dev->mutex); 79 mutex_init(&dev->mutex);
79 mutex_init(&dev->bus_mutex); 80 mutex_init(&dev->bus_mutex);
81 mutex_init(&dev->list_mutex);
80 82
81 memcpy(&dev->dev, device, sizeof(struct device)); 83 memcpy(&dev->dev, device, sizeof(struct device));
82 dev_set_name(&dev->dev, "w1_bus_master%u", dev->id); 84 dev_set_name(&dev->dev, "w1_bus_master%u", dev->id);
@@ -103,6 +105,10 @@ static void w1_free_dev(struct w1_master *dev)
103 device_unregister(&dev->dev); 105 device_unregister(&dev->dev);
104} 106}
105 107
108/**
109 * w1_add_master_device() - registers a new master device
110 * @master: master bus device to register
111 */
106int w1_add_master_device(struct w1_bus_master *master) 112int w1_add_master_device(struct w1_bus_master *master)
107{ 113{
108 struct w1_master *dev, *entry; 114 struct w1_master *dev, *entry;
@@ -172,6 +178,7 @@ int w1_add_master_device(struct w1_bus_master *master)
172 178
173#if 0 /* Thread cleanup code, not required currently. */ 179#if 0 /* Thread cleanup code, not required currently. */
174err_out_kill_thread: 180err_out_kill_thread:
181 set_bit(W1_ABORT_SEARCH, &dev->flags);
175 kthread_stop(dev->thread); 182 kthread_stop(dev->thread);
176#endif 183#endif
177err_out_rm_attr: 184err_out_rm_attr:
@@ -187,16 +194,22 @@ void __w1_remove_master_device(struct w1_master *dev)
187 struct w1_netlink_msg msg; 194 struct w1_netlink_msg msg;
188 struct w1_slave *sl, *sln; 195 struct w1_slave *sl, *sln;
189 196
190 kthread_stop(dev->thread);
191
192 mutex_lock(&w1_mlock); 197 mutex_lock(&w1_mlock);
193 list_del(&dev->w1_master_entry); 198 list_del(&dev->w1_master_entry);
194 mutex_unlock(&w1_mlock); 199 mutex_unlock(&w1_mlock);
195 200
201 set_bit(W1_ABORT_SEARCH, &dev->flags);
202 kthread_stop(dev->thread);
203
196 mutex_lock(&dev->mutex); 204 mutex_lock(&dev->mutex);
197 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) 205 mutex_lock(&dev->list_mutex);
206 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
207 mutex_unlock(&dev->list_mutex);
198 w1_slave_detach(sl); 208 w1_slave_detach(sl);
209 mutex_lock(&dev->list_mutex);
210 }
199 w1_destroy_master_attributes(dev); 211 w1_destroy_master_attributes(dev);
212 mutex_unlock(&dev->list_mutex);
200 mutex_unlock(&dev->mutex); 213 mutex_unlock(&dev->mutex);
201 atomic_dec(&dev->refcnt); 214 atomic_dec(&dev->refcnt);
202 215
@@ -206,7 +219,9 @@ void __w1_remove_master_device(struct w1_master *dev)
206 219
207 if (msleep_interruptible(1000)) 220 if (msleep_interruptible(1000))
208 flush_signals(current); 221 flush_signals(current);
222 w1_process_callbacks(dev);
209 } 223 }
224 w1_process_callbacks(dev);
210 225
211 memset(&msg, 0, sizeof(msg)); 226 memset(&msg, 0, sizeof(msg));
212 msg.id.mst.id = dev->id; 227 msg.id.mst.id = dev->id;
@@ -216,6 +231,10 @@ void __w1_remove_master_device(struct w1_master *dev)
216 w1_free_dev(dev); 231 w1_free_dev(dev);
217} 232}
218 233
234/**
235 * w1_remove_master_device() - unregister a master device
236 * @bm: master bus device to remove
237 */
219void w1_remove_master_device(struct w1_bus_master *bm) 238void w1_remove_master_device(struct w1_bus_master *bm)
220{ 239{
221 struct w1_master *dev, *found = NULL; 240 struct w1_master *dev, *found = NULL;