summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2011-11-02 19:12:52 +0800
committerJason Liu <r64343@freescale.com>2012-07-20 13:17:10 +0800
commit3d801ca8d8fee98c70fe9731ae94627d7975f49d (patch)
tree92320c7e711bdf2e4ebb62e72ad1a2fab54b25bb /drivers/net
parent801bb44aad2476d259d249b3c1d7375c7cfd8725 (diff)
ENGR00161256-1 flexcan: convert driver to use platform ids
Using platform ids to handle differences between different SoCs. The default rx fifo global mask register, newly introduced in mx6q, is 0xffffffff and the reset value in Message buffers(can be reused as the memory of rx fifo filter table) is none zero, it will wrongly cause the can to be unable to recevie packets due to filter. We need to clear it to make sure to receive all packets. Signed-off-by: Dong Aisheng <b29396@freescale.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/can/flexcan.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 17678117ed69..83cbbee95f8d 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -36,6 +36,7 @@
#include <linux/platform_device.h>
#include <mach/clock.h>
+#include <mach/hardware.h>
#define DRV_NAME "flexcan"
@@ -162,10 +163,22 @@ struct flexcan_regs {
u32 imask1; /* 0x28 */
u32 iflag2; /* 0x2c */
u32 iflag1; /* 0x30 */
- u32 _reserved2[19];
+ u32 crl2; /* 0x34 */
+ u32 esr2; /* 0x38 */
+ u32 _reserved2[2];
+ u32 crcr; /* 0x44 */
+ u32 rxfgmask; /* 0x48 */
+ u32 rxfir; /* 0x4c */
+ u32 _reserved3[12];
struct flexcan_mb cantxfg[64];
};
+enum flexcan_ip_version {
+ FLEXCAN_VER_3_0_0,
+ FLEXCAN_VER_3_0_4,
+ FLEXCAN_VER_10_0_12,
+};
+
struct flexcan_priv {
struct can_priv can;
struct net_device *dev;
@@ -177,6 +190,7 @@ struct flexcan_priv {
struct clk *clk;
struct flexcan_platform_data *pdata;
+ enum flexcan_ip_version version;
};
static struct can_bittiming_const flexcan_bittiming_const = {
@@ -723,6 +737,10 @@ static int flexcan_chip_start(struct net_device *dev)
writel(0x0, &regs->rx14mask);
writel(0x0, &regs->rx15mask);
+ /* clear rx fifo global mask */
+ if (priv->version >= FLEXCAN_VER_10_0_12)
+ writel(0x0, &regs->rxfgmask);
+
flexcan_transceiver_switch(priv, 1);
/* synchronize with the can bus */
@@ -896,6 +914,25 @@ static void __devexit unregister_flexcandev(struct net_device *dev)
unregister_candev(dev);
}
+static struct platform_device_id flexcan_devtype[] = {
+ {
+ .name = "imx25-flexcan",
+ .driver_data = FLEXCAN_VER_3_0_0,
+ }, {
+ .name = "imx28-flexcan",
+ .driver_data = FLEXCAN_VER_3_0_4,
+ }, {
+ .name = "imx35-flexcan",
+ .driver_data = FLEXCAN_VER_3_0_0,
+ }, {
+ .name = "imx53-flexcan",
+ .driver_data = FLEXCAN_VER_3_0_0,
+ }, {
+ .name = "imx6q-flexcan",
+ .driver_data = FLEXCAN_VER_10_0_12,
+ },
+};
+
static int __devinit flexcan_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -954,6 +991,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
priv->dev = dev;
priv->clk = clk;
priv->pdata = pdev->dev.platform_data;
+ priv->version = pdev->id_entry->driver_data;
netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
@@ -1006,6 +1044,7 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
static struct platform_driver flexcan_driver = {
.driver.name = DRV_NAME,
.probe = flexcan_probe,
+ .id_table = flexcan_devtype,
.remove = __devexit_p(flexcan_remove),
};