Loading drivers/net/can/mcp251x.c +70 −25 Original line number Diff line number Diff line Loading @@ -38,14 +38,14 @@ * static struct mcp251x_platform_data mcp251x_info = { * .oscillator_frequency = 8000000, * .board_specific_setup = &mcp251x_setup, * .model = CAN_MCP251X_MCP2510, * .power_enable = mcp251x_power_enable, * .transceiver_enable = NULL, * }; * * static struct spi_board_info spi_board_info[] = { * { * .modalias = "mcp251x", * .modalias = "mcp2510", * // or "mcp2515" depending on your controller * .platform_data = &mcp251x_info, * .irq = IRQ_EINT13, * .max_speed_hz = 2*1000*1000, Loading Loading @@ -125,6 +125,8 @@ # define CANINTF_TX0IF 0x04 # define CANINTF_RX1IF 0x02 # define CANINTF_RX0IF 0x01 # define CANINTF_ERR_TX \ (CANINTF_ERRIF | CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) #define EFLG 0x2d # define EFLG_EWARN 0x01 # define EFLG_RXWAR 0x02 Loading Loading @@ -222,10 +224,16 @@ static struct can_bittiming_const mcp251x_bittiming_const = { .brp_inc = 1, }; enum mcp251x_model { CAN_MCP251X_MCP2510 = 0x2510, CAN_MCP251X_MCP2515 = 0x2515, }; struct mcp251x_priv { struct can_priv can; struct net_device *net; struct spi_device *spi; enum mcp251x_model model; struct mutex mcp_lock; /* SPI device lock */ Loading @@ -250,6 +258,16 @@ struct mcp251x_priv { int restart_tx; }; #define MCP251X_IS(_model) \ static inline int mcp251x_is_##_model(struct spi_device *spi) \ { \ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \ return priv->model == CAN_MCP251X_MCP##_model; \ } MCP251X_IS(2510); MCP251X_IS(2515); static void mcp251x_clean(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); Loading Loading @@ -319,6 +337,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg) return val; } static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg, uint8_t *v1, uint8_t *v2) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); priv->spi_tx_buf[0] = INSTRUCTION_READ; priv->spi_tx_buf[1] = reg; mcp251x_spi_trans(spi, 4); *v1 = priv->spi_rx_buf[2]; *v2 = priv->spi_rx_buf[3]; } static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); Loading Loading @@ -346,10 +378,9 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg, static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, int len, int tx_buf_idx) { struct mcp251x_platform_data *pdata = spi->dev.platform_data; struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); if (pdata->model == CAN_MCP251X_MCP2510) { if (mcp251x_is_2510(spi)) { int i; for (i = 1; i < TXBDAT_OFF + len; i++) Loading Loading @@ -392,9 +423,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, int buf_idx) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); struct mcp251x_platform_data *pdata = spi->dev.platform_data; if (pdata->model == CAN_MCP251X_MCP2510) { if (mcp251x_is_2510(spi)) { int i, len; for (i = 1; i < RXBDAT_OFF; i++) Loading Loading @@ -451,7 +481,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) priv->net->stats.rx_packets++; priv->net->stats.rx_bytes += frame->can_dlc; netif_rx(skb); netif_rx_ni(skb); } static void mcp251x_hw_sleep(struct spi_device *spi) Loading Loading @@ -676,7 +706,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) if (skb) { frame->can_id = can_id; frame->data[1] = data1; netif_rx(skb); netif_rx_ni(skb); } else { dev_err(&net->dev, "cannot allocate error skb\n"); Loading Loading @@ -754,24 +784,39 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mutex_lock(&priv->mcp_lock); while (!priv->force_quit) { enum can_state new_state; u8 intf = mcp251x_read_reg(spi, CANINTF); u8 eflag; u8 intf, eflag; u8 clear_intf = 0; int can_id = 0, data1 = 0; mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); /* Free one buffer ASAP */ mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF, 0x00); /* * Free one buffer ASAP * (The MCP2515 does this automatically.) */ if (mcp251x_is_2510(spi)) mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); } if (intf & CANINTF_RX1IF) /* receive buffer 1 */ if (intf & CANINTF_RX1IF) { mcp251x_hw_rx(spi, 1); /* the MCP2515 does this automatically */ if (mcp251x_is_2510(spi)) clear_intf |= CANINTF_RX1IF; } mcp251x_write_bits(spi, CANINTF, intf, 0x00); /* any error or tx interrupt we need to clear? */ if (intf & CANINTF_ERR_TX) clear_intf |= intf & CANINTF_ERR_TX; if (clear_intf) mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00); eflag = mcp251x_read_reg(spi, EFLG); mcp251x_write_reg(spi, EFLG, 0x00); if (eflag) mcp251x_write_bits(spi, EFLG, eflag, 0x00); /* Update can state */ if (eflag & EFLG_TXBO) { Loading Loading @@ -816,10 +861,14 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf & CANINTF_ERRIF) { /* Handle overflow counters */ if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) { if (eflag & EFLG_RX0OVR) if (eflag & EFLG_RX0OVR) { net->stats.rx_over_errors++; if (eflag & EFLG_RX1OVR) net->stats.rx_errors++; } if (eflag & EFLG_RX1OVR) { net->stats.rx_over_errors++; net->stats.rx_errors++; } can_id |= CAN_ERR_CRTL; data1 |= CAN_ERR_CRTL_RX_OVERFLOW; } Loading Loading @@ -921,16 +970,12 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) struct net_device *net; struct mcp251x_priv *priv; struct mcp251x_platform_data *pdata = spi->dev.platform_data; int model = spi_get_device_id(spi)->driver_data; int ret = -ENODEV; if (!pdata) /* Platform data is required for osc freq */ goto error_out; if (model) pdata->model = model; /* Allocate can/net device */ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); if (!net) { Loading @@ -947,6 +992,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) priv->can.clock.freq = pdata->oscillator_frequency / 2; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; priv->model = spi_get_device_id(spi)->driver_data; priv->net = net; dev_set_drvdata(&spi->dev, priv); Loading Loading @@ -1120,8 +1166,7 @@ static int mcp251x_can_resume(struct spi_device *spi) #define mcp251x_can_resume NULL #endif static struct spi_device_id mcp251x_id_table[] = { { "mcp251x", 0 /* Use pdata.model */ }, static const struct spi_device_id mcp251x_id_table[] = { { "mcp2510", CAN_MCP251X_MCP2510 }, { "mcp2515", CAN_MCP251X_MCP2515 }, { }, Loading include/linux/can/platform/mcp251x.h +0 −4 Original line number Diff line number Diff line Loading @@ -12,7 +12,6 @@ /** * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data * @oscillator_frequency: - oscillator frequency in Hz * @model: - actual type of chip * @board_specific_setup: - called before probing the chip (power,reset) * @transceiver_enable: - called to power on/off the transceiver * @power_enable: - called to power on/off the mcp *and* the Loading @@ -25,9 +24,6 @@ struct mcp251x_platform_data { unsigned long oscillator_frequency; int model; #define CAN_MCP251X_MCP2510 0x2510 #define CAN_MCP251X_MCP2515 0x2515 int (*board_specific_setup)(struct spi_device *spi); int (*transceiver_enable)(int enable); int (*power_enable) (int enable); Loading Loading
drivers/net/can/mcp251x.c +70 −25 Original line number Diff line number Diff line Loading @@ -38,14 +38,14 @@ * static struct mcp251x_platform_data mcp251x_info = { * .oscillator_frequency = 8000000, * .board_specific_setup = &mcp251x_setup, * .model = CAN_MCP251X_MCP2510, * .power_enable = mcp251x_power_enable, * .transceiver_enable = NULL, * }; * * static struct spi_board_info spi_board_info[] = { * { * .modalias = "mcp251x", * .modalias = "mcp2510", * // or "mcp2515" depending on your controller * .platform_data = &mcp251x_info, * .irq = IRQ_EINT13, * .max_speed_hz = 2*1000*1000, Loading Loading @@ -125,6 +125,8 @@ # define CANINTF_TX0IF 0x04 # define CANINTF_RX1IF 0x02 # define CANINTF_RX0IF 0x01 # define CANINTF_ERR_TX \ (CANINTF_ERRIF | CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) #define EFLG 0x2d # define EFLG_EWARN 0x01 # define EFLG_RXWAR 0x02 Loading Loading @@ -222,10 +224,16 @@ static struct can_bittiming_const mcp251x_bittiming_const = { .brp_inc = 1, }; enum mcp251x_model { CAN_MCP251X_MCP2510 = 0x2510, CAN_MCP251X_MCP2515 = 0x2515, }; struct mcp251x_priv { struct can_priv can; struct net_device *net; struct spi_device *spi; enum mcp251x_model model; struct mutex mcp_lock; /* SPI device lock */ Loading @@ -250,6 +258,16 @@ struct mcp251x_priv { int restart_tx; }; #define MCP251X_IS(_model) \ static inline int mcp251x_is_##_model(struct spi_device *spi) \ { \ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \ return priv->model == CAN_MCP251X_MCP##_model; \ } MCP251X_IS(2510); MCP251X_IS(2515); static void mcp251x_clean(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); Loading Loading @@ -319,6 +337,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg) return val; } static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg, uint8_t *v1, uint8_t *v2) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); priv->spi_tx_buf[0] = INSTRUCTION_READ; priv->spi_tx_buf[1] = reg; mcp251x_spi_trans(spi, 4); *v1 = priv->spi_rx_buf[2]; *v2 = priv->spi_rx_buf[3]; } static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); Loading Loading @@ -346,10 +378,9 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg, static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, int len, int tx_buf_idx) { struct mcp251x_platform_data *pdata = spi->dev.platform_data; struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); if (pdata->model == CAN_MCP251X_MCP2510) { if (mcp251x_is_2510(spi)) { int i; for (i = 1; i < TXBDAT_OFF + len; i++) Loading Loading @@ -392,9 +423,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, int buf_idx) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); struct mcp251x_platform_data *pdata = spi->dev.platform_data; if (pdata->model == CAN_MCP251X_MCP2510) { if (mcp251x_is_2510(spi)) { int i, len; for (i = 1; i < RXBDAT_OFF; i++) Loading Loading @@ -451,7 +481,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) priv->net->stats.rx_packets++; priv->net->stats.rx_bytes += frame->can_dlc; netif_rx(skb); netif_rx_ni(skb); } static void mcp251x_hw_sleep(struct spi_device *spi) Loading Loading @@ -676,7 +706,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) if (skb) { frame->can_id = can_id; frame->data[1] = data1; netif_rx(skb); netif_rx_ni(skb); } else { dev_err(&net->dev, "cannot allocate error skb\n"); Loading Loading @@ -754,24 +784,39 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mutex_lock(&priv->mcp_lock); while (!priv->force_quit) { enum can_state new_state; u8 intf = mcp251x_read_reg(spi, CANINTF); u8 eflag; u8 intf, eflag; u8 clear_intf = 0; int can_id = 0, data1 = 0; mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); /* Free one buffer ASAP */ mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF, 0x00); /* * Free one buffer ASAP * (The MCP2515 does this automatically.) */ if (mcp251x_is_2510(spi)) mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); } if (intf & CANINTF_RX1IF) /* receive buffer 1 */ if (intf & CANINTF_RX1IF) { mcp251x_hw_rx(spi, 1); /* the MCP2515 does this automatically */ if (mcp251x_is_2510(spi)) clear_intf |= CANINTF_RX1IF; } mcp251x_write_bits(spi, CANINTF, intf, 0x00); /* any error or tx interrupt we need to clear? */ if (intf & CANINTF_ERR_TX) clear_intf |= intf & CANINTF_ERR_TX; if (clear_intf) mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00); eflag = mcp251x_read_reg(spi, EFLG); mcp251x_write_reg(spi, EFLG, 0x00); if (eflag) mcp251x_write_bits(spi, EFLG, eflag, 0x00); /* Update can state */ if (eflag & EFLG_TXBO) { Loading Loading @@ -816,10 +861,14 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf & CANINTF_ERRIF) { /* Handle overflow counters */ if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) { if (eflag & EFLG_RX0OVR) if (eflag & EFLG_RX0OVR) { net->stats.rx_over_errors++; if (eflag & EFLG_RX1OVR) net->stats.rx_errors++; } if (eflag & EFLG_RX1OVR) { net->stats.rx_over_errors++; net->stats.rx_errors++; } can_id |= CAN_ERR_CRTL; data1 |= CAN_ERR_CRTL_RX_OVERFLOW; } Loading Loading @@ -921,16 +970,12 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) struct net_device *net; struct mcp251x_priv *priv; struct mcp251x_platform_data *pdata = spi->dev.platform_data; int model = spi_get_device_id(spi)->driver_data; int ret = -ENODEV; if (!pdata) /* Platform data is required for osc freq */ goto error_out; if (model) pdata->model = model; /* Allocate can/net device */ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); if (!net) { Loading @@ -947,6 +992,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) priv->can.clock.freq = pdata->oscillator_frequency / 2; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; priv->model = spi_get_device_id(spi)->driver_data; priv->net = net; dev_set_drvdata(&spi->dev, priv); Loading Loading @@ -1120,8 +1166,7 @@ static int mcp251x_can_resume(struct spi_device *spi) #define mcp251x_can_resume NULL #endif static struct spi_device_id mcp251x_id_table[] = { { "mcp251x", 0 /* Use pdata.model */ }, static const struct spi_device_id mcp251x_id_table[] = { { "mcp2510", CAN_MCP251X_MCP2510 }, { "mcp2515", CAN_MCP251X_MCP2515 }, { }, Loading
include/linux/can/platform/mcp251x.h +0 −4 Original line number Diff line number Diff line Loading @@ -12,7 +12,6 @@ /** * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data * @oscillator_frequency: - oscillator frequency in Hz * @model: - actual type of chip * @board_specific_setup: - called before probing the chip (power,reset) * @transceiver_enable: - called to power on/off the transceiver * @power_enable: - called to power on/off the mcp *and* the Loading @@ -25,9 +24,6 @@ struct mcp251x_platform_data { unsigned long oscillator_frequency; int model; #define CAN_MCP251X_MCP2510 0x2510 #define CAN_MCP251X_MCP2515 0x2515 int (*board_specific_setup)(struct spi_device *spi); int (*transceiver_enable)(int enable); int (*power_enable) (int enable); Loading