summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-03-10 17:41:33 (GMT)
committerDavid S. Miller <davem@davemloft.net>2016-03-10 17:41:33 (GMT)
commit798fee48035f0c5fc6787767ff9e27de7e1a4fbb (patch)
tree0d9181a5d0ff6a6bf879dfb869e231b44b046303 /drivers
parentcdc4e47da8f4c32eeb6b2061a8a834f4362a12b7 (diff)
parente481ab23c57b37c989fa27e0a6b3e941a908775a (diff)
downloadlinux-798fee48035f0c5fc6787767ff9e27de7e1a4fbb.tar.xz
Merge tag 'linux-can-next-for-4.6-20160310' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says: ==================== pull-request: can-next 2016-03-10 this is a pull request of 5 patch for net-next/master. Marek Vasut contributes 4 patches for the ifi CAN driver, which makes it work on real hardware. There is one patch by Ramesh Shanmugasundaram for the rcar_can driver that adds support for the 3rd generation IP core. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/can/Kconfig2
-rw-r--r--drivers/net/can/ifi_canfd/ifi_canfd.c97
-rw-r--r--drivers/net/can/rcar_can.c1
3 files changed, 64 insertions, 36 deletions
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 164ccde..0d40aef 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -106,7 +106,7 @@ config CAN_JANZ_ICAN3
config CAN_RCAR
tristate "Renesas R-Car CAN controller"
- depends on ARM
+ depends on ARCH_RENESAS || ARM
---help---
Say Y here if you want to use CAN controller found on Renesas R-Car
SoCs.
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 0d1c164..a1bd54f 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -135,8 +135,12 @@
#define IFI_CANFD_RXFIFO_ID 0x6c
#define IFI_CANFD_RXFIFO_ID_ID_OFFSET 0
-#define IFI_CANFD_RXFIFO_ID_ID_STD_MASK 0x3ff
-#define IFI_CANFD_RXFIFO_ID_ID_XTD_MASK 0x1fffffff
+#define IFI_CANFD_RXFIFO_ID_ID_STD_MASK CAN_SFF_MASK
+#define IFI_CANFD_RXFIFO_ID_ID_STD_OFFSET 0
+#define IFI_CANFD_RXFIFO_ID_ID_STD_WIDTH 10
+#define IFI_CANFD_RXFIFO_ID_ID_XTD_MASK CAN_EFF_MASK
+#define IFI_CANFD_RXFIFO_ID_ID_XTD_OFFSET 11
+#define IFI_CANFD_RXFIFO_ID_ID_XTD_WIDTH 18
#define IFI_CANFD_RXFIFO_ID_IDE BIT(29)
#define IFI_CANFD_RXFIFO_DATA 0x70 /* 0x70..0xac */
@@ -156,8 +160,12 @@
#define IFI_CANFD_TXFIFO_ID 0xbc
#define IFI_CANFD_TXFIFO_ID_ID_OFFSET 0
-#define IFI_CANFD_TXFIFO_ID_ID_STD_MASK 0x3ff
-#define IFI_CANFD_TXFIFO_ID_ID_XTD_MASK 0x1fffffff
+#define IFI_CANFD_TXFIFO_ID_ID_STD_MASK CAN_SFF_MASK
+#define IFI_CANFD_TXFIFO_ID_ID_STD_OFFSET 0
+#define IFI_CANFD_TXFIFO_ID_ID_STD_WIDTH 10
+#define IFI_CANFD_TXFIFO_ID_ID_XTD_MASK CAN_EFF_MASK
+#define IFI_CANFD_TXFIFO_ID_ID_XTD_OFFSET 11
+#define IFI_CANFD_TXFIFO_ID_ID_XTD_WIDTH 18
#define IFI_CANFD_TXFIFO_ID_IDE BIT(29)
#define IFI_CANFD_TXFIFO_DATA 0xc0 /* 0xb0..0xfc */
@@ -229,10 +237,20 @@ static void ifi_canfd_read_fifo(struct net_device *ndev)
rxid = readl(priv->base + IFI_CANFD_RXFIFO_ID);
id = (rxid >> IFI_CANFD_RXFIFO_ID_ID_OFFSET);
- if (id & IFI_CANFD_RXFIFO_ID_IDE)
+ if (id & IFI_CANFD_RXFIFO_ID_IDE) {
id &= IFI_CANFD_RXFIFO_ID_ID_XTD_MASK;
- else
+ /*
+ * In case the Extended ID frame is received, the standard
+ * and extended part of the ID are swapped in the register,
+ * so swap them back to obtain the correct ID.
+ */
+ id = (id >> IFI_CANFD_RXFIFO_ID_ID_XTD_OFFSET) |
+ ((id & IFI_CANFD_RXFIFO_ID_ID_STD_MASK) <<
+ IFI_CANFD_RXFIFO_ID_ID_XTD_WIDTH);
+ id |= CAN_EFF_FLAG;
+ } else {
id &= IFI_CANFD_RXFIFO_ID_ID_STD_MASK;
+ }
cf->can_id = id;
if (rxdlc & IFI_CANFD_RXFIFO_DLC_ESI) {
@@ -514,25 +532,25 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
static const struct can_bittiming_const ifi_canfd_bittiming_const = {
.name = KBUILD_MODNAME,
- .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
+ .tseg1_min = 1, /* Time segment 1 = prop_seg + phase_seg1 */
.tseg1_max = 64,
- .tseg2_min = 1, /* Time segment 2 = phase_seg2 */
- .tseg2_max = 16,
+ .tseg2_min = 2, /* Time segment 2 = phase_seg2 */
+ .tseg2_max = 64,
.sjw_max = 16,
- .brp_min = 1,
- .brp_max = 1024,
+ .brp_min = 2,
+ .brp_max = 256,
.brp_inc = 1,
};
static const struct can_bittiming_const ifi_canfd_data_bittiming_const = {
.name = KBUILD_MODNAME,
- .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
- .tseg1_max = 16,
- .tseg2_min = 1, /* Time segment 2 = phase_seg2 */
- .tseg2_max = 8,
- .sjw_max = 4,
- .brp_min = 1,
- .brp_max = 32,
+ .tseg1_min = 1, /* Time segment 1 = prop_seg + phase_seg1 */
+ .tseg1_max = 64,
+ .tseg2_min = 2, /* Time segment 2 = phase_seg2 */
+ .tseg2_max = 64,
+ .sjw_max = 16,
+ .brp_min = 2,
+ .brp_max = 256,
.brp_inc = 1,
};
@@ -545,32 +563,34 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev)
u32 noniso_arg = 0;
u32 time_off;
- if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) {
+ if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) &&
+ !(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) {
+ time_off = IFI_CANFD_TIME_SJW_OFF_ISO;
+ } else {
noniso_arg = IFI_CANFD_TIME_SET_TIMEB_BOSCH |
IFI_CANFD_TIME_SET_TIMEA_BOSCH |
IFI_CANFD_TIME_SET_PRESC_BOSCH |
IFI_CANFD_TIME_SET_SJW_BOSCH;
time_off = IFI_CANFD_TIME_SJW_OFF_BOSCH;
- } else {
- time_off = IFI_CANFD_TIME_SJW_OFF_ISO;
}
/* Configure bit timing */
- brp = bt->brp - 1;
+ brp = bt->brp - 2;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
- tseg2 = bt->phase_seg2 - 1;
+ tseg2 = bt->phase_seg2 - 2;
writel((tseg2 << IFI_CANFD_TIME_TIMEB_OFF) |
(tseg1 << IFI_CANFD_TIME_TIMEA_OFF) |
(brp << IFI_CANFD_TIME_PRESCALE_OFF) |
- (sjw << time_off),
+ (sjw << time_off) |
+ noniso_arg,
priv->base + IFI_CANFD_TIME);
/* Configure data bit timing */
- brp = dbt->brp - 1;
+ brp = dbt->brp - 2;
sjw = dbt->sjw - 1;
tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
- tseg2 = dbt->phase_seg2 - 1;
+ tseg2 = dbt->phase_seg2 - 2;
writel((tseg2 << IFI_CANFD_TIME_TIMEB_OFF) |
(tseg1 << IFI_CANFD_TIME_TIMEA_OFF) |
(brp << IFI_CANFD_TIME_PRESCALE_OFF) |
@@ -747,8 +767,7 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb,
{
struct ifi_canfd_priv *priv = netdev_priv(ndev);
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
- u32 txst, txid;
- u32 txdlc = 0;
+ u32 txst, txid, txdlc;
int i;
if (can_dropped_invalid_skb(ndev, skb))
@@ -766,17 +785,25 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb,
if (cf->can_id & CAN_EFF_FLAG) {
txid = cf->can_id & CAN_EFF_MASK;
+ /*
+ * In case the Extended ID frame is transmitted, the
+ * standard and extended part of the ID are swapped
+ * in the register, so swap them back to send the
+ * correct ID.
+ */
+ txid = (txid >> IFI_CANFD_TXFIFO_ID_ID_XTD_WIDTH) |
+ ((txid & IFI_CANFD_TXFIFO_ID_ID_XTD_MASK) <<
+ IFI_CANFD_TXFIFO_ID_ID_XTD_OFFSET);
txid |= IFI_CANFD_TXFIFO_ID_IDE;
} else {
txid = cf->can_id & CAN_SFF_MASK;
}
- if (priv->can.ctrlmode & (CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO)) {
- if (can_is_canfd_skb(skb)) {
- txdlc |= IFI_CANFD_TXFIFO_DLC_EDL;
- if (cf->flags & CANFD_BRS)
- txdlc |= IFI_CANFD_TXFIFO_DLC_BRS;
- }
+ txdlc = can_len2dlc(cf->len);
+ if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) {
+ txdlc |= IFI_CANFD_TXFIFO_DLC_EDL;
+ if (cf->flags & CANFD_BRS)
+ txdlc |= IFI_CANFD_TXFIFO_DLC_BRS;
}
if (cf->can_id & CAN_RTR_FLAG)
@@ -847,7 +874,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
priv->can.state = CAN_STATE_STOPPED;
- priv->can.clock.freq = readl(addr + IFI_CANFD_SYSCLOCK);
+ priv->can.clock.freq = readl(addr + IFI_CANFD_CANCLOCK);
priv->can.bittiming_const = &ifi_canfd_bittiming_const;
priv->can.data_bittiming_const = &ifi_canfd_data_bittiming_const;
diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c
index ad3d2e0..788459f 100644
--- a/drivers/net/can/rcar_can.c
+++ b/drivers/net/can/rcar_can.c
@@ -906,6 +906,7 @@ static const struct of_device_id rcar_can_of_table[] __maybe_unused = {
{ .compatible = "renesas,can-r8a7791" },
{ .compatible = "renesas,rcar-gen1-can" },
{ .compatible = "renesas,rcar-gen2-can" },
+ { .compatible = "renesas,rcar-gen3-can" },
{ }
};
MODULE_DEVICE_TABLE(of, rcar_can_of_table);