* [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series
@ 2011-06-06 13:42 Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 05/11] can: at91_can: directly define AT91_MB_RX_LAST Marc Kleine-Budde
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA
Hello,
this patch series add support for the at91_can core on the upcoming
at91sam9x5 SOC series.
The original at91_can driver supports the at91sam9263 which has 16
mailboxes, but the CAN core on the at91sam9x5 has only 8. Most constants
used in the RX and TX path are derived from the number of mailboxes.
This patch series changes the driver from a static, compile time setup
of the mailboxes to a dynamic one. Patches 1-4 clean up the driver, 5+6
simplify the usage of the constants, patch 7 converts all derived constants
into functions. Patch 8 will add id_table support to the driver then all
remaining constants are converted into functions using the run time
selected mailbox constants. The next patch (9) takes care about an
at91sam9263 specific errata fix. Patch 10 and 11 will finally add supoprt
for the at91sam9x5 SOC.
This patch series applies to current net-next-2.6/master and has been tested
on a sam9263 and sam9x5ek.
(Allthough, the sam9x5 support is not mainline yet).
please review and consider to apply,
Marc
The following changes since commit e3cc055c18ab575291acf0af7622a2e97c4728fa:
include/net: Remove unnecessary semicolons (2011-06-05 14:33:40 -0700)
are available in the git repository at:
git://git.pengutronix.de/git/mkl/linux-2.6.git can/at91-sam9x5
Marc Kleine-Budde (10):
can: at91_can: don't align struct definitions
can: at91_can: fix comment about priv->tx_next
can: at91_can: don't copy data to rx'ed RTR frames
can: at91_can: let get_tx_* functions return unsigned int
can: at91_can: directly define AT91_MB_RX_LAST
can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX
can: at91_can: convert derived mailbox constants into functions
can: at91_can: add id_table and convert prime mailbox constats to functions
can: at91_can: register mb0 sysfs entry only on at91sam9263
can: at91_can: add support for the AT91SAM9X5 SOCs
Uwe Kleine-König (1):
net/can: allow CAN_AT91 on AT91SAM9X5
drivers/net/can/Kconfig | 5 +-
drivers/net/can/at91_can.c | 366 +++++++++++++++++++++++++++++++-------------
2 files changed, 259 insertions(+), 112 deletions(-)
_______________________________________________
Socketcan-core mailing list
Socketcan-core@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/socketcan-core
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 01/11] can: at91_can: don't align struct definitions
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 02/11] can: at91_can: fix comment about priv->tx_next Marc Kleine-Budde
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/at91_can.c | 34 +++++++++++++++++-----------------
1 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 74efb5a..8f15ae4 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,
},
};
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/11] can: at91_can: fix comment about priv->tx_next
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-06-06 13:42 ` [PATCH 01/11] can: at91_can: don't align struct definitions Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 03/11] can: at91_can: don't copy data to rx'ed RTR frames Marc Kleine-Budde
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/at91_can.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 8f15ae4..afd0f5d 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);
*
*/
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/11] can: at91_can: don't copy data to rx'ed RTR frames
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-06-06 13:42 ` [PATCH 01/11] can: at91_can: don't align struct definitions Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 02/11] can: at91_can: fix comment about priv->tx_next Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 04/11] can: at91_can: let get_tx_* functions return unsigned int Marc Kleine-Budde
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
---
drivers/net/can/at91_can.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index afd0f5d..5358d70 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);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/11] can: at91_can: let get_tx_* functions return unsigned int
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (2 preceding siblings ...)
2011-06-06 13:42 ` [PATCH 03/11] can: at91_can: don't copy data to rx'ed RTR frames Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 07/11] can: at91_can: convert derived mailbox constants into functions Marc Kleine-Budde
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/at91_can.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 5358d70..716f22b 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;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 05/11] can: at91_can: directly define AT91_MB_RX_LAST
2011-06-06 13:42 [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 06/11] can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX Marc Kleine-Budde
` (3 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem; +Cc: socketcan-core, netdev, Marc Kleine-Budde
...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 <mkl@pengutronix.de>
---
drivers/net/can/at91_can.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 716f22b..9ce00fa 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
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/11] can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX
2011-06-06 13:42 [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 05/11] can: at91_can: directly define AT91_MB_RX_LAST Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 09/11] can: at91_can: register mb0 sysfs entry only on at91sam9263 Marc Kleine-Budde
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem; +Cc: socketcan-core, netdev, Marc Kleine-Budde
... and use it for AT91_NEXT_MB_MASK,
AT91_IRQ_MB_RX and AT91_IRQ_MB_RX, too.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/at91_can.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 9ce00fa..8699484 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);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/11] can: at91_can: convert derived mailbox constants into functions
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (3 preceding siblings ...)
2011-06-06 13:42 ` [PATCH 04/11] can: at91_can: let get_tx_* functions return unsigned int Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 08/11] can: at91_can: add id_table and convert prime mailbox constats to functions Marc Kleine-Budde
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
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 <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/at91_can.c | 125 +++++++++++++++++++++++++++++---------------
1 files changed, 83 insertions(+), 42 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 8699484..900ff67 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;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/11] can: at91_can: add id_table and convert prime mailbox constats to functions
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (4 preceding siblings ...)
2011-06-06 13:42 ` [PATCH 07/11] can: at91_can: convert derived mailbox constants into functions Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 10/11] can: at91_can: add support for the AT91SAM9X5 SOCs Marc Kleine-Budde
2011-06-07 8:05 ` [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series David Miller
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
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 <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/at91_can.c | 137 +++++++++++++++++++++++++++++++------------
1 files changed, 99 insertions(+), 38 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 900ff67..248e03f 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -41,20 +41,7 @@
#include <mach/board.h>
-#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)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 09/11] can: at91_can: register mb0 sysfs entry only on at91sam9263
2011-06-06 13:42 [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 05/11] can: at91_can: directly define AT91_MB_RX_LAST Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 06/11] can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-06 13:43 ` [PATCH 11/11] net/can: allow CAN_AT91 on AT91SAM9X5 Marc Kleine-Budde
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
4 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem; +Cc: socketcan-core, netdev, Marc Kleine-Budde
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 <mkl@pengutronix.de>
---
drivers/net/can/at91_can.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 248e03f..2b97281 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);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/11] can: at91_can: add support for the AT91SAM9X5 SOCs
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (5 preceding siblings ...)
2011-06-06 13:42 ` [PATCH 08/11] can: at91_can: add id_table and convert prime mailbox constats to functions Marc Kleine-Budde
@ 2011-06-06 13:42 ` Marc Kleine-Budde
2011-06-07 8:05 ` [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series David Miller
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
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 <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/at91_can.c | 69 +++++++++++++++++++++++++++++++++++---------
1 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 2b97281..121ede6 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 */
@@ -1330,6 +1368,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 */
}
};
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 11/11] net/can: allow CAN_AT91 on AT91SAM9X5
2011-06-06 13:42 [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series Marc Kleine-Budde
` (2 preceding siblings ...)
2011-06-06 13:42 ` [PATCH 09/11] can: at91_can: register mb0 sysfs entry only on at91sam9263 Marc Kleine-Budde
@ 2011-06-06 13:43 ` Marc Kleine-Budde
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
4 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2011-06-06 13:43 UTC (permalink / raw)
To: davem; +Cc: socketcan-core, netdev, Uwe Kleine-König, Marc Kleine-Budde
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/Kconfig | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 1d699e3..bbf06f7 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
--
1.7.4.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (6 preceding siblings ...)
2011-06-06 13:42 ` [PATCH 10/11] can: at91_can: add support for the AT91SAM9X5 SOCs Marc Kleine-Budde
@ 2011-06-07 8:05 ` David Miller
7 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2011-06-07 8:05 UTC (permalink / raw)
To: mkl-bIcnvbaLZ9MEGnE8C9+IrQ
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA
From: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Date: Mon, 6 Jun 2011 15:42:49 +0200
> Hello,
>
> this patch series add support for the at91_can core on the upcoming
> at91sam9x5 SOC series.
>
> The original at91_can driver supports the at91sam9263 which has 16
> mailboxes, but the CAN core on the at91sam9x5 has only 8. Most constants
> used in the RX and TX path are derived from the number of mailboxes.
>
> This patch series changes the driver from a static, compile time setup
> of the mailboxes to a dynamic one. Patches 1-4 clean up the driver, 5+6
> simplify the usage of the constants, patch 7 converts all derived constants
> into functions. Patch 8 will add id_table support to the driver then all
> remaining constants are converted into functions using the run time
> selected mailbox constants. The next patch (9) takes care about an
> at91sam9263 specific errata fix. Patch 10 and 11 will finally add supoprt
> for the at91sam9x5 SOC.
>
> This patch series applies to current net-next-2.6/master and has been tested
> on a sam9263 and sam9x5ek.
> (Allthough, the sam9x5 support is not mainline yet).
>
> please review and consider to apply,
> Marc
>
> The following changes since commit e3cc055c18ab575291acf0af7622a2e97c4728fa:
>
> include/net: Remove unnecessary semicolons (2011-06-05 14:33:40 -0700)
>
> are available in the git repository at:
> git://git.pengutronix.de/git/mkl/linux-2.6.git can/at91-sam9x5
Pulled, t hanks Marc.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-06-07 8:05 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-06 13:42 [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 05/11] can: at91_can: directly define AT91_MB_RX_LAST Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 06/11] can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 09/11] can: at91_can: register mb0 sysfs entry only on at91sam9263 Marc Kleine-Budde
2011-06-06 13:43 ` [PATCH 11/11] net/can: allow CAN_AT91 on AT91SAM9X5 Marc Kleine-Budde
[not found] ` <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-06-06 13:42 ` [PATCH 01/11] can: at91_can: don't align struct definitions Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 02/11] can: at91_can: fix comment about priv->tx_next Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 03/11] can: at91_can: don't copy data to rx'ed RTR frames Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 04/11] can: at91_can: let get_tx_* functions return unsigned int Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 07/11] can: at91_can: convert derived mailbox constants into functions Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 08/11] can: at91_can: add id_table and convert prime mailbox constats to functions Marc Kleine-Budde
2011-06-06 13:42 ` [PATCH 10/11] can: at91_can: add support for the AT91SAM9X5 SOCs Marc Kleine-Budde
2011-06-07 8:05 ` [PATCH 00/11] can: at91_can: add support for AT91SAM9X5 series David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).