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

Commit 12f08412 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'renesas-bit-twiddling'



Sergei Shtylyov says:

====================
Factor out register bit twiddling in the Renesas Ethernet drivers

   Here's a set of 2 patches against DaveM's 'net-next.git' repo. We factor out
the often repeated pattern of reading a register, AND'ing and/or OR'ing some
bits, and then writing the value back.

[1/2] ravb: factor out register bit twiddling code
[2/2] sh_eth: factor out register bit twiddling code
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ef5c0e25 b2b14d2f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 *
 * Copyright (C) 2014-2015 Renesas Electronics Corporation
 * Copyright (C) 2015 Renesas Solutions Corp.
 * Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com>
 * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
 *
 * Based on the SuperH Ethernet driver
 *
@@ -837,6 +837,8 @@ static inline void ravb_write(struct net_device *ndev, u32 data,
	iowrite32(data, priv->addr + reg);
}

void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
		 u32 set);
int ravb_wait(struct net_device *ndev, enum ravb_reg reg, u32 mask, u32 value);

irqreturn_t ravb_ptp_interrupt(struct net_device *ndev);
+27 −41
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 *
 * Copyright (C) 2014-2015 Renesas Electronics Corporation
 * Copyright (C) 2015 Renesas Solutions Corp.
 * Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com>
 * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
 *
 * Based on the SuperH Ethernet driver
 *
@@ -42,6 +42,12 @@
		 NETIF_MSG_RX_ERR | \
		 NETIF_MSG_TX_ERR)

void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
		 u32 set)
{
	ravb_write(ndev, (ravb_read(ndev, reg) & ~clear) | set, reg);
}

int ravb_wait(struct net_device *ndev, enum ravb_reg reg, u32 mask, u32 value)
{
	int i;
@@ -59,8 +65,7 @@ static int ravb_config(struct net_device *ndev)
	int error;

	/* Set config mode */
	ravb_write(ndev, (ravb_read(ndev, CCC) & ~CCC_OPC) | CCC_OPC_CONFIG,
		   CCC);
	ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
	/* Check if the operating mode is changed to the config mode */
	error = ravb_wait(ndev, CSR, CSR_OPS, CSR_OPS_CONFIG);
	if (error)
@@ -72,13 +77,8 @@ static int ravb_config(struct net_device *ndev)
static void ravb_set_duplex(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	u32 ecmr = ravb_read(ndev, ECMR);

	if (priv->duplex)	/* Full */
		ecmr |=  ECMR_DM;
	else			/* Half */
		ecmr &= ~ECMR_DM;
	ravb_write(ndev, ecmr, ECMR);
	ravb_modify(ndev, ECMR, ECMR_DM, priv->duplex ? ECMR_DM : 0);
}

static void ravb_set_rate(struct net_device *ndev)
@@ -131,13 +131,8 @@ static void ravb_mdio_ctrl(struct mdiobb_ctrl *ctrl, u32 mask, int set)
{
	struct ravb_private *priv = container_of(ctrl, struct ravb_private,
						 mdiobb);
	u32 pir = ravb_read(priv->ndev, PIR);

	if (set)
		pir |=  mask;
	else
		pir &= ~mask;
	ravb_write(priv->ndev, pir, PIR);
	ravb_modify(priv->ndev, PIR, mask, set ? mask : 0);
}

/* MDC pin control */
@@ -393,9 +388,9 @@ static int ravb_dmac_init(struct net_device *ndev)
	ravb_ring_format(ndev, RAVB_NC);

#if defined(__LITTLE_ENDIAN)
	ravb_write(ndev, ravb_read(ndev, CCC) & ~CCC_BOC, CCC);
	ravb_modify(ndev, CCC, CCC_BOC, 0);
#else
	ravb_write(ndev, ravb_read(ndev, CCC) | CCC_BOC, CCC);
	ravb_modify(ndev, CCC, CCC_BOC, CCC_BOC);
#endif

	/* Set AVB RX */
@@ -418,8 +413,7 @@ static int ravb_dmac_init(struct net_device *ndev)
	ravb_write(ndev, TIC_FTE0 | TIC_FTE1 | TIC_TFUE, TIC);

	/* Setting the control will start the AVB-DMAC process. */
	ravb_write(ndev, (ravb_read(ndev, CCC) & ~CCC_OPC) | CCC_OPC_OPERATION,
		   CCC);
	ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION);

	return 0;
}
@@ -493,7 +487,7 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)
				break;
			}
		}
		ravb_write(ndev, ravb_read(ndev, TCCR) | TCCR_TFR, TCCR);
		ravb_modify(ndev, TCCR, TCCR_TFR, TCCR_TFR);
	}
}

