diff options
Diffstat (limited to 'drivers/staging/most')
-rw-r--r-- | drivers/staging/most/Kconfig | 8 | ||||
-rw-r--r-- | drivers/staging/most/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/cdev/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/cdev/cdev.c | 10 | ||||
-rw-r--r-- | drivers/staging/most/configfs.c | 183 | ||||
-rw-r--r-- | drivers/staging/most/core.c | 314 | ||||
-rw-r--r-- | drivers/staging/most/dim2/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/dim2/dim2.c | 26 | ||||
-rw-r--r-- | drivers/staging/most/dim2/hal.c | 99 | ||||
-rw-r--r-- | drivers/staging/most/dim2/hal.h | 4 | ||||
-rw-r--r-- | drivers/staging/most/i2c/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/i2c/i2c.c | 2 | ||||
-rw-r--r-- | drivers/staging/most/most.h (renamed from drivers/staging/most/core.h) | 31 | ||||
-rw-r--r-- | drivers/staging/most/net/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/net/net.c | 21 | ||||
-rw-r--r-- | drivers/staging/most/sound/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/sound/sound.c | 60 | ||||
-rw-r--r-- | drivers/staging/most/usb/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/usb/usb.c | 26 | ||||
-rw-r--r-- | drivers/staging/most/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/most/video/video.c | 10 |
21 files changed, 348 insertions, 454 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/Makefile b/drivers/staging/most/Makefile index 85ea5a434ced..20a99ecb37c4 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -2,7 +2,6 @@ obj-$(CONFIG_MOST) += most_core.o most_core-y := core.o most_core-y += configfs.o -ccflags-y += -I $(srctree)/drivers/staging/ obj-$(CONFIG_MOST_CDEV) += cdev/ obj-$(CONFIG_MOST_NET) += net/ diff --git a/drivers/staging/most/cdev/Makefile b/drivers/staging/most/cdev/Makefile index 9f4a8b8c9c27..ef90cd71994a 100644 --- a/drivers/staging/most/cdev/Makefile +++ b/drivers/staging/most/cdev/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_CDEV) += most_cdev.o most_cdev-objs := cdev.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index d0cc0b746107..71943d17f825 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -16,7 +16,8 @@ #include <linux/kfifo.h> #include <linux/uaccess.h> #include <linux/idr.h> -#include "most/core.h" + +#include "../most.h" #define CHRDEV_REGION_SIZE 50 @@ -25,7 +26,7 @@ static struct cdev_component { struct ida minor_id; unsigned int major; struct class *class; - struct core_component cc; + struct most_component cc; } comp; struct comp_channel { @@ -463,10 +464,8 @@ static int comp_probe(struct most_interface *iface, int channel_id, spin_lock_init(&c->unlink); INIT_KFIFO(c->fifo); retval = kfifo_alloc(&c->fifo, cfg->num_buffers, GFP_KERNEL); - if (retval) { - pr_info("failed to alloc channel kfifo"); + if (retval) goto err_del_cdev_and_free_channel; - } init_waitqueue_head(&c->wq); mutex_init(&c->io_mutex); spin_lock_irqsave(&ch_list_lock, cl_flags); @@ -496,6 +495,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..9a961222f458 100644 --- a/drivers/staging/most/configfs.c +++ b/drivers/staging/most/configfs.c @@ -10,7 +10,10 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/configfs.h> -#include <most/core.h> + +#include "most.h" + +#define MAX_STRING_SIZE 80 struct mdev_link { struct config_item item; @@ -22,13 +25,13 @@ struct mdev_link { u16 subbuffer_size; u16 packets_per_xact; u16 dbr_size; - char datatype[PAGE_SIZE]; - char direction[PAGE_SIZE]; - char name[PAGE_SIZE]; - char device[PAGE_SIZE]; - char channel[PAGE_SIZE]; - char comp[PAGE_SIZE]; - char comp_params[PAGE_SIZE]; + char datatype[MAX_STRING_SIZE]; + char direction[MAX_STRING_SIZE]; + char name[MAX_STRING_SIZE]; + char device[MAX_STRING_SIZE]; + char channel[MAX_STRING_SIZE]; + char comp[MAX_STRING_SIZE]; + char comp_params[MAX_STRING_SIZE]; }; static struct list_head mdev_link_list; @@ -125,6 +128,8 @@ static ssize_t mdev_link_create_link_store(struct config_item *item, return ret; list_add_tail(&mdev_link->list, &mdev_link_list); mdev_link->create_link = tmp; + mdev_link->destroy_link = false; + return count; } @@ -140,13 +145,16 @@ static ssize_t mdev_link_destroy_link_store(struct config_item *item, return ret; if (!tmp) return count; - mdev_link->destroy_link = tmp; + ret = most_remove_link(mdev_link->device, mdev_link->channel, mdev_link->comp); if (ret) return ret; if (!list_empty(&mdev_link_list)) list_del(&mdev_link->list); + + mdev_link->destroy_link = tmp; + return count; } @@ -164,6 +172,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 +191,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; } @@ -195,7 +205,8 @@ 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); + strlcpy(mdev_link->device, page, sizeof(mdev_link->device)); + strim(mdev_link->device); return count; } @@ -209,7 +220,8 @@ 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); + strlcpy(mdev_link->channel, page, sizeof(mdev_link->channel)); + strim(mdev_link->channel); return count; } @@ -223,7 +235,8 @@ static ssize_t mdev_link_comp_store(struct config_item *item, { struct mdev_link *mdev_link = to_mdev_link(item); - strcpy(mdev_link->comp, page); + strlcpy(mdev_link->comp, page, sizeof(mdev_link->comp)); + strim(mdev_link->comp); return count; } @@ -238,7 +251,8 @@ static ssize_t mdev_link_comp_params_store(struct config_item *item, { struct mdev_link *mdev_link = to_mdev_link(item); - strcpy(mdev_link->comp_params, page); + strlcpy(mdev_link->comp_params, page, sizeof(mdev_link->comp_params)); + strim(mdev_link->comp_params); return count; } @@ -369,13 +383,20 @@ static void mdev_link_release(struct config_item *item) struct mdev_link *mdev_link = to_mdev_link(item); int ret; - if (!list_empty(&mdev_link_list)) { - ret = most_remove_link(mdev_link->device, mdev_link->channel, - mdev_link->comp); - if (ret && (ret != -ENODEV)) - pr_err("Removing link failed.\n"); - list_del(&mdev_link->list); + if (mdev_link->destroy_link) + goto free_item; + + ret = most_remove_link(mdev_link->device, mdev_link->channel, + mdev_link->comp); + if (ret) { + pr_err("Removing link failed.\n"); + goto free_item; } + + if (!list_empty(&mdev_link_list)) + list_del(&mdev_link->list); + +free_item: kfree(to_mdev_link(item)); } @@ -391,22 +412,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 +450,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 +478,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 +532,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 +590,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 +606,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 = { @@ -589,20 +647,25 @@ static struct most_sound most_sound_subsys = { }, }; -int most_register_configfs_subsys(struct core_component *c) +int most_register_configfs_subsys(struct most_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", @@ -628,14 +691,14 @@ void most_interface_register_notify(const char *mdev) most_cfg_complete("sound"); } -void most_deregister_configfs_subsys(struct core_component *c) +void most_deregister_configfs_subsys(struct most_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 +706,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 b9841adb7181..0c4ae6920d77 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -2,10 +2,9 @@ /* * core.c - Implementation of core module of MOST Linux driver stack * - * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG + * Copyright (C) 2013-2020 Microchip Technology Germany II GmbH & Co. KG */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> #include <linux/fs.h> #include <linux/slab.h> @@ -21,25 +20,18 @@ #include <linux/kthread.h> #include <linux/dma-mapping.h> #include <linux/idr.h> -#include <most/core.h> + +#include "most.h" #define MAX_CHANNELS 64 #define STRING_SIZE 80 static struct ida mdev_id; static int dummy_num_buffers; - -static struct mostcore { - struct device dev; - struct device_driver drv; - struct bus_type bus; - struct list_head comp_list; -} mc; - -#define to_driver(d) container_of(d, struct mostcore, drv) +static struct list_head comp_list; struct pipe { - struct core_component *comp; + struct most_component *comp; int refs; int num_buffers; }; @@ -52,7 +44,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 +52,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 +76,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"}, }; /** @@ -151,7 +143,7 @@ static void flush_channel_fifos(struct most_channel *c) spin_unlock_irqrestore(&c->fifo_lock, hf_flags); if (unlikely((!list_empty(&c->fifo) || !list_empty(&c->halt_fifo)))) - pr_info("WARN: fifo | trash fifo not empty\n"); + dev_warn(&c->dev, "Channel or trash fifo not empty\n"); } /** @@ -303,7 +295,8 @@ static ssize_t set_datatype_show(struct device *dev, for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { if (c->cfg.data_type & ch_data_type[i].most_ch_data_type) - return snprintf(buf, PAGE_SIZE, "%s", ch_data_type[i].name); + return snprintf(buf, PAGE_SIZE, "%s", + ch_data_type[i].name); } return snprintf(buf, PAGE_SIZE, "unconfigured\n"); } @@ -401,7 +394,7 @@ static ssize_t description_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct most_interface *iface = to_most_interface(dev); + struct most_interface *iface = dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%s\n", iface->description); } @@ -410,7 +403,7 @@ static ssize_t interface_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct most_interface *iface = to_most_interface(dev); + struct most_interface *iface = dev_get_drvdata(dev); switch (iface->interface) { case ITYPE_LOOPBACK: @@ -453,11 +446,11 @@ static const struct attribute_group *interface_attr_groups[] = { NULL, }; -static struct core_component *match_component(char *name) +static struct most_component *match_component(char *name) { - struct core_component *comp; + struct most_component *comp; - list_for_each_entry(comp, &mc.comp_list, list) { + list_for_each_entry(comp, &comp_list, list) { if (!strcmp(comp->name, name)) return comp; } @@ -475,7 +468,7 @@ static int print_links(struct device *dev, void *data) int offs = d->offs; char *buf = d->buf; struct most_channel *c; - struct most_interface *iface = to_most_interface(dev); + struct most_interface *iface = dev_get_drvdata(dev); list_for_each_entry(c, &iface->p->channel_list, list) { if (c->pipe0.comp) { @@ -483,7 +476,7 @@ static int print_links(struct device *dev, void *data) PAGE_SIZE - offs, "%s:%s:%s\n", c->pipe0.comp->name, - dev_name(&iface->dev), + dev_name(iface->dev), dev_name(&c->dev)); } if (c->pipe1.comp) { @@ -491,7 +484,7 @@ static int print_links(struct device *dev, void *data) PAGE_SIZE - offs, "%s:%s:%s\n", c->pipe1.comp->name, - dev_name(&iface->dev), + dev_name(iface->dev), dev_name(&c->dev)); } } @@ -499,20 +492,33 @@ static int print_links(struct device *dev, void *data) return 0; } +static 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 mostbus = { + .name = "most", + .match = most_match, +}; + static ssize_t links_show(struct device_driver *drv, char *buf) { struct show_links_data d = { .buf = buf }; - bus_for_each_dev(&mc.bus, NULL, &d, print_links); + bus_for_each_dev(&mostbus, NULL, &d, print_links); return d.offs; } static ssize_t components_show(struct device_driver *drv, char *buf) { - struct core_component *comp; + struct most_component *comp; int offs = 0; - list_for_each_entry(comp, &mc.comp_list, list) { + list_for_each_entry(comp, &comp_list, list) { offs += snprintf(buf + offs, PAGE_SIZE - offs, "%s\n", comp->name); } @@ -520,48 +526,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 @@ -572,10 +536,11 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch) struct most_interface *iface; struct most_channel *c, *tmp; - dev = bus_find_device_by_name(&mc.bus, NULL, mdev); + dev = bus_find_device_by_name(&mostbus, NULL, mdev); if (!dev) return NULL; - iface = to_most_interface(dev); + put_device(dev); + iface = dev_get_drvdata(dev); list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) { if (!strcmp(dev_name(&c->dev), mdev_ch)) return c; @@ -585,12 +550,12 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch) static inline int link_channel_to_component(struct most_channel *c, - struct core_component *comp, + struct most_component *comp, char *name, char *comp_param) { int ret; - struct core_component **comp_ptr; + struct most_component **comp_ptr; if (!c->pipe0.comp) comp_ptr = &c->pipe0.comp; @@ -664,7 +629,7 @@ int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf) } if (i == ARRAY_SIZE(ch_data_type)) - pr_info("WARN: invalid attribute settings\n"); + dev_warn(&c->dev, "Invalid attribute settings\n"); return 0; } @@ -674,16 +639,16 @@ 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"); + dev_err(&c->dev, "Invalid direction\n"); return -ENODATA; } return 0; @@ -701,7 +666,7 @@ int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val) int most_cfg_complete(char *comp_name) { - struct core_component *comp; + struct most_component *comp; comp = match_component(comp_name); if (!comp) @@ -714,59 +679,18 @@ int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name, char *comp_param) { struct most_channel *c = get_channel(mdev, mdev_ch); - struct core_component *comp = match_component(comp_name); + struct most_component *comp = match_component(comp_name); if (!c || !comp) return -ENODEV; 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; - struct core_component *comp; + struct most_component *comp; comp = match_component(comp_name); if (!comp) @@ -788,12 +712,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, }; @@ -806,13 +728,11 @@ static const struct attribute_group *mc_attr_groups[] = { NULL, }; -static int most_match(struct device *dev, struct device_driver *drv) -{ - if (!strcmp(dev_name(dev), "most")) - return 0; - else - return 1; -} +static struct device_driver mostbus_driver = { + .name = "most_core", + .bus = &mostbus, + .groups = mc_attr_groups, +}; static inline void trash_mbo(struct mbo *mbo) { @@ -879,7 +799,7 @@ static int hdm_enqueue_thread(void *data) mutex_unlock(&c->nq_mutex); if (unlikely(ret)) { - pr_err("hdm enqueue failed\n"); + dev_err(&c->dev, "Buffer enqueue failed\n"); nq_hdm_mbo(mbo); c->hdm_enqueue_task = NULL; return 0; @@ -1006,7 +926,7 @@ flush_fifos: void most_submit_mbo(struct mbo *mbo) { if (WARN_ONCE(!mbo || !mbo->context, - "bad mbo or missing channel reference\n")) + "Bad buffer or missing channel reference\n")) return; nq_hdm_mbo(mbo); @@ -1025,8 +945,6 @@ static void most_write_completion(struct mbo *mbo) struct most_channel *c; c = mbo->context; - if (mbo->status == MBO_E_INVAL) - pr_info("WARN: Tx MBO status: invalid\n"); if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE))) trash_mbo(mbo); else @@ -1034,7 +952,7 @@ static void most_write_completion(struct mbo *mbo) } int channel_has_mbo(struct most_interface *iface, int id, - struct core_component *comp) + struct most_component *comp) { struct most_channel *c = iface->p->channel[id]; unsigned long flags; @@ -1065,7 +983,7 @@ EXPORT_SYMBOL_GPL(channel_has_mbo); * Returns a pointer to MBO on success or NULL otherwise. */ struct mbo *most_get_mbo(struct most_interface *iface, int id, - struct core_component *comp) + struct most_component *comp) { struct mbo *mbo; struct most_channel *c; @@ -1171,7 +1089,7 @@ static void most_read_completion(struct mbo *mbo) * Returns 0 on success or error code otherwise. */ int most_start_channel(struct most_interface *iface, int id, - struct core_component *comp) + struct most_component *comp) { int num_buffer; int ret; @@ -1185,14 +1103,14 @@ int most_start_channel(struct most_interface *iface, int id, goto out; /* already started by another component */ if (!try_module_get(iface->mod)) { - pr_info("failed to acquire HDM lock\n"); + dev_err(&c->dev, "Failed to acquire HDM lock\n"); mutex_unlock(&c->start_mutex); return -ENOLCK; } c->cfg.extra_len = 0; if (c->iface->configure(c->iface, c->channel_id, &c->cfg)) { - pr_info("channel configuration failed. Go check settings...\n"); + dev_err(&c->dev, "Channel configuration failed. Go check settings...\n"); ret = -EINVAL; goto err_put_module; } @@ -1241,7 +1159,7 @@ EXPORT_SYMBOL_GPL(most_start_channel); * @comp: driver component */ int most_stop_channel(struct most_interface *iface, int id, - struct core_component *comp) + struct most_component *comp) { struct most_channel *c; @@ -1266,8 +1184,8 @@ int most_stop_channel(struct most_interface *iface, int id, c->is_poisoned = true; if (c->iface->poison_channel(c->iface, c->channel_id)) { - pr_err("Cannot stop channel %d of mdev %s\n", c->channel_id, - c->iface->description); + dev_err(&c->dev, "Failed to stop channel %d of interface %s\n", c->channel_id, + c->iface->description); mutex_unlock(&c->start_mutex); return -EAGAIN; } @@ -1276,7 +1194,7 @@ int most_stop_channel(struct most_interface *iface, int id, #ifdef CMPL_INTERRUPTIBLE if (wait_for_completion_interruptible(&c->cleanup)) { - pr_info("Interrupted while clean up ch %d\n", c->channel_id); + dev_err(&c->dev, "Interrupted while cleaning up channel %d\n", c->channel_id); mutex_unlock(&c->start_mutex); return -EINTR; } @@ -1299,14 +1217,13 @@ EXPORT_SYMBOL_GPL(most_stop_channel); * most_register_component - registers a driver component with the core * @comp: driver component */ -int most_register_component(struct core_component *comp) +int most_register_component(struct most_component *comp) { if (!comp) { pr_err("Bad component\n"); return -EINVAL; } - list_add_tail(&comp->list, &mc.comp_list); - pr_info("registered new core component %s\n", comp->name); + list_add_tail(&comp->list, &comp_list); return 0; } EXPORT_SYMBOL_GPL(most_register_component); @@ -1315,9 +1232,9 @@ static int disconnect_channels(struct device *dev, void *data) { struct most_interface *iface; struct most_channel *c, *tmp; - struct core_component *comp = data; + struct most_component *comp = data; - iface = to_most_interface(dev); + iface = dev_get_drvdata(dev); list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) { if (c->pipe0.comp == comp || c->pipe1.comp == comp) comp->disconnect_channel(c->iface, c->channel_id); @@ -1333,28 +1250,24 @@ static int disconnect_channels(struct device *dev, void *data) * most_deregister_component - deregisters a driver component with the core * @comp: driver component */ -int most_deregister_component(struct core_component *comp) +int most_deregister_component(struct most_component *comp) { if (!comp) { pr_err("Bad component\n"); return -EINVAL; } - bus_for_each_dev(&mc.bus, NULL, comp, disconnect_channels); + bus_for_each_dev(&mostbus, NULL, comp, disconnect_channels); list_del(&comp->list); - pr_info("deregistering component %s\n", comp->name); return 0; } EXPORT_SYMBOL_GPL(most_deregister_component); -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)); + struct most_channel *c = to_channel(dev); + + kfree(c); } /** @@ -1372,13 +1285,13 @@ int 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"); + dev_err(iface->dev, "Bad interface or channel overflow\n"); return -EINVAL; } id = ida_simple_get(&mdev_id, 0, 0, GFP_KERNEL); if (id < 0) { - pr_info("Failed to alloc mdev ID\n"); + dev_err(iface->dev, "Failed to allocate device ID\n"); return id; } @@ -1391,14 +1304,13 @@ int most_register_interface(struct most_interface *iface) INIT_LIST_HEAD(&iface->p->channel_list); iface->p->dev_id = id; strscpy(iface->p->name, iface->description, sizeof(iface->p->name)); - iface->dev.init_name = iface->p->name; - iface->dev.bus = &mc.bus; - iface->dev.parent = &mc.dev; - iface->dev.groups = interface_attr_groups; - iface->dev.release = release_interface; - if (device_register(&iface->dev)) { - pr_err("registering iface->dev failed\n"); + iface->dev->bus = &mostbus; + iface->dev->groups = interface_attr_groups; + dev_set_drvdata(iface->dev, iface); + if (device_register(iface->dev)) { + dev_err(iface->dev, "Failed to register interface device\n"); kfree(iface->p); + put_device(iface->dev); ida_simple_remove(&mdev_id, id); return -ENOMEM; } @@ -1414,7 +1326,7 @@ int most_register_interface(struct most_interface *iface) else snprintf(c->name, STRING_SIZE, "%s", name_suffix); c->dev.init_name = c->name; - c->dev.parent = &iface->dev; + c->dev.parent = iface->dev; c->dev.groups = channel_attr_groups; c->dev.release = release_channel; iface->p->channel[i] = c; @@ -1440,26 +1352,23 @@ int most_register_interface(struct most_interface *iface) mutex_init(&c->nq_mutex); list_add_tail(&c->list, &iface->p->channel_list); if (device_register(&c->dev)) { - pr_err("registering c->dev failed\n"); + dev_err(&c->dev, "Failed to register channel device\n"); goto err_free_most_channel; } } - pr_info("registered new device mdev%d (%s)\n", - id, iface->description); most_interface_register_notify(iface->description); return 0; err_free_most_channel: - kfree(c); + put_device(&c->dev); err_free_resources: while (i > 0) { c = iface->p->channel[--i]; device_unregister(&c->dev); - kfree(c); } kfree(iface->p); - device_unregister(&iface->dev); + device_unregister(iface->dev); ida_simple_remove(&mdev_id, id); return -ENOMEM; } @@ -1477,8 +1386,6 @@ void most_deregister_interface(struct most_interface *iface) int i; struct most_channel *c; - pr_info("deregistering device %s (%s)\n", dev_name(&iface->dev), - iface->description); for (i = 0; i < iface->num_channels; i++) { c = iface->p->channel[i]; if (c->pipe0.comp) @@ -1491,12 +1398,11 @@ void most_deregister_interface(struct most_interface *iface) c->pipe1.comp = NULL; list_del(&c->list); device_unregister(&c->dev); - kfree(c); } ida_simple_remove(&mdev_id, iface->p->dev_id); kfree(iface->p); - device_unregister(&iface->dev); + device_unregister(iface->dev); } EXPORT_SYMBOL_GPL(most_deregister_interface); @@ -1546,57 +1452,35 @@ 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(&mc.comp_list); + INIT_LIST_HEAD(&comp_list); ida_init(&mdev_id); - mc.bus.name = "most", - mc.bus.match = most_match, - mc.drv.name = "most_core", - mc.drv.bus = &mc.bus, - mc.drv.groups = mc_attr_groups; - - err = bus_register(&mc.bus); + err = bus_register(&mostbus); if (err) { - pr_info("Cannot register most bus\n"); + pr_err("Failed to register most bus\n"); return err; } - err = driver_register(&mc.drv); + err = driver_register(&mostbus_driver); if (err) { - pr_info("Cannot register core driver\n"); + pr_err("Failed to register core driver\n"); goto err_unregister_bus; } - mc.dev.init_name = "most_bus"; - mc.dev.release = release_most_sub; - if (device_register(&mc.dev)) { - err = -ENOMEM; - goto err_unregister_driver; - } configfs_init(); return 0; -err_unregister_driver: - driver_unregister(&mc.drv); err_unregister_bus: - bus_unregister(&mc.bus); + bus_unregister(&mostbus); return err; } static void __exit most_exit(void) { - pr_info("exit core module\n"); - device_unregister(&mc.dev); - driver_unregister(&mc.drv); - bus_unregister(&mc.bus); + driver_unregister(&mostbus_driver); + bus_unregister(&mostbus); ida_destroy(&mdev_id); } diff --git a/drivers/staging/most/dim2/Makefile b/drivers/staging/most/dim2/Makefile index 116f04d69244..861adacf6c72 100644 --- a/drivers/staging/most/dim2/Makefile +++ b/drivers/staging/most/dim2/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_DIM2) += most_dim2.o most_dim2-objs := dim2.o hal.o sysfs.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 31fbc1a75b06..16593281fcda 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -21,7 +21,7 @@ #include <linux/sched.h> #include <linux/kthread.h> -#include "most/core.h" +#include "../most.h" #include "hal.h" #include "errors.h" #include "sysfs.h" @@ -129,25 +129,6 @@ bool dim2_sysfs_get_state_cb(void) } /** - * dimcb_io_read - callback from HAL to read an I/O register - * @ptr32: register address - */ -u32 dimcb_io_read(u32 __iomem *ptr32) -{ - return readl(ptr32); -} - -/** - * dimcb_io_write - callback from HAL to write value to an I/O register - * @ptr32: register address - * @value: value to write - */ -void dimcb_io_write(u32 __iomem *ptr32, u32 value) -{ - writel(value, ptr32); -} - -/** * dimcb_on_error - callback from HAL to report miscommunication between * HDM and HAL * @error_id: Error ID @@ -797,7 +778,6 @@ static int dim2_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, AHB0_INT_IDX); if (irq < 0) { - dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq); ret = irq; goto err_shutdown_dim; } @@ -811,7 +791,6 @@ static int dim2_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, MLB_INT_IDX); if (irq < 0) { - dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq); ret = irq; goto err_shutdown_dim; } @@ -875,8 +854,9 @@ static int dim2_probe(struct platform_device *pdev) dev->most_iface.poison_channel = poison_channel; dev->most_iface.request_netinfo = request_netinfo; dev->most_iface.driver_dev = &pdev->dev; + dev->most_iface.dev = &dev->dev; dev->dev.init_name = "dim2_state"; - dev->dev.parent = &dev->most_iface.dev; + dev->dev.parent = &pdev->dev; ret = most_register_interface(&dev->most_iface); if (ret) { diff --git a/drivers/staging/most/dim2/hal.c b/drivers/staging/most/dim2/hal.c index 699e02f83bd4..39e17a7d2f24 100644 --- a/drivers/staging/most/dim2/hal.c +++ b/drivers/staging/most/dim2/hal.c @@ -13,6 +13,7 @@ #include "reg.h" #include <linux/stddef.h> #include <linux/kernel.h> +#include <linux/io.h> /* * Size factor for isochronous DBR buffer. @@ -143,13 +144,13 @@ static void free_dbr(int offs, int size) static void dim2_transfer_madr(u32 val) { - dimcb_io_write(&g.dim2->MADR, val); + writel(val, &g.dim2->MADR); /* wait for transfer completion */ - while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1) + while ((readl(&g.dim2->MCTL) & 1) != 1) continue; - dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ + writel(0, &g.dim2->MCTL); /* clear transfer complete */ } static void dim2_clear_dbr(u16 addr, u16 size) @@ -159,8 +160,8 @@ static void dim2_clear_dbr(u16 addr, u16 size) u16 const end_addr = addr + size; u32 const cmd = bit_mask(MADR_WNR_BIT) | bit_mask(MADR_TB_BIT); - dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ - dimcb_io_write(&g.dim2->MDAT0, 0); + writel(0, &g.dim2->MCTL); /* clear transfer complete */ + writel(0, &g.dim2->MDAT0); for (; addr < end_addr; addr++) dim2_transfer_madr(cmd | addr); @@ -170,28 +171,28 @@ static u32 dim2_read_ctr(u32 ctr_addr, u16 mdat_idx) { dim2_transfer_madr(ctr_addr); - return dimcb_io_read((&g.dim2->MDAT0) + mdat_idx); + return readl((&g.dim2->MDAT0) + mdat_idx); } static void dim2_write_ctr_mask(u32 ctr_addr, const u32 *mask, const u32 *value) { enum { MADR_WNR_BIT = 31 }; - dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ + writel(0, &g.dim2->MCTL); /* clear transfer complete */ if (mask[0] != 0) - dimcb_io_write(&g.dim2->MDAT0, value[0]); + writel(value[0], &g.dim2->MDAT0); if (mask[1] != 0) - dimcb_io_write(&g.dim2->MDAT1, value[1]); + writel(value[1], &g.dim2->MDAT1); if (mask[2] != 0) - dimcb_io_write(&g.dim2->MDAT2, value[2]); + writel(value[2], &g.dim2->MDAT2); if (mask[3] != 0) - dimcb_io_write(&g.dim2->MDAT3, value[3]); + writel(value[3], &g.dim2->MDAT3); - dimcb_io_write(&g.dim2->MDWE0, mask[0]); - dimcb_io_write(&g.dim2->MDWE1, mask[1]); - dimcb_io_write(&g.dim2->MDWE2, mask[2]); - dimcb_io_write(&g.dim2->MDWE3, mask[3]); + writel(mask[0], &g.dim2->MDWE0); + writel(mask[1], &g.dim2->MDWE1); + writel(mask[2], &g.dim2->MDWE2); + writel(mask[3], &g.dim2->MDWE3); dim2_transfer_madr(bit_mask(MADR_WNR_BIT) | ctr_addr); } @@ -356,15 +357,13 @@ static void dim2_configure_channel( dim2_configure_cat(AHB_CAT, ch_addr, type, is_tx ? 0 : 1); /* unmask interrupt for used channel, enable mlb_sys_int[0] interrupt */ - dimcb_io_write(&g.dim2->ACMR0, - dimcb_io_read(&g.dim2->ACMR0) | bit_mask(ch_addr)); + writel(readl(&g.dim2->ACMR0) | bit_mask(ch_addr), &g.dim2->ACMR0); } static void dim2_clear_channel(u8 ch_addr) { /* mask interrupt for used channel, disable mlb_sys_int[0] interrupt */ - dimcb_io_write(&g.dim2->ACMR0, - dimcb_io_read(&g.dim2->ACMR0) & ~bit_mask(ch_addr)); + writel(readl(&g.dim2->ACMR0) & ~bit_mask(ch_addr), &g.dim2->ACMR0); dim2_clear_cat(AHB_CAT, ch_addr); dim2_clear_adt(ch_addr); @@ -373,7 +372,7 @@ static void dim2_clear_channel(u8 ch_addr) dim2_clear_cdt(ch_addr); /* clear channel status bit */ - dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr)); + writel(bit_mask(ch_addr), &g.dim2->ACSR0); } /* -------------------------------------------------------------------------- */ @@ -471,7 +470,7 @@ static inline bool check_bytes_per_frame(u32 bytes_per_frame) return true; } -static inline u16 norm_ctrl_async_buffer_size(u16 buf_size) +u16 dim_norm_ctrl_async_buffer_size(u16 buf_size) { u16 const max_size = (u16)ADT1_CTRL_ASYNC_BD_MASK + 1u; @@ -517,20 +516,20 @@ static inline u16 norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame) static void dim2_cleanup(void) { /* disable MediaLB */ - dimcb_io_write(&g.dim2->MLBC0, false << MLBC0_MLBEN_BIT); + writel(false << MLBC0_MLBEN_BIT, &g.dim2->MLBC0); dim2_clear_ctram(); /* disable mlb_int interrupt */ - dimcb_io_write(&g.dim2->MIEN, 0); + writel(0, &g.dim2->MIEN); /* clear status for all dma channels */ - dimcb_io_write(&g.dim2->ACSR0, 0xFFFFFFFF); - dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF); + writel(0xFFFFFFFF, &g.dim2->ACSR0); + writel(0xFFFFFFFF, &g.dim2->ACSR1); /* mask interrupts for all channels */ - dimcb_io_write(&g.dim2->ACMR0, 0); - dimcb_io_write(&g.dim2->ACMR1, 0); + writel(0, &g.dim2->ACMR0); + writel(0, &g.dim2->ACMR1); } static void dim2_initialize(bool enable_6pin, u8 mlb_clock) @@ -538,23 +537,22 @@ static void dim2_initialize(bool enable_6pin, u8 mlb_clock) dim2_cleanup(); /* configure and enable MediaLB */ - dimcb_io_write(&g.dim2->MLBC0, - enable_6pin << MLBC0_MLBPEN_BIT | - mlb_clock << MLBC0_MLBCLK_SHIFT | - g.fcnt << MLBC0_FCNT_SHIFT | - true << MLBC0_MLBEN_BIT); + writel(enable_6pin << MLBC0_MLBPEN_BIT | + mlb_clock << MLBC0_MLBCLK_SHIFT | + g.fcnt << MLBC0_FCNT_SHIFT | + true << MLBC0_MLBEN_BIT, + &g.dim2->MLBC0); /* activate all HBI channels */ - dimcb_io_write(&g.dim2->HCMR0, 0xFFFFFFFF); - dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF); + writel(0xFFFFFFFF, &g.dim2->HCMR0); + writel(0xFFFFFFFF, &g.dim2->HCMR1); /* enable HBI */ - dimcb_io_write(&g.dim2->HCTL, bit_mask(HCTL_EN_BIT)); + writel(bit_mask(HCTL_EN_BIT), &g.dim2->HCTL); /* configure DMA */ - dimcb_io_write(&g.dim2->ACTL, - ACTL_DMA_MODE_VAL_DMA_MODE_1 << ACTL_DMA_MODE_BIT | - true << ACTL_SCE_BIT); + writel(ACTL_DMA_MODE_VAL_DMA_MODE_1 << ACTL_DMA_MODE_BIT | + true << ACTL_SCE_BIT, &g.dim2->ACTL); } static bool dim2_is_mlb_locked(void) @@ -562,12 +560,12 @@ static bool dim2_is_mlb_locked(void) u32 const mask0 = bit_mask(MLBC0_MLBLK_BIT); u32 const mask1 = bit_mask(MLBC1_CLKMERR_BIT) | bit_mask(MLBC1_LOCKERR_BIT); - u32 const c1 = dimcb_io_read(&g.dim2->MLBC1); + u32 const c1 = readl(&g.dim2->MLBC1); u32 const nda_mask = (u32)MLBC1_NDA_MASK << MLBC1_NDA_SHIFT; - dimcb_io_write(&g.dim2->MLBC1, c1 & nda_mask); - return (dimcb_io_read(&g.dim2->MLBC1) & mask1) == 0 && - (dimcb_io_read(&g.dim2->MLBC0) & mask0) != 0; + writel(c1 & nda_mask, &g.dim2->MLBC1); + return (readl(&g.dim2->MLBC1) & mask1) == 0 && + (readl(&g.dim2->MLBC0) & mask0) != 0; } /* -------------------------------------------------------------------------- */ @@ -590,7 +588,7 @@ static inline bool service_channel(u8 ch_addr, u8 idx) dim2_write_ctr_mask(ADT + ch_addr, mask, adt_w); /* clear channel status bit */ - dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr)); + writel(bit_mask(ch_addr), &g.dim2->ACSR0); return true; } @@ -652,7 +650,7 @@ static bool channel_start(struct dim_channel *ch, u32 buf_addr, u16 buf_size) return dim_on_error(DIM_ERR_BAD_BUFFER_SIZE, "Bad buffer size"); if (ch->packet_length == 0 && ch->bytes_per_frame == 0 && - buf_size != norm_ctrl_async_buffer_size(buf_size)) + buf_size != dim_norm_ctrl_async_buffer_size(buf_size)) return dim_on_error(DIM_ERR_BAD_BUFFER_SIZE, "Bad control/async buffer size"); @@ -776,13 +774,8 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx, void dim_service_mlb_int_irq(void) { - dimcb_io_write(&g.dim2->MS0, 0); - dimcb_io_write(&g.dim2->MS1, 0); -} - -u16 dim_norm_ctrl_async_buffer_size(u16 buf_size) -{ - return norm_ctrl_async_buffer_size(buf_size); + writel(0, &g.dim2->MS0); + writel(0, &g.dim2->MS1); } /** @@ -829,7 +822,7 @@ u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, if (is_tx && !g.atx_dbr.ch_addr) { g.atx_dbr.ch_addr = ch->addr; dbrcnt_init(ch->addr, ch->dbr_size); - dimcb_io_write(&g.dim2->MIEN, bit_mask(20)); + writel(bit_mask(20), &g.dim2->MIEN); } return ret; @@ -896,7 +889,7 @@ u8 dim_destroy_channel(struct dim_channel *ch) return DIM_ERR_DRIVER_NOT_INITIALIZED; if (ch->addr == g.atx_dbr.ch_addr) { - dimcb_io_write(&g.dim2->MIEN, 0); + writel(0, &g.dim2->MIEN); g.atx_dbr.ch_addr = 0; } diff --git a/drivers/staging/most/dim2/hal.h b/drivers/staging/most/dim2/hal.h index fca6c22de8a6..20531449acab 100644 --- a/drivers/staging/most/dim2/hal.h +++ b/drivers/staging/most/dim2/hal.h @@ -97,10 +97,6 @@ bool dim_enqueue_buffer(struct dim_channel *ch, u32 buffer_addr, bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number); -u32 dimcb_io_read(u32 __iomem *ptr32); - -void dimcb_io_write(u32 __iomem *ptr32, u32 value); - void dimcb_on_error(u8 error_id, const char *error_message); #endif /* _DIM2_HAL_H */ diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile index 2b3769dc19e7..71099dd0f85b 100644 --- a/drivers/staging/most/i2c/Makefile +++ b/drivers/staging/most/i2c/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_I2C) += most_i2c.o most_i2c-objs := i2c.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c index 4a4fc1005932..2980f7065846 100644 --- a/drivers/staging/most/i2c/i2c.c +++ b/drivers/staging/most/i2c/i2c.c @@ -14,7 +14,7 @@ #include <linux/interrupt.h> #include <linux/err.h> -#include "most/core.h" +#include "../most.h" enum { CH_RX, CH_TX, NUM_CHANNELS }; diff --git a/drivers/staging/most/core.h b/drivers/staging/most/most.h index 652aaa771029..232e01b7f5d2 100644 --- a/drivers/staging/most/core.h +++ b/drivers/staging/most/most.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * most.h - API for component and adapter drivers * @@ -47,7 +47,7 @@ enum most_channel_data_type { MOST_CH_SYNC = 1 << 5, }; -enum mbo_status_flags { +enum most_status_flags { /* MBO was processed successfully (data was send or received )*/ MBO_SUCCESS = 0, /* The MBO contains wrong or missing information. */ @@ -184,7 +184,7 @@ struct mbo { dma_addr_t bus_address; u16 buffer_length; u16 processed_length; - enum mbo_status_flags status; + enum most_status_flags status; void (*complete)(struct mbo *mbo); }; @@ -229,7 +229,7 @@ struct mbo { * @priv Private field used by mostcore to store context information. */ struct most_interface { - struct device dev; + struct device *dev; struct device *driver_dev; struct module *mod; enum most_interface_type interface; @@ -251,10 +251,8 @@ struct most_interface { struct interface_private *p; }; -#define to_most_interface(d) container_of(d, struct most_interface, dev) - /** - * struct core_component - identifies a loadable component for the mostcore + * struct most_component - identifies a loadable component for the mostcore * @list: list_head * @name: component name * @probe_channel: function for core to notify driver about channel connection @@ -262,9 +260,10 @@ struct most_interface { * @rx_completion: completion handler for received packets * @tx_completion: completion handler for transmitted packets */ -struct core_component { +struct most_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); @@ -309,20 +308,20 @@ void most_stop_enqueue(struct most_interface *iface, int channel_idx); * in wait fifo. */ void most_resume_enqueue(struct most_interface *iface, int channel_idx); -int most_register_component(struct core_component *comp); -int most_deregister_component(struct core_component *comp); +int most_register_component(struct most_component *comp); +int most_deregister_component(struct most_component *comp); struct mbo *most_get_mbo(struct most_interface *iface, int channel_idx, - struct core_component *comp); + struct most_component *comp); void most_put_mbo(struct mbo *mbo); int channel_has_mbo(struct most_interface *iface, int channel_idx, - struct core_component *comp); + struct most_component *comp); int most_start_channel(struct most_interface *iface, int channel_idx, - struct core_component *comp); + struct most_component *comp); int most_stop_channel(struct most_interface *iface, int channel_idx, - struct core_component *comp); + struct most_component *comp); int __init configfs_init(void); -int most_register_configfs_subsys(struct core_component *comp); -void most_deregister_configfs_subsys(struct core_component *comp); +int most_register_configfs_subsys(struct most_component *comp); +void most_deregister_configfs_subsys(struct most_component *comp); int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name, char *comp_param); int most_remove_link(char *mdev, char *mdev_ch, char *comp_name); diff --git a/drivers/staging/most/net/Makefile b/drivers/staging/most/net/Makefile index f0ac64dee71b..1582c97eb204 100644 --- a/drivers/staging/most/net/Makefile +++ b/drivers/staging/most/net/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_NET) += most_net.o most_net-objs := net.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/net/net.c b/drivers/staging/most/net/net.c index aababdf2be12..5547e36e09de 100644 --- a/drivers/staging/most/net/net.c +++ b/drivers/staging/most/net/net.c @@ -15,7 +15,8 @@ #include <linux/list.h> #include <linux/wait.h> #include <linux/kobject.h> -#include "most/core.h" + +#include "../most.h" #define MEP_HDR_LEN 8 #define MDP_HDR_LEN 16 @@ -69,8 +70,8 @@ struct net_dev_context { static struct list_head net_devices = LIST_HEAD_INIT(net_devices); static struct mutex probe_disc_mt; /* ch->linked = true, most_nd_open */ -static struct spinlock list_lock; /* list_head, ch->linked = false, dev_hold */ -static struct core_component comp; +static DEFINE_SPINLOCK(list_lock); /* list_head, ch->linked = false, dev_hold */ +static struct most_component comp; static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo) { @@ -81,6 +82,11 @@ static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo) unsigned int payload_len = skb->len - ETH_HLEN; unsigned int mdp_len = payload_len + MDP_HDR_LEN; + if (mdp_len < skb->len) { + pr_err("drop: too large packet! (%u)\n", skb->len); + return -EINVAL; + } + if (mbo->buffer_length < mdp_len) { pr_err("drop: too small buffer! (%d for %d)\n", mbo->buffer_length, mdp_len); @@ -128,6 +134,11 @@ static int skb_to_mep(const struct sk_buff *skb, struct mbo *mbo) u8 *buff = mbo->virt_address; unsigned int mep_len = skb->len + MEP_HDR_LEN; + if (mep_len < skb->len) { + pr_err("drop: too large packet! (%u)\n", skb->len); + return -EINVAL; + } + if (mbo->buffer_length < mep_len) { pr_err("drop: too small buffer! (%d for %d)\n", mbo->buffer_length, mep_len); @@ -497,7 +508,8 @@ put_nd: return ret; } -static struct core_component comp = { +static struct most_component comp = { + .mod = THIS_MODULE, .name = "net", .probe_channel = comp_probe_channel, .disconnect_channel = comp_disconnect_channel, @@ -509,7 +521,6 @@ static int __init most_net_init(void) { int err; - spin_lock_init(&list_lock); mutex_init(&probe_disc_mt); err = most_register_component(&comp); if (err) diff --git a/drivers/staging/most/sound/Makefile b/drivers/staging/most/sound/Makefile index a3d086c6ca70..f0cd9d8d213e 100644 --- a/drivers/staging/most/sound/Makefile +++ b/drivers/staging/most/sound/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_SOUND) += most_sound.o most_sound-objs := sound.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c index 342f390d68b3..44cf2334834f 100644 --- a/drivers/staging/most/sound/sound.c +++ b/drivers/staging/most/sound/sound.c @@ -17,12 +17,13 @@ #include <sound/pcm_params.h> #include <linux/sched.h> #include <linux/kthread.h> -#include <most/core.h> + +#include "../most.h" #define DRIVER_NAME "sound" #define STRING_SIZE 80 -static struct core_component comp; +static struct most_component comp; /** * struct channel - private structure to keep channel specific data @@ -323,46 +324,6 @@ static int pcm_close(struct snd_pcm_substream *substream) } /** - * pcm_hw_params - implements hw_params callback function for PCM middle layer - * @substream: sub-stream pointer - * @hw_params: contains the hardware parameters set by the application - * - * This is called when the hardware parameters is set by the application, that - * is, once when the buffer size, the period size, the format, etc. are defined - * for the PCM substream. Many hardware setups should be done is this callback, - * including the allocation of buffers. - * - * Returns 0 on success or error code otherwise. - */ -static int pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct channel *channel = substream->private_data; - - if ((params_channels(hw_params) > channel->pcm_hardware.channels_max) || - (params_channels(hw_params) < channel->pcm_hardware.channels_min)) { - pr_err("Requested number of channels not supported.\n"); - return -EINVAL; - } - return snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); -} - -/** - * pcm_hw_free - implements hw_free callback function for PCM middle layer - * @substream: substream pointer - * - * This is called to release the resources allocated via hw_params. - * This function will be always called before the close callback is called. - * - * Returns 0 on success or error code otherwise. - */ -static int pcm_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_vmalloc_buffer(substream); -} - -/** * pcm_prepare - implements prepare callback function for PCM middle layer * @substream: substream pointer * @@ -463,13 +424,9 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) static const struct snd_pcm_ops pcm_ops = { .open = pcm_open, .close = pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pcm_hw_params, - .hw_free = pcm_hw_free, .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 +620,7 @@ 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_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); return 0; @@ -779,9 +737,10 @@ static int audio_tx_completion(struct most_interface *iface, int channel_id) } /** - * Initialization of the struct core_component + * Initialization of the struct most_component */ -static struct core_component comp = { +static struct most_component comp = { + .mod = THIS_MODULE, .name = DRIVER_NAME, .probe_channel = audio_probe_channel, .disconnect_channel = audio_disconnect_channel, @@ -802,8 +761,11 @@ static int __init audio_init(void) if (ret) pr_err("Failed to register %s\n", comp.name); ret = most_register_configfs_subsys(&comp); - if (ret) + if (ret) { pr_err("Failed to register %s configfs subsys\n", comp.name); + most_deregister_component(&comp); + } + return ret; } diff --git a/drivers/staging/most/usb/Makefile b/drivers/staging/most/usb/Makefile index 83cf2ead7122..c2b207339aec 100644 --- a/drivers/staging/most/usb/Makefile +++ b/drivers/staging/most/usb/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_USB) += most_usb.o most_usb-objs := usb.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/usb/usb.c b/drivers/staging/most/usb/usb.c index 360cb5b7a10b..0bda88c4bc89 100644 --- a/drivers/staging/most/usb/usb.c +++ b/drivers/staging/most/usb/usb.c @@ -23,7 +23,8 @@ #include <linux/dma-mapping.h> #include <linux/etherdevice.h> #include <linux/uaccess.h> -#include "most/core.h" + +#include "../most.h" #define USB_MTU 512 #define NO_ISOCHRONOUS_URB 0 @@ -101,6 +102,7 @@ struct clear_hold_work { * @poll_work_obj: work for polling link status */ struct most_dev { + struct device dev; struct usb_device *usb_device; struct most_interface iface; struct most_channel_capability *cap; @@ -122,6 +124,7 @@ struct most_dev { }; #define to_mdev(d) container_of(d, struct most_dev, iface) +#define to_mdev_from_dev(d) container_of(d, struct most_dev, dev) #define to_mdev_from_work(w) container_of(w, struct most_dev, poll_work_obj) static void wq_clear_halt(struct work_struct *wq_obj); @@ -1022,6 +1025,12 @@ static void release_dci(struct device *dev) kfree(dci); } +static void release_mdev(struct device *dev) +{ + struct most_dev *mdev = to_mdev_from_dev(dev); + + kfree(mdev); +} /** * hdm_probe - probe function of USB device driver * @interface: Interface of the attached USB device @@ -1060,6 +1069,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) mdev->link_stat_timer.expires = jiffies + (2 * HZ); mdev->iface.mod = hdm_usb_fops.owner; + mdev->iface.dev = &mdev->dev; mdev->iface.driver_dev = &interface->dev; mdev->iface.interface = ITYPE_USB; mdev->iface.configure = hdm_configure_channel; @@ -1078,6 +1088,9 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) usb_dev->config->desc.bConfigurationValue, usb_iface_desc->desc.bInterfaceNumber); + mdev->dev.init_name = mdev->description; + mdev->dev.parent = &interface->dev; + mdev->dev.release = release_mdev; mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL); if (!mdev->conf) goto err_free_mdev; @@ -1151,7 +1164,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) } mdev->dci->dev.init_name = "dci"; - mdev->dci->dev.parent = &mdev->iface.dev; + mdev->dci->dev.parent = get_device(mdev->iface.dev); mdev->dci->dev.groups = dci_attr_groups; mdev->dci->dev.release = release_dci; if (device_register(&mdev->dci->dev)) { @@ -1165,7 +1178,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) mutex_unlock(&mdev->io_mutex); return 0; err_free_dci: - kfree(mdev->dci); + put_device(&mdev->dci->dev); err_free_busy_urbs: kfree(mdev->busy_urbs); err_free_ep_address: @@ -1175,7 +1188,7 @@ err_free_cap: err_free_conf: kfree(mdev->conf); err_free_mdev: - kfree(mdev); + put_device(&mdev->dev); err_out_of_memory: if (ret == 0 || ret == -ENOMEM) { ret = -ENOMEM; @@ -1205,14 +1218,15 @@ static void hdm_disconnect(struct usb_interface *interface) del_timer_sync(&mdev->link_stat_timer); cancel_work_sync(&mdev->poll_work_obj); - device_unregister(&mdev->dci->dev); + if (mdev->dci) + device_unregister(&mdev->dci->dev); most_deregister_interface(&mdev->iface); kfree(mdev->busy_urbs); kfree(mdev->cap); kfree(mdev->conf); kfree(mdev->ep_address); - kfree(mdev); + put_device(&mdev->dev); } static struct usb_driver hdm_usb = { diff --git a/drivers/staging/most/video/Makefile b/drivers/staging/most/video/Makefile index 2d857d3cbcc8..856175fec8b6 100644 --- a/drivers/staging/most/video/Makefile +++ b/drivers/staging/most/video/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_MOST_VIDEO) += most_video.o most_video-objs := video.o -ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c index 6f6e98ab0550..d32ae49d617b 100644 --- a/drivers/staging/most/video/video.c +++ b/drivers/staging/most/video/video.c @@ -21,11 +21,11 @@ #include <media/v4l2-ctrls.h> #include <media/v4l2-fh.h> -#include "most/core.h" +#include "../most.h" #define V4L2_CMP_MAX_INPUT 1 -static struct core_component comp; +static struct most_component comp; struct most_video_dev { struct most_interface *iface; @@ -54,7 +54,7 @@ struct comp_fh { }; static struct list_head video_devices = LIST_HEAD_INIT(video_devices); -static struct spinlock list_lock; +static DEFINE_SPINLOCK(list_lock); static inline bool data_ready(struct most_video_dev *mdev) { @@ -527,7 +527,8 @@ static int comp_disconnect_channel(struct most_interface *iface, return 0; } -static struct core_component comp = { +static struct most_component comp = { + .mod = THIS_MODULE, .name = "video", .probe_channel = comp_probe_channel, .disconnect_channel = comp_disconnect_channel, @@ -538,7 +539,6 @@ static int __init comp_init(void) { int err; - spin_lock_init(&list_lock); err = most_register_component(&comp); if (err) return err; |