提交 3f8a2b74 编写于 作者: D David S. Miller

Merge tag 'linux-can-next-for-3.18-20140820' of git://gitorious.org/linux-can/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2014-08-20

this is a pull request of 10 patches for net-next/master.

There is one patch by Wolfram Sang to clean up the build system.
Two patches by Stefan Agner that add vf610 support to the flexcan
driver. Dong Aisheng add support for bosch's m_can core, which is found
in the new freescale ARM SoCs. Sergei Shtylyov improves the rcar_can
driver by supporting all input clocks and adding device tree support.
The next patch is a small cleanup for the bit rate calculation function
by Lad, Prabhakar. And finally a patch by Himangi Saraogi, which
converts the mcp251x driver to use dmam_alloc_coherent.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Bosch MCAN controller Device Tree Bindings
-------------------------------------------------
Required properties:
- compatible : Should be "bosch,m_can" for M_CAN controllers
- reg : physical base address and size of the M_CAN
registers map and Message RAM
- reg-names : Should be "m_can" and "message_ram"
- interrupts : Should be the interrupt number of M_CAN interrupt
line 0 and line 1, could be same if sharing
the same interrupt.
- interrupt-names : Should contain "int0" and "int1"
- clocks : Clocks used by controller, should be host clock
and CAN clock.
- clock-names : Should contain "hclk" and "cclk"
- pinctrl-<n> : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt
- pinctrl-names : Names corresponding to the numbered pinctrl states
- bosch,mram-cfg : Message RAM configuration data.
Multiple M_CAN instances can share the same Message
RAM and each element(e.g Rx FIFO or Tx Buffer and etc)
number in Message RAM is also configurable,
so this property is telling driver how the shared or
private Message RAM are used by this M_CAN controller.
The format should be as follows:
<offset sidf_elems xidf_elems rxf0_elems rxf1_elems
rxb_elems txe_elems txb_elems>
The 'offset' is an address offset of the Message RAM
where the following elements start from. This is
usually set to 0x0 if you're using a private Message
RAM. The remain cells are used to specify how many
elements are used for each FIFO/Buffer.
M_CAN includes the following elements according to user manual:
11-bit Filter 0-128 elements / 0-128 words
29-bit Filter 0-64 elements / 0-128 words
Rx FIFO 0 0-64 elements / 0-1152 words
Rx FIFO 1 0-64 elements / 0-1152 words
Rx Buffers 0-64 elements / 0-1152 words
Tx Event FIFO 0-32 elements / 0-64 words
Tx Buffers 0-32 elements / 0-576 words
Please refer to 2.4.1 Message RAM Configuration in
Bosch M_CAN user manual for details.
Example:
SoC dtsi:
m_can1: can@020e8000 {
compatible = "bosch,m_can";
reg = <0x020e8000 0x4000>, <0x02298000 0x4000>;
reg-names = "m_can", "message_ram";
interrupts = <0 114 0x04>,
<0 114 0x04>;
interrupt-names = "int0", "int1";
clocks = <&clks IMX6SX_CLK_CANFD>,
<&clks IMX6SX_CLK_CANFD>;
clock-names = "hclk", "cclk";
bosch,mram-cfg = <0x0 0 0 32 0 0 0 1>;
status = "disabled";
};
Board dts:
&m_can1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_m_can1>;
status = "enabled";
};
Renesas R-Car CAN controller Device Tree Bindings
-------------------------------------------------
Required properties:
- compatible: "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
"renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC.
"renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC.
"renesas,can-r8a7791" if CAN controller is a part of R8A7791 SoC.
- reg: physical base address and size of the R-Car CAN register map.
- interrupts: interrupt specifier for the sole interrupt.
- clocks: phandles and clock specifiers for 3 CAN clock inputs.
- clock-names: 3 clock input name strings: "clkp1", "clkp2", "can_clk".
- pinctrl-0: pin control group to be used for this controller.
- pinctrl-names: must be "default".
Optional properties:
- renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are:
<0x0> (default) : Peripheral clock (clkp1)
<0x1> : Peripheral clock (clkp2)
<0x3> : Externally input clock
Example
-------
SoC common .dtsi file:
can0: can@e6e80000 {
compatible = "renesas,can-r8a7791";
reg = <0 0xe6e80000 0 0x1000>;
interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_RCAN0>,
<&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
clock-names = "clkp1", "clkp2", "can_clk";
status = "disabled";
};
Board specific .dts file:
&can0 {
pinctrl-0 = <&can0_pins>;
pinctrl-names = "default";
status = "okay";
};
...@@ -143,6 +143,8 @@ source "drivers/net/can/sja1000/Kconfig" ...@@ -143,6 +143,8 @@ source "drivers/net/can/sja1000/Kconfig"
source "drivers/net/can/c_can/Kconfig" source "drivers/net/can/c_can/Kconfig"
source "drivers/net/can/m_can/Kconfig"
source "drivers/net/can/cc770/Kconfig" source "drivers/net/can/cc770/Kconfig"
source "drivers/net/can/spi/Kconfig" source "drivers/net/can/spi/Kconfig"
......
...@@ -17,6 +17,7 @@ obj-y += softing/ ...@@ -17,6 +17,7 @@ obj-y += softing/
obj-$(CONFIG_CAN_SJA1000) += sja1000/ obj-$(CONFIG_CAN_SJA1000) += sja1000/
obj-$(CONFIG_CAN_MSCAN) += mscan/ obj-$(CONFIG_CAN_MSCAN) += mscan/
obj-$(CONFIG_CAN_C_CAN) += c_can/ obj-$(CONFIG_CAN_C_CAN) += c_can/
obj-$(CONFIG_CAN_M_CAN) += m_can/
obj-$(CONFIG_CAN_CC770) += cc770/ obj-$(CONFIG_CAN_CC770) += cc770/
obj-$(CONFIG_CAN_AT91) += at91_can.o obj-$(CONFIG_CAN_AT91) += at91_can.o
obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
...@@ -28,4 +29,4 @@ obj-$(CONFIG_CAN_GRCAN) += grcan.o ...@@ -28,4 +29,4 @@ obj-$(CONFIG_CAN_GRCAN) += grcan.o
obj-$(CONFIG_CAN_RCAR) += rcar_can.o obj-$(CONFIG_CAN_RCAR) += rcar_can.o
obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -5,5 +5,3 @@ ...@@ -5,5 +5,3 @@
obj-$(CONFIG_CAN_C_CAN) += c_can.o obj-$(CONFIG_CAN_C_CAN) += c_can.o
obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o
obj-$(CONFIG_CAN_C_CAN_PCI) += c_can_pci.o obj-$(CONFIG_CAN_C_CAN_PCI) += c_can_pci.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -5,5 +5,3 @@ ...@@ -5,5 +5,3 @@
obj-$(CONFIG_CAN_CC770) += cc770.o obj-$(CONFIG_CAN_CC770) += cc770.o
obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -103,11 +103,11 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, ...@@ -103,11 +103,11 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
const struct can_bittiming_const *btc) const struct can_bittiming_const *btc)
{ {
struct can_priv *priv = netdev_priv(dev); struct can_priv *priv = netdev_priv(dev);
long rate, best_rate = 0;
long best_error = 1000000000, error = 0; long best_error = 1000000000, error = 0;
int best_tseg = 0, best_brp = 0, brp = 0; int best_tseg = 0, best_brp = 0, brp = 0;
int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0; int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
int spt_error = 1000, spt = 0, sampl_pt; int spt_error = 1000, spt = 0, sampl_pt;
long rate;
u64 v64; u64 v64;
/* Use CIA recommended sample points */ /* Use CIA recommended sample points */
...@@ -152,7 +152,6 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, ...@@ -152,7 +152,6 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
} }
best_tseg = tseg / 2; best_tseg = tseg / 2;
best_brp = brp; best_brp = brp;
best_rate = rate;
if (error == 0) if (error == 0)
break; break;
} }
......
...@@ -92,6 +92,27 @@ ...@@ -92,6 +92,27 @@
#define FLEXCAN_CTRL_ERR_ALL \ #define FLEXCAN_CTRL_ERR_ALL \
(FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
/* FLEXCAN control register 2 (CTRL2) bits */
#define FLEXCAN_CRL2_ECRWRE BIT(29)
#define FLEXCAN_CRL2_WRMFRZ BIT(28)
#define FLEXCAN_CRL2_RFFN(x) (((x) & 0x0f) << 24)
#define FLEXCAN_CRL2_TASD(x) (((x) & 0x1f) << 19)
#define FLEXCAN_CRL2_MRP BIT(18)
#define FLEXCAN_CRL2_RRS BIT(17)
#define FLEXCAN_CRL2_EACEN BIT(16)
/* FLEXCAN memory error control register (MECR) bits */
#define FLEXCAN_MECR_ECRWRDIS BIT(31)
#define FLEXCAN_MECR_HANCEI_MSK BIT(19)
#define FLEXCAN_MECR_FANCEI_MSK BIT(18)
#define FLEXCAN_MECR_CEI_MSK BIT(16)
#define FLEXCAN_MECR_HAERRIE BIT(15)
#define FLEXCAN_MECR_FAERRIE BIT(14)
#define FLEXCAN_MECR_EXTERRIE BIT(13)
#define FLEXCAN_MECR_RERRDIS BIT(9)
#define FLEXCAN_MECR_ECCDIS BIT(8)
#define FLEXCAN_MECR_NCEFAFRZ BIT(7)
/* FLEXCAN error and status register (ESR) bits */ /* FLEXCAN error and status register (ESR) bits */
#define FLEXCAN_ESR_TWRN_INT BIT(17) #define FLEXCAN_ESR_TWRN_INT BIT(17)
#define FLEXCAN_ESR_RWRN_INT BIT(16) #define FLEXCAN_ESR_RWRN_INT BIT(16)
...@@ -150,18 +171,20 @@ ...@@ -150,18 +171,20 @@
* FLEXCAN hardware feature flags * FLEXCAN hardware feature flags
* *
* Below is some version info we got: * Below is some version info we got:
* SOC Version IP-Version Glitch- [TR]WRN_INT * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err
* Filter? connected? * Filter? connected? detection
* MX25 FlexCAN2 03.00.00.00 no no * MX25 FlexCAN2 03.00.00.00 no no no
* MX28 FlexCAN2 03.00.04.00 yes yes * MX28 FlexCAN2 03.00.04.00 yes yes no
* MX35 FlexCAN2 03.00.00.00 no no * MX35 FlexCAN2 03.00.00.00 no no no
* MX53 FlexCAN2 03.00.00.00 yes no * MX53 FlexCAN2 03.00.00.00 yes no no
* MX6s FlexCAN3 10.00.12.00 yes yes * MX6s FlexCAN3 10.00.12.00 yes yes no
* VF610 FlexCAN3 ? no yes yes
* *
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
*/ */
#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
#define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */
/* Structure of the message buffer */ /* Structure of the message buffer */
struct flexcan_mb { struct flexcan_mb {
...@@ -192,8 +215,17 @@ struct flexcan_regs { ...@@ -192,8 +215,17 @@ struct flexcan_regs {
u32 crcr; /* 0x44 */ u32 crcr; /* 0x44 */
u32 rxfgmask; /* 0x48 */ u32 rxfgmask; /* 0x48 */
u32 rxfir; /* 0x4c */ u32 rxfir; /* 0x4c */
u32 _reserved3[12]; u32 _reserved3[12]; /* 0x50 */
struct flexcan_mb cantxfg[64]; struct flexcan_mb cantxfg[64]; /* 0x80 */
u32 _reserved4[408];
u32 mecr; /* 0xae0 */
u32 erriar; /* 0xae4 */
u32 erridpr; /* 0xae8 */
u32 errippr; /* 0xaec */
u32 rerrar; /* 0xaf0 */
u32 rerrdr; /* 0xaf4 */
u32 rerrsynr; /* 0xaf8 */
u32 errsr; /* 0xafc */
}; };
struct flexcan_devtype_data { struct flexcan_devtype_data {
...@@ -223,6 +255,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data; ...@@ -223,6 +255,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data;
static struct flexcan_devtype_data fsl_imx6q_devtype_data = { static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
.features = FLEXCAN_HAS_V10_FEATURES, .features = FLEXCAN_HAS_V10_FEATURES,
}; };
static struct flexcan_devtype_data fsl_vf610_devtype_data = {
.features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES,
};
static const struct can_bittiming_const flexcan_bittiming_const = { static const struct can_bittiming_const flexcan_bittiming_const = {
.name = DRV_NAME, .name = DRV_NAME,
...@@ -378,8 +413,9 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv) ...@@ -378,8 +413,9 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
return 0; return 0;
} }
static int flexcan_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec) static int __flexcan_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec)
{ {
const struct flexcan_priv *priv = netdev_priv(dev); const struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->base; struct flexcan_regs __iomem *regs = priv->base;
...@@ -391,6 +427,29 @@ static int flexcan_get_berr_counter(const struct net_device *dev, ...@@ -391,6 +427,29 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
return 0; return 0;
} }
static int flexcan_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec)
{
const struct flexcan_priv *priv = netdev_priv(dev);
int err;
err = clk_prepare_enable(priv->clk_ipg);
if (err)
return err;
err = clk_prepare_enable(priv->clk_per);
if (err)
goto out_disable_ipg;
err = __flexcan_get_berr_counter(dev, bec);
clk_disable_unprepare(priv->clk_per);
out_disable_ipg:
clk_disable_unprepare(priv->clk_ipg);
return err;
}
static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
const struct flexcan_priv *priv = netdev_priv(dev); const struct flexcan_priv *priv = netdev_priv(dev);
...@@ -503,7 +562,7 @@ static void do_state(struct net_device *dev, ...@@ -503,7 +562,7 @@ static void do_state(struct net_device *dev,
struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_priv *priv = netdev_priv(dev);
struct can_berr_counter bec; struct can_berr_counter bec;
flexcan_get_berr_counter(dev, &bec); __flexcan_get_berr_counter(dev, &bec);
switch (priv->can.state) { switch (priv->can.state) {
case CAN_STATE_ERROR_ACTIVE: case CAN_STATE_ERROR_ACTIVE:
...@@ -793,7 +852,7 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -793,7 +852,7 @@ static int flexcan_chip_start(struct net_device *dev)
struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->base; struct flexcan_regs __iomem *regs = priv->base;
int err; int err;
u32 reg_mcr, reg_ctrl; u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr;
/* enable module */ /* enable module */
err = flexcan_chip_enable(priv); err = flexcan_chip_enable(priv);
...@@ -870,6 +929,31 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -870,6 +929,31 @@ static int flexcan_chip_start(struct net_device *dev)
if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
flexcan_write(0x0, &regs->rxfgmask); flexcan_write(0x0, &regs->rxfgmask);
/*
* On Vybrid, disable memory error detection interrupts
* and freeze mode.
* This also works around errata e5295 which generates
* false positive memory errors and put the device in
* freeze mode.
*/
if (priv->devtype_data->features & FLEXCAN_HAS_MECR_FEATURES) {
/*
* Follow the protocol as described in "Detection
* and Correction of Memory Errors" to write to
* MECR register
*/
reg_crl2 = flexcan_read(&regs->crl2);
reg_crl2 |= FLEXCAN_CRL2_ECRWRE;
flexcan_write(reg_crl2, &regs->crl2);
reg_mecr = flexcan_read(&regs->mecr);
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
flexcan_write(reg_mecr, &regs->mecr);
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
FLEXCAN_MECR_FANCEI_MSK);
flexcan_write(reg_mecr, &regs->mecr);
}
err = flexcan_transceiver_enable(priv); err = flexcan_transceiver_enable(priv);
if (err) if (err)
goto out_chip_disable; goto out_chip_disable;
...@@ -1080,6 +1164,7 @@ static const struct of_device_id flexcan_of_match[] = { ...@@ -1080,6 +1164,7 @@ static const struct of_device_id flexcan_of_match[] = {
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
{ /* sentinel */ }, { /* sentinel */ },
}; };
MODULE_DEVICE_TABLE(of, flexcan_of_match); MODULE_DEVICE_TABLE(of, flexcan_of_match);
......
config CAN_M_CAN
tristate "Bosch M_CAN devices"
---help---
Say Y here if you want to support for Bosch M_CAN controller.
#
# Makefile for the Bosch M_CAN controller driver.
#
obj-$(CONFIG_CAN_M_CAN) += m_can.o
此差异已折叠。
obj-$(CONFIG_CAN_MPC5XXX) += mscan-mpc5xxx.o obj-$(CONFIG_CAN_MPC5XXX) += mscan-mpc5xxx.o
mscan-mpc5xxx-objs := mscan.o mpc5xxx_can.o mscan-mpc5xxx-objs := mscan.o mpc5xxx_can.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/can/platform/rcar_can.h> #include <linux/can/platform/rcar_can.h>
#include <linux/of.h>
#define RCAR_CAN_DRV_NAME "rcar_can" #define RCAR_CAN_DRV_NAME "rcar_can"
...@@ -87,6 +88,7 @@ struct rcar_can_priv { ...@@ -87,6 +88,7 @@ struct rcar_can_priv {
struct napi_struct napi; struct napi_struct napi;
struct rcar_can_regs __iomem *regs; struct rcar_can_regs __iomem *regs;
struct clk *clk; struct clk *clk;
struct clk *can_clk;
u8 tx_dlc[RCAR_CAN_FIFO_DEPTH]; u8 tx_dlc[RCAR_CAN_FIFO_DEPTH];
u32 tx_head; u32 tx_head;
u32 tx_tail; u32 tx_tail;
...@@ -505,14 +507,20 @@ static int rcar_can_open(struct net_device *ndev) ...@@ -505,14 +507,20 @@ static int rcar_can_open(struct net_device *ndev)
err = clk_prepare_enable(priv->clk); err = clk_prepare_enable(priv->clk);
if (err) { if (err) {
netdev_err(ndev, "clk_prepare_enable() failed, error %d\n", netdev_err(ndev, "failed to enable periperal clock, error %d\n",
err); err);
goto out; goto out;
} }
err = clk_prepare_enable(priv->can_clk);
if (err) {
netdev_err(ndev, "failed to enable CAN clock, error %d\n",
err);
goto out_clock;
}
err = open_candev(ndev); err = open_candev(ndev);
if (err) { if (err) {
netdev_err(ndev, "open_candev() failed, error %d\n", err); netdev_err(ndev, "open_candev() failed, error %d\n", err);
goto out_clock; goto out_can_clock;
} }
napi_enable(&priv->napi); napi_enable(&priv->napi);
err = request_irq(ndev->irq, rcar_can_interrupt, 0, ndev->name, ndev); err = request_irq(ndev->irq, rcar_can_interrupt, 0, ndev->name, ndev);
...@@ -527,6 +535,8 @@ static int rcar_can_open(struct net_device *ndev) ...@@ -527,6 +535,8 @@ static int rcar_can_open(struct net_device *ndev)
out_close: out_close:
napi_disable(&priv->napi); napi_disable(&priv->napi);
close_candev(ndev); close_candev(ndev);
out_can_clock:
clk_disable_unprepare(priv->can_clk);
out_clock: out_clock:
clk_disable_unprepare(priv->clk); clk_disable_unprepare(priv->clk);
out: out:
...@@ -565,6 +575,7 @@ static int rcar_can_close(struct net_device *ndev) ...@@ -565,6 +575,7 @@ static int rcar_can_close(struct net_device *ndev)
rcar_can_stop(ndev); rcar_can_stop(ndev);
free_irq(ndev->irq, ndev); free_irq(ndev->irq, ndev);
napi_disable(&priv->napi); napi_disable(&priv->napi);
clk_disable_unprepare(priv->can_clk);
clk_disable_unprepare(priv->clk); clk_disable_unprepare(priv->clk);
close_candev(ndev); close_candev(ndev);
can_led_event(ndev, CAN_LED_EVENT_STOP); can_led_event(ndev, CAN_LED_EVENT_STOP);
...@@ -715,6 +726,12 @@ static int rcar_can_get_berr_counter(const struct net_device *dev, ...@@ -715,6 +726,12 @@ static int rcar_can_get_berr_counter(const struct net_device *dev,
return 0; return 0;
} }
static const char * const clock_names[] = {
[CLKR_CLKP1] = "clkp1",
[CLKR_CLKP2] = "clkp2",
[CLKR_CLKEXT] = "can_clk",
};
static int rcar_can_probe(struct platform_device *pdev) static int rcar_can_probe(struct platform_device *pdev)
{ {
struct rcar_can_platform_data *pdata; struct rcar_can_platform_data *pdata;
...@@ -722,13 +739,20 @@ static int rcar_can_probe(struct platform_device *pdev) ...@@ -722,13 +739,20 @@ static int rcar_can_probe(struct platform_device *pdev)
struct net_device *ndev; struct net_device *ndev;
struct resource *mem; struct resource *mem;
void __iomem *addr; void __iomem *addr;
u32 clock_select = CLKR_CLKP1;
int err = -ENODEV; int err = -ENODEV;
int irq; int irq;
pdata = dev_get_platdata(&pdev->dev); if (pdev->dev.of_node) {
if (!pdata) { of_property_read_u32(pdev->dev.of_node,
dev_err(&pdev->dev, "No platform data provided!\n"); "renesas,can-clock-select", &clock_select);
goto fail; } else {
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "No platform data provided!\n");
goto fail;
}
clock_select = pdata->clock_select;
} }
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
...@@ -753,10 +777,22 @@ static int rcar_can_probe(struct platform_device *pdev) ...@@ -753,10 +777,22 @@ static int rcar_can_probe(struct platform_device *pdev)
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
priv->clk = devm_clk_get(&pdev->dev, NULL); priv->clk = devm_clk_get(&pdev->dev, "clkp1");
if (IS_ERR(priv->clk)) { if (IS_ERR(priv->clk)) {
err = PTR_ERR(priv->clk); err = PTR_ERR(priv->clk);
dev_err(&pdev->dev, "cannot get clock: %d\n", err); dev_err(&pdev->dev, "cannot get peripheral clock: %d\n", err);
goto fail_clk;
}
if (clock_select >= ARRAY_SIZE(clock_names)) {
err = -EINVAL;
dev_err(&pdev->dev, "invalid CAN clock selected\n");
goto fail_clk;
}
priv->can_clk = devm_clk_get(&pdev->dev, clock_names[clock_select]);
if (IS_ERR(priv->can_clk)) {
err = PTR_ERR(priv->can_clk);
dev_err(&pdev->dev, "cannot get CAN clock: %d\n", err);
goto fail_clk; goto fail_clk;
} }
...@@ -765,8 +801,8 @@ static int rcar_can_probe(struct platform_device *pdev) ...@@ -765,8 +801,8 @@ static int rcar_can_probe(struct platform_device *pdev)
ndev->flags |= IFF_ECHO; ndev->flags |= IFF_ECHO;
priv->ndev = ndev; priv->ndev = ndev;
priv->regs = addr; priv->regs = addr;
priv->clock_select = pdata->clock_select; priv->clock_select = clock_select;
priv->can.clock.freq = clk_get_rate(priv->clk); priv->can.clock.freq = clk_get_rate(priv->can_clk);
priv->can.bittiming_const = &rcar_can_bittiming_const; priv->can.bittiming_const = &rcar_can_bittiming_const;
priv->can.do_set_mode = rcar_can_do_set_mode; priv->can.do_set_mode = rcar_can_do_set_mode;
priv->can.do_get_berr_counter = rcar_can_get_berr_counter; priv->can.do_get_berr_counter = rcar_can_get_berr_counter;
...@@ -858,10 +894,20 @@ static int __maybe_unused rcar_can_resume(struct device *dev) ...@@ -858,10 +894,20 @@ static int __maybe_unused rcar_can_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(rcar_can_pm_ops, rcar_can_suspend, rcar_can_resume); static SIMPLE_DEV_PM_OPS(rcar_can_pm_ops, rcar_can_suspend, rcar_can_resume);
static const struct of_device_id rcar_can_of_table[] __maybe_unused = {
{ .compatible = "renesas,can-r8a7778" },
{ .compatible = "renesas,can-r8a7779" },
{ .compatible = "renesas,can-r8a7790" },
{ .compatible = "renesas,can-r8a7791" },
{ }
};
MODULE_DEVICE_TABLE(of, rcar_can_of_table);
static struct platform_driver rcar_can_driver = { static struct platform_driver rcar_can_driver = {
.driver = { .driver = {
.name = RCAR_CAN_DRV_NAME, .name = RCAR_CAN_DRV_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(rcar_can_of_table),
.pm = &rcar_can_pm_ops, .pm = &rcar_can_pm_ops,
}, },
.probe = rcar_can_probe, .probe = rcar_can_probe,
......
...@@ -12,5 +12,3 @@ obj-$(CONFIG_CAN_PEAK_PCMCIA) += peak_pcmcia.o ...@@ -12,5 +12,3 @@ obj-$(CONFIG_CAN_PEAK_PCMCIA) += peak_pcmcia.o
obj-$(CONFIG_CAN_PEAK_PCI) += peak_pci.o obj-$(CONFIG_CAN_PEAK_PCI) += peak_pci.o
obj-$(CONFIG_CAN_PLX_PCI) += plx_pci.o obj-$(CONFIG_CAN_PLX_PCI) += plx_pci.o
obj-$(CONFIG_CAN_TSCAN1) += tscan1.o obj-$(CONFIG_CAN_TSCAN1) += tscan1.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -2,5 +2,3 @@ ...@@ -2,5 +2,3 @@
softing-y := softing_main.o softing_fw.o softing-y := softing_main.o softing_fw.o
obj-$(CONFIG_CAN_SOFTING) += softing.o obj-$(CONFIG_CAN_SOFTING) += softing.o
obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -4,5 +4,3 @@ ...@@ -4,5 +4,3 @@
obj-$(CONFIG_CAN_MCP251X) += mcp251x.o obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
...@@ -1107,10 +1107,10 @@ static int mcp251x_can_probe(struct spi_device *spi) ...@@ -1107,10 +1107,10 @@ static int mcp251x_can_probe(struct spi_device *spi)
* Minimum coherent DMA allocation is PAGE_SIZE, so allocate * Minimum coherent DMA allocation is PAGE_SIZE, so allocate
* that much and share it between Tx and Rx DMA buffers. * that much and share it between Tx and Rx DMA buffers.
*/ */
priv->spi_tx_buf = dma_alloc_coherent(&spi->dev, priv->spi_tx_buf = dmam_alloc_coherent(&spi->dev,
PAGE_SIZE, PAGE_SIZE,
&priv->spi_tx_dma, &priv->spi_tx_dma,
GFP_DMA); GFP_DMA);
if (priv->spi_tx_buf) { if (priv->spi_tx_buf) {
priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2)); priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2));
...@@ -1156,9 +1156,6 @@ static int mcp251x_can_probe(struct spi_device *spi) ...@@ -1156,9 +1156,6 @@ static int mcp251x_can_probe(struct spi_device *spi)
return 0; return 0;
error_probe: error_probe:
if (mcp251x_enable_dma)
dma_free_coherent(&spi->dev, PAGE_SIZE,
priv->spi_tx_buf, priv->spi_tx_dma);
mcp251x_power_enable(priv->power, 0); mcp251x_power_enable(priv->power, 0);
out_clk: out_clk:
...@@ -1178,11 +1175,6 @@ static int mcp251x_can_remove(struct spi_device *spi) ...@@ -1178,11 +1175,6 @@ static int mcp251x_can_remove(struct spi_device *spi)
unregister_candev(net); unregister_candev(net);
if (mcp251x_enable_dma) {
dma_free_coherent(&spi->dev, PAGE_SIZE,
priv->spi_tx_buf, priv->spi_tx_dma);
}
mcp251x_power_enable(priv->power, 0); mcp251x_power_enable(priv->power, 0);
if (!IS_ERR(priv->clk)) if (!IS_ERR(priv->clk))
......
...@@ -8,5 +8,3 @@ obj-$(CONFIG_CAN_GS_USB) += gs_usb.o ...@@ -8,5 +8,3 @@ obj-$(CONFIG_CAN_GS_USB) += gs_usb.o
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o
obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/ obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/
obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册