diff options
Diffstat (limited to 'drivers/staging/most/core.c')
-rw-r--r-- | drivers/staging/most/core.c | 204 |
1 files changed, 86 insertions, 118 deletions
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 51a6b41d5b82..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; }; @@ -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"); } /** @@ -402,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); } @@ -411,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: @@ -454,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; } @@ -476,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) { @@ -484,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) { @@ -492,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)); } } @@ -500,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); } @@ -531,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; @@ -544,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; @@ -623,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; } @@ -642,7 +648,7 @@ int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf) } 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; @@ -660,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) @@ -673,7 +679,7 @@ 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; @@ -684,7 +690,7 @@ int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name, 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) @@ -722,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) { @@ -795,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; @@ -922,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); @@ -941,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 @@ -950,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; @@ -981,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; @@ -1087,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; @@ -1101,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; } @@ -1157,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; @@ -1182,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; } @@ -1192,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; } @@ -1215,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); @@ -1231,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); @@ -1249,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); } /** @@ -1288,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; } @@ -1307,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; } @@ -1330,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; @@ -1356,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; } @@ -1393,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) @@ -1407,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); @@ -1462,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); } |