Seems to remove a few instructions. Original message below: From: Ben Menchaca <ben.mench...@qca.qualcomm.com> Date: Tue, 11 Jun 2013 15:50:17 -0500 Subject: [ag71xx] optimize iomapped register access
Add register accessors that remove the per-register range check that was done previously. Additionally, we separate the write from the subsequent read that is designed to flush the write; this can now be called separately. Signed-off-by: Ben Menchaca <ben.mench...@qca.qualcomm.com> Signed-off-by: Rosen Penev <ros...@gmail.com> --- .../drivers/net/ethernet/atheros/ag71xx/ag71xx.h | 23 +++++++++++++++++++ .../net/ethernet/atheros/ag71xx/ag71xx_main.c | 26 +++++++++++++++------- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h index c39beaf..39237aa 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h @@ -163,6 +163,12 @@ struct ag71xx { struct ag71xx_ring rx_ring ____cacheline_aligned; struct ag71xx_ring tx_ring ____cacheline_aligned; + void __iomem *rx_ctrl_reg; + void __iomem *rx_status_reg; + void __iomem *tx_ctrl_reg; + void __iomem *tx_status_reg; + void __iomem *int_status_reg; + unsigned int max_frame_len; unsigned int desc_pktlen_mask; unsigned int rx_buf_size; @@ -400,6 +406,17 @@ static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) } } +static inline void ag71xx_wr_fast(void __iomem *r, u32 value) +{ + __raw_writel(value, r); +} + +static inline void ag71xx_wr_flush(void __iomem *r) +{ + (void)__raw_readl(r); +} + + static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) { ag71xx_check_reg_offset(ag, reg); @@ -409,6 +426,12 @@ static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) (void) __raw_readl(ag->mac_base + reg); } +static inline u32 ag71xx_rr_fast(void __iomem *r) +{ + return __raw_readl(r); +} + + static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) { ag71xx_check_reg_offset(ag, reg); diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c index 7760952..ffbe646 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c @@ -842,8 +842,8 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, DBG("%s: packet injected into TX queue\n", ag->dev->name); /* enable TX engine */ - ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); - + ag71xx_wr_fast(ag->tx_ctrl_reg, TX_CTRL_TXE); + ag71xx_wr_flush(ag->tx_ctrl_reg); return NETDEV_TX_OK; err_drop_unmap: @@ -994,7 +994,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag, bool flush) ring->dirty += n; while (n > 0) { - ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + ag71xx_wr_fast(ag->tx_status_reg, TX_STATUS_PS); n--; } } @@ -1048,7 +1048,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit) break; } - ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); + ag71xx_wr_fast(ag->rx_status_reg, RX_STATUS_PR); pktlen = desc->ctrl & pktlen_mask; pktlen -= ETH_FCS_LEN; @@ -1087,6 +1087,8 @@ next: ring->curr++; } + ag71xx_wr_flush(ag->rx_status_reg); + ag71xx_ring_rx_refill(ag); while ((skb = __skb_dequeue(&queue)) != NULL) { @@ -1123,13 +1125,15 @@ static int ag71xx_poll(struct napi_struct *napi, int limit) if (rx_ring->buf[rx_ring->dirty % rx_ring_size].rx_buf == NULL) goto oom; - status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); + status = ag71xx_rr_fast(ag->rx_status_reg); if (unlikely(status & RX_STATUS_OF)) { - ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); + ag71xx_wr_fast(ag->rx_status_reg, RX_STATUS_OF); + ag71xx_wr_flush(ag->rx_status_reg); dev->stats.rx_fifo_errors++; /* restart RX */ - ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + ag71xx_wr_fast(ag->rx_ctrl_reg, RX_CTRL_RXE); + ag71xx_wr_flush(ag->rx_ctrl_reg); } if (rx_done < limit) { @@ -1172,7 +1176,7 @@ static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) struct ag71xx *ag = netdev_priv(dev); u32 status; - status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); + status = ag71xx_rr_fast(ag->int_status_reg); ag71xx_dump_intr(ag, "raw", status); if (unlikely(!status)) @@ -1320,6 +1324,12 @@ static int ag71xx_probe(struct platform_device *pdev) goto err_free_dev; } + ag->rx_ctrl_reg = ag->mac_base + AG71XX_REG_RX_CTRL; + ag->rx_status_reg = ag->mac_base + AG71XX_REG_RX_STATUS; + ag->tx_ctrl_reg = ag->mac_base + AG71XX_REG_TX_CTRL; + ag->tx_status_reg = ag->mac_base + AG71XX_REG_TX_STATUS; + ag->int_status_reg = ag->mac_base + AG71XX_REG_INT_STATUS; + dev->irq = platform_get_irq(pdev, 0); err = request_irq(dev->irq, ag71xx_interrupt, 0x0, -- 2.7.4 _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev