summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3f2e7ef)
raw | patch | inline | side by side (parent: 3f2e7ef)
author | Mugunthan V N <mugunthanvnm@ti.com> | |
Thu, 8 Mar 2012 12:21:47 +0000 (17:51 +0530) | ||
committer | Sekhar Nori <nsekhar@ti.com> | |
Fri, 9 Mar 2012 14:47:26 +0000 (20:17 +0530) |
Need to reset all sub-components of CPGMAC to gate the clock
Moved omap_dm_timer enable and configure to cpsw_ndo_open and disabled the
timer in cpsw_ndo_close so that during suspend/resume timer will be disabled
and enabled respectively
Added timer omap_dm_timer_free in cpsw_ndo_remove to free the dm_timer while
removing the module
Added wait_for_clock_enable to ensure that CPGMAC clock is enabled before
accessing the CPGMAC registers
TODO: Currently driver doesnot support pm runtime, so hack for wait for cpgmac
clock enable is done. Once PM runtime support is done then the hack will be
removed
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Moved omap_dm_timer enable and configure to cpsw_ndo_open and disabled the
timer in cpsw_ndo_close so that during suspend/resume timer will be disabled
and enabled respectively
Added timer omap_dm_timer_free in cpsw_ndo_remove to free the dm_timer while
removing the module
Added wait_for_clock_enable to ensure that CPGMAC clock is enabled before
accessing the CPGMAC registers
TODO: Currently driver doesnot support pm runtime, so hack for wait for cpgmac
clock enable is done. Once PM runtime support is done then the hack will be
removed
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
index 640ceb877ba1b35012e63481810dc79bb93aafe4..3092588cb1be3e88c6a77faa5c35bea3fd496e47 100644 (file)
u32 soft_reset;
u32 stat_port_en;
u32 ptype;
+ u32 soft_idle;
};
struct cpsw_slave_regs {
cpsw_set_coalesce(ndev, &coal);
}
+ /* Enable Timer for capturing cpsw rx interrupts */
+ omap_dm_timer_set_int_enable(dmtimer_rx, OMAP_TIMER_INT_CAPTURE);
+ omap_dm_timer_set_capture(dmtimer_rx, 1, 0, 0);
+ omap_dm_timer_enable(dmtimer_rx);
+
+ /* Enable Timer for capturing cpsw tx interrupts */
+ omap_dm_timer_set_int_enable(dmtimer_tx, OMAP_TIMER_INT_CAPTURE);
+ omap_dm_timer_set_capture(dmtimer_tx, 1, 0, 0);
+ omap_dm_timer_enable(dmtimer_tx);
+
cpdma_ctlr_start(priv->dma);
cpsw_intr_enable(priv);
napi_enable(&priv->napi);
msg(info, ifdown, "shutting down cpsw device\n");
cpsw_intr_disable(priv);
cpdma_ctlr_int_ctrl(priv->dma, false);
+
+ omap_dm_timer_set_int_enable(dmtimer_rx, 0);
+ omap_dm_timer_set_int_enable(dmtimer_tx, 0);
+
netif_stop_queue(priv->ndev);
napi_disable(&priv->napi);
netif_carrier_off(priv->ndev);
omap_ctrl_writel(CPSW_TIMER_MASK, CPSW_TIMER_CAP_REG);
- /* Enable Timer for capturing cpsw rx interrupts */
dmtimer_rx = omap_dm_timer_request_specific(CPSW_RX_TIMER_REQ);
- omap_dm_timer_set_int_enable(dmtimer_rx, OMAP_TIMER_INT_CAPTURE);
- omap_dm_timer_set_capture(dmtimer_rx, 1, 0, 0);
- omap_dm_timer_enable(dmtimer_rx);
-
- /* Enable Timer for capturing cpsw tx interrupts */
+ if (!dmtimer_rx) {
+ dev_err(priv->dev, "Error getting Rx Timer resource\n");
+ ret = -ENODEV;
+ goto clean_iomap_ret;
+ }
dmtimer_tx = omap_dm_timer_request_specific(CPSW_TX_TIMER_REQ);
- omap_dm_timer_set_int_enable(dmtimer_tx, OMAP_TIMER_INT_CAPTURE);
- omap_dm_timer_set_capture(dmtimer_tx, 1, 0, 0);
- omap_dm_timer_enable(dmtimer_tx);
+ if (!dmtimer_tx) {
+ dev_err(priv->dev, "Error getting Tx Timer resource\n");
+ ret = -ENODEV;
+ goto clean_timer_rx_ret;
+ }
memset(&dma_params, 0, sizeof(dma_params));
dma_params.dev = &pdev->dev;
if (!priv->dma) {
dev_err(priv->dev, "error initializing dma\n");
ret = -ENOMEM;
- goto clean_iomap_ret;
+ goto clean_timer_ret;
}
priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0),
cpdma_chan_destroy(priv->txch);
cpdma_chan_destroy(priv->rxch);
cpdma_ctlr_destroy(priv->dma);
+clean_timer_ret:
+ omap_dm_timer_free(dmtimer_tx);
+clean_timer_rx_ret:
+ omap_dm_timer_free(dmtimer_rx);
clean_iomap_ret:
iounmap(priv->regs);
clean_cpsw_ss_iores_ret:
msg(notice, probe, "removing device\n");
platform_set_drvdata(pdev, NULL);
+ omap_dm_timer_free(dmtimer_rx);
+ omap_dm_timer_free(dmtimer_tx);
free_irq(ndev->irq, priv);
cpsw_ale_destroy(priv->ale);
cpdma_chan_destroy(priv->txch);
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev);
+ struct cpsw_priv *priv = netdev_priv(ndev);
if (netif_running(ndev))
cpsw_ndo_stop(ndev);
+
+ soft_reset("cpsw", &priv->regs->soft_reset);
+ soft_reset("sliver 0", &priv->slaves[0].sliver->soft_reset);
+ soft_reset("sliver 1", &priv->slaves[1].sliver->soft_reset);
+ soft_reset("cpsw_ss", &priv->ss_regs->soft_reset);
+
return 0;
}
index 2ce6739084f3e0df810d79b41bf24ca459126c82..9639c31f8755f27a6c5eb51d45b8ba8a7a37cce7 100644 (file)
void cpsw_ale_stop(struct cpsw_ale *ale)
{
+ cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
del_timer_sync(&ale->timer);
device_remove_file(ale->params.dev, &ale->ale_table_attr);
device_remove_file(ale->params.dev, &ale->ale_control_attr);
index 617252c7803b1c9c5f98e5b64d362c02619fabce..306d93036c1ed69a47fc9bf041c7d287a6ffa320 100644 (file)
ctlr->state = CPDMA_STATE_IDLE;
+ if (ctlr->params.has_soft_reset) {
+ unsigned long timeout = jiffies + HZ/10;
+
+ dma_reg_write(ctlr, CPDMA_SOFTRESET, 1);
+ while (time_before(jiffies, timeout)) {
+ if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0)
+ break;
+ }
+ WARN_ON(!time_before(jiffies, timeout));
+ }
+
spin_unlock_irqrestore(&ctlr->lock, flags);
return 0;
}
index 7615040df75621dda0684732017e4d21fac425eb..213d204dbc51387b755310dc52bfa2a012fb913c 100644 (file)
#define DEF_OUT_FREQ 2200000 /* 2.2 MHz */
+#define CPGMAC_CLK_CTRL_REG 0x44E00014
+
struct davinci_mdio_regs {
u32 version;
u32 control;
return 0;
}
+static inline int wait_for_clock_enable(struct davinci_mdio_data *data)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT);
+ u32 __iomem *cpgmac_clk = ioremap(CPGMAC_CLK_CTRL_REG, 4);
+ u32 reg = 0;
+
+ while (time_after(timeout, jiffies)) {
+ reg = readl(cpgmac_clk);
+ if ((reg & 0x70000) == 0)
+ goto iounmap_ret;
+ }
+ dev_err(data->dev,
+ "timed out waiting for CPGMAC clock enable, value = 0x%x\n",
+ reg);
+ iounmap(cpgmac_clk);
+ return -ETIMEDOUT;
+
+iounmap_ret:
+ iounmap(cpgmac_clk);
+ return 0;
+}
+
static int davinci_mdio_suspend(struct device *dev)
{
struct davinci_mdio_data *data = dev_get_drvdata(dev);
if (data->clk)
clk_enable(data->clk);
+ /* Need to wait till Module is enabled */
+ wait_for_clock_enable(data);
+
/* restart the scan state machine */
ctrl = __raw_readl(&data->regs->control);
ctrl |= CONTROL_ENABLE;
__raw_writel(ctrl, &data->regs->control);
-
data->suspended = false;
+
spin_unlock(&data->lock);
return 0;