mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-16 11:24:00 +00:00
can: Proper ctrlmode handling for CAN devices
This patch adds error checking of ctrlmode values for CAN devices. As an example all availabe bits are implemented in the mcp251x driver. Signed-off-by: Christian Pellegrin <chripell@fsfe.org> Acked-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1954dc1177
commit
ad72c347e5
9 changed files with 19 additions and 1 deletions
|
@ -1073,6 +1073,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
|
||||||
priv->can.bittiming_const = &at91_bittiming_const;
|
priv->can.bittiming_const = &at91_bittiming_const;
|
||||||
priv->can.do_set_bittiming = at91_set_bittiming;
|
priv->can.do_set_bittiming = at91_set_bittiming;
|
||||||
priv->can.do_set_mode = at91_set_mode;
|
priv->can.do_set_mode = at91_set_mode;
|
||||||
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||||
priv->reg_base = addr;
|
priv->reg_base = addr;
|
||||||
priv->dev = dev;
|
priv->dev = dev;
|
||||||
priv->clk = clk;
|
priv->clk = clk;
|
||||||
|
|
|
@ -603,6 +603,7 @@ struct net_device *alloc_bfin_candev(void)
|
||||||
priv->can.bittiming_const = &bfin_can_bittiming_const;
|
priv->can.bittiming_const = &bfin_can_bittiming_const;
|
||||||
priv->can.do_set_bittiming = bfin_can_set_bittiming;
|
priv->can.do_set_bittiming = bfin_can_set_bittiming;
|
||||||
priv->can.do_set_mode = bfin_can_set_mode;
|
priv->can.do_set_mode = bfin_can_set_mode;
|
||||||
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,6 +592,8 @@ static int can_changelink(struct net_device *dev,
|
||||||
if (dev->flags & IFF_UP)
|
if (dev->flags & IFF_UP)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
cm = nla_data(data[IFLA_CAN_CTRLMODE]);
|
cm = nla_data(data[IFLA_CAN_CTRLMODE]);
|
||||||
|
if (cm->flags & ~priv->ctrlmode_supported)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
priv->ctrlmode &= ~cm->mask;
|
priv->ctrlmode &= ~cm->mask;
|
||||||
priv->ctrlmode |= cm->flags;
|
priv->ctrlmode |= cm->flags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,9 +539,14 @@ static void mcp251x_set_normal_mode(struct spi_device *spi)
|
||||||
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
|
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
|
||||||
/* Put device into loopback mode */
|
/* Put device into loopback mode */
|
||||||
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
|
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
|
||||||
|
} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
|
||||||
|
/* Put device into listen-only mode */
|
||||||
|
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
|
||||||
} else {
|
} else {
|
||||||
/* Put device into normal mode */
|
/* Put device into normal mode */
|
||||||
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
|
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL |
|
||||||
|
(priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT ?
|
||||||
|
CANCTRL_OSM : 0));
|
||||||
|
|
||||||
/* Wait for the device to enter normal mode */
|
/* Wait for the device to enter normal mode */
|
||||||
timeout = jiffies + HZ;
|
timeout = jiffies + HZ;
|
||||||
|
@ -948,6 +953,10 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
|
||||||
priv->can.bittiming_const = &mcp251x_bittiming_const;
|
priv->can.bittiming_const = &mcp251x_bittiming_const;
|
||||||
priv->can.do_set_mode = mcp251x_do_set_mode;
|
priv->can.do_set_mode = mcp251x_do_set_mode;
|
||||||
priv->can.clock.freq = pdata->oscillator_frequency / 2;
|
priv->can.clock.freq = pdata->oscillator_frequency / 2;
|
||||||
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
|
||||||
|
CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
|
||||||
|
if (pdata->model == CAN_MCP251X_MCP2515)
|
||||||
|
priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
|
||||||
priv->net = net;
|
priv->net = net;
|
||||||
dev_set_drvdata(&spi->dev, priv);
|
dev_set_drvdata(&spi->dev, priv);
|
||||||
|
|
||||||
|
|
|
@ -686,6 +686,7 @@ struct net_device *alloc_mscandev(void)
|
||||||
priv->can.bittiming_const = &mscan_bittiming_const;
|
priv->can.bittiming_const = &mscan_bittiming_const;
|
||||||
priv->can.do_set_bittiming = mscan_do_set_bittiming;
|
priv->can.do_set_bittiming = mscan_do_set_bittiming;
|
||||||
priv->can.do_set_mode = mscan_do_set_mode;
|
priv->can.do_set_mode = mscan_do_set_mode;
|
||||||
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||||
|
|
||||||
for (i = 0; i < TX_QUEUE_SIZE; i++) {
|
for (i = 0; i < TX_QUEUE_SIZE; i++) {
|
||||||
priv->tx_queue[i].id = i;
|
priv->tx_queue[i].id = i;
|
||||||
|
|
|
@ -567,6 +567,7 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
|
||||||
priv->can.bittiming_const = &sja1000_bittiming_const;
|
priv->can.bittiming_const = &sja1000_bittiming_const;
|
||||||
priv->can.do_set_bittiming = sja1000_set_bittiming;
|
priv->can.do_set_bittiming = sja1000_set_bittiming;
|
||||||
priv->can.do_set_mode = sja1000_set_mode;
|
priv->can.do_set_mode = sja1000_set_mode;
|
||||||
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||||
|
|
||||||
if (sizeof_priv)
|
if (sizeof_priv)
|
||||||
priv->priv = (void *)priv + sizeof(struct sja1000_priv);
|
priv->priv = (void *)priv + sizeof(struct sja1000_priv);
|
||||||
|
|
|
@ -909,6 +909,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
|
||||||
priv->can.bittiming_const = &ti_hecc_bittiming_const;
|
priv->can.bittiming_const = &ti_hecc_bittiming_const;
|
||||||
priv->can.do_set_mode = ti_hecc_do_set_mode;
|
priv->can.do_set_mode = ti_hecc_do_set_mode;
|
||||||
priv->can.do_get_state = ti_hecc_get_state;
|
priv->can.do_get_state = ti_hecc_get_state;
|
||||||
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||||
|
|
||||||
ndev->irq = irq->start;
|
ndev->irq = irq->start;
|
||||||
ndev->flags |= IFF_ECHO;
|
ndev->flags |= IFF_ECHO;
|
||||||
|
|
|
@ -1022,6 +1022,7 @@ static int ems_usb_probe(struct usb_interface *intf,
|
||||||
dev->can.bittiming_const = &ems_usb_bittiming_const;
|
dev->can.bittiming_const = &ems_usb_bittiming_const;
|
||||||
dev->can.do_set_bittiming = ems_usb_set_bittiming;
|
dev->can.do_set_bittiming = ems_usb_set_bittiming;
|
||||||
dev->can.do_set_mode = ems_usb_set_mode;
|
dev->can.do_set_mode = ems_usb_set_mode;
|
||||||
|
dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||||
|
|
||||||
netdev->flags |= IFF_ECHO; /* we support local echo */
|
netdev->flags |= IFF_ECHO; /* we support local echo */
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct can_priv {
|
||||||
|
|
||||||
enum can_state state;
|
enum can_state state;
|
||||||
u32 ctrlmode;
|
u32 ctrlmode;
|
||||||
|
u32 ctrlmode_supported;
|
||||||
|
|
||||||
int restart_ms;
|
int restart_ms;
|
||||||
struct timer_list restart_timer;
|
struct timer_list restart_timer;
|
||||||
|
|
Loading…
Add table
Reference in a new issue