aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/flexcan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/flexcan.c')
-rw-r--r--drivers/net/can/flexcan.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index c5f143165f8..c78ecfca1e4 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -144,6 +144,10 @@
144 144
145#define FLEXCAN_MB_CODE_MASK (0xf0ffffff) 145#define FLEXCAN_MB_CODE_MASK (0xf0ffffff)
146 146
147/* FLEXCAN hardware feature flags */
148#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
149#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* Broken error state handling */
150
147/* Structure of the message buffer */ 151/* Structure of the message buffer */
148struct flexcan_mb { 152struct flexcan_mb {
149 u32 can_ctrl; 153 u32 can_ctrl;
@@ -178,7 +182,7 @@ struct flexcan_regs {
178}; 182};
179 183
180struct flexcan_devtype_data { 184struct flexcan_devtype_data {
181 u32 hw_ver; /* hardware controller version */ 185 u32 features; /* hardware controller features */
182}; 186};
183 187
184struct flexcan_priv { 188struct flexcan_priv {
@@ -197,11 +201,11 @@ struct flexcan_priv {
197}; 201};
198 202
199static struct flexcan_devtype_data fsl_p1010_devtype_data = { 203static struct flexcan_devtype_data fsl_p1010_devtype_data = {
200 .hw_ver = 3, 204 .features = FLEXCAN_HAS_BROKEN_ERR_STATE,
201}; 205};
202 206static struct flexcan_devtype_data fsl_imx28_devtype_data;
203static struct flexcan_devtype_data fsl_imx6q_devtype_data = { 207static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
204 .hw_ver = 10, 208 .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_BROKEN_ERR_STATE,
205}; 209};
206 210
207static const struct can_bittiming_const flexcan_bittiming_const = { 211static const struct can_bittiming_const flexcan_bittiming_const = {
@@ -741,15 +745,19 @@ static int flexcan_chip_start(struct net_device *dev)
741 * enable tx and rx warning interrupt 745 * enable tx and rx warning interrupt
742 * enable bus off interrupt 746 * enable bus off interrupt
743 * (== FLEXCAN_CTRL_ERR_STATE) 747 * (== FLEXCAN_CTRL_ERR_STATE)
744 *
745 * _note_: we enable the "error interrupt"
746 * (FLEXCAN_CTRL_ERR_MSK), too. Otherwise we don't get any
747 * warning or bus passive interrupts.
748 */ 748 */
749 reg_ctrl = flexcan_read(&regs->ctrl); 749 reg_ctrl = flexcan_read(&regs->ctrl);
750 reg_ctrl &= ~FLEXCAN_CTRL_TSYN; 750 reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
751 reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | 751 reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
752 FLEXCAN_CTRL_ERR_STATE | FLEXCAN_CTRL_ERR_MSK; 752 FLEXCAN_CTRL_ERR_STATE;
753 /*
754 * enable the "error interrupt" (FLEXCAN_CTRL_ERR_MSK),
755 * on most Flexcan cores, too. Otherwise we don't get
756 * any error warning or passive interrupts.
757 */
758 if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE ||
759 priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
760 reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
753 761
754 /* save for later use */ 762 /* save for later use */
755 priv->reg_ctrl_default = reg_ctrl; 763 priv->reg_ctrl_default = reg_ctrl;
@@ -772,7 +780,7 @@ static int flexcan_chip_start(struct net_device *dev)
772 flexcan_write(0x0, &regs->rx14mask); 780 flexcan_write(0x0, &regs->rx14mask);
773 flexcan_write(0x0, &regs->rx15mask); 781 flexcan_write(0x0, &regs->rx15mask);
774 782
775 if (priv->devtype_data->hw_ver >= 10) 783 if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
776 flexcan_write(0x0, &regs->rxfgmask); 784 flexcan_write(0x0, &regs->rxfgmask);
777 785
778 flexcan_transceiver_switch(priv, 1); 786 flexcan_transceiver_switch(priv, 1);
@@ -954,6 +962,7 @@ static void __devexit unregister_flexcandev(struct net_device *dev)
954 962
955static const struct of_device_id flexcan_of_match[] = { 963static const struct of_device_id flexcan_of_match[] = {
956 { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, 964 { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
965 { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
957 { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, 966 { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
958 { /* sentinel */ }, 967 { /* sentinel */ },
959}; 968};