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

Commit 3fa1ec15 authored by Sunil Paidimarri's avatar Sunil Paidimarri Committed by Gerrit - the friendly Code Review server
Browse files

data-kernel: EMAC: Fix completion event for clock enable



Clock enable completion event is used only in intr mode.
Fix the warnings in enable/disable irq for wol.
Add the PHY pm_wakeup_event in interrupt handler.

CRs-Fixed: 2327922
Acked-by: default avatarRahul Kawadgave <rahulak@qti.qualcomm.com>
Signed-off-by: default avatarSunil Paidimarri <hisunil@codeaurora.org>

Change-Id: I0c219c88a392bbf848e41ee6796f38382907510d
parent 5f149b99
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -761,6 +761,9 @@ irqreturn_t DWC_ETH_QOS_PHY_ISR(int irq, void *dev_data)
	struct DWC_ETH_QOS_prv_data *pdata =
		(struct DWC_ETH_QOS_prv_data *)dev_data;

	/* Set a wakeup event to ensure enough time for processing */
	pm_wakeup_event(&pdata->pdev->dev, 5000);

	/* Queue the work in system_wq */
	queue_work(system_wq, &pdata->emac_phy_work);

@@ -6557,8 +6560,6 @@ INT DWC_ETH_QOS_powerdown(struct net_device *dev, UINT wakeup_type,
		hw_if->enable_remote_pmt();
	if (wakeup_type & DWC_ETH_QOS_MAGIC_WAKEUP)
		hw_if->enable_magic_pmt();
	if (wakeup_type & DWC_ETH_QOS_PHY_INTR_WAKEUP)
		enable_irq_wake(pdata->phy_irq);

	pdata->power_down_type = wakeup_type;

@@ -6619,11 +6620,6 @@ INT DWC_ETH_QOS_powerup(struct net_device *dev, UINT caller)
		pdata->power_down_type &= ~DWC_ETH_QOS_REMOTE_WAKEUP;
	}

	if (pdata->power_down_type & DWC_ETH_QOS_PHY_INTR_WAKEUP) {
		disable_irq_wake(pdata->phy_irq);
		pdata->power_down_type &= ~DWC_ETH_QOS_PHY_INTR_WAKEUP;
	}

	pdata->power_down = 0;

	if (pdata->phydev)
+32 −19
Original line number Diff line number Diff line
@@ -808,10 +808,15 @@ static int DWC_ETH_QOS_set_wol(struct net_device *dev,
			       struct ethtool_wolinfo *wol)
{
	struct DWC_ETH_QOS_prv_data *pdata = netdev_priv(dev);
	u32 support = WAKE_MAGIC | WAKE_UCAST | pdata->phy_wol_supported;
	u32 emac_wol_support = 0;
	int ret = 0;

	if (wol->wolopts & ~support)
	if (pdata->hw_feat.mgk_sel == 1)
			emac_wol_support |= WAKE_MAGIC;
	if (pdata->hw_feat.rwk_sel == 1)
			emac_wol_support |= WAKE_UCAST;

	if (wol->wolopts & ~(emac_wol_support | pdata->phy_wol_supported))
		return -EOPNOTSUPP;

	if (!device_can_wakeup(&pdata->pdev->dev))
@@ -825,28 +830,35 @@ static int DWC_ETH_QOS_set_wol(struct net_device *dev,
	 */
	spin_lock_irq(&pdata->lock);

	pdata->wolopts = 0;

	if (pdata->hw_feat.mgk_sel == 1)
		pdata->wolopts |= WAKE_MAGIC;
	if (pdata->hw_feat.rwk_sel == 1)
		pdata->wolopts |= WAKE_UCAST;

	spin_unlock_irq(&pdata->lock);

	if (emac_wol_support && (pdata->wolopts != wol->wolopts)) {
		if (pdata->wolopts)
			enable_irq_wake(pdata->irq_number);
		else
			disable_irq_wake(pdata->irq_number);

	spin_unlock_irq(&pdata->lock);

		device_set_wakeup_enable(&pdata->pdev->dev, pdata->wolopts ? 1 : 0);
	}

	if (pdata->phy_intr_en && pdata->phy_irq && pdata->phy_wol_supported){
	if (pdata->phy_wol_wolopts != wol->wolopts) {
		if (pdata->phy_intr_en && pdata->phy_wol_supported){

			pdata->phy_wol_wolopts = 0;

		if (!phy_ethtool_set_wol(pdata->phydev, wol))
			pdata->phy_wol_wolopts = pdata->phy_wol_supported;
			ret = phy_ethtool_set_wol(pdata->phydev, wol);

			if (ret) {
				EMACERR("set wol in PHY failed\n");
				return ret;
			}

			pdata->phy_wol_wolopts = wol->wolopts;

			if (pdata->phy_wol_wolopts)
				enable_irq_wake(pdata->phy_irq);
@@ -855,6 +867,7 @@ static int DWC_ETH_QOS_set_wol(struct net_device *dev,

			device_set_wakeup_enable(&pdata->pdev->dev, pdata->phy_wol_wolopts ? 1 : 0);
		}
	}

	DBGPR("<--DWC_ETH_QOS_set_wol\n");

+9 −2
Original line number Diff line number Diff line
@@ -1034,6 +1034,9 @@ static void DWC_ETH_QOS_request_phy_wol(struct DWC_ETH_QOS_prv_data *pdata)

			if (!phy_ethtool_set_wol(pdata->phydev, &wol)){
				pdata->phy_wol_wolopts = wol.wolopts;

				enable_irq_wake(pdata->phy_irq);

				device_set_wakeup_enable(&pdata->pdev->dev, 1);
				EMACINFO("Enabled WoL[0x%x] in %s\n", wol.wolopts,
						 pdata->phydev->drv->name);
@@ -1148,7 +1151,7 @@ static int DWC_ETH_QOS_init_phy(struct net_device *dev)
		DWC_ETH_QOS_set_phy_hibernation_mode(pdata, 0);
	}

	if (pdata->phy_intr_en && pdata->phy_irq) {
	if (pdata->phy_intr_en) {

		INIT_WORK(&pdata->emac_phy_work, DWC_ETH_QOS_defer_phy_isr_work);
		init_completion(&pdata->clk_enable_done);
@@ -1164,8 +1167,12 @@ static int DWC_ETH_QOS_init_phy(struct net_device *dev)
		phydev->interrupts =  PHY_INTERRUPT_ENABLED;

		if (phydev->drv->config_intr &&
			!phydev->drv->config_intr(phydev))
			!phydev->drv->config_intr(phydev)){
			DWC_ETH_QOS_request_phy_wol(pdata);
		} else {
			EMACERR("Failed to configure PHY interrupts");
			BUG();
		}
	}

	phy_start(pdata->phydev);
+6 −11
Original line number Diff line number Diff line
@@ -976,6 +976,8 @@ void DWC_ETH_QOS_resume_clks(struct DWC_ETH_QOS_prv_data *pdata)
#endif

	pdata->clks_suspended = 0;

	if (pdata->phy_intr_en)
		complete_all(&pdata->clk_enable_done);

	EMACDBG("Exit\n");
@@ -985,7 +987,9 @@ void DWC_ETH_QOS_suspend_clks(struct DWC_ETH_QOS_prv_data *pdata)
{
	EMACDBG("Enter\n");

	if (pdata->phy_intr_en)
		reinit_completion(&pdata->clk_enable_done);

	pdata->clks_suspended = 1;

	DWC_ETH_QOS_set_clk_and_bus_config(pdata, 0);
@@ -2061,12 +2065,6 @@ static INT DWC_ETH_QOS_suspend(struct platform_device *pdev, pm_message_t state)
		pdata->power_down_type |= DWC_ETH_QOS_EMAC_INTR_WAKEUP;
		enable_irq_wake(pdata->irq_number);

		/* Set PHY intr as wakeup-capable to handle change in PHY link status after suspend */
		if (pdata->phy_intr_en && pdata->phy_irq && pdata->phy_wol_wolopts) {
			pmt_flags |= DWC_ETH_QOS_PHY_INTR_WAKEUP;
			enable_irq_wake(pdata->phy_irq);
		}

		return 0;
	}

@@ -2082,9 +2080,6 @@ static INT DWC_ETH_QOS_suspend(struct platform_device *pdev, pm_message_t state)
	if (pdata->hw_feat.mgk_sel && (pdata->wolopts & WAKE_MAGIC))
		pmt_flags |= DWC_ETH_QOS_MAGIC_WAKEUP;

	if (pdata->phy_intr_en && pdata->phy_irq && pdata->phy_wol_wolopts)
		pmt_flags |= DWC_ETH_QOS_PHY_INTR_WAKEUP;

	ret = DWC_ETH_QOS_powerdown(dev, pmt_flags, DWC_ETH_QOS_DRIVER_CONTEXT);

	DWC_ETH_QOS_suspend_clks(pdata);