Commit 112d59c7 authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-4.16-20171201' of...

Merge tag 'linux-can-next-for-4.16-20171201' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2017-12-01

this is a pull request of 10 patches for net-next/master.

The first two patches are by Arnd Bergmann, they convert the peak_usb
from using "struct timeval" to "ktime_t". The error handling in the
vxcan driver is clean up by Markus Elfring's patch. Bhumika Goyal
contributes a patch for the c_can_pci driver to make the pci data const.
The six patches by Pankaj Bansal for the flexcan driver add LS1021A
support by making the endianness of the driver configurable by the
device tree.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d671965b fa2edcfb
...@@ -18,6 +18,12 @@ Optional properties: ...@@ -18,6 +18,12 @@ Optional properties:
- xceiver-supply: Regulator that powers the CAN transceiver - xceiver-supply: Regulator that powers the CAN transceiver
- big-endian: This means the registers of FlexCAN controller are big endian.
This is optional property.i.e. if this property is not present in
device tree node then controller is assumed to be little endian.
if this property is present then controller is assumed to be big
endian.
Example: Example:
can@1c000 { can@1c000 {
......
...@@ -122,7 +122,7 @@ i2c3: i2c@43f84000 { ...@@ -122,7 +122,7 @@ i2c3: i2c@43f84000 {
}; };
can1: can@43f88000 { can1: can@43f88000 {
compatible = "fsl,imx25-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx25-flexcan";
reg = <0x43f88000 0x4000>; reg = <0x43f88000 0x4000>;
interrupts = <43>; interrupts = <43>;
clocks = <&clks 75>, <&clks 75>; clocks = <&clks 75>, <&clks 75>;
...@@ -131,7 +131,7 @@ can1: can@43f88000 { ...@@ -131,7 +131,7 @@ can1: can@43f88000 {
}; };
can2: can@43f8c000 { can2: can@43f8c000 {
compatible = "fsl,imx25-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx25-flexcan";
reg = <0x43f8c000 0x4000>; reg = <0x43f8c000 0x4000>;
interrupts = <44>; interrupts = <44>;
clocks = <&clks 76>, <&clks 76>; clocks = <&clks 76>, <&clks 76>;
......
...@@ -1038,7 +1038,7 @@ lcdif: lcdif@80030000 { ...@@ -1038,7 +1038,7 @@ lcdif: lcdif@80030000 {
}; };
can0: can@80032000 { can0: can@80032000 {
compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx28-flexcan";
reg = <0x80032000 0x2000>; reg = <0x80032000 0x2000>;
interrupts = <8>; interrupts = <8>;
clocks = <&clks 58>, <&clks 58>; clocks = <&clks 58>, <&clks 58>;
...@@ -1047,7 +1047,7 @@ can0: can@80032000 { ...@@ -1047,7 +1047,7 @@ can0: can@80032000 {
}; };
can1: can@80034000 { can1: can@80034000 {
compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx28-flexcan";
reg = <0x80034000 0x2000>; reg = <0x80034000 0x2000>;
interrupts = <9>; interrupts = <9>;
clocks = <&clks 59>, <&clks 59>; clocks = <&clks 59>, <&clks 59>;
......
...@@ -303,7 +303,7 @@ wdog: wdog@53fdc000 { ...@@ -303,7 +303,7 @@ wdog: wdog@53fdc000 {
}; };
can1: can@53fe4000 { can1: can@53fe4000 {
compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx35-flexcan";
reg = <0x53fe4000 0x1000>; reg = <0x53fe4000 0x1000>;
clocks = <&clks 33>, <&clks 33>; clocks = <&clks 33>, <&clks 33>;
clock-names = "ipg", "per"; clock-names = "ipg", "per";
...@@ -312,7 +312,7 @@ can1: can@53fe4000 { ...@@ -312,7 +312,7 @@ can1: can@53fe4000 {
}; };
can2: can@53fe8000 { can2: can@53fe8000 {
compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx35-flexcan";
reg = <0x53fe8000 0x1000>; reg = <0x53fe8000 0x1000>;
clocks = <&clks 34>, <&clks 34>; clocks = <&clks 34>, <&clks 34>;
clock-names = "ipg", "per"; clock-names = "ipg", "per";
......
...@@ -545,7 +545,7 @@ uart2: serial@53fc0000 { ...@@ -545,7 +545,7 @@ uart2: serial@53fc0000 {
}; };
can1: can@53fc8000 { can1: can@53fc8000 {
compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx53-flexcan";
reg = <0x53fc8000 0x4000>; reg = <0x53fc8000 0x4000>;
interrupts = <82>; interrupts = <82>;
clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>,
...@@ -555,7 +555,7 @@ can1: can@53fc8000 { ...@@ -555,7 +555,7 @@ can1: can@53fc8000 {
}; };
can2: can@53fcc000 { can2: can@53fcc000 {
compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan"; compatible = "fsl,imx53-flexcan";
reg = <0x53fcc000 0x4000>; reg = <0x53fcc000 0x4000>;
interrupts = <83>; interrupts = <83>;
clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>, clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>,
......
...@@ -331,3 +331,19 @@ &uart0 { ...@@ -331,3 +331,19 @@ &uart0 {
&uart1 { &uart1 {
status = "okay"; status = "okay";
}; };
&can0 {
status = "okay";
};
&can1 {
status = "okay";
};
&can2 {
status = "disabled";
};
&can3 {
status = "disabled";
};
...@@ -243,3 +243,19 @@ &uart0 { ...@@ -243,3 +243,19 @@ &uart0 {
&uart1 { &uart1 {
status = "okay"; status = "okay";
}; };
&can0 {
status = "okay";
};
&can1 {
status = "okay";
};
&can2 {
status = "disabled";
};
&can3 {
status = "disabled";
};
...@@ -730,5 +730,41 @@ pcie@3500000 { ...@@ -730,5 +730,41 @@ pcie@3500000 {
<0000 0 0 3 &gic GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 3 &gic GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
<0000 0 0 4 &gic GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; <0000 0 0 4 &gic GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
}; };
can0: can@2a70000 {
compatible = "fsl,ls1021ar2-flexcan";
reg = <0x0 0x2a70000 0x0 0x1000>;
interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>, <&clockgen 4 1>;
clock-names = "ipg", "per";
big-endian;
};
can1: can@2a80000 {
compatible = "fsl,ls1021ar2-flexcan";
reg = <0x0 0x2a80000 0x0 0x1000>;
interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>, <&clockgen 4 1>;
clock-names = "ipg", "per";
big-endian;
};
can2: can@2a90000 {
compatible = "fsl,ls1021ar2-flexcan";
reg = <0x0 0x2a90000 0x0 0x1000>;
interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>, <&clockgen 4 1>;
clock-names = "ipg", "per";
big-endian;
};
can3: can@2aa0000 {
compatible = "fsl,ls1021ar2-flexcan";
reg = <0x0 0x2aa0000 0x0 0x1000>;
interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>, <&clockgen 4 1>;
clock-names = "ipg", "per";
big-endian;
};
}; };
}; };
...@@ -137,12 +137,14 @@ can0: can@1c000 { ...@@ -137,12 +137,14 @@ can0: can@1c000 {
compatible = "fsl,p1010-flexcan"; compatible = "fsl,p1010-flexcan";
reg = <0x1c000 0x1000>; reg = <0x1c000 0x1000>;
interrupts = <48 0x2 0 0>; interrupts = <48 0x2 0 0>;
big-endian;
}; };
can1: can@1d000 { can1: can@1d000 {
compatible = "fsl,p1010-flexcan"; compatible = "fsl,p1010-flexcan";
reg = <0x1d000 0x1000>; reg = <0x1d000 0x1000>;
interrupts = <61 0x2 0 0>; interrupts = <61 0x2 0 0>;
big-endian;
}; };
L2: l2-cache-controller@20000 { L2: l2-cache-controller@20000 {
......
...@@ -251,14 +251,14 @@ static void c_can_pci_remove(struct pci_dev *pdev) ...@@ -251,14 +251,14 @@ static void c_can_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev); pci_disable_device(pdev);
} }
static struct c_can_pci_data c_can_sta2x11= { static const struct c_can_pci_data c_can_sta2x11= {
.type = BOSCH_C_CAN, .type = BOSCH_C_CAN,
.reg_align = C_CAN_REG_ALIGN_32, .reg_align = C_CAN_REG_ALIGN_32,
.freq = 52000000, /* 52 Mhz */ .freq = 52000000, /* 52 Mhz */
.bar = 0, .bar = 0,
}; };
static struct c_can_pci_data c_can_pch = { static const struct c_can_pci_data c_can_pch = {
.type = BOSCH_C_CAN, .type = BOSCH_C_CAN,
.reg_align = C_CAN_REG_32, .reg_align = C_CAN_REG_32,
.freq = 50000000, /* 50 MHz */ .freq = 50000000, /* 50 MHz */
......
...@@ -190,6 +190,7 @@ ...@@ -190,6 +190,7 @@
* MX53 FlexCAN2 03.00.00.00 yes no no no no * MX53 FlexCAN2 03.00.00.00 yes no no no no
* MX6s FlexCAN3 10.00.12.00 yes yes no no yes * MX6s FlexCAN3 10.00.12.00 yes yes no no yes
* VF610 FlexCAN3 ? no yes ? yes yes? * VF610 FlexCAN3 ? no yes ? yes yes?
* LS1021A FlexCAN2 03.00.04.00 no yes no no yes
* *
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
*/ */
...@@ -279,6 +280,10 @@ struct flexcan_priv { ...@@ -279,6 +280,10 @@ struct flexcan_priv {
struct clk *clk_per; struct clk *clk_per;
const struct flexcan_devtype_data *devtype_data; const struct flexcan_devtype_data *devtype_data;
struct regulator *reg_xceiver; struct regulator *reg_xceiver;
/* Read and Write APIs */
u32 (*read)(void __iomem *addr);
void (*write)(u32 val, void __iomem *addr);
}; };
static const struct flexcan_devtype_data fsl_p1010_devtype_data = { static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
...@@ -300,6 +305,12 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = { ...@@ -300,6 +305,12 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
}; };
static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
};
static const struct can_bittiming_const flexcan_bittiming_const = { static const struct can_bittiming_const flexcan_bittiming_const = {
.name = DRV_NAME, .name = DRV_NAME,
.tseg1_min = 4, .tseg1_min = 4,
...@@ -312,39 +323,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = { ...@@ -312,39 +323,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
.brp_inc = 1, .brp_inc = 1,
}; };
/* Abstract off the read/write for arm versus ppc. This /* FlexCAN module is essentially modelled as a little-endian IP in most
* assumes that PPC uses big-endian registers and everything * SoCs, i.e the registers as well as the message buffer areas are
* else uses little-endian registers, independent of CPU * implemented in a little-endian fashion.
* endianness. *
* However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
* module in a big-endian fashion (i.e the registers as well as the
* message buffer areas are implemented in a big-endian way).
*
* In addition, the FlexCAN module can be found on SoCs having ARM or
* PPC cores. So, we need to abstract off the register read/write
* functions, ensuring that these cater to all the combinations of module
* endianness and underlying CPU endianness.
*/ */
#if defined(CONFIG_PPC) static inline u32 flexcan_read_be(void __iomem *addr)
static inline u32 flexcan_read(void __iomem *addr)
{ {
return in_be32(addr); return ioread32be(addr);
} }
static inline void flexcan_write(u32 val, void __iomem *addr) static inline void flexcan_write_be(u32 val, void __iomem *addr)
{ {
out_be32(addr, val); iowrite32be(val, addr);
} }
#else
static inline u32 flexcan_read(void __iomem *addr) static inline u32 flexcan_read_le(void __iomem *addr)
{ {
return readl(addr); return ioread32(addr);
} }
static inline void flexcan_write(u32 val, void __iomem *addr) static inline void flexcan_write_le(u32 val, void __iomem *addr)
{ {
writel(val, addr); iowrite32(val, addr);
} }
#endif
static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
{ {
struct flexcan_regs __iomem *regs = priv->regs; struct flexcan_regs __iomem *regs = priv->regs;
u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
flexcan_write(reg_ctrl, &regs->ctrl); priv->write(reg_ctrl, &regs->ctrl);
} }
static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
...@@ -352,7 +369,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) ...@@ -352,7 +369,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->regs; struct flexcan_regs __iomem *regs = priv->regs;
u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
flexcan_write(reg_ctrl, &regs->ctrl); priv->write(reg_ctrl, &regs->ctrl);
} }
static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
...@@ -377,14 +394,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv) ...@@ -377,14 +394,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
u32 reg; u32 reg;
reg = flexcan_read(&regs->mcr); reg = priv->read(&regs->mcr);
reg &= ~FLEXCAN_MCR_MDIS; reg &= ~FLEXCAN_MCR_MDIS;
flexcan_write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)) while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
udelay(10); udelay(10);
if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK) if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
return -ETIMEDOUT; return -ETIMEDOUT;
return 0; return 0;
...@@ -396,14 +413,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv) ...@@ -396,14 +413,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
u32 reg; u32 reg;
reg = flexcan_read(&regs->mcr); reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_MDIS; reg |= FLEXCAN_MCR_MDIS;
flexcan_write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)) while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
udelay(10); udelay(10);
if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)) if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
return -ETIMEDOUT; return -ETIMEDOUT;
return 0; return 0;
...@@ -415,14 +432,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv) ...@@ -415,14 +432,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
u32 reg; u32 reg;
reg = flexcan_read(&regs->mcr); reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_HALT; reg |= FLEXCAN_MCR_HALT;
flexcan_write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)) while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
udelay(100); udelay(100);
if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)) if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
return -ETIMEDOUT; return -ETIMEDOUT;
return 0; return 0;
...@@ -434,14 +451,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv) ...@@ -434,14 +451,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
u32 reg; u32 reg;
reg = flexcan_read(&regs->mcr); reg = priv->read(&regs->mcr);
reg &= ~FLEXCAN_MCR_HALT; reg &= ~FLEXCAN_MCR_HALT;
flexcan_write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)) while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
udelay(10); udelay(10);
if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK) if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
return -ETIMEDOUT; return -ETIMEDOUT;
return 0; return 0;
...@@ -452,11 +469,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv) ...@@ -452,11 +469,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->regs; struct flexcan_regs __iomem *regs = priv->regs;
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr); priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)) while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
udelay(10); udelay(10);
if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST) if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
return -ETIMEDOUT; return -ETIMEDOUT;
return 0; return 0;
...@@ -467,7 +484,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev, ...@@ -467,7 +484,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev,
{ {
const struct flexcan_priv *priv = netdev_priv(dev); const struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->regs; struct flexcan_regs __iomem *regs = priv->regs;
u32 reg = flexcan_read(&regs->ecr); u32 reg = priv->read(&regs->ecr);
bec->txerr = (reg >> 0) & 0xff; bec->txerr = (reg >> 0) & 0xff;
bec->rxerr = (reg >> 8) & 0xff; bec->rxerr = (reg >> 8) & 0xff;
...@@ -523,24 +540,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -523,24 +540,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (cf->can_dlc > 0) { if (cf->can_dlc > 0) {
data = be32_to_cpup((__be32 *)&cf->data[0]); data = be32_to_cpup((__be32 *)&cf->data[0]);
flexcan_write(data, &priv->tx_mb->data[0]); priv->write(data, &priv->tx_mb->data[0]);
} }
if (cf->can_dlc > 3) { if (cf->can_dlc > 3) {
data = be32_to_cpup((__be32 *)&cf->data[4]); data = be32_to_cpup((__be32 *)&cf->data[4]);
flexcan_write(data, &priv->tx_mb->data[1]); priv->write(data, &priv->tx_mb->data[1]);
} }
can_put_echo_skb(skb, dev, 0); can_put_echo_skb(skb, dev, 0);
flexcan_write(can_id, &priv->tx_mb->can_id); priv->write(can_id, &priv->tx_mb->can_id);
flexcan_write(ctrl, &priv->tx_mb->can_ctrl); priv->write(ctrl, &priv->tx_mb->can_ctrl);
/* Errata ERR005829 step8: /* Errata ERR005829 step8:
* Write twice INACTIVE(0x8) code to first MB. * Write twice INACTIVE(0x8) code to first MB.
*/ */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb_reserved->can_ctrl); &priv->tx_mb_reserved->can_ctrl);
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb_reserved->can_ctrl); &priv->tx_mb_reserved->can_ctrl);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -659,7 +676,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, ...@@ -659,7 +676,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
u32 code; u32 code;
do { do {
reg_ctrl = flexcan_read(&mb->can_ctrl); reg_ctrl = priv->read(&mb->can_ctrl);
} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT); } while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
/* is this MB empty? */ /* is this MB empty? */
...@@ -674,17 +691,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, ...@@ -674,17 +691,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
offload->dev->stats.rx_errors++; offload->dev->stats.rx_errors++;
} }
} else { } else {
reg_iflag1 = flexcan_read(&regs->iflag1); reg_iflag1 = priv->read(&regs->iflag1);
if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)) if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
return 0; return 0;
reg_ctrl = flexcan_read(&mb->can_ctrl); reg_ctrl = priv->read(&mb->can_ctrl);
} }
/* increase timstamp to full 32 bit */ /* increase timstamp to full 32 bit */
*timestamp = reg_ctrl << 16; *timestamp = reg_ctrl << 16;
reg_id = flexcan_read(&mb->can_id); reg_id = priv->read(&mb->can_id);
if (reg_ctrl & FLEXCAN_MB_CNT_IDE) if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
else else
...@@ -694,19 +711,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, ...@@ -694,19 +711,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
cf->can_id |= CAN_RTR_FLAG; cf->can_id |= CAN_RTR_FLAG;
cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0])); *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1])); *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
/* mark as read */ /* mark as read */
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
/* Clear IRQ */ /* Clear IRQ */
if (n < 32) if (n < 32)
flexcan_write(BIT(n), &regs->iflag1); priv->write(BIT(n), &regs->iflag1);
else else
flexcan_write(BIT(n - 32), &regs->iflag2); priv->write(BIT(n - 32), &regs->iflag2);
} else { } else {
flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1); priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
flexcan_read(&regs->timer); priv->read(&regs->timer);
} }
return 1; return 1;
...@@ -718,8 +735,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) ...@@ -718,8 +735,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->regs; struct flexcan_regs __iomem *regs = priv->regs;
u32 iflag1, iflag2; u32 iflag1, iflag2;
iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default; iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default & iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
return (u64)iflag2 << 32 | iflag1; return (u64)iflag2 << 32 | iflag1;
...@@ -735,7 +752,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) ...@@ -735,7 +752,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
u32 reg_iflag1, reg_esr; u32 reg_iflag1, reg_esr;
enum can_state last_state = priv->can.state; enum can_state last_state = priv->can.state;
reg_iflag1 = flexcan_read(&regs->iflag1); reg_iflag1 = priv->read(&regs->iflag1);
/* reception interrupt */ /* reception interrupt */
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
...@@ -758,7 +775,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) ...@@ -758,7 +775,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
/* FIFO overflow interrupt */ /* FIFO overflow interrupt */
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
handled = IRQ_HANDLED; handled = IRQ_HANDLED;
flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1); priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
&regs->iflag1);
dev->stats.rx_over_errors++; dev->stats.rx_over_errors++;
dev->stats.rx_errors++; dev->stats.rx_errors++;
} }
...@@ -772,18 +790,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) ...@@ -772,18 +790,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
can_led_event(dev, CAN_LED_EVENT_TX); can_led_event(dev, CAN_LED_EVENT_TX);
/* after sending a RTR frame MB is in RX mode */ /* after sending a RTR frame MB is in RX mode */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb->can_ctrl); &priv->tx_mb->can_ctrl);
flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1); priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
netif_wake_queue(dev); netif_wake_queue(dev);
} }
reg_esr = flexcan_read(&regs->esr); reg_esr = priv->read(&regs->esr);
/* ACK all bus error and state change IRQ sources */ /* ACK all bus error and state change IRQ sources */
if (reg_esr & FLEXCAN_ESR_ALL_INT) { if (reg_esr & FLEXCAN_ESR_ALL_INT) {
handled = IRQ_HANDLED; handled = IRQ_HANDLED;
flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr); priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
} }
/* state change interrupt or broken error state quirk fix is enabled */ /* state change interrupt or broken error state quirk fix is enabled */
...@@ -845,7 +863,7 @@ static void flexcan_set_bittiming(struct net_device *dev) ...@@ -845,7 +863,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
struct flexcan_regs __iomem *regs = priv->regs; struct flexcan_regs __iomem *regs = priv->regs;
u32 reg; u32 reg;
reg = flexcan_read(&regs->ctrl); reg = priv->read(&regs->ctrl);
reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
FLEXCAN_CTRL_RJW(0x3) | FLEXCAN_CTRL_RJW(0x3) |
FLEXCAN_CTRL_PSEG1(0x7) | FLEXCAN_CTRL_PSEG1(0x7) |
...@@ -869,11 +887,11 @@ static void flexcan_set_bittiming(struct net_device *dev) ...@@ -869,11 +887,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
reg |= FLEXCAN_CTRL_SMP; reg |= FLEXCAN_CTRL_SMP;
netdev_dbg(dev, "writing ctrl=0x%08x\n", reg); netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
flexcan_write(reg, &regs->ctrl); priv->write(reg, &regs->ctrl);
/* print chip status */ /* print chip status */
netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl)); priv->read(&regs->mcr), priv->read(&regs->ctrl));
} }
/* flexcan_chip_start /* flexcan_chip_start
...@@ -912,7 +930,7 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -912,7 +930,7 @@ static int flexcan_chip_start(struct net_device *dev)
* choose format C * choose format C
* set max mailbox number * set max mailbox number
*/ */
reg_mcr = flexcan_read(&regs->mcr); reg_mcr = priv->read(&regs->mcr);
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
...@@ -926,7 +944,7 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -926,7 +944,7 @@ static int flexcan_chip_start(struct net_device *dev)
FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
} }
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
flexcan_write(reg_mcr, &regs->mcr); priv->write(reg_mcr, &regs->mcr);
/* CTRL /* CTRL
* *
...@@ -939,7 +957,7 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -939,7 +957,7 @@ static int flexcan_chip_start(struct net_device *dev)
* enable bus off interrupt * enable bus off interrupt
* (== FLEXCAN_CTRL_ERR_STATE) * (== FLEXCAN_CTRL_ERR_STATE)
*/ */
reg_ctrl = flexcan_read(&regs->ctrl); reg_ctrl = priv->read(&regs->ctrl);
reg_ctrl &= ~FLEXCAN_CTRL_TSYN; reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
FLEXCAN_CTRL_ERR_STATE; FLEXCAN_CTRL_ERR_STATE;
...@@ -959,45 +977,45 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -959,45 +977,45 @@ static int flexcan_chip_start(struct net_device *dev)
/* leave interrupts disabled for now */ /* leave interrupts disabled for now */
reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL; reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
flexcan_write(reg_ctrl, &regs->ctrl); priv->write(reg_ctrl, &regs->ctrl);
if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
reg_ctrl2 = flexcan_read(&regs->ctrl2); reg_ctrl2 = priv->read(&regs->ctrl2);
reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS; reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
flexcan_write(reg_ctrl2, &regs->ctrl2); priv->write(reg_ctrl2, &regs->ctrl2);
} }
/* clear and invalidate all mailboxes first */ /* clear and invalidate all mailboxes first */
for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) { for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE, priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
&regs->mb[i].can_ctrl); &regs->mb[i].can_ctrl);
} }
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY, priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
&regs->mb[i].can_ctrl); &regs->mb[i].can_ctrl);
} }
/* Errata ERR005829: mark first TX mailbox as INACTIVE */ /* Errata ERR005829: mark first TX mailbox as INACTIVE */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb_reserved->can_ctrl); &priv->tx_mb_reserved->can_ctrl);
/* mark TX mailbox as INACTIVE */ /* mark TX mailbox as INACTIVE */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb->can_ctrl); &priv->tx_mb->can_ctrl);
/* acceptance mask/acceptance code (accept everything) */ /* acceptance mask/acceptance code (accept everything) */
flexcan_write(0x0, &regs->rxgmask); priv->write(0x0, &regs->rxgmask);
flexcan_write(0x0, &regs->rx14mask); priv->write(0x0, &regs->rx14mask);
flexcan_write(0x0, &regs->rx15mask); priv->write(0x0, &regs->rx15mask);
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
flexcan_write(0x0, &regs->rxfgmask); priv->write(0x0, &regs->rxfgmask);
/* clear acceptance filters */ /* clear acceptance filters */
for (i = 0; i < ARRAY_SIZE(regs->mb); i++) for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
flexcan_write(0, &regs->rximr[i]); priv->write(0, &regs->rximr[i]);
/* On Vybrid, disable memory error detection interrupts /* On Vybrid, disable memory error detection interrupts
* and freeze mode. * and freeze mode.
...@@ -1010,16 +1028,16 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -1010,16 +1028,16 @@ static int flexcan_chip_start(struct net_device *dev)
* and Correction of Memory Errors" to write to * and Correction of Memory Errors" to write to
* MECR register * MECR register
*/ */
reg_ctrl2 = flexcan_read(&regs->ctrl2); reg_ctrl2 = priv->read(&regs->ctrl2);
reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE; reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
flexcan_write(reg_ctrl2, &regs->ctrl2); priv->write(reg_ctrl2, &regs->ctrl2);
reg_mecr = flexcan_read(&regs->mecr); reg_mecr = priv->read(&regs->mecr);
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
flexcan_write(reg_mecr, &regs->mecr); priv->write(reg_mecr, &regs->mecr);
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
FLEXCAN_MECR_FANCEI_MSK); FLEXCAN_MECR_FANCEI_MSK);
flexcan_write(reg_mecr, &regs->mecr); priv->write(reg_mecr, &regs->mecr);
} }
err = flexcan_transceiver_enable(priv); err = flexcan_transceiver_enable(priv);
...@@ -1035,14 +1053,14 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -1035,14 +1053,14 @@ static int flexcan_chip_start(struct net_device *dev)
/* enable interrupts atomically */ /* enable interrupts atomically */
disable_irq(dev->irq); disable_irq(dev->irq);
flexcan_write(priv->reg_ctrl_default, &regs->ctrl); priv->write(priv->reg_ctrl_default, &regs->ctrl);
flexcan_write(priv->reg_imask1_default, &regs->imask1); priv->write(priv->reg_imask1_default, &regs->imask1);
flexcan_write(priv->reg_imask2_default, &regs->imask2); priv->write(priv->reg_imask2_default, &regs->imask2);
enable_irq(dev->irq); enable_irq(dev->irq);
/* print chip status */ /* print chip status */
netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl)); priv->read(&regs->mcr), priv->read(&regs->ctrl));
return 0; return 0;
...@@ -1067,10 +1085,10 @@ static void flexcan_chip_stop(struct net_device *dev) ...@@ -1067,10 +1085,10 @@ static void flexcan_chip_stop(struct net_device *dev)
flexcan_chip_disable(priv); flexcan_chip_disable(priv);
/* Disable all interrupts */ /* Disable all interrupts */
flexcan_write(0, &regs->imask2); priv->write(0, &regs->imask2);
flexcan_write(0, &regs->imask1); priv->write(0, &regs->imask1);
flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
&regs->ctrl); &regs->ctrl);
flexcan_transceiver_disable(priv); flexcan_transceiver_disable(priv);
priv->can.state = CAN_STATE_STOPPED; priv->can.state = CAN_STATE_STOPPED;
...@@ -1185,26 +1203,26 @@ static int register_flexcandev(struct net_device *dev) ...@@ -1185,26 +1203,26 @@ static int register_flexcandev(struct net_device *dev)
err = flexcan_chip_disable(priv); err = flexcan_chip_disable(priv);
if (err) if (err)
goto out_disable_per; goto out_disable_per;
reg = flexcan_read(&regs->ctrl); reg = priv->read(&regs->ctrl);
reg |= FLEXCAN_CTRL_CLK_SRC; reg |= FLEXCAN_CTRL_CLK_SRC;
flexcan_write(reg, &regs->ctrl); priv->write(reg, &regs->ctrl);
err = flexcan_chip_enable(priv); err = flexcan_chip_enable(priv);
if (err) if (err)
goto out_chip_disable; goto out_chip_disable;
/* set freeze, halt and activate FIFO, restrict register access */ /* set freeze, halt and activate FIFO, restrict register access */
reg = flexcan_read(&regs->mcr); reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
flexcan_write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
/* Currently we only support newer versions of this core /* Currently we only support newer versions of this core
* featuring a RX hardware FIFO (although this driver doesn't * featuring a RX hardware FIFO (although this driver doesn't
* make use of it on some cores). Older cores, found on some * make use of it on some cores). Older cores, found on some
* Coldfire derivates are not tested. * Coldfire derivates are not tested.
*/ */
reg = flexcan_read(&regs->mcr); reg = priv->read(&regs->mcr);
if (!(reg & FLEXCAN_MCR_FEN)) { if (!(reg & FLEXCAN_MCR_FEN)) {
netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
err = -ENODEV; err = -ENODEV;
...@@ -1232,8 +1250,12 @@ static void unregister_flexcandev(struct net_device *dev) ...@@ -1232,8 +1250,12 @@ static void unregister_flexcandev(struct net_device *dev)
static const struct of_device_id flexcan_of_match[] = { static const struct of_device_id flexcan_of_match[] = {
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
{ .compatible = "fsl,imx53-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,imx35-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
{ .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, },
{ /* sentinel */ }, { /* sentinel */ },
}; };
MODULE_DEVICE_TABLE(of, flexcan_of_match); MODULE_DEVICE_TABLE(of, flexcan_of_match);
...@@ -1313,6 +1335,21 @@ static int flexcan_probe(struct platform_device *pdev) ...@@ -1313,6 +1335,21 @@ static int flexcan_probe(struct platform_device *pdev)
dev->flags |= IFF_ECHO; dev->flags |= IFF_ECHO;
priv = netdev_priv(dev); priv = netdev_priv(dev);
if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
priv->read = flexcan_read_be;
priv->write = flexcan_write_be;
} else {
if (of_device_is_compatible(pdev->dev.of_node,
"fsl,p1010-flexcan")) {
priv->read = flexcan_read_be;
priv->write = flexcan_write_be;
} else {
priv->read = flexcan_read_le;
priv->write = flexcan_write_le;
}
}
priv->can.clock.freq = clock_freq; priv->can.clock.freq = clock_freq;
priv->can.bittiming_const = &flexcan_bittiming_const; priv->can.bittiming_const = &flexcan_bittiming_const;
priv->can.do_set_mode = flexcan_set_mode; priv->can.do_set_mode = flexcan_set_mode;
......
...@@ -408,7 +408,6 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, ...@@ -408,7 +408,6 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct can_frame *cf; struct can_frame *cf;
struct timeval tv;
enum can_state new_state; enum can_state new_state;
/* ignore this error until 1st ts received */ /* ignore this error until 1st ts received */
...@@ -525,8 +524,8 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, ...@@ -525,8 +524,8 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); peak_usb_get_ts_time(&mc->pdev->time_ref, mc->ts16,
hwts->hwtstamp = timeval_to_ktime(tv); &hwts->hwtstamp);
} }
mc->netdev->stats.rx_packets++; mc->netdev->stats.rx_packets++;
...@@ -610,7 +609,6 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) ...@@ -610,7 +609,6 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
u8 rec_len = status_len & PCAN_USB_STATUSLEN_DLC; u8 rec_len = status_len & PCAN_USB_STATUSLEN_DLC;
struct sk_buff *skb; struct sk_buff *skb;
struct can_frame *cf; struct can_frame *cf;
struct timeval tv;
struct skb_shared_hwtstamps *hwts; struct skb_shared_hwtstamps *hwts;
skb = alloc_can_skb(mc->netdev, &cf); skb = alloc_can_skb(mc->netdev, &cf);
...@@ -658,9 +656,8 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) ...@@ -658,9 +656,8 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
} }
/* convert timestamp into kernel time */ /* convert timestamp into kernel time */
peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
hwts = skb_hwtstamps(skb); hwts = skb_hwtstamps(skb);
hwts->hwtstamp = timeval_to_ktime(tv); peak_usb_get_ts_time(&mc->pdev->time_ref, mc->ts16, &hwts->hwtstamp);
/* update statistics */ /* update statistics */
mc->netdev->stats.rx_packets++; mc->netdev->stats.rx_packets++;
......
...@@ -80,21 +80,6 @@ void peak_usb_init_time_ref(struct peak_time_ref *time_ref, ...@@ -80,21 +80,6 @@ void peak_usb_init_time_ref(struct peak_time_ref *time_ref,
} }
} }
static void peak_usb_add_us(struct timeval *tv, u32 delta_us)
{
/* number of s. to add to final time */
u32 delta_s = delta_us / 1000000;
delta_us -= delta_s * 1000000;
tv->tv_usec += delta_us;
if (tv->tv_usec >= 1000000) {
tv->tv_usec -= 1000000;
delta_s++;
}
tv->tv_sec += delta_s;
}
/* /*
* sometimes, another now may be more recent than current one... * sometimes, another now may be more recent than current one...
*/ */
...@@ -103,7 +88,7 @@ void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now) ...@@ -103,7 +88,7 @@ void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now)
time_ref->ts_dev_2 = ts_now; time_ref->ts_dev_2 = ts_now;
/* should wait at least two passes before computing */ /* should wait at least two passes before computing */
if (time_ref->tv_host.tv_sec > 0) { if (ktime_to_ns(time_ref->tv_host) > 0) {
u32 delta_ts = time_ref->ts_dev_2 - time_ref->ts_dev_1; u32 delta_ts = time_ref->ts_dev_2 - time_ref->ts_dev_1;
if (time_ref->ts_dev_2 < time_ref->ts_dev_1) if (time_ref->ts_dev_2 < time_ref->ts_dev_1)
...@@ -118,26 +103,26 @@ void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now) ...@@ -118,26 +103,26 @@ void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now)
*/ */
void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now) void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now)
{ {
if (time_ref->tv_host_0.tv_sec == 0) { if (ktime_to_ns(time_ref->tv_host_0) == 0) {
/* use monotonic clock to correctly compute further deltas */ /* use monotonic clock to correctly compute further deltas */
time_ref->tv_host_0 = ktime_to_timeval(ktime_get()); time_ref->tv_host_0 = ktime_get();
time_ref->tv_host.tv_sec = 0; time_ref->tv_host = ktime_set(0, 0);
} else { } else {
/* /*
* delta_us should not be >= 2^32 => delta_s should be < 4294 * delta_us should not be >= 2^32 => delta should be < 4294s
* handle 32-bits wrapping here: if count of s. reaches 4200, * handle 32-bits wrapping here: if count of s. reaches 4200,
* reset counters and change time base * reset counters and change time base
*/ */
if (time_ref->tv_host.tv_sec != 0) { if (ktime_to_ns(time_ref->tv_host)) {
u32 delta_s = time_ref->tv_host.tv_sec ktime_t delta = ktime_sub(time_ref->tv_host,
- time_ref->tv_host_0.tv_sec; time_ref->tv_host_0);
if (delta_s > 4200) { if (ktime_to_ns(delta) > (4200ull * NSEC_PER_SEC)) {
time_ref->tv_host_0 = time_ref->tv_host; time_ref->tv_host_0 = time_ref->tv_host;
time_ref->ts_total = 0; time_ref->ts_total = 0;
} }
} }
time_ref->tv_host = ktime_to_timeval(ktime_get()); time_ref->tv_host = ktime_get();
time_ref->tick_count++; time_ref->tick_count++;
} }
...@@ -146,13 +131,12 @@ void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now) ...@@ -146,13 +131,12 @@ void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now)
} }
/* /*
* compute timeval according to current ts and time_ref data * compute time according to current ts and time_ref data
*/ */
void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts, void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *time)
struct timeval *tv)
{ {
/* protect from getting timeval before setting now */ /* protect from getting time before setting now */
if (time_ref->tv_host.tv_sec > 0) { if (ktime_to_ns(time_ref->tv_host)) {
u64 delta_us; u64 delta_us;
delta_us = ts - time_ref->ts_dev_2; delta_us = ts - time_ref->ts_dev_2;
...@@ -164,10 +148,9 @@ void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts, ...@@ -164,10 +148,9 @@ void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts,
delta_us *= time_ref->adapter->us_per_ts_scale; delta_us *= time_ref->adapter->us_per_ts_scale;
delta_us >>= time_ref->adapter->us_per_ts_shift; delta_us >>= time_ref->adapter->us_per_ts_shift;
*tv = time_ref->tv_host_0; *time = ktime_add_us(time_ref->tv_host_0, delta_us);
peak_usb_add_us(tv, (u32)delta_us);
} else { } else {
*tv = ktime_to_timeval(ktime_get()); *time = ktime_get();
} }
} }
...@@ -178,10 +161,8 @@ int peak_usb_netif_rx(struct sk_buff *skb, ...@@ -178,10 +161,8 @@ int peak_usb_netif_rx(struct sk_buff *skb,
struct peak_time_ref *time_ref, u32 ts_low, u32 ts_high) struct peak_time_ref *time_ref, u32 ts_low, u32 ts_high)
{ {
struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
struct timeval tv;
peak_usb_get_ts_tv(time_ref, ts_low, &tv); peak_usb_get_ts_time(time_ref, ts_low, &hwts->hwtstamp);
hwts->hwtstamp = timeval_to_ktime(tv);
return netif_rx(skb); return netif_rx(skb);
} }
......
...@@ -96,7 +96,7 @@ extern const struct peak_usb_adapter pcan_usb_pro_fd; ...@@ -96,7 +96,7 @@ extern const struct peak_usb_adapter pcan_usb_pro_fd;
extern const struct peak_usb_adapter pcan_usb_x6; extern const struct peak_usb_adapter pcan_usb_x6;
struct peak_time_ref { struct peak_time_ref {
struct timeval tv_host_0, tv_host; ktime_t tv_host_0, tv_host;
u32 ts_dev_1, ts_dev_2; u32 ts_dev_1, ts_dev_2;
u64 ts_total; u64 ts_total;
u32 tick_count; u32 tick_count;
...@@ -151,8 +151,7 @@ void peak_usb_init_time_ref(struct peak_time_ref *time_ref, ...@@ -151,8 +151,7 @@ void peak_usb_init_time_ref(struct peak_time_ref *time_ref,
const struct peak_usb_adapter *adapter); const struct peak_usb_adapter *adapter);
void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now); void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now); void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts, void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *tv);
struct timeval *tv);
int peak_usb_netif_rx(struct sk_buff *skb, int peak_usb_netif_rx(struct sk_buff *skb,
struct peak_time_ref *time_ref, u32 ts_low, u32 ts_high); struct peak_time_ref *time_ref, u32 ts_low, u32 ts_high);
void peak_usb_async_complete(struct urb *urb); void peak_usb_async_complete(struct urb *urb);
......
...@@ -531,7 +531,6 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, ...@@ -531,7 +531,6 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
struct net_device *netdev = dev->netdev; struct net_device *netdev = dev->netdev;
struct can_frame *can_frame; struct can_frame *can_frame;
struct sk_buff *skb; struct sk_buff *skb;
struct timeval tv;
struct skb_shared_hwtstamps *hwts; struct skb_shared_hwtstamps *hwts;
skb = alloc_can_skb(netdev, &can_frame); skb = alloc_can_skb(netdev, &can_frame);
...@@ -549,9 +548,9 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, ...@@ -549,9 +548,9 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
else else
memcpy(can_frame->data, rx->data, can_frame->can_dlc); memcpy(can_frame->data, rx->data, can_frame->can_dlc);
peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv);
hwts = skb_hwtstamps(skb); hwts = skb_hwtstamps(skb);
hwts->hwtstamp = timeval_to_ktime(tv); peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(rx->ts32),
&hwts->hwtstamp);
netdev->stats.rx_packets++; netdev->stats.rx_packets++;
netdev->stats.rx_bytes += can_frame->can_dlc; netdev->stats.rx_bytes += can_frame->can_dlc;
...@@ -571,7 +570,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, ...@@ -571,7 +570,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
enum can_state new_state = CAN_STATE_ERROR_ACTIVE; enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
u8 err_mask = 0; u8 err_mask = 0;
struct sk_buff *skb; struct sk_buff *skb;
struct timeval tv;
struct skb_shared_hwtstamps *hwts; struct skb_shared_hwtstamps *hwts;
/* nothing should be sent while in BUS_OFF state */ /* nothing should be sent while in BUS_OFF state */
...@@ -667,9 +665,8 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, ...@@ -667,9 +665,8 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
dev->can.state = new_state; dev->can.state = new_state;
peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv);
hwts = skb_hwtstamps(skb); hwts = skb_hwtstamps(skb);
hwts->hwtstamp = timeval_to_ktime(tv); peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(er->ts32), &hwts->hwtstamp);
netdev->stats.rx_packets++; netdev->stats.rx_packets++;
netdev->stats.rx_bytes += can_frame->can_dlc; netdev->stats.rx_bytes += can_frame->can_dlc;
netif_rx(skb); netif_rx(skb);
......
...@@ -227,10 +227,8 @@ static int vxcan_newlink(struct net *net, struct net_device *dev, ...@@ -227,10 +227,8 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
netif_carrier_off(peer); netif_carrier_off(peer);
err = rtnl_configure_link(peer, ifmp); err = rtnl_configure_link(peer, ifmp);
if (err < 0) { if (err < 0)
unregister_netdevice(peer); goto unregister_network_device;
return err;
}
/* register first device */ /* register first device */
if (tb[IFLA_IFNAME]) if (tb[IFLA_IFNAME])
...@@ -239,10 +237,8 @@ static int vxcan_newlink(struct net *net, struct net_device *dev, ...@@ -239,10 +237,8 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d"); snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
err = register_netdevice(dev); err = register_netdevice(dev);
if (err < 0) { if (err < 0)
unregister_netdevice(peer); goto unregister_network_device;
return err;
}
netif_carrier_off(dev); netif_carrier_off(dev);
...@@ -254,6 +250,10 @@ static int vxcan_newlink(struct net *net, struct net_device *dev, ...@@ -254,6 +250,10 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
rcu_assign_pointer(priv->peer, dev); rcu_assign_pointer(priv->peer, dev);
return 0; return 0;
unregister_network_device:
unregister_netdevice(peer);
return err;
} }
static void vxcan_dellink(struct net_device *dev, struct list_head *head) static void vxcan_dellink(struct net_device *dev, struct list_head *head)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment