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);
}
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:
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) {
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) {
PAGE_SIZE - offs,
"%s:%s:%s\n",
c->pipe1.comp->name,
- dev_name(&iface->dev),
+ dev_name(iface->dev),
dev_name(&c->dev));
}
}
dev = bus_find_device_by_name(&mc.bus, NULL, mdev);
if (!dev)
return NULL;
- iface = to_most_interface(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;
struct most_channel *c, *tmp;
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);
}
EXPORT_SYMBOL_GPL(most_deregister_component);
-static void release_interface(struct device *dev)
-{
- dev_info(&mc.dev, "releasing interface dev %s...\n", dev_name(dev));
-}
-
static void release_channel(struct device *dev)
{
- dev_info(&mc.dev, "releasing channel dev %s...\n", dev_name(dev));
+ struct most_channel *c = to_channel(dev);
+
+ kfree(c);
}
/**
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)) {
+ iface->dev->bus = &mc.bus;
+ iface->dev->parent = &mc.dev;
+ iface->dev->groups = interface_attr_groups;
+ dev_set_drvdata(iface->dev, iface);
+ if (device_register(iface->dev)) {
dev_err(&mc.dev, "registering iface->dev failed\n");
kfree(iface->p);
+ put_device(iface->dev);
ida_simple_remove(&mdev_id, id);
return -ENOMEM;
}
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;
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;
}
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);
* @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;
};
#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);
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
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;
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;
}
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)) {
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:
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;
kfree(mdev->cap);
kfree(mdev->conf);
kfree(mdev->ep_address);
- kfree(mdev);
+ put_device(&mdev->dev);
}
static struct usb_driver hdm_usb = {