Skip to content

Commit

Permalink
Merge tag 'linux-can-next-for-3.16-20140425' of git://gitorious.org/l…
Browse files Browse the repository at this point in the history
…inux-can/linux-can-next

Marc Kleine-Budde says:

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

It consists of three patches by Alexander Shiyan, which improve the
mcp251x driver. Stefano Babic's patch move the SPI driver into a sub
folder. The three patches by Olivier Sobrie add support for the Kvaser
Leaf v2 and usb mini PCIe hardware to the existing driver. Alexander
Stein contributes eg20t support to the c_can pci driver. Together with
the patches on the net-tree, we'll be able to remove the pch_can driver
soon. Kurt Van Dijck's two patches clean up the sysfs attributes of the
softing driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 26, 2014
2 parents 16b4630 + 0f8dced commit 98a20b7
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 95 deletions.
8 changes: 2 additions & 6 deletions drivers/net/can/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ config CAN_TI_HECC
Driver for TI HECC (High End CAN Controller) module found on many
TI devices. The device specifications are available from www.ti.com

config CAN_MCP251X
tristate "Microchip MCP251x SPI CAN controllers"
depends on SPI && HAS_DMA
---help---
Driver for the Microchip MCP251x SPI CAN controllers.

config CAN_BFIN
depends on BF534 || BF536 || BF537 || BF538 || BF539 || BF54x
tristate "Analog Devices Blackfin on-chip CAN"
Expand Down Expand Up @@ -133,6 +127,8 @@ source "drivers/net/can/c_can/Kconfig"

source "drivers/net/can/cc770/Kconfig"

source "drivers/net/can/spi/Kconfig"

source "drivers/net/can/usb/Kconfig"

source "drivers/net/can/softing/Kconfig"
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ can-dev-y := dev.o

can-dev-$(CONFIG_CAN_LEDS) += led.o

obj-y += spi/
obj-y += usb/
obj-y += softing/

Expand All @@ -19,7 +20,6 @@ obj-$(CONFIG_CAN_C_CAN) += c_can/
obj-$(CONFIG_CAN_CC770) += cc770/
obj-$(CONFIG_CAN_AT91) += at91_can.o
obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
obj-$(CONFIG_CAN_BFIN) += bfin_can.o
obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
Expand Down
51 changes: 50 additions & 1 deletion drivers/net/can/c_can/c_can_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@

#include "c_can.h"

#define PCI_DEVICE_ID_PCH_CAN 0x8818
#define PCH_PCI_SOFT_RESET 0x01fc

enum c_can_pci_reg_align {
C_CAN_REG_ALIGN_16,
C_CAN_REG_ALIGN_32,
C_CAN_REG_32,
};

struct c_can_pci_data {
Expand All @@ -31,6 +35,10 @@ struct c_can_pci_data {
enum c_can_pci_reg_align reg_align;
/* Set the frequency */
unsigned int freq;
/* PCI bar number */
int bar;
/* Callback for reset */
void (*init)(const struct c_can_priv *priv, bool enable);
};

/*
Expand Down Expand Up @@ -63,6 +71,29 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv,
writew(val, priv->base + 2 * priv->regs[index]);
}

static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv,
enum reg index)
{
return (u16)ioread32(priv->base + 2 * priv->regs[index]);
}

static void c_can_pci_write_reg_32bit(struct c_can_priv *priv,
enum reg index, u16 val)
{
iowrite32((u32)val, priv->base + 2 * priv->regs[index]);
}

static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable)
{
if (enable) {
u32 __iomem *addr = priv->base + PCH_PCI_SOFT_RESET;

/* write to sw reset register */
iowrite32(1, addr);
iowrite32(0, addr);
}
}

static int c_can_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
Expand All @@ -87,7 +118,8 @@ static int c_can_pci_probe(struct pci_dev *pdev,
pci_set_master(pdev);
pci_enable_msi(pdev);

addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
addr = pci_iomap(pdev, c_can_pci_data->bar,
pci_resource_len(pdev, c_can_pci_data->bar));
if (!addr) {
dev_err(&pdev->dev,
"device has no PCI memory resources, "
Expand Down Expand Up @@ -142,11 +174,17 @@ static int c_can_pci_probe(struct pci_dev *pdev,
priv->read_reg = c_can_pci_read_reg_aligned_to_16bit;
priv->write_reg = c_can_pci_write_reg_aligned_to_16bit;
break;
case C_CAN_REG_32:
priv->read_reg = c_can_pci_read_reg_32bit;
priv->write_reg = c_can_pci_write_reg_32bit;
break;
default:
ret = -EINVAL;
goto out_free_c_can;
}

priv->raminit = c_can_pci_data->init;

ret = register_c_can_dev(dev);
if (ret) {
dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
Expand Down Expand Up @@ -193,6 +231,15 @@ static struct c_can_pci_data c_can_sta2x11= {
.type = BOSCH_C_CAN,
.reg_align = C_CAN_REG_ALIGN_32,
.freq = 52000000, /* 52 Mhz */
.bar = 0,
};

static struct c_can_pci_data c_can_pch = {
.type = BOSCH_C_CAN,
.reg_align = C_CAN_REG_32,
.freq = 50000000, /* 50 MHz */
.init = c_can_pci_reset_pch,
.bar = 1,
};

#define C_CAN_ID(_vend, _dev, _driverdata) { \
Expand All @@ -202,6 +249,8 @@ static struct c_can_pci_data c_can_sta2x11= {
static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = {
C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN,
c_can_sta2x11),
C_CAN_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_CAN,
c_can_pch),
{},
};
static struct pci_driver c_can_pci_driver = {
Expand Down
20 changes: 4 additions & 16 deletions drivers/net/can/softing/softing_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,15 +556,6 @@ static int softing_card_boot(struct softing *card)
/*
* netdev sysfs
*/
static ssize_t show_channel(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct net_device *ndev = to_net_dev(dev);
struct softing_priv *priv = netdev2softing(ndev);

return sprintf(buf, "%i\n", priv->index);
}

static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
char *buf)
{
Expand Down Expand Up @@ -609,12 +600,10 @@ static ssize_t store_output(struct device *dev, struct device_attribute *attr,
return count;
}

static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL);
static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output);

static const struct attribute *const netdev_sysfs_attrs[] = {
&dev_attr_channel.attr,
&dev_attr_chip.attr,
&dev_attr_output.attr,
NULL,
Expand Down Expand Up @@ -679,17 +668,20 @@ static int softing_netdev_register(struct net_device *netdev)
{
int ret;

netdev->sysfs_groups[0] = &netdev_sysfs_group;
ret = register_candev(netdev);
if (ret) {
dev_alert(&netdev->dev, "register failed\n");
return ret;
}
if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0)
netdev_alert(netdev, "sysfs group failed\n");

return 0;
}

static void softing_netdev_cleanup(struct net_device *netdev)
{
sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group);
unregister_candev(netdev);
free_candev(netdev);
}
Expand Down Expand Up @@ -721,8 +713,6 @@ DEV_ATTR_RO(firmware_version, id.fw_version);
DEV_ATTR_RO_STR(hardware, pdat->name);
DEV_ATTR_RO(hardware_version, id.hw_version);
DEV_ATTR_RO(license, id.license);
DEV_ATTR_RO(frequency, id.freq);
DEV_ATTR_RO(txpending, tx.pending);

static struct attribute *softing_pdev_attrs[] = {
&dev_attr_serial.attr,
Expand All @@ -731,8 +721,6 @@ static struct attribute *softing_pdev_attrs[] = {
&dev_attr_hardware.attr,
&dev_attr_hardware_version.attr,
&dev_attr_license.attr,
&dev_attr_frequency.attr,
&dev_attr_txpending.attr,
NULL,
};

Expand Down
10 changes: 10 additions & 0 deletions drivers/net/can/spi/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
menu "CAN SPI interfaces"
depends on SPI

config CAN_MCP251X
tristate "Microchip MCP251x SPI CAN controllers"
depends on HAS_DMA
---help---
Driver for the Microchip MCP251x SPI CAN controllers.

endmenu
8 changes: 8 additions & 0 deletions drivers/net/can/spi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# Makefile for the Linux Controller Area Network SPI drivers.
#


obj-$(CONFIG_CAN_MCP251X) += mcp251x.o

ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
93 changes: 45 additions & 48 deletions drivers/net/can/mcp251x.c → drivers/net/can/spi/mcp251x.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@

#define TX_ECHO_SKB_MAX 1

#define MCP251X_OST_DELAY_MS (5)

#define DEVICE_NAME "mcp251x"

static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
Expand Down Expand Up @@ -624,50 +626,45 @@ static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
static int mcp251x_hw_reset(struct spi_device *spi)
{
struct mcp251x_priv *priv = spi_get_drvdata(spi);
u8 reg;
int ret;
unsigned long timeout;

/* Wait for oscillator startup timer after power up */
mdelay(MCP251X_OST_DELAY_MS);

priv->spi_tx_buf[0] = INSTRUCTION_RESET;
ret = spi_write(spi, priv->spi_tx_buf, 1);
if (ret) {
dev_err(&spi->dev, "reset failed: ret = %d\n", ret);
return -EIO;
}
ret = mcp251x_spi_trans(spi, 1);
if (ret)
return ret;

/* Wait for oscillator startup timer after reset */
mdelay(MCP251X_OST_DELAY_MS);

reg = mcp251x_read_reg(spi, CANSTAT);
if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
return -ENODEV;

/* Wait for reset to finish */
timeout = jiffies + HZ;
mdelay(10);
while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK)
!= CANCTRL_REQOP_CONF) {
schedule();
if (time_after(jiffies, timeout)) {
dev_err(&spi->dev, "MCP251x didn't"
" enter in conf mode after reset\n");
return -EBUSY;
}
}
return 0;
}

