summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/f_acm.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-05 15:18:00 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-05 15:18:00 -0700
commit64dc9e2e7320f079b97c46b106133b58b8e18d40 (patch)
treeab010dc1337d44e29c2b32b7f11788620a91fe4f /drivers/usb/gadget/f_acm.c
parent01a60e76b6392547ad3dca3ac05b9c886fa5da45 (diff)
parent9b192de60b5a584ee4ed967fb6758773c75e4643 (diff)
downloadolio-linux-3.10-64dc9e2e7320f079b97c46b106133b58b8e18d40.tar.xz
olio-linux-3.10-64dc9e2e7320f079b97c46b106133b58b8e18d40.zip
Merge tag 'usb-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v3.10 merge window Here is the big Gadget & PHY pull request. Many of us have been really busy lately getting multiple drivers to a better position. Since this pull request is so large, I will divide it in sections so it's easier to grasp what's included. - cleanups: . UDC drivers no longer touch gadget->dev, that's now udc-core responsibility . Many more UDC drivers converted to usb_gadget_map/unmap_request() . UDC drivers no longer initialize DMA-related fields from gadget's device structure . UDC drivers don't touch gadget.dev.driver directly . UDC drivers don't assign gadget.dev.release directly . Removal of some unused DMA_ADDR_INVALID . Introduction of CONFIG_USB_PHY . All phy drivers have been moved to drivers/usb/phy and renamed to a common naming scheme . Fix PHY layer so it never returns a NULL pointer, also fix all callers to avoid using IS_ERR_OR_NULL() . Sparse fixes all over the place . drivers/usb/otg/ has been deleted . Marvel drivers (mv_udc, ehci-mv, mv_otg and mv_u3d) improved clock usage - new features: . UDC core now provides a generic way for tracking and reporting UDC's state (not attached, resuming, suspended, addressed, default, etc) . twl4030-usb learned that it shouldn't be enabled during init . Full DT support for DWC3 has been implemented . ab8500-usb learned about pinctrl framework . nop PHY learned about DeviceTree and regulators . DWC3 learned about suspend/resume . DWC3 can now be compiled in host-only and gadget-only (as well as DRD) configurations . UVC now enables streaming endpoint based on negotiated speed . isp1301 now implements the PHY API properly . configfs-based interface for gadget drivers which will lead to the removal of all code which just combines functions together to build functional gadget drivers. . f_serial and f_obex were converted to new configfs interface while maintaining old interface around. - non-critical fixes: . UVC gadget driver got fixes for Endpoint usage and stream calculation . ab8500-usb fixed unbalanced clock and regulator API usage . twl4030-usb got a fix for when OMAP3 is booted with cable connected . fusb300_udc got a fix for DMA usage . UVC got fixes for two assertions of the USB Video Class Compliance specification revision 1.1 . build warning issues caused by recent addition of __must_check to regulator API These are all changes which deserve a mention, all other changes are related to these one or minor spelling fixes and other similar tasks. Signed-of-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/f_acm.c')
-rw-r--r--drivers/usb/gadget/f_acm.c135
1 files changed, 72 insertions, 63 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 1ae180baa59..4b7e33e5d9c 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -715,13 +715,31 @@ fail:
return status;
}
-static struct f_acm *acm_alloc_basic_func(void)
+static void acm_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+ struct f_acm *acm = func_to_acm(f);
+
+ acm_string_defs[0].id = 0;
+ usb_free_all_descriptors(f);
+ if (acm->notify_req)
+ gs_free_req(acm->notify, acm->notify_req);
+}
+
+static void acm_free_func(struct usb_function *f)
+{
+ struct f_acm *acm = func_to_acm(f);
+
+ kfree(acm);
+}
+
+static struct usb_function *acm_alloc_func(struct usb_function_instance *fi)
{
- struct f_acm *acm;
+ struct f_serial_opts *opts;
+ struct f_acm *acm;
acm = kzalloc(sizeof(*acm), GFP_KERNEL);
if (!acm)
- return NULL;
+ return ERR_PTR(-ENOMEM);
spin_lock_init(&acm->lock);
@@ -730,109 +748,100 @@ static struct f_acm *acm_alloc_basic_func(void)
acm->port.send_break = acm_send_break;
acm->port.func.name = "acm";
+ acm->port.func.strings = acm_strings;
/* descriptors are per-instance copies */
acm->port.func.bind = acm_bind;
acm->port.func.set_alt = acm_set_alt;
acm->port.func.setup = acm_setup;
acm->port.func.disable = acm_disable;
- return acm;
+ opts = container_of(fi, struct f_serial_opts, func_inst);
+ acm->port_num = opts->port_num;
+ acm->port.func.unbind = acm_unbind;
+ acm->port.func.free_func = acm_free_func;
+
+ return &acm->port.func;
}
-#ifdef USB_FACM_INCLUDED
-static void
-acm_old_unbind(struct usb_configuration *c, struct usb_function *f)
+static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
{
- struct f_acm *acm = func_to_acm(f);
-
- usb_free_all_descriptors(f);
- if (acm->notify_req)
- gs_free_req(acm->notify, acm->notify_req);
- kfree(acm);
+ return container_of(to_config_group(item), struct f_serial_opts,
+ func_inst.group);
}
-/**
- * acm_bind_config - add a CDC ACM function to a configuration
- * @c: the configuration to support the CDC ACM instance
- * @port_num: /dev/ttyGS* port this interface will use
- * Context: single threaded during gadget setup
- *
- * Returns zero on success, else negative errno.
- *
- */
-int acm_bind_config(struct usb_configuration *c, u8 port_num)
+CONFIGFS_ATTR_STRUCT(f_serial_opts);
+static ssize_t f_acm_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
{
- struct f_acm *acm;
- int status;
-
- /* allocate and initialize one new instance */
- acm = acm_alloc_basic_func();
- if (!acm)
- return -ENOMEM;
+ struct f_serial_opts *opts = to_f_serial_opts(item);
+ struct f_serial_opts_attribute *f_serial_opts_attr =
+ container_of(attr, struct f_serial_opts_attribute, attr);
+ ssize_t ret = 0;
- acm->port_num = port_num;
- acm->port.func.unbind = acm_old_unbind;
-
- status = usb_add_function(c, &acm->port.func);
- if (status)
- kfree(acm);
- return status;
+ if (f_serial_opts_attr->show)
+ ret = f_serial_opts_attr->show(opts, page);
+ return ret;
}
-#else
-
-static void acm_unbind(struct usb_configuration *c, struct usb_function *f)
+static void acm_attr_release(struct config_item *item)
{
- struct f_acm *acm = func_to_acm(f);
+ struct f_serial_opts *opts = to_f_serial_opts(item);
- acm_string_defs[0].id = 0;
- usb_free_all_descriptors(f);
- if (acm->notify_req)
- gs_free_req(acm->notify, acm->notify_req);
+ usb_put_function_instance(&opts->func_inst);
}
-static void acm_free_func(struct usb_function *f)
-{
- struct f_acm *acm = func_to_acm(f);
+static struct configfs_item_operations acm_item_ops = {
+ .release = acm_attr_release,
+ .show_attribute = f_acm_attr_show,
+};
- kfree(acm);
+static ssize_t f_acm_port_num_show(struct f_serial_opts *opts, char *page)
+{
+ return sprintf(page, "%u\n", opts->port_num);
}
-static struct usb_function *acm_alloc_func(struct usb_function_instance *fi)
-{
- struct f_serial_opts *opts;
- struct f_acm *acm;
+static struct f_serial_opts_attribute f_acm_port_num =
+ __CONFIGFS_ATTR_RO(port_num, f_acm_port_num_show);
- acm = acm_alloc_basic_func();
- if (!acm)
- return ERR_PTR(-ENOMEM);
- opts = container_of(fi, struct f_serial_opts, func_inst);
- acm->port_num = opts->port_num;
- acm->port.func.unbind = acm_unbind;
- acm->port.func.free_func = acm_free_func;
+static struct configfs_attribute *acm_attrs[] = {
+ &f_acm_port_num.attr,
+ NULL,
+};
- return &acm->port.func;
-}
+static struct config_item_type acm_func_type = {
+ .ct_item_ops = &acm_item_ops,
+ .ct_attrs = acm_attrs,
+ .ct_owner = THIS_MODULE,
+};
static void acm_free_instance(struct usb_function_instance *fi)
{
struct f_serial_opts *opts;
opts = container_of(fi, struct f_serial_opts, func_inst);
+ gserial_free_line(opts->port_num);
kfree(opts);
}
static struct usb_function_instance *acm_alloc_instance(void)
{
struct f_serial_opts *opts;
+ int ret;
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts)
return ERR_PTR(-ENOMEM);
opts->func_inst.free_func_inst = acm_free_instance;
+ ret = gserial_alloc_line(&opts->port_num);
+ if (ret) {
+ kfree(opts);
+ return ERR_PTR(ret);
+ }
+ config_group_init_type_name(&opts->func_inst.group, "",
+ &acm_func_type);
return &opts->func_inst;
}
DECLARE_USB_FUNCTION_INIT(acm, acm_alloc_instance, acm_alloc_func);
MODULE_LICENSE("GPL");
-#endif