Commit 9a9f5129 authored by Alex Elder's avatar Alex Elder Committed by David S. Miller
Browse files

net: ipa: use a bitmap for defined endpoints



IPA v5.0 supports more than 32 endpoints, so we will be unable to
represent endpoints defined in the configuration data with a 32-bit
value.  To prepare for that, convert the field in the IPA structure
representing defined endpoints to be a Linux bitmap.

Convert loops based on that field into for_each_set_bit() calls over
the new bitmap.  Note that the loop in ipa_endpoint_config() still
assumes there are 32 or fewer endpoints (when comparing against the
available endpoint bit mask); that assumption goes away in the next
patch.

Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f298ba78
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ struct ipa_interrupt;
 * @zero_virt:		Virtual address of preallocated zero-filled memory
 * @zero_size:		Size (bytes) of preallocated zero-filled memory
 * @endpoint_count:	Number of endpoints represented by bit masks below
 * @defined:		Bit mask indicating endpoints defined in config data
 * @defined:		Bitmap of endpoints defined in config data
 * @available:		Bit mask indicating endpoints hardware supports
 * @filter_map:		Bit mask indicating endpoints that support filtering
 * @set_up:		Bit mask indicating endpoints set up
@@ -117,9 +117,9 @@ struct ipa {
	void *zero_virt;
	size_t zero_size;

	/* Bit masks indicating endpoint state */
	/* Bitmaps indicating endpoint state */
	u32 endpoint_count;
	u32 defined;			/* Defined in configuration data */
	unsigned long *defined;		/* Defined in configuration data */
	u32 available;			/* Supported by hardware */
	u32 filter_map;
	u32 set_up;
+17 −27
Original line number Diff line number Diff line
@@ -459,8 +459,8 @@ void ipa_endpoint_modem_pause_all(struct ipa *ipa, bool enable)
/* Reset all modem endpoints to use the default exception endpoint */
int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
{
	u32 defined = ipa->defined;
	struct gsi_trans *trans;
	u32 endpoint_id;
	u32 count;

	/* We need one command per modem TX endpoint, plus the commands
@@ -474,14 +474,11 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
		return -EBUSY;
	}

	while (defined) {
		u32 endpoint_id = __ffs(defined);
	for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count) {
		struct ipa_endpoint *endpoint;
		const struct ipa_reg *reg;
		u32 offset;

		defined ^= BIT(endpoint_id);

		/* We only reset modem TX endpoints */
		endpoint = &ipa->endpoint[endpoint_id];
		if (!(endpoint->ee_id == GSI_EE_MODEM && endpoint->toward_ipa))
@@ -1823,17 +1820,12 @@ static void ipa_endpoint_teardown_one(struct ipa_endpoint *endpoint)

void ipa_endpoint_setup(struct ipa *ipa)
{
	u32 defined = ipa->defined;
	u32 endpoint_id;

	ipa->set_up = 0;
	while (defined) {
		u32 endpoint_id = __ffs(defined);

		defined ^= BIT(endpoint_id);

	for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count)
		ipa_endpoint_setup_one(&ipa->endpoint[endpoint_id]);
}
}

void ipa_endpoint_teardown(struct ipa *ipa)
{
@@ -1853,10 +1845,10 @@ int ipa_endpoint_config(struct ipa *ipa)
{
	struct device *dev = &ipa->pdev->dev;
	const struct ipa_reg *reg;
	u32 endpoint_id;
	u32 tx_count;
	u32 rx_count;
	u32 rx_base;
	u32 defined;
	u32 limit;
	u32 val;

@@ -1896,13 +1888,9 @@ int ipa_endpoint_config(struct ipa *ipa)
	/* Mark all supported RX and TX endpoints as available */
	ipa->available = GENMASK(limit - 1, rx_base) | GENMASK(tx_count - 1, 0);

	defined = ipa->defined;
	while (defined) {
		u32 endpoint_id = __ffs(defined);
	for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count) {
		struct ipa_endpoint *endpoint;

		defined ^= BIT(endpoint_id);

		if (endpoint_id >= limit) {
			dev_err(dev, "invalid endpoint id, %u > %u\n",
				endpoint_id, limit - 1);
@@ -1954,27 +1942,26 @@ static void ipa_endpoint_init_one(struct ipa *ipa, enum ipa_endpoint_name name,
	endpoint->toward_ipa = data->toward_ipa;
	endpoint->config = data->endpoint.config;

	ipa->defined |= BIT(endpoint->endpoint_id);
	__set_bit(endpoint->endpoint_id, ipa->defined);
}

static void ipa_endpoint_exit_one(struct ipa_endpoint *endpoint)
{
	endpoint->ipa->defined &= ~BIT(endpoint->endpoint_id);
	__clear_bit(endpoint->endpoint_id, endpoint->ipa->defined);

	memset(endpoint, 0, sizeof(*endpoint));
}

void ipa_endpoint_exit(struct ipa *ipa)
{
	u32 defined = ipa->defined;
	u32 endpoint_id;

	while (defined) {
		u32 endpoint_id = __fls(defined);
	for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count)
		ipa_endpoint_exit_one(&ipa->endpoint[endpoint_id]);

		defined ^= BIT(endpoint_id);
	bitmap_free(ipa->defined);
	ipa->defined = NULL;

		ipa_endpoint_exit_one(&ipa->endpoint[endpoint_id]);
	}
	memset(ipa->name_map, 0, sizeof(ipa->name_map));
	memset(ipa->channel_map, 0, sizeof(ipa->channel_map));
}
@@ -1993,7 +1980,10 @@ u32 ipa_endpoint_init(struct ipa *ipa, u32 count,
	if (!ipa->endpoint_count)
		return 0;	/* Error */

	ipa->defined = 0;
	/* Initialize the defined endpoint bitmap */
	ipa->defined = bitmap_zalloc(ipa->endpoint_count, GFP_KERNEL);
	if (!ipa->defined)
		return 0;	/* Error */

	filter_map = 0;
	for (name = 0; name < count; name++, data++) {