This patch removes the proprietary kobjects used by the driver modules and replaces them with device structs. The patch is needed to have the driver being integrated into the kernel's device model. Signed-off-by: Christian Gromm <christian.gromm@xxxxxxxxxxxxx> --- drivers/staging/most/cdev/cdev.c | 6 +- drivers/staging/most/core.c | 803 +++++++++++-------------------------- drivers/staging/most/core.h | 13 +- drivers/staging/most/dim2/dim2.c | 19 +- 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 | 3 +- drivers/staging/most/sound/sound.c | 3 +- drivers/staging/most/usb/usb.c | 243 +++-------- drivers/staging/most/video/video.c | 3 +- 11 files changed, 342 insertions(+), 856 deletions(-) diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index b6849c8..c6baa9c 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -418,7 +418,6 @@ static int aim_tx_completion(struct most_interface *iface, int channel_id) * @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) * @name: name of the device to be created * * This allocates achannel object and creates the device node in /dev @@ -426,15 +425,14 @@ static int aim_tx_completion(struct most_interface *iface, int channel_id) * Returns 0 on success or error code otherwise. */ static int aim_probe(struct most_interface *iface, int channel_id, - struct most_channel_config *cfg, - struct kobject *parent, char *name) + struct most_channel_config *cfg, 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; } diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 6ee6acf..8c9b10d 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,6 @@ static const struct { { MOST_CH_ISOC, "isoc_avp\n"}, }; -#define to_inst_obj(d) container_of(d, struct most_inst_obj, kobj) - /** * list_pop_mbo - retrieves the first MBO of the list and removes it * @ptr: the list head to grab the MBO from. @@ -109,68 +106,6 @@ static const struct { */ /** - * 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 * @mbo: buffer to be released * @@ -241,21 +176,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 +192,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 +212,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 +288,21 @@ 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 +310,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 +323,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 +345,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 +359,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 +381,21 @@ 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 +403,21 @@ 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 +425,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 +473,22 @@ create_most_c_obj(const char *name, struct kobject *parent) 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 +511,42 @@ 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 struct most_inst_attribute most_inst_attr_interface = - __ATTR_RO(interface); +static DEVICE_ATTR_RO(description); +static DEVICE_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; - - 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); -} +static const struct attribute_group *interface_attr_groups[] = { + &interface_attr_group, + NULL, +}; /* ___ ___ * ___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)); } } } @@ -907,7 +607,7 @@ most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch) 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 +616,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; } @@ -948,13 +648,14 @@ 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; @@ -986,9 +687,8 @@ static ssize_t add_link_store(struct most_aim_obj *aim_obj, 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); + *aim_ptr = aim; + ret = aim->probe_channel(c->iface, c->channel_id, &c->cfg, mdev_devnod); if (ret) { *aim_ptr = NULL; return ret; @@ -1007,12 +707,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,74 +729,34 @@ 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___ @@ -1621,28 +1282,35 @@ 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; + 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); return 0; } EXPORT_SYMBOL_GPL(most_register_aim); @@ -1653,7 +1321,6 @@ EXPORT_SYMBOL_GPL(most_register_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 +1329,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 +1340,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 +1363,7 @@ EXPORT_SYMBOL_GPL(most_deregister_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 +1375,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 +1396,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; + 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 +1418,17 @@ 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; + 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 +1454,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 +1474,14 @@ EXPORT_SYMBOL_GPL(most_register_interface); */ 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 +1490,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); @@ -1858,13 +1547,17 @@ 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; pr_info("init()\n"); INIT_LIST_HEAD(&instance_list); - INIT_LIST_HEAD(&aim_list); ida_init(&mdev_id); err = bus_register(&most_bus); @@ -1886,30 +1579,15 @@ static int __init most_init(void) 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) { - err = -ENOMEM; - goto exit_class_container; - } - - most_inst_kset = kset_create_and_add("devices", NULL, &core_dev->kobj); - if (!most_inst_kset) { + core_dev.init_name = "most_bus"; + core_dev.release = release_most_sub; + if (device_register(&core_dev)) { 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: @@ -1921,21 +1599,8 @@ static int __init most_init(void) 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); diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h index a6e618c..b392ba5 100644 --- a/drivers/staging/most/core.h +++ b/drivers/staging/most/core.h @@ -23,8 +23,8 @@ #define __MOST_CORE_H__ #include <linux/types.h> +#include <linux/device.h> -struct kobject; struct module; /** @@ -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,8 @@ 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 +268,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 +279,8 @@ 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 +290,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 0a1b785..d2d914d 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,17 +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) { @@ -853,7 +856,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 +884,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 6081943..9165c72 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 9b4a804..06501ff 100644 --- a/drivers/staging/most/net/net.c +++ b/drivers/staging/most/net/net.c @@ -297,8 +297,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) + struct most_channel_config *ccfg, char *name) { struct net_dev_context *nd; struct net_dev_channel *ch; diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c index 72603ae..d8ce059 100644 --- a/drivers/staging/most/sound/sound.c +++ b/drivers/staging/most/sound/sound.c @@ -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 492480d..da2fc54 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 const struct usb_device_id usbid[] = { { } /* 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 show_value(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 store_value(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, show_value, NULL); +DEVICE_ATTR(packet_bandwidth, 0444, show_value, NULL); +DEVICE_ATTR(node_address, 0444, show_value, NULL); +DEVICE_ATTR(node_position, 0444, show_value, NULL); +DEVICE_ATTR(sync_ep, 0200, NULL, store_value); +DEVICE_ATTR(mep_filter, 0644, show_value, store_value); +DEVICE_ATTR(mep_hash0, 0644, show_value, store_value); +DEVICE_ATTR(mep_hash1, 0644, show_value, store_value); +DEVICE_ATTR(mep_hash2, 0644, show_value, store_value); +DEVICE_ATTR(mep_hash3, 0644, show_value, store_value); +DEVICE_ATTR(mep_eui48_hi, 0644, show_value, store_value); +DEVICE_ATTR(mep_eui48_mi, 0644, show_value, store_value); +DEVICE_ATTR(mep_eui48_lo, 0644, show_value, store_value); +DEVICE_ATTR(arb_address, 0644, show_value, store_value); +DEVICE_ATTR(arb_value, 0644, show_value, store_value); + +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,20 +1092,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) 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); @@ -1239,12 +1108,21 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) 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 +1162,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 b418c09..2c27416 100644 --- a/drivers/staging/most/video/video.c +++ b/drivers/staging/most/video/video.c @@ -486,8 +486,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) + struct most_channel_config *ccfg, char *name) { int ret; struct most_video_dev *mdev = get_aim_dev(iface, channel_idx); -- 2.7.4 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel