Commit 886ab57c authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-3.15-20140212' of git://gitorious.org/linux-can/linux-can-next

linux-can-next-for-3.15-20140212

Marc Kleine-Budde says:

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

Florian Vaussard contributed a series that merged the sja1000 of_platform
into the platform driver. The of_platform driver is finally removed.
Stephane Grosjean supplied a patch to allocate CANFD skbs. In a patch
by Uwe Kleine-König another missing copyright information was added to
a userspace header. And a patch by Yoann DI RUZZA that adds listen only
mode to the at91_can driver.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3410f22e 17a50ee4
...@@ -12,6 +12,10 @@ Required properties: ...@@ -12,6 +12,10 @@ Required properties:
Optional properties: Optional properties:
- reg-io-width : Specify the size (in bytes) of the IO accesses that
should be performed on the device. Valid value is 1, 2 or 4.
Default to 1 (8 bits).
- nxp,external-clock-frequency : Frequency of the external oscillator - nxp,external-clock-frequency : Frequency of the external oscillator
clock in Hz. Note that the internal clock frequency used by the clock in Hz. Note that the internal clock frequency used by the
SJA1000 is half of that value. If not specified, a default value SJA1000 is half of that value. If not specified, a default value
......
...@@ -420,7 +420,11 @@ static void at91_chip_start(struct net_device *dev) ...@@ -420,7 +420,11 @@ static void at91_chip_start(struct net_device *dev)
at91_transceiver_switch(priv, 1); at91_transceiver_switch(priv, 1);
/* enable chip */ /* enable chip */
at91_write(priv, AT91_MR, AT91_MR_CANEN); if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
reg_mr = AT91_MR_CANEN | AT91_MR_ABM;
else
reg_mr = AT91_MR_CANEN;
at91_write(priv, AT91_MR, reg_mr);
priv->can.state = CAN_STATE_ERROR_ACTIVE; priv->can.state = CAN_STATE_ERROR_ACTIVE;
...@@ -1341,7 +1345,8 @@ static int at91_can_probe(struct platform_device *pdev) ...@@ -1341,7 +1345,8 @@ static int at91_can_probe(struct platform_device *pdev)
priv->can.bittiming_const = &at91_bittiming_const; priv->can.bittiming_const = &at91_bittiming_const;
priv->can.do_set_mode = at91_set_mode; priv->can.do_set_mode = at91_set_mode;
priv->can.do_get_berr_counter = at91_get_berr_counter; priv->can.do_get_berr_counter = at91_get_berr_counter;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
CAN_CTRLMODE_LISTENONLY;
priv->dev = dev; priv->dev = dev;
priv->reg_base = addr; priv->reg_base = addr;
priv->devtype_data = *devtype_data; priv->devtype_data = *devtype_data;
......
...@@ -512,6 +512,30 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) ...@@ -512,6 +512,30 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
} }
EXPORT_SYMBOL_GPL(alloc_can_skb); EXPORT_SYMBOL_GPL(alloc_can_skb);
struct sk_buff *alloc_canfd_skb(struct net_device *dev,
struct canfd_frame **cfd)
{
struct sk_buff *skb;
skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
sizeof(struct canfd_frame));
if (unlikely(!skb))
return NULL;
skb->protocol = htons(ETH_P_CANFD);
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
*cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame));
memset(*cfd, 0, sizeof(struct canfd_frame));
return skb;
}
EXPORT_SYMBOL_GPL(alloc_canfd_skb);
struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
{ {
struct sk_buff *skb; struct sk_buff *skb;
......
...@@ -17,16 +17,9 @@ config CAN_SJA1000_PLATFORM ...@@ -17,16 +17,9 @@ config CAN_SJA1000_PLATFORM
the "platform bus" (Linux abstraction for directly to the the "platform bus" (Linux abstraction for directly to the
processor attached devices). Which can be found on various processor attached devices). Which can be found on various
boards from Phytec (http://www.phytec.de) like the PCM027, boards from Phytec (http://www.phytec.de) like the PCM027,
PCM038. PCM038. It also provides the OpenFirmware "platform bus" found
on embedded systems with OpenFirmware bindings, e.g. if you
config CAN_SJA1000_OF_PLATFORM have a PowerPC based system you may want to enable this option.
tristate "Generic OF Platform Bus based SJA1000 driver"
depends on OF
---help---
This driver adds support for the SJA1000 chips connected to
the OpenFirmware "platform bus" found on embedded systems with
OpenFirmware bindings, e.g. if you have a PowerPC based system
you may want to enable this option.
config CAN_EMS_PCMCIA config CAN_EMS_PCMCIA
tristate "EMS CPC-CARD Card" tristate "EMS CPC-CARD Card"
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
obj-$(CONFIG_CAN_SJA1000) += sja1000.o obj-$(CONFIG_CAN_SJA1000) += sja1000.o
obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o
obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o
obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
......
...@@ -106,8 +106,7 @@ static int sja1000_probe_chip(struct net_device *dev) ...@@ -106,8 +106,7 @@ static int sja1000_probe_chip(struct net_device *dev)
struct sja1000_priv *priv = netdev_priv(dev); struct sja1000_priv *priv = netdev_priv(dev);
if (priv->reg_base && sja1000_is_absent(priv)) { if (priv->reg_base && sja1000_is_absent(priv)) {
printk(KERN_INFO "%s: probing @0x%lX failed\n", netdev_err(dev, "probing failed\n");
DRV_NAME, dev->base_addr);
return 0; return 0;
} }
return -1; return -1;
......
/*
* Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
*
* Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the version 2 of the GNU General Public License
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
* bus found on embedded PowerPC systems. You need a SJA1000 CAN node
* definition in your flattened device tree source (DTS) file similar to:
*
* can@3,100 {
* compatible = "nxp,sja1000";
* reg = <3 0x100 0x80>;
* interrupts = <2 0>;
* interrupt-parent = <&mpic>;
* nxp,external-clock-frequency = <16000000>;
* };
*
* See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further
* information.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/can/dev.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include "sja1000.h"
#define DRV_NAME "sja1000_of_platform"
MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus");
MODULE_LICENSE("GPL v2");
#define SJA1000_OFP_CAN_CLOCK (16000000 / 2)
#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN
#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF)
static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg)
{
return ioread8(priv->reg_base + reg);
}
static void sja1000_ofp_write_reg(const struct sja1000_priv *priv,
int reg, u8 val)
{
iowrite8(val, priv->reg_base + reg);
}
static int sja1000_ofp_remove(struct platform_device *ofdev)
{
struct net_device *dev = platform_get_drvdata(ofdev);
struct sja1000_priv *priv = netdev_priv(dev);
struct device_node *np = ofdev->dev.of_node;
struct resource res;
unregister_sja1000dev(dev);
free_sja1000dev(dev);
iounmap(priv->reg_base);
irq_dispose_mapping(dev->irq);
of_address_to_resource(np, 0, &res);
release_mem_region(res.start, resource_size(&res));
return 0;
}
static int sja1000_ofp_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct net_device *dev;
struct sja1000_priv *priv;
struct resource res;
u32 prop;
int err, irq, res_size;
void __iomem *base;
err = of_address_to_resource(np, 0, &res);
if (err) {
dev_err(&ofdev->dev, "invalid address\n");
return err;
}
res_size = resource_size(&res);
if (!request_mem_region(res.start, res_size, DRV_NAME)) {
dev_err(&ofdev->dev, "couldn't request %pR\n", &res);
return -EBUSY;
}
base = ioremap_nocache(res.start, res_size);
if (!base) {
dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res);
err = -ENOMEM;
goto exit_release_mem;
}
irq = irq_of_parse_and_map(np, 0);
if (irq == 0) {
dev_err(&ofdev->dev, "no irq found\n");
err = -ENODEV;
goto exit_unmap_mem;
}
dev = alloc_sja1000dev(0);
if (!dev) {
err = -ENOMEM;
goto exit_dispose_irq;
}
priv = netdev_priv(dev);
priv->read_reg = sja1000_ofp_read_reg;
priv->write_reg = sja1000_ofp_write_reg;
err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop);
if (!err)
priv->can.clock.freq = prop / 2;
else
priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
err = of_property_read_u32(np, "nxp,tx-output-mode", &prop);
if (!err)
priv->ocr |= prop & OCR_MODE_MASK;
else
priv->ocr |= OCR_MODE_NORMAL; /* default */
err = of_property_read_u32(np, "nxp,tx-output-config", &prop);
if (!err)
priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
else
priv->ocr |= OCR_TX0_PULLDOWN; /* default */
err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop);
if (!err && prop) {
u32 divider = priv->can.clock.freq * 2 / prop;
if (divider > 1)
priv->cdr |= divider / 2 - 1;
else
priv->cdr |= CDR_CLKOUT_MASK;
} else {
priv->cdr |= CDR_CLK_OFF; /* default */
}
if (!of_property_read_bool(np, "nxp,no-comparator-bypass"))
priv->cdr |= CDR_CBP; /* default */
priv->irq_flags = IRQF_SHARED;
priv->reg_base = base;
dev->irq = irq;
dev_info(&ofdev->dev,
"reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n",
priv->reg_base, dev->irq, priv->can.clock.freq,
priv->ocr, priv->cdr);
platform_set_drvdata(ofdev, dev);
SET_NETDEV_DEV(dev, &ofdev->dev);
err = register_sja1000dev(dev);
if (err) {
dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
DRV_NAME, err);
goto exit_free_sja1000;
}
return 0;
exit_free_sja1000:
free_sja1000dev(dev);
exit_dispose_irq:
irq_dispose_mapping(irq);
exit_unmap_mem:
iounmap(base);
exit_release_mem:
release_mem_region(res.start, res_size);
return err;
}
static struct of_device_id sja1000_ofp_table[] = {
{.compatible = "nxp,sja1000"},
{},
};
MODULE_DEVICE_TABLE(of, sja1000_ofp_table);
static struct platform_driver sja1000_ofp_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DRV_NAME,
.of_match_table = sja1000_ofp_table,
},
.probe = sja1000_ofp_probe,
.remove = sja1000_ofp_remove,
};
module_platform_driver(sja1000_ofp_driver);
...@@ -26,12 +26,16 @@ ...@@ -26,12 +26,16 @@
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/can/platform/sja1000.h> #include <linux/can/platform/sja1000.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include "sja1000.h" #include "sja1000.h"
#define DRV_NAME "sja1000_platform" #define DRV_NAME "sja1000_platform"
#define SP_CAN_CLOCK (16000000 / 2)
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
MODULE_ALIAS("platform:" DRV_NAME); MODULE_ALIAS("platform:" DRV_NAME);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -66,59 +70,16 @@ static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val) ...@@ -66,59 +70,16 @@ static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val)
iowrite8(val, priv->reg_base + reg * 4); iowrite8(val, priv->reg_base + reg * 4);
} }
static int sp_probe(struct platform_device *pdev) static void sp_populate(struct sja1000_priv *priv,
struct sja1000_platform_data *pdata,
unsigned long resource_mem_flags)
{ {
int err;
void __iomem *addr;
struct net_device *dev;
struct sja1000_priv *priv;
struct resource *res_mem, *res_irq;
struct sja1000_platform_data *pdata;
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "No platform data provided!\n");
err = -ENODEV;
goto exit;
}
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res_mem || !res_irq) {
err = -ENODEV;
goto exit;
}
if (!request_mem_region(res_mem->start, resource_size(res_mem),
DRV_NAME)) {
err = -EBUSY;
goto exit;
}
addr = ioremap_nocache(res_mem->start, resource_size(res_mem));
if (!addr) {
err = -ENOMEM;
goto exit_release;
}
dev = alloc_sja1000dev(0);
if (!dev) {
err = -ENOMEM;
goto exit_iounmap;
}
priv = netdev_priv(dev);
dev->irq = res_irq->start;
priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
priv->irq_flags |= IRQF_SHARED;
priv->reg_base = addr;
/* The CAN clock frequency is half the oscillator clock frequency */ /* The CAN clock frequency is half the oscillator clock frequency */
priv->can.clock.freq = pdata->osc_freq / 2; priv->can.clock.freq = pdata->osc_freq / 2;
priv->ocr = pdata->ocr; priv->ocr = pdata->ocr;
priv->cdr = pdata->cdr; priv->cdr = pdata->cdr;
switch (res_mem->flags & IORESOURCE_MEM_TYPE_MASK) { switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) {
case IORESOURCE_MEM_32BIT: case IORESOURCE_MEM_32BIT:
priv->read_reg = sp_read_reg32; priv->read_reg = sp_read_reg32;
priv->write_reg = sp_write_reg32; priv->write_reg = sp_write_reg32;
...@@ -133,6 +94,124 @@ static int sp_probe(struct platform_device *pdev) ...@@ -133,6 +94,124 @@ static int sp_probe(struct platform_device *pdev)
priv->write_reg = sp_write_reg8; priv->write_reg = sp_write_reg8;
break; break;
} }
}
static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
{
int err;
u32 prop;
err = of_property_read_u32(of, "reg-io-width", &prop);
if (err)
prop = 1; /* 8 bit is default */
switch (prop) {
case 4:
priv->read_reg = sp_read_reg32;
priv->write_reg = sp_write_reg32;
break;
case 2:
priv->read_reg = sp_read_reg16;
priv->write_reg = sp_write_reg16;
break;
case 1: /* fallthrough */
default:
priv->read_reg = sp_read_reg8;
priv->write_reg = sp_write_reg8;
}
err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop);
if (!err)
priv->can.clock.freq = prop / 2;
else
priv->can.clock.freq = SP_CAN_CLOCK; /* default */
err = of_property_read_u32(of, "nxp,tx-output-mode", &prop);
if (!err)
priv->ocr |= prop & OCR_MODE_MASK;
else
priv->ocr |= OCR_MODE_NORMAL; /* default */
err = of_property_read_u32(of, "nxp,tx-output-config", &prop);
if (!err)
priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
else
priv->ocr |= OCR_TX0_PULLDOWN; /* default */
err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop);
if (!err && prop) {
u32 divider = priv->can.clock.freq * 2 / prop;
if (divider > 1)
priv->cdr |= divider / 2 - 1;
else
priv->cdr |= CDR_CLKOUT_MASK;
} else {
priv->cdr |= CDR_CLK_OFF; /* default */
}
if (!of_property_read_bool(of, "nxp,no-comparator-bypass"))
priv->cdr |= CDR_CBP; /* default */
}
static int sp_probe(struct platform_device *pdev)
{
int err, irq = 0;
void __iomem *addr;
struct net_device *dev;
struct sja1000_priv *priv;
struct resource *res_mem, *res_irq = NULL;
struct sja1000_platform_data *pdata;
struct device_node *of = pdev->dev.of_node;
pdata = dev_get_platdata(&pdev->dev);
if (!pdata && !of) {
dev_err(&pdev->dev, "No platform data provided!\n");
return -ENODEV;
}
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res_mem)
return -ENODEV;
if (!devm_request_mem_region(&pdev->dev, res_mem->start,
resource_size(res_mem), DRV_NAME))
return -EBUSY;
addr = devm_ioremap_nocache(&pdev->dev, res_mem->start,
resource_size(res_mem));
if (!addr)
return -ENOMEM;
if (of)
irq = irq_of_parse_and_map(of, 0);
else
res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq && !res_irq)
return -ENODEV;
dev = alloc_sja1000dev(0);
if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
if (res_irq) {
irq = res_irq->start;
priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
priv->irq_flags |= IRQF_SHARED;
} else {
priv->irq_flags = IRQF_SHARED;
}
dev->irq = irq;
priv->reg_base = addr;
if (of)
sp_populate_of(priv, of);
else
sp_populate(priv, pdata, res_mem->flags);
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
...@@ -150,39 +229,32 @@ static int sp_probe(struct platform_device *pdev) ...@@ -150,39 +229,32 @@ static int sp_probe(struct platform_device *pdev)
exit_free: exit_free:
free_sja1000dev(dev); free_sja1000dev(dev);
exit_iounmap:
iounmap(addr);
exit_release:
release_mem_region(res_mem->start, resource_size(res_mem));
exit:
return err; return err;
} }
static int sp_remove(struct platform_device *pdev) static int sp_remove(struct platform_device *pdev)
{ {
struct net_device *dev = platform_get_drvdata(pdev); struct net_device *dev = platform_get_drvdata(pdev);
struct sja1000_priv *priv = netdev_priv(dev);
struct resource *res;
unregister_sja1000dev(dev); unregister_sja1000dev(dev);
if (priv->reg_base)
iounmap(priv->reg_base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
free_sja1000dev(dev); free_sja1000dev(dev);
return 0; return 0;
} }
static struct of_device_id sp_of_table[] = {
{.compatible = "nxp,sja1000"},
{},
};
MODULE_DEVICE_TABLE(of, sp_of_table);
static struct platform_driver sp_driver = { static struct platform_driver sp_driver = {
.probe = sp_probe, .probe = sp_probe,
.remove = sp_remove, .remove = sp_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = sp_of_table,
}, },
}; };
......
...@@ -124,6 +124,8 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); ...@@ -124,6 +124,8 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
void can_free_echo_skb(struct net_device *dev, unsigned int idx); void can_free_echo_skb(struct net_device *dev, unsigned int idx);
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf); struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
struct sk_buff *alloc_canfd_skb(struct net_device *dev,
struct canfd_frame **cfd);
struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct sk_buff *alloc_can_err_skb(struct net_device *dev,
struct can_frame **cf); struct can_frame **cf);
......
...@@ -8,6 +8,38 @@ ...@@ -8,6 +8,38 @@
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Volkswagen nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* Alternatively, provided that this notice is retained in full, this
* software may be distributed under the terms of the GNU General
* Public License ("GPL") version 2, in which case the provisions of the
* GPL apply INSTEAD OF those given above.
*
* The provided data structures and external interfaces from this code
* are not restricted to be used by modules with a GPL compatible license.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/ */
#ifndef CAN_H #ifndef CAN_H
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment