diff options
Diffstat (limited to 'drivers/net/can/m_can/tcan4x5x.c')
-rw-r--r-- | drivers/net/can/m_can/tcan4x5x.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c index 7347ab39c5b6..24c737c4fc44 100644 --- a/drivers/net/can/m_can/tcan4x5x.c +++ b/drivers/net/can/m_can/tcan4x5x.c @@ -114,21 +114,23 @@ #define TCAN4X5X_WD_6_S_TIMER (BIT(28) | BIT(29)) struct tcan4x5x_priv { + struct m_can_classdev cdev; + struct regmap *regmap; struct spi_device *spi; - struct m_can_classdev *mcan_dev; - struct gpio_desc *reset_gpio; struct gpio_desc *device_wake_gpio; struct gpio_desc *device_state_gpio; struct regulator *power; - - /* Register based ip */ - int mram_start; - int reg_offset; }; +static inline struct tcan4x5x_priv *cdev_to_priv(struct m_can_classdev *cdev) +{ + return container_of(cdev, struct tcan4x5x_priv, cdev); + +} + static struct can_bittiming_const tcan4x5x_bittiming_const = { .name = DEVICE_NAME, .tseg1_min = 2, @@ -257,37 +259,37 @@ static struct regmap_bus tcan4x5x_bus = { static u32 tcan4x5x_read_reg(struct m_can_classdev *cdev, int reg) { - struct tcan4x5x_priv *priv = cdev->device_data; + struct tcan4x5x_priv *priv = cdev_to_priv(cdev); u32 val; - regmap_read(priv->regmap, priv->reg_offset + reg, &val); + regmap_read(priv->regmap, TCAN4X5X_MCAN_OFFSET + reg, &val); return val; } static u32 tcan4x5x_read_fifo(struct m_can_classdev *cdev, int addr_offset) { - struct tcan4x5x_priv *priv = cdev->device_data; + struct tcan4x5x_priv *priv = cdev_to_priv(cdev); u32 val; - regmap_read(priv->regmap, priv->mram_start + addr_offset, &val); + regmap_read(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, &val); return val; } static int tcan4x5x_write_reg(struct m_can_classdev *cdev, int reg, int val) { - struct tcan4x5x_priv *priv = cdev->device_data; + struct tcan4x5x_priv *priv = cdev_to_priv(cdev); - return regmap_write(priv->regmap, priv->reg_offset + reg, val); + return regmap_write(priv->regmap, TCAN4X5X_MCAN_OFFSET + reg, val); } static int tcan4x5x_write_fifo(struct m_can_classdev *cdev, int addr_offset, int val) { - struct tcan4x5x_priv *priv = cdev->device_data; + struct tcan4x5x_priv *priv = cdev_to_priv(cdev); - return regmap_write(priv->regmap, priv->mram_start + addr_offset, val); + return regmap_write(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, val); } static int tcan4x5x_power_enable(struct regulator *reg, int enable) @@ -304,7 +306,7 @@ static int tcan4x5x_power_enable(struct regulator *reg, int enable) static int tcan4x5x_write_tcan_reg(struct m_can_classdev *cdev, int reg, int val) { - struct tcan4x5x_priv *priv = cdev->device_data; + struct tcan4x5x_priv *priv = cdev_to_priv(cdev); return regmap_write(priv->regmap, reg, val); } @@ -328,17 +330,13 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev) if (ret) return ret; - ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS, - TCAN4X5X_CLEAR_ALL_INT); - if (ret) - return ret; - - return ret; + return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS, + TCAN4X5X_CLEAR_ALL_INT); } static int tcan4x5x_init(struct m_can_classdev *cdev) { - struct tcan4x5x_priv *tcan4x5x = cdev->device_data; + struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); int ret; tcan4x5x_check_wake(tcan4x5x); @@ -365,7 +363,7 @@ static int tcan4x5x_init(struct m_can_classdev *cdev) static int tcan4x5x_disable_wake(struct m_can_classdev *cdev) { - struct tcan4x5x_priv *tcan4x5x = cdev->device_data; + struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, TCAN4X5X_DISABLE_WAKE_MSK, 0x00); @@ -373,15 +371,15 @@ static int tcan4x5x_disable_wake(struct m_can_classdev *cdev) static int tcan4x5x_disable_state(struct m_can_classdev *cdev) { - struct tcan4x5x_priv *tcan4x5x = cdev->device_data; + struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, TCAN4X5X_DISABLE_INH_MSK, 0x01); } -static int tcan4x5x_parse_config(struct m_can_classdev *cdev) +static int tcan4x5x_get_gpios(struct m_can_classdev *cdev) { - struct tcan4x5x_priv *tcan4x5x = cdev->device_data; + struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); int ret; tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake", @@ -435,15 +433,12 @@ static int tcan4x5x_can_probe(struct spi_device *spi) struct m_can_classdev *mcan_class; int freq, ret; - mcan_class = m_can_class_allocate_dev(&spi->dev); + mcan_class = m_can_class_allocate_dev(&spi->dev, + sizeof(struct tcan4x5x_priv)); if (!mcan_class) return -ENOMEM; - priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto out_m_can_class_free_dev; - } + priv = cdev_to_priv(mcan_class); priv->power = devm_regulator_get_optional(&spi->dev, "vsup"); if (PTR_ERR(priv->power) == -EPROBE_DEFER) { @@ -453,8 +448,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi) priv->power = NULL; } - mcan_class->device_data = priv; - m_can_class_get_clocks(mcan_class); if (IS_ERR(mcan_class->cclk)) { dev_err(&spi->dev, "no CAN clock source defined\n"); @@ -469,10 +462,7 @@ static int tcan4x5x_can_probe(struct spi_device *spi) goto out_m_can_class_free_dev; } - priv->reg_offset = TCAN4X5X_MCAN_OFFSET; - priv->mram_start = TCAN4X5X_MRAM_START; priv->spi = spi; - priv->mcan_dev = mcan_class; mcan_class->pm_clock_support = 0; mcan_class->can.clock.freq = freq; @@ -502,7 +492,7 @@ static int tcan4x5x_can_probe(struct spi_device *spi) if (ret) goto out_m_can_class_free_dev; - ret = tcan4x5x_parse_config(mcan_class); + ret = tcan4x5x_get_gpios(mcan_class); if (ret) goto out_power; @@ -521,8 +511,6 @@ out_power: tcan4x5x_power_enable(priv->power, 0); out_m_can_class_free_dev: m_can_class_free_dev(mcan_class->net); - dev_err(&spi->dev, "Probe failed, err=%d\n", ret); - return ret; } @@ -530,11 +518,11 @@ static int tcan4x5x_can_remove(struct spi_device *spi) { struct tcan4x5x_priv *priv = spi_get_drvdata(spi); - m_can_class_unregister(priv->mcan_dev); + m_can_class_unregister(&priv->cdev); tcan4x5x_power_enable(priv->power, 0); - m_can_class_free_dev(priv->mcan_dev->net); + m_can_class_free_dev(priv->cdev.net); return 0; } |