[PATCH v3 02/26] staging: most: integrate driver in kernel's device model

Christian Gromm christian.gromm at microchip.com
Mon Oct 16 08:46:09 UTC 2017


The following patch adapts the driver to use the device model by:

	- adopting the MOST bus_type
	- registering the core as a busdriver
	- removing private kobject/kset usage
	- removing private lists and structures to track registered modules
	  and making use of the device model API
	- removing prefix of modules
	- allowing adapter drivers (a.k.a. HDM) to register MOST devices
	- registering AIM modules as components with the core to build
	  the user space experience of the driver stack
	- using attribute groups to create the sysfs files
	- renaming variables to prevent collision with the introduced device
	  structs.

Signed-off-by: Christian Gromm <christian.gromm at microchip.com>
---
v2: fix patch numeration
v3: - add cover letter
    - create patches with -M switch to make file movement visible

 drivers/staging/most/cdev/cdev.c   |   6 +-
 drivers/staging/most/core.c        | 930 ++++++++++++-------------------------
 drivers/staging/most/core.h        |   9 +-
 drivers/staging/most/dim2/dim2.c   |  20 +-
 drivers/staging/most/dim2/sysfs.c  |  92 +---
 drivers/staging/most/dim2/sysfs.h  |   6 +-
 drivers/staging/most/i2c/i2c.c     |   7 +-
 drivers/staging/most/net/net.c     |   4 +-
 drivers/staging/most/sound/sound.c |   5 +-
 drivers/staging/most/usb/usb.c     | 244 +++-------
 drivers/staging/most/video/video.c |   4 +-
 11 files changed, 405 insertions(+), 922 deletions(-)

diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c
index 3dce5e0..4b4c112 100644
--- a/drivers/staging/most/cdev/cdev.c
+++ b/drivers/staging/most/cdev/cdev.c
@@ -427,14 +427,14 @@ static int aim_tx_completion(struct most_interface *iface, int channel_id)
  */
 static int aim_probe(struct most_interface *iface, int channel_id,
 		     struct most_channel_config *cfg,
-		     struct kobject *parent, char *name)
+		     char *name)
 {
 	struct aim_channel *c;
 	unsigned long cl_flags;
 	int retval;
 	int current_minor;
 
-	if ((!iface) || (!cfg) || (!parent) || (!name)) {
+	if ((!iface) || (!cfg) || (!name)) {
 		pr_info("Probing AIM with bad arguments");
 		return -EINVAL;
 	}
@@ -498,7 +498,7 @@ static int aim_probe(struct most_interface *iface, int channel_id,
 }
 
 static struct most_aim cdev_aim = {
-	.name = "cdev",
+	.name = "aim_cdev",
 	.probe_channel = aim_probe,
 	.disconnect_channel = aim_disconnect_channel,
 	.rx_completion = aim_rx_completion,
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index 6ee6acf..54a56a0 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -33,7 +33,7 @@
 #define STRING_SIZE	80
 
 static struct class *most_class;
-static struct device *core_dev;
+static struct device core_dev;
 static struct ida mdev_id;
 static int dummy_num_buffers;
 
@@ -44,7 +44,7 @@ struct most_c_aim_obj {
 };
 
 struct most_c_obj {
-	struct kobject kobj;
+	struct device dev;
 	struct completion cleanup;
 	atomic_t mbo_ref;
 	atomic_t mbo_nq_level;
@@ -69,14 +69,13 @@ struct most_c_obj {
 	wait_queue_head_t hdm_fifo_wq;
 };
 
-#define to_c_obj(d) container_of(d, struct most_c_obj, kobj)
+#define to_c_obj(d) container_of(d, struct most_c_obj, dev)
 
 struct most_inst_obj {
 	int dev_id;
 	struct most_interface *iface;
 	struct list_head channel_list;
 	struct most_c_obj *channel[MAX_CHANNELS];
-	struct kobject kobj;
 	struct list_head list;
 };
 
@@ -91,8 +90,23 @@ struct most_inst_obj {
 	{ MOST_CH_ISOC, "isoc_avp\n"},
 };
 
-#define to_inst_obj(d) container_of(d, struct most_inst_obj, kobj)
+int most_match(struct device *dev, struct device_driver *drv)
+{
+	if (!strcmp(dev_name(dev), "most"))
+		return 0;
+	else
+		return 1;
+}
+
+static struct bus_type most_bus_type = {
+	.name = "most",
+	.match = most_match,
+};
 
+static struct device_driver mostcore = {
+	.name = "most_core",
+	.bus = &most_bus_type,
+};
 /**
  * list_pop_mbo - retrieves the first MBO of the list and removes it
  * @ptr: the list head to grab the MBO from.
@@ -108,67 +122,6 @@ struct most_inst_obj {
  *		     ___C H A N N E L___
  */
 
-/**
- * struct most_c_attr - to access the attributes of a channel object
- * @attr: attributes of a channel
- * @show: pointer to the show function
- * @store: pointer to the store function
- */
-struct most_c_attr {
-	struct attribute attr;
-	ssize_t (*show)(struct most_c_obj *d,
-			struct most_c_attr *attr,
-			char *buf);
-	ssize_t (*store)(struct most_c_obj *d,
-			 struct most_c_attr *attr,
-			 const char *buf,
-			 size_t count);
-};
-
-#define to_channel_attr(a) container_of(a, struct most_c_attr, attr)
-
-/**
- * channel_attr_show - show function of channel object
- * @kobj: pointer to its kobject
- * @attr: pointer to its attributes
- * @buf: buffer
- */
-static ssize_t channel_attr_show(struct kobject *kobj, struct attribute *attr,
-				 char *buf)
-{
-	struct most_c_attr *channel_attr = to_channel_attr(attr);
-	struct most_c_obj *c_obj = to_c_obj(kobj);
-
-	if (!channel_attr->show)
-		return -EIO;
-
-	return channel_attr->show(c_obj, channel_attr, buf);
-}
-
-/**
- * channel_attr_store - store function of channel object
- * @kobj: pointer to its kobject
- * @attr: pointer to its attributes
- * @buf: buffer
- * @len: length of buffer
- */
-static ssize_t channel_attr_store(struct kobject *kobj,
-				  struct attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	struct most_c_attr *channel_attr = to_channel_attr(attr);
-	struct most_c_obj *c_obj = to_c_obj(kobj);
-
-	if (!channel_attr->store)
-		return -EIO;
-	return channel_attr->store(c_obj, channel_attr, buf, len);
-}
-
-static const struct sysfs_ops most_channel_sysfs_ops = {
-	.show = channel_attr_show,
-	.store = channel_attr_store,
-};
 
 /**
  * most_free_mbo_coherent - free an MBO and its coherent buffer
@@ -241,21 +194,11 @@ static int flush_trash_fifo(struct most_c_obj *c)
 	return 0;
 }
 
-/**
- * most_channel_release - release function of channel object
- * @kobj: pointer to channel's kobject
- */
-static void most_channel_release(struct kobject *kobj)
-{
-	struct most_c_obj *c = to_c_obj(kobj);
-
-	kfree(c);
-}
-
-static ssize_t available_directions_show(struct most_c_obj *c,
-					 struct most_c_attr *attr,
+static ssize_t available_directions_show(struct device *dev,
+					 struct device_attribute *attr,
 					 char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
 	unsigned int i = c->channel_id;
 
 	strcpy(buf, "");
@@ -267,10 +210,11 @@ static ssize_t available_directions_show(struct most_c_obj *c,
 	return strlen(buf);
 }
 
-static ssize_t available_datatypes_show(struct most_c_obj *c,
-					struct most_c_attr *attr,
+static ssize_t available_datatypes_show(struct device *dev,
+					struct device_attribute *attr,
 					char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
 	unsigned int i = c->channel_id;
 
 	strcpy(buf, "");
@@ -286,65 +230,75 @@ static ssize_t available_datatypes_show(struct most_c_obj *c,
 	return strlen(buf);
 }
 
-static ssize_t number_of_packet_buffers_show(struct most_c_obj *c,
-					     struct most_c_attr *attr,
+static ssize_t number_of_packet_buffers_show(struct device *dev,
+					     struct device_attribute *attr,
 					     char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
 	unsigned int i = c->channel_id;
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			c->iface->channel_vector[i].num_buffers_packet);
 }
 
-static ssize_t number_of_stream_buffers_show(struct most_c_obj *c,
-					     struct most_c_attr *attr,
+static ssize_t number_of_stream_buffers_show(struct device *dev,
+					     struct device_attribute *attr,
 					     char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
 	unsigned int i = c->channel_id;
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			c->iface->channel_vector[i].num_buffers_streaming);
 }
 
-static ssize_t size_of_packet_buffer_show(struct most_c_obj *c,
-					  struct most_c_attr *attr,
+static ssize_t size_of_packet_buffer_show(struct device *dev,
+					  struct device_attribute *attr,
 					  char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
 	unsigned int i = c->channel_id;
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			c->iface->channel_vector[i].buffer_size_packet);
 }
 
-static ssize_t size_of_stream_buffer_show(struct most_c_obj *c,
-					  struct most_c_attr *attr,
+static ssize_t size_of_stream_buffer_show(struct device *dev,
+					  struct device_attribute *attr,
 					  char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
 	unsigned int i = c->channel_id;
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			c->iface->channel_vector[i].buffer_size_streaming);
 }
 
-static ssize_t channel_starving_show(struct most_c_obj *c,
-				     struct most_c_attr *attr,
+static ssize_t channel_starving_show(struct device *dev,
+				     struct device_attribute *attr,
 				     char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->is_starving);
 }
 
-static ssize_t set_number_of_buffers_show(struct most_c_obj *c,
-					  struct most_c_attr *attr,
+static ssize_t set_number_of_buffers_show(struct device *dev,
+					  struct device_attribute *attr,
 					  char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.num_buffers);
 }
 
-static ssize_t set_number_of_buffers_store(struct most_c_obj *c,
-					   struct most_c_attr *attr,
+static ssize_t set_number_of_buffers_store(struct device *dev,
+					   struct device_attribute *attr,
 					   const char *buf,
 					   size_t count)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	int ret = kstrtou16(buf, 0, &c->cfg.num_buffers);
 
 	if (ret)
@@ -352,18 +306,22 @@ static ssize_t set_number_of_buffers_store(struct most_c_obj *c,
 	return count;
 }
 
-static ssize_t set_buffer_size_show(struct most_c_obj *c,
-				    struct most_c_attr *attr,
+static ssize_t set_buffer_size_show(struct device *dev,
+				    struct device_attribute *attr,
 				    char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.buffer_size);
 }
 
-static ssize_t set_buffer_size_store(struct most_c_obj *c,
-				     struct most_c_attr *attr,
+static ssize_t set_buffer_size_store(struct device *dev,
+				     struct device_attribute *attr,
 				     const char *buf,
 				     size_t count)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	int ret = kstrtou16(buf, 0, &c->cfg.buffer_size);
 
 	if (ret)
@@ -371,10 +329,12 @@ static ssize_t set_buffer_size_store(struct most_c_obj *c,
 	return count;
 }
 
-static ssize_t set_direction_show(struct most_c_obj *c,
-				  struct most_c_attr *attr,
+static ssize_t set_direction_show(struct device *dev,
+				  struct device_attribute *attr,
 				  char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	if (c->cfg.direction & MOST_CH_TX)
 		return snprintf(buf, PAGE_SIZE, "tx\n");
 	else if (c->cfg.direction & MOST_CH_RX)
@@ -382,11 +342,13 @@ static ssize_t set_direction_show(struct most_c_obj *c,
 	return snprintf(buf, PAGE_SIZE, "unconfigured\n");
 }
 
-static ssize_t set_direction_store(struct most_c_obj *c,
-				   struct most_c_attr *attr,
+static ssize_t set_direction_store(struct device *dev,
+				   struct device_attribute *attr,
 				   const char *buf,
 				   size_t count)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	if (!strcmp(buf, "dir_rx\n")) {
 		c->cfg.direction = MOST_CH_RX;
 	} else if (!strcmp(buf, "rx\n")) {
@@ -402,11 +364,12 @@ static ssize_t set_direction_store(struct most_c_obj *c,
 	return count;
 }
 
-static ssize_t set_datatype_show(struct most_c_obj *c,
-				 struct most_c_attr *attr,
+static ssize_t set_datatype_show(struct device *dev,
+				 struct device_attribute *attr,
 				 char *buf)
 {
 	int i;
+	struct most_c_obj *c = to_c_obj(dev);
 
 	for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
 		if (c->cfg.data_type & ch_data_type[i].most_ch_data_type)
@@ -415,12 +378,13 @@ static ssize_t set_datatype_show(struct most_c_obj *c,
 	return snprintf(buf, PAGE_SIZE, "unconfigured\n");
 }
 
-static ssize_t set_datatype_store(struct most_c_obj *c,
-				  struct most_c_attr *attr,
+static ssize_t set_datatype_store(struct device *dev,
+				  struct device_attribute *attr,
 				  const char *buf,
 				  size_t count)
 {
 	int i;
+	struct most_c_obj *c = to_c_obj(dev);
 
 	for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
 		if (!strcmp(buf, ch_data_type[i].name)) {
@@ -436,18 +400,22 @@ static ssize_t set_datatype_store(struct most_c_obj *c,
 	return count;
 }
 
-static ssize_t set_subbuffer_size_show(struct most_c_obj *c,
-				       struct most_c_attr *attr,
+static ssize_t set_subbuffer_size_show(struct device *dev,
+				       struct device_attribute *attr,
 				       char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.subbuffer_size);
 }
 
-static ssize_t set_subbuffer_size_store(struct most_c_obj *c,
-					struct most_c_attr *attr,
+static ssize_t set_subbuffer_size_store(struct device *dev,
+					struct device_attribute *attr,
 					const char *buf,
 					size_t count)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	int ret = kstrtou16(buf, 0, &c->cfg.subbuffer_size);
 
 	if (ret)
@@ -455,18 +423,22 @@ static ssize_t set_subbuffer_size_store(struct most_c_obj *c,
 	return count;
 }
 
-static ssize_t set_packets_per_xact_show(struct most_c_obj *c,
-					 struct most_c_attr *attr,
+static ssize_t set_packets_per_xact_show(struct device *dev,
+					 struct device_attribute *attr,
 					 char *buf)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.packets_per_xact);
 }
 
-static ssize_t set_packets_per_xact_store(struct most_c_obj *c,
-					  struct most_c_attr *attr,
+static ssize_t set_packets_per_xact_store(struct device *dev,
+					  struct device_attribute *attr,
 					  const char *buf,
 					  size_t count)
 {
+	struct most_c_obj *c = to_c_obj(dev);
+
 	int ret = kstrtou16(buf, 0, &c->cfg.packets_per_xact);
 
 	if (ret)
@@ -474,77 +446,47 @@ static ssize_t set_packets_per_xact_store(struct most_c_obj *c,
 	return count;
 }
 
-static struct most_c_attr most_c_attrs[] = {
-	__ATTR_RO(available_directions),
-	__ATTR_RO(available_datatypes),
-	__ATTR_RO(number_of_packet_buffers),
-	__ATTR_RO(number_of_stream_buffers),
-	__ATTR_RO(size_of_stream_buffer),
-	__ATTR_RO(size_of_packet_buffer),
-	__ATTR_RO(channel_starving),
-	__ATTR_RW(set_buffer_size),
-	__ATTR_RW(set_number_of_buffers),
-	__ATTR_RW(set_direction),
-	__ATTR_RW(set_datatype),
-	__ATTR_RW(set_subbuffer_size),
-	__ATTR_RW(set_packets_per_xact),
-};
-
-/**
- * most_channel_def_attrs - array of default attributes of channel object
- */
-static struct attribute *most_channel_def_attrs[] = {
-	&most_c_attrs[0].attr,
-	&most_c_attrs[1].attr,
-	&most_c_attrs[2].attr,
-	&most_c_attrs[3].attr,
-	&most_c_attrs[4].attr,
-	&most_c_attrs[5].attr,
-	&most_c_attrs[6].attr,
-	&most_c_attrs[7].attr,
-	&most_c_attrs[8].attr,
-	&most_c_attrs[9].attr,
-	&most_c_attrs[10].attr,
-	&most_c_attrs[11].attr,
-	&most_c_attrs[12].attr,
+#define DEV_ATTR(_name)  &dev_attr_##_name.attr
+
+static DEVICE_ATTR_RO(available_directions);
+static DEVICE_ATTR_RO(available_datatypes);
+static DEVICE_ATTR_RO(number_of_packet_buffers);
+static DEVICE_ATTR_RO(number_of_stream_buffers);
+static DEVICE_ATTR_RO(size_of_stream_buffer);
+static DEVICE_ATTR_RO(size_of_packet_buffer);
+static DEVICE_ATTR_RO(channel_starving);
+static DEVICE_ATTR_RW(set_buffer_size);
+static DEVICE_ATTR_RW(set_number_of_buffers);
+static DEVICE_ATTR_RW(set_direction);
+static DEVICE_ATTR_RW(set_datatype);
+static DEVICE_ATTR_RW(set_subbuffer_size);
+static DEVICE_ATTR_RW(set_packets_per_xact);
+
+static struct attribute *channel_attrs[] = {
+	DEV_ATTR(available_directions),
+	DEV_ATTR(available_datatypes),
+	DEV_ATTR(number_of_packet_buffers),
+	DEV_ATTR(number_of_stream_buffers),
+	DEV_ATTR(size_of_stream_buffer),
+	DEV_ATTR(size_of_packet_buffer),
+	DEV_ATTR(channel_starving),
+	DEV_ATTR(set_buffer_size),
+	DEV_ATTR(set_number_of_buffers),
+	DEV_ATTR(set_direction),
+	DEV_ATTR(set_datatype),
+	DEV_ATTR(set_subbuffer_size),
+	DEV_ATTR(set_packets_per_xact),
 	NULL,
 };
 
-static struct kobj_type most_channel_ktype = {
-	.sysfs_ops = &most_channel_sysfs_ops,
-	.release = most_channel_release,
-	.default_attrs = most_channel_def_attrs,
+static struct attribute_group channel_attr_group = {
+	.attrs = channel_attrs,
 };
 
-static struct kset *most_channel_kset;
-
-/**
- * create_most_c_obj - allocates a channel object
- * @name: name of the channel object
- * @parent: parent kobject
- *
- * This create a channel object and registers it with sysfs.
- * Returns a pointer to the object or NULL when something went wrong.
- */
-static struct most_c_obj *
-create_most_c_obj(const char *name, struct kobject *parent)
-{
-	struct most_c_obj *c;
-	int retval;
-
-	c = kzalloc(sizeof(*c), GFP_KERNEL);
-	if (!c)
-		return NULL;
-	c->kobj.kset = most_channel_kset;
-	retval = kobject_init_and_add(&c->kobj, &most_channel_ktype, parent,
-				      "%s", name);
-	if (retval) {
-		kobject_put(&c->kobj);
-		return NULL;
-	}
-	kobject_uevent(&c->kobj, KOBJ_ADD);
-	return c;
-}
+static const struct attribute_group *channel_attr_groups[] = {
+	&channel_attr_group,
+	NULL,
+};
 
 /*		     ___	       ___
  *		     ___I N S T A N C E___
@@ -552,103 +494,22 @@ static ssize_t set_packets_per_xact_store(struct most_c_obj *c,
 
 static struct list_head instance_list;
 
-/**
- * struct most_inst_attribute - to access the attributes of instance object
- * @attr: attributes of an instance
- * @show: pointer to the show function
- * @store: pointer to the store function
- */
-struct most_inst_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct most_inst_obj *d,
-			struct most_inst_attribute *attr,
-			char *buf);
-	ssize_t (*store)(struct most_inst_obj *d,
-			 struct most_inst_attribute *attr,
-			 const char *buf,
-			 size_t count);
-};
-
-#define to_instance_attr(a) \
-	container_of(a, struct most_inst_attribute, attr)
-
-/**
- * instance_attr_show - show function for an instance object
- * @kobj: pointer to kobject
- * @attr: pointer to attribute struct
- * @buf: buffer
- */
-static ssize_t instance_attr_show(struct kobject *kobj,
-				  struct attribute *attr,
-				  char *buf)
-{
-	struct most_inst_attribute *instance_attr;
-	struct most_inst_obj *instance_obj;
-
-	instance_attr = to_instance_attr(attr);
-	instance_obj = to_inst_obj(kobj);
-
-	if (!instance_attr->show)
-		return -EIO;
-
-	return instance_attr->show(instance_obj, instance_attr, buf);
-}
-
-/**
- * instance_attr_store - store function for an instance object
- * @kobj: pointer to kobject
- * @attr: pointer to attribute struct
- * @buf: buffer
- * @len: length of buffer
- */
-static ssize_t instance_attr_store(struct kobject *kobj,
-				   struct attribute *attr,
-				   const char *buf,
-				   size_t len)
-{
-	struct most_inst_attribute *instance_attr;
-	struct most_inst_obj *instance_obj;
-
-	instance_attr = to_instance_attr(attr);
-	instance_obj = to_inst_obj(kobj);
-
-	if (!instance_attr->store)
-		return -EIO;
-
-	return instance_attr->store(instance_obj, instance_attr, buf, len);
-}
-
-static const struct sysfs_ops most_inst_sysfs_ops = {
-	.show = instance_attr_show,
-	.store = instance_attr_store,
-};
-
-/**
- * most_inst_release - release function for instance object
- * @kobj: pointer to instance's kobject
- *
- * This frees the allocated memory for the instance object
- */
-static void most_inst_release(struct kobject *kobj)
-{
-	struct most_inst_obj *inst = to_inst_obj(kobj);
-
-	kfree(inst);
-}
-
-static ssize_t description_show(struct most_inst_obj *instance_obj,
-				struct most_inst_attribute *attr,
+static ssize_t description_show(struct device *dev,
+				struct device_attribute *attr,
 				char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			instance_obj->iface->description);
+	struct most_interface *iface = to_most_interface(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", iface->description);
 }
 
-static ssize_t interface_show(struct most_inst_obj *instance_obj,
-			      struct most_inst_attribute *attr,
+static ssize_t interface_show(struct device *dev,
+			      struct device_attribute *attr,
 			      char *buf)
 {
-	switch (instance_obj->iface->interface) {
+	struct most_interface *iface = to_most_interface(dev);
+
+	switch (iface->interface) {
 	case ITYPE_LOOPBACK:
 		return snprintf(buf, PAGE_SIZE, "loopback\n");
 	case ITYPE_I2C:
@@ -671,182 +532,45 @@ static ssize_t interface_show(struct most_inst_obj *instance_obj,
 	return snprintf(buf, PAGE_SIZE, "unknown\n");
 }
 
-static struct most_inst_attribute most_inst_attr_description =
-	__ATTR_RO(description);
+static DEVICE_ATTR_RO(description);
+static DEVICE_ATTR_RO(interface);
 
-static struct most_inst_attribute most_inst_attr_interface =
-	__ATTR_RO(interface);
-
-static struct attribute *most_inst_def_attrs[] = {
-	&most_inst_attr_description.attr,
-	&most_inst_attr_interface.attr,
+static struct attribute *interface_attrs[] = {
+	DEV_ATTR(description),
+	DEV_ATTR(interface),
 	NULL,
 };
 
-static struct kobj_type most_inst_ktype = {
-	.sysfs_ops = &most_inst_sysfs_ops,
-	.release = most_inst_release,
-	.default_attrs = most_inst_def_attrs,
+static struct attribute_group interface_attr_group = {
+	.attrs = interface_attrs,
 };
 
-static struct kset *most_inst_kset;
-
-/**
- * create_most_inst_obj - creates an instance object
- * @name: name of the object to be created
- *
- * This allocates memory for an instance structure, assigns the proper kset
- * and registers it with sysfs.
- *
- * Returns a pointer to the instance object or NULL when something went wrong.
- */
-static struct most_inst_obj *create_most_inst_obj(const char *name)
-{
-	struct most_inst_obj *inst;
-	int retval;
-
-	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
-	if (!inst)
-		return NULL;
-	inst->kobj.kset = most_inst_kset;
-	retval = kobject_init_and_add(&inst->kobj, &most_inst_ktype, NULL,
-				      "%s", name);
-	if (retval) {
-		kobject_put(&inst->kobj);
-		return NULL;
-	}
-	kobject_uevent(&inst->kobj, KOBJ_ADD);
-	return inst;
-}
-
-/**
- * destroy_most_inst_obj - MOST instance release function
- * @inst: pointer to the instance object
- *
- * This decrements the reference counter of the instance object.
- * If the reference count turns zero, its release function is called
- */
-static void destroy_most_inst_obj(struct most_inst_obj *inst)
-{
-	struct most_c_obj *c, *tmp;
+static const struct attribute_group *interface_attr_groups[] = {
+	&interface_attr_group,
+	NULL,
+};
 
-	list_for_each_entry_safe(c, tmp, &inst->channel_list, list) {
-		flush_trash_fifo(c);
-		flush_channel_fifos(c);
-		kobject_put(&c->kobj);
-	}
-	kobject_put(&inst->kobj);
-}
 
 /*		     ___     ___
  *		     ___A I M___
  */
-struct most_aim_obj {
-	struct kobject kobj;
-	struct list_head list;
-	struct most_aim *driver;
-};
-
-#define to_aim_obj(d) container_of(d, struct most_aim_obj, kobj)
-
 static struct list_head aim_list;
 
-/**
- * struct most_aim_attribute - to access the attributes of AIM object
- * @attr: attributes of an AIM
- * @show: pointer to the show function
- * @store: pointer to the store function
- */
-struct most_aim_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct most_aim_obj *d,
-			struct most_aim_attribute *attr,
-			char *buf);
-	ssize_t (*store)(struct most_aim_obj *d,
-			 struct most_aim_attribute *attr,
-			 const char *buf,
-			 size_t count);
-};
-
-#define to_aim_attr(a) container_of(a, struct most_aim_attribute, attr)
-
-/**
- * aim_attr_show - show function of an AIM object
- * @kobj: pointer to kobject
- * @attr: pointer to attribute struct
- * @buf: buffer
- */
-static ssize_t aim_attr_show(struct kobject *kobj,
-			     struct attribute *attr,
-			     char *buf)
-{
-	struct most_aim_attribute *aim_attr;
-	struct most_aim_obj *aim_obj;
-
-	aim_attr = to_aim_attr(attr);
-	aim_obj = to_aim_obj(kobj);
-
-	if (!aim_attr->show)
-		return -EIO;
-
-	return aim_attr->show(aim_obj, aim_attr, buf);
-}
-
-/**
- * aim_attr_store - store function of an AIM object
- * @kobj: pointer to kobject
- * @attr: pointer to attribute struct
- * @buf: buffer
- * @len: length of buffer
- */
-static ssize_t aim_attr_store(struct kobject *kobj,
-			      struct attribute *attr,
-			      const char *buf,
-			      size_t len)
-{
-	struct most_aim_attribute *aim_attr;
-	struct most_aim_obj *aim_obj;
-
-	aim_attr = to_aim_attr(attr);
-	aim_obj = to_aim_obj(kobj);
-
-	if (!aim_attr->store)
-		return -EIO;
-	return aim_attr->store(aim_obj, aim_attr, buf, len);
-}
-
-static const struct sysfs_ops most_aim_sysfs_ops = {
-	.show = aim_attr_show,
-	.store = aim_attr_store,
-};
-
-/**
- * most_aim_release - AIM release function
- * @kobj: pointer to AIM's kobject
- */
-static void most_aim_release(struct kobject *kobj)
-{
-	struct most_aim_obj *aim_obj = to_aim_obj(kobj);
-
-	kfree(aim_obj);
-}
-
-static ssize_t links_show(struct most_aim_obj *aim_obj,
-			  struct most_aim_attribute *attr,
+static ssize_t links_show(struct device *dev, struct device_attribute *attr,
 			  char *buf)
 {
 	struct most_c_obj *c;
 	struct most_inst_obj *i;
+	struct most_aim *aim = to_most_aim(dev);
 	int offs = 0;
 
 	list_for_each_entry(i, &instance_list, list) {
 		list_for_each_entry(c, &i->channel_list, list) {
-			if (c->aim0.ptr == aim_obj->driver ||
-			    c->aim1.ptr == aim_obj->driver) {
+			if (c->aim0.ptr == aim || c->aim1.ptr == aim) {
 				offs += snprintf(buf + offs, PAGE_SIZE - offs,
 						 "%s:%s\n",
-						 kobject_name(&i->kobj),
-						 kobject_name(&c->kobj));
+						 dev_name(&i->iface->dev),
+						 dev_name(&c->dev));
 			}
 		}
 	}
@@ -899,15 +623,14 @@ static int split_string(char *buf, char **a, char **b, char **c)
  *
  * This retrieves the pointer to a channel object.
  */
-static struct
-most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch)
+static struct most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch)
 {
 	struct most_c_obj *c, *tmp;
 	struct most_inst_obj *i, *i_tmp;
 	int found = 0;
 
 	list_for_each_entry_safe(i, i_tmp, &instance_list, list) {
-		if (!strcmp(kobject_name(&i->kobj), mdev)) {
+		if (!strcmp(dev_name(&i->iface->dev), mdev)) {
 			found++;
 			break;
 		}
@@ -916,7 +639,7 @@ most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch)
 		return ERR_PTR(-EIO);
 
 	list_for_each_entry_safe(c, tmp, &i->channel_list, list) {
-		if (!strcmp(kobject_name(&c->kobj), mdev_ch)) {
+		if (!strcmp(dev_name(&c->dev), mdev_ch)) {
 			found++;
 			break;
 		}
@@ -926,6 +649,30 @@ most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch)
 	return c;
 }
 
+static int link_channel_to_aim(struct most_c_obj *c, struct most_aim *aim,
+			       char *aim_param)
+{
+	int ret;
+	struct most_aim **aim_ptr;
+
+	if (!c->aim0.ptr)
+		aim_ptr = &c->aim0.ptr;
+	else if (!c->aim1.ptr)
+		aim_ptr = &c->aim1.ptr;
+	else
+		return -ENOSPC;
+
+	*aim_ptr = aim;
+	ret = aim->probe_channel(c->iface, c->channel_id,
+				 &c->cfg, aim_param);
+	if (ret) {
+		*aim_ptr = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
 /**
  * add_link_store - store() function for add_link attribute
  * @aim_obj: pointer to AIM object
@@ -948,13 +695,13 @@ most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch)
  * (1) would create the device node /dev/my_rxchannel
  * (2) would create the device node /dev/mdev1-ep81
  */
-static ssize_t add_link_store(struct most_aim_obj *aim_obj,
-			      struct most_aim_attribute *attr,
+static ssize_t add_link_store(struct device *dev,
+			      struct device_attribute *attr,
 			      const char *buf,
 			      size_t len)
 {
 	struct most_c_obj *c;
-	struct most_aim **aim_ptr;
+	struct most_aim *aim = to_most_aim(dev);
 	char buffer[STRING_SIZE];
 	char *mdev;
 	char *mdev_ch;
@@ -979,20 +726,9 @@ static ssize_t add_link_store(struct most_aim_obj *aim_obj,
 	if (IS_ERR(c))
 		return -ENODEV;
 
-	if (!c->aim0.ptr)
-		aim_ptr = &c->aim0.ptr;
-	else if (!c->aim1.ptr)
-		aim_ptr = &c->aim1.ptr;
-	else
-		return -ENOSPC;
-
-	*aim_ptr = aim_obj->driver;
-	ret = aim_obj->driver->probe_channel(c->iface, c->channel_id,
-					     &c->cfg, &c->kobj, mdev_devnod);
-	if (ret) {
-		*aim_ptr = NULL;
+	ret = link_channel_to_aim(c, aim, mdev_devnod);
+	if (ret)
 		return ret;
-	}
 
 	return len;
 }
@@ -1007,12 +743,13 @@ static ssize_t add_link_store(struct most_aim_obj *aim_obj,
  * Example:
  * echo "mdev0:ep81" >remove_link
  */
-static ssize_t remove_link_store(struct most_aim_obj *aim_obj,
-				 struct most_aim_attribute *attr,
+static ssize_t remove_link_store(struct device *dev,
+				 struct device_attribute *attr,
 				 const char *buf,
 				 size_t len)
 {
 	struct most_c_obj *c;
+	struct most_aim *aim = to_most_aim(dev);
 	char buffer[STRING_SIZE];
 	char *mdev;
 	char *mdev_ch;
@@ -1028,94 +765,38 @@ static ssize_t remove_link_store(struct most_aim_obj *aim_obj,
 	if (IS_ERR(c))
 		return -ENODEV;
 
-	if (aim_obj->driver->disconnect_channel(c->iface, c->channel_id))
+	if (aim->disconnect_channel(c->iface, c->channel_id))
 		return -EIO;
-	if (c->aim0.ptr == aim_obj->driver)
+	if (c->aim0.ptr == aim)
 		c->aim0.ptr = NULL;
-	if (c->aim1.ptr == aim_obj->driver)
+	if (c->aim1.ptr == aim)
 		c->aim1.ptr = NULL;
 	return len;
 }
 
-static struct most_aim_attribute most_aim_attrs[] = {
-	__ATTR_RO(links),
-	__ATTR_WO(add_link),
-	__ATTR_WO(remove_link),
-};
+static DEVICE_ATTR_RO(links);
+static DEVICE_ATTR_WO(add_link);
+static DEVICE_ATTR_WO(remove_link);
 
-static struct attribute *most_aim_def_attrs[] = {
-	&most_aim_attrs[0].attr,
-	&most_aim_attrs[1].attr,
-	&most_aim_attrs[2].attr,
+static struct attribute *aim_attrs[] = {
+	DEV_ATTR(links),
+	DEV_ATTR(add_link),
+	DEV_ATTR(remove_link),
 	NULL,
 };
 
-static struct kobj_type most_aim_ktype = {
-	.sysfs_ops = &most_aim_sysfs_ops,
-	.release = most_aim_release,
-	.default_attrs = most_aim_def_attrs,
+static struct attribute_group aim_attr_group = {
+	.attrs = aim_attrs,
 };
 
-static struct kset *most_aim_kset;
-
-/**
- * create_most_aim_obj - creates an AIM object
- * @name: name of the AIM
- *
- * This creates an AIM object assigns the proper kset and registers
- * it with sysfs.
- * Returns a pointer to the object or NULL if something went wrong.
- */
-static struct most_aim_obj *create_most_aim_obj(const char *name)
-{
-	struct most_aim_obj *most_aim;
-	int retval;
-
-	most_aim = kzalloc(sizeof(*most_aim), GFP_KERNEL);
-	if (!most_aim)
-		return NULL;
-	most_aim->kobj.kset = most_aim_kset;
-	retval = kobject_init_and_add(&most_aim->kobj, &most_aim_ktype,
-				      NULL, "%s", name);
-	if (retval) {
-		kobject_put(&most_aim->kobj);
-		return NULL;
-	}
-	kobject_uevent(&most_aim->kobj, KOBJ_ADD);
-	return most_aim;
-}
-
-/**
- * destroy_most_aim_obj - AIM release function
- * @p: pointer to AIM object
- *
- * This decrements the reference counter of the AIM object. If the
- * reference count turns zero, its release function will be called.
- */
-static void destroy_most_aim_obj(struct most_aim_obj *p)
-{
-	kobject_put(&p->kobj);
-}
-
+static const struct attribute_group *aim_attr_groups[] = {
+	&aim_attr_group,
+	NULL,
+};
 /*		     ___       ___
  *		     ___C O R E___
  */
 
-/**
- * Instantiation of the MOST bus
- */
-static struct bus_type most_bus = {
-	.name = "most",
-};
-
-/**
- * Instantiation of the core driver
- */
-static struct device_driver mostcore = {
-	.name = "mostcore",
-	.bus = &most_bus,
-};
-
 static inline void trash_mbo(struct mbo *mbo)
 {
 	unsigned long flags;
@@ -1334,37 +1015,10 @@ static void most_write_completion(struct mbo *mbo)
 		arm_mbo(mbo);
 }
 
-/**
- * get_channel_by_iface - get pointer to channel object
- * @iface: pointer to interface instance
- * @id: channel ID
- *
- * This retrieves a pointer to a channel of the given interface and channel ID.
- */
-static struct
-most_c_obj *get_channel_by_iface(struct most_interface *iface, int id)
-{
-	struct most_inst_obj *i;
-
-	if (unlikely(!iface)) {
-		pr_err("Bad interface\n");
-		return NULL;
-	}
-	if (unlikely((id < 0) || (id >= iface->num_channels))) {
-		pr_err("Channel index (%d) out of range\n", id);
-		return NULL;
-	}
-	i = iface->priv;
-	if (unlikely(!i)) {
-		pr_err("interface is not registered\n");
-		return NULL;
-	}
-	return i->channel[id];
-}
-
 int channel_has_mbo(struct most_interface *iface, int id, struct most_aim *aim)
 {
-	struct most_c_obj *c = get_channel_by_iface(iface, id);
+	struct most_inst_obj *inst = iface->priv;
+	struct most_c_obj *c = inst->channel[id];
 	unsigned long flags;
 	int empty;
 
@@ -1396,10 +1050,11 @@ struct mbo *most_get_mbo(struct most_interface *iface, int id,
 {
 	struct mbo *mbo;
 	struct most_c_obj *c;
+	struct most_inst_obj *inst = iface->priv;
 	unsigned long flags;
 	int *num_buffers_ptr;
 
-	c = get_channel_by_iface(iface, id);
+	c = inst->channel[id];
 	if (unlikely(!c))
 		return NULL;
 
@@ -1501,7 +1156,8 @@ int most_start_channel(struct most_interface *iface, int id,
 {
 	int num_buffer;
 	int ret;
-	struct most_c_obj *c = get_channel_by_iface(iface, id);
+	struct most_inst_obj *inst = iface->priv;
+	struct most_c_obj *c = inst->channel[id];
 
 	if (unlikely(!c))
 		return -EINVAL;
@@ -1569,13 +1225,15 @@ int most_start_channel(struct most_interface *iface, int id,
 int most_stop_channel(struct most_interface *iface, int id,
 		      struct most_aim *aim)
 {
+	struct most_inst_obj *inst;
 	struct most_c_obj *c;
 
 	if (unlikely((!iface) || (id >= iface->num_channels) || (id < 0))) {
 		pr_err("Bad interface or index out of range\n");
 		return -EINVAL;
 	}
-	c = get_channel_by_iface(iface, id);
+	inst = iface->priv;
+	c = inst->channel[id];
 	if (unlikely(!c))
 		return -EINVAL;
 
@@ -1621,28 +1279,34 @@ int most_stop_channel(struct most_interface *iface, int id,
 }
 EXPORT_SYMBOL_GPL(most_stop_channel);
 
+void release_aim(struct device *dev)
+{
+	pr_info("releasing aim %s\n", dev_name(dev));
+}
+
 /**
  * most_register_aim - registers an AIM (driver) with the core
  * @aim: instance of AIM to be registered
  */
 int most_register_aim(struct most_aim *aim)
 {
-	struct most_aim_obj *aim_obj;
+	int ret;
 
 	if (!aim) {
 		pr_err("Bad driver\n");
 		return -EINVAL;
 	}
-	aim_obj = create_most_aim_obj(aim->name);
-	if (!aim_obj) {
-		pr_info("failed to alloc driver object\n");
-		return -ENOMEM;
+	aim->dev.init_name = aim->name;
+	aim->dev.bus = &most_bus_type;
+	aim->dev.parent = &core_dev;
+	aim->dev.groups = aim_attr_groups;
+	aim->dev.release = release_aim;
+	ret = device_register(&aim->dev);
+	if (ret) {
+		pr_err("registering device %s failed\n", aim->name);
+		return ret;
 	}
-	aim_obj->driver = aim;
-	aim->context = aim_obj;
-	pr_info("registered new application interfacing module %s\n",
-		aim->name);
-	list_add_tail(&aim_obj->list, &aim_list);
+	pr_info("registered new application interfacing module %s\n", aim->name);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(most_register_aim);
@@ -1653,7 +1317,6 @@ int most_register_aim(struct most_aim *aim)
  */
 int most_deregister_aim(struct most_aim *aim)
 {
-	struct most_aim_obj *aim_obj;
 	struct most_c_obj *c, *tmp;
 	struct most_inst_obj *i, *i_tmp;
 
@@ -1662,11 +1325,6 @@ int most_deregister_aim(struct most_aim *aim)
 		return -EINVAL;
 	}
 
-	aim_obj = aim->context;
-	if (!aim_obj) {
-		pr_info("driver not registered.\n");
-		return -EINVAL;
-	}
 	list_for_each_entry_safe(i, i_tmp, &instance_list, list) {
 		list_for_each_entry_safe(c, tmp, &i->channel_list, list) {
 			if (c->aim0.ptr == aim || c->aim1.ptr == aim)
@@ -1678,13 +1336,22 @@ int most_deregister_aim(struct most_aim *aim)
 				c->aim1.ptr = NULL;
 		}
 	}
-	list_del(&aim_obj->list);
-	destroy_most_aim_obj(aim_obj);
+	device_unregister(&aim->dev);
 	pr_info("deregistering application interfacing module %s\n", aim->name);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(most_deregister_aim);
 
+static void release_interface(struct device *dev)
+{
+	pr_info("releasing interface dev %s...\n", dev_name(dev));
+}
+
+static void release_channel(struct device *dev)
+{
+	pr_info("releasing channel dev %s...\n", dev_name(dev));
+}
+
 /**
  * most_register_interface - registers an interface with core
  * @iface: pointer to the instance of the interface description.
@@ -1692,7 +1359,7 @@ int most_deregister_aim(struct most_aim *aim)
  * Allocates and initializes a new interface instance and all of its channels.
  * Returns a pointer to kobject or an error pointer.
  */
-struct kobject *most_register_interface(struct most_interface *iface)
+int most_register_interface(struct most_interface *iface)
 {
 	unsigned int i;
 	int id;
@@ -1704,21 +1371,20 @@ struct kobject *most_register_interface(struct most_interface *iface)
 	if (!iface || !iface->enqueue || !iface->configure ||
 	    !iface->poison_channel || (iface->num_channels > MAX_CHANNELS)) {
 		pr_err("Bad interface or channel overflow\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	id = ida_simple_get(&mdev_id, 0, 0, GFP_KERNEL);
 	if (id < 0) {
 		pr_info("Failed to alloc mdev ID\n");
-		return ERR_PTR(id);
+		return id;
 	}
-	snprintf(name, STRING_SIZE, "mdev%d", id);
 
-	inst = create_most_inst_obj(name);
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst) {
 		pr_info("Failed to allocate interface instance\n");
 		ida_simple_remove(&mdev_id, id);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	iface->priv = inst;
@@ -1726,6 +1392,18 @@ struct kobject *most_register_interface(struct most_interface *iface)
 	inst->iface = iface;
 	inst->dev_id = id;
 	list_add_tail(&inst->list, &instance_list);
+	snprintf(name, STRING_SIZE, "mdev%d", id);
+	iface->dev.init_name = name;
+	iface->dev.bus = &most_bus_type;
+	iface->dev.parent = &core_dev;
+	iface->dev.groups = interface_attr_groups;
+	iface->dev.release = release_interface;
+	if (device_register(&iface->dev)) {
+		pr_err("registering iface->dev failed\n");
+		kfree(inst);
+		ida_simple_remove(&mdev_id, id);
+		return -ENOMEM;
+	}
 
 	for (i = 0; i < iface->num_channels; i++) {
 		const char *name_suffix = iface->channel_vector[i].name_suffix;
@@ -1736,9 +1414,18 @@ struct kobject *most_register_interface(struct most_interface *iface)
 			snprintf(channel_name, STRING_SIZE, "%s", name_suffix);
 
 		/* this increments the reference count of this instance */
-		c = create_most_c_obj(channel_name, &inst->kobj);
+		c = kzalloc(sizeof(*c), GFP_KERNEL);
 		if (!c)
 			goto free_instance;
+		//snprintf(c->dev.init_name, STRING_SIZE, channel_name);
+		c->dev.init_name = channel_name;
+		c->dev.parent = &iface->dev;
+		c->dev.groups = channel_attr_groups;
+		c->dev.release = release_channel;
+		if (device_register(&c->dev)) {
+			pr_err("registering c->dev failed\n");
+			goto free_instance;
+		}
 		inst->channel[i] = c;
 		c->is_starving = 0;
 		c->iface = iface;
@@ -1764,15 +1451,14 @@ struct kobject *most_register_interface(struct most_interface *iface)
 		list_add_tail(&c->list, &inst->channel_list);
 	}
 	pr_info("registered new MOST device mdev%d (%s)\n",
-		inst->dev_id, iface->description);
-	return &inst->kobj;
+		id, iface->description);
+	return 0;
 
 free_instance:
 	pr_info("Failed allocate channel(s)\n");
-	list_del(&inst->list);
+	device_unregister(&iface->dev);
 	ida_simple_remove(&mdev_id, id);
-	destroy_most_inst_obj(inst);
-	return ERR_PTR(-ENOMEM);
+	return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(most_register_interface);
 
@@ -1785,17 +1471,14 @@ struct kobject *most_register_interface(struct most_interface *iface)
  */
 void most_deregister_interface(struct most_interface *iface)
 {
-	struct most_inst_obj *i = iface->priv;
+	int i;
 	struct most_c_obj *c;
+	struct most_inst_obj *inst;
 
-	if (unlikely(!i)) {
-		pr_info("Bad Interface\n");
-		return;
-	}
-	pr_info("deregistering MOST device %s (%s)\n", i->kobj.name,
-		iface->description);
-
-	list_for_each_entry(c, &i->channel_list, list) {
+	pr_info("deregistering MOST device %s (%s)\n", dev_name(&iface->dev), iface->description);
+	inst = iface->priv;
+	for (i = 0; i < iface->num_channels; i++) {
+		c = inst->channel[i];
 		if (c->aim0.ptr)
 			c->aim0.ptr->disconnect_channel(c->iface,
 							c->channel_id);
@@ -1804,11 +1487,14 @@ void most_deregister_interface(struct most_interface *iface)
 							c->channel_id);
 		c->aim0.ptr = NULL;
 		c->aim1.ptr = NULL;
+		list_del(&c->list);
+		device_unregister(&c->dev);
+		kfree(c);
 	}
 
-	ida_simple_remove(&mdev_id, i->dev_id);
-	list_del(&i->list);
-	destroy_most_inst_obj(i);
+	ida_simple_remove(&mdev_id, inst->dev_id);
+	kfree(inst);
+	device_unregister(&iface->dev);
 }
 EXPORT_SYMBOL_GPL(most_deregister_interface);
 
@@ -1824,7 +1510,8 @@ void most_deregister_interface(struct most_interface *iface)
  */
 void most_stop_enqueue(struct most_interface *iface, int id)
 {
-	struct most_c_obj *c = get_channel_by_iface(iface, id);
+	struct most_inst_obj *inst = iface->priv;
+	struct most_c_obj *c = inst->channel[id];
 
 	if (!c)
 		return;
@@ -1845,7 +1532,8 @@ void most_stop_enqueue(struct most_interface *iface, int id)
  */
 void most_resume_enqueue(struct most_interface *iface, int id)
 {
-	struct most_c_obj *c = get_channel_by_iface(iface, id);
+	struct most_inst_obj *inst = iface->priv;
+	struct most_c_obj *c = inst->channel[id];
 
 	if (!c)
 		return;
@@ -1858,6 +1546,11 @@ void most_resume_enqueue(struct most_interface *iface, int id)
 }
 EXPORT_SYMBOL_GPL(most_resume_enqueue);
 
+static void release_most_sub(struct device *dev)
+{
+	pr_info("releasing most_subsystem\n");
+}
+
 static int __init most_init(void)
 {
 	int err;
@@ -1867,12 +1560,11 @@ static int __init most_init(void)
 	INIT_LIST_HEAD(&aim_list);
 	ida_init(&mdev_id);
 
-	err = bus_register(&most_bus);
+	err = bus_register(&most_bus_type);
 	if (err) {
 		pr_info("Cannot register most bus\n");
 		return err;
 	}
-
 	most_class = class_create(THIS_MODULE, "most");
 	if (IS_ERR(most_class)) {
 		pr_info("No udev support.\n");
@@ -1885,60 +1577,30 @@ static int __init most_init(void)
 		pr_info("Cannot register core driver\n");
 		goto exit_class;
 	}
-
-	core_dev = device_create(most_class, NULL, 0, NULL, "mostcore");
-	if (IS_ERR(core_dev)) {
-		err = PTR_ERR(core_dev);
-		goto exit_driver;
-	}
-
-	most_aim_kset = kset_create_and_add("aims", NULL, &core_dev->kobj);
-	if (!most_aim_kset) {
+	core_dev.init_name = "most_bus";
+	core_dev.release = release_most_sub;
+	if (device_register(&core_dev)) {
 		err = -ENOMEM;
-		goto exit_class_container;
-	}
-
-	most_inst_kset = kset_create_and_add("devices", NULL, &core_dev->kobj);
-	if (!most_inst_kset) {
-		err = -ENOMEM;
-		goto exit_driver_kset;
+		goto exit_driver;
 	}
-
 	return 0;
 
-exit_driver_kset:
-	kset_unregister(most_aim_kset);
-exit_class_container:
-	device_destroy(most_class, 0);
 exit_driver:
 	driver_unregister(&mostcore);
 exit_class:
 	class_destroy(most_class);
 exit_bus:
-	bus_unregister(&most_bus);
+	bus_unregister(&most_bus_type);
 	return err;
 }
 
 static void __exit most_exit(void)
 {
-	struct most_inst_obj *i, *i_tmp;
-	struct most_aim_obj *d, *d_tmp;
-
 	pr_info("exit core module\n");
-	list_for_each_entry_safe(d, d_tmp, &aim_list, list) {
-		destroy_most_aim_obj(d);
-	}
-
-	list_for_each_entry_safe(i, i_tmp, &instance_list, list) {
-		list_del(&i->list);
-		destroy_most_inst_obj(i);
-	}
-	kset_unregister(most_inst_kset);
-	kset_unregister(most_aim_kset);
-	device_destroy(most_class, 0);
+	device_unregister(&core_dev);
 	driver_unregister(&mostcore);
 	class_destroy(most_class);
-	bus_unregister(&most_bus);
+	bus_unregister(&most_bus_type);
 	ida_destroy(&mdev_id);
 }
 
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h
index a6e618c..588aadb 100644
--- a/drivers/staging/most/core.h
+++ b/drivers/staging/most/core.h
@@ -238,6 +238,7 @@ struct mbo {
  * @priv Private field used by mostcore to store context information.
  */
 struct most_interface {
+	struct device dev;
 	struct module *mod;
 	enum most_interface_type interface;
 	const char *description;
@@ -255,6 +256,7 @@ struct most_interface {
 	void *priv;
 };
 
+#define to_most_interface(d) container_of(d, struct most_interface, dev)
 /**
  * struct most_aim - identifies MOST device driver to mostcore
  * @name: Driver name
@@ -265,10 +267,10 @@ struct most_interface {
  * @context: context pointer to be used by mostcore
  */
 struct most_aim {
+	struct device dev;
 	const char *name;
 	int (*probe_channel)(struct most_interface *iface, int channel_idx,
-			     struct most_channel_config *cfg,
-			     struct kobject *parent, char *name);
+			     struct most_channel_config *cfg, char *name);
 	int (*disconnect_channel)(struct most_interface *iface,
 				  int channel_idx);
 	int (*rx_completion)(struct mbo *mbo);
@@ -276,6 +278,7 @@ struct most_aim {
 	void *context;
 };
 
+#define to_most_aim(d) container_of(d, struct most_aim, dev)
 /**
  * most_register_interface - Registers instance of the interface.
  * @iface: Pointer to the interface instance description.
@@ -285,7 +288,7 @@ struct most_aim {
  * Note: HDM has to ensure that any reference held on the kobj is
  * released before deregistering the interface.
  */
-struct kobject *most_register_interface(struct most_interface *iface);
+int most_register_interface(struct most_interface *iface);
 
 /**
  * Deregisters instance of the interface.
diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c
index cc8563f..309ef13 100644
--- a/drivers/staging/most/dim2/dim2.c
+++ b/drivers/staging/most/dim2/dim2.c
@@ -93,6 +93,7 @@ struct hdm_channel {
  * @atx_idx: index of async tx channel
  */
 struct dim2_hdm {
+	struct device dev;
 	struct hdm_channel hch[DMA_CHANNELS];
 	struct most_channel_capability capabilities[DMA_CHANNELS];
 	struct most_interface most_iface;
@@ -744,7 +745,6 @@ static int dim2_probe(struct platform_device *pdev)
 	struct dim2_hdm *dev;
 	struct resource *res;
 	int ret, i;
-	struct kobject *kobj;
 	int irq;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -832,18 +832,20 @@ static int dim2_probe(struct platform_device *pdev)
 	dev->most_iface.enqueue = enqueue;
 	dev->most_iface.poison_channel = poison_channel;
 	dev->most_iface.request_netinfo = request_netinfo;
+	dev->dev.init_name = "dim2_state";
+	dev->dev.parent = &dev->most_iface.dev;
 
-	kobj = most_register_interface(&dev->most_iface);
-	if (IS_ERR(kobj)) {
-		ret = PTR_ERR(kobj);
+	ret = most_register_interface(&dev->most_iface);
+	if (ret) {
 		dev_err(&pdev->dev, "failed to register MOST interface\n");
 		goto err_stop_thread;
 	}
 
-	ret = dim2_sysfs_probe(&dev->bus, kobj);
-	if (ret)
+	ret = dim2_sysfs_probe(&dev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to create sysfs attribute\n");
 		goto err_unreg_iface;
-
+	}
 	ret = startup_dim(pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to initialize DIM2\n");
@@ -853,7 +855,7 @@ static int dim2_probe(struct platform_device *pdev)
 	return 0;
 
 err_destroy_bus:
-	dim2_sysfs_destroy(&dev->bus);
+	dim2_sysfs_destroy(&dev->dev);
 err_unreg_iface:
 	most_deregister_interface(&dev->most_iface);
 err_stop_thread:
@@ -881,7 +883,7 @@ static int dim2_remove(struct platform_device *pdev)
 	if (pdata && pdata->destroy)
 		pdata->destroy(pdata);
 
-	dim2_sysfs_destroy(&dev->bus);
+	dim2_sysfs_destroy(&dev->dev);
 	most_deregister_interface(&dev->most_iface);
 	kthread_stop(dev->netinfo_task);
 
diff --git a/drivers/staging/most/dim2/sysfs.c b/drivers/staging/most/dim2/sysfs.c
index 1331cf0..5ab0c02 100644
--- a/drivers/staging/most/dim2/sysfs.c
+++ b/drivers/staging/most/dim2/sysfs.c
@@ -17,99 +17,39 @@
 
 #include <linux/kernel.h>
 #include "sysfs.h"
+#include <linux/device.h>
 
-struct bus_attr {
-	struct attribute attr;
-	ssize_t (*show)(struct medialb_bus *bus, char *buf);
-	ssize_t (*store)(struct medialb_bus *bus, const char *buf,
-			 size_t count);
-};
-
-static ssize_t state_show(struct medialb_bus *bus, char *buf)
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
 {
 	bool state = dim2_sysfs_get_state_cb();
 
 	return sprintf(buf, "%s\n", state ? "locked" : "");
 }
 
-static struct bus_attr state_attr = __ATTR_RO(state);
+DEVICE_ATTR_RO(state);
 
-static struct attribute *bus_default_attrs[] = {
-	&state_attr.attr,
+static struct attribute *dev_attrs[] = {
+	&dev_attr_state.attr,
 	NULL,
 };
 
-static const struct attribute_group bus_attr_group = {
-	.attrs = bus_default_attrs,
+static struct attribute_group dev_attr_group = {
+	.attrs = dev_attrs,
 };
 
-static void bus_kobj_release(struct kobject *kobj)
-{
-}
-
-static ssize_t bus_kobj_attr_show(struct kobject *kobj, struct attribute *attr,
-				  char *buf)
-{
-	struct medialb_bus *bus =
-		container_of(kobj, struct medialb_bus, kobj_group);
-	struct bus_attr *xattr = container_of(attr, struct bus_attr, attr);
-
-	if (!xattr->show)
-		return -EIO;
-
-	return xattr->show(bus, buf);
-}
-
-static ssize_t bus_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
-				   const char *buf, size_t count)
-{
-	struct medialb_bus *bus =
-		container_of(kobj, struct medialb_bus, kobj_group);
-	struct bus_attr *xattr = container_of(attr, struct bus_attr, attr);
-
-	if (!xattr->store)
-		return -EIO;
-
-	return xattr->store(bus, buf, count);
-}
-
-static struct sysfs_ops const bus_kobj_sysfs_ops = {
-	.show = bus_kobj_attr_show,
-	.store = bus_kobj_attr_store,
-};
-
-static struct kobj_type bus_ktype = {
-	.release = bus_kobj_release,
-	.sysfs_ops = &bus_kobj_sysfs_ops,
+static const struct attribute_group *dev_attr_groups[] = {
+	&dev_attr_group,
+	NULL,
 };
 
-int dim2_sysfs_probe(struct medialb_bus *bus, struct kobject *parent_kobj)
+int dim2_sysfs_probe(struct device *dev)
 {
-	int err;
-
-	kobject_init(&bus->kobj_group, &bus_ktype);
-	err = kobject_add(&bus->kobj_group, parent_kobj, "bus");
-	if (err) {
-		pr_err("kobject_add() failed: %d\n", err);
-		goto err_kobject_add;
-	}
-
-	err = sysfs_create_group(&bus->kobj_group, &bus_attr_group);
-	if (err) {
-		pr_err("sysfs_create_group() failed: %d\n", err);
-		goto err_create_group;
-	}
-
-	return 0;
-
-err_create_group:
-	kobject_put(&bus->kobj_group);
-
-err_kobject_add:
-	return err;
+	dev->groups = dev_attr_groups;
+	return device_register(dev);
 }
 
-void dim2_sysfs_destroy(struct medialb_bus *bus)
+void dim2_sysfs_destroy(struct device *dev)
 {
-	kobject_put(&bus->kobj_group);
+	device_unregister(dev);
 }
diff --git a/drivers/staging/most/dim2/sysfs.h b/drivers/staging/most/dim2/sysfs.h
index 236de47..070a70c 100644
--- a/drivers/staging/most/dim2/sysfs.h
+++ b/drivers/staging/most/dim2/sysfs.h
@@ -22,10 +22,10 @@ struct medialb_bus {
 	struct kobject kobj_group;
 };
 
-struct dim2_hdm;
+struct device;
 
-int dim2_sysfs_probe(struct medialb_bus *bus, struct kobject *parent_kobj);
-void dim2_sysfs_destroy(struct medialb_bus *bus);
+int dim2_sysfs_probe(struct device *dev);
+void dim2_sysfs_destroy(struct device *dev);
 
 /*
  * callback,
diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c
index 0a3e858..587ac86 100644
--- a/drivers/staging/most/i2c/i2c.c
+++ b/drivers/staging/most/i2c/i2c.c
@@ -309,7 +309,6 @@ static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct hdm_i2c *dev;
 	int ret, i;
-	struct kobject *kobj;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -347,11 +346,11 @@ static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	dev->client = client;
 	i2c_set_clientdata(client, dev);
 
-	kobj = most_register_interface(&dev->most_iface);
-	if (IS_ERR(kobj)) {
+	ret = most_register_interface(&dev->most_iface);
+	if (ret) {
 		pr_err("Failed to register i2c as a MOST interface\n");
 		kfree(dev);
-		return PTR_ERR(kobj);
+		return ret;
 	}
 
 	dev->polling_mode = polling_req || client->irq <= 0;
diff --git a/drivers/staging/most/net/net.c b/drivers/staging/most/net/net.c
index d43aad3..194fe63 100644
--- a/drivers/staging/most/net/net.c
+++ b/drivers/staging/most/net/net.c
@@ -298,7 +298,7 @@ static struct net_dev_context *get_net_dev_hold(struct most_interface *iface)
 
 static int aim_probe_channel(struct most_interface *iface, int channel_idx,
 			     struct most_channel_config *ccfg,
-			     struct kobject *parent, char *name)
+			     char *name)
 {
 	struct net_dev_context *nd;
 	struct net_dev_channel *ch;
@@ -502,7 +502,7 @@ static int aim_rx_data(struct mbo *mbo)
 }
 
 static struct most_aim aim = {
-	.name = "networking",
+	.name = "aim_networking",
 	.probe_channel = aim_probe_channel,
 	.disconnect_channel = aim_disconnect_channel,
 	.tx_completion = aim_resume_tx_channel,
diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c
index 72603ae..4c3397a 100644
--- a/drivers/staging/most/sound/sound.c
+++ b/drivers/staging/most/sound/sound.c
@@ -24,7 +24,7 @@
 #include <linux/kthread.h>
 #include <most/core.h>
 
-#define DRIVER_NAME "sound"
+#define DRIVER_NAME "aim_sound"
 
 static struct list_head dev_list;
 static struct most_aim audio_aim;
@@ -545,7 +545,6 @@ static int audio_set_hw_params(struct snd_pcm_hardware *pcm_hw,
  * @iface: pointer to interface instance
  * @channel_id: channel index/ID
  * @cfg: pointer to actual channel configuration
- * @parent: pointer to kobject (needed for sysfs hook-up)
  * @arg_list: string that provides the name of the device to be created in /dev
  *	      plus the desired audio resolution
  *
@@ -555,7 +554,7 @@ static int audio_set_hw_params(struct snd_pcm_hardware *pcm_hw,
  */
 static int audio_probe_channel(struct most_interface *iface, int channel_id,
 			       struct most_channel_config *cfg,
-			       struct kobject *parent, char *arg_list)
+			       char *arg_list)
 {
 	struct channel *channel;
 	struct snd_card *card;
diff --git a/drivers/staging/most/usb/usb.c b/drivers/staging/most/usb/usb.c
index 2e4f237..9e2a270 100644
--- a/drivers/staging/most/usb/usb.c
+++ b/drivers/staging/most/usb/usb.c
@@ -70,12 +70,12 @@
  * @reg_addr: register address for arbitrary DCI access
  */
 struct most_dci_obj {
-	struct kobject kobj;
+	struct device dev;
 	struct usb_device *usb_device;
 	u16 reg_addr;
 };
 
-#define to_dci_obj(p) container_of(p, struct most_dci_obj, kobj)
+#define to_dci_obj(p) container_of(p, struct most_dci_obj, dev)
 
 struct most_dev;
 
@@ -90,7 +90,6 @@ struct clear_hold_work {
 
 /**
  * struct most_dev - holds all usb interface specific stuff
- * @parent: parent object in sysfs
  * @usb_device: pointer to usb device
  * @iface: hardware interface
  * @cap: channel capabilities
@@ -108,7 +107,6 @@ struct clear_hold_work {
  * @poll_work_obj: work for polling link status
  */
 struct most_dev {
-	struct kobject *parent;
 	struct usb_device *usb_device;
 	struct most_interface iface;
 	struct most_channel_capability *cap;
@@ -840,94 +838,6 @@ static void wq_clear_halt(struct work_struct *wq_obj)
 	{ } /* Terminating entry */
 };
 
-#define MOST_DCI_RO_ATTR(_name) \
-	struct most_dci_attribute most_dci_attr_##_name = \
-		__ATTR(_name, 0444, show_value, NULL)
-
-#define MOST_DCI_ATTR(_name) \
-	struct most_dci_attribute most_dci_attr_##_name = \
-		__ATTR(_name, 0644, show_value, store_value)
-
-#define MOST_DCI_WO_ATTR(_name) \
-	struct most_dci_attribute most_dci_attr_##_name = \
-		__ATTR(_name, 0200, NULL, store_value)
-
-/**
- * struct most_dci_attribute - to access the attributes of a dci object
- * @attr: attributes of a dci object
- * @show: pointer to the show function
- * @store: pointer to the store function
- */
-struct most_dci_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct most_dci_obj *d,
-			struct most_dci_attribute *attr,
-			char *buf);
-	ssize_t (*store)(struct most_dci_obj *d,
-			 struct most_dci_attribute *attr,
-			 const char *buf,
-			 size_t count);
-};
-
-#define to_dci_attr(a) container_of(a, struct most_dci_attribute, attr)
-
-/**
- * dci_attr_show - show function for dci object
- * @kobj: pointer to kobject
- * @attr: pointer to attribute struct
- * @buf: buffer
- */
-static ssize_t dci_attr_show(struct kobject *kobj, struct attribute *attr,
-			     char *buf)
-{
-	struct most_dci_attribute *dci_attr = to_dci_attr(attr);
-	struct most_dci_obj *dci_obj = to_dci_obj(kobj);
-
-	if (!dci_attr->show)
-		return -EIO;
-
-	return dci_attr->show(dci_obj, dci_attr, buf);
-}
-
-/**
- * dci_attr_store - store function for dci object
- * @kobj: pointer to kobject
- * @attr: pointer to attribute struct
- * @buf: buffer
- * @len: length of buffer
- */
-static ssize_t dci_attr_store(struct kobject *kobj,
-			      struct attribute *attr,
-			      const char *buf,
-			      size_t len)
-{
-	struct most_dci_attribute *dci_attr = to_dci_attr(attr);
-	struct most_dci_obj *dci_obj = to_dci_obj(kobj);
-
-	if (!dci_attr->store)
-		return -EIO;
-
-	return dci_attr->store(dci_obj, dci_attr, buf, len);
-}
-
-static const struct sysfs_ops most_dci_sysfs_ops = {
-	.show = dci_attr_show,
-	.store = dci_attr_store,
-};
-
-/**
- * most_dci_release - release function for dci object
- * @kobj: pointer to kobject
- *
- * This frees the memory allocated for the dci object
- */
-static void most_dci_release(struct kobject *kobj)
-{
-	struct most_dci_obj *dci_obj = to_dci_obj(kobj);
-
-	kfree(dci_obj);
-}
-
 struct regs {
 	const char *name;
 	u16 reg;
@@ -968,10 +878,11 @@ static int get_stat_reg_addr(const struct regs *regs, int size,
 #define get_static_reg_addr(regs, name, reg_addr) \
 	get_stat_reg_addr(regs, ARRAY_SIZE(regs), name, reg_addr)
 
-static ssize_t show_value(struct most_dci_obj *dci_obj,
-			  struct most_dci_attribute *attr, char *buf)
+static ssize_t value_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
 {
 	const char *name = attr->attr.name;
+	struct most_dci_obj *dci_obj = to_dci_obj(dev);
 	u16 val;
 	u16 reg_addr;
 	int err;
@@ -992,13 +903,13 @@ static ssize_t show_value(struct most_dci_obj *dci_obj,
 	return snprintf(buf, PAGE_SIZE, "%04x\n", val);
 }
 
-static ssize_t store_value(struct most_dci_obj *dci_obj,
-			   struct most_dci_attribute *attr,
+static ssize_t value_store(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
 	u16 val;
 	u16 reg_addr;
 	const char *name = attr->attr.name;
+	struct most_dci_obj *dci_obj = to_dci_obj(dev);
 	struct usb_device *usb_dev = dci_obj->usb_device;
 	int err = kstrtou16(buf, 16, &val);
 
@@ -1025,86 +936,49 @@ static ssize_t store_value(struct most_dci_obj *dci_obj,
 	return count;
 }
 
-static MOST_DCI_RO_ATTR(ni_state);
-static MOST_DCI_RO_ATTR(packet_bandwidth);
-static MOST_DCI_RO_ATTR(node_address);
-static MOST_DCI_RO_ATTR(node_position);
-static MOST_DCI_WO_ATTR(sync_ep);
-static MOST_DCI_ATTR(mep_filter);
-static MOST_DCI_ATTR(mep_hash0);
-static MOST_DCI_ATTR(mep_hash1);
-static MOST_DCI_ATTR(mep_hash2);
-static MOST_DCI_ATTR(mep_hash3);
-static MOST_DCI_ATTR(mep_eui48_hi);
-static MOST_DCI_ATTR(mep_eui48_mi);
-static MOST_DCI_ATTR(mep_eui48_lo);
-static MOST_DCI_ATTR(arb_address);
-static MOST_DCI_ATTR(arb_value);
-
-/**
- * most_dci_def_attrs - array of default attribute files of the dci object
- */
-static struct attribute *most_dci_def_attrs[] = {
-	&most_dci_attr_ni_state.attr,
-	&most_dci_attr_packet_bandwidth.attr,
-	&most_dci_attr_node_address.attr,
-	&most_dci_attr_node_position.attr,
-	&most_dci_attr_sync_ep.attr,
-	&most_dci_attr_mep_filter.attr,
-	&most_dci_attr_mep_hash0.attr,
-	&most_dci_attr_mep_hash1.attr,
-	&most_dci_attr_mep_hash2.attr,
-	&most_dci_attr_mep_hash3.attr,
-	&most_dci_attr_mep_eui48_hi.attr,
-	&most_dci_attr_mep_eui48_mi.attr,
-	&most_dci_attr_mep_eui48_lo.attr,
-	&most_dci_attr_arb_address.attr,
-	&most_dci_attr_arb_value.attr,
+DEVICE_ATTR(ni_state, 0444, value_show, NULL);
+DEVICE_ATTR(packet_bandwidth, 0444, value_show, NULL);
+DEVICE_ATTR(node_address, 0444, value_show, NULL);
+DEVICE_ATTR(node_position, 0444, value_show, NULL);
+DEVICE_ATTR(sync_ep, 0200, NULL, value_store);
+DEVICE_ATTR(mep_filter, 0644, value_show, value_store);
+DEVICE_ATTR(mep_hash0, 0644, value_show, value_store);
+DEVICE_ATTR(mep_hash1, 0644, value_show, value_store);
+DEVICE_ATTR(mep_hash2, 0644, value_show, value_store);
+DEVICE_ATTR(mep_hash3, 0644, value_show, value_store);
+DEVICE_ATTR(mep_eui48_hi, 0644, value_show, value_store);
+DEVICE_ATTR(mep_eui48_mi, 0644, value_show, value_store);
+DEVICE_ATTR(mep_eui48_lo, 0644, value_show, value_store);
+DEVICE_ATTR(arb_address, 0644, value_show, value_store);
+DEVICE_ATTR(arb_value, 0644, value_show, value_store);
+
+static struct attribute *dci_attrs[] = {
+	&dev_attr_ni_state.attr,
+	&dev_attr_packet_bandwidth.attr,
+	&dev_attr_node_address.attr,
+	&dev_attr_node_position.attr,
+	&dev_attr_sync_ep.attr,
+	&dev_attr_mep_filter.attr,
+	&dev_attr_mep_hash0.attr,
+	&dev_attr_mep_hash1.attr,
+	&dev_attr_mep_hash2.attr,
+	&dev_attr_mep_hash3.attr,
+	&dev_attr_mep_eui48_hi.attr,
+	&dev_attr_mep_eui48_mi.attr,
+	&dev_attr_mep_eui48_lo.attr,
+	&dev_attr_arb_address.attr,
+	&dev_attr_arb_value.attr,
 	NULL,
 };
 
-/**
- * DCI ktype
- */
-static struct kobj_type most_dci_ktype = {
-	.sysfs_ops = &most_dci_sysfs_ops,
-	.release = most_dci_release,
-	.default_attrs = most_dci_def_attrs,
+static struct attribute_group dci_attr_group = {
+	.attrs = dci_attrs,
 };
 
-/**
- * create_most_dci_obj - allocates a dci object
- * @parent: parent kobject
- *
- * This creates a dci object and registers it with sysfs.
- * Returns a pointer to the object or NULL when something went wrong.
- */
-static struct
-most_dci_obj *create_most_dci_obj(struct kobject *parent)
-{
-	struct most_dci_obj *most_dci = kzalloc(sizeof(*most_dci), GFP_KERNEL);
-	int retval;
-
-	if (!most_dci)
-		return NULL;
-
-	retval = kobject_init_and_add(&most_dci->kobj, &most_dci_ktype, parent,
-				      "dci");
-	if (retval) {
-		kobject_put(&most_dci->kobj);
-		return NULL;
-	}
-	return most_dci;
-}
-
-/**
- * destroy_most_dci_obj - DCI object release function
- * @p: pointer to dci object
- */
-static void destroy_most_dci_obj(struct most_dci_obj *p)
-{
-	kobject_put(&p->kobj);
-}
+static const struct attribute_group *dci_attr_groups[] = {
+	&dci_attr_group,
+	NULL,
+};
 
 /**
  * hdm_probe - probe function of USB device driver
@@ -1218,33 +1092,36 @@ static void destroy_most_dci_obj(struct most_dci_obj *p)
 		   usb_dev->config->desc.bConfigurationValue,
 		   usb_iface_desc->desc.bInterfaceNumber);
 
-	mdev->parent = most_register_interface(&mdev->iface);
-	if (IS_ERR(mdev->parent)) {
-		ret = PTR_ERR(mdev->parent);
+	ret = most_register_interface(&mdev->iface);
+	if (ret)
 		goto exit_free4;
-	}
 
 	mutex_lock(&mdev->io_mutex);
 	if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
 	    le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 ||
 	    le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) {
-		/* this increments the reference count of the instance
-		 * object of the core
-		 */
-		mdev->dci = create_most_dci_obj(mdev->parent);
+		mdev->dci = kzalloc(sizeof(*mdev->dci), GFP_KERNEL);
 		if (!mdev->dci) {
 			mutex_unlock(&mdev->io_mutex);
 			most_deregister_interface(&mdev->iface);
 			ret = -ENOMEM;
 			goto exit_free4;
 		}
-
-		kobject_uevent(&mdev->dci->kobj, KOBJ_ADD);
+		mdev->dci->dev.init_name = "dci";
+		mdev->dci->dev.parent = &mdev->iface.dev;
+		mdev->dci->dev.groups = dci_attr_groups;
+		if (device_register(&mdev->dci->dev)) {
+			mutex_unlock(&mdev->io_mutex);
+			most_deregister_interface(&mdev->iface);
+			ret = -ENOMEM;
+			goto exit_free5;
+		}
 		mdev->dci->usb_device = mdev->usb_device;
 	}
 	mutex_unlock(&mdev->io_mutex);
 	return 0;
-
+exit_free5:
+	kfree(mdev->dci);
 exit_free4:
 	kfree(mdev->busy_urbs);
 exit_free3:
@@ -1284,7 +1161,8 @@ static void hdm_disconnect(struct usb_interface *interface)
 	del_timer_sync(&mdev->link_stat_timer);
 	cancel_work_sync(&mdev->poll_work_obj);
 
-	destroy_most_dci_obj(mdev->dci);
+	device_unregister(&mdev->dci->dev);
+	kfree(mdev->dci);
 	most_deregister_interface(&mdev->iface);
 
 	kfree(mdev->busy_urbs);
diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c
index eed9046..5b704d9 100644
--- a/drivers/staging/most/video/video.c
+++ b/drivers/staging/most/video/video.c
@@ -487,7 +487,7 @@ static void aim_v4l2_dev_release(struct v4l2_device *v4l2_dev)
 
 static int aim_probe_channel(struct most_interface *iface, int channel_idx,
 			     struct most_channel_config *ccfg,
-			     struct kobject *parent, char *name)
+			     char *name)
 {
 	int ret;
 	struct most_video_dev *mdev = get_aim_dev(iface, channel_idx);
@@ -570,7 +570,7 @@ static int aim_disconnect_channel(struct most_interface *iface,
 }
 
 static struct most_aim aim_info = {
-	.name = "v4l",
+	.name = "aim_v4l",
 	.probe_channel = aim_probe_channel,
 	.disconnect_channel = aim_disconnect_channel,
 	.rx_completion = aim_rx_data,
-- 
1.9.1



More information about the devel mailing list