From 44d856665789288859b7aa47ca25933c1c6ab57d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 30 Jan 2011 22:14:49 +0100 Subject: can: at91_can: don't align struct definitions Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 74efb5a2ad41..8f15ae4c719f 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -157,21 +157,21 @@ enum at91_mb_mode { #define AT91_IRQ_ALL (0x1fffffff) struct at91_priv { - struct can_priv can; /* must be the first member! */ - struct net_device *dev; - struct napi_struct napi; + struct can_priv can; /* must be the first member! */ + struct net_device *dev; + struct napi_struct napi; - void __iomem *reg_base; + void __iomem *reg_base; - u32 reg_sr; - unsigned int tx_next; - unsigned int tx_echo; - unsigned int rx_next; + u32 reg_sr; + unsigned int tx_next; + unsigned int tx_echo; + unsigned int rx_next; - struct clk *clk; - struct at91_can_data *pdata; + struct clk *clk; + struct at91_can_data *pdata; - canid_t mb0_id; + canid_t mb0_id; }; static struct can_bittiming_const at91_bittiming_const = { @@ -271,7 +271,7 @@ static void at91_setup_mailboxes(struct net_device *dev) /* reset acceptance mask and id register */ for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) { - at91_write(priv, AT91_MAM(i), 0x0 ); + at91_write(priv, AT91_MAM(i), 0x0); at91_write(priv, AT91_MID(i), AT91_MID_MIDE); } @@ -1231,11 +1231,11 @@ static int __devexit at91_can_remove(struct platform_device *pdev) } static struct platform_driver at91_can_driver = { - .probe = at91_can_probe, - .remove = __devexit_p(at91_can_remove), - .driver = { - .name = KBUILD_MODNAME, - .owner = THIS_MODULE, + .probe = at91_can_probe, + .remove = __devexit_p(at91_can_remove), + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, }, }; -- cgit v1.2.3 From 5613fff2dc315e5f44623031cb62a29942548427 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 16 Apr 2011 13:25:15 +0200 Subject: can: at91_can: fix comment about priv->tx_next Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 8f15ae4c719f..afd0f5d394b0 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -375,7 +375,7 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state) * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits * encode the mailbox number, the upper 4 bits the mailbox priority: * - * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) || + * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) | * (mb - AT91_MB_TX_FIRST); * */ -- cgit v1.2.3 From e14ee40bece891b5edccdd514112999ec423a448 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 21 Oct 2010 18:39:26 +0200 Subject: can: at91_can: don't copy data to rx'ed RTR frames Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/at91_can.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index afd0f5d394b0..5358d7059211 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -513,12 +513,14 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK; reg_msr = at91_read(priv, AT91_MSR(mb)); - if (reg_msr & AT91_MSR_MRTR) - cf->can_id |= CAN_RTR_FLAG; cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf); - *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb)); - *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb)); + if (reg_msr & AT91_MSR_MRTR) + cf->can_id |= CAN_RTR_FLAG; + else { + *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb)); + *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb)); + } /* allow RX of extended frames */ at91_write(priv, AT91_MID(mb), AT91_MID_MIDE); -- cgit v1.2.3 From 9c2e0a6d2f7b7c76e0cbc42a8da99fd732f0fdfa Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 17:47:55 +0200 Subject: can: at91_can: let get_tx_* functions return unsigned int Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 5358d7059211..716f22bf3d2f 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -186,17 +186,17 @@ static struct can_bittiming_const at91_bittiming_const = { .brp_inc = 1, }; -static inline int get_tx_next_mb(const struct at91_priv *priv) +static inline unsigned int get_tx_next_mb(const struct at91_priv *priv) { return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; } -static inline int get_tx_next_prio(const struct at91_priv *priv) +static inline unsigned int get_tx_next_prio(const struct at91_priv *priv) { return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf; } -static inline int get_tx_echo_mb(const struct at91_priv *priv) +static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv) { return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; } -- cgit v1.2.3 From 267cbe047cb4f6a3a6337029fc60862be1cf437d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 30 Apr 2011 20:46:12 +0200 Subject: can: at91_can: directly define AT91_MB_RX_LAST ...instead of deriving it from AT91_MB_RX_FIRST and AT91_MB_RX_NUM. This removes a level of computation, when switching the driver from compile time constants to runtime values. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 716f22bf3d2f..9ce00fa90d96 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -47,11 +47,10 @@ * RX/TX Mailbox split * don't dare to touch */ -#define AT91_MB_RX_NUM 11 #define AT91_MB_TX_SHIFT 2 #define AT91_MB_RX_FIRST 1 -#define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) +#define AT91_MB_RX_LAST 11 #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) #define AT91_MB_RX_SPLIT 8 -- cgit v1.2.3 From b049994d0f3a19c1706627117a7269ce5bd335ab Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 16:37:16 +0200 Subject: can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX ... and use it for AT91_NEXT_MB_MASK, AT91_IRQ_MB_RX and AT91_IRQ_MB_RX, too. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 9ce00fa90d96..86994845a1d4 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -52,11 +52,11 @@ #define AT91_MB_RX_FIRST 1 #define AT91_MB_RX_LAST 11 -#define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) +#define AT91_MB_MASK(i) ((1 << (i)) - 1) #define AT91_MB_RX_SPLIT 8 #define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) -#define AT91_MB_RX_LOW_MASK (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \ - ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST)) +#define AT91_MB_RX_LOW_MASK (AT91_MB_MASK(AT91_MB_RX_SPLIT) & \ + ~AT91_MB_MASK(AT91_MB_RX_FIRST)) #define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) #define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) @@ -64,7 +64,7 @@ #define AT91_NEXT_PRIO_SHIFT (AT91_MB_TX_SHIFT) #define AT91_NEXT_PRIO_MASK (0xf << AT91_MB_TX_SHIFT) -#define AT91_NEXT_MB_MASK (AT91_MB_TX_NUM - 1) +#define AT91_NEXT_MB_MASK (AT91_MB_MASK(AT91_MB_TX_SHIFT)) #define AT91_NEXT_MASK ((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK) /* Common registers */ @@ -127,10 +127,10 @@ enum at91_mb_mode { }; /* Interrupt mask bits */ -#define AT91_IRQ_MB_RX ((1 << (AT91_MB_RX_LAST + 1)) \ - - (1 << AT91_MB_RX_FIRST)) -#define AT91_IRQ_MB_TX ((1 << (AT91_MB_TX_LAST + 1)) \ - - (1 << AT91_MB_TX_FIRST)) +#define AT91_IRQ_MB_RX (AT91_MB_MASK(AT91_MB_RX_LAST + 1) & \ + ~AT91_MB_MASK(AT91_MB_RX_FIRST)) +#define AT91_IRQ_MB_TX (AT91_MB_MASK(AT91_MB_TX_LAST + 1) & \ + ~AT91_MB_MASK(AT91_MB_TX_FIRST)) #define AT91_IRQ_MB_ALL (AT91_IRQ_MB_RX | AT91_IRQ_MB_TX) #define AT91_IRQ_ERRA (1 << 16) @@ -735,7 +735,7 @@ static int at91_poll(struct napi_struct *napi, int quota) if (work_done < quota) { /* enable IRQs for frame errors and all mailboxes >= rx_next */ u32 reg_ier = AT91_IRQ_ERR_FRAME; - reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_RX_MASK(priv->rx_next); + reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_MASK(priv->rx_next); napi_complete(napi); at91_write(priv, AT91_IER, reg_ier); -- cgit v1.2.3 From 79008997e232ad1d871bb6fedfb7fbd77ea95af8 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 17:31:40 +0200 Subject: can: at91_can: convert derived mailbox constants into functions This is the first of two patches converting the at91_can driver from a compile time mailbox setup to a dynamic one. This patch converts all derived mailbox constants to functions. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 125 ++++++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 42 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 86994845a1d4..900ff67ed7f3 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -54,18 +54,7 @@ #define AT91_MB_MASK(i) ((1 << (i)) - 1) #define AT91_MB_RX_SPLIT 8 -#define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) -#define AT91_MB_RX_LOW_MASK (AT91_MB_MASK(AT91_MB_RX_SPLIT) & \ - ~AT91_MB_MASK(AT91_MB_RX_FIRST)) -#define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) -#define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) -#define AT91_MB_TX_LAST (AT91_MB_TX_FIRST + AT91_MB_TX_NUM - 1) - -#define AT91_NEXT_PRIO_SHIFT (AT91_MB_TX_SHIFT) -#define AT91_NEXT_PRIO_MASK (0xf << AT91_MB_TX_SHIFT) -#define AT91_NEXT_MB_MASK (AT91_MB_MASK(AT91_MB_TX_SHIFT)) -#define AT91_NEXT_MASK ((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK) /* Common registers */ enum at91_reg { @@ -127,12 +116,6 @@ enum at91_mb_mode { }; /* Interrupt mask bits */ -#define AT91_IRQ_MB_RX (AT91_MB_MASK(AT91_MB_RX_LAST + 1) & \ - ~AT91_MB_MASK(AT91_MB_RX_FIRST)) -#define AT91_IRQ_MB_TX (AT91_MB_MASK(AT91_MB_TX_LAST + 1) & \ - ~AT91_MB_MASK(AT91_MB_TX_FIRST)) -#define AT91_IRQ_MB_ALL (AT91_IRQ_MB_RX | AT91_IRQ_MB_TX) - #define AT91_IRQ_ERRA (1 << 16) #define AT91_IRQ_WARN (1 << 17) #define AT91_IRQ_ERRP (1 << 18) @@ -185,19 +168,77 @@ static struct can_bittiming_const at91_bittiming_const = { .brp_inc = 1, }; +static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv) +{ + return AT91_MB_RX_SPLIT - 1; +} + +static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv) +{ + return AT91_MB_MASK(AT91_MB_RX_SPLIT) & + ~AT91_MB_MASK(AT91_MB_RX_FIRST); +} + +static inline unsigned int get_mb_tx_num(const struct at91_priv *priv) +{ + return 1 << AT91_MB_TX_SHIFT; +} + +static inline unsigned int get_mb_tx_first(const struct at91_priv *priv) +{ + return AT91_MB_RX_LAST + 1; +} + +static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) +{ + return get_mb_tx_first(priv) + get_mb_tx_num(priv) - 1; +} + +static inline unsigned int get_next_prio_shift(const struct at91_priv *priv) +{ + return AT91_MB_TX_SHIFT; +} + +static inline unsigned int get_next_prio_mask(const struct at91_priv *priv) +{ + return 0xf << AT91_MB_TX_SHIFT; +} + +static inline unsigned int get_next_mb_mask(const struct at91_priv *priv) +{ + return AT91_MB_MASK(AT91_MB_TX_SHIFT); +} + +static inline unsigned int get_next_mask(const struct at91_priv *priv) +{ + return get_next_mb_mask(priv) | get_next_prio_mask(priv); +} + +static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv) +{ + return AT91_MB_MASK(AT91_MB_RX_LAST + 1) & + ~AT91_MB_MASK(AT91_MB_RX_FIRST); +} + +static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv) +{ + return AT91_MB_MASK(get_mb_tx_last(priv) + 1) & + ~AT91_MB_MASK(get_mb_tx_first(priv)); +} + static inline unsigned int get_tx_next_mb(const struct at91_priv *priv) { - return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; + return (priv->tx_next & get_next_mb_mask(priv)) + get_mb_tx_first(priv); } static inline unsigned int get_tx_next_prio(const struct at91_priv *priv) { - return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf; + return (priv->tx_next >> get_next_prio_shift(priv)) & 0xf; } static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv) { - return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; + return (priv->tx_echo & get_next_mb_mask(priv)) + get_mb_tx_first(priv); } static inline u32 at91_read(const struct at91_priv *priv, enum at91_reg reg) @@ -275,7 +316,7 @@ static void at91_setup_mailboxes(struct net_device *dev) } /* The last 4 mailboxes are used for transmitting. */ - for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++) + for (i = get_mb_tx_first(priv); i <= get_mb_tx_last(priv); i++) set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); /* Reset tx and rx helper pointers */ @@ -335,7 +376,7 @@ static void at91_chip_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; /* Enable interrupts */ - reg_ier = AT91_IRQ_MB_RX | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME; + reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME; at91_write(priv, AT91_IDR, AT91_IRQ_ALL); at91_write(priv, AT91_IER, reg_ier); } @@ -416,7 +457,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) stats->tx_bytes += cf->can_dlc; /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ - can_put_echo_skb(skb, dev, mb - AT91_MB_TX_FIRST); + can_put_echo_skb(skb, dev, mb - get_mb_tx_first(priv)); /* * we have to stop the queue and deliver all messages in case @@ -429,7 +470,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) priv->tx_next++; if (!(at91_read(priv, AT91_MSR(get_tx_next_mb(priv))) & AT91_MSR_MRDY) || - (priv->tx_next & AT91_NEXT_MASK) == 0) + (priv->tx_next & get_next_mask(priv)) == 0) netif_stop_queue(dev); /* Enable interrupt for this mailbox */ @@ -446,7 +487,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static inline void at91_activate_rx_low(const struct at91_priv *priv) { - u32 mask = AT91_MB_RX_LOW_MASK; + u32 mask = get_mb_rx_low_mask(priv); at91_write(priv, AT91_TCR, mask); } @@ -611,23 +652,23 @@ static int at91_poll_rx(struct net_device *dev, int quota) unsigned int mb; int received = 0; - if (priv->rx_next > AT91_MB_RX_LOW_LAST && - reg_sr & AT91_MB_RX_LOW_MASK) + if (priv->rx_next > get_mb_rx_low_last(priv) && + reg_sr & get_mb_rx_low_mask(priv)) netdev_info(dev, "order of incoming frames cannot be guaranteed\n"); again: - for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next); - mb < AT91_MB_RX_LAST + 1 && quota > 0; + for (mb = find_next_bit(addr, get_mb_tx_first(priv), priv->rx_next); + mb < get_mb_tx_first(priv) && quota > 0; reg_sr = at91_read(priv, AT91_SR), - mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) { + mb = find_next_bit(addr, get_mb_tx_first(priv), ++priv->rx_next)) { at91_read_msg(dev, mb); /* reactivate mailboxes */ - if (mb == AT91_MB_RX_LOW_LAST) + if (mb == get_mb_rx_low_last(priv)) /* all lower mailboxed, if just finished it */ at91_activate_rx_low(priv); - else if (mb > AT91_MB_RX_LOW_LAST) + else if (mb > get_mb_rx_low_last(priv)) /* only the mailbox we read */ at91_activate_rx_mb(priv, mb); @@ -636,7 +677,7 @@ static int at91_poll_rx(struct net_device *dev, int quota) } /* upper group completed, look again in lower */ - if (priv->rx_next > AT91_MB_RX_LOW_LAST && + if (priv->rx_next > get_mb_rx_low_last(priv) && quota > 0 && mb > AT91_MB_RX_LAST) { priv->rx_next = AT91_MB_RX_FIRST; goto again; @@ -721,7 +762,7 @@ static int at91_poll(struct napi_struct *napi, int quota) u32 reg_sr = at91_read(priv, AT91_SR); int work_done = 0; - if (reg_sr & AT91_IRQ_MB_RX) + if (reg_sr & get_irq_mb_rx(priv)) work_done += at91_poll_rx(dev, quota - work_done); /* @@ -735,7 +776,7 @@ static int at91_poll(struct napi_struct *napi, int quota) if (work_done < quota) { /* enable IRQs for frame errors and all mailboxes >= rx_next */ u32 reg_ier = AT91_IRQ_ERR_FRAME; - reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_MASK(priv->rx_next); + reg_ier |= get_irq_mb_rx(priv) & ~AT91_MB_MASK(priv->rx_next); napi_complete(napi); at91_write(priv, AT91_IER, reg_ier); @@ -784,7 +825,7 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr) if (likely(reg_msr & AT91_MSR_MRDY && ~reg_msr & AT91_MSR_MABT)) { /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ - can_get_echo_skb(dev, mb - AT91_MB_TX_FIRST); + can_get_echo_skb(dev, mb - get_mb_tx_first(priv)); dev->stats.tx_packets++; } } @@ -794,8 +835,8 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr) * we get a TX int for the last can frame directly before a * wrap around. */ - if ((priv->tx_next & AT91_NEXT_MASK) != 0 || - (priv->tx_echo & AT91_NEXT_MASK) == 0) + if ((priv->tx_next & get_next_mask(priv)) != 0 || + (priv->tx_echo & get_next_mask(priv)) == 0) netif_wake_queue(dev); } @@ -969,19 +1010,19 @@ static irqreturn_t at91_irq(int irq, void *dev_id) handled = IRQ_HANDLED; /* Receive or error interrupt? -> napi */ - if (reg_sr & (AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME)) { + if (reg_sr & (get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME)) { /* * The error bits are clear on read, * save for later use. */ priv->reg_sr = reg_sr; at91_write(priv, AT91_IDR, - AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME); + get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME); napi_schedule(&priv->napi); } /* Transmission complete interrupt */ - if (reg_sr & AT91_IRQ_MB_TX) + if (reg_sr & get_irq_mb_tx(priv)) at91_irq_tx(dev, reg_sr); at91_irq_err(dev); @@ -1158,7 +1199,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev) goto exit_release; } - dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM); + dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT); if (!dev) { err = -ENOMEM; goto exit_iounmap; -- cgit v1.2.3 From d3d47264a364aa3adcbb485471dbf9f693fb4216 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 17:41:09 +0200 Subject: can: at91_can: add id_table and convert prime mailbox constats to functions This is the second of two patches converting the at91_can driver from a compile time mailbox setup to a dynamic one. This patch first adds a id_table to the platform driver. Depending on the driver_data the constants for the mailbox setup is selected. Then all remaining prime mailbox constants are converted to functions, using the run time selected mailbox constants. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 137 ++++++++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 38 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 900ff67ed7f3..248e03fec034 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -41,20 +41,7 @@ #include -#define AT91_NAPI_WEIGHT 11 - -/* - * RX/TX Mailbox split - * don't dare to touch - */ -#define AT91_MB_TX_SHIFT 2 - -#define AT91_MB_RX_FIRST 1 -#define AT91_MB_RX_LAST 11 - #define AT91_MB_MASK(i) ((1 << (i)) - 1) -#define AT91_MB_RX_SPLIT 8 - /* Common registers */ enum at91_reg { @@ -138,6 +125,18 @@ enum at91_mb_mode { #define AT91_IRQ_ALL (0x1fffffff) +enum at91_devtype { + AT91_DEVTYPE_SAM9263, +}; + +struct at91_devtype_data { + unsigned int rx_first; + unsigned int rx_split; + unsigned int rx_last; + unsigned int tx_shift; + enum at91_devtype type; +}; + struct at91_priv { struct can_priv can; /* must be the first member! */ struct net_device *dev; @@ -149,6 +148,7 @@ struct at91_priv { unsigned int tx_next; unsigned int tx_echo; unsigned int rx_next; + struct at91_devtype_data devtype_data; struct clk *clk; struct at91_can_data *pdata; @@ -156,6 +156,15 @@ struct at91_priv { canid_t mb0_id; }; +static const struct at91_devtype_data at91_devtype_data[] __devinitconst = { + [AT91_DEVTYPE_SAM9263] = { + .rx_first = 1, + .rx_split = 8, + .rx_last = 11, + .tx_shift = 2, + }, +}; + static struct can_bittiming_const at91_bittiming_const = { .name = KBUILD_MODNAME, .tseg1_min = 4, @@ -168,25 +177,58 @@ static struct can_bittiming_const at91_bittiming_const = { .brp_inc = 1, }; +#define AT91_IS(_model) \ +static inline int at91_is_sam##_model(const struct at91_priv *priv) \ +{ \ + return priv->devtype_data.type == AT91_DEVTYPE_SAM##_model; \ +} + +AT91_IS(9263); + +static inline unsigned int get_mb_rx_first(const struct at91_priv *priv) +{ + return priv->devtype_data.rx_first; +} + +static inline unsigned int get_mb_rx_last(const struct at91_priv *priv) +{ + return priv->devtype_data.rx_last; +} + +static inline unsigned int get_mb_rx_split(const struct at91_priv *priv) +{ + return priv->devtype_data.rx_split; +} + +static inline unsigned int get_mb_rx_num(const struct at91_priv *priv) +{ + return get_mb_rx_last(priv) - get_mb_rx_first(priv) + 1; +} + static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv) { - return AT91_MB_RX_SPLIT - 1; + return get_mb_rx_split(priv) - 1; } static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv) { - return AT91_MB_MASK(AT91_MB_RX_SPLIT) & - ~AT91_MB_MASK(AT91_MB_RX_FIRST); + return AT91_MB_MASK(get_mb_rx_split(priv)) & + ~AT91_MB_MASK(get_mb_rx_first(priv)); +} + +static inline unsigned int get_mb_tx_shift(const struct at91_priv *priv) +{ + return priv->devtype_data.tx_shift; } static inline unsigned int get_mb_tx_num(const struct at91_priv *priv) { - return 1 << AT91_MB_TX_SHIFT; + return 1 << get_mb_tx_shift(priv); } static inline unsigned int get_mb_tx_first(const struct at91_priv *priv) { - return AT91_MB_RX_LAST + 1; + return get_mb_rx_last(priv) + 1; } static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) @@ -196,17 +238,17 @@ static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) static inline unsigned int get_next_prio_shift(const struct at91_priv *priv) { - return AT91_MB_TX_SHIFT; + return get_mb_tx_shift(priv); } static inline unsigned int get_next_prio_mask(const struct at91_priv *priv) { - return 0xf << AT91_MB_TX_SHIFT; + return 0xf << get_mb_tx_shift(priv); } static inline unsigned int get_next_mb_mask(const struct at91_priv *priv) { - return AT91_MB_MASK(AT91_MB_TX_SHIFT); + return AT91_MB_MASK(get_mb_tx_shift(priv)); } static inline unsigned int get_next_mask(const struct at91_priv *priv) @@ -216,8 +258,8 @@ static inline unsigned int get_next_mask(const struct at91_priv *priv) static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv) { - return AT91_MB_MASK(AT91_MB_RX_LAST + 1) & - ~AT91_MB_MASK(AT91_MB_RX_FIRST); + return AT91_MB_MASK(get_mb_rx_last(priv) + 1) & + ~AT91_MB_MASK(get_mb_rx_first(priv)); } static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv) @@ -299,18 +341,18 @@ static void at91_setup_mailboxes(struct net_device *dev) * overflow. */ reg_mid = at91_can_id_to_reg_mid(priv->mb0_id); - for (i = 0; i < AT91_MB_RX_FIRST; i++) { + for (i = 0; i < get_mb_rx_first(priv); i++) { set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); at91_write(priv, AT91_MID(i), reg_mid); at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */ } - for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) + for (i = get_mb_rx_first(priv); i < get_mb_rx_last(priv); i++) set_mb_mode(priv, i, AT91_MB_MODE_RX); - set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); + set_mb_mode(priv, get_mb_rx_last(priv), AT91_MB_MODE_RX_OVRWR); /* reset acceptance mask and id register */ - for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) { + for (i = get_mb_rx_first(priv); i <= get_mb_rx_last(priv); i++) { at91_write(priv, AT91_MAM(i), 0x0); at91_write(priv, AT91_MID(i), AT91_MID_MIDE); } @@ -321,7 +363,7 @@ static void at91_setup_mailboxes(struct net_device *dev) /* Reset tx and rx helper pointers */ priv->tx_next = priv->tx_echo = 0; - priv->rx_next = AT91_MB_RX_FIRST; + priv->rx_next = get_mb_rx_first(priv); } static int at91_set_bittiming(struct net_device *dev) @@ -415,8 +457,8 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state) * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits * encode the mailbox number, the upper 4 bits the mailbox priority: * - * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) | - * (mb - AT91_MB_TX_FIRST); + * priv->tx_next = (prio << get_next_prio_shift(priv)) | + * (mb - get_mb_tx_first(priv)); * */ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) @@ -565,7 +607,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, /* allow RX of extended frames */ at91_write(priv, AT91_MID(mb), AT91_MID_MIDE); - if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI)) + if (unlikely(mb == get_mb_rx_last(priv) && reg_msr & AT91_MSR_MMI)) at91_rx_overflow_err(dev); } @@ -603,8 +645,9 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) * * Theory of Operation: * - * 11 of the 16 mailboxes on the chip are reserved for RX. we split - * them into 2 groups. The lower group holds 7 and upper 4 mailboxes. + * About 3/4 of the mailboxes (get_mb_rx_first()...get_mb_rx_last()) + * on the chip are reserved for RX. We split them into 2 groups. The + * lower group ranges from get_mb_rx_first() to get_mb_rx_low_last(). * * Like it or not, but the chip always saves a received CAN message * into the first free mailbox it finds (starting with the @@ -678,8 +721,8 @@ static int at91_poll_rx(struct net_device *dev, int quota) /* upper group completed, look again in lower */ if (priv->rx_next > get_mb_rx_low_last(priv) && - quota > 0 && mb > AT91_MB_RX_LAST) { - priv->rx_next = AT91_MB_RX_FIRST; + quota > 0 && mb > get_mb_rx_last(priv)) { + priv->rx_next = get_mb_rx_first(priv); goto again; } @@ -1165,6 +1208,8 @@ static struct attribute_group at91_sysfs_attr_group = { static int __devinit at91_can_probe(struct platform_device *pdev) { + const struct at91_devtype_data *devtype_data; + enum at91_devtype devtype; struct net_device *dev; struct at91_priv *priv; struct resource *res; @@ -1172,6 +1217,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev) void __iomem *addr; int err, irq; + devtype = pdev->id_entry->driver_data; + devtype_data = &at91_devtype_data[devtype]; + clk = clk_get(&pdev->dev, "can_clk"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "no clock defined\n"); @@ -1199,7 +1247,8 @@ static int __devinit at91_can_probe(struct platform_device *pdev) goto exit_release; } - dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT); + dev = alloc_candev(sizeof(struct at91_priv), + 1 << devtype_data->tx_shift); if (!dev) { err = -ENOMEM; goto exit_iounmap; @@ -1216,13 +1265,15 @@ static int __devinit at91_can_probe(struct platform_device *pdev) priv->can.do_set_mode = at91_set_mode; priv->can.do_get_berr_counter = at91_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; - priv->reg_base = addr; priv->dev = dev; + priv->reg_base = addr; + priv->devtype_data = *devtype_data; + priv->devtype_data.type = devtype; priv->clk = clk; priv->pdata = pdev->dev.platform_data; priv->mb0_id = 0x7ff; - netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); + netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv)); dev_set_drvdata(&pdev->dev, dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -1272,6 +1323,15 @@ static int __devexit at91_can_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id at91_can_id_table[] = { + { + .name = "at91_can", + .driver_data = AT91_DEVTYPE_SAM9263, + }, { + /* sentinel */ + } +}; + static struct platform_driver at91_can_driver = { .probe = at91_can_probe, .remove = __devexit_p(at91_can_remove), @@ -1279,6 +1339,7 @@ static struct platform_driver at91_can_driver = { .name = KBUILD_MODNAME, .owner = THIS_MODULE, }, + .id_table = at91_can_id_table, }; static int __init at91_can_module_init(void) -- cgit v1.2.3 From 07a648e668aa7f7c94d41d8d2e4ad53b609e391d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 1 Jun 2011 00:20:17 +0200 Subject: can: at91_can: register mb0 sysfs entry only on at91sam9263 This patch prepares the driver for the at91sam9X5 processors, which don't have the mb0 bug. (See commit 3a5655a5b545e9647c3437473ee3d815fe1b9050 for more details.) Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 248e03fec034..2b972812b2d1 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1257,7 +1257,6 @@ static int __devinit at91_can_probe(struct platform_device *pdev) dev->netdev_ops = &at91_netdev_ops; dev->irq = irq; dev->flags |= IFF_ECHO; - dev->sysfs_groups[0] = &at91_sysfs_attr_group; priv = netdev_priv(dev); priv->can.clock.freq = clk_get_rate(clk); @@ -1275,6 +1274,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev) netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv)); + if (at91_is_sam9263(priv)) + dev->sysfs_groups[0] = &at91_sysfs_attr_group; + dev_set_drvdata(&pdev->dev, dev); SET_NETDEV_DEV(dev, &pdev->dev); -- cgit v1.2.3 From 6388b39614208d63661607f45157e3326548eb62 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 17 Apr 2011 00:08:45 +0200 Subject: can: at91_can: add support for the AT91SAM9X5 SOCs The AT91SAM9X5 SOCs have a similar CAN core, but they only have 8 compared to 16 mailboxes on the AT91SAM9263 SOC. Another difference is that the bits defining the state of the CAN core are cleared on read, thus the driver has to derive the state by looking at the error counters. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 69 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 2b972812b2d1..121ede663e20 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -127,6 +127,7 @@ enum at91_mb_mode { enum at91_devtype { AT91_DEVTYPE_SAM9263, + AT91_DEVTYPE_SAM9X5, }; struct at91_devtype_data { @@ -163,6 +164,12 @@ static const struct at91_devtype_data at91_devtype_data[] __devinitconst = { .rx_last = 11, .tx_shift = 2, }, + [AT91_DEVTYPE_SAM9X5] = { + .rx_first = 0, + .rx_split = 4, + .rx_last = 5, + .tx_shift = 1, + }, }; static struct can_bittiming_const at91_bittiming_const = { @@ -184,6 +191,7 @@ static inline int at91_is_sam##_model(const struct at91_priv *priv) \ } AT91_IS(9263); +AT91_IS(9X5); static inline unsigned int get_mb_rx_first(const struct at91_priv *priv) { @@ -991,6 +999,29 @@ static void at91_irq_err_state(struct net_device *dev, at91_write(priv, AT91_IER, reg_ier); } +static int at91_get_state_by_bec(const struct net_device *dev, + enum can_state *state) +{ + struct can_berr_counter bec; + int err; + + err = at91_get_berr_counter(dev, &bec); + if (err) + return err; + + if (bec.txerr < 96 && bec.rxerr < 96) + *state = CAN_STATE_ERROR_ACTIVE; + else if (bec.txerr < 128 && bec.rxerr < 128) + *state = CAN_STATE_ERROR_WARNING; + else if (bec.txerr < 256 && bec.rxerr < 256) + *state = CAN_STATE_ERROR_PASSIVE; + else + *state = CAN_STATE_BUS_OFF; + + return 0; +} + + static void at91_irq_err(struct net_device *dev) { struct at91_priv *priv = netdev_priv(dev); @@ -998,21 +1029,28 @@ static void at91_irq_err(struct net_device *dev) struct can_frame *cf; enum can_state new_state; u32 reg_sr; + int err; - reg_sr = at91_read(priv, AT91_SR); - - /* we need to look at the unmasked reg_sr */ - if (unlikely(reg_sr & AT91_IRQ_BOFF)) - new_state = CAN_STATE_BUS_OFF; - else if (unlikely(reg_sr & AT91_IRQ_ERRP)) - new_state = CAN_STATE_ERROR_PASSIVE; - else if (unlikely(reg_sr & AT91_IRQ_WARN)) - new_state = CAN_STATE_ERROR_WARNING; - else if (likely(reg_sr & AT91_IRQ_ERRA)) - new_state = CAN_STATE_ERROR_ACTIVE; - else { - netdev_err(dev, "BUG! hardware in undefined state\n"); - return; + if (at91_is_sam9263(priv)) { + reg_sr = at91_read(priv, AT91_SR); + + /* we need to look at the unmasked reg_sr */ + if (unlikely(reg_sr & AT91_IRQ_BOFF)) + new_state = CAN_STATE_BUS_OFF; + else if (unlikely(reg_sr & AT91_IRQ_ERRP)) + new_state = CAN_STATE_ERROR_PASSIVE; + else if (unlikely(reg_sr & AT91_IRQ_WARN)) + new_state = CAN_STATE_ERROR_WARNING; + else if (likely(reg_sr & AT91_IRQ_ERRA)) + new_state = CAN_STATE_ERROR_ACTIVE; + else { + netdev_err(dev, "BUG! hardware in undefined state\n"); + return; + } + } else { + err = at91_get_state_by_bec(dev, &new_state); + if (err) + return; } /* state hasn't changed */ @@ -1329,6 +1367,9 @@ static const struct platform_device_id at91_can_id_table[] = { { .name = "at91_can", .driver_data = AT91_DEVTYPE_SAM9263, + }, { + .name = "at91sam9x5_can", + .driver_data = AT91_DEVTYPE_SAM9X5, }, { /* sentinel */ } -- cgit v1.2.3 From b9e379bccda6913f7baece42cd249824c0758b97 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 26 Apr 2011 15:05:59 +0200 Subject: net/can: allow CAN_AT91 on AT91SAM9X5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 1d699e3df547..bbf06f77ee8c 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -58,9 +58,10 @@ config CAN_CALC_BITTIMING config CAN_AT91 tristate "Atmel AT91 onchip CAN controller" - depends on CAN_DEV && ARCH_AT91SAM9263 + depends on CAN_DEV && (ARCH_AT91SAM9263 || ARCH_AT91SAM9X5) ---help--- - This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. + This is a driver for the SoC CAN controller in Atmel's AT91SAM9263 + and AT91SAM9X5 processors. config CAN_TI_HECC depends on CAN_DEV && ARCH_OMAP3 -- cgit v1.2.3