@@ -613,13 +607,13 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
static void ravb_rcv_snd_disable(struct net_device *ndev)
{
	/* Disable TX and RX */
	ravb_write(ndev, ravb_read(ndev, ECMR) & ~(ECMR_RE | ECMR_TE), ECMR);
	ravb_modify(ndev, ECMR, ECMR_RE | ECMR_TE, 0);
}

static void ravb_rcv_snd_enable(struct net_device *ndev)
{
	/* Enable TX and RX */
	ravb_write(ndev, ravb_read(ndev, ECMR) | ECMR_RE | ECMR_TE, ECMR);
	ravb_modify(ndev, ECMR, ECMR_RE | ECMR_TE, ECMR_RE | ECMR_TE);
}

/* function for waiting dma process finished */
@@ -812,8 +806,8 @@ static int ravb_poll(struct napi_struct *napi, int budget)

	/* Re-enable RX/TX interrupts */
	spin_lock_irqsave(&priv->lock, flags);
	ravb_write(ndev, ravb_read(ndev, RIC0) | mask, RIC0);
	ravb_write(ndev, ravb_read(ndev, TIC)  | mask,  TIC);
	ravb_modify(ndev, RIC0, mask, mask);
	ravb_modify(ndev, TIC,  mask, mask);
	mmiowb();
	spin_unlock_irqrestore(&priv->lock, flags);

@@ -852,8 +846,7 @@ static void ravb_adjust_link(struct net_device *ndev)
			ravb_set_rate(ndev);
		}
		if (!priv->link) {
			ravb_write(ndev, ravb_read(ndev, ECMR) & ~ECMR_TXF,
				   ECMR);
			ravb_modify(ndev, ECMR, ECMR_TXF, 0);
			new_state = true;
			priv->link = phydev->link;
			if (priv->no_avb_link)
@@ -1393,7 +1386,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
	desc--;
	desc->die_dt = DT_FSTART;

	ravb_write(ndev, ravb_read(ndev, TCCR) | (TCCR_TSRQ0 << q), TCCR);
	ravb_modify(ndev, TCCR, TCCR_TSRQ0 << q, TCCR_TSRQ0 << q);

	priv->cur_tx[q] += NUM_TX_DESC;
	if (priv->cur_tx[q] - priv->dirty_tx[q] >
@@ -1468,15 +1461,10 @@ static void ravb_set_rx_mode(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	unsigned long flags;
	u32 ecmr;

	spin_lock_irqsave(&priv->lock, flags);
	ecmr = ravb_read(ndev, ECMR);
	if (ndev->flags & IFF_PROMISC)
		ecmr |=  ECMR_PRM;
	else
		ecmr &= ~ECMR_PRM;
	ravb_write(ndev, ecmr, ECMR);
	ravb_modify(ndev, ECMR, ECMR_PRM,
		    ndev->flags & IFF_PROMISC ? ECMR_PRM : 0);
	mmiowb();
	spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -1804,14 +1792,12 @@ static int ravb_probe(struct platform_device *pdev)

	/* Set AVB config mode */
	if (chip_id == RCAR_GEN2) {
		ravb_write(ndev, (ravb_read(ndev, CCC) & ~CCC_OPC) |
			   CCC_OPC_CONFIG, CCC);
		ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
		/* Set CSEL value */
		ravb_write(ndev, (ravb_read(ndev, CCC) & ~CCC_CSEL) |
			   CCC_CSEL_HPB, CCC);
		ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
	} else {
		ravb_write(ndev, (ravb_read(ndev, CCC) & ~CCC_OPC) |
			   CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB, CCC);
		ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG |
			    CCC_GAC | CCC_CSEL_HPB);
	}

	/* Set CSEL value */
@@ -1824,7 +1810,7 @@ static int ravb_probe(struct platform_device *pdev)
		goto out_release;

	/* Request GTI loading */
	ravb_write(ndev, ravb_read(ndev, GCCR) | GCCR_LTI, GCCR);
	ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);

	/* Allocate descriptor base address table */
	priv->desc_bat_size = sizeof(struct ravb_desc) * DBAT_ENTRY_NUM;
+6 −19
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 *
 * Copyright (C) 2013-2015 Renesas Electronics Corporation
 * Copyright (C) 2015 Renesas Solutions Corp.
 * Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com>
 * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@ static int ravb_ptp_tcr_request(struct ravb_private *priv, u32 request)
	if (error)
		return error;

	ravb_write(ndev, ravb_read(ndev, GCCR) | request, GCCR);
	ravb_modify(ndev, GCCR, request, request);
	return ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
}

