Commit dff79620 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: dsa: sja1105: Replace sja1105_spi_send_int with sja1105_xfer_{u32, u64}

Having a function that takes a variable number of unpacked bytes which
it generically calls an "int" is confusing and makes auditing patches
next to impossible.

We only use spi_send_int with the int sizes of 32 and 64 bits. So just
make the spi_send_int function less generic and replace it with the
appropriate two explicit functions, which can now type-check the int
pointer type.

Note that there is still a small weirdness in the u32 function, which
has to convert it to a u64 temporary. This is because of how the packing
API works at the moment, but the weirdness is at least hidden from
callers of sja1105_xfer_u32 now.
Suggested-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarVladimir Oltean <olteanv@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 09c1b412
......@@ -130,9 +130,10 @@ int sja1105_static_config_reload(struct sja1105_private *priv);
int sja1105_spi_send_packed_buf(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr,
void *packed_buf, size_t size_bytes);
int sja1105_spi_send_int(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr,
u64 *value, u64 size_bytes);
int sja1105_xfer_u32(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value);
int sja1105_xfer_u64(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value);
int sja1105_spi_send_long_packed_buf(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 base_addr,
void *packed_buf, u64 buf_len);
......
......@@ -2109,17 +2109,16 @@ static int sja1105_check_device_id(struct sja1105_private *priv)
const struct sja1105_regs *regs = priv->info->regs;
u8 prod_id[SJA1105_SIZE_DEVICE_ID] = {0};
struct device *dev = &priv->spidev->dev;
u64 device_id;
u32 device_id;
u64 part_no;
int rc;
rc = sja1105_spi_send_int(priv, SPI_READ, regs->device_id,
&device_id, SJA1105_SIZE_DEVICE_ID);
rc = sja1105_xfer_u32(priv, SPI_READ, regs->device_id, &device_id);
if (rc < 0)
return rc;
if (device_id != priv->info->device_id) {
dev_err(dev, "Expected device ID 0x%llx but read 0x%llx\n",
dev_err(dev, "Expected device ID 0x%llx but read 0x%x\n",
priv->info->device_id, device_id);
return -ENODEV;
}
......
......@@ -327,8 +327,7 @@ static u64 sja1105_ptptsclk_read(const struct cyclecounter *cc)
u64 ptptsclk = 0;
int rc;
rc = sja1105_spi_send_int(priv, SPI_READ, regs->ptptsclk,
&ptptsclk, 8);
rc = sja1105_xfer_u64(priv, SPI_READ, regs->ptptsclk, &ptptsclk);
if (rc < 0)
dev_err_ratelimited(priv->ds->dev,
"failed to read ptp cycle counter: %d\n",
......
......@@ -7,7 +7,6 @@
#include <linux/packing.h>
#include "sja1105.h"
#define SJA1105_SIZE_PORT_CTRL 4
#define SJA1105_SIZE_RESET_CMD 4
#define SJA1105_SIZE_SPI_MSG_HEADER 4
#define SJA1105_SIZE_SPI_MSG_MAXLEN (64 * 4)
......@@ -103,35 +102,52 @@ int sja1105_spi_send_packed_buf(const struct sja1105_private *priv,
/* If @rw is:
* - SPI_WRITE: creates and sends an SPI write message at absolute
* address reg_addr, taking size_bytes from *packed_buf
* address reg_addr
* - SPI_READ: creates and sends an SPI read message from absolute
* address reg_addr, writing size_bytes into *packed_buf
* address reg_addr
*
* The u64 *value is unpacked, meaning that it's stored in the native
* CPU endianness and directly usable by software running on the core.
*
* This is a wrapper around sja1105_spi_send_packed_buf().
*/
int sja1105_spi_send_int(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr,
u64 *value, u64 size_bytes)
int sja1105_xfer_u64(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value)
{
u8 packed_buf[SJA1105_SIZE_SPI_MSG_MAXLEN];
u8 packed_buf[8];
int rc;
if (size_bytes > SJA1105_SIZE_SPI_MSG_MAXLEN)
return -ERANGE;
if (rw == SPI_WRITE)
sja1105_pack(packed_buf, value, 8 * size_bytes - 1, 0,
size_bytes);
sja1105_pack(packed_buf, value, 63, 0, 8);
rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf,
size_bytes);
rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf, 8);
if (rw == SPI_READ)
sja1105_unpack(packed_buf, value, 8 * size_bytes - 1, 0,
size_bytes);
sja1105_unpack(packed_buf, value, 63, 0, 8);
return rc;
}
/* Same as above, but transfers only a 4 byte word */
int sja1105_xfer_u32(const struct sja1105_private *priv,
sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value)
{
u8 packed_buf[4];
u64 tmp;
int rc;
if (rw == SPI_WRITE) {
/* The packing API only supports u64 as CPU word size,
* so we need to convert.
*/
tmp = *value;
sja1105_pack(packed_buf, &tmp, 31, 0, 4);
}
rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf, 4);
if (rw == SPI_READ) {
sja1105_unpack(packed_buf, &tmp, 31, 0, 4);
*value = tmp;
}
return rc;
}
......@@ -287,11 +303,11 @@ int sja1105_inhibit_tx(const struct sja1105_private *priv,
unsigned long port_bitmap, bool tx_inhibited)
{
const struct sja1105_regs *regs = priv->info->regs;
u64 inhibit_cmd;
u32 inhibit_cmd;
int rc;
rc = sja1105_spi_send_int(priv, SPI_READ, regs->port_control,
&inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
rc = sja1105_xfer_u32(priv, SPI_READ, regs->port_control,
&inhibit_cmd);
if (rc < 0)
return rc;
......@@ -300,8 +316,8 @@ int sja1105_inhibit_tx(const struct sja1105_private *priv,
else
inhibit_cmd &= ~port_bitmap;
return sja1105_spi_send_int(priv, SPI_WRITE, regs->port_control,
&inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
return sja1105_xfer_u32(priv, SPI_WRITE, regs->port_control,
&inhibit_cmd);
}
struct sja1105_status {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment