aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-03-18 13:19:14 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2014-04-01 05:55:01 -0400
commit5a7513adab521909e836fa5b9aaabbf22b48859f (patch)
tree438976107899ac0787e5a53964daea7f394868e4 /drivers
parent902470085406934d3f20c4af02de7d79c01b6b93 (diff)
can: c_can: Simplify TX interrupt cleanup
The function loads the message object from the hardware to get the payload length. The previous patch stores that information in an array, so we can avoid the hardware access. Remove the hardware access and move the led toggle outside of the spinlocked region. Toggle the led only once when at least one packet has been received. Binary size shrinks along with the code Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/can/c_can/c_can.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 1e75223d614f..42c038d523c9 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -232,10 +232,9 @@ static inline int get_tx_next_msg_obj(const struct c_can_priv *priv)
232 C_CAN_MSG_OBJ_TX_FIRST; 232 C_CAN_MSG_OBJ_TX_FIRST;
233} 233}
234 234
235static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) 235static inline int get_tx_echo_msg_obj(int txecho)
236{ 236{
237 return (priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) + 237 return (txecho & C_CAN_NEXT_MSG_OBJ_MASK) + C_CAN_MSG_OBJ_TX_FIRST;
238 C_CAN_MSG_OBJ_TX_FIRST;
239} 238}
240 239
241static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) 240static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index)
@@ -729,8 +728,6 @@ static int c_can_get_berr_counter(const struct net_device *dev,
729} 728}
730 729
731/* 730/*
732 * theory of operation:
733 *
734 * priv->tx_echo holds the number of the oldest can_frame put for 731 * priv->tx_echo holds the number of the oldest can_frame put for
735 * transmission into the hardware, but not yet ACKed by the CAN tx 732 * transmission into the hardware, but not yet ACKed by the CAN tx
736 * complete IRQ. 733 * complete IRQ.
@@ -741,29 +738,23 @@ static int c_can_get_berr_counter(const struct net_device *dev,
741 */ 738 */
742static void c_can_do_tx(struct net_device *dev) 739static void c_can_do_tx(struct net_device *dev)
743{ 740{
744 u32 val;
745 u32 msg_obj_no;
746 struct c_can_priv *priv = netdev_priv(dev); 741 struct c_can_priv *priv = netdev_priv(dev);
747 struct net_device_stats *stats = &dev->stats; 742 struct net_device_stats *stats = &dev->stats;
743 u32 val, obj, pkts = 0, bytes = 0;
748 744
749 spin_lock_bh(&priv->xmit_lock); 745 spin_lock_bh(&priv->xmit_lock);
750 746
751 for (; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { 747 for (; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
752 msg_obj_no = get_tx_echo_msg_obj(priv); 748 obj = get_tx_echo_msg_obj(priv->tx_echo);
753 val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); 749 val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG);
754 if (!(val & (1 << (msg_obj_no - 1)))) { 750
755 can_get_echo_skb(dev, 751 if (val & (1 << (obj - 1)))
756 msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
757 c_can_object_get(dev, IF_TX, msg_obj_no, IF_COMM_ALL);
758 stats->tx_bytes += priv->read_reg(priv,
759 C_CAN_IFACE(MSGCTRL_REG, IF_TX))
760 & IF_MCONT_DLC_MASK;
761 stats->tx_packets++;
762 can_led_event(dev, CAN_LED_EVENT_TX);
763 c_can_inval_msg_object(dev, IF_TX, msg_obj_no);
764 } else {
765 break; 752 break;
766 } 753
754 can_get_echo_skb(dev, obj - C_CAN_MSG_OBJ_TX_FIRST);
755 bytes += priv->dlc[obj - C_CAN_MSG_OBJ_TX_FIRST];
756 pkts++;
757 c_can_inval_msg_object(dev, IF_TX, obj);
767 } 758 }
768 759
769 /* restart queue if wrap-up or if queue stalled on last pkt */ 760 /* restart queue if wrap-up or if queue stalled on last pkt */
@@ -772,6 +763,12 @@ static void c_can_do_tx(struct net_device *dev)
772 netif_wake_queue(dev); 763 netif_wake_queue(dev);
773 764
774 spin_unlock_bh(&priv->xmit_lock); 765 spin_unlock_bh(&priv->xmit_lock);
766
767 if (pkts) {
768 stats->tx_bytes += bytes;
769 stats->tx_packets += pkts;
770 can_led_event(dev, CAN_LED_EVENT_TX);
771 }
775} 772}
776 773
777/* 774/*