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

Commit f73dc4f6 authored by Niranjana Vishwanathapura's avatar Niranjana Vishwanathapura
Browse files

msm: emac: Add MDC/MDIO gpio resource handling



Update code to ensure exclusive access to MDC/MDIO gpio resources
when the ethernet interface is up.

Change-Id: I72af79ea3703e2dbd5b011a4c33632fd837a6c57
Signed-off-by: default avatarNiranjana Vishwanathapura <nvishwan@codeaurora.org>
parent 90bc70e2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@
/* 4 emac core irqs */
#define EMAC_NUM_CORE_IRQ     4

/* mdio/mdc gpios */
#define EMAC_NUM_GPIO         2

#define EMAC_LINK_SPEED_UNKNOWN         0x0
#define EMAC_LINK_SPEED_10_HALF         0x0001
#define EMAC_LINK_SPEED_10_FULL         0x0002
@@ -465,6 +468,11 @@ struct emac_irq_info {
	struct emac_adapter  *adpt;
};

struct emac_gpio_info {
	unsigned int gpio;
	char *name;
};

/* emac_ring_header represents a single, contiguous block of DMA space
 * mapped for the three descriptor rings (tpd, rfd, rrd)
 */
@@ -569,6 +577,7 @@ struct emac_adapter {
	struct net_device *netdev;

	struct emac_irq_info  irq_info[EMAC_NUM_CORE_IRQ];
	struct emac_gpio_info gpio_info[EMAC_NUM_GPIO];

	/* dma parameters */
	u64                             dma_mask;
+25 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
/* MSM EMAC Ethernet Controller driver.
 */

#include <linux/gpio.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
@@ -72,6 +73,11 @@ static struct emac_irq_info emac_irq[EMAC_NUM_CORE_IRQ] = {
	  EMAC_INT3_MASK, 0, NULL, NULL },
};

static struct emac_gpio_info emac_gpio[EMAC_NUM_GPIO] = {
	{ 0, "qcom,emac-gpio-mdc" },
	{ 0, "qcom,emac-gpio-mdio" },
};

/* reinitialize */
void emac_reinit_locked(struct emac_adapter *adpt)
{
@@ -1369,6 +1375,18 @@ static int emac_up(struct emac_adapter *adpt)
	for (i = 0; i < adpt->num_rxques; i++)
		emac_refresh_rx_buffer(&adpt->rx_queue[i]);

	for (i = 0; i < EMAC_NUM_GPIO; i++) {
		struct emac_gpio_info *gpio_info = &adpt->gpio_info[i];
		retval = gpio_request(gpio_info->gpio, gpio_info->name);
		if (retval) {
			emac_err(adpt, "failed to request gpio %s: %d\n",
				 gpio_info->name, retval);
			while (--i >= 0)
				gpio_free(adpt->gpio_info[i].gpio);
			goto err_request_gpio;
		}
	}

	for (i = 0; i < EMAC_NUM_CORE_IRQ; i++) {
		struct emac_irq_info *irq_info = &adpt->irq_info[i];
		retval = request_irq(irq_info->irq, irq_info->handler,
@@ -1397,6 +1415,9 @@ static int emac_up(struct emac_adapter *adpt)
	return retval;

err_request_irq:
	for (i = 0; i < EMAC_NUM_GPIO; i++)
		gpio_free(adpt->gpio_info[i].gpio);
err_request_gpio:
	emac_clean_all_rx_queues(adpt);
	return retval;
}
@@ -1418,6 +1439,9 @@ static void emac_down(struct emac_adapter *adpt, u32 ctrl)
	for (i = 0; i < EMAC_NUM_CORE_IRQ; i++)
		free_irq(adpt->irq_info[i].irq, &adpt->irq_info[i]);

	for (i = 0; i < EMAC_NUM_GPIO; i++)
		gpio_free(adpt->gpio_info[i].gpio);

	CLI_ADPT_FLAG(TASK_LSC_REQ);
	CLI_ADPT_FLAG(TASK_REINIT_REQ);
	del_timer_sync(&adpt->emac_timer);
@@ -2156,6 +2180,7 @@ static int emac_probe(struct platform_device *pdev)
	dma_set_max_seg_size(&pdev->dev, 65536);
	dma_set_seg_boundary(&pdev->dev, 0xffffffff);

	memcpy(adpt->gpio_info, emac_gpio, sizeof(adpt->gpio_info));
	memcpy(adpt->irq_info, emac_irq, sizeof(adpt->irq_info));
	for (i = 0; i < EMAC_NUM_CORE_IRQ; i++) {
		adpt->irq_info[i].adpt = adpt;