Commit 74a5d93c authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

greybus: hd: move CPort allocation to host-device code



Move host-device CPort allocation to the host-device code.

Proper CPort allocation requires knowledge of the hardware and must be
handled by the host-device driver. This is an intermediate step that
moves the generic CPort-allocation code to the host-device code.

Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Reviewed-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent a8af1631
Loading
Loading
Loading
Loading
+8 −22
Original line number Diff line number Diff line
@@ -142,21 +142,8 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
				unsigned long flags)
{
	struct gb_connection *connection;
	struct ida *id_map = &hd->cport_id_map;
	int ida_start, ida_end;
	int ret;

	if (hd_cport_id < 0) {
		ida_start = 0;
		ida_end = hd->num_cports;
	} else if (hd_cport_id < hd->num_cports) {
		ida_start = hd_cport_id;
		ida_end = hd_cport_id + 1;
	} else {
		dev_err(&hd->dev, "cport %d not available\n", hd_cport_id);
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&gb_connection_mutex);

	if (intf && gb_connection_intf_find(intf, cport_id)) {
@@ -165,15 +152,17 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
		goto err_unlock;
	}

	ret = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
	if (ret < 0)
	ret = gb_hd_cport_allocate(hd, hd_cport_id);
	if (ret < 0) {
		dev_err(&hd->dev, "failed to allocate cport: %d\n", ret);
		goto err_unlock;
	}
	hd_cport_id = ret;

	connection = kzalloc(sizeof(*connection), GFP_KERNEL);
	if (!connection) {
		ret = -ENOMEM;
		goto err_remove_ida;
		goto err_hd_cport_release;
	}

	connection->hd_cport_id = hd_cport_id;
@@ -219,8 +208,8 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,

err_free_connection:
	kfree(connection);
err_remove_ida:
	ida_simple_remove(id_map, hd_cport_id);
err_hd_cport_release:
	gb_hd_cport_release(hd, hd_cport_id);
err_unlock:
	mutex_unlock(&gb_connection_mutex);

@@ -658,8 +647,6 @@ EXPORT_SYMBOL_GPL(gb_connection_disable);
/* Caller must have disabled the connection before destroying it. */
void gb_connection_destroy(struct gb_connection *connection)
{
	struct ida *id_map;

	if (!connection)
		return;

@@ -672,8 +659,7 @@ void gb_connection_destroy(struct gb_connection *connection)

	destroy_workqueue(connection->wq);

	id_map = &connection->hd->cport_id_map;
	ida_simple_remove(id_map, connection->hd_cport_id);
	gb_hd_cport_release(connection->hd, connection->hd_cport_id);
	connection->hd_cport_id = CPORT_ID_BAD;

	mutex_unlock(&gb_connection_mutex);
+26 −0
Original line number Diff line number Diff line
@@ -39,6 +39,32 @@ static struct attribute *bus_attrs[] = {
};
ATTRIBUTE_GROUPS(bus);

/* Locking: Caller guarantees serialisation */
int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id)
{
	struct ida *id_map = &hd->cport_id_map;
	int ida_start, ida_end;

	if (cport_id < 0) {
		ida_start = 0;
		ida_end = hd->num_cports;
	} else if (cport_id < hd->num_cports) {
		ida_start = cport_id;
		ida_end = cport_id + 1;
	} else {
		dev_err(&hd->dev, "cport %d not available\n", cport_id);
		return -EINVAL;
	}

	return ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
}

/* Locking: Caller guarantees serialisation */
void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id)
{
	ida_simple_remove(&hd->cport_id_map, cport_id);
}

static void gb_hd_release(struct device *dev)
{
	struct gb_host_device *hd = to_gb_host_device(dev);
+3 −0
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ struct gb_host_device {
};
#define to_gb_host_device(d) container_of(d, struct gb_host_device, dev)

int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id);
void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id);

struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
					struct device *parent,
					size_t buffer_size_max,