From aee208a3f787e9944faccfedf3feef91fb6b77ea Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Wed, 30 Jan 2019 12:47:03 +0100 Subject: [PATCH] apalis-tk1: mfd: k20: update supported fw version to 1.4 Signed-off-by: Dominik Sliwa apalis-tk1: can: mfd: k20: use level interrupts and prioritize tx Prioritize CAN TX trafic, and move from edge to level triggered interrupts. Signed-off-by: Dominik Sliwa --- arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi | 4 +-- drivers/mfd/apalis-tk1-k20.c | 3 +- drivers/net/can/apalis-tk1-k20-can.c | 35 +++++++++++---------- include/linux/mfd/apalis-tk1-k20-api.h | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi index 1336e8caf95d..93fce73e385a 100644 --- a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi @@ -1761,8 +1761,8 @@ spi-max-frequency = <6120000>; interrupt-parent =<&gpio>; interrupts = , - , /* INT3 CAN0 */ - ; /* INT4 CAN1 */ + , /* INT3 CAN0 */ + ; /* INT4 CAN1 */ rst-gpio = <&gpio TEGRA_GPIO(BB, 6) GPIO_ACTIVE_HIGH>; /* GPIO based CS used to enter K20 EzPort mode */ diff --git a/drivers/mfd/apalis-tk1-k20.c b/drivers/mfd/apalis-tk1-k20.c index a6d1c1cdc0b6..dfdd3683d527 100644 --- a/drivers/mfd/apalis-tk1-k20.c +++ b/drivers/mfd/apalis-tk1-k20.c @@ -351,8 +351,7 @@ int apalis_tk1_k20_irq_request(struct apalis_tk1_k20_regmap *apalis_tk1_k20, } else { virq = (irq == APALIS_TK1_K20_CAN0_IRQ) ? apalis_tk1_k20->can0_irq:apalis_tk1_k20->can1_irq; - irq_flags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING; + irq_flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH; } return devm_request_threaded_irq(apalis_tk1_k20->dev, virq, NULL, handler, irq_flags, name, dev); diff --git a/drivers/net/can/apalis-tk1-k20-can.c b/drivers/net/can/apalis-tk1-k20-can.c index 0c238b8062ca..d78940e3d262 100644 --- a/drivers/net/can/apalis-tk1-k20-can.c +++ b/drivers/net/can/apalis-tk1-k20-can.c @@ -125,8 +125,6 @@ static void apalis_tk1_k20_can_hw_tx_frame(struct net_device *net, u8 *buf, + APALIS_TK1_K20_CAN_DEV_OFFSET( priv->pdata->id), buf, len); apalis_tk1_k20_unlock(priv->apalis_tk1_k20); - - priv->tx_frame = 1; } static void apalis_tk1_k20_can_hw_tx(struct net_device *net, @@ -142,7 +140,7 @@ static void apalis_tk1_k20_can_hw_tx(struct net_device *net, + CAN_HEADER_MAX_LEN, tx_buf_idx); } -static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) +static int apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) { int i = 0; struct apalis_tk1_k20_priv *priv = netdev_priv(net); @@ -169,7 +167,7 @@ static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) if (!skb) { dev_err(&net->dev, "cannot allocate RX skb\n"); priv->net->stats.rx_dropped++; - return; + return -ENOMEM; } memcpy(&frame->can_id, &buf[i * CAN_TRANSFER_BUF_LEN] + MB_EID_OFF, MB_EID_LEN); @@ -187,6 +185,7 @@ static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) netif_rx_ni(skb); } + return frame_available; } @@ -436,6 +435,7 @@ static void apalis_tk1_k20_can_tx_work_handler(struct work_struct *ws) priv->tx_len = 1 + frame->can_dlc; can_put_echo_skb(priv->tx_skb, net, 0); priv->tx_skb = NULL; + priv->tx_frame = 1; } } mutex_unlock(&priv->apalis_tk1_k20_can_lock); @@ -546,7 +546,7 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) mutex_lock(&priv->apalis_tk1_k20_can_lock); while (!priv->force_quit) { enum can_state new_state = CAN_STATE_ERROR_ACTIVE; - int ret; + int ret, rx_cnt = 0; u32 intf, eflag; u8 clear_intf = 0; int can_id = 0, data1 = 0; @@ -566,31 +566,31 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) intf &= CANCTRL_INTMASK; - if (!(intf & CANINTF_TX) && + if (intf == 0) + break; + + /* TX complete */ + if ((intf & CANINTF_TX) && (priv->tx_frame == 1)) { priv->tx_frame = 0; net->stats.tx_packets++; - net->stats.tx_bytes += priv->tx_len - 1; - can_led_event(net, CAN_LED_EVENT_TX); if (priv->tx_len) { + net->stats.tx_bytes += priv->tx_len - 1; + can_led_event(net, CAN_LED_EVENT_TX); can_get_echo_skb(net, 0); priv->tx_len = 0; } netif_wake_queue(net); - if (!(intf & (CANINTF_RX | CANINTF_ERR))) - break; + clear_intf |= CANINTF_TX; } - - if (intf == 0) - break; - /* receive */ if (intf & CANINTF_RX) - apalis_tk1_k20_can_hw_rx(net, 0); + rx_cnt = apalis_tk1_k20_can_hw_rx(net, 0); /* any error interrupt we need to clear? */ if (intf & CANINTF_ERR) - clear_intf |= intf & CANINTF_ERR; + clear_intf |= CANINTF_ERR; + apalis_tk1_k20_lock(priv->apalis_tk1_k20); if (clear_intf) ret = apalis_tk1_k20_reg_write(priv->apalis_tk1_k20, @@ -677,6 +677,9 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) break; } + if (priv->tx_skb != NULL) { + break; + } } mutex_unlock(&priv->apalis_tk1_k20_can_lock); diff --git a/include/linux/mfd/apalis-tk1-k20-api.h b/include/linux/mfd/apalis-tk1-k20-api.h index 75c7821ec43f..333d20f7852b 100644 --- a/include/linux/mfd/apalis-tk1-k20-api.h +++ b/include/linux/mfd/apalis-tk1-k20-api.h @@ -104,7 +104,7 @@ #define APALIS_TK1_K20_TSC_IRQ 4 #define APALIS_TK1_K20_GPIO_IRQ 5 -#define APALIS_TK1_K20_FW_VER 0x13 +#define APALIS_TK1_K20_FW_VER 0x14 #define APALIS_TK1_K20_TESTER_FW_VER 0xFE #define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F) -- 2.20.1