Skip to content

Commit

Permalink
can: c_can: Add device tree support to Bosch C_CAN/D_CAN controller
Browse files Browse the repository at this point in the history
Add device tree support to C_CAN/D_CAN controller and usage details
are added to device tree documentation. Driver was tested on AM335x
EVM.

Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
For the of binding doc:
Reviewed-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
AnilKumar Ch authored and Marc Kleine-Budde committed Sep 21, 2012
1 parent f27b1db commit 2469627
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
49 changes: 49 additions & 0 deletions Documentation/devicetree/bindings/net/can/c_can.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Bosch C_CAN/D_CAN controller Device Tree Bindings
-------------------------------------------------

Required properties:
- compatible : Should be "bosch,c_can" for C_CAN controllers and
"bosch,d_can" for D_CAN controllers.
- reg : physical base address and size of the C_CAN/D_CAN
registers map
- interrupts : property with a value describing the interrupt
number

Optional properties:
- ti,hwmods : Must be "d_can<n>" or "c_can<n>", n being the
instance number

Note: "ti,hwmods" field is used to fetch the base address and irq
resources from TI, omap hwmod data base during device registration.
Future plan is to migrate hwmod data base contents into device tree
blob so that, all the required data will be used from device tree dts
file.

Example:

Step1: SoC common .dtsi file

dcan1: d_can@481d0000 {
compatible = "bosch,d_can";
reg = <0x481d0000 0x2000>;
interrupts = <55>;
interrupt-parent = <&intc>;
status = "disabled";
};

(or)

dcan1: d_can@481d0000 {
compatible = "bosch,d_can";
ti,hwmods = "d_can1";
reg = <0x481d0000 0x2000>;
interrupts = <55>;
interrupt-parent = <&intc>;
status = "disabled";
};

Step 2: board specific .dts file

&dcan1 {
status = "okay";
};
55 changes: 38 additions & 17 deletions drivers/net/can/c_can/c_can_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include <linux/can/dev.h>

Expand Down Expand Up @@ -65,17 +67,52 @@ static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv,
writew(val, priv->base + 2 * priv->regs[index]);
}

static struct platform_device_id c_can_id_table[] = {
[BOSCH_C_CAN_PLATFORM] = {
.name = KBUILD_MODNAME,
.driver_data = BOSCH_C_CAN,
},
[BOSCH_C_CAN] = {
.name = "c_can",
.driver_data = BOSCH_C_CAN,
},
[BOSCH_D_CAN] = {
.name = "d_can",
.driver_data = BOSCH_D_CAN,
}, {
}
};

static const struct of_device_id c_can_of_table[] = {
{ .compatible = "bosch,c_can", .data = &c_can_id_table[BOSCH_C_CAN] },
{ .compatible = "bosch,d_can", .data = &c_can_id_table[BOSCH_D_CAN] },
{ /* sentinel */ },
};

static int __devinit c_can_plat_probe(struct platform_device *pdev)
{
int ret;
void __iomem *addr;
struct net_device *dev;
struct c_can_priv *priv;
const struct of_device_id *match;
const struct platform_device_id *id;
struct resource *mem;
int irq;
struct clk *clk;

if (pdev->dev.of_node) {
match = of_match_device(c_can_of_table, &pdev->dev);
if (!match) {
dev_err(&pdev->dev, "Failed to find matching dt id\n");
ret = -EINVAL;
goto exit;
}
id = match->data;
} else {
id = platform_get_device_id(pdev);
}

/* get the appropriate clk */
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
Expand Down Expand Up @@ -114,7 +151,6 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
}

priv = netdev_priv(dev);
id = platform_get_device_id(pdev);
switch (id->driver_data) {
case BOSCH_C_CAN:
priv->regs = reg_map_c_can;
Expand Down Expand Up @@ -195,26 +231,11 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev)
return 0;
}

static const struct platform_device_id c_can_id_table[] = {
[BOSCH_C_CAN_PLATFORM] = {
.name = KBUILD_MODNAME,
.driver_data = BOSCH_C_CAN,
},
[BOSCH_C_CAN] = {
.name = "c_can",
.driver_data = BOSCH_C_CAN,
},
[BOSCH_D_CAN] = {
.name = "d_can",
.driver_data = BOSCH_D_CAN,
}, {
}
};

static struct platform_driver c_can_plat_driver = {
.driver = {
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(c_can_of_table),
},
.probe = c_can_plat_probe,
.remove = __devexit_p(c_can_plat_remove),
Expand Down

0 comments on commit 2469627

Please sign in to comment.