diff options
Diffstat (limited to 'drivers/staging/most')
-rw-r--r-- | drivers/staging/most/Kconfig | 8 | ||||
-rw-r--r-- | drivers/staging/most/cdev/cdev.c | 1 | ||||
-rw-r--r-- | drivers/staging/most/configfs.c | 124 | ||||
-rw-r--r-- | drivers/staging/most/core.c | 108 | ||||
-rw-r--r-- | drivers/staging/most/core.h | 1 | ||||
-rw-r--r-- | drivers/staging/most/net/net.c | 1 | ||||
-rw-r--r-- | drivers/staging/most/sound/sound.c | 9 | ||||
-rw-r--r-- | drivers/staging/most/video/video.c | 1 |
8 files changed, 109 insertions, 144 deletions
diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig index 8948d5246409..6262eb25c80b 100644 --- a/drivers/staging/most/Kconfig +++ b/drivers/staging/most/Kconfig @@ -1,9 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 menuconfig MOST - tristate "MOST support" + tristate "MOST support" depends on HAS_DMA && CONFIGFS_FS - default n - help + default n + help Say Y here if you want to enable MOST support. This driver needs at least one additional component to enable the desired access from userspace (e.g. character devices) and one that @@ -12,7 +12,7 @@ menuconfig MOST To compile this driver as a module, choose M here: the module will be called most_core. - If in doubt, say N here. + If in doubt, say N here. diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index 724d098aeef0..f880147c82fd 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -494,6 +494,7 @@ err_remove_ida: static struct cdev_component comp = { .cc = { + .mod = THIS_MODULE, .name = "cdev", .probe_channel = comp_probe, .disconnect_channel = comp_disconnect_channel, diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c index 025495657b68..34a9fb53985c 100644 --- a/drivers/staging/most/configfs.c +++ b/drivers/staging/most/configfs.c @@ -164,6 +164,7 @@ static ssize_t mdev_link_direction_store(struct config_item *item, !sysfs_streq(page, "dir_tx") && !sysfs_streq(page, "tx")) return -EINVAL; strcpy(mdev_link->direction, page); + strim(mdev_link->direction); return count; } @@ -182,6 +183,7 @@ static ssize_t mdev_link_datatype_store(struct config_item *item, !sysfs_streq(page, "isoc_avp")) return -EINVAL; strcpy(mdev_link->datatype, page); + strim(mdev_link->datatype); return count; } @@ -196,6 +198,7 @@ static ssize_t mdev_link_device_store(struct config_item *item, struct mdev_link *mdev_link = to_mdev_link(item); strcpy(mdev_link->device, page); + strim(mdev_link->device); return count; } @@ -210,6 +213,7 @@ static ssize_t mdev_link_channel_store(struct config_item *item, struct mdev_link *mdev_link = to_mdev_link(item); strcpy(mdev_link->channel, page); + strim(mdev_link->channel); return count; } @@ -391,22 +395,29 @@ static const struct config_item_type mdev_link_type = { struct most_common { struct config_group group; + struct module *mod; + struct configfs_subsystem subsys; }; -static struct most_common *to_most_common(struct config_item *item) +static struct most_common *to_most_common(struct configfs_subsystem *subsys) { - return container_of(to_config_group(item), struct most_common, group); + return container_of(subsys, struct most_common, subsys); } static struct config_item *most_common_make_item(struct config_group *group, const char *name) { struct mdev_link *mdev_link; + struct most_common *mc = to_most_common(group->cg_subsys); mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL); if (!mdev_link) return ERR_PTR(-ENOMEM); + if (!try_module_get(mc->mod)) { + kfree(mdev_link); + return ERR_PTR(-ENOLCK); + } config_item_init_type_name(&mdev_link->item, name, &mdev_link_type); @@ -422,15 +433,26 @@ static struct config_item *most_common_make_item(struct config_group *group, static void most_common_release(struct config_item *item) { - kfree(to_most_common(item)); + struct config_group *group = to_config_group(item); + + kfree(to_most_common(group->cg_subsys)); } static struct configfs_item_operations most_common_item_ops = { .release = most_common_release, }; +static void most_common_disconnect(struct config_group *group, + struct config_item *item) +{ + struct most_common *mc = to_most_common(group->cg_subsys); + + module_put(mc->mod); +} + static struct configfs_group_operations most_common_group_ops = { .make_item = most_common_make_item, + .disconnect_notify = most_common_disconnect, }; static const struct config_item_type most_common_type = { @@ -439,29 +461,35 @@ static const struct config_item_type most_common_type = { .ct_owner = THIS_MODULE, }; -static struct configfs_subsystem most_cdev_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "most_cdev", - .ci_type = &most_common_type, +static struct most_common most_cdev = { + .subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "most_cdev", + .ci_type = &most_common_type, + }, }, }, }; -static struct configfs_subsystem most_net_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "most_net", - .ci_type = &most_common_type, +static struct most_common most_net = { + .subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "most_net", + .ci_type = &most_common_type, + }, }, }, }; -static struct configfs_subsystem most_video_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "most_video", - .ci_type = &most_common_type, +static struct most_common most_video = { + .subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "most_video", + .ci_type = &most_common_type, + }, }, }, }; @@ -487,7 +515,7 @@ static struct config_item *most_snd_grp_make_item(struct config_group *group, return ERR_PTR(-ENOMEM); config_item_init_type_name(&mdev_link->item, name, &mdev_link_type); - mdev_link->create_link = 0; + mdev_link->create_link = false; strcpy(mdev_link->name, name); strcpy(mdev_link->comp, "sound"); return &mdev_link->item; @@ -545,13 +573,14 @@ static const struct config_item_type most_snd_grp_type = { struct most_sound { struct configfs_subsystem subsys; struct list_head soundcard_list; + struct module *mod; }; static struct config_group *most_sound_make_group(struct config_group *group, const char *name) { struct most_snd_grp *most; - struct most_sound *ms = container_of(to_configfs_subsystem(group), + struct most_sound *ms = container_of(group->cg_subsys, struct most_sound, subsys); list_for_each_entry(most, &ms->soundcard_list, list) { @@ -560,17 +589,29 @@ static struct config_group *most_sound_make_group(struct config_group *group, return ERR_PTR(-EPROTO); } } + if (!try_module_get(ms->mod)) + return ERR_PTR(-ENOLCK); most = kzalloc(sizeof(*most), GFP_KERNEL); - if (!most) + if (!most) { + module_put(ms->mod); return ERR_PTR(-ENOMEM); - + } config_group_init_type_name(&most->group, name, &most_snd_grp_type); list_add_tail(&most->list, &ms->soundcard_list); return &most->group; } +static void most_sound_disconnect(struct config_group *group, + struct config_item *item) +{ + struct most_sound *ms = container_of(group->cg_subsys, + struct most_sound, subsys); + module_put(ms->mod); +} + static struct configfs_group_operations most_sound_group_ops = { .make_group = most_sound_make_group, + .disconnect_notify = most_sound_disconnect, }; static const struct config_item_type most_sound_type = { @@ -593,16 +634,21 @@ int most_register_configfs_subsys(struct core_component *c) { int ret; - if (!strcmp(c->name, "cdev")) - ret = configfs_register_subsystem(&most_cdev_subsys); - else if (!strcmp(c->name, "net")) - ret = configfs_register_subsystem(&most_net_subsys); - else if (!strcmp(c->name, "video")) - ret = configfs_register_subsystem(&most_video_subsys); - else if (!strcmp(c->name, "sound")) + if (!strcmp(c->name, "cdev")) { + most_cdev.mod = c->mod; + ret = configfs_register_subsystem(&most_cdev.subsys); + } else if (!strcmp(c->name, "net")) { + most_net.mod = c->mod; + ret = configfs_register_subsystem(&most_net.subsys); + } else if (!strcmp(c->name, "video")) { + most_video.mod = c->mod; + ret = configfs_register_subsystem(&most_video.subsys); + } else if (!strcmp(c->name, "sound")) { + most_sound_subsys.mod = c->mod; ret = configfs_register_subsystem(&most_sound_subsys.subsys); - else + } else { return -ENODEV; + } if (ret) { pr_err("Error %d while registering subsystem %s\n", @@ -631,11 +677,11 @@ void most_interface_register_notify(const char *mdev) void most_deregister_configfs_subsys(struct core_component *c) { if (!strcmp(c->name, "cdev")) - configfs_unregister_subsystem(&most_cdev_subsys); + configfs_unregister_subsystem(&most_cdev.subsys); else if (!strcmp(c->name, "net")) - configfs_unregister_subsystem(&most_net_subsys); + configfs_unregister_subsystem(&most_net.subsys); else if (!strcmp(c->name, "video")) - configfs_unregister_subsystem(&most_video_subsys); + configfs_unregister_subsystem(&most_video.subsys); else if (!strcmp(c->name, "sound")) configfs_unregister_subsystem(&most_sound_subsys.subsys); } @@ -643,14 +689,14 @@ EXPORT_SYMBOL_GPL(most_deregister_configfs_subsys); int __init configfs_init(void) { - config_group_init(&most_cdev_subsys.su_group); - mutex_init(&most_cdev_subsys.su_mutex); + config_group_init(&most_cdev.subsys.su_group); + mutex_init(&most_cdev.subsys.su_mutex); - config_group_init(&most_net_subsys.su_group); - mutex_init(&most_net_subsys.su_mutex); + config_group_init(&most_net.subsys.su_group); + mutex_init(&most_net.subsys.su_mutex); - config_group_init(&most_video_subsys.su_group); - mutex_init(&most_video_subsys.su_mutex); + config_group_init(&most_video.subsys.su_group); + mutex_init(&most_video.subsys.su_mutex); config_group_init(&most_sound_subsys.subsys.su_group); mutex_init(&most_sound_subsys.subsys.su_mutex); diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 8e9a0b67c6ed..51a6b41d5b82 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -52,7 +52,7 @@ struct most_channel { u16 channel_id; char name[STRING_SIZE]; bool is_poisoned; - struct mutex start_mutex; + struct mutex start_mutex; /* channel activation synchronization */ struct mutex nq_mutex; /* nq thread synchronization */ int is_starving; struct most_interface *iface; @@ -60,7 +60,7 @@ struct most_channel { bool keep_mbo; bool enqueue_halt; struct list_head fifo; - spinlock_t fifo_lock; + spinlock_t fifo_lock; /* fifo access synchronization */ struct list_head halt_fifo; struct list_head list; struct pipe pipe0; @@ -84,11 +84,11 @@ static const struct { int most_ch_data_type; const char *name; } ch_data_type[] = { - { MOST_CH_CONTROL, "control\n" }, - { MOST_CH_ASYNC, "async\n" }, - { MOST_CH_SYNC, "sync\n" }, - { MOST_CH_ISOC, "isoc\n"}, - { MOST_CH_ISOC, "isoc_avp\n"}, + { MOST_CH_CONTROL, "control" }, + { MOST_CH_ASYNC, "async" }, + { MOST_CH_SYNC, "sync" }, + { MOST_CH_ISOC, "isoc"}, + { MOST_CH_ISOC, "isoc_avp"}, }; /** @@ -521,48 +521,6 @@ static ssize_t components_show(struct device_driver *drv, char *buf) } /** - * split_string - parses buf and extracts ':' separated substrings. - * - * @buf: complete string from attribute 'add_channel' - * @a: storage for 1st substring (=interface name) - * @b: storage for 2nd substring (=channel name) - * @c: storage for 3rd substring (=component name) - * @d: storage optional 4th substring (=user defined name) - * - * Examples: - * - * Input: "mdev0:ch6:cdev:my_channel\n" or - * "mdev0:ch6:cdev:my_channel" - * - * Output: *a -> "mdev0", *b -> "ch6", *c -> "cdev" *d -> "my_channel" - * - * Input: "mdev1:ep81:cdev\n" - * Output: *a -> "mdev1", *b -> "ep81", *c -> "cdev" *d -> "" - * - * Input: "mdev1:ep81" - * Output: *a -> "mdev1", *b -> "ep81", *c -> "cdev" *d == NULL - */ -static int split_string(char *buf, char **a, char **b, char **c, char **d) -{ - *a = strsep(&buf, ":"); - if (!*a) - return -EIO; - - *b = strsep(&buf, ":\n"); - if (!*b) - return -EIO; - - *c = strsep(&buf, ":\n"); - if (!*c) - return -EIO; - - if (d) - *d = strsep(&buf, ":\n"); - - return 0; -} - -/** * get_channel - get pointer to channel * @mdev: name of the device interface * @mdev_ch: name of channel @@ -675,13 +633,13 @@ int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf) if (!c) return -ENODEV; - if (!strcmp(buf, "dir_rx\n")) { + if (!strcmp(buf, "dir_rx")) { c->cfg.direction = MOST_CH_RX; - } else if (!strcmp(buf, "rx\n")) { + } else if (!strcmp(buf, "rx")) { c->cfg.direction = MOST_CH_RX; - } else if (!strcmp(buf, "dir_tx\n")) { + } else if (!strcmp(buf, "dir_tx")) { c->cfg.direction = MOST_CH_TX; - } else if (!strcmp(buf, "tx\n")) { + } else if (!strcmp(buf, "tx")) { c->cfg.direction = MOST_CH_TX; } else { pr_info("Invalid direction\n"); @@ -723,48 +681,6 @@ int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name, return link_channel_to_component(c, comp, link_name, comp_param); } -/** - * remove_link_store - store function for remove_link attribute - * @drv: device driver - * @buf: buffer - * @len: buffer length - * - * Example: - * echo "mdev0:ep81" >remove_link - */ -static ssize_t remove_link_store(struct device_driver *drv, - const char *buf, - size_t len) -{ - struct most_channel *c; - struct core_component *comp; - char buffer[STRING_SIZE]; - char *mdev; - char *mdev_ch; - char *comp_name; - int ret; - size_t max_len = min_t(size_t, len + 1, STRING_SIZE); - - strlcpy(buffer, buf, max_len); - ret = split_string(buffer, &mdev, &mdev_ch, &comp_name, NULL); - if (ret) - return ret; - comp = match_component(comp_name); - if (!comp) - return -ENODEV; - c = get_channel(mdev, mdev_ch); - if (!c) - return -ENODEV; - - if (comp->disconnect_channel(c->iface, c->channel_id)) - return -EIO; - if (c->pipe0.comp == comp) - c->pipe0.comp = NULL; - if (c->pipe1.comp == comp) - c->pipe1.comp = NULL; - return len; -} - int most_remove_link(char *mdev, char *mdev_ch, char *comp_name) { struct most_channel *c; @@ -790,12 +706,10 @@ int most_remove_link(char *mdev, char *mdev_ch, char *comp_name) static DRIVER_ATTR_RO(links); static DRIVER_ATTR_RO(components); -static DRIVER_ATTR_WO(remove_link); static struct attribute *mc_attrs[] = { DRV_ATTR(links), DRV_ATTR(components), - DRV_ATTR(remove_link), NULL, }; diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h index 652aaa771029..49859aef98df 100644 --- a/drivers/staging/most/core.h +++ b/drivers/staging/most/core.h @@ -265,6 +265,7 @@ struct most_interface { struct core_component { struct list_head list; const char *name; + struct module *mod; int (*probe_channel)(struct most_interface *iface, int channel_idx, struct most_channel_config *cfg, char *name, char *param); diff --git a/drivers/staging/most/net/net.c b/drivers/staging/most/net/net.c index 26a31854c636..6cab1bb8956e 100644 --- a/drivers/staging/most/net/net.c +++ b/drivers/staging/most/net/net.c @@ -498,6 +498,7 @@ put_nd: } static struct core_component comp = { + .mod = THIS_MODULE, .name = "net", .probe_channel = comp_probe_channel, .disconnect_channel = comp_disconnect_channel, diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c index 79817061fcfa..723d0bd1cc21 100644 --- a/drivers/staging/most/sound/sound.c +++ b/drivers/staging/most/sound/sound.c @@ -344,8 +344,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, pr_err("Requested number of channels not supported.\n"); return -EINVAL; } - return snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } /** @@ -359,7 +358,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, */ static int pcm_hw_free(struct snd_pcm_substream *substream) { - return snd_pcm_lib_free_vmalloc_buffer(substream); + return snd_pcm_lib_free_pages(substream); } /** @@ -469,7 +468,6 @@ static const struct snd_pcm_ops pcm_ops = { .prepare = pcm_prepare, .trigger = pcm_trigger, .pointer = pcm_pointer, - .page = snd_pcm_lib_get_vmalloc_page, }; static int split_arg_list(char *buf, u16 *ch_num, char **sample_res) @@ -663,6 +661,8 @@ skip_adpt_alloc: pcm->private_data = channel; strscpy(pcm->name, device_name, sizeof(pcm->name)); snd_pcm_set_ops(pcm, direction, &pcm_ops); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC, + NULL, 0, 0); return 0; @@ -782,6 +782,7 @@ static int audio_tx_completion(struct most_interface *iface, int channel_id) * Initialization of the struct core_component */ static struct core_component comp = { + .mod = THIS_MODULE, .name = DRIVER_NAME, .probe_channel = audio_probe_channel, .disconnect_channel = audio_disconnect_channel, diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c index 250af9fb704d..10c1ef7e3a3e 100644 --- a/drivers/staging/most/video/video.c +++ b/drivers/staging/most/video/video.c @@ -528,6 +528,7 @@ static int comp_disconnect_channel(struct most_interface *iface, } static struct core_component comp = { + .mod = THIS_MODULE, .name = "video", .probe_channel = comp_probe_channel, .disconnect_channel = comp_disconnect_channel, |