10738eff1SGerhard Bertelsmann /*
20738eff1SGerhard Bertelsmann * sun4i_can.c - CAN bus controller driver for Allwinner SUN4I&SUN7I based SoCs
30738eff1SGerhard Bertelsmann *
40738eff1SGerhard Bertelsmann * Copyright (C) 2013 Peter Chen
50738eff1SGerhard Bertelsmann * Copyright (C) 2015 Gerhard Bertelsmann
60738eff1SGerhard Bertelsmann * All rights reserved.
70738eff1SGerhard Bertelsmann *
80738eff1SGerhard Bertelsmann * Parts of this software are based on (derived from) the SJA1000 code by:
90738eff1SGerhard Bertelsmann * Copyright (C) 2014 Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
100738eff1SGerhard Bertelsmann * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
110738eff1SGerhard Bertelsmann * Copyright (C) 2002-2007 Volkswagen Group Electronic Research
120738eff1SGerhard Bertelsmann * Copyright (C) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
130738eff1SGerhard Bertelsmann * 38106 Braunschweig, GERMANY
140738eff1SGerhard Bertelsmann *
150738eff1SGerhard Bertelsmann * Redistribution and use in source and binary forms, with or without
160738eff1SGerhard Bertelsmann * modification, are permitted provided that the following conditions
170738eff1SGerhard Bertelsmann * are met:
180738eff1SGerhard Bertelsmann * 1. Redistributions of source code must retain the above copyright
190738eff1SGerhard Bertelsmann * notice, this list of conditions and the following disclaimer.
200738eff1SGerhard Bertelsmann * 2. Redistributions in binary form must reproduce the above copyright
210738eff1SGerhard Bertelsmann * notice, this list of conditions and the following disclaimer in the
220738eff1SGerhard Bertelsmann * documentation and/or other materials provided with the distribution.
230738eff1SGerhard Bertelsmann * 3. Neither the name of Volkswagen nor the names of its contributors
240738eff1SGerhard Bertelsmann * may be used to endorse or promote products derived from this software
250738eff1SGerhard Bertelsmann * without specific prior written permission.
260738eff1SGerhard Bertelsmann *
270738eff1SGerhard Bertelsmann * Alternatively, provided that this notice is retained in full, this
280738eff1SGerhard Bertelsmann * software may be distributed under the terms of the GNU General
290738eff1SGerhard Bertelsmann * Public License ("GPL") version 2, in which case the provisions of the
300738eff1SGerhard Bertelsmann * GPL apply INSTEAD OF those given above.
310738eff1SGerhard Bertelsmann *
320738eff1SGerhard Bertelsmann * The provided data structures and external interfaces from this code
330738eff1SGerhard Bertelsmann * are not restricted to be used by modules with a GPL compatible license.
340738eff1SGerhard Bertelsmann *
350738eff1SGerhard Bertelsmann * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
360738eff1SGerhard Bertelsmann * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
370738eff1SGerhard Bertelsmann * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
380738eff1SGerhard Bertelsmann * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
390738eff1SGerhard Bertelsmann * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
400738eff1SGerhard Bertelsmann * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
410738eff1SGerhard Bertelsmann * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
420738eff1SGerhard Bertelsmann * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
430738eff1SGerhard Bertelsmann * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
440738eff1SGerhard Bertelsmann * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
450738eff1SGerhard Bertelsmann * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
460738eff1SGerhard Bertelsmann * DAMAGE.
470738eff1SGerhard Bertelsmann *
480738eff1SGerhard Bertelsmann */
490738eff1SGerhard Bertelsmann
500738eff1SGerhard Bertelsmann #include <linux/netdevice.h>
510738eff1SGerhard Bertelsmann #include <linux/can.h>
520738eff1SGerhard Bertelsmann #include <linux/can/dev.h>
530738eff1SGerhard Bertelsmann #include <linux/can/error.h>
540738eff1SGerhard Bertelsmann #include <linux/clk.h>
550738eff1SGerhard Bertelsmann #include <linux/delay.h>
56409c188cSVincent Mailhol #include <linux/ethtool.h>
570738eff1SGerhard Bertelsmann #include <linux/interrupt.h>
580738eff1SGerhard Bertelsmann #include <linux/init.h>
590738eff1SGerhard Bertelsmann #include <linux/io.h>
600738eff1SGerhard Bertelsmann #include <linux/module.h>
610738eff1SGerhard Bertelsmann #include <linux/of.h>
620738eff1SGerhard Bertelsmann #include <linux/platform_device.h>
632c2fd0e6SEvgeny Boger #include <linux/reset.h>
640738eff1SGerhard Bertelsmann
650738eff1SGerhard Bertelsmann #define DRV_NAME "sun4i_can"
660738eff1SGerhard Bertelsmann
670738eff1SGerhard Bertelsmann /* Registers address (physical base address 0x01C2BC00) */
680738eff1SGerhard Bertelsmann #define SUN4I_REG_MSEL_ADDR 0x0000 /* CAN Mode Select */
690738eff1SGerhard Bertelsmann #define SUN4I_REG_CMD_ADDR 0x0004 /* CAN Command */
700738eff1SGerhard Bertelsmann #define SUN4I_REG_STA_ADDR 0x0008 /* CAN Status */
710738eff1SGerhard Bertelsmann #define SUN4I_REG_INT_ADDR 0x000c /* CAN Interrupt Flag */
720738eff1SGerhard Bertelsmann #define SUN4I_REG_INTEN_ADDR 0x0010 /* CAN Interrupt Enable */
730738eff1SGerhard Bertelsmann #define SUN4I_REG_BTIME_ADDR 0x0014 /* CAN Bus Timing 0 */
740738eff1SGerhard Bertelsmann #define SUN4I_REG_TEWL_ADDR 0x0018 /* CAN Tx Error Warning Limit */
750738eff1SGerhard Bertelsmann #define SUN4I_REG_ERRC_ADDR 0x001c /* CAN Error Counter */
760738eff1SGerhard Bertelsmann #define SUN4I_REG_RMCNT_ADDR 0x0020 /* CAN Receive Message Counter */
770738eff1SGerhard Bertelsmann #define SUN4I_REG_RBUFSA_ADDR 0x0024 /* CAN Receive Buffer Start Address */
780738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF0_ADDR 0x0040 /* CAN Tx/Rx Buffer 0 */
790738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF1_ADDR 0x0044 /* CAN Tx/Rx Buffer 1 */
800738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF2_ADDR 0x0048 /* CAN Tx/Rx Buffer 2 */
810738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF3_ADDR 0x004c /* CAN Tx/Rx Buffer 3 */
820738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF4_ADDR 0x0050 /* CAN Tx/Rx Buffer 4 */
830738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF5_ADDR 0x0054 /* CAN Tx/Rx Buffer 5 */
840738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF6_ADDR 0x0058 /* CAN Tx/Rx Buffer 6 */
850738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF7_ADDR 0x005c /* CAN Tx/Rx Buffer 7 */
860738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF8_ADDR 0x0060 /* CAN Tx/Rx Buffer 8 */
870738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF9_ADDR 0x0064 /* CAN Tx/Rx Buffer 9 */
880738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF10_ADDR 0x0068 /* CAN Tx/Rx Buffer 10 */
890738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF11_ADDR 0x006c /* CAN Tx/Rx Buffer 11 */
900738eff1SGerhard Bertelsmann #define SUN4I_REG_BUF12_ADDR 0x0070 /* CAN Tx/Rx Buffer 12 */
910738eff1SGerhard Bertelsmann #define SUN4I_REG_ACPC_ADDR 0x0040 /* CAN Acceptance Code 0 */
920738eff1SGerhard Bertelsmann #define SUN4I_REG_ACPM_ADDR 0x0044 /* CAN Acceptance Mask 0 */
938abb9525SJohn Watts #define SUN4I_REG_ACPC_ADDR_D1 0x0028 /* CAN Acceptance Code 0 on the D1 */
948abb9525SJohn Watts #define SUN4I_REG_ACPM_ADDR_D1 0x002C /* CAN Acceptance Mask 0 on the D1 */
950738eff1SGerhard Bertelsmann #define SUN4I_REG_RBUF_RBACK_START_ADDR 0x0180 /* CAN transmit buffer start */
960738eff1SGerhard Bertelsmann #define SUN4I_REG_RBUF_RBACK_END_ADDR 0x01b0 /* CAN transmit buffer end */
970738eff1SGerhard Bertelsmann
980738eff1SGerhard Bertelsmann /* Controller Register Description */
990738eff1SGerhard Bertelsmann
1000738eff1SGerhard Bertelsmann /* mode select register (r/w)
1010738eff1SGerhard Bertelsmann * offset:0x0000 default:0x0000_0001
1020738eff1SGerhard Bertelsmann */
1030738eff1SGerhard Bertelsmann #define SUN4I_MSEL_SLEEP_MODE (0x01 << 4) /* write in reset mode */
1040738eff1SGerhard Bertelsmann #define SUN4I_MSEL_WAKE_UP (0x00 << 4)
1050738eff1SGerhard Bertelsmann #define SUN4I_MSEL_SINGLE_FILTER (0x01 << 3) /* write in reset mode */
1060738eff1SGerhard Bertelsmann #define SUN4I_MSEL_DUAL_FILTERS (0x00 << 3)
1070738eff1SGerhard Bertelsmann #define SUN4I_MSEL_LOOPBACK_MODE BIT(2)
1080738eff1SGerhard Bertelsmann #define SUN4I_MSEL_LISTEN_ONLY_MODE BIT(1)
1090738eff1SGerhard Bertelsmann #define SUN4I_MSEL_RESET_MODE BIT(0)
1100738eff1SGerhard Bertelsmann
1110738eff1SGerhard Bertelsmann /* command register (w)
1120738eff1SGerhard Bertelsmann * offset:0x0004 default:0x0000_0000
1130738eff1SGerhard Bertelsmann */
1140738eff1SGerhard Bertelsmann #define SUN4I_CMD_BUS_OFF_REQ BIT(5)
1150738eff1SGerhard Bertelsmann #define SUN4I_CMD_SELF_RCV_REQ BIT(4)
1160738eff1SGerhard Bertelsmann #define SUN4I_CMD_CLEAR_OR_FLAG BIT(3)
1170738eff1SGerhard Bertelsmann #define SUN4I_CMD_RELEASE_RBUF BIT(2)
1180738eff1SGerhard Bertelsmann #define SUN4I_CMD_ABORT_REQ BIT(1)
1190738eff1SGerhard Bertelsmann #define SUN4I_CMD_TRANS_REQ BIT(0)
1200738eff1SGerhard Bertelsmann
1210738eff1SGerhard Bertelsmann /* status register (r)
1220738eff1SGerhard Bertelsmann * offset:0x0008 default:0x0000_003c
1230738eff1SGerhard Bertelsmann */
1240738eff1SGerhard Bertelsmann #define SUN4I_STA_BIT_ERR (0x00 << 22)
1250738eff1SGerhard Bertelsmann #define SUN4I_STA_FORM_ERR (0x01 << 22)
1260738eff1SGerhard Bertelsmann #define SUN4I_STA_STUFF_ERR (0x02 << 22)
1270738eff1SGerhard Bertelsmann #define SUN4I_STA_OTHER_ERR (0x03 << 22)
1280738eff1SGerhard Bertelsmann #define SUN4I_STA_MASK_ERR (0x03 << 22)
1290738eff1SGerhard Bertelsmann #define SUN4I_STA_ERR_DIR BIT(21)
1300738eff1SGerhard Bertelsmann #define SUN4I_STA_ERR_SEG_CODE (0x1f << 16)
1310738eff1SGerhard Bertelsmann #define SUN4I_STA_START (0x03 << 16)
1320738eff1SGerhard Bertelsmann #define SUN4I_STA_ID28_21 (0x02 << 16)
1330738eff1SGerhard Bertelsmann #define SUN4I_STA_ID20_18 (0x06 << 16)
1340738eff1SGerhard Bertelsmann #define SUN4I_STA_SRTR (0x04 << 16)
1350738eff1SGerhard Bertelsmann #define SUN4I_STA_IDE (0x05 << 16)
1360738eff1SGerhard Bertelsmann #define SUN4I_STA_ID17_13 (0x07 << 16)
1370738eff1SGerhard Bertelsmann #define SUN4I_STA_ID12_5 (0x0f << 16)
1380738eff1SGerhard Bertelsmann #define SUN4I_STA_ID4_0 (0x0e << 16)
1390738eff1SGerhard Bertelsmann #define SUN4I_STA_RTR (0x0c << 16)
1400738eff1SGerhard Bertelsmann #define SUN4I_STA_RB1 (0x0d << 16)
1410738eff1SGerhard Bertelsmann #define SUN4I_STA_RB0 (0x09 << 16)
1420738eff1SGerhard Bertelsmann #define SUN4I_STA_DLEN (0x0b << 16)
1430738eff1SGerhard Bertelsmann #define SUN4I_STA_DATA_FIELD (0x0a << 16)
1440738eff1SGerhard Bertelsmann #define SUN4I_STA_CRC_SEQUENCE (0x08 << 16)
1450738eff1SGerhard Bertelsmann #define SUN4I_STA_CRC_DELIMITER (0x18 << 16)
1460738eff1SGerhard Bertelsmann #define SUN4I_STA_ACK (0x19 << 16)
1470738eff1SGerhard Bertelsmann #define SUN4I_STA_ACK_DELIMITER (0x1b << 16)
1480738eff1SGerhard Bertelsmann #define SUN4I_STA_END (0x1a << 16)
1490738eff1SGerhard Bertelsmann #define SUN4I_STA_INTERMISSION (0x12 << 16)
1500738eff1SGerhard Bertelsmann #define SUN4I_STA_ACTIVE_ERROR (0x11 << 16)
1510738eff1SGerhard Bertelsmann #define SUN4I_STA_PASSIVE_ERROR (0x16 << 16)
1520738eff1SGerhard Bertelsmann #define SUN4I_STA_TOLERATE_DOMINANT_BITS (0x13 << 16)
1530738eff1SGerhard Bertelsmann #define SUN4I_STA_ERROR_DELIMITER (0x17 << 16)
1540738eff1SGerhard Bertelsmann #define SUN4I_STA_OVERLOAD (0x1c << 16)
1550738eff1SGerhard Bertelsmann #define SUN4I_STA_BUS_OFF BIT(7)
1560738eff1SGerhard Bertelsmann #define SUN4I_STA_ERR_STA BIT(6)
1570738eff1SGerhard Bertelsmann #define SUN4I_STA_TRANS_BUSY BIT(5)
1580738eff1SGerhard Bertelsmann #define SUN4I_STA_RCV_BUSY BIT(4)
1590738eff1SGerhard Bertelsmann #define SUN4I_STA_TRANS_OVER BIT(3)
1600738eff1SGerhard Bertelsmann #define SUN4I_STA_TBUF_RDY BIT(2)
1610738eff1SGerhard Bertelsmann #define SUN4I_STA_DATA_ORUN BIT(1)
1620738eff1SGerhard Bertelsmann #define SUN4I_STA_RBUF_RDY BIT(0)
1630738eff1SGerhard Bertelsmann
1640738eff1SGerhard Bertelsmann /* interrupt register (r)
1650738eff1SGerhard Bertelsmann * offset:0x000c default:0x0000_0000
1660738eff1SGerhard Bertelsmann */
1670738eff1SGerhard Bertelsmann #define SUN4I_INT_BUS_ERR BIT(7)
1680738eff1SGerhard Bertelsmann #define SUN4I_INT_ARB_LOST BIT(6)
1690738eff1SGerhard Bertelsmann #define SUN4I_INT_ERR_PASSIVE BIT(5)
1700738eff1SGerhard Bertelsmann #define SUN4I_INT_WAKEUP BIT(4)
1710738eff1SGerhard Bertelsmann #define SUN4I_INT_DATA_OR BIT(3)
1720738eff1SGerhard Bertelsmann #define SUN4I_INT_ERR_WRN BIT(2)
1730738eff1SGerhard Bertelsmann #define SUN4I_INT_TBUF_VLD BIT(1)
1740738eff1SGerhard Bertelsmann #define SUN4I_INT_RBUF_VLD BIT(0)
1750738eff1SGerhard Bertelsmann
1760738eff1SGerhard Bertelsmann /* interrupt enable register (r/w)
1770738eff1SGerhard Bertelsmann * offset:0x0010 default:0x0000_0000
1780738eff1SGerhard Bertelsmann */
1790738eff1SGerhard Bertelsmann #define SUN4I_INTEN_BERR BIT(7)
1800738eff1SGerhard Bertelsmann #define SUN4I_INTEN_ARB_LOST BIT(6)
1810738eff1SGerhard Bertelsmann #define SUN4I_INTEN_ERR_PASSIVE BIT(5)
1820738eff1SGerhard Bertelsmann #define SUN4I_INTEN_WAKEUP BIT(4)
1830738eff1SGerhard Bertelsmann #define SUN4I_INTEN_OR BIT(3)
1840738eff1SGerhard Bertelsmann #define SUN4I_INTEN_ERR_WRN BIT(2)
1850738eff1SGerhard Bertelsmann #define SUN4I_INTEN_TX BIT(1)
1860738eff1SGerhard Bertelsmann #define SUN4I_INTEN_RX BIT(0)
1870738eff1SGerhard Bertelsmann
1880738eff1SGerhard Bertelsmann /* error code */
1890738eff1SGerhard Bertelsmann #define SUN4I_ERR_INRCV (0x1 << 5)
1900738eff1SGerhard Bertelsmann #define SUN4I_ERR_INTRANS (0x0 << 5)
1910738eff1SGerhard Bertelsmann
1920738eff1SGerhard Bertelsmann /* filter mode */
1930738eff1SGerhard Bertelsmann #define SUN4I_FILTER_CLOSE 0
1940738eff1SGerhard Bertelsmann #define SUN4I_SINGLE_FLTER_MODE 1
1950738eff1SGerhard Bertelsmann #define SUN4I_DUAL_FILTER_MODE 2
1960738eff1SGerhard Bertelsmann
1970738eff1SGerhard Bertelsmann /* message buffer flags */
1980738eff1SGerhard Bertelsmann #define SUN4I_MSG_EFF_FLAG BIT(7)
1990738eff1SGerhard Bertelsmann #define SUN4I_MSG_RTR_FLAG BIT(6)
2000738eff1SGerhard Bertelsmann
2010738eff1SGerhard Bertelsmann /* max. number of interrupts handled in ISR */
2020738eff1SGerhard Bertelsmann #define SUN4I_CAN_MAX_IRQ 20
2030738eff1SGerhard Bertelsmann #define SUN4I_MODE_MAX_RETRIES 100
2040738eff1SGerhard Bertelsmann
2052c2fd0e6SEvgeny Boger /**
2062c2fd0e6SEvgeny Boger * struct sun4ican_quirks - Differences between SoC variants.
2072c2fd0e6SEvgeny Boger *
2082c2fd0e6SEvgeny Boger * @has_reset: SoC needs reset deasserted.
2098cda0c6dSJohn Watts * @acp_offset: Offset of ACPC and ACPM registers
2102c2fd0e6SEvgeny Boger */
2112c2fd0e6SEvgeny Boger struct sun4ican_quirks {
2122c2fd0e6SEvgeny Boger bool has_reset;
2138cda0c6dSJohn Watts int acp_offset;
2142c2fd0e6SEvgeny Boger };
2152c2fd0e6SEvgeny Boger
2160738eff1SGerhard Bertelsmann struct sun4ican_priv {
2170738eff1SGerhard Bertelsmann struct can_priv can;
2180738eff1SGerhard Bertelsmann void __iomem *base;
2190738eff1SGerhard Bertelsmann struct clk *clk;
2202c2fd0e6SEvgeny Boger struct reset_control *reset;
2210738eff1SGerhard Bertelsmann spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */
2228cda0c6dSJohn Watts int acp_offset;
2230738eff1SGerhard Bertelsmann };
2240738eff1SGerhard Bertelsmann
2250738eff1SGerhard Bertelsmann static const struct can_bittiming_const sun4ican_bittiming_const = {
2260738eff1SGerhard Bertelsmann .name = DRV_NAME,
2270738eff1SGerhard Bertelsmann .tseg1_min = 1,
2280738eff1SGerhard Bertelsmann .tseg1_max = 16,
2290738eff1SGerhard Bertelsmann .tseg2_min = 1,
2300738eff1SGerhard Bertelsmann .tseg2_max = 8,
2310738eff1SGerhard Bertelsmann .sjw_max = 4,
2320738eff1SGerhard Bertelsmann .brp_min = 1,
2330738eff1SGerhard Bertelsmann .brp_max = 64,
2340738eff1SGerhard Bertelsmann .brp_inc = 1,
2350738eff1SGerhard Bertelsmann };
2360738eff1SGerhard Bertelsmann
sun4i_can_write_cmdreg(struct sun4ican_priv * priv,u8 val)2370738eff1SGerhard Bertelsmann static void sun4i_can_write_cmdreg(struct sun4ican_priv *priv, u8 val)
2380738eff1SGerhard Bertelsmann {
2390738eff1SGerhard Bertelsmann unsigned long flags;
2400738eff1SGerhard Bertelsmann
2410738eff1SGerhard Bertelsmann spin_lock_irqsave(&priv->cmdreg_lock, flags);
2420738eff1SGerhard Bertelsmann writel(val, priv->base + SUN4I_REG_CMD_ADDR);
2430738eff1SGerhard Bertelsmann spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
2440738eff1SGerhard Bertelsmann }
2450738eff1SGerhard Bertelsmann
set_normal_mode(struct net_device * dev)2460738eff1SGerhard Bertelsmann static int set_normal_mode(struct net_device *dev)
2470738eff1SGerhard Bertelsmann {
2480738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
2490738eff1SGerhard Bertelsmann int retry = SUN4I_MODE_MAX_RETRIES;
2500738eff1SGerhard Bertelsmann u32 mod_reg_val = 0;
2510738eff1SGerhard Bertelsmann
2520738eff1SGerhard Bertelsmann do {
2530738eff1SGerhard Bertelsmann mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR);
2540738eff1SGerhard Bertelsmann mod_reg_val &= ~SUN4I_MSEL_RESET_MODE;
2550738eff1SGerhard Bertelsmann writel(mod_reg_val, priv->base + SUN4I_REG_MSEL_ADDR);
2560738eff1SGerhard Bertelsmann } while (retry-- && (mod_reg_val & SUN4I_MSEL_RESET_MODE));
2570738eff1SGerhard Bertelsmann
2580738eff1SGerhard Bertelsmann if (readl(priv->base + SUN4I_REG_MSEL_ADDR) & SUN4I_MSEL_RESET_MODE) {
2590738eff1SGerhard Bertelsmann netdev_err(dev,
2600738eff1SGerhard Bertelsmann "setting controller into normal mode failed!\n");
2610738eff1SGerhard Bertelsmann return -ETIMEDOUT;
2620738eff1SGerhard Bertelsmann }
2630738eff1SGerhard Bertelsmann
2640738eff1SGerhard Bertelsmann return 0;
2650738eff1SGerhard Bertelsmann }
2660738eff1SGerhard Bertelsmann
set_reset_mode(struct net_device * dev)2670738eff1SGerhard Bertelsmann static int set_reset_mode(struct net_device *dev)
2680738eff1SGerhard Bertelsmann {
2690738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
2700738eff1SGerhard Bertelsmann int retry = SUN4I_MODE_MAX_RETRIES;
2710738eff1SGerhard Bertelsmann u32 mod_reg_val = 0;
2720738eff1SGerhard Bertelsmann
2730738eff1SGerhard Bertelsmann do {
2740738eff1SGerhard Bertelsmann mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR);
2750738eff1SGerhard Bertelsmann mod_reg_val |= SUN4I_MSEL_RESET_MODE;
2760738eff1SGerhard Bertelsmann writel(mod_reg_val, priv->base + SUN4I_REG_MSEL_ADDR);
2770738eff1SGerhard Bertelsmann } while (retry-- && !(mod_reg_val & SUN4I_MSEL_RESET_MODE));
2780738eff1SGerhard Bertelsmann
2790738eff1SGerhard Bertelsmann if (!(readl(priv->base + SUN4I_REG_MSEL_ADDR) &
2800738eff1SGerhard Bertelsmann SUN4I_MSEL_RESET_MODE)) {
2810738eff1SGerhard Bertelsmann netdev_err(dev, "setting controller into reset mode failed!\n");
2820738eff1SGerhard Bertelsmann return -ETIMEDOUT;
2830738eff1SGerhard Bertelsmann }
2840738eff1SGerhard Bertelsmann
2850738eff1SGerhard Bertelsmann return 0;
2860738eff1SGerhard Bertelsmann }
2870738eff1SGerhard Bertelsmann
2880738eff1SGerhard Bertelsmann /* bittiming is called in reset_mode only */
sun4ican_set_bittiming(struct net_device * dev)2890738eff1SGerhard Bertelsmann static int sun4ican_set_bittiming(struct net_device *dev)
2900738eff1SGerhard Bertelsmann {
2910738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
2920738eff1SGerhard Bertelsmann struct can_bittiming *bt = &priv->can.bittiming;
2930738eff1SGerhard Bertelsmann u32 cfg;
2940738eff1SGerhard Bertelsmann
2950738eff1SGerhard Bertelsmann cfg = ((bt->brp - 1) & 0x3FF) |
2960738eff1SGerhard Bertelsmann (((bt->sjw - 1) & 0x3) << 14) |
2970738eff1SGerhard Bertelsmann (((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) << 16) |
2980738eff1SGerhard Bertelsmann (((bt->phase_seg2 - 1) & 0x7) << 20);
2990738eff1SGerhard Bertelsmann if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
3000738eff1SGerhard Bertelsmann cfg |= 0x800000;
3010738eff1SGerhard Bertelsmann
3020738eff1SGerhard Bertelsmann netdev_dbg(dev, "setting BITTIMING=0x%08x\n", cfg);
3030738eff1SGerhard Bertelsmann writel(cfg, priv->base + SUN4I_REG_BTIME_ADDR);
3040738eff1SGerhard Bertelsmann
3050738eff1SGerhard Bertelsmann return 0;
3060738eff1SGerhard Bertelsmann }
3070738eff1SGerhard Bertelsmann
sun4ican_get_berr_counter(const struct net_device * dev,struct can_berr_counter * bec)3080738eff1SGerhard Bertelsmann static int sun4ican_get_berr_counter(const struct net_device *dev,
3090738eff1SGerhard Bertelsmann struct can_berr_counter *bec)
3100738eff1SGerhard Bertelsmann {
3110738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
3120738eff1SGerhard Bertelsmann u32 errors;
3130738eff1SGerhard Bertelsmann int err;
3140738eff1SGerhard Bertelsmann
3150738eff1SGerhard Bertelsmann err = clk_prepare_enable(priv->clk);
3160738eff1SGerhard Bertelsmann if (err) {
3170738eff1SGerhard Bertelsmann netdev_err(dev, "could not enable clock\n");
3180738eff1SGerhard Bertelsmann return err;
3190738eff1SGerhard Bertelsmann }
3200738eff1SGerhard Bertelsmann
3210738eff1SGerhard Bertelsmann errors = readl(priv->base + SUN4I_REG_ERRC_ADDR);
3220738eff1SGerhard Bertelsmann
3230738eff1SGerhard Bertelsmann bec->txerr = errors & 0xFF;
3240738eff1SGerhard Bertelsmann bec->rxerr = (errors >> 16) & 0xFF;
3250738eff1SGerhard Bertelsmann
3260738eff1SGerhard Bertelsmann clk_disable_unprepare(priv->clk);
3270738eff1SGerhard Bertelsmann
3280738eff1SGerhard Bertelsmann return 0;
3290738eff1SGerhard Bertelsmann }
3300738eff1SGerhard Bertelsmann
sun4i_can_start(struct net_device * dev)3310738eff1SGerhard Bertelsmann static int sun4i_can_start(struct net_device *dev)
3320738eff1SGerhard Bertelsmann {
3330738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
3340738eff1SGerhard Bertelsmann int err;
3350738eff1SGerhard Bertelsmann u32 mod_reg_val;
3360738eff1SGerhard Bertelsmann
3370738eff1SGerhard Bertelsmann /* we need to enter the reset mode */
3380738eff1SGerhard Bertelsmann err = set_reset_mode(dev);
3390738eff1SGerhard Bertelsmann if (err) {
3400738eff1SGerhard Bertelsmann netdev_err(dev, "could not enter reset mode\n");
3410738eff1SGerhard Bertelsmann return err;
3420738eff1SGerhard Bertelsmann }
3430738eff1SGerhard Bertelsmann
3440738eff1SGerhard Bertelsmann /* set filters - we accept all */
3458cda0c6dSJohn Watts writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR + priv->acp_offset);
3468cda0c6dSJohn Watts writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR + priv->acp_offset);
3470738eff1SGerhard Bertelsmann
3480738eff1SGerhard Bertelsmann /* clear error counters and error code capture */
3490738eff1SGerhard Bertelsmann writel(0, priv->base + SUN4I_REG_ERRC_ADDR);
3500738eff1SGerhard Bertelsmann
3510738eff1SGerhard Bertelsmann /* enable interrupts */
3520738eff1SGerhard Bertelsmann if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
3530738eff1SGerhard Bertelsmann writel(0xFF, priv->base + SUN4I_REG_INTEN_ADDR);
3540738eff1SGerhard Bertelsmann else
3550738eff1SGerhard Bertelsmann writel(0xFF & ~SUN4I_INTEN_BERR,
3560738eff1SGerhard Bertelsmann priv->base + SUN4I_REG_INTEN_ADDR);
3570738eff1SGerhard Bertelsmann
3580738eff1SGerhard Bertelsmann /* enter the selected mode */
3590738eff1SGerhard Bertelsmann mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR);
3603a379f5bSGerhard Bertelsmann if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
3610738eff1SGerhard Bertelsmann mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE;
3620738eff1SGerhard Bertelsmann else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
3630738eff1SGerhard Bertelsmann mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE;
3640738eff1SGerhard Bertelsmann writel(mod_reg_val, priv->base + SUN4I_REG_MSEL_ADDR);
3650738eff1SGerhard Bertelsmann
3660738eff1SGerhard Bertelsmann err = sun4ican_set_bittiming(dev);
3670738eff1SGerhard Bertelsmann if (err)
3680738eff1SGerhard Bertelsmann return err;
3690738eff1SGerhard Bertelsmann
3700738eff1SGerhard Bertelsmann /* we are ready to enter the normal mode */
3710738eff1SGerhard Bertelsmann err = set_normal_mode(dev);
3720738eff1SGerhard Bertelsmann if (err) {
3730738eff1SGerhard Bertelsmann netdev_err(dev, "could not enter normal mode\n");
3740738eff1SGerhard Bertelsmann return err;
3750738eff1SGerhard Bertelsmann }
3760738eff1SGerhard Bertelsmann
3770738eff1SGerhard Bertelsmann priv->can.state = CAN_STATE_ERROR_ACTIVE;
3780738eff1SGerhard Bertelsmann
3790738eff1SGerhard Bertelsmann return 0;
3800738eff1SGerhard Bertelsmann }
3810738eff1SGerhard Bertelsmann
sun4i_can_stop(struct net_device * dev)3820738eff1SGerhard Bertelsmann static int sun4i_can_stop(struct net_device *dev)
3830738eff1SGerhard Bertelsmann {
3840738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
3850738eff1SGerhard Bertelsmann int err;
3860738eff1SGerhard Bertelsmann
3870738eff1SGerhard Bertelsmann priv->can.state = CAN_STATE_STOPPED;
3880738eff1SGerhard Bertelsmann /* we need to enter reset mode */
3890738eff1SGerhard Bertelsmann err = set_reset_mode(dev);
3900738eff1SGerhard Bertelsmann if (err) {
3910738eff1SGerhard Bertelsmann netdev_err(dev, "could not enter reset mode\n");
3920738eff1SGerhard Bertelsmann return err;
3930738eff1SGerhard Bertelsmann }
3940738eff1SGerhard Bertelsmann
3950738eff1SGerhard Bertelsmann /* disable all interrupts */
3960738eff1SGerhard Bertelsmann writel(0, priv->base + SUN4I_REG_INTEN_ADDR);
3970738eff1SGerhard Bertelsmann
3980738eff1SGerhard Bertelsmann return 0;
3990738eff1SGerhard Bertelsmann }
4000738eff1SGerhard Bertelsmann
sun4ican_set_mode(struct net_device * dev,enum can_mode mode)4010738eff1SGerhard Bertelsmann static int sun4ican_set_mode(struct net_device *dev, enum can_mode mode)
4020738eff1SGerhard Bertelsmann {
4030738eff1SGerhard Bertelsmann int err;
4040738eff1SGerhard Bertelsmann
4050738eff1SGerhard Bertelsmann switch (mode) {
4060738eff1SGerhard Bertelsmann case CAN_MODE_START:
4070738eff1SGerhard Bertelsmann err = sun4i_can_start(dev);
4080738eff1SGerhard Bertelsmann if (err) {
4090738eff1SGerhard Bertelsmann netdev_err(dev, "starting CAN controller failed!\n");
4100738eff1SGerhard Bertelsmann return err;
4110738eff1SGerhard Bertelsmann }
4120738eff1SGerhard Bertelsmann if (netif_queue_stopped(dev))
4130738eff1SGerhard Bertelsmann netif_wake_queue(dev);
4140738eff1SGerhard Bertelsmann break;
4150738eff1SGerhard Bertelsmann
4160738eff1SGerhard Bertelsmann default:
4170738eff1SGerhard Bertelsmann return -EOPNOTSUPP;
4180738eff1SGerhard Bertelsmann }
4190738eff1SGerhard Bertelsmann return 0;
4200738eff1SGerhard Bertelsmann }
4210738eff1SGerhard Bertelsmann
4220738eff1SGerhard Bertelsmann /* transmit a CAN message
4230738eff1SGerhard Bertelsmann * message layout in the sk_buff should be like this:
4240738eff1SGerhard Bertelsmann * xx xx xx xx ff ll 00 11 22 33 44 55 66 77
4250738eff1SGerhard Bertelsmann * [ can_id ] [flags] [len] [can data (up to 8 bytes]
4260738eff1SGerhard Bertelsmann */
sun4ican_start_xmit(struct sk_buff * skb,struct net_device * dev)42779b110bbSLuc Van Oostenryck static netdev_tx_t sun4ican_start_xmit(struct sk_buff *skb, struct net_device *dev)
4280738eff1SGerhard Bertelsmann {
4290738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
4300738eff1SGerhard Bertelsmann struct can_frame *cf = (struct can_frame *)skb->data;
4310738eff1SGerhard Bertelsmann u8 dlc;
4320738eff1SGerhard Bertelsmann u32 dreg, msg_flag_n;
4330738eff1SGerhard Bertelsmann canid_t id;
4340738eff1SGerhard Bertelsmann int i;
4350738eff1SGerhard Bertelsmann
436ae64438bSOliver Hartkopp if (can_dev_dropped_skb(dev, skb))
4370738eff1SGerhard Bertelsmann return NETDEV_TX_OK;
4380738eff1SGerhard Bertelsmann
4390738eff1SGerhard Bertelsmann netif_stop_queue(dev);
4400738eff1SGerhard Bertelsmann
4410738eff1SGerhard Bertelsmann id = cf->can_id;
442c7b74967SOliver Hartkopp dlc = cf->len;
4430738eff1SGerhard Bertelsmann msg_flag_n = dlc;
4440738eff1SGerhard Bertelsmann
4450738eff1SGerhard Bertelsmann if (id & CAN_RTR_FLAG)
4460738eff1SGerhard Bertelsmann msg_flag_n |= SUN4I_MSG_RTR_FLAG;
4470738eff1SGerhard Bertelsmann
4480738eff1SGerhard Bertelsmann if (id & CAN_EFF_FLAG) {
4490738eff1SGerhard Bertelsmann msg_flag_n |= SUN4I_MSG_EFF_FLAG;
4500738eff1SGerhard Bertelsmann dreg = SUN4I_REG_BUF5_ADDR;
4510738eff1SGerhard Bertelsmann writel((id >> 21) & 0xFF, priv->base + SUN4I_REG_BUF1_ADDR);
4520738eff1SGerhard Bertelsmann writel((id >> 13) & 0xFF, priv->base + SUN4I_REG_BUF2_ADDR);
4530738eff1SGerhard Bertelsmann writel((id >> 5) & 0xFF, priv->base + SUN4I_REG_BUF3_ADDR);
4540738eff1SGerhard Bertelsmann writel((id << 3) & 0xF8, priv->base + SUN4I_REG_BUF4_ADDR);
4550738eff1SGerhard Bertelsmann } else {
4560738eff1SGerhard Bertelsmann dreg = SUN4I_REG_BUF3_ADDR;
4570738eff1SGerhard Bertelsmann writel((id >> 3) & 0xFF, priv->base + SUN4I_REG_BUF1_ADDR);
4580738eff1SGerhard Bertelsmann writel((id << 5) & 0xE0, priv->base + SUN4I_REG_BUF2_ADDR);
4590738eff1SGerhard Bertelsmann }
4600738eff1SGerhard Bertelsmann
4610738eff1SGerhard Bertelsmann for (i = 0; i < dlc; i++)
4620738eff1SGerhard Bertelsmann writel(cf->data[i], priv->base + (dreg + i * 4));
4630738eff1SGerhard Bertelsmann
4640738eff1SGerhard Bertelsmann writel(msg_flag_n, priv->base + SUN4I_REG_BUF0_ADDR);
4650738eff1SGerhard Bertelsmann
4661dcb6e57SVincent Mailhol can_put_echo_skb(skb, dev, 0, 0);
4670738eff1SGerhard Bertelsmann
4680738eff1SGerhard Bertelsmann if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
4690738eff1SGerhard Bertelsmann sun4i_can_write_cmdreg(priv, SUN4I_CMD_SELF_RCV_REQ);
4700738eff1SGerhard Bertelsmann else
4710738eff1SGerhard Bertelsmann sun4i_can_write_cmdreg(priv, SUN4I_CMD_TRANS_REQ);
4720738eff1SGerhard Bertelsmann
4730738eff1SGerhard Bertelsmann return NETDEV_TX_OK;
4740738eff1SGerhard Bertelsmann }
4750738eff1SGerhard Bertelsmann
sun4i_can_rx(struct net_device * dev)4760738eff1SGerhard Bertelsmann static void sun4i_can_rx(struct net_device *dev)
4770738eff1SGerhard Bertelsmann {
4780738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
4790738eff1SGerhard Bertelsmann struct net_device_stats *stats = &dev->stats;
4800738eff1SGerhard Bertelsmann struct can_frame *cf;
4810738eff1SGerhard Bertelsmann struct sk_buff *skb;
4820738eff1SGerhard Bertelsmann u8 fi;
4830738eff1SGerhard Bertelsmann u32 dreg;
4840738eff1SGerhard Bertelsmann canid_t id;
4850738eff1SGerhard Bertelsmann int i;
4860738eff1SGerhard Bertelsmann
4870738eff1SGerhard Bertelsmann /* create zero'ed CAN frame buffer */
4880738eff1SGerhard Bertelsmann skb = alloc_can_skb(dev, &cf);
4890738eff1SGerhard Bertelsmann if (!skb)
4900738eff1SGerhard Bertelsmann return;
4910738eff1SGerhard Bertelsmann
4920738eff1SGerhard Bertelsmann fi = readl(priv->base + SUN4I_REG_BUF0_ADDR);
493c7b74967SOliver Hartkopp cf->len = can_cc_dlc2len(fi & 0x0F);
4940738eff1SGerhard Bertelsmann if (fi & SUN4I_MSG_EFF_FLAG) {
4950738eff1SGerhard Bertelsmann dreg = SUN4I_REG_BUF5_ADDR;
4960738eff1SGerhard Bertelsmann id = (readl(priv->base + SUN4I_REG_BUF1_ADDR) << 21) |
4970738eff1SGerhard Bertelsmann (readl(priv->base + SUN4I_REG_BUF2_ADDR) << 13) |
4980738eff1SGerhard Bertelsmann (readl(priv->base + SUN4I_REG_BUF3_ADDR) << 5) |
4990738eff1SGerhard Bertelsmann ((readl(priv->base + SUN4I_REG_BUF4_ADDR) >> 3) & 0x1f);
5000738eff1SGerhard Bertelsmann id |= CAN_EFF_FLAG;
5010738eff1SGerhard Bertelsmann } else {
5020738eff1SGerhard Bertelsmann dreg = SUN4I_REG_BUF3_ADDR;
5030738eff1SGerhard Bertelsmann id = (readl(priv->base + SUN4I_REG_BUF1_ADDR) << 3) |
5040738eff1SGerhard Bertelsmann ((readl(priv->base + SUN4I_REG_BUF2_ADDR) >> 5) & 0x7);
5050738eff1SGerhard Bertelsmann }
5060738eff1SGerhard Bertelsmann
5070738eff1SGerhard Bertelsmann /* remote frame ? */
5088e674ca7SVincent Mailhol if (fi & SUN4I_MSG_RTR_FLAG) {
5090738eff1SGerhard Bertelsmann id |= CAN_RTR_FLAG;
5108e674ca7SVincent Mailhol } else {
511c7b74967SOliver Hartkopp for (i = 0; i < cf->len; i++)
5120738eff1SGerhard Bertelsmann cf->data[i] = readl(priv->base + dreg + i * 4);
5130738eff1SGerhard Bertelsmann
5148e674ca7SVincent Mailhol stats->rx_bytes += cf->len;
5158e674ca7SVincent Mailhol }
5168e674ca7SVincent Mailhol stats->rx_packets++;
5178e674ca7SVincent Mailhol
5180738eff1SGerhard Bertelsmann cf->can_id = id;
5190738eff1SGerhard Bertelsmann
5200738eff1SGerhard Bertelsmann sun4i_can_write_cmdreg(priv, SUN4I_CMD_RELEASE_RBUF);
5210738eff1SGerhard Bertelsmann
5220738eff1SGerhard Bertelsmann netif_rx(skb);
5230738eff1SGerhard Bertelsmann }
5240738eff1SGerhard Bertelsmann
sun4i_can_err(struct net_device * dev,u8 isrc,u8 status)5250738eff1SGerhard Bertelsmann static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
5260738eff1SGerhard Bertelsmann {
5270738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
5280738eff1SGerhard Bertelsmann struct net_device_stats *stats = &dev->stats;
5290738eff1SGerhard Bertelsmann struct can_frame *cf;
5300738eff1SGerhard Bertelsmann struct sk_buff *skb;
5310738eff1SGerhard Bertelsmann enum can_state state = priv->can.state;
5320738eff1SGerhard Bertelsmann enum can_state rx_state, tx_state;
5330738eff1SGerhard Bertelsmann unsigned int rxerr, txerr, errc;
5340738eff1SGerhard Bertelsmann u32 ecc, alc;
5350738eff1SGerhard Bertelsmann
5360738eff1SGerhard Bertelsmann /* we don't skip if alloc fails because we want the stats anyhow */
5370738eff1SGerhard Bertelsmann skb = alloc_can_err_skb(dev, &cf);
5380738eff1SGerhard Bertelsmann
5390738eff1SGerhard Bertelsmann errc = readl(priv->base + SUN4I_REG_ERRC_ADDR);
5400738eff1SGerhard Bertelsmann rxerr = (errc >> 16) & 0xFF;
5410738eff1SGerhard Bertelsmann txerr = errc & 0xFF;
5420738eff1SGerhard Bertelsmann
5430738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_DATA_OR) {
5440738eff1SGerhard Bertelsmann /* data overrun interrupt */
5450738eff1SGerhard Bertelsmann netdev_dbg(dev, "data overrun interrupt\n");
5460738eff1SGerhard Bertelsmann if (likely(skb)) {
5470738eff1SGerhard Bertelsmann cf->can_id |= CAN_ERR_CRTL;
5480738eff1SGerhard Bertelsmann cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
5490738eff1SGerhard Bertelsmann }
5500738eff1SGerhard Bertelsmann stats->rx_over_errors++;
5510738eff1SGerhard Bertelsmann stats->rx_errors++;
5524dcf924cSGerhard Bertelsmann
5534dcf924cSGerhard Bertelsmann /* reset the CAN IP by entering reset mode
5544dcf924cSGerhard Bertelsmann * ignoring timeout error
5554dcf924cSGerhard Bertelsmann */
5564dcf924cSGerhard Bertelsmann set_reset_mode(dev);
5574dcf924cSGerhard Bertelsmann set_normal_mode(dev);
5584dcf924cSGerhard Bertelsmann
5590738eff1SGerhard Bertelsmann /* clear bit */
5600738eff1SGerhard Bertelsmann sun4i_can_write_cmdreg(priv, SUN4I_CMD_CLEAR_OR_FLAG);
5610738eff1SGerhard Bertelsmann }
5620738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_ERR_WRN) {
5630738eff1SGerhard Bertelsmann /* error warning interrupt */
5640738eff1SGerhard Bertelsmann netdev_dbg(dev, "error warning interrupt\n");
5650738eff1SGerhard Bertelsmann
5660738eff1SGerhard Bertelsmann if (status & SUN4I_STA_BUS_OFF)
5670738eff1SGerhard Bertelsmann state = CAN_STATE_BUS_OFF;
5680738eff1SGerhard Bertelsmann else if (status & SUN4I_STA_ERR_STA)
5690738eff1SGerhard Bertelsmann state = CAN_STATE_ERROR_WARNING;
5700738eff1SGerhard Bertelsmann else
5710738eff1SGerhard Bertelsmann state = CAN_STATE_ERROR_ACTIVE;
5720738eff1SGerhard Bertelsmann }
5730ac15a8fSVincent Mailhol if (skb && state != CAN_STATE_BUS_OFF) {
5743e5c291cSVincent Mailhol cf->can_id |= CAN_ERR_CNT;
5750ac15a8fSVincent Mailhol cf->data[6] = txerr;
5760ac15a8fSVincent Mailhol cf->data[7] = rxerr;
5770ac15a8fSVincent Mailhol }
5780738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_BUS_ERR) {
5790738eff1SGerhard Bertelsmann /* bus error interrupt */
5800738eff1SGerhard Bertelsmann netdev_dbg(dev, "bus error interrupt\n");
5810738eff1SGerhard Bertelsmann priv->can.can_stats.bus_error++;
5820738eff1SGerhard Bertelsmann ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
5830738eff1SGerhard Bertelsmann
584*0fef1604SDario Binacchi if (likely(skb)) {
5850738eff1SGerhard Bertelsmann cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
5860738eff1SGerhard Bertelsmann
5870738eff1SGerhard Bertelsmann switch (ecc & SUN4I_STA_MASK_ERR) {
5880738eff1SGerhard Bertelsmann case SUN4I_STA_BIT_ERR:
5890738eff1SGerhard Bertelsmann cf->data[2] |= CAN_ERR_PROT_BIT;
5900738eff1SGerhard Bertelsmann break;
5910738eff1SGerhard Bertelsmann case SUN4I_STA_FORM_ERR:
5920738eff1SGerhard Bertelsmann cf->data[2] |= CAN_ERR_PROT_FORM;
5930738eff1SGerhard Bertelsmann break;
5940738eff1SGerhard Bertelsmann case SUN4I_STA_STUFF_ERR:
5950738eff1SGerhard Bertelsmann cf->data[2] |= CAN_ERR_PROT_STUFF;
5960738eff1SGerhard Bertelsmann break;
5970738eff1SGerhard Bertelsmann default:
5980738eff1SGerhard Bertelsmann cf->data[3] = (ecc & SUN4I_STA_ERR_SEG_CODE)
5990738eff1SGerhard Bertelsmann >> 16;
6000738eff1SGerhard Bertelsmann break;
6010738eff1SGerhard Bertelsmann }
602*0fef1604SDario Binacchi }
603*0fef1604SDario Binacchi
6040738eff1SGerhard Bertelsmann /* error occurred during transmission? */
605*0fef1604SDario Binacchi if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
606*0fef1604SDario Binacchi if (likely(skb))
6070738eff1SGerhard Bertelsmann cf->data[2] |= CAN_ERR_PROT_TX;
608*0fef1604SDario Binacchi stats->tx_errors++;
609*0fef1604SDario Binacchi } else {
610*0fef1604SDario Binacchi stats->rx_errors++;
6110738eff1SGerhard Bertelsmann }
6120738eff1SGerhard Bertelsmann }
6130738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_ERR_PASSIVE) {
6140738eff1SGerhard Bertelsmann /* error passive interrupt */
6150738eff1SGerhard Bertelsmann netdev_dbg(dev, "error passive interrupt\n");
6160738eff1SGerhard Bertelsmann if (state == CAN_STATE_ERROR_PASSIVE)
6170738eff1SGerhard Bertelsmann state = CAN_STATE_ERROR_WARNING;
6180738eff1SGerhard Bertelsmann else
6190738eff1SGerhard Bertelsmann state = CAN_STATE_ERROR_PASSIVE;
6200738eff1SGerhard Bertelsmann }
6210738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_ARB_LOST) {
6220738eff1SGerhard Bertelsmann /* arbitration lost interrupt */
6230738eff1SGerhard Bertelsmann netdev_dbg(dev, "arbitration lost interrupt\n");
6240738eff1SGerhard Bertelsmann alc = readl(priv->base + SUN4I_REG_STA_ADDR);
6250738eff1SGerhard Bertelsmann priv->can.can_stats.arbitration_lost++;
6260738eff1SGerhard Bertelsmann if (likely(skb)) {
6270738eff1SGerhard Bertelsmann cf->can_id |= CAN_ERR_LOSTARB;
628887e07beSGerhard Bertelsmann cf->data[0] = (alc >> 8) & 0x1f;
6290738eff1SGerhard Bertelsmann }
6300738eff1SGerhard Bertelsmann }
6310738eff1SGerhard Bertelsmann
6320738eff1SGerhard Bertelsmann if (state != priv->can.state) {
6330738eff1SGerhard Bertelsmann tx_state = txerr >= rxerr ? state : 0;
6340738eff1SGerhard Bertelsmann rx_state = txerr <= rxerr ? state : 0;
6350738eff1SGerhard Bertelsmann
6368ac49d8fSDario Binacchi /* The skb allocation might fail, but can_change_state()
6378ac49d8fSDario Binacchi * handles cf == NULL.
6388ac49d8fSDario Binacchi */
6390738eff1SGerhard Bertelsmann can_change_state(dev, cf, tx_state, rx_state);
6400738eff1SGerhard Bertelsmann if (state == CAN_STATE_BUS_OFF)
6410738eff1SGerhard Bertelsmann can_bus_off(dev);
6420738eff1SGerhard Bertelsmann }
6430738eff1SGerhard Bertelsmann
644676068dbSVincent Mailhol if (likely(skb))
6450738eff1SGerhard Bertelsmann netif_rx(skb);
646676068dbSVincent Mailhol else
6470738eff1SGerhard Bertelsmann return -ENOMEM;
6480738eff1SGerhard Bertelsmann
6490738eff1SGerhard Bertelsmann return 0;
6500738eff1SGerhard Bertelsmann }
6510738eff1SGerhard Bertelsmann
sun4i_can_interrupt(int irq,void * dev_id)6520738eff1SGerhard Bertelsmann static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id)
6530738eff1SGerhard Bertelsmann {
6540738eff1SGerhard Bertelsmann struct net_device *dev = (struct net_device *)dev_id;
6550738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
6560738eff1SGerhard Bertelsmann struct net_device_stats *stats = &dev->stats;
6570738eff1SGerhard Bertelsmann u8 isrc, status;
6580738eff1SGerhard Bertelsmann int n = 0;
6590738eff1SGerhard Bertelsmann
6600738eff1SGerhard Bertelsmann while ((isrc = readl(priv->base + SUN4I_REG_INT_ADDR)) &&
6610738eff1SGerhard Bertelsmann (n < SUN4I_CAN_MAX_IRQ)) {
6620738eff1SGerhard Bertelsmann n++;
6630738eff1SGerhard Bertelsmann status = readl(priv->base + SUN4I_REG_STA_ADDR);
6640738eff1SGerhard Bertelsmann
6650738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_WAKEUP)
6660738eff1SGerhard Bertelsmann netdev_warn(dev, "wakeup interrupt\n");
6670738eff1SGerhard Bertelsmann
6680738eff1SGerhard Bertelsmann if (isrc & SUN4I_INT_TBUF_VLD) {
6690738eff1SGerhard Bertelsmann /* transmission complete interrupt */
670cc4b08c3SVincent Mailhol stats->tx_bytes += can_get_echo_skb(dev, 0, NULL);
6710738eff1SGerhard Bertelsmann stats->tx_packets++;
6720738eff1SGerhard Bertelsmann netif_wake_queue(dev);
6730738eff1SGerhard Bertelsmann }
6744dcf924cSGerhard Bertelsmann if ((isrc & SUN4I_INT_RBUF_VLD) &&
6754dcf924cSGerhard Bertelsmann !(isrc & SUN4I_INT_DATA_OR)) {
6764dcf924cSGerhard Bertelsmann /* receive interrupt - don't read if overrun occurred */
6770738eff1SGerhard Bertelsmann while (status & SUN4I_STA_RBUF_RDY) {
6780738eff1SGerhard Bertelsmann /* RX buffer is not empty */
6790738eff1SGerhard Bertelsmann sun4i_can_rx(dev);
6800738eff1SGerhard Bertelsmann status = readl(priv->base + SUN4I_REG_STA_ADDR);
6810738eff1SGerhard Bertelsmann }
6820738eff1SGerhard Bertelsmann }
6830738eff1SGerhard Bertelsmann if (isrc &
6840738eff1SGerhard Bertelsmann (SUN4I_INT_DATA_OR | SUN4I_INT_ERR_WRN | SUN4I_INT_BUS_ERR |
6850738eff1SGerhard Bertelsmann SUN4I_INT_ERR_PASSIVE | SUN4I_INT_ARB_LOST)) {
6860738eff1SGerhard Bertelsmann /* error interrupt */
6870738eff1SGerhard Bertelsmann if (sun4i_can_err(dev, isrc, status))
6880738eff1SGerhard Bertelsmann netdev_err(dev, "can't allocate buffer - clearing pending interrupts\n");
6890738eff1SGerhard Bertelsmann }
6900738eff1SGerhard Bertelsmann /* clear interrupts */
6910738eff1SGerhard Bertelsmann writel(isrc, priv->base + SUN4I_REG_INT_ADDR);
6920738eff1SGerhard Bertelsmann readl(priv->base + SUN4I_REG_INT_ADDR);
6930738eff1SGerhard Bertelsmann }
6940738eff1SGerhard Bertelsmann if (n >= SUN4I_CAN_MAX_IRQ)
6950738eff1SGerhard Bertelsmann netdev_dbg(dev, "%d messages handled in ISR", n);
6960738eff1SGerhard Bertelsmann
6970738eff1SGerhard Bertelsmann return (n) ? IRQ_HANDLED : IRQ_NONE;
6980738eff1SGerhard Bertelsmann }
6990738eff1SGerhard Bertelsmann
sun4ican_open(struct net_device * dev)7000738eff1SGerhard Bertelsmann static int sun4ican_open(struct net_device *dev)
7010738eff1SGerhard Bertelsmann {
7020738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
7030738eff1SGerhard Bertelsmann int err;
7040738eff1SGerhard Bertelsmann
7050738eff1SGerhard Bertelsmann /* common open */
7060738eff1SGerhard Bertelsmann err = open_candev(dev);
7070738eff1SGerhard Bertelsmann if (err)
7080738eff1SGerhard Bertelsmann return err;
7090738eff1SGerhard Bertelsmann
7100738eff1SGerhard Bertelsmann /* register interrupt handler */
7110738eff1SGerhard Bertelsmann err = request_irq(dev->irq, sun4i_can_interrupt, 0, dev->name, dev);
7120738eff1SGerhard Bertelsmann if (err) {
7130738eff1SGerhard Bertelsmann netdev_err(dev, "request_irq err: %d\n", err);
7140738eff1SGerhard Bertelsmann goto exit_irq;
7150738eff1SGerhard Bertelsmann }
7160738eff1SGerhard Bertelsmann
7172c2fd0e6SEvgeny Boger /* software reset deassert */
7182c2fd0e6SEvgeny Boger err = reset_control_deassert(priv->reset);
7192c2fd0e6SEvgeny Boger if (err) {
7202c2fd0e6SEvgeny Boger netdev_err(dev, "could not deassert CAN reset\n");
7212c2fd0e6SEvgeny Boger goto exit_soft_reset;
7222c2fd0e6SEvgeny Boger }
7232c2fd0e6SEvgeny Boger
7240738eff1SGerhard Bertelsmann /* turn on clocking for CAN peripheral block */
7250738eff1SGerhard Bertelsmann err = clk_prepare_enable(priv->clk);
7260738eff1SGerhard Bertelsmann if (err) {
7270738eff1SGerhard Bertelsmann netdev_err(dev, "could not enable CAN peripheral clock\n");
7280738eff1SGerhard Bertelsmann goto exit_clock;
7290738eff1SGerhard Bertelsmann }
7300738eff1SGerhard Bertelsmann
7310738eff1SGerhard Bertelsmann err = sun4i_can_start(dev);
7320738eff1SGerhard Bertelsmann if (err) {
7330738eff1SGerhard Bertelsmann netdev_err(dev, "could not start CAN peripheral\n");
7340738eff1SGerhard Bertelsmann goto exit_can_start;
7350738eff1SGerhard Bertelsmann }
7360738eff1SGerhard Bertelsmann
7370738eff1SGerhard Bertelsmann netif_start_queue(dev);
7380738eff1SGerhard Bertelsmann
7390738eff1SGerhard Bertelsmann return 0;
7400738eff1SGerhard Bertelsmann
7410738eff1SGerhard Bertelsmann exit_can_start:
7420738eff1SGerhard Bertelsmann clk_disable_unprepare(priv->clk);
7430738eff1SGerhard Bertelsmann exit_clock:
7442c2fd0e6SEvgeny Boger reset_control_assert(priv->reset);
7452c2fd0e6SEvgeny Boger exit_soft_reset:
7460738eff1SGerhard Bertelsmann free_irq(dev->irq, dev);
7470738eff1SGerhard Bertelsmann exit_irq:
7480738eff1SGerhard Bertelsmann close_candev(dev);
7490738eff1SGerhard Bertelsmann return err;
7500738eff1SGerhard Bertelsmann }
7510738eff1SGerhard Bertelsmann
sun4ican_close(struct net_device * dev)7520738eff1SGerhard Bertelsmann static int sun4ican_close(struct net_device *dev)
7530738eff1SGerhard Bertelsmann {
7540738eff1SGerhard Bertelsmann struct sun4ican_priv *priv = netdev_priv(dev);
7550738eff1SGerhard Bertelsmann
7560738eff1SGerhard Bertelsmann netif_stop_queue(dev);
7570738eff1SGerhard Bertelsmann sun4i_can_stop(dev);
7580738eff1SGerhard Bertelsmann clk_disable_unprepare(priv->clk);
7592c2fd0e6SEvgeny Boger reset_control_assert(priv->reset);
7600738eff1SGerhard Bertelsmann
7610738eff1SGerhard Bertelsmann free_irq(dev->irq, dev);
7620738eff1SGerhard Bertelsmann close_candev(dev);
7630738eff1SGerhard Bertelsmann
7640738eff1SGerhard Bertelsmann return 0;
7650738eff1SGerhard Bertelsmann }
7660738eff1SGerhard Bertelsmann
7670738eff1SGerhard Bertelsmann static const struct net_device_ops sun4ican_netdev_ops = {
7680738eff1SGerhard Bertelsmann .ndo_open = sun4ican_open,
7690738eff1SGerhard Bertelsmann .ndo_stop = sun4ican_close,
7700738eff1SGerhard Bertelsmann .ndo_start_xmit = sun4ican_start_xmit,
7710738eff1SGerhard Bertelsmann };
7720738eff1SGerhard Bertelsmann
773409c188cSVincent Mailhol static const struct ethtool_ops sun4ican_ethtool_ops = {
774409c188cSVincent Mailhol .get_ts_info = ethtool_op_get_ts_info,
775409c188cSVincent Mailhol };
776409c188cSVincent Mailhol
7772c2fd0e6SEvgeny Boger static const struct sun4ican_quirks sun4ican_quirks_a10 = {
7782c2fd0e6SEvgeny Boger .has_reset = false,
7798cda0c6dSJohn Watts .acp_offset = 0,
7802c2fd0e6SEvgeny Boger };
7812c2fd0e6SEvgeny Boger
7822c2fd0e6SEvgeny Boger static const struct sun4ican_quirks sun4ican_quirks_r40 = {
7832c2fd0e6SEvgeny Boger .has_reset = true,
7848cda0c6dSJohn Watts .acp_offset = 0,
7852c2fd0e6SEvgeny Boger };
7862c2fd0e6SEvgeny Boger
7878abb9525SJohn Watts static const struct sun4ican_quirks sun4ican_quirks_d1 = {
7888abb9525SJohn Watts .has_reset = true,
7898abb9525SJohn Watts .acp_offset = (SUN4I_REG_ACPC_ADDR_D1 - SUN4I_REG_ACPC_ADDR),
7908abb9525SJohn Watts };
7918abb9525SJohn Watts
7920738eff1SGerhard Bertelsmann static const struct of_device_id sun4ican_of_match[] = {
7932c2fd0e6SEvgeny Boger {
7942c2fd0e6SEvgeny Boger .compatible = "allwinner,sun4i-a10-can",
7952c2fd0e6SEvgeny Boger .data = &sun4ican_quirks_a10
7962c2fd0e6SEvgeny Boger }, {
7972c2fd0e6SEvgeny Boger .compatible = "allwinner,sun7i-a20-can",
7982c2fd0e6SEvgeny Boger .data = &sun4ican_quirks_a10
7992c2fd0e6SEvgeny Boger }, {
8002c2fd0e6SEvgeny Boger .compatible = "allwinner,sun8i-r40-can",
8012c2fd0e6SEvgeny Boger .data = &sun4ican_quirks_r40
8022c2fd0e6SEvgeny Boger }, {
8038abb9525SJohn Watts .compatible = "allwinner,sun20i-d1-can",
8048abb9525SJohn Watts .data = &sun4ican_quirks_d1
8058abb9525SJohn Watts }, {
8062c2fd0e6SEvgeny Boger /* sentinel */
8072c2fd0e6SEvgeny Boger },
8080738eff1SGerhard Bertelsmann };
8090738eff1SGerhard Bertelsmann
8100738eff1SGerhard Bertelsmann MODULE_DEVICE_TABLE(of, sun4ican_of_match);
8110738eff1SGerhard Bertelsmann
sun4ican_remove(struct platform_device * pdev)812aaa278e6SUwe Kleine-König static void sun4ican_remove(struct platform_device *pdev)
8130738eff1SGerhard Bertelsmann {
8140738eff1SGerhard Bertelsmann struct net_device *dev = platform_get_drvdata(pdev);
8150738eff1SGerhard Bertelsmann
8160738eff1SGerhard Bertelsmann unregister_netdev(dev);
8170738eff1SGerhard Bertelsmann free_candev(dev);
8180738eff1SGerhard Bertelsmann }
8190738eff1SGerhard Bertelsmann
sun4ican_probe(struct platform_device * pdev)8200738eff1SGerhard Bertelsmann static int sun4ican_probe(struct platform_device *pdev)
8210738eff1SGerhard Bertelsmann {
8220738eff1SGerhard Bertelsmann struct device_node *np = pdev->dev.of_node;
8230738eff1SGerhard Bertelsmann struct clk *clk;
8242c2fd0e6SEvgeny Boger struct reset_control *reset = NULL;
8250738eff1SGerhard Bertelsmann void __iomem *addr;
8260738eff1SGerhard Bertelsmann int err, irq;
8270738eff1SGerhard Bertelsmann struct net_device *dev;
8280738eff1SGerhard Bertelsmann struct sun4ican_priv *priv;
8292c2fd0e6SEvgeny Boger const struct sun4ican_quirks *quirks;
8302c2fd0e6SEvgeny Boger
8312c2fd0e6SEvgeny Boger quirks = of_device_get_match_data(&pdev->dev);
8322c2fd0e6SEvgeny Boger if (!quirks) {
8332c2fd0e6SEvgeny Boger dev_err(&pdev->dev, "failed to determine the quirks to use\n");
8342c2fd0e6SEvgeny Boger err = -ENODEV;
8352c2fd0e6SEvgeny Boger goto exit;
8362c2fd0e6SEvgeny Boger }
8372c2fd0e6SEvgeny Boger
8382c2fd0e6SEvgeny Boger if (quirks->has_reset) {
8392c2fd0e6SEvgeny Boger reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
8402c2fd0e6SEvgeny Boger if (IS_ERR(reset)) {
8412c2fd0e6SEvgeny Boger dev_err(&pdev->dev, "unable to request reset\n");
8422c2fd0e6SEvgeny Boger err = PTR_ERR(reset);
8432c2fd0e6SEvgeny Boger goto exit;
8442c2fd0e6SEvgeny Boger }
8452c2fd0e6SEvgeny Boger }
8460738eff1SGerhard Bertelsmann
8470738eff1SGerhard Bertelsmann clk = of_clk_get(np, 0);
8480738eff1SGerhard Bertelsmann if (IS_ERR(clk)) {
8490738eff1SGerhard Bertelsmann dev_err(&pdev->dev, "unable to request clock\n");
8500738eff1SGerhard Bertelsmann err = -ENODEV;
8510738eff1SGerhard Bertelsmann goto exit;
8520738eff1SGerhard Bertelsmann }
8530738eff1SGerhard Bertelsmann
8540738eff1SGerhard Bertelsmann irq = platform_get_irq(pdev, 0);
8550738eff1SGerhard Bertelsmann if (irq < 0) {
8560738eff1SGerhard Bertelsmann err = -ENODEV;
8570738eff1SGerhard Bertelsmann goto exit;
8580738eff1SGerhard Bertelsmann }
8590738eff1SGerhard Bertelsmann
8600767bbe5SYueHaibing addr = devm_platform_ioremap_resource(pdev, 0);
8610738eff1SGerhard Bertelsmann if (IS_ERR(addr)) {
862ef24d6c3STiezhu Yang err = PTR_ERR(addr);
8630738eff1SGerhard Bertelsmann goto exit;
8640738eff1SGerhard Bertelsmann }
8650738eff1SGerhard Bertelsmann
8660738eff1SGerhard Bertelsmann dev = alloc_candev(sizeof(struct sun4ican_priv), 1);
8670738eff1SGerhard Bertelsmann if (!dev) {
8680738eff1SGerhard Bertelsmann dev_err(&pdev->dev,
8690738eff1SGerhard Bertelsmann "could not allocate memory for CAN device\n");
8700738eff1SGerhard Bertelsmann err = -ENOMEM;
8710738eff1SGerhard Bertelsmann goto exit;
8720738eff1SGerhard Bertelsmann }
8730738eff1SGerhard Bertelsmann
8740738eff1SGerhard Bertelsmann dev->netdev_ops = &sun4ican_netdev_ops;
875409c188cSVincent Mailhol dev->ethtool_ops = &sun4ican_ethtool_ops;
8760738eff1SGerhard Bertelsmann dev->irq = irq;
8770738eff1SGerhard Bertelsmann dev->flags |= IFF_ECHO;
8780738eff1SGerhard Bertelsmann
8790738eff1SGerhard Bertelsmann priv = netdev_priv(dev);
8800738eff1SGerhard Bertelsmann priv->can.clock.freq = clk_get_rate(clk);
8810738eff1SGerhard Bertelsmann priv->can.bittiming_const = &sun4ican_bittiming_const;
8820738eff1SGerhard Bertelsmann priv->can.do_set_mode = sun4ican_set_mode;
8830738eff1SGerhard Bertelsmann priv->can.do_get_berr_counter = sun4ican_get_berr_counter;
8840738eff1SGerhard Bertelsmann priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
8850738eff1SGerhard Bertelsmann CAN_CTRLMODE_LISTENONLY |
8860738eff1SGerhard Bertelsmann CAN_CTRLMODE_LOOPBACK |
8870738eff1SGerhard Bertelsmann CAN_CTRLMODE_3_SAMPLES;
8880738eff1SGerhard Bertelsmann priv->base = addr;
8890738eff1SGerhard Bertelsmann priv->clk = clk;
8902c2fd0e6SEvgeny Boger priv->reset = reset;
8918cda0c6dSJohn Watts priv->acp_offset = quirks->acp_offset;
8920738eff1SGerhard Bertelsmann spin_lock_init(&priv->cmdreg_lock);
8930738eff1SGerhard Bertelsmann
8940738eff1SGerhard Bertelsmann platform_set_drvdata(pdev, dev);
8950738eff1SGerhard Bertelsmann SET_NETDEV_DEV(dev, &pdev->dev);
8960738eff1SGerhard Bertelsmann
8970738eff1SGerhard Bertelsmann err = register_candev(dev);
8980738eff1SGerhard Bertelsmann if (err) {
8990738eff1SGerhard Bertelsmann dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
9000738eff1SGerhard Bertelsmann DRV_NAME, err);
9010738eff1SGerhard Bertelsmann goto exit_free;
9020738eff1SGerhard Bertelsmann }
9030738eff1SGerhard Bertelsmann
9040738eff1SGerhard Bertelsmann dev_info(&pdev->dev, "device registered (base=%p, irq=%d)\n",
9050738eff1SGerhard Bertelsmann priv->base, dev->irq);
9060738eff1SGerhard Bertelsmann
9070738eff1SGerhard Bertelsmann return 0;
9080738eff1SGerhard Bertelsmann
9090738eff1SGerhard Bertelsmann exit_free:
9100738eff1SGerhard Bertelsmann free_candev(dev);
9110738eff1SGerhard Bertelsmann exit:
9120738eff1SGerhard Bertelsmann return err;
9130738eff1SGerhard Bertelsmann }
9140738eff1SGerhard Bertelsmann
9150738eff1SGerhard Bertelsmann static struct platform_driver sun4i_can_driver = {
9160738eff1SGerhard Bertelsmann .driver = {
9170738eff1SGerhard Bertelsmann .name = DRV_NAME,
9180738eff1SGerhard Bertelsmann .of_match_table = sun4ican_of_match,
9190738eff1SGerhard Bertelsmann },
9200738eff1SGerhard Bertelsmann .probe = sun4ican_probe,
921aaa278e6SUwe Kleine-König .remove_new = sun4ican_remove,
9220738eff1SGerhard Bertelsmann };
9230738eff1SGerhard Bertelsmann
9240738eff1SGerhard Bertelsmann module_platform_driver(sun4i_can_driver);
9250738eff1SGerhard Bertelsmann
9260738eff1SGerhard Bertelsmann MODULE_AUTHOR("Peter Chen <xingkongcp@gmail.com>");
9270738eff1SGerhard Bertelsmann MODULE_AUTHOR("Gerhard Bertelsmann <info@gerhard-bertelsmann.de>");
9280738eff1SGerhard Bertelsmann MODULE_LICENSE("Dual BSD/GPL");
9298abb9525SJohn Watts MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20/D1)");
930