static int mcp251x_hw_probe(struct spi_device *spi)
{
int st1, st2;
u8 ctrl;
int ret;

mcp251x_hw_reset(spi);
ret = mcp251x_hw_reset(spi);
if (ret)
return ret;

/*
* Please note that these are "magic values" based on after
* reset defaults taken from data sheet which allows us to see
* if we really have a chip on the bus (we avoid common all
* zeroes or all ones situations)
*/
st1 = mcp251x_read_reg(spi, CANSTAT) & 0xEE;
st2 = mcp251x_read_reg(spi, CANCTRL) & 0x17;
ctrl = mcp251x_read_reg(spi, CANCTRL);

dev_dbg(&spi->dev, "CANCTRL 0x%02x\n", ctrl);

dev_dbg(&spi->dev, "CANSTAT 0x%02x CANCTRL 0x%02x\n", st1, st2);
/* Check for power up default value */
if ((ctrl & 0x17) != 0x07)
return -ENODEV;

/* Check for power up default values */
return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
return 0;
}

static int mcp251x_power_enable(struct regulator *reg, int enable)
Expand Down Expand Up @@ -776,7 +773,6 @@ static void mcp251x_restart_work_handler(struct work_struct *ws)

mutex_lock(&priv->mcp_lock);
if (priv->after_suspend) {
mdelay(10);
mcp251x_hw_reset(spi);
mcp251x_setup(net, priv, spi);
if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
Expand Down Expand Up @@ -1032,8 +1028,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
struct net_device *net;
struct mcp251x_priv *priv;
int freq, ret = -ENODEV;
struct clk *clk;
int freq, ret;

clk = devm_clk_get(&spi->dev, NULL);
if (IS_ERR(clk)) {
Expand Down Expand Up @@ -1076,6 +1072,18 @@ static int mcp251x_can_probe(struct spi_device *spi)
priv->net = net;
priv->clk = clk;

spi_set_drvdata(spi, priv);

/* Configure the SPI bus */
spi->bits_per_word = 8;
if (mcp251x_is_2510(spi))
spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
else
spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
ret = spi_setup(spi);
if (ret)
goto out_clk;

priv->power = devm_regulator_get(&spi->dev, "vdd");
priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
Expand All @@ -1088,8 +1096,6 @@ static int mcp251x_can_probe(struct spi_device *spi)
if (ret)
goto out_clk;

spi_set_drvdata(spi, priv);

priv->spi = spi;
mutex_init(&priv->mcp_lock);

Expand Down Expand Up @@ -1134,20 +1140,11 @@ static int mcp251x_can_probe(struct spi_device *spi)

SET_NETDEV_DEV(net, &spi->dev);

/* Configure the SPI bus */
spi->mode = spi->mode ? : SPI_MODE_0;
if (mcp251x_is_2510(spi))
spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
else
spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
spi->bits_per_word = 8;
spi_setup(spi);

/* Here is OK to not lock the MCP, no one knows about it yet */
if (!mcp251x_hw_probe(spi)) {
ret = -ENODEV;
ret = mcp251x_hw_probe(spi);
if (ret)
goto error_probe;
}

mcp251x_hw_sleep(spi);

ret = register_candev(net);
Expand All @@ -1156,7 +1153,7 @@ static int mcp251x_can_probe(struct spi_device *spi)

devm_can_led_init(net);

return ret;
return 0;

error_probe:
if (mcp251x_enable_dma)
Expand Down
Loading

0 comments on commit 98a20b7

Please sign in to comment.