.read = &w1_default_read_bin,
 };
 
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
 
 static struct bus_type w1_bus_type = {
        .name = "w1",
        .match = w1_master_match,
+       .hotplug = w1_hotplug,
 };
 
-struct device_driver w1_driver = {
-       .name = "w1_driver",
+struct device_driver w1_master_driver = {
+       .name = "w1_master_driver",
        .bus = &w1_bus_type,
        .probe = w1_master_probe,
        .remove = w1_master_remove,
 };
 
-struct device w1_device = {
+struct device w1_master_device = {
        .parent = NULL,
        .bus = &w1_bus_type,
        .bus_id = "w1 bus master",
-       .driver = &w1_driver,
+       .driver = &w1_master_driver,
        .release = &w1_master_release
 };
 
+struct device_driver w1_slave_driver = {
+       .name = "w1_slave_driver",
+       .bus = &w1_bus_type,
+};
+
+struct device w1_slave_device = {
+       .parent = NULL,
+       .bus = &w1_bus_type,
+       .bus_id = "w1 bus slave",
+       .driver = &w1_slave_driver,
+};
+
 static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct w1_master *md = container_of(dev, struct w1_master, dev);
        sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
 }
 
+#ifdef CONFIG_HOTPLUG
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+{
+       struct w1_master *md = NULL;
+       struct w1_slave *sl = NULL;
+       char *event_owner, *name;
+       int err, cur_index=0, cur_len=0;
+
+       if (dev->driver == &w1_master_driver) {
+               md = container_of(dev, struct w1_master, dev);
+               event_owner = "master";
+               name = md->name;
+       } else if (dev->driver == &w1_slave_driver) {
+               sl = container_of(dev, struct w1_slave, dev);
+               event_owner = "slave";
+               name = sl->name;
+       } else {
+               dev_dbg(dev, "Unknown hotplug event.\n");
+               return -EINVAL;
+       }
+
+       dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id);
+
+       if (dev->driver != &w1_slave_driver || !sl)
+               return 0;
+
+       err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
+       if (err)
+               return err;
+
+       err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024llX", sl->reg_num.id);
+       if (err)
+               return err;
+
+       return 0;
+};
+#else
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+{
+       return 0;
+}
+#endif
+
 static int __w1_attach_slave_device(struct w1_slave *sl)
 {
        int err;
 
        sl->dev.parent = &sl->master->dev;
-       sl->dev.driver = sl->master->driver;
+       sl->dev.driver = &w1_slave_driver;
        sl->dev.bus = &w1_bus_type;
        sl->dev.release = &w1_slave_release;
 
        spin_unlock_bh(&w1_mlock);
 }
 
-
 static void w1_slave_found(unsigned long data, u64 rn)
 {
        int slave_count;
                goto err_out_exit_init;
        }
 
-       retval = driver_register(&w1_driver);
+       retval = driver_register(&w1_master_driver);
        if (retval) {
                printk(KERN_ERR
                        "Failed to register master driver. err=%d.\n",
                goto err_out_bus_unregister;
        }
 
+       retval = driver_register(&w1_slave_driver);
+       if (retval) {
+               printk(KERN_ERR
+                       "Failed to register master driver. err=%d.\n",
+                       retval);
+               goto err_out_master_unregister;
+       }
+
        control_thread = kernel_thread(&w1_control, NULL, 0);
        if (control_thread < 0) {
                printk(KERN_ERR "Failed to create control thread. err=%d\n",
                        control_thread);
                retval = control_thread;
-               goto err_out_driver_unregister;
+               goto err_out_slave_unregister;
        }
 
        return 0;
 
-err_out_driver_unregister:
-       driver_unregister(&w1_driver);
+err_out_slave_unregister:
+       driver_unregister(&w1_slave_driver);
+
+err_out_master_unregister:
+       driver_unregister(&w1_master_driver);
 
 err_out_bus_unregister:
        bus_unregister(&w1_bus_type);
        control_needs_exit = 1;
        wait_for_completion(&w1_control_complete);
 
-       driver_unregister(&w1_driver);
+       driver_unregister(&w1_slave_driver);
+       driver_unregister(&w1_master_driver);
        bus_unregister(&w1_bus_type);
 }