From 3dbfb1776e535cdf0464e4b39e707173acd62c69 Mon Sep 17 00:00:00 2001 From: Elias Hasnat Date: Mon, 15 Jan 2018 20:11:50 +0900 Subject: [PATCH] experimental unblock --- drivers/i2c/i2c-dev.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 1 + 2 files changed, 39 insertions(+) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 2cab27a6847980..4f0d645d0e6d8c 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -687,6 +687,27 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) return 0; } +static int i2cdev_detach_adapter_unblock(struct device *dev, void *dummy) +{ + struct i2c_adapter *adap; + struct i2c_dev *i2c_dev; + + if (dev->type != &i2c_adapter_type) + return 0; + adap = to_i2c_adapter(dev); + + i2c_dev = i2c_dev_get_my_minor(adap->nr); + if (!i2c_dev) + return 0; + + cdev_del(&i2c_dev->cdev); + put_i2c_dev(i2c_dev); + device_destroy()i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr); + + pr_debug("i2c-dev: adapter [%s] unblock expereiment\n", adap->name); + return 0; +} + static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, void *data) { @@ -702,10 +723,27 @@ static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, return 0; } +static int i2cdev_notifier_unblock(struct notifier_block *nb, unsigned long action, void *data, int flag) +{ + struct device *dev = data; + + switch (action) { + case BUS_NOTIFY_DEL_DEVICE: + return i2cdev_detach_adapter(dev, NULL); + case BUS_NOTIFY_ADD_DEVICE: + return i2cdev_attach_adapter(dev, NULL); + case BUS_NOTIFY_BLOCK_DEVICE: + return i2cdev_detach_adapter(dev, NULL); + } +} + static struct notifier_block i2cdev_notifier = { .notifier_call = i2cdev_notifier_call, }; +static struct notifier_unblock i2cdev_notifier = { + .notifier_call = i2cdev_notifier_unblock, +} /* ------------------------------------------------------------------------- */ /* diff --git a/include/linux/device.h b/include/linux/device.h index 9d32000725da84..790d135d98ce2a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -202,6 +202,7 @@ extern int bus_unregister_notifier(struct bus_type *bus, #define BUS_NOTIFY_UNBOUND_DRIVER 0x00000007 /* driver is unbound from the device */ #define BUS_NOTIFY_DRIVER_NOT_BOUND 0x00000008 /* driver fails to be bound */ +#define BUS_NOTIFY_BLOCK_DEVICE 0x00000110 /* experiemental device block notification */ extern struct kset *bus_get_kset(struct bus_type *bus); extern struct klist *bus_get_device_klist(struct bus_type *bus);