From c0ebbdd6b57949775d428f00b8696a4078f86ac4 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 4 Dec 2013 19:52:36 +0100 Subject: [PATCH 1/3] can: gw: remove obsolete checks In commit be286bafe1f4069094865264f29805854c5788bf ("can: gw: add a variable limit for CAN frame routings") the detection of the frame routing has been changed. The former solution required dev->header_ops to be unused (== NULL). I missed to remove the obsolete checks in the original commit - so here it is. Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- net/can/gw.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/can/gw.c b/net/can/gw.c index 3f9b0f3a2818..88c8a39c173d 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -844,8 +844,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) if (!gwj->src.dev) goto out; - /* check for CAN netdev not using header_ops - see gw_rcv() */ - if (gwj->src.dev->type != ARPHRD_CAN || gwj->src.dev->header_ops) + if (gwj->src.dev->type != ARPHRD_CAN) goto put_src_out; gwj->dst.dev = dev_get_by_index(&init_net, gwj->ccgw.dst_idx); @@ -853,8 +852,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) if (!gwj->dst.dev) goto put_src_out; - /* check for CAN netdev not using header_ops - see gw_rcv() */ - if (gwj->dst.dev->type != ARPHRD_CAN || gwj->dst.dev->header_ops) + if (gwj->dst.dev->type != ARPHRD_CAN) goto put_src_dst_out; gwj->limit_hops = limhops; From 66606aafd8cd6cffbefa463b27e1f16e793e40a9 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 21 Dec 2013 09:01:41 +0400 Subject: [PATCH 2/3] can: mcp251x: Add device tree support This patch adds Device Tree support to the Microchip MCP251X driver. Signed-off-by: Alexander Shiyan Signed-off-by: Marc Kleine-Budde --- .../bindings/net/can/microchip,mcp251x.txt | 25 +++++ drivers/net/can/mcp251x.c | 99 ++++++++++++++----- 2 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt new file mode 100644 index 000000000000..ee3723beb701 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt @@ -0,0 +1,25 @@ +* Microchip MCP251X stand-alone CAN controller device tree bindings + +Required properties: + - compatible: Should be one of the following: + - "microchip,mcp2510" for MCP2510. + - "microchip,mcp2515" for MCP2515. + - reg: SPI chip select. + - clocks: The clock feeding the CAN controller. + - interrupt-parent: The parent interrupt controller. + - interrupts: Should contain IRQ line for the CAN controller. + +Optional properties: + - vdd-supply: Regulator that powers the CAN controller. + - xceiver-supply: Regulator that powers the CAN transceiver. + +Example: + can0: can@1 { + compatible = "microchip,mcp2515"; + reg = <1>; + clocks = <&clk24m>; + interrupt-parent = <&gpio4>; + interrupts = <13 0x2>; + vdd-supply = <®5v0>; + xceiver-supply = <®5v0>; + }; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 88d3877b6277..cdb9808d12db 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,8 @@ #include #include #include +#include +#include #include #include #include @@ -263,6 +266,7 @@ struct mcp251x_priv { int restart_tx; struct regulator *power; struct regulator *transceiver; + struct clk *clk; }; #define MCP251X_IS(_model) \ @@ -994,22 +998,65 @@ static const struct net_device_ops mcp251x_netdev_ops = { .ndo_start_xmit = mcp251x_hard_start_xmit, }; +static const struct of_device_id mcp251x_of_match[] = { + { + .compatible = "microchip,mcp2510", + .data = (void *)CAN_MCP251X_MCP2510, + }, + { + .compatible = "microchip,mcp2515", + .data = (void *)CAN_MCP251X_MCP2515, + }, + { } +}; +MODULE_DEVICE_TABLE(of, mcp251x_of_match); + +static const struct spi_device_id mcp251x_id_table[] = { + { + .name = "mcp2510", + .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2510, + }, + { + .name = "mcp2515", + .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515, + }, + { } +}; +MODULE_DEVICE_TABLE(spi, mcp251x_id_table); + static int mcp251x_can_probe(struct spi_device *spi) { + const struct of_device_id *of_id = of_match_device(mcp251x_of_match, + &spi->dev); + struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev); struct net_device *net; struct mcp251x_priv *priv; - struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev); - int ret = -ENODEV; + int freq, ret = -ENODEV; + struct clk *clk; - if (!pdata) - /* Platform data is required for osc freq */ - goto error_out; + clk = devm_clk_get(&spi->dev, NULL); + if (IS_ERR(clk)) { + if (pdata) + freq = pdata->oscillator_frequency; + else + return PTR_ERR(clk); + } else { + freq = clk_get_rate(clk); + } + + /* Sanity check */ + if (freq < 1000000 || freq > 25000000) + return -ERANGE; /* Allocate can/net device */ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); - if (!net) { - ret = -ENOMEM; - goto error_alloc; + if (!net) + return -ENOMEM; + + if (!IS_ERR(clk)) { + ret = clk_prepare_enable(clk); + if (ret) + goto out_free; } net->netdev_ops = &mcp251x_netdev_ops; @@ -1018,23 +1065,27 @@ static int mcp251x_can_probe(struct spi_device *spi) priv = netdev_priv(net); priv->can.bittiming_const = &mcp251x_bittiming_const; priv->can.do_set_mode = mcp251x_do_set_mode; - priv->can.clock.freq = pdata->oscillator_frequency / 2; + priv->can.clock.freq = freq / 2; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; - priv->model = spi_get_device_id(spi)->driver_data; + if (of_id) + priv->model = (enum mcp251x_model)of_id->data; + else + priv->model = spi_get_device_id(spi)->driver_data; priv->net = net; + priv->clk = clk; priv->power = devm_regulator_get(&spi->dev, "vdd"); priv->transceiver = devm_regulator_get(&spi->dev, "xceiver"); if ((PTR_ERR(priv->power) == -EPROBE_DEFER) || (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) { ret = -EPROBE_DEFER; - goto error_power; + goto out_clk; } ret = mcp251x_power_enable(priv->power, 1); if (ret) - goto error_power; + goto out_clk; spi_set_drvdata(spi, priv); @@ -1113,11 +1164,14 @@ static int mcp251x_can_probe(struct spi_device *spi) dma_free_coherent(&spi->dev, PAGE_SIZE, priv->spi_tx_buf, priv->spi_tx_dma); mcp251x_power_enable(priv->power, 0); -error_power: + +out_clk: + if (!IS_ERR(clk)) + clk_disable_unprepare(clk); + +out_free: free_candev(net); -error_alloc: - dev_err(&spi->dev, "probe failed\n"); -error_out: + return ret; } @@ -1135,6 +1189,9 @@ static int mcp251x_can_remove(struct spi_device *spi) mcp251x_power_enable(priv->power, 0); + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + free_candev(net); return 0; @@ -1197,21 +1254,13 @@ static int mcp251x_can_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend, mcp251x_can_resume); -static const struct spi_device_id mcp251x_id_table[] = { - { "mcp2510", CAN_MCP251X_MCP2510 }, - { "mcp2515", CAN_MCP251X_MCP2515 }, - { }, -}; - -MODULE_DEVICE_TABLE(spi, mcp251x_id_table); - static struct spi_driver mcp251x_can_driver = { .driver = { .name = DEVICE_NAME, .owner = THIS_MODULE, + .of_match_table = mcp251x_of_match, .pm = &mcp251x_can_pm_ops, }, - .id_table = mcp251x_id_table, .probe = mcp251x_can_probe, .remove = mcp251x_can_remove, From 44cc479a41c028a229c5491e9fa97df08901178b Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 20 Dec 2013 17:14:20 -0300 Subject: [PATCH 3/3] can: ti_hecc: Replace platform dependency with ARM dependency OMAP's ti_hecc driver is used to support the CAN controller on many omap2plus SoCs (OMAP2430, OMAP3, OMAP4, OMAP5 and AM335x), so it's wrong to make this depend on OMAP3 only. Take an extra step, to get wider build coverage, and make the driver depend on ARM. Signed-off-by: Ezequiel Garcia Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 3c069472eb8b..9e7d95dae2c7 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -71,7 +71,7 @@ config CAN_AT91 and AT91SAM9X5 processors. config CAN_TI_HECC - depends on ARCH_OMAP3 + depends on ARM tristate "TI High End CAN Controller" ---help--- Driver for TI HECC (High End CAN Controller) module found on many