@@ -185,7 +185,6 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
						 ptp.info);
	struct net_device *ndev = priv->ndev;
	unsigned long flags;
	u32 gic;

	if (req->index)
		return -EINVAL;
@@ -195,12 +194,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
	priv->ptp.extts[req->index] = on;

	spin_lock_irqsave(&priv->lock, flags);
	gic = ravb_read(ndev, GIC);
	if (on)
		gic |= GIC_PTCE;
	else
		gic &= ~GIC_PTCE;
	ravb_write(ndev, gic, GIC);
	ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
	mmiowb();
	spin_unlock_irqrestore(&priv->lock, flags);

@@ -216,7 +210,6 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
	struct ravb_ptp_perout *perout;
	unsigned long flags;
	int error = 0;
	u32 gic;

	if (req->index)
		return -EINVAL;
@@ -248,9 +241,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
		error = ravb_ptp_update_compare(priv, (u32)start_ns);
		if (!error) {
			/* Unmask interrupt */
			gic = ravb_read(ndev, GIC);
			gic |= GIC_PTME;
			ravb_write(ndev, gic, GIC);
			ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
		}
	} else	{
		spin_lock_irqsave(&priv->lock, flags);
@@ -259,9 +250,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
		perout->period = 0;

		/* Mask interrupt */
		gic = ravb_read(ndev, GIC);
		gic &= ~GIC_PTME;
		ravb_write(ndev, gic, GIC);
		ravb_modify(ndev, GIC, GIC_PTME, 0);
	}
	mmiowb();
	spin_unlock_irqrestore(&priv->lock, flags);
@@ -331,7 +320,6 @@ void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	unsigned long flags;
	u32 gccr;

	priv->ptp.info = ravb_ptp_info;

@@ -340,8 +328,7 @@ void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)

	spin_lock_irqsave(&priv->lock, flags);
	ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
	gccr = ravb_read(ndev, GCCR) & ~GCCR_TCSS;
	ravb_write(ndev, gccr | GCCR_TCSS_ADJGPTP, GCCR);
	ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
	mmiowb();
	spin_unlock_irqrestore(&priv->lock, flags);

+24 −29
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 *  Copyright (C) 2014  Renesas Electronics Corporation
 *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
 *  Copyright (C) 2008-2014 Renesas Solutions Corp.
 *  Copyright (C) 2013-2014 Cogent Embedded, Inc.
 *  Copyright (C) 2013-2016 Cogent Embedded, Inc.
 *  Copyright (C) 2014 Codethink Limited
 *
 *  This program is free software; you can redistribute it and/or modify it
@@ -428,6 +428,13 @@ static u32 sh_eth_read(struct net_device *ndev, int enum_index)
	return ioread32(mdp->addr + offset);
}

static void sh_eth_modify(struct net_device *ndev, int enum_index, u32 clear,
			  u32 set)
{
	sh_eth_write(ndev, (sh_eth_read(ndev, enum_index) & ~clear) | set,
		     enum_index);
}

static bool sh_eth_is_gether(struct sh_eth_private *mdp)
{
	return mdp->reg_offset == sh_eth_offset_gigabit;
@@ -467,10 +474,7 @@ static void sh_eth_set_duplex(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);

	if (mdp->duplex) /* Full */
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
	else		/* Half */
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
	sh_eth_modify(ndev, ECMR, ECMR_DM, mdp->duplex ? ECMR_DM : 0);
}

