Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0a4f6f8 authored by Ajay Agarwal's avatar Ajay Agarwal Committed by Hemant Kumar
Browse files

usb: gadget: Bind android devices for all UDC gadgets



For targets with multiple UDCs having DRD feature, two UDCs
may be in peripheral mode. In that case, create and bind
android device corresponding to each gadget as and when
mkdir gadget is run. Keep global structure android_device as
android0 (or g1's device) for ease of use by f_midi and
f_audio_source.

Change-Id: Idae6f6d0d8811f27e836f5f6399395a15fbf3c2f
Signed-off-by: default avatarAjay Agarwal <ajaya@codeaurora.org>
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 55c3d32b
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ void acc_disconnect(void);
static struct class *android_class;
static struct device *android_device;
static int index;
static int gadget_index;

struct device *create_function_device(char *name)
{
@@ -1441,21 +1442,21 @@ static void android_work(struct work_struct *data)
	spin_unlock_irqrestore(&cdev->lock, flags);

	if (status[0]) {
		kobject_uevent_env(&android_device->kobj,
		kobject_uevent_env(&gi->dev->kobj,
					KOBJ_CHANGE, connected);
		pr_info("%s: sent uevent %s\n", __func__, connected[0]);
		uevent_sent = true;
	}

	if (status[1]) {
		kobject_uevent_env(&android_device->kobj,
		kobject_uevent_env(&gi->dev->kobj,
					KOBJ_CHANGE, configured);
		pr_info("%s: sent uevent %s\n", __func__, configured[0]);
		uevent_sent = true;
	}

	if (status[2]) {
		kobject_uevent_env(&android_device->kobj,
		kobject_uevent_env(&gi->dev->kobj,
					KOBJ_CHANGE, disconnected);
		pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
		uevent_sent = true;
@@ -1635,21 +1636,25 @@ static int android_device_create(struct gadget_info *gi)
	struct device_attribute *attr;

	INIT_WORK(&gi->work, android_work);
	android_device = device_create(android_class, NULL,
				MKDEV(0, 0), NULL, "android0");
	if (IS_ERR(android_device))
		return PTR_ERR(android_device);
	gi->dev = device_create(android_class, NULL,
			MKDEV(0, 0), NULL, "android%d", gadget_index++);
	if (IS_ERR(gi->dev))
		return PTR_ERR(gi->dev);

	dev_set_drvdata(android_device, gi);
	pr_debug("Creating gadget index %d\n", gadget_index);

	dev_set_drvdata(gi->dev, gi);
	if (!android_device)
		android_device = gi->dev;

	attrs = android_usb_attributes;
	while ((attr = *attrs++)) {
		int err;

		err = device_create_file(android_device, attr);
		err = device_create_file(gi->dev, attr);
		if (err) {
			device_destroy(android_device->class,
				       android_device->devt);
			device_destroy(gi->dev->class,
				       gi->dev->devt);
			return err;
		}
	}
@@ -1657,15 +1662,15 @@ static int android_device_create(struct gadget_info *gi)
	return 0;
}

static void android_device_destroy(void)
static void android_device_destroy(struct device *dev)
{
	struct device_attribute **attrs;
	struct device_attribute *attr;

	attrs = android_usb_attributes;
	while ((attr = *attrs++))
		device_remove_file(android_device, attr);
	device_destroy(android_device->class, android_device->devt);
		device_remove_file(dev, attr);
	device_destroy(dev->class, dev->devt);
}
#else
static inline int android_device_create(struct gadget_info *gi)
@@ -1673,7 +1678,7 @@ static inline int android_device_create(struct gadget_info *gi)
	return 0;
}

static inline void android_device_destroy(void)
static inline void android_device_destroy(struct device *dev)
{
}
#endif
@@ -1741,8 +1746,14 @@ static struct config_group *gadgets_make(

static void gadgets_drop(struct config_group *group, struct config_item *item)
{
	struct gadget_info *gi;

	gi = container_of(to_config_group(item), struct gadget_info, group);
	config_item_put(item);
	android_device_destroy();
	if (gi->dev) {
		android_device_destroy(gi->dev);
		gi->dev = NULL;
	}
}

static struct configfs_group_operations gadgets_ops = {