linux-can-next-for-5.4-20190820
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEmvEkXzgOfc881GuFWsYho5HknSAFAl1b6WITHG1rbEBwZW5n dXRyb25peC5kZQAKCRBaxiGjkeSdIEceB/47kBVi8VF+vHUqEwKYhYObYQBVjoMi 8Jvzy9Swu6G0isVFVGnSQHI5QZ3rGDtho7FkwjPTjtu4nEY3VgkrBIbUbJItNXDt 9K7YgIA3Z6t7zAe+bnBSQGDpnbbvdySJ/TyNESu/A3snRKl5IY9IR3CTW1DBchBY aHd8YkYNSB//cgej6PXt0N/UDGrZxHRNOGc46SQeMQ7eSIMLo3UZ66Oo1ejON1bT 4yjFFmYULC/y4q8hkoKTUD9sdbYBSmDD2be50yEhoa9NHagrQNPzWET3bI64Key9 sOnuXL0dVfxPzDX9xjWMrFxeiDipLrzINTbw0v/9TVkxpBSr5Nhbebz3 =pRoe -----END PGP SIGNATURE----- Merge tag 'linux-can-next-for-5.4-20190820' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next Marc Kleine-Budde says: ==================== pull-request: can-next 2019-08-20 this is a pull request for net-next/master consisting of 18 patches. The first patch is by Geert Uytterhoeven, it removes the unused platform data support from the rcar_can driver. A patch by Nishka Dasgupta marks the structure peak_pciec_i2c_bit_ops in the peak_pci driver as constant. A patch by me removes the custom DMA support from the hi311x driver. The next 4 patches target the tcan4x5x driver and are also by me, they first clean up the driver a bit, and then add missing error handling and fix a bug in the length calculation in the regmap callbacks. The next 2 patches are by me for the m_can_platform driver, they also remove unneeded casts and add missing error handling. The remaining 9 patches all target the mcp251x driver. The first 5 are clean up patches by me, the next relaxes the timing in the mcp251x_hw_reset() function. Alexander Shiyan's patch improves the name which is used while registering the interrupt handler. Phil Elwell's patch improves the mcp251x_open() function to use the DT-supplied interrupt flags instead of hard coding them. The final patch is again by me, it removes the custom DMA support from the hi311x driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
f588af848b
|
@ -16,24 +16,21 @@ struct m_can_plat_priv {
|
||||||
|
|
||||||
static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg)
|
static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg)
|
||||||
{
|
{
|
||||||
struct m_can_plat_priv *priv =
|
struct m_can_plat_priv *priv = cdev->device_data;
|
||||||
(struct m_can_plat_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
return readl(priv->base + reg);
|
return readl(priv->base + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 iomap_read_fifo(struct m_can_classdev *cdev, int offset)
|
static u32 iomap_read_fifo(struct m_can_classdev *cdev, int offset)
|
||||||
{
|
{
|
||||||
struct m_can_plat_priv *priv =
|
struct m_can_plat_priv *priv = cdev->device_data;
|
||||||
(struct m_can_plat_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
return readl(priv->mram_base + offset);
|
return readl(priv->mram_base + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iomap_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
static int iomap_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
||||||
{
|
{
|
||||||
struct m_can_plat_priv *priv =
|
struct m_can_plat_priv *priv = cdev->device_data;
|
||||||
(struct m_can_plat_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
writel(val, priv->base + reg);
|
writel(val, priv->base + reg);
|
||||||
|
|
||||||
|
@ -42,8 +39,7 @@ static int iomap_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
||||||
|
|
||||||
static int iomap_write_fifo(struct m_can_classdev *cdev, int offset, int val)
|
static int iomap_write_fifo(struct m_can_classdev *cdev, int offset, int val)
|
||||||
{
|
{
|
||||||
struct m_can_plat_priv *priv =
|
struct m_can_plat_priv *priv = cdev->device_data;
|
||||||
(struct m_can_plat_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
writel(val, priv->mram_base + offset);
|
writel(val, priv->mram_base + offset);
|
||||||
|
|
||||||
|
@ -67,6 +63,9 @@ static int m_can_plat_probe(struct platform_device *pdev)
|
||||||
int irq, ret = 0;
|
int irq, ret = 0;
|
||||||
|
|
||||||
mcan_class = m_can_class_allocate_dev(&pdev->dev);
|
mcan_class = m_can_class_allocate_dev(&pdev->dev);
|
||||||
|
if (!mcan_class)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -113,7 +113,6 @@
|
||||||
struct tcan4x5x_priv {
|
struct tcan4x5x_priv {
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct spi_device *spi;
|
struct spi_device *spi;
|
||||||
struct mutex tcan4x5x_lock; /* SPI device lock */
|
|
||||||
|
|
||||||
struct m_can_classdev *mcan_dev;
|
struct m_can_classdev *mcan_dev;
|
||||||
|
|
||||||
|
@ -179,7 +178,7 @@ static int regmap_spi_gather_write(void *context, const void *reg,
|
||||||
{ .tx_buf = val, .len = val_len, },
|
{ .tx_buf = val, .len = val_len, },
|
||||||
};
|
};
|
||||||
|
|
||||||
addr = TCAN4X5X_WRITE_CMD | (*((u16 *)reg) << 8) | val_len >> 3;
|
addr = TCAN4X5X_WRITE_CMD | (*((u16 *)reg) << 8) | val_len >> 2;
|
||||||
|
|
||||||
spi_message_init(&m);
|
spi_message_init(&m);
|
||||||
spi_message_add_tail(&t[0], &m);
|
spi_message_add_tail(&t[0], &m);
|
||||||
|
@ -193,7 +192,7 @@ static int tcan4x5x_regmap_write(void *context, const void *data, size_t count)
|
||||||
u16 *reg = (u16 *)(data);
|
u16 *reg = (u16 *)(data);
|
||||||
const u32 *val = data + 4;
|
const u32 *val = data + 4;
|
||||||
|
|
||||||
return regmap_spi_gather_write(context, reg, 4, val, count);
|
return regmap_spi_gather_write(context, reg, 4, val, count - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regmap_spi_async_write(void *context,
|
static int regmap_spi_async_write(void *context,
|
||||||
|
@ -234,7 +233,7 @@ static struct regmap_bus tcan4x5x_bus = {
|
||||||
|
|
||||||
static u32 tcan4x5x_read_reg(struct m_can_classdev *cdev, int reg)
|
static u32 tcan4x5x_read_reg(struct m_can_classdev *cdev, int reg)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)cdev->device_data;
|
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
tcan4x5x_check_wake(priv);
|
tcan4x5x_check_wake(priv);
|
||||||
|
@ -246,7 +245,7 @@ static u32 tcan4x5x_read_reg(struct m_can_classdev *cdev, int reg)
|
||||||
|
|
||||||
static u32 tcan4x5x_read_fifo(struct m_can_classdev *cdev, int addr_offset)
|
static u32 tcan4x5x_read_fifo(struct m_can_classdev *cdev, int addr_offset)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)cdev->device_data;
|
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
tcan4x5x_check_wake(priv);
|
tcan4x5x_check_wake(priv);
|
||||||
|
@ -258,7 +257,7 @@ static u32 tcan4x5x_read_fifo(struct m_can_classdev *cdev, int addr_offset)
|
||||||
|
|
||||||
static int tcan4x5x_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
static int tcan4x5x_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)cdev->device_data;
|
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||||
|
|
||||||
tcan4x5x_check_wake(priv);
|
tcan4x5x_check_wake(priv);
|
||||||
|
|
||||||
|
@ -268,8 +267,7 @@ static int tcan4x5x_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
||||||
static int tcan4x5x_write_fifo(struct m_can_classdev *cdev,
|
static int tcan4x5x_write_fifo(struct m_can_classdev *cdev,
|
||||||
int addr_offset, int val)
|
int addr_offset, int val)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *priv =
|
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||||
(struct tcan4x5x_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
tcan4x5x_check_wake(priv);
|
tcan4x5x_check_wake(priv);
|
||||||
|
|
||||||
|
@ -290,8 +288,7 @@ static int tcan4x5x_power_enable(struct regulator *reg, int enable)
|
||||||
static int tcan4x5x_write_tcan_reg(struct m_can_classdev *cdev,
|
static int tcan4x5x_write_tcan_reg(struct m_can_classdev *cdev,
|
||||||
int reg, int val)
|
int reg, int val)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *priv =
|
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||||
(struct tcan4x5x_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
tcan4x5x_check_wake(priv);
|
tcan4x5x_check_wake(priv);
|
||||||
|
|
||||||
|
@ -300,8 +297,7 @@ static int tcan4x5x_write_tcan_reg(struct m_can_classdev *cdev,
|
||||||
|
|
||||||
static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
|
static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *tcan4x5x =
|
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
||||||
(struct tcan4x5x_priv *)cdev->device_data;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tcan4x5x_check_wake(tcan4x5x);
|
tcan4x5x_check_wake(tcan4x5x);
|
||||||
|
@ -331,8 +327,7 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
|
||||||
|
|
||||||
static int tcan4x5x_init(struct m_can_classdev *cdev)
|
static int tcan4x5x_init(struct m_can_classdev *cdev)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *tcan4x5x =
|
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
||||||
(struct tcan4x5x_priv *)cdev->device_data;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tcan4x5x_check_wake(tcan4x5x);
|
tcan4x5x_check_wake(tcan4x5x);
|
||||||
|
@ -359,8 +354,7 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
|
||||||
|
|
||||||
static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *tcan4x5x =
|
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
||||||
(struct tcan4x5x_priv *)cdev->device_data;
|
|
||||||
|
|
||||||
tcan4x5x->interrupt_gpio = devm_gpiod_get(cdev->dev, "data-ready",
|
tcan4x5x->interrupt_gpio = devm_gpiod_get(cdev->dev, "data-ready",
|
||||||
GPIOD_IN);
|
GPIOD_IN);
|
||||||
|
@ -420,6 +414,9 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
||||||
int freq, ret;
|
int freq, ret;
|
||||||
|
|
||||||
mcan_class = m_can_class_allocate_dev(&spi->dev);
|
mcan_class = m_can_class_allocate_dev(&spi->dev);
|
||||||
|
if (!mcan_class)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
|
priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -466,8 +463,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
||||||
priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus,
|
priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus,
|
||||||
&spi->dev, &tcan4x5x_regmap);
|
&spi->dev, &tcan4x5x_regmap);
|
||||||
|
|
||||||
mutex_init(&priv->tcan4x5x_lock);
|
|
||||||
|
|
||||||
tcan4x5x_power_enable(priv->power, 1);
|
tcan4x5x_power_enable(priv->power, 1);
|
||||||
|
|
||||||
ret = m_can_class_register(mcan_class);
|
ret = m_can_class_register(mcan_class);
|
||||||
|
|
|
@ -15,11 +15,17 @@
|
||||||
#include <linux/can/led.h>
|
#include <linux/can/led.h>
|
||||||
#include <linux/can/dev.h>
|
#include <linux/can/dev.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/can/platform/rcar_can.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
|
||||||
#define RCAR_CAN_DRV_NAME "rcar_can"
|
#define RCAR_CAN_DRV_NAME "rcar_can"
|
||||||
|
|
||||||
|
/* Clock Select Register settings */
|
||||||
|
enum CLKR {
|
||||||
|
CLKR_CLKP1 = 0, /* Peripheral clock (clkp1) */
|
||||||
|
CLKR_CLKP2 = 1, /* Peripheral clock (clkp2) */
|
||||||
|
CLKR_CLKEXT = 3, /* Externally input clock */
|
||||||
|
};
|
||||||
|
|
||||||
#define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \
|
#define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \
|
||||||
BIT(CLKR_CLKEXT))
|
BIT(CLKR_CLKEXT))
|
||||||
|
|
||||||
|
@ -736,7 +742,6 @@ static const char * const clock_names[] = {
|
||||||
|
|
||||||
static int rcar_can_probe(struct platform_device *pdev)
|
static int rcar_can_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rcar_can_platform_data *pdata;
|
|
||||||
struct rcar_can_priv *priv;
|
struct rcar_can_priv *priv;
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
struct resource *mem;
|
struct resource *mem;
|
||||||
|
@ -745,17 +750,8 @@ static int rcar_can_probe(struct platform_device *pdev)
|
||||||
int err = -ENODEV;
|
int err = -ENODEV;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
if (pdev->dev.of_node) {
|
of_property_read_u32(pdev->dev.of_node, "renesas,can-clock-select",
|
||||||
of_property_read_u32(pdev->dev.of_node,
|
&clock_select);
|
||||||
"renesas,can-clock-select", &clock_select);
|
|
||||||
} else {
|
|
||||||
pdata = dev_get_platdata(&pdev->dev);
|
|
||||||
if (!pdata) {
|
|
||||||
dev_err(&pdev->dev, "No platform data provided!\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
clock_select = pdata->clock_select;
|
|
||||||
}
|
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (irq < 0) {
|
if (irq < 0) {
|
||||||
|
|
|
@ -417,7 +417,7 @@ static void peak_pciec_write_reg(const struct sja1000_priv *priv,
|
||||||
peak_pci_write_reg(priv, port, val);
|
peak_pci_write_reg(priv, port, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct i2c_algo_bit_data peak_pciec_i2c_bit_ops = {
|
static const struct i2c_algo_bit_data peak_pciec_i2c_bit_ops = {
|
||||||
.setsda = pita_setsda,
|
.setsda = pita_setsda,
|
||||||
.setscl = pita_setscl,
|
.setscl = pita_setscl,
|
||||||
.getsda = pita_getsda,
|
.getsda = pita_getsda,
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <linux/freezer.h>
|
#include <linux/freezer.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
@ -126,10 +125,6 @@
|
||||||
|
|
||||||
#define DEVICE_NAME "hi3110"
|
#define DEVICE_NAME "hi3110"
|
||||||
|
|
||||||
static int hi3110_enable_dma = 1; /* Enable SPI DMA. Default: 1 (On) */
|
|
||||||
module_param(hi3110_enable_dma, int, 0444);
|
|
||||||
MODULE_PARM_DESC(hi3110_enable_dma, "Enable SPI DMA. Default: 1 (On)");
|
|
||||||
|
|
||||||
static const struct can_bittiming_const hi3110_bittiming_const = {
|
static const struct can_bittiming_const hi3110_bittiming_const = {
|
||||||
.name = DEVICE_NAME,
|
.name = DEVICE_NAME,
|
||||||
.tseg1_min = 2,
|
.tseg1_min = 2,
|
||||||
|
@ -156,8 +151,6 @@ struct hi3110_priv {
|
||||||
|
|
||||||
u8 *spi_tx_buf;
|
u8 *spi_tx_buf;
|
||||||
u8 *spi_rx_buf;
|
u8 *spi_rx_buf;
|
||||||
dma_addr_t spi_tx_dma;
|
|
||||||
dma_addr_t spi_rx_dma;
|
|
||||||
|
|
||||||
struct sk_buff *tx_skb;
|
struct sk_buff *tx_skb;
|
||||||
int tx_len;
|
int tx_len;
|
||||||
|
@ -217,13 +210,6 @@ static int hi3110_spi_trans(struct spi_device *spi, int len)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spi_message_init(&m);
|
spi_message_init(&m);
|
||||||
|
|
||||||
if (hi3110_enable_dma) {
|
|
||||||
t.tx_dma = priv->spi_tx_dma;
|
|
||||||
t.rx_dma = priv->spi_rx_dma;
|
|
||||||
m.is_dma_mapped = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
spi_message_add_tail(&t, &m);
|
spi_message_add_tail(&t, &m);
|
||||||
|
|
||||||
ret = spi_sync(spi, &m);
|
ret = spi_sync(spi, &m);
|
||||||
|
@ -915,43 +901,18 @@ static int hi3110_can_probe(struct spi_device *spi)
|
||||||
priv->spi = spi;
|
priv->spi = spi;
|
||||||
mutex_init(&priv->hi3110_lock);
|
mutex_init(&priv->hi3110_lock);
|
||||||
|
|
||||||
/* If requested, allocate DMA buffers */
|
priv->spi_tx_buf = devm_kzalloc(&spi->dev, HI3110_RX_BUF_LEN,
|
||||||
if (hi3110_enable_dma) {
|
GFP_KERNEL);
|
||||||
spi->dev.coherent_dma_mask = ~0;
|
if (!priv->spi_tx_buf) {
|
||||||
|
ret = -ENOMEM;
|
||||||
/* Minimum coherent DMA allocation is PAGE_SIZE, so allocate
|
goto error_probe;
|
||||||
* that much and share it between Tx and Rx DMA buffers.
|
|
||||||
*/
|
|
||||||
priv->spi_tx_buf = dmam_alloc_coherent(&spi->dev,
|
|
||||||
PAGE_SIZE,
|
|
||||||
&priv->spi_tx_dma,
|
|
||||||
GFP_DMA);
|
|
||||||
|
|
||||||
if (priv->spi_tx_buf) {
|
|
||||||
priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2));
|
|
||||||
priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma +
|
|
||||||
(PAGE_SIZE / 2));
|
|
||||||
} else {
|
|
||||||
/* Fall back to non-DMA */
|
|
||||||
hi3110_enable_dma = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
priv->spi_rx_buf = devm_kzalloc(&spi->dev, HI3110_RX_BUF_LEN,
|
||||||
|
GFP_KERNEL);
|
||||||
|
|
||||||
/* Allocate non-DMA buffers */
|
if (!priv->spi_rx_buf) {
|
||||||
if (!hi3110_enable_dma) {
|
ret = -ENOMEM;
|
||||||
priv->spi_tx_buf = devm_kzalloc(&spi->dev, HI3110_RX_BUF_LEN,
|
goto error_probe;
|
||||||
GFP_KERNEL);
|
|
||||||
if (!priv->spi_tx_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto error_probe;
|
|
||||||
}
|
|
||||||
priv->spi_rx_buf = devm_kzalloc(&spi->dev, HI3110_RX_BUF_LEN,
|
|
||||||
GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!priv->spi_rx_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto error_probe;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_NETDEV_DEV(net, &spi->dev);
|
SET_NETDEV_DEV(net, &spi->dev);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/* CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface
|
||||||
* CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface
|
|
||||||
*
|
*
|
||||||
* MCP2510 support and bug fixes by Christian Pellegrin
|
* MCP2510 support and bug fixes by Christian Pellegrin
|
||||||
* <chripell@evolware.org>
|
* <chripell@evolware.org>
|
||||||
|
@ -48,7 +47,6 @@
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <linux/freezer.h>
|
#include <linux/freezer.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
@ -75,7 +73,6 @@
|
||||||
#define RTS_TXB2 0x04
|
#define RTS_TXB2 0x04
|
||||||
#define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07))
|
#define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07))
|
||||||
|
|
||||||
|
|
||||||
/* MPC251x registers */
|
/* MPC251x registers */
|
||||||
#define CANSTAT 0x0e
|
#define CANSTAT 0x0e
|
||||||
#define CANCTRL 0x0f
|
#define CANCTRL 0x0f
|
||||||
|
@ -191,8 +188,7 @@
|
||||||
#define SET_BYTE(val, byte) \
|
#define SET_BYTE(val, byte) \
|
||||||
(((val) & 0xff) << ((byte) * 8))
|
(((val) & 0xff) << ((byte) * 8))
|
||||||
|
|
||||||
/*
|
/* Buffer size required for the largest SPI transfer (i.e., reading a
|
||||||
* Buffer size required for the largest SPI transfer (i.e., reading a
|
|
||||||
* frame)
|
* frame)
|
||||||
*/
|
*/
|
||||||
#define CAN_FRAME_MAX_DATA_LEN 8
|
#define CAN_FRAME_MAX_DATA_LEN 8
|
||||||
|
@ -205,10 +201,6 @@
|
||||||
|
|
||||||
#define DEVICE_NAME "mcp251x"
|
#define DEVICE_NAME "mcp251x"
|
||||||
|
|
||||||
static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
|
|
||||||
module_param(mcp251x_enable_dma, int, 0444);
|
|
||||||
MODULE_PARM_DESC(mcp251x_enable_dma, "Enable SPI DMA. Default: 0 (Off)");
|
|
||||||
|
|
||||||
static const struct can_bittiming_const mcp251x_bittiming_const = {
|
static const struct can_bittiming_const mcp251x_bittiming_const = {
|
||||||
.name = DEVICE_NAME,
|
.name = DEVICE_NAME,
|
||||||
.tseg1_min = 3,
|
.tseg1_min = 3,
|
||||||
|
@ -237,8 +229,6 @@ struct mcp251x_priv {
|
||||||
|
|
||||||
u8 *spi_tx_buf;
|
u8 *spi_tx_buf;
|
||||||
u8 *spi_rx_buf;
|
u8 *spi_rx_buf;
|
||||||
dma_addr_t spi_tx_dma;
|
|
||||||
dma_addr_t spi_rx_dma;
|
|
||||||
|
|
||||||
struct sk_buff *tx_skb;
|
struct sk_buff *tx_skb;
|
||||||
int tx_len;
|
int tx_len;
|
||||||
|
@ -282,8 +272,7 @@ static void mcp251x_clean(struct net_device *net)
|
||||||
priv->tx_len = 0;
|
priv->tx_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Note about handling of error return of mcp251x_spi_trans: accessing
|
||||||
* Note about handling of error return of mcp251x_spi_trans: accessing
|
|
||||||
* registers via SPI is not really different conceptually than using
|
* registers via SPI is not really different conceptually than using
|
||||||
* normal I/O assembler instructions, although it's much more
|
* normal I/O assembler instructions, although it's much more
|
||||||
* complicated from a practical POV. So it's not advisable to always
|
* complicated from a practical POV. So it's not advisable to always
|
||||||
|
@ -308,13 +297,6 @@ static int mcp251x_spi_trans(struct spi_device *spi, int len)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spi_message_init(&m);
|
spi_message_init(&m);
|
||||||
|
|
||||||
if (mcp251x_enable_dma) {
|
|
||||||
t.tx_dma = priv->spi_tx_dma;
|
|
||||||
t.rx_dma = priv->spi_rx_dma;
|
|
||||||
m.is_dma_mapped = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
spi_message_add_tail(&t, &m);
|
spi_message_add_tail(&t, &m);
|
||||||
|
|
||||||
ret = spi_sync(spi, &m);
|
ret = spi_sync(spi, &m);
|
||||||
|
@ -323,7 +305,7 @@ static int mcp251x_spi_trans(struct spi_device *spi, int len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg)
|
static u8 mcp251x_read_reg(struct spi_device *spi, u8 reg)
|
||||||
{
|
{
|
||||||
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
||||||
u8 val = 0;
|
u8 val = 0;
|
||||||
|
@ -337,8 +319,7 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg,
|
static void mcp251x_read_2regs(struct spi_device *spi, u8 reg, u8 *v1, u8 *v2)
|
||||||
uint8_t *v1, uint8_t *v2)
|
|
||||||
{
|
{
|
||||||
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
||||||
|
|
||||||
|
@ -351,7 +332,7 @@ static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg,
|
||||||
*v2 = priv->spi_rx_buf[3];
|
*v2 = priv->spi_rx_buf[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val)
|
static void mcp251x_write_reg(struct spi_device *spi, u8 reg, u8 val)
|
||||||
{
|
{
|
||||||
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
||||||
|
|
||||||
|
@ -363,7 +344,7 @@ static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
|
static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
|
||||||
u8 mask, uint8_t val)
|
u8 mask, u8 val)
|
||||||
{
|
{
|
||||||
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
||||||
|
|
||||||
|
@ -565,8 +546,7 @@ static int mcp251x_set_normal_mode(struct spi_device *spi)
|
||||||
while (mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) {
|
while (mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) {
|
||||||
schedule();
|
schedule();
|
||||||
if (time_after(jiffies, timeout)) {
|
if (time_after(jiffies, timeout)) {
|
||||||
dev_err(&spi->dev, "MCP251x didn't"
|
dev_err(&spi->dev, "MCP251x didn't enter in normal mode\n");
|
||||||
" enter in normal mode\n");
|
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -612,7 +592,7 @@ static int mcp251x_setup(struct net_device *net, struct spi_device *spi)
|
||||||
static int mcp251x_hw_reset(struct spi_device *spi)
|
static int mcp251x_hw_reset(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
struct mcp251x_priv *priv = spi_get_drvdata(spi);
|
||||||
u8 reg;
|
unsigned long timeout;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Wait for oscillator startup timer after power up */
|
/* Wait for oscillator startup timer after power up */
|
||||||
|
@ -626,10 +606,19 @@ static int mcp251x_hw_reset(struct spi_device *spi)
|
||||||
/* Wait for oscillator startup timer after reset */
|
/* Wait for oscillator startup timer after reset */
|
||||||
mdelay(MCP251X_OST_DELAY_MS);
|
mdelay(MCP251X_OST_DELAY_MS);
|
||||||
|
|
||||||
reg = mcp251x_read_reg(spi, CANSTAT);
|
/* Wait for reset to finish */
|
||||||
if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
|
timeout = jiffies + HZ;
|
||||||
return -ENODEV;
|
while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) !=
|
||||||
|
CANCTRL_REQOP_CONF) {
|
||||||
|
usleep_range(MCP251X_OST_DELAY_MS * 1000,
|
||||||
|
MCP251X_OST_DELAY_MS * 1000 * 2);
|
||||||
|
|
||||||
|
if (time_after(jiffies, timeout)) {
|
||||||
|
dev_err(&spi->dev,
|
||||||
|
"MCP251x didn't enter in conf mode after reset\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,7 +788,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
|
||||||
* (The MCP2515/25625 does this automatically.)
|
* (The MCP2515/25625 does this automatically.)
|
||||||
*/
|
*/
|
||||||
if (mcp251x_is_2510(spi))
|
if (mcp251x_is_2510(spi))
|
||||||
mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
|
mcp251x_write_bits(spi, CANINTF,
|
||||||
|
CANINTF_RX0IF, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* receive buffer 1 */
|
/* receive buffer 1 */
|
||||||
|
@ -900,7 +890,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
netif_wake_queue(net);
|
netif_wake_queue(net);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&priv->mcp_lock);
|
mutex_unlock(&priv->mcp_lock);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@ -910,7 +899,7 @@ static int mcp251x_open(struct net_device *net)
|
||||||
{
|
{
|
||||||
struct mcp251x_priv *priv = netdev_priv(net);
|
struct mcp251x_priv *priv = netdev_priv(net);
|
||||||
struct spi_device *spi = priv->spi;
|
struct spi_device *spi = priv->spi;
|
||||||
unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING;
|
unsigned long flags = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = open_candev(net);
|
ret = open_candev(net);
|
||||||
|
@ -926,8 +915,12 @@ static int mcp251x_open(struct net_device *net)
|
||||||
priv->tx_skb = NULL;
|
priv->tx_skb = NULL;
|
||||||
priv->tx_len = 0;
|
priv->tx_len = 0;
|
||||||
|
|
||||||
|
if (!spi->dev.of_node)
|
||||||
|
flags = IRQF_TRIGGER_FALLING;
|
||||||
|
|
||||||
ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
|
ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
|
||||||
flags | IRQF_ONESHOT, DEVICE_NAME, priv);
|
flags | IRQF_ONESHOT, dev_name(&spi->dev),
|
||||||
|
priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
|
dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
|
@ -1090,43 +1083,18 @@ static int mcp251x_can_probe(struct spi_device *spi)
|
||||||
priv->spi = spi;
|
priv->spi = spi;
|
||||||
mutex_init(&priv->mcp_lock);
|
mutex_init(&priv->mcp_lock);
|
||||||
|
|
||||||
/* If requested, allocate DMA buffers */
|
priv->spi_tx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN,
|
||||||
if (mcp251x_enable_dma) {
|
GFP_KERNEL);
|
||||||
spi->dev.coherent_dma_mask = ~0;
|
if (!priv->spi_tx_buf) {
|
||||||
|
ret = -ENOMEM;
|
||||||
/*
|
goto error_probe;
|
||||||
* Minimum coherent DMA allocation is PAGE_SIZE, so allocate
|
|
||||||
* that much and share it between Tx and Rx DMA buffers.
|
|
||||||
*/
|
|
||||||
priv->spi_tx_buf = dmam_alloc_coherent(&spi->dev,
|
|
||||||
PAGE_SIZE,
|
|
||||||
&priv->spi_tx_dma,
|
|
||||||
GFP_DMA);
|
|
||||||
|
|
||||||
if (priv->spi_tx_buf) {
|
|
||||||
priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2));
|
|
||||||
priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma +
|
|
||||||
(PAGE_SIZE / 2));
|
|
||||||
} else {
|
|
||||||
/* Fall back to non-DMA */
|
|
||||||
mcp251x_enable_dma = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate non-DMA buffers */
|
priv->spi_rx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN,
|
||||||
if (!mcp251x_enable_dma) {
|
GFP_KERNEL);
|
||||||
priv->spi_tx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN,
|
if (!priv->spi_rx_buf) {
|
||||||
GFP_KERNEL);
|
ret = -ENOMEM;
|
||||||
if (!priv->spi_tx_buf) {
|
goto error_probe;
|
||||||
ret = -ENOMEM;
|
|
||||||
goto error_probe;
|
|
||||||
}
|
|
||||||
priv->spi_rx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!priv->spi_rx_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto error_probe;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_NETDEV_DEV(net, &spi->dev);
|
SET_NETDEV_DEV(net, &spi->dev);
|
||||||
|
@ -1135,7 +1103,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
|
||||||
ret = mcp251x_hw_probe(spi);
|
ret = mcp251x_hw_probe(spi);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -ENODEV)
|
if (ret == -ENODEV)
|
||||||
dev_err(&spi->dev, "Cannot initialize MCP%x. Wrong wiring?\n", priv->model);
|
dev_err(&spi->dev, "Cannot initialize MCP%x. Wrong wiring?\n",
|
||||||
|
priv->model);
|
||||||
goto error_probe;
|
goto error_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1189,8 +1158,7 @@ static int __maybe_unused mcp251x_can_suspend(struct device *dev)
|
||||||
|
|
||||||
priv->force_quit = 1;
|
priv->force_quit = 1;
|
||||||
disable_irq(spi->irq);
|
disable_irq(spi->irq);
|
||||||
/*
|
/* Note: at this point neither IST nor workqueues are running.
|
||||||
* Note: at this point neither IST nor workqueues are running.
|
|
||||||
* open/stop cannot be called anyway so locking is not needed
|
* open/stop cannot be called anyway so locking is not needed
|
||||||
*/
|
*/
|
||||||
if (netif_running(net)) {
|
if (netif_running(net)) {
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef _CAN_PLATFORM_RCAR_CAN_H_
|
|
||||||
#define _CAN_PLATFORM_RCAR_CAN_H_
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
/* Clock Select Register settings */
|
|
||||||
enum CLKR {
|
|
||||||
CLKR_CLKP1 = 0, /* Peripheral clock (clkp1) */
|
|
||||||
CLKR_CLKP2 = 1, /* Peripheral clock (clkp2) */
|
|
||||||
CLKR_CLKEXT = 3 /* Externally input clock */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rcar_can_platform_data {
|
|
||||||
enum CLKR clock_select; /* Clock source select */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* !_CAN_PLATFORM_RCAR_CAN_H_ */
|
|
Loading…
Reference in New Issue