diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2009-07-01 10:45:20 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2009-07-01 10:45:20 +0200 |
commit | fd4fc6d45170c30cfb6c11cc7fda7b12c0a5ce54 (patch) | |
tree | 1b4a9c3be917831c9c826981febe76011e7f3417 | |
parent | cb5cb5b32ea035557a03e599a1fc9ea6b74d96d8 (diff) | |
download | linux-2.6-fd4fc6d45170c30cfb6c11cc7fda7b12c0a5ce54.tar.gz linux-2.6-fd4fc6d45170c30cfb6c11cc7fda7b12c0a5ce54.tar.xz |
Remove old CAN support
only keep mainline and the drivers we need for phytec
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | arch/arm/mach-at91/at91sam9263_devices.c | 36 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-sam9263ek.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/board.h | 6 | ||||
-rw-r--r-- | drivers/net/can/at91_can.c | 1189 | ||||
-rw-r--r-- | drivers/net/can/mscan/Makefile | 7 | ||||
-rw-r--r-- | drivers/net/can/mscan/mpc52xx_can.c | 245 | ||||
-rw-r--r-- | drivers/net/can/mscan/mscan.c | 717 | ||||
-rw-r--r-- | drivers/net/can/mscan/mscan.h | 247 | ||||
-rw-r--r-- | drivers/net/can/sja1000/ixxat_pci.c | 272 | ||||
-rw-r--r-- | drivers/net/can/sja1000/peak_pci.c | 348 | ||||
-rw-r--r-- | drivers/net/can/sja1000/pipcan.c | 199 | ||||
-rw-r--r-- | drivers/net/can/sysfs.c | 509 | ||||
-rw-r--r-- | drivers/net/can/sysfs.h | 24 | ||||
-rw-r--r-- | include/linux/can/sja1000_platform.h | 11 |
14 files changed, 0 insertions, 3829 deletions
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 6026c2e0d5c..b7f23324231 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -757,42 +757,6 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} #endif -/* -------------------------------------------------------------------- - * CAN Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE) -static struct resource can_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_CAN, - .end = AT91SAM9263_BASE_CAN + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9263_ID_CAN, - .end = AT91SAM9263_ID_CAN, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_can_device = { - .name = "at91_can", - .id = -1, - .resource = can_resources, - .num_resources = ARRAY_SIZE(can_resources), -}; - -void __init at91_add_device_can(struct at91_can_data *data) -{ - at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */ - at91sam9263_can_device.dev.platform_data = data; - - platform_device_register(&at91sam9263_can_device); -} -#else -void __init at91_add_device_can(struct at91_can_data *data) {} -#endif /* -------------------------------------------------------------------- * LCD Controller diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index e62c161169c..57d52528f22 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -400,23 +400,6 @@ static struct gpio_led ek_pwm_led[] = { } }; -/* - * CAN - */ -static void sam9263ek_transceiver_enable(int enable) -{ - if (enable) { - at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */ - at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */ - } else { - at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */ - at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */ - } -} - -static struct at91_can_data ek_can_data = { - .transceiver_enable = sam9263ek_transceiver_enable, -}; static void __init ek_board_init(void) { @@ -448,8 +431,6 @@ static void __init ek_board_init(void) /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); - /* CAN */ - at91_add_device_can(&ek_can_data); } MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 2b3bd70631b..e6afff849b8 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -179,12 +179,6 @@ extern void __init at91_add_device_isi(void); /* Touchscreen Controller */ extern void __init at91_add_device_tsadcc(void); -/* CAN */ -struct at91_can_data { - void (*transceiver_enable)(int enable); -}; -extern void __init at91_add_device_can(struct at91_can_data *data); - /* LEDs */ extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c deleted file mode 100644 index eaafbc59959..00000000000 --- a/drivers/net/can/at91_can.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * at91_can.c - CAN network driver for AT91 SoC CAN controller - * - * (C) 2007 by Hans J. Koch <hjk@linutronix.de> - * (C) 2008 by Marc Kleine-Budde <kernel@pengutronix.de> - * - * This software may be distributed under the terms of the GNU General - * Public License ("GPL") version 2 as distributed in the 'COPYING' - * file from the main directory of the linux kernel source. - * - * Send feedback to <socketcan-users@lists.berlios.de> - * - */ - -//#define DEBUG - -#include <linux/can.h> -#include <linux/clk.h> -#include <linux/errno.h> -#include <linux/if_arp.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/platform_device.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/version.h> - -#include <linux/can/dev.h> - -#include <mach/board.h> - -#define DRV_NAME "at91_can" -#define MAX_INTERRUPT_WORK 4 - -/* - * RX/TX Mailbox split - * don't dare to touch - */ -#define AT91_MB_RX_NUM 12 -#define AT91_MB_TX_SHIFT 2 - -#define AT91_MB_RX_FIRST 0 -#define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) -#define AT91_MB_RX_BANKS 3 -#define AT91_MB_RX_BANK_WIDTH (AT91_MB_RX_NUM / AT91_MB_RX_BANKS) -#define AT91_MB_RX_BANK_MASK(i) (((1 << AT91_MB_RX_BANK_WIDTH) - 1) << \ - (AT91_MB_RX_BANK_WIDTH * (i))) - -#define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) -#define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) -#define AT91_MB_TX_LAST (AT91_MB_TX_FIRST + AT91_MB_TX_NUM - 1) - - -/* Common registers */ -enum at91_reg { - AT91_MR = 0x000, - AT91_IER = 0x004, - AT91_IDR = 0x008, - AT91_IMR = 0x00C, - AT91_SR = 0x010, - AT91_BR = 0x014, - AT91_TIM = 0x018, - AT91_TIMESTP = 0x01C, - AT91_ECR = 0x020, - AT91_TCR = 0x024, - AT91_ACR = 0x028, -}; - -/* Mailbox registers (0 <= i <= 15) */ -#define AT91_MMR(i) (enum at91_reg)(0x200 + ((i) * 0x20)) -#define AT91_MAM(i) (enum at91_reg)(0x204 + ((i) * 0x20)) -#define AT91_MID(i) (enum at91_reg)(0x208 + ((i) * 0x20)) -#define AT91_MFID(i) (enum at91_reg)(0x20C + ((i) * 0x20)) -#define AT91_MSR(i) (enum at91_reg)(0x210 + ((i) * 0x20)) -#define AT91_MDL(i) (enum at91_reg)(0x214 + ((i) * 0x20)) -#define AT91_MDH(i) (enum at91_reg)(0x218 + ((i) * 0x20)) -#define AT91_MCR(i) (enum at91_reg)(0x21C + ((i) * 0x20)) - -/* Register bits */ -#define AT91_MR_AT91EN (1 << 0) -#define AT91_MR_LPM (1 << 1) -#define AT91_MR_ABM (1 << 2) -#define AT91_MR_OVL (1 << 3) -#define AT91_MR_TEOF (1 << 4) -#define AT91_MR_TTM (1 << 5) -#define AT91_MR_TIMFRZ (1 << 6) -#define AT91_MR_DRPT (1 << 7) - -#define AT91_SR_RBSY (1 << 29) - -#define AT91_MMR_PRIO_SHIFT 16 - -#define AT91_MID_MIDE (1 << 29) - -#define AT91_MSR_MRTR (1 << 20) -#define AT91_MSR_MABT (1 << 22) -#define AT91_MSR_MRDY (1 << 23) -#define AT91_MSR_MMI (1 << 24) - -#define AT91_MCR_MRTR (1 << 20) -#define AT91_MCR_MTCR (1 << 23) - -/* Mailbox Modes */ -enum at91_mb_mode { - AT91_MB_MODE_DISABLED = 0, - AT91_MB_MODE_RX = 1, - AT91_MB_MODE_RX_OVRWR = 2, - AT91_MB_MODE_TX = 3, - AT91_MB_MODE_CONSUMER = 4, - AT91_MB_MODE_PRODUCER = 5, -}; - -/* Interrupt mask bits */ -#define AT91_IRQ_MB_RX ((1 << (AT91_MB_RX_LAST + 1)) - (1 << AT91_MB_RX_FIRST)) -#define AT91_IRQ_MB_TX ((1 << (AT91_MB_TX_LAST + 1)) - (1 << AT91_MB_TX_FIRST)) -#define AT91_IRQ_MB_ALL (AT91_IRQ_MB_RX | AT91_IRQ_MB_TX) - -#define AT91_IRQ_ERRA (1 << 16) -#define AT91_IRQ_WARN (1 << 17) -#define AT91_IRQ_ERRP (1 << 18) -#define AT91_IRQ_BOFF (1 << 19) -#define AT91_IRQ_SLEEP (1 << 20) -#define AT91_IRQ_WAKEUP (1 << 21) -#define AT91_IRQ_TOVF (1 << 22) -#define AT91_IRQ_TSTP (1 << 23) -#define AT91_IRQ_CERR (1 << 24) -#define AT91_IRQ_SERR (1 << 25) -#define AT91_IRQ_AERR (1 << 26) -#define AT91_IRQ_FERR (1 << 27) -#define AT91_IRQ_BERR (1 << 28) - -#define AT91_IRQ_ERR_ALL 0x1fff0000 -#define AT91_IRQ_ERR_CANFRAME (AT91_IRQ_CERR | AT91_IRQ_SERR | \ - AT91_IRQ_AERR | AT91_IRQ_FERR | AT91_IRQ_BERR) -#define AT91_IRQ_ERR_LINE (AT91_IRQ_ERRA | AT91_IRQ_WARN | \ - AT91_IRQ_ERRP |AT91_IRQ_BOFF) - -struct at91_priv { - struct can_priv can; /* must be the first member! */ - - struct clk *clk; - struct at91_can_data *pdata; - -#define AT91_NEXT_PRIO_SHIFT (AT91_MB_TX_SHIFT) -#define AT91_NEXT_PRIO_MASK (0xf << AT91_MB_TX_SHIFT) -#define AT91_NEXT_MB_MASK (AT91_MB_TX_NUM - 1) -#define AT91_NEXT_MASK ((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK) - unsigned int tx_next; - unsigned int tx_echo; - - unsigned int rx_bank; -}; - - -static inline int get_tx_next_mb(struct at91_priv *priv) -{ - return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; -} - -static inline int get_tx_next_prio(struct at91_priv *priv) -{ - return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf; -} - -static inline int get_tx_echo_mb(struct at91_priv *priv) -{ - return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; -} - - -static inline u32 at91_read(struct net_device *ndev, enum at91_reg reg) -{ - return readl((void __iomem *)ndev->base_addr + reg); -} - -static inline void -at91_write(struct net_device *ndev, enum at91_reg reg, u32 value) -{ - writel(value, (void __iomem *)ndev->base_addr + reg); -} - - -static inline void -set_mb_mode_prio(struct net_device *ndev, int mb, enum at91_mb_mode mode, int prio) -{ - at91_write(ndev, AT91_MMR(mb), - (mode << 24) | - (prio << 16)); -} - -static inline void -set_mb_mode(struct net_device *ndev, int mb, enum at91_mb_mode mode) -{ - set_mb_mode_prio(ndev, mb, mode, 0); -} - - -/* - * Enable or disable transceiver - */ -static void enable_can_transceiver(struct at91_priv *priv, int enable) -{ - if (priv->pdata && priv->pdata->transceiver_enable) - priv->pdata->transceiver_enable(enable); -} - - - -/* - * theory of operation: - * - * Accoring to the datasheet priority 0 is the highest priority, 15 is - * the lowest. If two mailboxes have the same priority level the - * message of the mailbox with the lowest number is sent first. - * - * We use the first TX mailbox mailbox (AT91_MB_TX_FIRST) with prio 0, - * then the next mailbox with prio 0, and so on, until all mailboxes - * are used. Then we start from the beginning with mailbox - * AT91_MB_TX_FIRST, but with prio 1, mailbox AT91_MB_TX_FIRST + 1 - * prio 1. When we reach the last mailbox with prio 15, we have to - * stop sending, waiting for all messages to be delivered, than start - * again with mailbox AT91_MB_TX_FIRST prio 0. - * - * We use the priv->tx_next as counter for the next transmission - * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits - * encode the mailbox number, the upper 4 bits the mailbox priority: - * - * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) || - * (mb - AT91_MB_TX_FIRST); - * - */ -static int at91_start_xmit(struct sk_buff *skb, struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - struct net_device_stats *stats = &ndev->stats; - struct can_frame *cf = (struct can_frame *)skb->data; - u32 reg_mid, reg_mcr; - int mb, prio; - - mb = get_tx_next_mb(priv); - prio = get_tx_next_prio(priv); - - if (!(at91_read(ndev, AT91_MSR(mb)) & AT91_MSR_MRDY)) { - BUG(); - /* FIXME: kfree? stats? */ - return -EBUSY; - } - - if (cf->can_id & CAN_EFF_FLAG) - reg_mid = (cf->can_id & CAN_EFF_MASK) | AT91_MID_MIDE; - else - reg_mid = (cf->can_id & CAN_SFF_MASK) << 18; - - reg_mcr = (cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0 | - (cf->can_dlc << 16) | - AT91_MCR_MTCR; - - /* disable MB while writing ID (see datasheet) */ - set_mb_mode(ndev, mb, AT91_MB_MODE_DISABLED); - at91_write(ndev, AT91_MID(mb), reg_mid); - set_mb_mode_prio(ndev, mb, AT91_MB_MODE_TX, prio); - - at91_write(ndev, AT91_MDL(mb), *(u32 *)(cf->data + 0)); - at91_write(ndev, AT91_MDH(mb), *(u32 *)(cf->data + 4)); - - /* This triggers transmission */ - wmb(); - at91_write(ndev, AT91_MCR(mb), reg_mcr); - - stats->tx_bytes += cf->can_dlc; - ndev->trans_start = jiffies; - - /* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */ - can_put_echo_skb(skb, ndev, mb - AT91_MB_TX_FIRST); - - /* - * we have to stop the queue and deliver all messages in case - * of a prio+mb counter wrap around. This is the case if - * tx_next buffer prio and mailbox equals 0. - * - * also stop the queue if next buffer is still in use - * (== not ready) - */ - priv->tx_next++; - if (!(at91_read(ndev, AT91_MSR(get_tx_next_mb(priv))) & - AT91_MSR_MRDY) || - (priv->tx_next & AT91_NEXT_MASK) == 0) { - netif_stop_queue(ndev); - dev_dbg(ND2D(ndev), - "stopping netif_queue, priv->tx_next=%d, prio=%d, mb=%d\n", - priv->tx_next, - get_tx_next_prio(priv), - get_tx_next_mb(priv)); - } - - /* Enable interrupt for this mailbox */ - at91_write(ndev, AT91_IER, 1 << mb); - - return 0; -} - - -/** - * at91_clear_bank - clear and reactive bank - * @ndev: net device - * @bank: bank to clear - * - * Clears and reenables IRQs on given bank in order to enable - * reception of new CAN messages - */ -static void at91_clear_bank(struct net_device *ndev, int bank) -{ - int last, i; - u32 mask; - - last = AT91_MB_RX_BANK_WIDTH * (bank + 1); - for (i = AT91_MB_RX_BANK_WIDTH * bank; i < last; i++) - at91_write(ndev, AT91_MCR(i), AT91_MCR_MTCR); - - mask = AT91_MB_RX_BANK_MASK(bank); - at91_write(ndev, AT91_IER, mask); -} - - -/** - * at91_read_mb - read CAN msg from mailbox (lowlevel impl) - * @ndev: net device - * @mb: mailbox number to read from - * @cf: can frame where to store message - * - * Reads a CAN message from the giben mailbox and stores data into - * given can frame. "mb" and "cf" must be valid. - */ -static void at91_read_mb(struct net_device *ndev, int mb, struct can_frame *cf) -{ - u32 reg_msr, reg_mid, reg_mdl, reg_mdh; - - reg_mid = at91_read(ndev, AT91_MID(mb)); - if (reg_mid & AT91_MID_MIDE) - cf->can_id = ((reg_mid >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; - else - cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK; - - reg_msr = at91_read(ndev, AT91_MSR(mb)); - if (reg_msr & AT91_MSR_MRTR) - cf->can_id |= CAN_RTR_FLAG; - cf->can_dlc = (reg_msr >> 16) & 0xf; - - reg_mdl = at91_read(ndev, AT91_MDL(mb)); - reg_mdh = at91_read(ndev, AT91_MDH(mb)); - - *(u32 *)(cf->data + 0) = reg_mdl; - *(u32 *)(cf->data + 4) = reg_mdh; - - /* FIXME: take care about AT91_MB_MODE_RX_OVRWR mb */ -} - - -/** - * at91_read_msg - read CAN message from mailbox - * @ndev: net device - * @mb: mail box to read from - * - * Reads a CAN mesage from given mailbox, and put into linux network - * RX queue, does all housekeeping chores (stats, ...) - */ -static void at91_read_msg(struct net_device *ndev, int mb) -{ - struct net_device_stats *stats = &ndev->stats; - struct can_frame *cf; - struct sk_buff *skb; - - skb = netdev_alloc_skb(ndev, sizeof(struct can_frame)); - if (unlikely(!skb)) { - if (net_ratelimit()) - dev_warn(ND2D(ndev), - "Memory squeeze, dropping packet.\n"); - stats->rx_dropped++; - return; - } - skb->protocol = htons(ETH_P_CAN); - cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); - - at91_read_mb(ndev, mb, cf); - - netif_rx(skb); - - ndev->last_rx = jiffies; - stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; -} - - -/* - * theory of operation - * - * 12 of the 16 mailboxes on the chip are reserved for RX. we split - * them into 3 groups (3 x 4 mbs) a.k.a banks. - * - * like it or not, but the chip always saves a received CAN message - * into the first fres mailbox it finds. This makes it very difficult - * to read the messages in the right order from the chip. this is how - * we work around that problem: - * - * The first message goes into mb nr. 0 and issues an interrupt. We - * read it, do _not_ reenable the mb (to receive another message), but - * disable the interrupt though. This is done for the first bank - * (i.e. mailbox 0-3). - * - * bank0 bank1 bank2 - * __^__ __^__ __^__ - * / \ / \ / \ - * +-+-+-+-++-+-+-+-++-+-+-+-+ - * |x|x|x|x|| | | | || | | | | - * +-+-+-+-++-+-+-+-++-+-+-+-+ - * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail - * 0 1 2 3 4 5 6 7 8 9 0 1 / box - * - * Then we switch to bank 1. If this bank is full, too, we reenable - * bank numer 0, and switch to bank 2. imagine bank 2 like an overflow - * bank, which takes CAN messages if bank 1 is full, but bank 0 not - * cleared yet. in other words: from the reception of a message into - * mb 07, we have the "four mailboxes" (of bank 2) time to enter the - * interrupt service routine and reenable bank 0. - * - * Nevertheless, after reenabling bank 0, we look at bank 2 first, to - * see if there are some messages. Then we reactivate bank 1 and 2, - * and switch to bank 0. - * - */ -static void at91_irq_rx(struct net_device *ndev, u32 reg_sr) -{ - struct at91_priv *priv = netdev_priv(ndev); - unsigned long *addr = (unsigned long *)®_sr; - int mb; - - /* masking of reg_sr not needed, already done by at91_irq */ - - mb = find_next_bit(addr, AT91_MB_RX_NUM, - AT91_MB_RX_BANK_WIDTH * priv->rx_bank); - while (mb < AT91_MB_RX_NUM) { - dev_dbg(ND2D(ndev), - "%s: SR=0x%08x, mb=%d, mb_bit=0x%04x, rx_bank=%d\n", - __func__, reg_sr, mb, 1 << mb, priv->rx_bank); - - at91_read_msg(ndev, mb); - - /* disable interrupt */ - at91_write(ndev, AT91_IDR, 1 << mb); - - /* find next pending mailbox */ - mb = find_next_bit(addr, AT91_MB_RX_NUM, mb + 1); - } - - switch (priv->rx_bank) { - case 0: - if (!(at91_read(ndev, AT91_IMR) & AT91_MB_RX_BANK_MASK(0))) - priv->rx_bank = 1; - break; - case 1: - if (!(at91_read(ndev, AT91_IMR) & AT91_MB_RX_BANK_MASK(1))) { -/* printk("..oo\n"); */ - at91_clear_bank(ndev, 0); - priv->rx_bank = 2; - } - break; - case 2: - at91_clear_bank(ndev, 1); - at91_clear_bank(ndev, 2); - priv->rx_bank = 0; - break; - } -} - - -static void at91_tx_timeout(struct net_device *ndev) -{ - ndev->stats.tx_errors++; - dev_dbg(ND2D(ndev), "TX timeout!\n"); -} - - -/* - * theory of operation: - * - * priv->tx_echo holds the number of the oldest can_frame put for - * transmission into the hardware, but not yet ACKed by the CAN tx - * complete IRQ. - * - * We iterate from priv->tx_echo to priv->tx_next and check if the - * packet has been transmitted, echo it back to the CAN framework. If - * we discover a not yet transmitted package, stop looking for more. - * - */ -static void at91_irq_tx(struct net_device *ndev, u32 reg_sr) -{ - struct at91_priv *priv = netdev_priv(ndev); - u32 reg_msr; - int mb; - - /* masking of reg_sr not needed, already done by at91_irq */ - - for (/* nix */; priv->tx_echo < priv->tx_next; priv->tx_echo++) { - mb = get_tx_echo_mb(priv); - - /* no event in mailbox? */ - if (!(reg_sr & (1 << mb))) - break; - - reg_msr = at91_read(ndev, AT91_MSR(mb)); - - /* FIXME: BUGON no ready | abort */ - - dev_dbg(ND2D(ndev), - "%s: SR=0x%08x, mb=%d, mb_bit=0x%04x, mb status: %s, tx_next=%d, tx_echo=%d\n", - __func__, reg_sr, mb, 1 << mb, - reg_msr & AT91_MSR_MRDY ? "MRDY" : "MABT", - priv->tx_next, priv->tx_echo); - - /* Disable irq for this TX mailbox */ - at91_write(ndev, AT91_IDR, 1 << mb); - - /* - * only echo if mailbox signals us an transfer - * complete (MSR_MRDY). Otherwise it's an tansfer - * abort. "can_bus_off()" takes care about the skbs - * parked in the echo queue. - */ - if (likely(reg_msr & AT91_MSR_MRDY)) { - /* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */ - can_get_echo_skb(ndev, mb - AT91_MB_TX_FIRST); - ndev->stats.tx_packets++; - } - } - - /* - * restart queue if we don't have a wrap around but restart if - * we get an TX int for the last can frame directly before a - * wrap around. - */ - if ((priv->tx_next & AT91_NEXT_MASK) != 0 || - (priv->tx_echo & AT91_NEXT_MASK) == 0) - netif_wake_queue(ndev); -} - - -static void at91_irq_err_canframe(struct net_device *ndev, u32 reg_sr) -{ - /* CRC error */ - if (reg_sr & AT91_IRQ_CERR) - dev_dbg(ND2D(ndev), "CERR irq\n"); - - /* stuffing error */ - if (reg_sr & AT91_IRQ_SERR) - dev_dbg(ND2D(ndev), "SERR irq\n"); - - /* Acknowledgement error */ - if (reg_sr & AT91_IRQ_AERR) - dev_dbg(ND2D(ndev), "AERR irq\n"); - - /* form error */ - if (reg_sr & AT91_IRQ_FERR) - dev_dbg(ND2D(ndev), "FERR irq\n"); - - /* bit error */ - if (reg_sr & AT91_IRQ_BERR) - dev_dbg(ND2D(ndev), "BERR irq\n"); -} - - -static void at91_irq_err(struct net_device *ndev, u32 reg_sr_masked) -{ - struct at91_priv *priv = netdev_priv(ndev); - enum can_state new_state; - u32 reg_sr, reg_ecr, reg_idr, reg_ier; - u8 tec, rec; - - reg_sr = at91_read(ndev, AT91_SR); - reg_ecr = at91_read(ndev, AT91_ECR); - tec = reg_ecr >> 16; - rec = reg_ecr & 0xff; - - dev_dbg(ND2D(ndev), "%s: TEC=%3d%s, REC=%3d, bits set: %s%s%s%s\n", - __func__, - tec, - reg_sr & AT91_IRQ_BOFF ? " (bus-off!)" : "", - rec, - reg_sr & AT91_IRQ_ERRA ? "ERRA " : "", - reg_sr & AT91_IRQ_WARN ? "WARN " : "", - reg_sr & AT91_IRQ_ERRP ? "ERRP " : "", - reg_sr & AT91_IRQ_BOFF ? "BOFF " : ""); - - /* we need to look at the unmasked reg_sr */ - if (unlikely(reg_sr & AT91_IRQ_BOFF)) - new_state = CAN_STATE_BUS_OFF; - else if (unlikely(reg_sr & AT91_IRQ_ERRP)) - new_state = CAN_STATE_BUS_PASSIVE; - else if (unlikely(reg_sr & AT91_IRQ_WARN)) - new_state = CAN_STATE_BUS_WARNING; - else if (likely(reg_sr & AT91_IRQ_ERRA)) - new_state = CAN_STATE_ACTIVE; - else { - BUG(); /* FIXME */ - return; - } - - /* state hasn't changed, no error in canframe */ - if (new_state == priv->can.state && - !(reg_sr_masked & AT91_IRQ_ERR_CANFRAME)) - return; - - - switch (priv->can.state) { - case CAN_STATE_ACTIVE: - /* - * from: ACTIVE - * to : BUS_WARNING, BUS_PASSIVE, BUS_OFF - * => : there was a warning int - */ - if (new_state >= CAN_STATE_BUS_WARNING && - new_state <= CAN_STATE_BUS_OFF) - priv->can.can_stats.error_warning++; - case CAN_STATE_BUS_WARNING: /* fallthrough */ - /* - * from: ACTIVE, BUS_WARNING - * to : BUS_PASSIVE, BUS_OFF - * => : error passive int - */ - if (new_state >= CAN_STATE_BUS_PASSIVE && - new_state <= CAN_STATE_BUS_OFF) - priv->can.can_stats.error_passive++; - break; - case CAN_STATE_BUS_OFF: - /* - * this is a crude chip, happens very often that it is - * in BUS_OFF but still tries to send a package. on - * success it leaves bus off. so we have to reenable - * the carrier. - */ - if (new_state <= CAN_STATE_BUS_PASSIVE) - netif_carrier_on(ndev); - break; - default: - break; - } - - - /* process state changes depending on the new state */ - switch (new_state) { - case CAN_STATE_ACTIVE: - /* - * actually we want to enable AT91_IRQ_WARN here, but - * it screws up the system under certain - * circumstances. so just enable AT91_IRQ_ERRP, thus - * the "fallthrough" - */ - case CAN_STATE_BUS_WARNING: /* fallthrough */ - reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_BOFF; - reg_ier = AT91_IRQ_ERRP; - break; - case CAN_STATE_BUS_PASSIVE: - reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_ERRP; - reg_ier = AT91_IRQ_BOFF; - break; - case CAN_STATE_BUS_OFF: - reg_idr = AT91_IRQ_ERRA | AT91_IRQ_ERRP | - AT91_IRQ_WARN | AT91_IRQ_BOFF; - reg_ier = 0; - - /* - * FIXME: really abort? - * - * a somewhat "special" chip, even in BUS_OFF mode, it - * accesses the bus. this is a no-no. we try to abort - * transfers on all mailboxes. but the chip doesn't - * seem to handle this correctly. a stuck-in-transfer - * message isn't aborted. after bringing the CAN bus - * back xin shape again, the stuck-in-transfer message - * is tranferred and its MRDY bit is set. all other - * queued messages are aborted (not send) their MABT - * bit in MSR is _not_ set but the MRDY bit, too. - */ - dev_dbg(ND2D(ndev), "%s: aborting transfers, due to BUS OFF\n", - __func__); - - at91_write(ndev, AT91_ACR, AT91_IRQ_MB_TX); - - can_bus_off(ndev); - break; - default: - break; - } - - dev_dbg(ND2D(ndev), "%s: writing IDR=0x%08x, IER=0x%08x\n", - __func__, reg_idr, reg_ier); - at91_write(ndev, AT91_IDR, reg_idr); - at91_write(ndev, AT91_IER, reg_ier); - - - { - struct sk_buff *skb; - struct can_frame *cf; - - skb = netdev_alloc_skb(ndev, sizeof(struct can_frame)); - if (unlikely(!skb)) - goto out; - - skb->protocol = htons(ETH_P_CAN); - cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); - - memset(cf, 0x0, sizeof(struct can_frame)); - - cf->can_id = CAN_ERR_FLAG; - cf->can_dlc = CAN_ERR_DLC; - - switch (new_state) { - case CAN_STATE_BUS_WARNING: - case CAN_STATE_BUS_PASSIVE: - cf->can_id |= CAN_ERR_CRTL; - - if (new_state == CAN_STATE_BUS_WARNING) - cf->data[1] = (tec > rec) ? - CAN_ERR_CRTL_TX_WARNING : - CAN_ERR_CRTL_RX_WARNING; - else - cf->data[1] = (tec > rec) ? - CAN_ERR_CRTL_TX_PASSIVE : - CAN_ERR_CRTL_RX_PASSIVE; - - break; - case CAN_STATE_BUS_OFF: - cf->can_id |= CAN_ERR_BUSOFF; - break; - default: - break; - } - - - netif_rx(skb); - - ndev->last_rx = jiffies; - ndev->stats.rx_packets++; - ndev->stats.rx_bytes += cf->can_dlc; - } - - out: - priv->can.state = new_state; -} - - - -/* - * interrupt handler - */ -static irqreturn_t at91_irq(int irq, void *ndev_id) -{ - struct net_device *ndev = ndev_id; - irqreturn_t handled = IRQ_NONE; - u32 reg_sr, reg_imr; - int boguscnt = MAX_INTERRUPT_WORK; - - do { - reg_sr = at91_read(ndev, AT91_SR); - reg_imr = at91_read(ndev, AT91_IMR); - dev_dbg(ND2D(ndev), "%s: SR=0x%08x, IMR=0x%08x, [0x%08x]\n", - __func__, - reg_sr, reg_imr, reg_sr & reg_imr); - - /* Ignore masked interrupts */ - reg_sr &= reg_imr; - if (!reg_sr) - goto exit; - - handled = IRQ_HANDLED; - - if (reg_sr & AT91_IRQ_MB_RX) - at91_irq_rx(ndev, reg_sr); - - if (reg_sr & AT91_IRQ_MB_TX) - at91_irq_tx(ndev, reg_sr); - - at91_irq_err(ndev, reg_sr); - - } while (--boguscnt > 0); - - if (unlikely(boguscnt <= 0)) { - dev_warn(ND2D(ndev), "Too much work at interrupt, " - "status (at enter): 0x%08x, now: 0x%08x\n", - reg_sr, - at91_read(ndev, AT91_SR) & at91_read(ndev, AT91_IMR)); - - /* Clear all interrupt sources. */ - /* FIXME: do it? */ - } - - exit: - return handled; -} - - -static void at91_setup_mailboxes(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - int i; - - /* - * The first 12 mailboxes are used as a reception FIFO. The - * last mailbox is configured with overwrite option. The - * overwrite flag indicates a FIFO overflow. - */ - /* FIXME: clear accept regs (MID/MAM) */ - for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) - set_mb_mode(ndev, i, AT91_MB_MODE_RX); - set_mb_mode(ndev, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); - - /* The last 4 mailboxes are used for transmitting. */ - for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++) - set_mb_mode_prio(ndev, i, AT91_MB_MODE_TX, 0); - - - /* reset both tx and rx helper pointers */ - priv->tx_next = priv->tx_echo = priv->rx_bank = 0; -} - - -static struct net_device_stats *at91_get_stats(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - u32 reg_ecr = at91_read(ndev, AT91_ECR); - - ndev->stats.rx_errors = reg_ecr & 0xff; - ndev->stats.tx_errors = reg_ecr >> 16; - - /* - * here comes another one: - * - * the transmit error counter (TEC) has only a width of 8 - * bits, so when the devices goes into BUS OFF (which is - * defined by a TEC > 255), the TEC in the chip shows "0". Not - * only that, it keeps accumulating errors, so they can vary - * between 0 and 255. We set TEC to 256 (hard) in BUS_OFF. - * - */ - if (unlikely(priv->can.state == CAN_STATE_BUS_OFF)) - ndev->stats.tx_errors = 256; - - return &ndev->stats; -} - - -static int at91_set_bittiming(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - struct can_bittiming *bt = &priv->can.bittiming; - u32 reg_br; - - reg_br = ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) << 24) | - ((bt->brp - 1) << 16) | - ((bt->sjw - 1) << 12) | - ((bt->prop_seg - 1) << 8) | - ((bt->phase_seg1 - 1) << 4) | - ((bt->phase_seg2 - 1) << 0); - - dev_dbg(ND2D(ndev), "writing AT91_BR: 0x%08x, can_sys_clock: %d\n", - reg_br, priv->can.bittiming.clock); - at91_write(ndev, AT91_BR, reg_br); - - return 0; -} - - -static void at91_chip_start(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - u32 reg_mr, reg_ier; - - /* disable interrupts */ - at91_write(ndev, AT91_IDR, 0x1fffffff); - - /* disable chip */ - reg_mr = at91_read(ndev, AT91_MR); - at91_write(ndev, AT91_MR, reg_mr & ~AT91_MR_AT91EN); - wmb(); - - at91_setup_mailboxes(ndev); - - enable_can_transceiver(priv, 1); - - /* enable chip */ - reg_mr = at91_read(ndev, AT91_MR); - at91_write(ndev, AT91_MR, reg_mr | AT91_MR_AT91EN); - - priv->can.state = CAN_STATE_ACTIVE; - - /* Enable interrupts */ - reg_ier = - AT91_IRQ_MB_RX | - AT91_IRQ_ERRP; /* AT91_IRQ_WARN screws up system */ -/* AT91_IRQ_CERR | AT91_IRQ_SERR | AT91_IRQ_AERR | */ -/* AT91_IRQ_FERR | AT91_IRQ_BERR; */ - at91_write(ndev, AT91_IDR, 0x1fffffff); - at91_write(ndev, AT91_IER, reg_ier); -} - - -static void at91_chip_stop(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - u32 reg_mr; - - /* disable interrupts */ - at91_write(ndev, AT91_IDR, 0x1fffffff); - - reg_mr = at91_read(ndev, AT91_MR); - at91_write(ndev, AT91_MR, reg_mr & ~AT91_MR_AT91EN); - - priv->can.state = CAN_STATE_STOPPED; - enable_can_transceiver(priv, 0); -} - - -static int at91_open(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - int err; - - clk_enable(priv->clk); - - /* register interrupt handler */ - if (request_irq(ndev->irq, at91_irq, IRQF_SHARED, - ndev->name, ndev)) { - err = -EAGAIN; - goto out; - } - - /* start chip and queuing */ - at91_chip_start(ndev); - netif_start_queue(ndev); - - return 0; - - out: - clk_disable(priv->clk); - - return err; -} - - -/* - * stop CAN bus activity - */ -static int at91_close(struct net_device *ndev) -{ - struct at91_priv *priv = netdev_priv(ndev); - - netif_stop_queue(ndev); - - at91_chip_stop(ndev); - free_irq(ndev->irq, ndev); - clk_disable(priv->clk); - - can_close_cleanup(ndev); - - return 0; -} - - -static int at91_get_state(struct net_device *ndev, u32 *state) -{ - struct at91_priv *priv = netdev_priv(ndev); - *state = priv->can.state; - return 0; -} - - -static int at91_set_mode(struct net_device *ndev, u32 _mode) -{ - enum can_mode mode = _mode; - - switch (mode) { - case CAN_MODE_START: - dev_dbg(ND2D(ndev), "%s: CAN_MODE_START requested\n", __func__); - - at91_chip_start(ndev); - netif_wake_queue(ndev); - break; - - default: - return -EOPNOTSUPP; - } - - return 0; -} - - -static struct can_bittiming_const at91_bittiming_const = { - .tseg1_min = 1, - .tseg1_max = 8, - .tseg2_min = 2, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 2, - .brp_max = 128, - .brp_inc = 1, -}; - - -static int __init at91_can_probe(struct platform_device *pdev) -{ - struct net_device *ndev; - struct at91_priv *priv; - struct resource *res; - struct clk *clk; - void __iomem *addr; - int err, irq; - - clk = clk_get(&pdev->dev, "can_clk"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "no clock defined\n"); - err = -ENODEV; - goto exit; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!res || !irq) { - err = -ENODEV; - goto exit_put; - } - - if (!request_mem_region(res->start, - res->end - res->start + 1, - pdev->name)) { - err = -EBUSY; - goto exit_put; - } - - addr = ioremap_nocache(res->start, res->end - res->start + 1); - if (!addr) { - err = -ENOMEM; - goto exit_release; - } - - ndev = alloc_candev(sizeof(struct at91_priv)); - if (!ndev) { - err = -ENOMEM; - goto exit_iounmap; - } - - dev_set_drvdata(&pdev->dev, ndev); - SET_NETDEV_DEV(ndev, &pdev->dev); - - ndev->open = at91_open; - ndev->stop = at91_close; - ndev->hard_start_xmit = at91_start_xmit; - ndev->tx_timeout = at91_tx_timeout; - ndev->get_stats = at91_get_stats; - ndev->irq = irq; - ndev->base_addr = (unsigned long)addr; - ndev->flags |= IFF_ECHO; - - priv = netdev_priv(ndev); - priv->can.bittiming.clock = clk_get_rate(clk); - priv->can.bittiming_const = &at91_bittiming_const; - priv->can.do_set_bittiming = at91_set_bittiming; - priv->can.do_get_state = at91_get_state; - priv->can.do_set_mode = at91_set_mode; - priv->clk = clk; - - priv->pdata = pdev->dev.platform_data; - - - err = register_netdev(ndev); - if (err) { - dev_err(&pdev->dev, "registering netdev failed\n"); - goto exit_free; - } - - dev_info(&pdev->dev, "device registered (base_addr=%#lx, irq=%d)\n", - ndev->base_addr, ndev->irq); - - return 0; - - exit_free: - free_netdev(ndev); - exit_iounmap: - iounmap(addr); - exit_release: - release_mem_region(res->start, res->end - res->start + 1); - exit_put: - clk_put(clk); - exit: - return err; -} - - -static int __devexit at91_can_remove(struct platform_device *pdev) -{ - struct net_device *ndev = platform_get_drvdata(pdev); - struct at91_priv *priv = netdev_priv(ndev); - struct resource *res; - - unregister_netdev(ndev); - - platform_set_drvdata(pdev, NULL); - - free_netdev(ndev); - - iounmap((void __iomem *)ndev->base_addr); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); - - clk_put(priv->clk); - - return 0; -} - -#ifdef CONFIG_PM -static int at91_can_suspend(struct platform_device *pdev, - pm_message_t mesg) -{ - struct net_device *net_dev = platform_get_drvdata(pdev); - struct at91_priv *priv = netdev_priv(net_dev); - - if (netif_running(net_dev)) { - /* TODO Disable IRQ? */ - netif_stop_queue(net_dev); - netif_ndevice_detach(net_dev); - enable_can_transceiver(priv, 0); - clk_disable(priv->clk); - } - return 0; -} - - -static int at91_can_resume(struct platform_device *pdev) -{ - struct net_device *net_dev = platform_get_drvdata(pdev); - struct at91_priv *priv = netdev_priv(net_dev); - - if (netif_running(net_dev)) { - clk_enable(priv->clk); - enable_can_transceiver(priv, 1); - netif_ndevice_attach(net_dev); - netif_start_queue(net_dev); - /* TODO Enable IRQ? */ - } - return 0; -} -#else -#define at91_can_suspend NULL -#define at91_can_resume NULL -#endif - -static struct platform_driver at91_can_driver = { - .probe = at91_can_probe, - .remove = __devexit_p(at91_can_remove), - .suspend = at91_can_suspend, - .resume = at91_can_resume, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init at91_can_module_init(void) -{ - printk(KERN_INFO "%s netdevice driver\n", DRV_NAME); - return platform_driver_register(&at91_can_driver); -} - -static void __exit at91_can_module_exit(void) -{ - platform_driver_unregister(&at91_can_driver); - printk(KERN_INFO "%s: driver removed\n", DRV_NAME); -} - -module_init(at91_can_module_init); -module_exit(at91_can_module_exit); - -MODULE_AUTHOR("Marc Kleine-Budde <mkl@pengutronix.de>"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("LLCF/socketcan '" DRV_NAME "' network ndevice driver"); diff --git a/drivers/net/can/mscan/Makefile b/drivers/net/can/mscan/Makefile deleted file mode 100644 index 17d9a4b78f4..00000000000 --- a/drivers/net/can/mscan/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for Freescale MSCAN drivers -# - -obj-$(CONFIG_CAN_MPC52XX) += mscan-mpc52xx.o - -mscan-mpc52xx-objs := mscan.o mpc52xx_can.o diff --git a/drivers/net/can/mscan/mpc52xx_can.c b/drivers/net/can/mscan/mpc52xx_can.c deleted file mode 100644 index 34cbf753ce6..00000000000 --- a/drivers/net/can/mscan/mpc52xx_can.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * DESCRIPTION: - * CAN bus driver for the Freescale MPC52xx embedded CPU. - * - * AUTHOR: - * Andrey Volkov <avolkov@varma-el.com> - * - * COPYRIGHT: - * 2004-2005, Varma Electronics Oy - * - * LICENCE: - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * HISTORY: - * 2005-02-03 created - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/netdevice.h> -#include <linux/can.h> -#include <linux/can/dev.h> -#include <linux/io.h> -#include <asm/mpc52xx.h> - -#include "mscan.h" - - -#define PDEV_MAX 2 - -struct platform_device *pdev[PDEV_MAX]; - -static int __devinit mpc52xx_can_probe(struct platform_device *pdev) -{ - struct resource *mem; - struct net_device *dev; - struct mscan_platform_data *pdata = pdev->dev.platform_data; - struct can_priv *priv; - u32 mem_size; - int ret = -ENODEV; - - if (!pdata) - return ret; - - dev = alloc_mscandev(); - if (!dev) - return -ENOMEM; - priv = netdev_priv(dev); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dev->irq = platform_get_irq(pdev, 0); - if (!mem || !dev->irq) - goto req_error; - - mem_size = mem->end - mem->start + 1; - if (!request_mem_region(mem->start, mem_size, pdev->dev.driver->name)) { - dev_err(&pdev->dev, "resource unavailable\n"); - goto req_error; - } - - SET_NETDEV_DEV(dev, &pdev->dev); - - dev->base_addr = (unsigned long)ioremap_nocache(mem->start, mem_size); - - if (!dev->base_addr) { - dev_err(&pdev->dev, "failed to map can port\n"); - ret = -ENOMEM; - goto fail_map; - } - - priv->bittiming.clock = pdata->clock_frq; - - platform_set_drvdata(pdev, dev); - - ret = register_mscandev(dev, pdata->clock_src); - if (ret >= 0) { - dev_info(&pdev->dev, "probe for port 0x%lX done (irq=%d)\n", - dev->base_addr, dev->irq); - return ret; - } - - iounmap((unsigned long *)dev->base_addr); - -fail_map: - release_mem_region(mem->start, mem_size); - -req_error: - free_candev(dev); - dev_err(&pdev->dev, "probe failed\n"); - return ret; -} - -static int __devexit mpc52xx_can_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct resource *mem; - - platform_set_drvdata(pdev, NULL); - unregister_mscandev(dev); - - iounmap((volatile void __iomem *)dev->base_addr); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, mem->end - mem->start + 1); - free_candev(dev); - return 0; -} - -#ifdef CONFIG_PM -static struct mscan_regs saved_regs; -static int mpc52xx_can_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - - _memcpy_fromio(&saved_regs, regs, sizeof(*regs)); - - return 0; -} - -static int mpc52xx_can_resume(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - - regs->canctl0 |= MSCAN_INITRQ; - while ((regs->canctl1 & MSCAN_INITAK) == 0) - udelay(10); - - regs->canctl1 = saved_regs.canctl1; - regs->canbtr0 = saved_regs.canbtr0; - regs->canbtr1 = saved_regs.canbtr1; - regs->canidac = saved_regs.canidac; - - /* restore masks, buffers etc. */ - _memcpy_toio(®s->canidar1_0, (void *)&saved_regs.canidar1_0, - sizeof(*regs) - offsetof(struct mscan_regs, canidar1_0)); - - regs->canctl0 &= ~MSCAN_INITRQ; - regs->cantbsel = saved_regs.cantbsel; - regs->canrier = saved_regs.canrier; - regs->cantier = saved_regs.cantier; - regs->canctl0 = saved_regs.canctl0; - - return 0; -} -#endif - -static struct platform_driver mpc52xx_can_driver = { - .driver = { - .name = "mpc52xx-mscan", - }, - .probe = mpc52xx_can_probe, - .remove = __devexit_p(mpc52xx_can_remove), -#ifdef CONFIG_PM - .suspend = mpc52xx_can_suspend, - .resume = mpc52xx_can_resume, -#endif -}; - -#ifdef CONFIG_PPC_MERGE -static int __init mpc52xx_of_to_pdev(void) -{ - struct device_node *np = NULL; - unsigned int i; - int err = -ENODEV; - - for (i = 0; - (np = of_find_compatible_node(np, NULL, "fsl,mpc5200-mscan")); - i++) { - struct resource r[2] = { }; - struct mscan_platform_data pdata; - - if (i >= PDEV_MAX) { - printk(KERN_WARNING "%s: increase PDEV_MAX for more " - "than %i devices\n", __func__, PDEV_MAX); - break; - } - - err = of_address_to_resource(np, 0, &r[0]); - if (err) - break; - - of_irq_to_resource(np, 0, &r[1]); - - pdev[i] = - platform_device_register_simple("mpc52xx-mscan", i, r, 2); - if (IS_ERR(pdev[i])) { - err = PTR_ERR(pdev[i]); - break; - } - - pdata.clock_src = MSCAN_CLKSRC_BUS; - pdata.clock_frq = mpc52xx_find_ipb_freq(np); - err = platform_device_add_data(pdev[i], &pdata, sizeof(pdata)); - if (err) - break; - } - return err; -} -#endif - -int __init mpc52xx_can_init(void) -{ -#ifdef CONFIG_PPC_MERGE - int err = mpc52xx_of_to_pdev(); - - if (err) { - printk(KERN_ERR "%s init failed with err=%d\n", - mpc52xx_can_driver.driver.name, err); - return err; - } -#endif - return platform_driver_register(&mpc52xx_can_driver); -} - -void __exit mpc52xx_can_exit(void) -{ - int i; - platform_driver_unregister(&mpc52xx_can_driver); - for (i = 0; i < PDEV_MAX; i++) - platform_device_unregister(pdev[i]); - printk(KERN_INFO "%s unloaded\n", mpc52xx_can_driver.driver.name); -} - -module_init(mpc52xx_can_init); -module_exit(mpc52xx_can_exit); - -MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>"); -MODULE_DESCRIPTION("Freescale MPC5200 CAN driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c deleted file mode 100644 index a6be4a339d9..00000000000 --- a/drivers/net/can/mscan/mscan.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - * mscan.c - * - * DESCRIPTION: - * CAN bus driver for the alone generic (as possible as) MSCAN controller. - * - * AUTHOR: - * Andrey Volkov <avolkov@varma-el.com> - * - * COPYRIGHT: - * 2005-2006, Varma Electronics Oy - * - * LICENCE: - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <linux/if_ether.h> -#include <linux/list.h> -#include <linux/can.h> -#include <linux/can/dev.h> -#include <linux/can/error.h> -#include <linux/io.h> - -#include "mscan.h" - -#define MSCAN_NORMAL_MODE 0 -#define MSCAN_SLEEP_MODE MSCAN_SLPRQ -#define MSCAN_INIT_MODE (MSCAN_INITRQ | MSCAN_SLPRQ) -#define MSCAN_POWEROFF_MODE (MSCAN_CSWAI | MSCAN_SLPRQ) -#define MSCAN_SET_MODE_RETRIES 255 - - -#define BTR0_BRP_MASK 0x3f -#define BTR0_SJW_SHIFT 6 -#define BTR0_SJW_MASK (0x3 << BTR0_SJW_SHIFT) - -#define BTR1_TSEG1_MASK 0xf -#define BTR1_TSEG2_SHIFT 4 -#define BTR1_TSEG2_MASK (0x7 << BTR1_TSEG2_SHIFT) -#define BTR1_SAM_SHIFT 7 - -#define BTR0_SET_BRP(brp) (((brp) - 1) & BTR0_BRP_MASK) -#define BTR0_SET_SJW(sjw) ((((sjw) - 1) << BTR0_SJW_SHIFT) & \ - BTR0_SJW_MASK) - -#define BTR1_SET_TSEG1(tseg1) (((tseg1) - 1) & BTR1_TSEG1_MASK) -#define BTR1_SET_TSEG2(tseg2) ((((tseg2) - 1) << BTR1_TSEG2_SHIFT) & \ - BTR1_TSEG2_MASK) -#define BTR1_SET_SAM(sam) (((sam) & 1) << BTR1_SAM_SHIFT) - -static struct can_bittiming_const mscan_bittiming_const = { - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 64, - .brp_inc = 1, -}; - -struct mscan_state { - u8 mode; - u8 canrier; - u8 cantier; -}; - -#define TX_QUEUE_SIZE 3 - -struct tx_queue_entry { - struct list_head list; - u8 mask; - u8 id; -}; - -struct mscan_priv { - struct can_priv can; - long open_time; - volatile unsigned long flags; - u8 shadow_statflg; - u8 shadow_canrier; - u8 cur_pri; - u8 tx_active; - - struct list_head tx_head; - struct tx_queue_entry tx_queue[TX_QUEUE_SIZE]; - struct napi_struct napi; - struct net_device *dev; -}; - -#define F_RX_PROGRESS 0 -#define F_TX_PROGRESS 1 -#define F_TX_WAIT_ALL 2 - -static enum can_state state_map[] = { - CAN_STATE_ACTIVE, - CAN_STATE_BUS_WARNING, - CAN_STATE_BUS_PASSIVE, - CAN_STATE_BUS_OFF -}; - -static int mscan_set_mode(struct net_device *dev, u8 mode) -{ - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - struct mscan_priv *priv = netdev_priv(dev); - int ret = 0; - int i; - u8 canctl1; - - if (mode != MSCAN_NORMAL_MODE) { - - if (priv->tx_active) { - /* Abort transfers before going to sleep */ - out_8(®s->cantier, 0); - out_8(®s->cantarq, priv->tx_active); - out_8(®s->cantier, priv->tx_active); - } - - canctl1 = in_8(®s->canctl1); - if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) { - out_8(®s->canctl0, - in_8(®s->canctl0) | MSCAN_SLPRQ); - for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) { - if (in_8(®s->canctl1) & MSCAN_SLPAK) - break; - udelay(100); - } - if (i >= MSCAN_SET_MODE_RETRIES) - ret = -ENODEV; - } - if (!ret) - priv->can.state = CAN_STATE_SLEEPING; - - if (!ret && (mode & MSCAN_INITRQ) - && (canctl1 & MSCAN_INITAK) == 0) { - out_8(®s->canctl0, - in_8(®s->canctl0) | MSCAN_INITRQ); - for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) { - if (in_8(®s->canctl1) & MSCAN_INITAK) - break; - } - if (i >= MSCAN_SET_MODE_RETRIES) - ret = -ENODEV; - } - if (!ret) - priv->can.state = CAN_STATE_STOPPED; - - if (!ret && (mode & MSCAN_CSWAI)) - out_8(®s->canctl0, - in_8(®s->canctl0) | MSCAN_CSWAI); - - } else { - canctl1 = in_8(®s->canctl1); - if (canctl1 & (MSCAN_SLPAK | MSCAN_INITAK)) { - out_8(®s->canctl0, in_8(®s->canctl0) & - ~(MSCAN_SLPRQ | MSCAN_INITRQ)); - for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) { - canctl1 = in_8(®s->canctl1); - if (!(canctl1 & (MSCAN_INITAK | MSCAN_SLPAK))) - break; - } - if (i >= MSCAN_SET_MODE_RETRIES) - ret = -ENODEV; - else - priv->can.state = CAN_STATE_ACTIVE; - } - } - return ret; -} - -static int mscan_start(struct net_device *dev) -{ - struct mscan_priv *priv = netdev_priv(dev); - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - u8 canrflg; - int err; - - out_8(®s->canrier, 0); - - INIT_LIST_HEAD(&priv->tx_head); - priv->cur_pri = 0; - priv->tx_active = 0; - priv->shadow_canrier = 0; - priv->flags = 0; - - err = mscan_set_mode(dev, MSCAN_NORMAL_MODE); - if (err) - return err; - - canrflg = in_8(®s->canrflg); - priv->shadow_statflg = canrflg & MSCAN_STAT_MSK; - priv->can.state = state_map[max(MSCAN_STATE_RX(canrflg), - MSCAN_STATE_TX(canrflg))]; - out_8(®s->cantier, 0); - - /* Enable receive interrupts. */ - out_8(®s->canrier, MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE | - MSCAN_RSTATE1 | MSCAN_RSTATE0 | MSCAN_TSTATE1 | MSCAN_TSTATE0); - - return 0; -} - -static int mscan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct can_frame *frame = (struct can_frame *)skb->data; - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - struct mscan_priv *priv = netdev_priv(dev); - int i, rtr, buf_id; - u32 can_id; - - if (frame->can_dlc > 8) - return -EINVAL; - - dev_dbg(ND2D(dev), "%s\n", __func__); - out_8(®s->cantier, 0); - - i = ~priv->tx_active & MSCAN_TXE; - buf_id = ffs(i) - 1; - switch (hweight8(i)) { - case 0: - netif_stop_queue(dev); - dev_err(ND2D(dev), "BUG! Tx Ring full when queue awake!\n"); - return NETDEV_TX_BUSY; - case 1: - /* if buf_id < 3, then current frame will be send out of order, - since buffer with lower id have higher priority (hell..) */ - if (buf_id < 3) - priv->cur_pri++; - if (priv->cur_pri == 0xff) - set_bit(F_TX_WAIT_ALL, &priv->flags); - netif_stop_queue(dev); - case 2: - set_bit(F_TX_PROGRESS, &priv->flags); - } - out_8(®s->cantbsel, i); - - rtr = frame->can_id & CAN_RTR_FLAG; - - if (frame->can_id & CAN_EFF_FLAG) { - dev_dbg(ND2D(dev), "sending extended frame\n"); - - can_id = (frame->can_id & CAN_EFF_MASK) << 1; - if (rtr) - can_id |= 1; - out_be16(®s->tx.idr3_2, can_id); - - can_id >>= 16; - can_id = (can_id & 0x7) | ((can_id << 2) & 0xffe0) | (3 << 3); - } else { - dev_dbg(ND2D(dev), "sending standard frame\n"); - can_id = (frame->can_id & CAN_SFF_MASK) << 5; - if (rtr) - can_id |= 1 << 4; - } - out_be16(®s->tx.idr1_0, can_id); - - if (!rtr) { - volatile void __iomem *data = ®s->tx.dsr1_0; - u16 *payload = (u16 *) frame->data; - /*Its safe to write into dsr[dlc+1] */ - for (i = 0; i < (frame->can_dlc + 1) / 2; i++) { - out_be16(data, *payload++); - data += 2 + _MSCAN_RESERVED_DSR_SIZE; - } - } - - out_8(®s->tx.dlr, frame->can_dlc); - out_8(®s->tx.tbpr, priv->cur_pri); - - /* Start transmission. */ - out_8(®s->cantflg, 1 << buf_id); - - if (!test_bit(F_TX_PROGRESS, &priv->flags)) - dev->trans_start = jiffies; - - list_add_tail(&priv->tx_queue[buf_id].list, &priv->tx_head); - - can_put_echo_skb(skb, dev, buf_id); - - /* Enable interrupt. */ - priv->tx_active |= 1 << buf_id; - out_8(®s->cantier, priv->tx_active); - - return NETDEV_TX_OK; -} - -static inline int check_set_state(struct net_device *dev, u8 canrflg) -{ - struct mscan_priv *priv = netdev_priv(dev); - enum can_state state; - int ret = 0; - - if (!(canrflg & MSCAN_CSCIF) || priv->can.state > CAN_STATE_BUS_OFF) - return 0; - - state = state_map[max(MSCAN_STATE_RX(canrflg), - MSCAN_STATE_TX(canrflg))]; - if (priv->can.state < state) - ret = 1; - if (state == CAN_STATE_BUS_OFF) - can_bus_off(dev); - priv->can.state = state; - return ret; -} - -static int mscan_rx_poll(struct napi_struct *napi, int quota) -{ - struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi); - struct net_device *dev = priv->dev; - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - struct net_device_stats *stats = dev->get_stats(dev); - int npackets = 0; - int ret = 1; - struct sk_buff *skb; - struct can_frame *frame; - u32 can_id; - u8 canrflg; - int i; - - while (npackets < quota && ((canrflg = in_8(®s->canrflg)) & - (MSCAN_RXF | MSCAN_ERR_IF))) { - - skb = dev_alloc_skb(sizeof(struct can_frame)); - if (!skb) { - if (printk_ratelimit()) - dev_notice(ND2D(dev), "packet dropped\n"); - stats->rx_dropped++; - out_8(®s->canrflg, canrflg); - continue; - } - - frame = (struct can_frame *)skb_put(skb, sizeof(*frame)); - memset(frame, 0, sizeof(*frame)); - - if (canrflg & MSCAN_RXF) { - can_id = in_be16(®s->rx.idr1_0); - if (can_id & (1 << 3)) { - frame->can_id = CAN_EFF_FLAG; - can_id = ((can_id << 16) | - in_be16(®s->rx.idr3_2)); - can_id = ((can_id & 0xffe00000) | - ((can_id & 0x7ffff) << 2)) >> 2; - } else { - can_id >>= 4; - frame->can_id = 0; - } - - frame->can_id |= can_id >> 1; - if (can_id & 1) - frame->can_id |= CAN_RTR_FLAG; - frame->can_dlc = in_8(®s->rx.dlr) & 0xf; - - if (!(frame->can_id & CAN_RTR_FLAG)) { - volatile void __iomem *data = ®s->rx.dsr1_0; - u16 *payload = (u16 *) frame->data; - for (i = 0; i < (frame->can_dlc + 1) / 2; i++) { - *payload++ = in_be16(data); - data += 2 + _MSCAN_RESERVED_DSR_SIZE; - } - } - - dev_dbg(ND2D(dev), - "received pkt: id: %u dlc: %u data: ", - frame->can_id, frame->can_dlc); -#ifdef DEBUG - for (i = 0; - i < frame->can_dlc && !(frame->can_id & - CAN_FLAG_RTR); i++) - printk(KERN_DEBUG "%2x ", frame->data[i]); - printk(KERN_DEBUG "\n"); -#endif - - out_8(®s->canrflg, MSCAN_RXF); - dev->last_rx = jiffies; - stats->rx_packets++; - stats->rx_bytes += frame->can_dlc; - } else if (canrflg & MSCAN_ERR_IF) { - frame->can_id = CAN_ERR_FLAG; - - if (canrflg & MSCAN_OVRIF) { - frame->can_id |= CAN_ERR_CRTL; - frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; - stats->rx_over_errors++; - } else - frame->data[1] = 0; - - if (check_set_state(dev, canrflg)) { - frame->can_id |= CAN_ERR_CRTL; - switch (priv->can.state) { - case CAN_STATE_BUS_WARNING: - if ((priv->shadow_statflg & - MSCAN_RSTAT_MSK) < - (canrflg & MSCAN_RSTAT_MSK)) - frame->data[1] |= - CAN_ERR_CRTL_RX_WARNING; - - if ((priv->shadow_statflg & - MSCAN_TSTAT_MSK) < - (canrflg & MSCAN_TSTAT_MSK)) - frame->data[1] |= - CAN_ERR_CRTL_TX_WARNING; - break; - case CAN_STATE_BUS_PASSIVE: - frame->data[1] |= - CAN_ERR_CRTL_RX_PASSIVE; - break; - case CAN_STATE_BUS_OFF: - frame->can_id |= CAN_ERR_BUSOFF; - frame->can_id &= ~CAN_ERR_CRTL; - break; - default: - break; - } - } - priv->shadow_statflg = canrflg & MSCAN_STAT_MSK; - frame->can_dlc = CAN_ERR_DLC; - out_8(®s->canrflg, MSCAN_ERR_IF); - } - - npackets++; - skb->dev = dev; - skb->protocol = __constant_htons(ETH_P_CAN); - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_receive_skb(skb); - } - - if (!(in_8(®s->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) { - netif_rx_complete(dev, &priv->napi); - clear_bit(F_RX_PROGRESS, &priv->flags); -#if 0 - out_8(®s->canrier, - in_8(®s->canrier) | MSCAN_ERR_IF | MSCAN_RXFIE); -#else - if (priv->can.state < CAN_STATE_BUS_OFF) - out_8(®s->canrier, priv->shadow_canrier); -#endif - ret = 0; - } - return ret; -} - - -static irqreturn_t mscan_isr(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *)dev_id; - struct mscan_priv *priv = netdev_priv(dev); - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - struct net_device_stats *stats = dev->get_stats(dev); - u8 cantier, cantflg, canrflg; - irqreturn_t ret = IRQ_NONE; - - cantier = in_8(®s->cantier) & MSCAN_TXE; - cantflg = in_8(®s->cantflg) & cantier; - - if (cantier && cantflg) { - - struct list_head *tmp, *pos; - - list_for_each_safe(pos, tmp, &priv->tx_head) { - struct tx_queue_entry *entry = - list_entry(pos, struct tx_queue_entry, list); - u8 mask = entry->mask; - - if (!(cantflg & mask)) - continue; - - out_8(®s->cantbsel, mask); - stats->tx_bytes += in_8(®s->tx.dlr); - stats->tx_packets++; - can_get_echo_skb(dev, entry->id); - priv->tx_active &= ~mask; - list_del(pos); - } - - if (list_empty(&priv->tx_head)) { - clear_bit(F_TX_WAIT_ALL, &priv->flags); - clear_bit(F_TX_PROGRESS, &priv->flags); - priv->cur_pri = 0; - } else - dev->trans_start = jiffies; - - if (!test_bit(F_TX_WAIT_ALL, &priv->flags)) - netif_wake_queue(dev); - - out_8(®s->cantier, priv->tx_active); - ret = IRQ_HANDLED; - } - - canrflg = in_8(®s->canrflg); - if ((canrflg & ~MSCAN_STAT_MSK) && - !test_and_set_bit(F_RX_PROGRESS, &priv->flags)) { -#if 0 - printk(KERN_DEBUG "%s: canrflg=%#02x canrier=%#02x\n", - dev->name, canrflg, in_8(®s->canrier)); -#endif -#if 0 - if (check_set_state(dev, canrflg)) { - out_8(®s->canrflg, MSCAN_CSCIF); - ret = IRQ_HANDLED; - } -#endif - if (canrflg & ~MSCAN_STAT_MSK) { - priv->shadow_canrier = in_8(®s->canrier); - out_8(®s->canrier, 0); - netif_rx_schedule(dev, &priv->napi); - ret = IRQ_HANDLED; - } else - clear_bit(F_RX_PROGRESS, &priv->flags); - } - return ret; -} - -static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode) -{ - - struct mscan_priv *priv = netdev_priv(dev); - int ret = 0; - - if (!priv->open_time) - return -EINVAL; - - switch (mode) { - case CAN_MODE_SLEEP: - case CAN_MODE_STOP: - netif_stop_queue(dev); - mscan_set_mode(dev, - (mode == - CAN_MODE_STOP) ? MSCAN_INIT_MODE : - MSCAN_SLEEP_MODE); - break; - case CAN_MODE_START: - if (priv->can.state <= CAN_STATE_BUS_OFF) - mscan_set_mode(dev, MSCAN_INIT_MODE); - ret = mscan_start(dev); - if (ret) - break; - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); - break; - - default: - ret = -EOPNOTSUPP; - break; - } - return ret; -} - -static int mscan_do_set_bittiming(struct net_device *dev) -{ - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - struct mscan_priv *priv = netdev_priv(dev); - struct can_bittiming *bt = &priv->can.bittiming; - u8 btr0, btr1; - - btr0 = BTR0_SET_BRP(bt->brp) | BTR0_SET_SJW(bt->sjw); - btr1 = (BTR1_SET_TSEG1(bt->prop_seg + bt->phase_seg1) | - BTR1_SET_TSEG2(bt->phase_seg2) | - BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)); - - dev_info(ND2D(dev), "BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); - - out_8(®s->canbtr0, btr0); - out_8(®s->canbtr1, btr1); - - return 0; -} - -static int mscan_open(struct net_device *dev) -{ - int ret; - struct mscan_priv *priv = netdev_priv(dev); - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - - /* determine and set bittime */ - ret = can_set_bittiming(dev); - if (ret) - return ret; - - napi_enable(&priv->napi); - ret = request_irq(dev->irq, mscan_isr, IRQF_SHARED, dev->name, dev); - - if (ret < 0) { - napi_disable(&priv->napi); - printk(KERN_ERR "%s - failed to attach interrupt\n", - dev->name); - return ret; - } - - priv->open_time = jiffies; - - out_8(®s->canctl1, in_8(®s->canctl1) & ~MSCAN_LISTEN); - - ret = mscan_start(dev); - if (ret) - return ret; - - netif_start_queue(dev); - - return 0; -} - -static int mscan_close(struct net_device *dev) -{ - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - struct mscan_priv *priv = netdev_priv(dev); - - napi_disable(&priv->napi); - - out_8(®s->cantier, 0); - out_8(®s->canrier, 0); - free_irq(dev->irq, dev); - mscan_set_mode(dev, MSCAN_INIT_MODE); - can_close_cleanup(dev); - netif_stop_queue(dev); - priv->open_time = 0; - - return 0; -} - -int register_mscandev(struct net_device *dev, int clock_src) -{ - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - u8 ctl1; - - ctl1 = in_8(®s->canctl1); - if (clock_src) - ctl1 |= MSCAN_CLKSRC; - else - ctl1 &= ~MSCAN_CLKSRC; - - ctl1 |= MSCAN_CANE; - out_8(®s->canctl1, ctl1); - udelay(100); - - /* acceptance mask/acceptance code (accept everything) */ - out_be16(®s->canidar1_0, 0); - out_be16(®s->canidar3_2, 0); - out_be16(®s->canidar5_4, 0); - out_be16(®s->canidar7_6, 0); - - out_be16(®s->canidmr1_0, 0xffff); - out_be16(®s->canidmr3_2, 0xffff); - out_be16(®s->canidmr5_4, 0xffff); - out_be16(®s->canidmr7_6, 0xffff); - /* Two 32 bit Acceptance Filters */ - out_8(®s->canidac, MSCAN_AF_32BIT); - - mscan_set_mode(dev, MSCAN_INIT_MODE); - - return register_netdev(dev); -} -EXPORT_SYMBOL(register_mscandev); - -void unregister_mscandev(struct net_device *dev) -{ - struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; - mscan_set_mode(dev, MSCAN_INIT_MODE); - out_8(®s->canctl1, in_8(®s->canctl1) & ~MSCAN_CANE); - unregister_netdev(dev); -} -EXPORT_SYMBOL(unregister_mscandev); - -struct net_device *alloc_mscandev(void) -{ - struct net_device *dev; - struct mscan_priv *priv; - int i; - - dev = alloc_candev(sizeof(struct mscan_priv)); - if (!dev) - return NULL; - priv = netdev_priv(dev); - - dev->open = mscan_open; - dev->stop = mscan_close; - dev->hard_start_xmit = mscan_hard_start_xmit; - - dev->flags |= IFF_ECHO; /* we support local echo */ - - priv->dev = dev; - netif_napi_add(dev, &priv->napi, mscan_rx_poll, 8); - - priv->can.bittiming_const = &mscan_bittiming_const; - priv->can.do_set_bittiming = mscan_do_set_bittiming; - priv->can.do_set_mode = mscan_do_set_mode; - - for (i = 0; i < TX_QUEUE_SIZE; i++) { - priv->tx_queue[i].id = i; - priv->tx_queue[i].mask = 1 << i; - } - - return dev; -} -EXPORT_SYMBOL(alloc_mscandev); - -MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("CAN port driver for a mscan based chips"); diff --git a/drivers/net/can/mscan/mscan.h b/drivers/net/can/mscan/mscan.h deleted file mode 100644 index 87cf479efc6..00000000000 --- a/drivers/net/can/mscan/mscan.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * DESCRIPTION: - * Definitions of consts/structs to drive the Freescale MSCAN. - * - * AUTHOR: - * Andrey Volkov <avolkov@varma-el.com> - * - * COPYRIGHT: - * 2004-2006, Varma Electronics Oy - * - * LICENCE: - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __MSCAN_H__ -#define __MSCAN_H__ - -#include <linux/autoconf.h> -#include <linux/types.h> - -/* MSCAN control register 0 (CANCTL0) bits */ -#define MSCAN_RXFRM 0x80 -#define MSCAN_RXACT 0x40 -#define MSCAN_CSWAI 0x20 -#define MSCAN_SYNCH 0x10 -#define MSCAN_TIME 0x08 -#define MSCAN_WUPE 0x04 -#define MSCAN_SLPRQ 0x02 -#define MSCAN_INITRQ 0x01 - -/* MSCAN control register 1 (CANCTL1) bits */ -#define MSCAN_CANE 0x80 -#define MSCAN_CLKSRC 0x40 -#define MSCAN_LOOPB 0x20 -#define MSCAN_LISTEN 0x10 -#define MSCAN_WUPM 0x04 -#define MSCAN_SLPAK 0x02 -#define MSCAN_INITAK 0x01 - -#ifdef CONFIG_PPC_MPC52xx -#define MSCAN_CLKSRC_BUS 0 -#define MSCAN_CLKSRC_XTAL MSCAN_CLKSRC -#else -#define MSCAN_CLKSRC_BUS MSCAN_CLKSRC -#define MSCAN_CLKSRC_XTAL 0 -#endif - -/* MSCAN receiver flag register (CANRFLG) bits */ -#define MSCAN_WUPIF 0x80 -#define MSCAN_CSCIF 0x40 -#define MSCAN_RSTAT1 0x20 -#define MSCAN_RSTAT0 0x10 -#define MSCAN_TSTAT1 0x08 -#define MSCAN_TSTAT0 0x04 -#define MSCAN_OVRIF 0x02 -#define MSCAN_RXF 0x01 -#define MSCAN_ERR_IF (MSCAN_OVRIF | MSCAN_CSCIF) -#define MSCAN_RSTAT_MSK (MSCAN_RSTAT1 | MSCAN_RSTAT0) -#define MSCAN_TSTAT_MSK (MSCAN_TSTAT1 | MSCAN_TSTAT0) -#define MSCAN_STAT_MSK (MSCAN_RSTAT_MSK | MSCAN_TSTAT_MSK) - -#define MSCAN_STATE_BUS_OFF (MSCAN_RSTAT1 | MSCAN_RSTAT0 | \ - MSCAN_TSTAT1 | MSCAN_TSTAT0) -#define MSCAN_STATE_TX(canrflg) (((canrflg)&MSCAN_TSTAT_MSK)>>2) -#define MSCAN_STATE_RX(canrflg) (((canrflg)&MSCAN_RSTAT_MSK)>>4) -#define MSCAN_STATE_ACTIVE 0 -#define MSCAN_STATE_WARNING 1 -#define MSCAN_STATE_PASSIVE 2 -#define MSCAN_STATE_BUSOFF 3 - -/* MSCAN receiver interrupt enable register (CANRIER) bits */ -#define MSCAN_WUPIE 0x80 -#define MSCAN_CSCIE 0x40 -#define MSCAN_RSTATE1 0x20 -#define MSCAN_RSTATE0 0x10 -#define MSCAN_TSTATE1 0x08 -#define MSCAN_TSTATE0 0x04 -#define MSCAN_OVRIE 0x02 -#define MSCAN_RXFIE 0x01 - -/* MSCAN transmitter flag register (CANTFLG) bits */ -#define MSCAN_TXE2 0x04 -#define MSCAN_TXE1 0x02 -#define MSCAN_TXE0 0x01 -#define MSCAN_TXE (MSCAN_TXE2 | MSCAN_TXE1 | MSCAN_TXE0) - -/* MSCAN transmitter interrupt enable register (CANTIER) bits */ -#define MSCAN_TXIE2 0x04 -#define MSCAN_TXIE1 0x02 -#define MSCAN_TXIE0 0x01 -#define MSCAN_TXIE (MSCAN_TXIE2 | MSCAN_TXIE1 | MSCAN_TXIE0) - -/* MSCAN transmitter message abort request (CANTARQ) bits */ -#define MSCAN_ABTRQ2 0x04 -#define MSCAN_ABTRQ1 0x02 -#define MSCAN_ABTRQ0 0x01 - -/* MSCAN transmitter message abort ack (CANTAAK) bits */ -#define MSCAN_ABTAK2 0x04 -#define MSCAN_ABTAK1 0x02 -#define MSCAN_ABTAK0 0x01 - -/* MSCAN transmit buffer selection (CANTBSEL) bits */ -#define MSCAN_TX2 0x04 -#define MSCAN_TX1 0x02 -#define MSCAN_TX0 0x01 - -/* MSCAN ID acceptance control register (CANIDAC) bits */ -#define MSCAN_IDAM1 0x20 -#define MSCAN_IDAM0 0x10 -#define MSCAN_IDHIT2 0x04 -#define MSCAN_IDHIT1 0x02 -#define MSCAN_IDHIT0 0x01 - -#define MSCAN_AF_32BIT 0x00 -#define MSCAN_AF_16BIT MSCAN_IDAM0 -#define MSCAN_AF_8BIT MSCAN_IDAM1 -#define MSCAN_AF_CLOSED (MSCAN_IDAM0|MSCAN_IDAM1) -#define MSCAN_AF_MASK (~(MSCAN_IDAM0|MSCAN_IDAM1)) - -/* MSCAN Miscellaneous Register (CANMISC) bits */ -#define MSCAN_BOHOLD 0x01 - -#ifdef CONFIG_PPC_MPC52xx -#define _MSCAN_RESERVED_(n, num) u8 _res##n[num] -#define _MSCAN_RESERVED_DSR_SIZE 2 -#else -#define _MSCAN_RESERVED_(n, num) -#define _MSCAN_RESERVED_DSR_SIZE 0 -#endif - -/* Structure of the hardware registers */ -struct mscan_regs { - /* (see doco S12MSCANV3/D) MPC5200 MSCAN */ - u8 canctl0; /* + 0x00 0x00 */ - u8 canctl1; /* + 0x01 0x01 */ - _MSCAN_RESERVED_(1, 2); /* + 0x02 */ - u8 canbtr0; /* + 0x04 0x02 */ - u8 canbtr1; /* + 0x05 0x03 */ - _MSCAN_RESERVED_(2, 2); /* + 0x06 */ - u8 canrflg; /* + 0x08 0x04 */ - u8 canrier; /* + 0x09 0x05 */ - _MSCAN_RESERVED_(3, 2); /* + 0x0a */ - u8 cantflg; /* + 0x0c 0x06 */ - u8 cantier; /* + 0x0d 0x07 */ - _MSCAN_RESERVED_(4, 2); /* + 0x0e */ - u8 cantarq; /* + 0x10 0x08 */ - u8 cantaak; /* + 0x11 0x09 */ - _MSCAN_RESERVED_(5, 2); /* + 0x12 */ - u8 cantbsel; /* + 0x14 0x0a */ - u8 canidac; /* + 0x15 0x0b */ - u8 reserved; /* + 0x16 0x0c */ - _MSCAN_RESERVED_(6, 5); /* + 0x17 */ -#ifndef CONFIG_PPC_MPC52xx - u8 canmisc; /* 0x0d */ -#endif - u8 canrxerr; /* + 0x1c 0x0e */ - u8 cantxerr; /* + 0x1d 0x0f */ - _MSCAN_RESERVED_(7, 2); /* + 0x1e */ - u16 canidar1_0; /* + 0x20 0x10 */ - _MSCAN_RESERVED_(8, 2); /* + 0x22 */ - u16 canidar3_2; /* + 0x24 0x12 */ - _MSCAN_RESERVED_(9, 2); /* + 0x26 */ - u16 canidmr1_0; /* + 0x28 0x14 */ - _MSCAN_RESERVED_(10, 2); /* + 0x2a */ - u16 canidmr3_2; /* + 0x2c 0x16 */ - _MSCAN_RESERVED_(11, 2); /* + 0x2e */ - u16 canidar5_4; /* + 0x30 0x18 */ - _MSCAN_RESERVED_(12, 2); /* + 0x32 */ - u16 canidar7_6; /* + 0x34 0x1a */ - _MSCAN_RESERVED_(13, 2); /* + 0x36 */ - u16 canidmr5_4; /* + 0x38 0x1c */ - _MSCAN_RESERVED_(14, 2); /* + 0x3a */ - u16 canidmr7_6; /* + 0x3c 0x1e */ - _MSCAN_RESERVED_(15, 2); /* + 0x3e */ - struct { - u16 idr1_0; /* + 0x40 0x20 */ - _MSCAN_RESERVED_(16, 2); /* + 0x42 */ - u16 idr3_2; /* + 0x44 0x22 */ - _MSCAN_RESERVED_(17, 2); /* + 0x46 */ - u16 dsr1_0; /* + 0x48 0x24 */ - _MSCAN_RESERVED_(18, 2); /* + 0x4a */ - u16 dsr3_2; /* + 0x4c 0x26 */ - _MSCAN_RESERVED_(19, 2); /* + 0x4e */ - u16 dsr5_4; /* + 0x50 0x28 */ - _MSCAN_RESERVED_(20, 2); /* + 0x52 */ - u16 dsr7_6; /* + 0x54 0x2a */ - _MSCAN_RESERVED_(21, 2); /* + 0x56 */ - u8 dlr; /* + 0x58 0x2c */ - u8:8; /* + 0x59 0x2d */ - _MSCAN_RESERVED_(22, 2); /* + 0x5a */ - u16 time; /* + 0x5c 0x2e */ - } rx; - _MSCAN_RESERVED_(23, 2); /* + 0x5e */ - struct { - u16 idr1_0; /* + 0x60 0x30 */ - _MSCAN_RESERVED_(24, 2); /* + 0x62 */ - u16 idr3_2; /* + 0x64 0x32 */ - _MSCAN_RESERVED_(25, 2); /* + 0x66 */ - u16 dsr1_0; /* + 0x68 0x34 */ - _MSCAN_RESERVED_(26, 2); /* + 0x6a */ - u16 dsr3_2; /* + 0x6c 0x36 */ - _MSCAN_RESERVED_(27, 2); /* + 0x6e */ - u16 dsr5_4; /* + 0x70 0x38 */ - _MSCAN_RESERVED_(28, 2); /* + 0x72 */ - u16 dsr7_6; /* + 0x74 0x3a */ - _MSCAN_RESERVED_(29, 2); /* + 0x76 */ - u8 dlr; /* + 0x78 0x3c */ - u8 tbpr; /* + 0x79 0x3d */ - _MSCAN_RESERVED_(30, 2); /* + 0x7a */ - u16 time; /* + 0x7c 0x3e */ - } tx; - _MSCAN_RESERVED_(31, 2); /* + 0x7e */ -} __attribute__ ((packed)); - -#undef _MSCAN_RESERVED_ -#define MSCAN_REGION sizeof(struct mscan) - -#define MSCAN_WATCHDOG_TIMEOUT ((500*HZ)/1000) - -struct mscan_platform_data { - u8 clock_src; /* MSCAN_CLKSRC_BUS or MSCAN_CLKSRC_XTAL */ - u32 clock_frq; /* can ref. clock, in Hz */ -}; - -struct net_device *alloc_mscandev(void); -/* @clock_src: - 1 = The MSCAN clock source is the onchip Bus Clock. - 0 = The MSCAN clock source is the chip Oscillator Clock. -*/ -extern int register_mscandev(struct net_device *dev, int clock_src); -extern void unregister_mscandev(struct net_device *dev); - -#endif /* __MSCAN_H__ */ diff --git a/drivers/net/can/sja1000/ixxat_pci.c b/drivers/net/can/sja1000/ixxat_pci.c deleted file mode 100644 index 4768a610b70..00000000000 --- a/drivers/net/can/sja1000/ixxat_pci.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com> - * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/delay.h> -#include <linux/pci.h> -#include <linux/can.h> -#include <linux/can/dev.h> -#include <linux/io.h> - -#include "sja1000.h" - -#define DRV_NAME "ixxat_pci" - -MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); -MODULE_DESCRIPTION("Socket-CAN driver for IXXAT PC-I 04/PCI PCI cards"); -MODULE_SUPPORTED_DEVICE("IXXAT PC-I 04/PCI card"); -MODULE_LICENSE("GPL v2"); - -/* Maximum number of interfaces supported on one card. Currently - * we only support a maximum of two interfaces, which is the maximum - * of what Ixxat sells anyway. - */ -#define IXXAT_PCI_MAX_CAN 2 - -struct ixxat_pci { - struct pci_dev *pci_dev; - struct net_device *dev[IXXAT_PCI_MAX_CAN]; - int conf_addr; - void __iomem *base_addr; -}; - -#define IXXAT_PCI_CAN_CLOCK (16000000 / 2) - -#define IXXAT_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX0_INVERT | \ - OCR_TX1_PUSHPULL) -#define IXXAT_PCI_CDR 0 - -#define CHANNEL_RESET_OFFSET 0x110 -#define CHANNEL_OFFSET 0x200 - -#define INTCSR_OFFSET 0x4c /* Offset in PLX9050 conf registers */ -#define INTCSR_LINTI1 (1 << 0) -#define INTCSR_LINTI2 (1 << 3) -#define INTCSR_PCI (1 << 6) - -/* PCI vender, device and sub-device ID */ -#define IXXAT_PCI_VENDOR_ID 0x10b5 -#define IXXAT_PCI_DEVICE_ID 0x9050 -#define IXXAT_PCI_SUB_SYS_ID 0x2540 - -#define IXXAT_PCI_BASE_SIZE 0x400 - -static struct pci_device_id ixxat_pci_tbl[] = { - {IXXAT_PCI_VENDOR_ID, IXXAT_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, ixxat_pci_tbl); - -static u8 ixxat_pci_read_reg(struct net_device *ndev, int port) -{ - u8 val; - val = readb((void __iomem *)(ndev->base_addr + port)); - return val; -} - -static void ixxat_pci_write_reg(struct net_device *ndev, int port, u8 val) -{ - writeb(val, (void __iomem *)(ndev->base_addr + port)); -} - -static void ixxat_pci_del_chan(struct pci_dev *pdev, struct net_device *ndev) -{ - dev_info(&pdev->dev, "Removing device %s\n", ndev->name); - - unregister_sja1000dev(ndev); - - free_sja1000dev(ndev); -} - -static struct net_device *ixxat_pci_add_chan(struct pci_dev *pdev, - void __iomem *base_addr) -{ - struct net_device *ndev; - struct sja1000_priv *priv; - int err; - - ndev = alloc_sja1000dev(0); - if (ndev == NULL) - return ERR_PTR(-ENOMEM); - - priv = netdev_priv(ndev); - - ndev->base_addr = (unsigned long)base_addr; - - priv->read_reg = ixxat_pci_read_reg; - priv->write_reg = ixxat_pci_write_reg; - - priv->can.bittiming.clock = IXXAT_PCI_CAN_CLOCK; - - priv->ocr = IXXAT_PCI_OCR; - priv->cdr = IXXAT_PCI_CDR; - - /* Set and enable PCI interrupts */ - ndev->irq = pdev->irq; - - dev_dbg(&pdev->dev, "base_addr=%#lx irq=%d\n", - ndev->base_addr, ndev->irq); - - SET_NETDEV_DEV(ndev, &pdev->dev); - - err = register_sja1000dev(ndev); - if (err) { - dev_err(&pdev->dev, "Failed to register (err=%d)\n", err); - goto failure; - } - - return ndev; - -failure: - free_sja1000dev(ndev); - return ERR_PTR(err); -} - -static int __devinit ixxat_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct ixxat_pci *board; - int err, intcsr = INTCSR_LINTI1 | INTCSR_PCI; - u16 sub_sys_id; - void __iomem *base_addr; - - dev_info(&pdev->dev, "Initializing device %04x:%04x\n", - pdev->vendor, pdev->device); - - board = kzalloc(sizeof(*board), GFP_KERNEL); - if (!board) - return -ENOMEM; - - err = pci_enable_device(pdev); - if (err) - goto failure; - - err = pci_request_regions(pdev, DRV_NAME); - if (err) - goto failure; - - err = pci_read_config_word(pdev, 0x2e, &sub_sys_id); - if (err) - goto failure_release_pci; - - if (sub_sys_id != IXXAT_PCI_SUB_SYS_ID) - return -ENODEV; - - /* Enable memory and I/O space */ - err = pci_write_config_word(pdev, 0x04, 0x3); - if (err) - goto failure_release_pci; - - board->conf_addr = pci_resource_start(pdev, 1); - - base_addr = pci_iomap(pdev, 2, IXXAT_PCI_BASE_SIZE); - if (base_addr == 0) { - err = -ENODEV; - goto failure_release_pci; - } - - board->base_addr = base_addr; - - writeb(0x1, base_addr + CHANNEL_RESET_OFFSET); - writeb(0x1, base_addr + CHANNEL_OFFSET + CHANNEL_RESET_OFFSET); - udelay(100); - - board->dev[0] = ixxat_pci_add_chan(pdev, base_addr); - if (IS_ERR(board->dev[0])) - goto failure_iounmap; - - /* Check if second channel is available */ - if (readb(base_addr + CHANNEL_OFFSET + REG_MOD) == 0x21 && - readb(base_addr + CHANNEL_OFFSET + REG_SR) == 0x0c && - readb(base_addr + CHANNEL_OFFSET + REG_IR) == 0xe0) { - board->dev[1] = ixxat_pci_add_chan(pdev, - base_addr + CHANNEL_OFFSET); - if (IS_ERR(board->dev[1])) - goto failure_unreg_dev0; - - intcsr |= INTCSR_LINTI2; - } - - /* enable interrupt(s) in PLX9050 */ - outb(intcsr, board->conf_addr + INTCSR_OFFSET); - - pci_set_drvdata(pdev, board); - - return 0; - -failure_unreg_dev0: - ixxat_pci_del_chan(pdev, board->dev[0]); - -failure_iounmap: - pci_iounmap(pdev, board->base_addr); - -failure_release_pci: - pci_release_regions(pdev); - -failure: - kfree(board); - - return err; -} - -static void __devexit ixxat_pci_remove_one(struct pci_dev *pdev) -{ - struct ixxat_pci *board = pci_get_drvdata(pdev); - int i; - - /* Disable interrupts in PLX9050*/ - outb(0, board->conf_addr + INTCSR_OFFSET); - - for (i = 0; i < IXXAT_PCI_MAX_CAN; i++) { - if (!board->dev[i]) - break; - ixxat_pci_del_chan(pdev, board->dev[i]); - } - - pci_iounmap(pdev, board->base_addr); - - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - - kfree(board); -} - -static struct pci_driver ixxat_pci_driver = { - .name = DRV_NAME, - .id_table = ixxat_pci_tbl, - .probe = ixxat_pci_init_one, - .remove = __devexit_p(ixxat_pci_remove_one), -}; - -static int __init ixxat_pci_init(void) -{ - return pci_register_driver(&ixxat_pci_driver); -} - -static void __exit ixxat_pci_exit(void) -{ - pci_unregister_driver(&ixxat_pci_driver); -} - -module_init(ixxat_pci_init); -module_exit(ixxat_pci_exit); diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c deleted file mode 100644 index d1089a3d62e..00000000000 --- a/drivers/net/can/sja1000/peak_pci.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com> - * - * Derived from the PCAN project file driver/src/pcan_pci.c: - * - * Copyright (C) 2001-2006 PEAK System-Technik GmbH - * - * 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, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/delay.h> -#include <linux/pci.h> -#include <linux/can.h> -#include <linux/can/dev.h> -#include <linux/io.h> - -#include "sja1000.h" - -#define DRV_NAME "peak_pci" - -MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); -MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI cards"); -MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI CAN card"); -MODULE_LICENSE("GPL v2"); - -struct peak_pci { - int channel; - struct pci_dev *pci_dev; - struct net_device *slave_dev; - volatile void __iomem *conf_addr; -}; - -#define PEAK_PCI_SINGLE 0 /* single channel device */ -#define PEAK_PCI_MASTER 1 /* multi channel master device */ -#define PEAK_PCI_SLAVE 2 /* multi channel slave device */ - -#define PEAK_PCI_CAN_CLOCK (16000000 / 2) - -#define PEAK_PCI_CDR_SINGLE (CDR_CBP | CDR_CLKOUT_MASK | CDR_CLK_OFF) -#define PEAK_PCI_CDR_MASTER (CDR_CBP | CDR_CLKOUT_MASK) - -#define PEAK_PCI_OCR OCR_TX0_PUSHPULL - -/* - * Important PITA registers - */ -#define PITA_ICR 0x00 /* interrupt control register */ -#define PITA_GPIOICR 0x18 /* general purpose I/O interface - control register */ -#define PITA_MISC 0x1C /* miscellanoes register */ - -#define PCI_CONFIG_PORT_SIZE 0x1000 /* size of the config io-memory */ -#define PCI_PORT_SIZE 0x0400 /* size of a channel io-memory */ - -#define PEAK_PCI_VENDOR_ID 0x001C /* the PCI device and vendor IDs */ -#define PEAK_PCI_DEVICE_ID 0x0001 - -static struct pci_device_id peak_pci_tbl[] = { - {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, peak_pci_tbl); - -static u8 peak_pci_read_reg(struct net_device *dev, int port) -{ - u8 val; - val = readb((const volatile void __iomem *) - (dev->base_addr + (port << 2))); - return val; -} - -static void peak_pci_write_reg(struct net_device *dev, int port, u8 val) -{ - writeb(val, (volatile void __iomem *) - (dev->base_addr + (port << 2))); -} - -static void peak_pci_post_irq(struct net_device *dev) -{ - struct sja1000_priv *priv = netdev_priv(dev); - struct peak_pci *board = priv->priv; - u16 icr_low; - - /* Select and clear in Pita stored interrupt */ - icr_low = readw(board->conf_addr + PITA_ICR); - if (board->channel == PEAK_PCI_SLAVE) { - if (icr_low & 0x0001) - writew(0x0001, board->conf_addr + PITA_ICR); - } else { - if (icr_low & 0x0002) - writew(0x0002, board->conf_addr + PITA_ICR); - } -} - -static void peak_pci_del_chan(struct net_device *dev, int init_step) -{ - struct sja1000_priv *priv = netdev_priv(dev); - struct peak_pci *board; - u16 icr_high; - - if (!dev) - return; - priv = netdev_priv(dev); - if (!priv) - return; - board = priv->priv; - if (!board) - return; - - switch (init_step) { - case 0: /* Full cleanup */ - printk(KERN_INFO "Removing %s device %s\n", - DRV_NAME, dev->name); - unregister_sja1000dev(dev); - case 4: - icr_high = readw(board->conf_addr + PITA_ICR + 2); - if (board->channel == PEAK_PCI_SLAVE) - icr_high &= ~0x0001; - else - icr_high &= ~0x0002; - writew(icr_high, board->conf_addr + PITA_ICR + 2); - case 3: - iounmap((void *)dev->base_addr); - case 2: - if (board->channel != PEAK_PCI_SLAVE) - iounmap((void *)board->conf_addr); - case 1: - free_sja1000dev(dev); - break; - } - -} - -static int peak_pci_add_chan(struct pci_dev *pdev, int channel, - struct net_device **master_dev) -{ - struct net_device *dev; - struct sja1000_priv *priv; - struct peak_pci *board; - u16 icr_high; - unsigned long addr; - int err, init_step; - - dev = alloc_sja1000dev(sizeof(struct peak_pci)); - if (dev == NULL) - return -ENOMEM; - init_step = 1; - - priv = netdev_priv(dev); - board = priv->priv; - - board->pci_dev = pdev; - board->channel = channel; - - if (channel != PEAK_PCI_SLAVE) { - - addr = pci_resource_start(pdev, 0); - board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE); - if (board->conf_addr == 0) { - err = -ENODEV; - goto failure; - } - init_step = 2; - - /* Set GPIO control register */ - writew(0x0005, board->conf_addr + PITA_GPIOICR + 2); - - /* Enable single or dual channel */ - if (channel == PEAK_PCI_MASTER) - writeb(0x00, board->conf_addr + PITA_GPIOICR); - else - writeb(0x04, board->conf_addr + PITA_GPIOICR); - /* Toggle reset */ - writeb(0x05, board->conf_addr + PITA_MISC + 3); - mdelay(5); - /* Leave parport mux mode */ - writeb(0x04, board->conf_addr + PITA_MISC + 3); - } else { - struct sja1000_priv *master_priv = netdev_priv(*master_dev); - struct peak_pci *master_board = master_priv->priv; - master_board->slave_dev = dev; - board->conf_addr = master_board->conf_addr; - } - - addr = pci_resource_start(pdev, 1); - if (channel == PEAK_PCI_SLAVE) - addr += PCI_PORT_SIZE; - - dev->base_addr = (unsigned long)ioremap(addr, PCI_PORT_SIZE); - if (dev->base_addr == 0) { - err = -ENOMEM; - goto failure; - } - init_step = 3; - - priv->read_reg = peak_pci_read_reg; - priv->write_reg = peak_pci_write_reg; - priv->post_irq = peak_pci_post_irq; - - priv->can.bittiming.clock = PEAK_PCI_CAN_CLOCK; - - priv->ocr = PEAK_PCI_OCR; - - if (channel == PEAK_PCI_MASTER) - priv->cdr = PEAK_PCI_CDR_MASTER; - else - priv->cdr = PEAK_PCI_CDR_SINGLE; - - /* Register and setup interrupt handling */ - dev->irq = pdev->irq; - icr_high = readw(board->conf_addr + PITA_ICR + 2); - if (channel == PEAK_PCI_SLAVE) - icr_high |= 0x0001; - else - icr_high |= 0x0002; - writew(icr_high, board->conf_addr + PITA_ICR + 2); - init_step = 4; - - SET_NETDEV_DEV(dev, &pdev->dev); - - /* Register SJA1000 device */ - err = register_sja1000dev(dev); - if (err) { - printk(KERN_ERR "Registering %s device failed (err=%d)\n", - DRV_NAME, err); - goto failure; - } - - if (channel != PEAK_PCI_SLAVE) - *master_dev = dev; - - printk(KERN_INFO "%s: %s at base_addr=%#lx conf_addr=%p irq=%d\n", - DRV_NAME, dev->name, dev->base_addr, board->conf_addr, dev->irq); - - return 0; - -failure: - peak_pci_del_chan(dev, init_step); - return err; -} - -static int __devinit peak_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int err; - u16 sub_sys_id; - struct net_device *master_dev = NULL; - - printk(KERN_INFO "%s: initializing device %04x:%04x\n", - DRV_NAME, pdev->vendor, pdev->device); - - err = pci_enable_device(pdev); - if (err) - goto failure; - - err = pci_request_regions(pdev, DRV_NAME); - if (err) - goto failure; - - err = pci_read_config_word(pdev, 0x2e, &sub_sys_id); - if (err) - goto failure_cleanup; - - err = pci_write_config_word(pdev, 0x44, 0); - if (err) - goto failure_cleanup; - - if (sub_sys_id > 3) { - err = peak_pci_add_chan(pdev, - PEAK_PCI_MASTER, &master_dev); - if (err) - goto failure_cleanup; - - err = peak_pci_add_chan(pdev, - PEAK_PCI_SLAVE, &master_dev); - if (err) - goto failure_cleanup; - } else { - err = peak_pci_add_chan(pdev, PEAK_PCI_SINGLE, - &master_dev); - if (err) - goto failure_cleanup; - } - - pci_set_drvdata(pdev, master_dev); - return 0; - -failure_cleanup: - if (master_dev) - peak_pci_del_chan(master_dev, 0); - - pci_release_regions(pdev); - -failure: - return err; - -} - -static void __devexit peak_pci_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct sja1000_priv *priv = netdev_priv(dev); - struct peak_pci *board = priv->priv; - - if (board->slave_dev) - peak_pci_del_chan(board->slave_dev, 0); - peak_pci_del_chan(dev, 0); - - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); -} - -static struct pci_driver peak_pci_driver = { - .name = DRV_NAME, - .id_table = peak_pci_tbl, - .probe = peak_pci_init_one, - .remove = __devexit_p(peak_pci_remove_one), -}; - -static int __init peak_pci_init(void) -{ - return pci_register_driver(&peak_pci_driver); -} - -static void __exit peak_pci_exit(void) -{ - pci_unregister_driver(&peak_pci_driver); -} - -module_init(peak_pci_init); -module_exit(peak_pci_exit); diff --git a/drivers/net/can/sja1000/pipcan.c b/drivers/net/can/sja1000/pipcan.c deleted file mode 100644 index 9b51c0a4ce8..00000000000 --- a/drivers/net/can/sja1000/pipcan.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2008 David Müller, <d.mueller@elsoft.ch> - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/can.h> -#include <linux/can/dev.h> -#include <linux/io.h> - -#include "sja1000.h" - -#define DRV_NAME "pipcan" - -MODULE_AUTHOR("David Müller <d.mueller@elsoft.ch>"); -MODULE_DESCRIPTION("Socket-CAN driver for MPL PIPCAN module"); -MODULE_SUPPORTED_DEVICE("MPL PIPCAN module"); -MODULE_LICENSE("GPL v2"); - -#define PIPCAN_CAN_CLOCK (16000000 / 2) - -#define PIPCAN_OCR (OCR_TX1_PUSHPULL) -#define PIPCAN_CDR (CDR_CBP | CDR_CLK_OFF) - -#define PIPCAN_IOSIZE (0x100) - -#define PIPCAN_RES (0x804) -#define PIPCAN_RST (0x805) - -static u8 pc_read_reg(struct net_device *dev, int reg) -{ - return inb(dev->base_addr + reg); -} - -static void pc_write_reg(struct net_device *dev, int reg, u8 val) -{ - outb(val, dev->base_addr + reg); -} - -static int __init pc_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct sja1000_priv *priv; - struct resource *res; - int rc, irq; - - rc = -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - irq = platform_get_irq(pdev, 0); - if (!res || !irq) - goto exit; - - rc = -EBUSY; - if (!request_region(res->start, res->end - res->start + 1, DRV_NAME)) - goto exit; - - rc = -ENOMEM; - dev = alloc_sja1000dev(0); - if (!dev) - goto exit_release; - - priv = netdev_priv(dev); - - priv->read_reg = pc_read_reg; - priv->write_reg = pc_write_reg; - priv->can.bittiming.clock = PIPCAN_CAN_CLOCK; - priv->ocr = PIPCAN_OCR; - priv->cdr = PIPCAN_CDR; - - dev->irq = irq; - dev->base_addr = res->start; - - dev_set_drvdata(&pdev->dev, dev); - - /* deactivate RST */ - outb(inb(PIPCAN_RST) & ~0x01, PIPCAN_RST); - - rc = register_sja1000dev(dev); - if (rc) { - dev_err(&pdev->dev, "registering %s failed (err=%d)\n", - DRV_NAME, rc); - goto exit_free; - } - - dev_info(&pdev->dev, "device registered (base_addr=%#lx, irq=%d)\n", - dev->base_addr, dev->irq); - return 0; - -exit_free: - free_sja1000dev(dev); - -exit_release: - release_region(res->start, res->end - res->start + 1); - -exit: - return rc; -} - -static int __exit pc_remove(struct platform_device *pdev) -{ - struct net_device *dev = dev_get_drvdata(&pdev->dev); - struct resource *res; - - dev_set_drvdata(&pdev->dev, NULL); - unregister_sja1000dev(dev); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - - free_sja1000dev(dev); - - release_region(res->start, res->end - res->start + 1); - - /* activate RST */ - outb(inb(PIPCAN_RST) | 0x01, PIPCAN_RST); - - return 0; -} - -static struct platform_driver pc_driver = { - .remove = __exit_p(pc_remove), - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, -}; - -static struct platform_device *pc_pdev; -static const u16 pipcan_ioport[] = {0x1000, 0x8000, 0xE000}; - -static int __init pc_init(void) -{ - struct resource r[2]; - int rc, addr, irq, idx; - u8 pc_res; - - /* get PIPCAN resources from EPLD */ - pc_res = inb(PIPCAN_RES); - - idx = (pc_res & 0x0F); - if ((idx <= 0) || (idx > ARRAY_SIZE(pipcan_ioport))) { - printk(KERN_ERR DRV_NAME " invalid base address\n"); - return -EINVAL; - } - addr = pipcan_ioport[idx-1]; - - irq = (pc_res >> 4) & 0x0F; - if ((irq < 3) || (irq == 8) || (irq == 13)) { - printk(KERN_ERR DRV_NAME " invalid IRQ\n"); - return -EINVAL; - } - - /* fill in resources */ - r[0].start = addr; - r[0].end = addr + PIPCAN_IOSIZE - 1; - r[0].name = DRV_NAME; - r[0].flags = IORESOURCE_IO; - r[1].start = r[1].end = irq; - r[1].name = DRV_NAME; - r[1].flags = IORESOURCE_IRQ; - - pc_pdev = platform_device_register_simple(DRV_NAME, 0, r, - ARRAY_SIZE(r)); - if (IS_ERR(pc_pdev)) - return PTR_ERR(pc_pdev); - - rc = platform_driver_probe(&pc_driver, pc_probe); - if (rc) { - platform_device_unregister(pc_pdev); - printk(KERN_ERR DRV_NAME - " platform_driver_probe() failed (%d)\n", rc); - } - - return rc; -} - -static void __exit pc_exit(void) -{ - platform_driver_unregister(&pc_driver); - platform_device_unregister(pc_pdev); -} - -module_init(pc_init); -module_exit(pc_exit); diff --git a/drivers/net/can/sysfs.c b/drivers/net/can/sysfs.c deleted file mode 100644 index 746f6410cbe..00000000000 --- a/drivers/net/can/sysfs.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (C) 2007-2008 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/capability.h> -#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <net/sock.h> -#include <linux/rtnetlink.h> - -#include <linux/can.h> -#include <linux/can/dev.h> - -#include "sysfs.h" - -#ifdef CONFIG_SYSFS - -/* - * SYSFS access functions and attributes. Use same locking as - * net/core/net-sysfs.c does. - */ -static inline int dev_isalive(const struct net_device *dev) -{ - return dev->reg_state <= NETREG_REGISTERED; -} - -/* use same locking rules as GIF* ioctl's */ -static ssize_t can_dev_show(struct device *d, - struct device_attribute *attr, char *buf, - ssize_t (*fmt)(struct net_device *, char *)) -{ - struct net_device *dev = to_net_dev(d); - ssize_t ret = -EINVAL; - - read_lock(&dev_base_lock); - if (dev_isalive(dev)) - ret = (*fmt)(dev, buf); - read_unlock(&dev_base_lock); - - return ret; -} - -/* generate a show function for simple field */ -#define CAN_DEV_SHOW(field, fmt_string) \ -static ssize_t fmt_can_##field(struct net_device *dev, char *buf) \ -{ \ - struct can_priv *priv = netdev_priv(dev); \ - return sprintf(buf, fmt_string, priv->field); \ -} \ -static ssize_t show_can_##field(struct device *d, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return can_dev_show(d, attr, buf, fmt_can_##field); \ -} - -/* use same locking and permission rules as SIF* ioctl's */ -static ssize_t can_dev_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len, - int (*set)(struct net_device *, unsigned long)) -{ - struct net_device *dev = to_net_dev(d); - unsigned long new; - int ret = -EINVAL; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - ret = strict_strtoul(buf, 0, &new); - if (ret) - goto out; - - rtnl_lock(); - if (dev_isalive(dev)) { - ret = (*set)(dev, new); - if (!ret) - ret = len; - } - rtnl_unlock(); -out: - return ret; -} - -#define CAN_CREATE_FILE(_dev, _name) \ - if (device_create_file(&_dev->dev, &dev_attr_##_name)) \ - dev_err(ND2D(_dev), \ - "Couldn't create device file for ##_name\n") - -#define CAN_REMOVE_FILE(_dev, _name) \ - device_remove_file(&_dev->dev, &dev_attr_##_name) \ - -CAN_DEV_SHOW(ctrlmode, "0x%x\n"); - -static int change_can_ctrlmode(struct net_device *dev, unsigned long ctrlmode) -{ - struct can_priv *priv = netdev_priv(dev); - int err = 0; - - if (priv->state != CAN_STATE_STOPPED) - return -EBUSY; - - if (priv->do_set_ctrlmode) - err = priv->do_set_ctrlmode(dev, ctrlmode); - - if (!err) - priv->ctrlmode = ctrlmode; - - return err; -} - -static ssize_t store_can_ctrlmode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - return can_dev_store(dev, attr, buf, len, change_can_ctrlmode); -} - -static DEVICE_ATTR(can_ctrlmode, S_IRUGO | S_IWUSR, - show_can_ctrlmode, store_can_ctrlmode); - -static const char *can_state_names[] = { - "active", "bus-warn", "bus-pass" , "bus-off", - "stopped", "sleeping", "unkown" -}; - -static ssize_t printf_can_state(struct net_device *dev, char *buf) -{ - struct can_priv *priv = netdev_priv(dev); - enum can_state state; - int err = 0; - - if (priv->do_get_state) { - err = priv->do_get_state(dev, &state); - if (err) - goto out; - priv->state = state; - } else - state = priv->state; - - if (state >= ARRAY_SIZE(can_state_names)) - state = ARRAY_SIZE(can_state_names) - 1; - err = sprintf(buf, "%s\n", can_state_names[state]); -out: - return err; -} - -static ssize_t show_can_state(struct device *d, - struct device_attribute *attr, char *buf) -{ - return can_dev_show(d, attr, buf, printf_can_state); -} - -static DEVICE_ATTR(can_state, S_IRUGO, show_can_state, NULL); - -CAN_DEV_SHOW(restart_ms, "%d\n"); - -static int change_can_restart_ms(struct net_device *dev, unsigned long ms) -{ - struct can_priv *priv = netdev_priv(dev); - - if (priv->restart_ms < 0) - return -EOPNOTSUPP; - priv->restart_ms = ms; - return 0; -} - -static ssize_t store_can_restart_ms(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - return can_dev_store(dev, attr, buf, len, change_can_restart_ms); -} - -static DEVICE_ATTR(can_restart_ms, S_IRUGO | S_IWUSR, - show_can_restart_ms, store_can_restart_ms); - -static ssize_t printf_can_echo(struct net_device *dev, char *buf) -{ - return sprintf(buf, "%d\n", dev->flags & IFF_ECHO ? 1 : 0); -} - -static ssize_t show_can_echo(struct device *d, - struct device_attribute *attr, char *buf) -{ - return can_dev_show(d, attr, buf, printf_can_echo); -} - -static int change_can_echo(struct net_device *dev, unsigned long on) -{ - if (on) - dev->flags |= IFF_ECHO; - else - dev->flags &= ~IFF_ECHO; - return 0; -} - -static ssize_t store_can_echo(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - return can_dev_store(dev, attr, buf, len, change_can_echo); -} - -static DEVICE_ATTR(can_echo, S_IRUGO | S_IWUSR, show_can_echo, store_can_echo); - -static int change_can_restart(struct net_device *dev, unsigned long on) -{ - return can_restart_now(dev); -} - -static ssize_t store_can_restart(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - return can_dev_store(dev, attr, buf, len, change_can_restart); -} - -static DEVICE_ATTR(can_restart, S_IWUSR, NULL, store_can_restart); - -/* Show a given attribute if the CAN bittiming group */ -static ssize_t can_btc_show(const struct device *d, - struct device_attribute *attr, char *buf, - unsigned long offset) -{ - struct net_device *dev = to_net_dev(d); - struct can_priv *priv = netdev_priv(dev); - struct can_bittiming_const *btc = priv->bittiming_const; - ssize_t ret = -EINVAL; - - WARN_ON(offset >= sizeof(struct can_bittiming_const) || - offset % sizeof(u32) != 0); - - read_lock(&dev_base_lock); - if (dev_isalive(dev) && btc) - ret = sprintf(buf, "%d\n", - *(u32 *)(((u8 *)btc) + offset)); - - read_unlock(&dev_base_lock); - return ret; -} - -/* Generate a read-only bittiming const attribute */ -#define CAN_BT_CONST_ENTRY(name) \ -static ssize_t show_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ -{ \ - return can_btc_show(d, attr, buf, \ - offsetof(struct can_bittiming_const, name));\ -} \ -static DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL) - -CAN_BT_CONST_ENTRY(tseg1_min); -CAN_BT_CONST_ENTRY(tseg1_max); -CAN_BT_CONST_ENTRY(tseg2_min); -CAN_BT_CONST_ENTRY(tseg2_max); -CAN_BT_CONST_ENTRY(sjw_max); -CAN_BT_CONST_ENTRY(brp_min); -CAN_BT_CONST_ENTRY(brp_max); -CAN_BT_CONST_ENTRY(brp_inc); - -static ssize_t can_bt_show(const struct device *d, - struct device_attribute *attr, char *buf, - unsigned long offset) -{ - struct net_device *dev = to_net_dev(d); - struct can_priv *priv = netdev_priv(dev); - struct can_bittiming *bt = &priv->bittiming; - ssize_t ret = -EINVAL; - u32 *ptr, val; - - WARN_ON(offset >= sizeof(struct can_bittiming) || - offset % sizeof(u32) != 0); - - read_lock(&dev_base_lock); - if (dev_isalive(dev)) { - ptr = (u32 *)(((u8 *)bt) + offset); - if (ptr == &bt->sample_point && - priv->state != CAN_STATE_STOPPED) - val = can_sample_point(bt); - else - val = *ptr; - ret = sprintf(buf, "%d\n", val); - } - read_unlock(&dev_base_lock); - return ret; -} - -static ssize_t can_bt_store(const struct device *d, - struct device_attribute *attr, - const char *buf, size_t count, - unsigned long offset) -{ - struct net_device *dev = to_net_dev(d); - struct can_priv *priv = netdev_priv(dev); - struct can_bittiming *bt = &priv->bittiming; - unsigned long new; - ssize_t ret = -EINVAL; - u32 *ptr; - - if (priv->state != CAN_STATE_STOPPED) - return -EBUSY; - - WARN_ON(offset >= sizeof(struct can_bittiming) || - offset % sizeof(u32) != 0); - - ret = strict_strtoul(buf, 0, &new); - if (ret) - goto out; - - ptr = (u32 *)(((u8 *)bt) + offset); - rtnl_lock(); - if (dev_isalive(dev)) { - *ptr = (u32)new; - - if ((ptr == &bt->bitrate) || (ptr == &bt->sample_point)) { - bt->tq = 0; - bt->brp = 0; - bt->sjw = 0; - bt->prop_seg = 0; - bt->phase_seg1 = 0; - bt->phase_seg2 = 0; - } else { - bt->bitrate = 0; - bt->sample_point = 0; - } - ret = count; - } - rtnl_unlock(); -out: - return ret; -} - -#define CAN_BT_ENTRY_RO(name) \ -static ssize_t show_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ -{ \ - return can_bt_show(d, attr, buf, \ - offsetof(struct can_bittiming, name)); \ -} \ -static DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL) - -CAN_BT_ENTRY_RO(clock); - -#define CAN_BT_ENTRY(name) \ -static ssize_t show_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ -{ \ - return can_bt_show(d, attr, buf, \ - offsetof(struct can_bittiming, name)); \ -} \ -static ssize_t store_##name(struct device *d, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - return can_bt_store(d, attr, buf, count, \ - offsetof(struct can_bittiming, name)); \ -} \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) - -CAN_BT_ENTRY(bitrate); -CAN_BT_ENTRY(sample_point); -CAN_BT_ENTRY(tq); -CAN_BT_ENTRY(prop_seg); -CAN_BT_ENTRY(phase_seg1); -CAN_BT_ENTRY(phase_seg2); -CAN_BT_ENTRY(sjw); - -static struct attribute *can_bittiming_attrs[] = { - &dev_attr_hw_tseg1_min.attr, - &dev_attr_hw_tseg1_max.attr, - &dev_attr_hw_tseg2_max.attr, - &dev_attr_hw_tseg2_min.attr, - &dev_attr_hw_sjw_max.attr, - &dev_attr_hw_brp_min.attr, - &dev_attr_hw_brp_max.attr, - &dev_attr_hw_brp_inc.attr, - &dev_attr_hw_clock.attr, - &dev_attr_bitrate.attr, - &dev_attr_sample_point.attr, - &dev_attr_tq.attr, - &dev_attr_prop_seg.attr, - &dev_attr_phase_seg1.attr, - &dev_attr_phase_seg2.attr, - &dev_attr_sjw.attr, - NULL -}; - -static struct attribute_group can_bittiming_group = { - .name = "can_bittiming", - .attrs = can_bittiming_attrs, -}; - -/* Show a given attribute in the CAN statistics group */ -static ssize_t can_stat_show(const struct device *d, - struct device_attribute *attr, char *buf, - unsigned long offset) -{ - struct net_device *dev = to_net_dev(d); - struct can_priv *priv = netdev_priv(dev); - struct can_device_stats *stats = &priv->can_stats; - ssize_t ret = -EINVAL; - - WARN_ON(offset >= sizeof(struct can_device_stats) || - offset % sizeof(unsigned long) != 0); - - read_lock(&dev_base_lock); - if (dev_isalive(dev)) - ret = sprintf(buf, "%ld\n", - *(unsigned long *)(((u8 *)stats) + offset)); - - read_unlock(&dev_base_lock); - return ret; -} - -/* Generate a read-only CAN statistics attribute */ -#define CAN_STAT_ENTRY(name) \ -static ssize_t show_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ -{ \ - return can_stat_show(d, attr, buf, \ - offsetof(struct can_device_stats, name)); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) - -CAN_STAT_ENTRY(error_warning); -CAN_STAT_ENTRY(error_passive); -CAN_STAT_ENTRY(bus_error); -CAN_STAT_ENTRY(arbitration_lost); -CAN_STAT_ENTRY(data_overrun); -CAN_STAT_ENTRY(wakeup); -CAN_STAT_ENTRY(restarts); - -static struct attribute *can_statistics_attrs[] = { - &dev_attr_error_warning.attr, - &dev_attr_error_passive.attr, - &dev_attr_bus_error.attr, - &dev_attr_arbitration_lost.attr, - &dev_attr_data_overrun.attr, - &dev_attr_wakeup.attr, - &dev_attr_restarts.attr, - NULL -}; - -static struct attribute_group can_statistics_group = { - .name = "can_statistics", - .attrs = can_statistics_attrs, -}; - -void can_create_sysfs(struct net_device *dev) -{ - struct can_priv *priv = netdev_priv(dev); - int err; - - CAN_CREATE_FILE(dev, can_ctrlmode); - CAN_CREATE_FILE(dev, can_echo); - CAN_CREATE_FILE(dev, can_restart); - CAN_CREATE_FILE(dev, can_state); - CAN_CREATE_FILE(dev, can_restart_ms); - - err = sysfs_create_group(&(dev->dev.kobj), - &can_statistics_group); - if (err) { - printk(KERN_EMERG - "couldn't create sysfs group for CAN statistics\n"); - } - - if (priv->bittiming_const) { - err = sysfs_create_group(&(dev->dev.kobj), - &can_bittiming_group); - if (err) { - printk(KERN_EMERG "couldn't create sysfs " - "group for CAN bittiming\n"); - } - } -} - -void can_remove_sysfs(struct net_device *dev) -{ - struct can_priv *priv = netdev_priv(dev); - - CAN_REMOVE_FILE(dev, can_ctrlmode); - CAN_REMOVE_FILE(dev, can_echo); - CAN_REMOVE_FILE(dev, can_state); - CAN_REMOVE_FILE(dev, can_restart); - CAN_REMOVE_FILE(dev, can_restart_ms); - - sysfs_remove_group(&(dev->dev.kobj), &can_statistics_group); - if (priv->bittiming_const) - sysfs_remove_group(&(dev->dev.kobj), &can_bittiming_group); -} - -#endif /* CONFIG_SYSFS */ - - - diff --git a/drivers/net/can/sysfs.h b/drivers/net/can/sysfs.h deleted file mode 100644 index e21f2fa4b15..00000000000 --- a/drivers/net/can/sysfs.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2007 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CAN_SYSFS_H -#define CAN_SYSFS_H - -void can_create_sysfs(struct net_device *dev); -void can_remove_sysfs(struct net_device *dev); - -#endif /* CAN_SYSFS_H */ diff --git a/include/linux/can/sja1000_platform.h b/include/linux/can/sja1000_platform.h deleted file mode 100644 index adde3cf837d..00000000000 --- a/include/linux/can/sja1000_platform.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _CAN_SJA1000_PLATFORM_H_ -#define _CAN_SJA1000_PLATFORM_H_ - -struct sja1000_platform_data { - u32 clock; /* CAN bus oscillator frequency in Hz */ - - u8 ocr; /* output control register */ - u8 cdr; /* clock divider register */ -}; - -#endif /* !_CAN_SJA1000_PLATFORM_H_ */ |