Commit f9b873da authored by Evgeniy Polyakov's avatar Evgeniy Polyakov Committed by Greg Kroah-Hartman

[PATCH] w1: Added slave->ttl - time to live for the registered slave.

Added slave->ttl - time to live for the registered slave.
When slave was not found we will not remove it immediately but wait until ->ttl attempts were done.
It prevents various debouncing effects(problems with pull-up, power).
Signed-off-by: default avatarEvgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent c424d67c
...@@ -47,9 +47,11 @@ MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); ...@@ -47,9 +47,11 @@ MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
static int w1_timeout = 10; static int w1_timeout = 10;
int w1_max_slave_count = 10; int w1_max_slave_count = 10;
int w1_max_slave_ttl = 10;
module_param_named(timeout, w1_timeout, int, 0); module_param_named(timeout, w1_timeout, int, 0);
module_param_named(max_slave_count, w1_max_slave_count, int, 0); module_param_named(max_slave_count, w1_max_slave_count, int, 0);
module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
spinlock_t w1_mlock = SPIN_LOCK_UNLOCKED; spinlock_t w1_mlock = SPIN_LOCK_UNLOCKED;
LIST_HEAD(w1_masters); LIST_HEAD(w1_masters);
...@@ -431,6 +433,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) ...@@ -431,6 +433,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
return err; return err;
} }
sl->ttl = dev->slave_ttl;
dev->slave_count++; dev->slave_count++;
memcpy(&msg.id.id, rn, sizeof(msg.id.id)); memcpy(&msg.id.id, rn, sizeof(msg.id.id));
...@@ -569,7 +572,7 @@ static void w1_search(struct w1_master *dev) ...@@ -569,7 +572,7 @@ static void w1_search(struct w1_master *dev)
} }
if (slave_count == dev->slave_count && if (slave_count == dev->slave_count &&
((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) { rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
w1_attach_slave_device(dev, (struct w1_reg_num *) &rn); w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
} }
} }
...@@ -718,7 +721,7 @@ int w1_process(void *data) ...@@ -718,7 +721,7 @@ int w1_process(void *data)
list_for_each_safe(ent, n, &dev->slist) { list_for_each_safe(ent, n, &dev->slist) {
sl = list_entry(ent, struct w1_slave, w1_slave_entry); sl = list_entry(ent, struct w1_slave, w1_slave_entry);
if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) { if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
list_del (&sl->w1_slave_entry); list_del (&sl->w1_slave_entry);
w1_slave_detach (sl); w1_slave_detach (sl);
...@@ -726,6 +729,8 @@ int w1_process(void *data) ...@@ -726,6 +729,8 @@ int w1_process(void *data)
dev->slave_count--; dev->slave_count--;
} }
else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
sl->ttl = dev->slave_ttl;
} }
up(&dev->mutex); up(&dev->mutex);
} }
......
...@@ -63,6 +63,7 @@ struct w1_slave ...@@ -63,6 +63,7 @@ struct w1_slave
atomic_t refcnt; atomic_t refcnt;
u8 rom[9]; u8 rom[9];
u32 flags; u32 flags;
int ttl;
struct w1_master *master; struct w1_master *master;
struct w1_family *family; struct w1_family *family;
...@@ -99,6 +100,7 @@ struct w1_master ...@@ -99,6 +100,7 @@ struct w1_master
struct list_head slist; struct list_head slist;
int max_slave_count, slave_count; int max_slave_count, slave_count;
unsigned long attempts; unsigned long attempts;
int slave_ttl;
int initialized; int initialized;
u32 id; u32 id;
......
...@@ -32,12 +32,13 @@ extern struct device_driver w1_driver; ...@@ -32,12 +32,13 @@ extern struct device_driver w1_driver;
extern struct bus_type w1_bus_type; extern struct bus_type w1_bus_type;
extern struct device w1_device; extern struct device w1_device;
extern int w1_max_slave_count; extern int w1_max_slave_count;
extern int w1_max_slave_ttl;
extern struct list_head w1_masters; extern struct list_head w1_masters;
extern spinlock_t w1_mlock; extern spinlock_t w1_mlock;
extern int w1_process(void *); extern int w1_process(void *);
struct w1_master * w1_alloc_dev(u32 id, int slave_count, struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
struct device_driver *driver, struct device *device) struct device_driver *driver, struct device *device)
{ {
struct w1_master *dev; struct w1_master *dev;
...@@ -65,6 +66,7 @@ struct w1_master * w1_alloc_dev(u32 id, int slave_count, ...@@ -65,6 +66,7 @@ struct w1_master * w1_alloc_dev(u32 id, int slave_count,
dev->kpid = -1; dev->kpid = -1;
dev->initialized = 0; dev->initialized = 0;
dev->id = id; dev->id = id;
dev->slave_ttl = slave_ttl;
atomic_set(&dev->refcnt, 2); atomic_set(&dev->refcnt, 2);
...@@ -121,7 +123,7 @@ int w1_add_master_device(struct w1_bus_master *master) ...@@ -121,7 +123,7 @@ int w1_add_master_device(struct w1_bus_master *master)
int retval = 0; int retval = 0;
struct w1_netlink_msg msg; struct w1_netlink_msg msg;
dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, &w1_driver, &w1_device); dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "w1.h" #include "w1.h"
struct w1_master * w1_alloc_dev(int, struct device_driver *, struct device *); struct w1_master * w1_alloc_dev(u32, int, int, struct device_driver *, struct device *);
void w1_free_dev(struct w1_master *dev); void w1_free_dev(struct w1_master *dev);
int w1_add_master_device(struct w1_bus_master *); int w1_add_master_device(struct w1_bus_master *);
void w1_remove_master_device(struct w1_bus_master *); void w1_remove_master_device(struct w1_bus_master *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment