^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "w1_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "w1_netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int w1_search_count = -1; /* Default is continual scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) module_param_named(search_count, w1_search_count, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int w1_enable_pullup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) module_param_named(enable_pullup, w1_enable_pullup, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct device_driver *driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct w1_master *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * We are in process context(kernel thread), so can sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) dev = kzalloc(sizeof(struct w1_master) + sizeof(struct w1_bus_master), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) pr_err("Failed to allocate %zd bytes for new w1 device.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) sizeof(struct w1_master));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) dev->bus_master = (struct w1_bus_master *)(dev + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) dev->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dev->max_slave_count = slave_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dev->slave_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) dev->attempts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dev->initialized = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) dev->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) dev->slave_ttl = slave_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dev->search_count = w1_search_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) dev->enable_pullup = w1_enable_pullup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* 1 for w1_process to decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * 1 for __w1_remove_master_device to decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) atomic_set(&dev->refcnt, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) INIT_LIST_HEAD(&dev->slist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) INIT_LIST_HEAD(&dev->async_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mutex_init(&dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mutex_init(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mutex_init(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) memcpy(&dev->dev, device, sizeof(struct device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) dev_set_name(&dev->dev, "w1_bus_master%u", dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) snprintf(dev->name, sizeof(dev->name), "w1_bus_master%u", dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) dev->dev.init_name = dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) dev->driver = driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) dev->seq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) err = device_register(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pr_err("Failed to register master device. err=%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) put_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void w1_free_dev(struct w1_master *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) device_unregister(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * w1_add_master_device() - registers a new master device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @master: master bus device to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int w1_add_master_device(struct w1_bus_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct w1_master *dev, *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct w1_netlink_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int id, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* validate minimum functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!(master->touch_bit && master->reset_bus) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) !(master->write_bit && master->read_bit) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) !(master->write_byte && master->read_byte && master->reset_bus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) pr_err("w1_add_master_device: invalid function set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Lock until the device is added (or not) to w1_masters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mutex_lock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Search for the first available id (starting at 1). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ++id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) list_for_each_entry(entry, &w1_masters, w1_master_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (entry->id == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) } while (found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) &w1_master_driver, &w1_master_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mutex_unlock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) retval = w1_create_master_attributes(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mutex_unlock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) goto err_out_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dev->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev->thread = kthread_run(&w1_process, dev, "%s", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (IS_ERR(dev->thread)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) retval = PTR_ERR(dev->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev_err(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "Failed to create new kernel thread. err=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mutex_unlock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) goto err_out_rm_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) list_add(&dev->w1_master_entry, &w1_masters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mutex_unlock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) memset(&msg, 0, sizeof(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) msg.id.mst.id = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) msg.type = W1_MASTER_ADD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) w1_netlink_send(dev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #if 0 /* Thread cleanup code, not required currently. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) err_out_kill_thread:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) set_bit(W1_ABORT_SEARCH, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) kthread_stop(dev->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) err_out_rm_attr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) w1_destroy_master_attributes(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) err_out_free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) w1_free_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) EXPORT_SYMBOL(w1_add_master_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void __w1_remove_master_device(struct w1_master *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct w1_netlink_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct w1_slave *sl, *sln;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mutex_lock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) list_del(&dev->w1_master_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mutex_unlock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) set_bit(W1_ABORT_SEARCH, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) kthread_stop(dev->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mutex_lock(&dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) w1_slave_detach(sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) w1_destroy_master_attributes(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mutex_unlock(&dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) atomic_dec(&dev->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) while (atomic_read(&dev->refcnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dev->name, atomic_read(&dev->refcnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (msleep_interruptible(1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) w1_process_callbacks(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) w1_process_callbacks(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) memset(&msg, 0, sizeof(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) msg.id.mst.id = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) msg.type = W1_MASTER_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) w1_netlink_send(dev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) w1_free_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * w1_remove_master_device() - unregister a master device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * @bm: master bus device to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) void w1_remove_master_device(struct w1_bus_master *bm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct w1_master *dev, *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) list_for_each_entry(dev, &w1_masters, w1_master_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!dev->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (dev->bus_master->data == bm->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) found = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) pr_err("Device doesn't exist.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) __w1_remove_master_device(found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) EXPORT_SYMBOL(w1_remove_master_device);