static void sh_eth_chip_reset(struct net_device *ndev)
@@ -583,10 +587,10 @@ static void sh_eth_set_rate_r8a777x(struct net_device *ndev)

	switch (mdp->speed) {
	case 10: /* 10BASE */
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_ELB, ECMR);
		sh_eth_modify(ndev, ECMR, ECMR_ELB, 0);
		break;
	case 100:/* 100BASE */
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_ELB, ECMR);
		sh_eth_modify(ndev, ECMR, ECMR_ELB, ECMR_ELB);
		break;
	default:
		break;
@@ -649,10 +653,10 @@ static void sh_eth_set_rate_sh7724(struct net_device *ndev)

	switch (mdp->speed) {
	case 10: /* 10BASE */
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
		sh_eth_modify(ndev, ECMR, ECMR_RTM, 0);
		break;
	case 100:/* 100BASE */
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
		sh_eth_modify(ndev, ECMR, ECMR_RTM, ECMR_RTM);
		break;
	default:
		break;
@@ -924,8 +928,7 @@ static int sh_eth_reset(struct net_device *ndev)

	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) {
		sh_eth_write(ndev, EDSR_ENALL, EDSR);
		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
			     EDMR);
		sh_eth_modify(ndev, EDMR, EDMR_SRST_GETHER, EDMR_SRST_GETHER);

		ret = sh_eth_check_reset(ndev);
		if (ret)
@@ -949,11 +952,9 @@ static int sh_eth_reset(struct net_device *ndev)
		if (mdp->cd->select_mii)
			sh_eth_select_mii(ndev);
	} else {
		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
			     EDMR);
		sh_eth_modify(ndev, EDMR, EDMR_SRST_ETHER, EDMR_SRST_ETHER);
		mdelay(3);
		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
			     EDMR);
		sh_eth_modify(ndev, EDMR, EDMR_SRST_ETHER, 0);
	}

	return ret;
@@ -1285,7 +1286,7 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)
	sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN,
		     RFLR);

	sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
	sh_eth_modify(ndev, EESR, 0, 0);
	if (start) {
		mdp->irq_enabled = true;
		sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
@@ -1532,15 +1533,13 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
static void sh_eth_rcv_snd_disable(struct net_device *ndev)
{
	/* disable tx and rx */
	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
		~(ECMR_RE | ECMR_TE), ECMR);
	sh_eth_modify(ndev, ECMR, ECMR_RE | ECMR_TE, 0);
}

static void sh_eth_rcv_snd_enable(struct net_device *ndev)
{
	/* enable tx and rx */
	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) |
		(ECMR_RE | ECMR_TE), ECMR);
	sh_eth_modify(ndev, ECMR, ECMR_RE | ECMR_TE, ECMR_RE | ECMR_TE);
}

/* error control function */
@@ -1569,13 +1568,11 @@ static void sh_eth_error(struct net_device *ndev, u32 intr_status)
				sh_eth_rcv_snd_disable(ndev);
			} else {
				/* Link Up */
				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
						   ~DMAC_M_ECI, EESIPR);
				sh_eth_modify(ndev, EESIPR, DMAC_M_ECI, 0);
				/* clear int */
				sh_eth_write(ndev, sh_eth_read(ndev, ECSR),
					     ECSR);
				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) |
						   DMAC_M_ECI, EESIPR);
				sh_eth_modify(ndev, ECSR, 0, 0);
				sh_eth_modify(ndev, EESIPR, DMAC_M_ECI,
					      DMAC_M_ECI);
				/* enable tx and rx */
				sh_eth_rcv_snd_enable(ndev);
			}
@@ -1765,9 +1762,7 @@ static void sh_eth_adjust_link(struct net_device *ndev)
				mdp->cd->set_rate(ndev);
		}
		if (!mdp->link) {
			sh_eth_write(ndev,
				     sh_eth_read(ndev, ECMR) & ~ECMR_TXF,
				     ECMR);
			sh_eth_modify(ndev, ECMR, ECMR_TXF, 0);
			new_state = 1;
			mdp->link = phydev->link;
			if (mdp->cd->no_psr || mdp->no_ether_link)