Re: [can-next] can: remove Softing CANcard driver
Oliver Hartkopp <[email protected]>
| Newsgroups | org.kernel.vger.linux-can |
|---|---|
| Message-ID | <[email protected]> |
Hi Kurt, sorry for picking the old mail address I found in the code. I'm suggesting to remove your softing driver from 2010. Are you fine with it? Best regards, Oliver On 15.08.26 12:34, Oliver Hartkopp wrote: > The PCMCIA Softing CANcard2 is discontinued since 2013 and the latest > Windows drivers date back to Windows 7/8. The CANcard2 and also the > rebranded Vector CANcardXL make use of a firmware to drive its onboard > CPU to handle raw CAN messages (DPRAM) and its capability to perform > timing critical Classical CAN protocols like ISO 15765-2:2004. > > The Softing Linux driver supported none of those higher layer CAN > protocols but only raw CAN CC traffic. In 2026 this functionality is > substituted with cost-effective USB CAN adapters, e.g. gs_usb. > > Remove the softing driver as there's no known user and we lack the access > to this at least 25 y/o hardware for 10 years now. > > Cc: Kurt Van Dijck <[email protected]> > Signed-off-by: Oliver Hartkopp <[email protected]> > --- > drivers/net/can/Kconfig | 1 - > drivers/net/can/Makefile | 1 - > drivers/net/can/softing/Kconfig | 31 - > drivers/net/can/softing/Makefile | 5 - > drivers/net/can/softing/softing.h | 168 ---- > drivers/net/can/softing/softing_cs.c | 335 -------- > drivers/net/can/softing/softing_fw.c | 700 ----------------- > drivers/net/can/softing/softing_main.c | 864 --------------------- > drivers/net/can/softing/softing_platform.h | 41 - > 9 files changed, 2146 deletions(-) > delete mode 100644 drivers/net/can/softing/Kconfig > delete mode 100644 drivers/net/can/softing/Makefile > delete mode 100644 drivers/net/can/softing/softing.h > delete mode 100644 drivers/net/can/softing/softing_cs.c > delete mode 100644 drivers/net/can/softing/softing_fw.c > delete mode 100644 drivers/net/can/softing/softing_main.c > delete mode 100644 drivers/net/can/softing/softing_platform.h > > diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig > index a8fad6fe5302..fb16f67a99f9 100644 > --- a/drivers/net/can/Kconfig > +++ b/drivers/net/can/Kconfig > @@ -252,11 +252,10 @@ source "drivers/net/can/m_can/Kconfig" > source "drivers/net/can/mscan/Kconfig" > source "drivers/net/can/peak_canfd/Kconfig" > source "drivers/net/can/rcar/Kconfig" > source "drivers/net/can/rockchip/Kconfig" > source "drivers/net/can/sja1000/Kconfig" > -source "drivers/net/can/softing/Kconfig" > source "drivers/net/can/spi/Kconfig" > source "drivers/net/can/usb/Kconfig" > > endif #CAN_NETLINK > > diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile > index 4010d17f8583..fa2cdd7bcd0a 100644 > --- a/drivers/net/can/Makefile > +++ b/drivers/net/can/Makefile > @@ -11,11 +11,10 @@ obj-y += dev/ > obj-y += esd/ > obj-y += rcar/ > obj-y += rockchip/ > obj-y += spi/ > obj-y += usb/ > -obj-y += softing/ > > obj-$(CONFIG_CAN_AT91) += at91_can.o > obj-$(CONFIG_CAN_BXCAN) += bxcan.o > obj-$(CONFIG_CAN_CAN327) += can327.o > obj-$(CONFIG_CAN_CC770) += cc770/ > diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig > deleted file mode 100644 > index 8afd7d0a1000..000000000000 > --- a/drivers/net/can/softing/Kconfig > +++ /dev/null > @@ -1,31 +0,0 @@ > -# SPDX-License-Identifier: GPL-2.0-only > -config CAN_SOFTING > - tristate "Softing Gmbh CAN generic support" > - depends on HAS_IOMEM > - help > - Support for CAN cards from Softing Gmbh & some cards > - from Vector Gmbh. > - Softing Gmbh CAN cards come with 1 or 2 physical buses. > - Those cards typically use Dual Port RAM to communicate > - with the host CPU. The interface is then identical for PCI > - and PCMCIA cards. This driver operates on a platform device, > - which has been created by softing_cs or softing_pci driver. > - Warning: > - The API of the card does not allow fine control per bus, but > - controls the 2 buses on the card together. > - As such, some actions (start/stop/busoff recovery) on 1 bus > - must bring down the other bus too temporarily. > - > -config CAN_SOFTING_CS > - tristate "Softing Gmbh CAN pcmcia cards" > - depends on PCMCIA > - depends on CAN_SOFTING > - help > - Support for PCMCIA cards from Softing Gmbh & some cards > - from Vector Gmbh. > - You need firmware for these, which you can get at > - https://github.com/linux-can/can-firmware > - This version of the driver is written against > - firmware version 4.6 (softing-fw-4.6-binaries.tar.gz) > - In order to use the card as CAN device, you need the Softing generic > - support too. > diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile > deleted file mode 100644 > index c51154000377..000000000000 > --- a/drivers/net/can/softing/Makefile > +++ /dev/null > @@ -1,5 +0,0 @@ > -# SPDX-License-Identifier: GPL-2.0-only > - > -softing-y := softing_main.o softing_fw.o > -obj-$(CONFIG_CAN_SOFTING) += softing.o > -obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o > diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h > deleted file mode 100644 > index 2893007ea05e..000000000000 > --- a/drivers/net/can/softing/softing.h > +++ /dev/null > @@ -1,168 +0,0 @@ > -/* SPDX-License-Identifier: GPL-2.0 */ > -/* > - * softing common interfaces > - * > - * by Kurt Van Dijck, 2008-2010 > - */ > - > -#include <linux/atomic.h> > -#include <linux/netdevice.h> > -#include <linux/ktime.h> > -#include <linux/mutex.h> > -#include <linux/spinlock.h> > -#include <linux/can.h> > -#include <linux/can/dev.h> > - > -#include "softing_platform.h" > - > -struct softing; > - > -struct softing_priv { > - struct can_priv can; /* must be the first member! */ > - struct net_device *netdev; > - struct softing *card; > - struct { > - int pending; > - /* variables which hold the circular buffer */ > - int echo_put; > - int echo_get; > - } tx; > - struct can_bittiming_const btr_const; > - int index; > - uint8_t output; > - uint16_t chip; > -}; > -#define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev)) > - > -struct softing { > - const struct softing_platform_data *pdat; > - struct platform_device *pdev; > - struct net_device *net[2]; > - spinlock_t spin; /* protect this structure & DPRAM access */ > - ktime_t ts_ref; > - ktime_t ts_overflow; /* timestamp overflow value, in ktime */ > - > - struct { > - /* indication of firmware status */ > - int up; > - /* protection of the 'up' variable */ > - struct mutex lock; > - } fw; > - struct { > - int nr; > - int requested; > - int svc_count; > - unsigned int dpram_position; > - } irq; > - struct { > - int pending; > - int last_bus; > - /* > - * keep the bus that last tx'd a message, > - * in order to let every netdev queue resume > - */ > - } tx; > - __iomem uint8_t *dpram; > - unsigned long dpram_phys; > - unsigned long dpram_size; > - struct { > - uint16_t fw_version, hw_version, license, serial; > - uint16_t chip[2]; > - unsigned int freq; /* remote cpu's operating frequency */ > - } id; > -}; > - > -int softing_default_output(struct net_device *netdev); > - > -ktime_t softing_raw2ktime(struct softing *card, u32 raw); > - > -int softing_chip_poweron(struct softing *card); > - > -int softing_bootloader_command(struct softing *card, int16_t cmd, > - const char *msg); > - > -/* Load firmware after reset */ > -int softing_load_fw(const char *file, struct softing *card, > - __iomem uint8_t *virt, unsigned int size, int offset); > - > -/* Load final application firmware after bootloader */ > -int softing_load_app_fw(const char *file, struct softing *card); > - > -/* > - * enable or disable irq > - * only called with fw.lock locked > - */ > -int softing_enable_irq(struct softing *card, int enable); > - > -/* start/stop 1 bus on card */ > -int softing_startstop(struct net_device *netdev, int up); > - > -/* netif_rx() */ > -int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, > - ktime_t ktime); > - > -/* SOFTING DPRAM mappings */ > -#define DPRAM_RX 0x0000 > - #define DPRAM_RX_SIZE 32 > - #define DPRAM_RX_CNT 16 > -#define DPRAM_RX_RD 0x0201 /* uint8_t */ > -#define DPRAM_RX_WR 0x0205 /* uint8_t */ > -#define DPRAM_RX_LOST 0x0207 /* uint8_t */ > - > -#define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */ > -#define DPRAM_FCT_RESULT 0x0328 /* int16_t */ > -#define DPRAM_FCT_HOST 0x032b /* uint16_t */ > - > -#define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */ > -#define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */ > -#define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */ > -#define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */ > -#define DPRAM_RESET 0x0341 /* uint16_t */ > -#define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */ > -#define DPRAM_RESET_TIME 0x034d /* uint16_t */ > -#define DPRAM_TIME 0x0350 /* uint64_t */ > -#define DPRAM_WR_START 0x0358 /* uint8_t */ > -#define DPRAM_WR_END 0x0359 /* uint8_t */ > -#define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */ > -#define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */ > -#define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */ > -#define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */ > -#define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */ > - > -#define DPRAM_TX 0x0400 /* uint16_t */ > - #define DPRAM_TX_SIZE 16 > - #define DPRAM_TX_CNT 32 > -#define DPRAM_TX_RD 0x0601 /* uint8_t */ > -#define DPRAM_TX_WR 0x0605 /* uint8_t */ > - > -#define DPRAM_COMMAND 0x07e0 /* uint16_t */ > -#define DPRAM_RECEIPT 0x07f0 /* uint16_t */ > -#define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */ > -#define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */ > - > -#define DPRAM_V2_RESET 0x0e00 /* uint8_t */ > -#define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */ > - > -#define TXMAX (DPRAM_TX_CNT - 1) > - > -/* DPRAM return codes */ > -#define RES_NONE 0 > -#define RES_OK 1 > -#define RES_NOK 2 > -#define RES_UNKNOWN 3 > -/* DPRAM flags */ > -#define CMD_TX 0x01 > -#define CMD_ACK 0x02 > -#define CMD_XTD 0x04 > -#define CMD_RTR 0x08 > -#define CMD_ERR 0x10 > -#define CMD_BUS2 0x80 > - > -/* returned fifo entry bus state masks */ > -#define SF_MASK_BUSOFF 0x80 > -#define SF_MASK_EPASSIVE 0x60 > - > -/* bus states */ > -#define STATE_BUSOFF 2 > -#define STATE_EPASSIVE 1 > -#define STATE_EACTIVE 0 > diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c > deleted file mode 100644 > index 3cea14cf055a..000000000000 > --- a/drivers/net/can/softing/softing_cs.c > +++ /dev/null > @@ -1,335 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-only > -/* > - * Copyright (C) 2008-2010 > - * > - * - Kurt Van Dijck, EIA Electronics > - */ > - > -#include <linux/module.h> > -#include <linux/kernel.h> > -#include <linux/slab.h> > - > -#include <pcmcia/cistpl.h> > -#include <pcmcia/ds.h> > - > -#include "softing_platform.h" > - > -static int softingcs_index; > -static DEFINE_SPINLOCK(softingcs_index_lock); > - > -static int softingcs_reset(struct platform_device *pdev, int v); > -static int softingcs_enable_irq(struct platform_device *pdev, int v); > - > -/* > - * platform_data descriptions > - */ > -#define MHZ (1000*1000) > -static const struct softing_platform_data softingcs_platform_data[] = { > -{ > - .name = "CANcard", > - .manf = 0x0168, .prod = 0x001, > - .generation = 1, > - .nbus = 2, > - .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, > - .dpram_size = 0x0800, > - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, > - .reset = softingcs_reset, > - .enable_irq = softingcs_enable_irq, > -}, { > - .name = "CANcard-NEC", > - .manf = 0x0168, .prod = 0x002, > - .generation = 1, > - .nbus = 2, > - .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, > - .dpram_size = 0x0800, > - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, > - .reset = softingcs_reset, > - .enable_irq = softingcs_enable_irq, > -}, { > - .name = "CANcard-SJA", > - .manf = 0x0168, .prod = 0x004, > - .generation = 1, > - .nbus = 2, > - .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, > - .dpram_size = 0x0800, > - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, > - .reset = softingcs_reset, > - .enable_irq = softingcs_enable_irq, > -}, { > - .name = "CANcard-2", > - .manf = 0x0168, .prod = 0x005, > - .generation = 2, > - .nbus = 2, > - .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, > - .dpram_size = 0x1000, > - .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, > - .reset = softingcs_reset, > - .enable_irq = NULL, > -}, { > - .name = "Vector-CANcard", > - .manf = 0x0168, .prod = 0x081, > - .generation = 1, > - .nbus = 2, > - .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, > - .dpram_size = 0x0800, > - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, > - .reset = softingcs_reset, > - .enable_irq = softingcs_enable_irq, > -}, { > - .name = "Vector-CANcard-SJA", > - .manf = 0x0168, .prod = 0x084, > - .generation = 1, > - .nbus = 2, > - .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, > - .dpram_size = 0x0800, > - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, > - .reset = softingcs_reset, > - .enable_irq = softingcs_enable_irq, > -}, { > - .name = "Vector-CANcard-2", > - .manf = 0x0168, .prod = 0x085, > - .generation = 2, > - .nbus = 2, > - .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, > - .dpram_size = 0x1000, > - .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, > - .reset = softingcs_reset, > - .enable_irq = NULL, > -}, { > - .name = "EDICcard-NEC", > - .manf = 0x0168, .prod = 0x102, > - .generation = 1, > - .nbus = 2, > - .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, > - .dpram_size = 0x0800, > - .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, > - .reset = softingcs_reset, > - .enable_irq = softingcs_enable_irq, > -}, { > - .name = "EDICcard-2", > - .manf = 0x0168, .prod = 0x105, > - .generation = 2, > - .nbus = 2, > - .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, > - .dpram_size = 0x1000, > - .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, > - .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, > - .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, > - .reset = softingcs_reset, > - .enable_irq = NULL, > -}, { > - 0, 0, > -}, > -}; > - > -MODULE_FIRMWARE(fw_dir "bcard.bin"); > -MODULE_FIRMWARE(fw_dir "ldcard.bin"); > -MODULE_FIRMWARE(fw_dir "cancard.bin"); > -MODULE_FIRMWARE(fw_dir "cansja.bin"); > - > -MODULE_FIRMWARE(fw_dir "bcard2.bin"); > -MODULE_FIRMWARE(fw_dir "ldcard2.bin"); > -MODULE_FIRMWARE(fw_dir "cancrd2.bin"); > - > -static const struct softing_platform_data > -*softingcs_find_platform_data(unsigned int manf, unsigned int prod) > -{ > - const struct softing_platform_data *lp; > - > - for (lp = softingcs_platform_data; lp->manf; ++lp) { > - if ((lp->manf == manf) && (lp->prod == prod)) > - return lp; > - } > - return NULL; > -} > - > -/* > - * platformdata callbacks > - */ > -static int softingcs_reset(struct platform_device *pdev, int v) > -{ > - struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); > - > - dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20); > - return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20); > -} > - > -static int softingcs_enable_irq(struct platform_device *pdev, int v) > -{ > - struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); > - > - dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0); > - return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0); > -} > - > -/* > - * pcmcia check > - */ > -static int softingcs_probe_config(struct pcmcia_device *pcmcia, void *priv_data) > -{ > - struct softing_platform_data *pdat = priv_data; > - struct resource *pres; > - int memspeed = 0; > - > - WARN_ON(!pdat); > - pres = pcmcia->resource[PCMCIA_IOMEM_0]; > - if (resource_size(pres) < 0x1000) > - return -ERANGE; > - > - pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; > - if (pdat->generation < 2) { > - pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8; > - memspeed = 3; > - } else { > - pres->flags |= WIN_DATA_WIDTH_16; > - } > - return pcmcia_request_window(pcmcia, pres, memspeed); > -} > - > -static void softingcs_remove(struct pcmcia_device *pcmcia) > -{ > - struct platform_device *pdev = pcmcia->priv; > - > - /* free bits */ > - platform_device_unregister(pdev); > - /* release pcmcia stuff */ > - pcmcia_disable_device(pcmcia); > -} > - > -/* > - * platform_device wrapper > - * pdev->resource has 2 entries: io & irq > - */ > -static void softingcs_pdev_release(struct device *dev) > -{ > - struct platform_device *pdev = to_platform_device(dev); > - kfree(pdev); > -} > - > -static int softingcs_probe(struct pcmcia_device *pcmcia) > -{ > - int ret; > - struct platform_device *pdev; > - const struct softing_platform_data *pdat; > - struct resource *pres; > - struct dev { > - struct platform_device pdev; > - struct resource res[2]; > - } *dev; > - > - /* find matching platform_data */ > - pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id); > - if (!pdat) > - return -ENOTTY; > - > - /* setup pcmcia device */ > - pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM | > - CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; > - ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat); > - if (ret) > - goto pcmcia_failed; > - > - ret = pcmcia_enable_device(pcmcia); > - if (ret < 0) > - goto pcmcia_failed; > - > - pres = pcmcia->resource[PCMCIA_IOMEM_0]; > - if (!pres) { > - ret = -EBADF; > - goto pcmcia_bad; > - } > - > - /* create softing platform device */ > - dev = kzalloc_obj(*dev); > - if (!dev) { > - ret = -ENOMEM; > - goto mem_failed; > - } > - dev->pdev.resource = dev->res; > - dev->pdev.num_resources = ARRAY_SIZE(dev->res); > - dev->pdev.dev.release = softingcs_pdev_release; > - > - pdev = &dev->pdev; > - pdev->dev.platform_data = (void *)pdat; > - pdev->dev.parent = &pcmcia->dev; > - pcmcia->priv = pdev; > - > - /* platform device resources */ > - pdev->resource[0].flags = IORESOURCE_MEM; > - pdev->resource[0].start = pres->start; > - pdev->resource[0].end = pres->end; > - > - pdev->resource[1].flags = IORESOURCE_IRQ; > - pdev->resource[1].start = pcmcia->irq; > - pdev->resource[1].end = pdev->resource[1].start; > - > - /* platform device setup */ > - spin_lock(&softingcs_index_lock); > - pdev->id = softingcs_index++; > - spin_unlock(&softingcs_index_lock); > - pdev->name = "softing"; > - dev_set_name(&pdev->dev, "softingcs.%i", pdev->id); > - ret = platform_device_register(pdev); > - if (ret < 0) > - goto platform_failed; > - > - dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev)); > - return 0; > - > -platform_failed: > - platform_device_put(pdev); > -mem_failed: > -pcmcia_bad: > -pcmcia_failed: > - pcmcia_disable_device(pcmcia); > - pcmcia->priv = NULL; > - return ret; > -} > - > -static const struct pcmcia_device_id softingcs_ids[] = { > - /* softing */ > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001), > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002), > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004), > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005), > - /* vector, manufacturer? */ > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081), > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084), > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085), > - /* EDIC */ > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102), > - PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105), > - PCMCIA_DEVICE_NULL, > -}; > - > -MODULE_DEVICE_TABLE(pcmcia, softingcs_ids); > - > -static struct pcmcia_driver softingcs_driver = { > - .owner = THIS_MODULE, > - .name = "softingcs", > - .id_table = softingcs_ids, > - .probe = softingcs_probe, > - .remove = softingcs_remove, > -}; > - > -module_pcmcia_driver(softingcs_driver); > - > -MODULE_DESCRIPTION("softing CANcard driver" > - ", links PCMCIA card to softing driver"); > -MODULE_LICENSE("GPL v2"); > diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c > deleted file mode 100644 > index 282570daf3ef..000000000000 > --- a/drivers/net/can/softing/softing_fw.c > +++ /dev/null > @@ -1,700 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-only > -/* > - * Copyright (C) 2008-2010 > - * > - * - Kurt Van Dijck, EIA Electronics > - */ > - > -#include <linux/firmware.h> > -#include <linux/sched/signal.h> > -#include <asm/div64.h> > -#include <asm/io.h> > - > -#include "softing.h" > - > -/* > - * low level DPRAM command. > - * Make sure that card->dpram[DPRAM_FCT_HOST] is preset > - */ > -static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector, > - const char *msg) > -{ > - int ret; > - unsigned long stamp; > - > - iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]); > - iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]); > - iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]); > - /* be sure to flush this to the card */ > - wmb(); > - stamp = jiffies + 1 * HZ; > - /* wait for card */ > - do { > - /* DPRAM_FCT_HOST is _not_ aligned */ > - ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) + > - (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8); > - /* don't have any cached variables */ > - rmb(); > - if (ret == RES_OK) > - /* read return-value now */ > - return ioread16(&card->dpram[DPRAM_FCT_RESULT]); > - > - if ((ret != vector) || time_after(jiffies, stamp)) > - break; > - /* process context => relax */ > - usleep_range(500, 10000); > - } while (1); > - > - ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; > - dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret); > - return ret; > -} > - > -static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg) > -{ > - int ret; > - > - ret = _softing_fct_cmd(card, cmd, 0, msg); > - if (ret > 0) { > - dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret); > - ret = -EIO; > - } > - return ret; > -} > - > -int softing_bootloader_command(struct softing *card, int16_t cmd, > - const char *msg) > -{ > - int ret; > - unsigned long stamp; > - > - iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]); > - iowrite16(cmd, &card->dpram[DPRAM_COMMAND]); > - /* be sure to flush this to the card */ > - wmb(); > - stamp = jiffies + 3 * HZ; > - /* wait for card */ > - do { > - ret = ioread16(&card->dpram[DPRAM_RECEIPT]); > - /* don't have any cached variables */ > - rmb(); > - if (ret == RES_OK) > - return 0; > - if (time_after(jiffies, stamp)) > - break; > - /* process context => relax */ > - usleep_range(500, 10000); > - } while (!signal_pending(current)); > - > - ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; > - dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret); > - return ret; > -} > - > -static int fw_parse(const u8 **pmem, const u8 *limit, u16 *ptype, > - u32 *paddr, u16 *plen, const u8 **pdat) > -{ > - uint16_t checksum[2]; > - const u8 *mem; > - const u8 *record_end; > - > - /* > - * firmware records are a binary, unaligned stream composed of: > - * uint16_t type; > - * uint32_t addr; > - * uint16_t len; > - * uint8_t dat[len]; > - * uint16_t checksum; > - * all values in little endian. > - * We could define a struct for this, with __attribute__((packed)), > - * but would that solve the alignment in _all_ cases (cfr. the > - * struct itself may be an odd address)? > - * > - * I chose to use leXX_to_cpup() since this solves both > - * endianness & alignment. > - */ > - mem = *pmem; > - /* A record needs an 8-byte prefix and a 2-byte checksum. */ > - if (mem > limit || limit - mem < 10) > - return -EINVAL; > - > - *ptype = le16_to_cpup((void *)&mem[0]); > - *paddr = le32_to_cpup((void *)&mem[2]); > - *plen = le16_to_cpup((void *)&mem[6]); > - if (*plen > limit - mem - 10) > - return -EINVAL; > - > - *pdat = &mem[8]; > - /* verify checksum */ > - record_end = &mem[8 + *plen]; > - checksum[0] = le16_to_cpup((void *)record_end); > - for (checksum[1] = 0; mem < record_end; ++mem) > - checksum[1] += *mem; > - if (checksum[0] != checksum[1]) > - return -EINVAL; > - /* increment */ > - *pmem += 10 + *plen; > - return 0; > -} > - > -int softing_load_fw(const char *file, struct softing *card, > - __iomem uint8_t *dpram, unsigned int size, int offset) > -{ > - const struct firmware *fw; > - int ret; > - const uint8_t *mem, *end, *dat; > - uint16_t type, len; > - uint32_t addr; > - uint8_t *buf = NULL, *new_buf; > - s64 dpram_offset; > - int buflen = 0; > - int8_t type_end = 0; > - > - ret = request_firmware(&fw, file, &card->pdev->dev); > - if (ret < 0) > - return ret; > - dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes" > - ", offset %c0x%04x\n", > - card->pdat->name, file, (unsigned int)fw->size, > - (offset >= 0) ? '+' : '-', (unsigned int)abs(offset)); > - /* parse the firmware */ > - mem = fw->data; > - end = &mem[fw->size]; > - /* look for header record */ > - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); > - if (ret < 0) > - goto failed; > - if (type != 0xffff) > - goto failed; > - if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { > - ret = -EINVAL; > - goto failed; > - } > - /* ok, we had a header */ > - while (mem < end) { > - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); > - if (ret < 0) > - goto failed; > - if (type == 3) { > - /* start address, not used here */ > - continue; > - } else if (type == 1) { > - /* eof */ > - type_end = 1; > - break; > - } else if (type != 0) { > - ret = -EINVAL; > - goto failed; > - } > - > - dpram_offset = (s64)addr + offset; > - if (dpram_offset < 0 || dpram_offset > size || > - len > size - dpram_offset) { > - ret = -EINVAL; > - goto failed; > - } > - memcpy_toio(&dpram[dpram_offset], dat, len); > - /* be sure to flush caches from IO space */ > - mb(); > - if (len > buflen) { > - /* align buflen */ > - buflen = (len + (1024-1)) & ~(1024-1); > - new_buf = krealloc(buf, buflen, GFP_KERNEL); > - if (!new_buf) { > - ret = -ENOMEM; > - goto failed; > - } > - buf = new_buf; > - } > - /* verify record data */ > - memcpy_fromio(buf, &dpram[dpram_offset], len); > - if (memcmp(buf, dat, len)) { > - /* is not ok */ > - dev_alert(&card->pdev->dev, "DPRAM readback failed\n"); > - ret = -EIO; > - goto failed; > - } > - } > - if (!type_end) > - /* no end record seen */ > - goto failed; > - ret = 0; > -failed: > - kfree(buf); > - release_firmware(fw); > - if (ret < 0) > - dev_info(&card->pdev->dev, "firmware %s failed\n", file); > - return ret; > -} > - > -int softing_load_app_fw(const char *file, struct softing *card) > -{ > - const struct firmware *fw; > - const uint8_t *mem, *end, *dat; > - int ret, j; > - uint16_t type, len; > - uint32_t addr, start_addr = 0; > - unsigned int sum, rx_sum; > - int8_t type_end = 0, type_entrypoint = 0; > - > - ret = request_firmware(&fw, file, &card->pdev->dev); > - if (ret) { > - dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", > - file, ret); > - return ret; > - } > - dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", > - file, (unsigned long)fw->size); > - /* parse the firmware */ > - mem = fw->data; > - end = &mem[fw->size]; > - /* look for header record */ > - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); > - if (ret) > - goto failed; > - ret = -EINVAL; > - if (type != 0xffff) { > - dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n", > - type); > - goto failed; > - } > - if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) { > - dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n", > - len, dat); > - goto failed; > - } > - /* ok, we had a header */ > - while (mem < end) { > - ret = fw_parse(&mem, end, &type, &addr, &len, &dat); > - if (ret) > - goto failed; > - > - if (type == 3) { > - /* start address */ > - start_addr = addr; > - type_entrypoint = 1; > - continue; > - } else if (type == 1) { > - /* eof */ > - type_end = 1; > - break; > - } else if (type != 0) { > - dev_alert(&card->pdev->dev, > - "unknown record type 0x%04x\n", type); > - ret = -EINVAL; > - goto failed; > - } > - > - /* regular data */ > - for (sum = 0, j = 0; j < len; ++j) > - sum += dat[j]; > - /* work in 16bit (target) */ > - sum &= 0xffff; > - > - if (card->pdat->app.offs > card->dpram_size || > - len > card->dpram_size - card->pdat->app.offs) { > - ret = -EINVAL; > - goto failed; > - } > - > - memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); > - iowrite32(card->pdat->app.offs + card->pdat->app.addr, > - &card->dpram[DPRAM_COMMAND + 2]); > - iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]); > - iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]); > - iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]); > - ret = softing_bootloader_command(card, 1, "loading app."); > - if (ret < 0) > - goto failed; > - /* verify checksum */ > - rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]); > - if (rx_sum != sum) { > - dev_alert(&card->pdev->dev, "SRAM seems to be damaged" > - ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum); > - ret = -EIO; > - goto failed; > - } > - } > - if (!type_end || !type_entrypoint) > - goto failed; > - /* start application in card */ > - iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]); > - iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]); > - ret = softing_bootloader_command(card, 3, "start app."); > - if (ret < 0) > - goto failed; > - ret = 0; > -failed: > - release_firmware(fw); > - if (ret < 0) > - dev_info(&card->pdev->dev, "firmware %s failed\n", file); > - return ret; > -} > - > -static int softing_reset_chip(struct softing *card) > -{ > - int ret; > - > - do { > - /* reset chip */ > - iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]); > - iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]); > - iowrite8(1, &card->dpram[DPRAM_RESET]); > - iowrite8(0, &card->dpram[DPRAM_RESET+1]); > - > - ret = softing_fct_cmd(card, 0, "reset_can"); > - if (!ret) > - break; > - if (signal_pending(current)) > - /* don't wait any longer */ > - break; > - } while (1); > - card->tx.pending = 0; > - return ret; > -} > - > -int softing_chip_poweron(struct softing *card) > -{ > - int ret; > - /* sync */ > - ret = _softing_fct_cmd(card, 99, 0x55, "sync-a"); > - if (ret < 0) > - goto failed; > - > - ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b"); > - if (ret < 0) > - goto failed; > - > - ret = softing_reset_chip(card); > - if (ret < 0) > - goto failed; > - /* get_serial */ > - ret = softing_fct_cmd(card, 43, "get_serial_number"); > - if (ret < 0) > - goto failed; > - card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]); > - /* get_version */ > - ret = softing_fct_cmd(card, 12, "get_version"); > - if (ret < 0) > - goto failed; > - card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]); > - card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]); > - card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]); > - card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]); > - card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]); > - return 0; > -failed: > - return ret; > -} > - > -static void softing_initialize_timestamp(struct softing *card) > -{ > - uint64_t ovf; > - > - card->ts_ref = ktime_get(); > - > - /* 16MHz is the reference */ > - ovf = 0x100000000ULL * 16; > - do_div(ovf, card->pdat->freq ?: 16); > - > - card->ts_overflow = ktime_add_us(0, ovf); > -} > - > -ktime_t softing_raw2ktime(struct softing *card, u32 raw) > -{ > - uint64_t rawl; > - ktime_t now, real_offset; > - ktime_t target; > - ktime_t tmp; > - > - now = ktime_get(); > - real_offset = ktime_sub(ktime_get_real(), now); > - > - /* find nsec from card */ > - rawl = raw * 16; > - do_div(rawl, card->pdat->freq ?: 16); > - target = ktime_add_us(card->ts_ref, rawl); > - /* test for overflows */ > - tmp = ktime_add(target, card->ts_overflow); > - while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) { > - card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow); > - target = tmp; > - tmp = ktime_add(target, card->ts_overflow); > - } > - return ktime_add(target, real_offset); > -} > - > -static inline int softing_error_reporting(struct net_device *netdev) > -{ > - struct softing_priv *priv = netdev_priv(netdev); > - > - return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) > - ? 1 : 0; > -} > - > -int softing_startstop(struct net_device *dev, int up) > -{ > - int ret; > - struct softing *card; > - struct softing_priv *priv; > - struct net_device *netdev; > - int bus_bitmask_start; > - int j, error_reporting; > - struct can_frame msg; > - const struct can_bittiming *bt; > - > - priv = netdev_priv(dev); > - card = priv->card; > - > - if (!card->fw.up) > - return -EIO; > - > - ret = mutex_lock_interruptible(&card->fw.lock); > - if (ret) > - return ret; > - > - bus_bitmask_start = 0; > - if (up) > - /* prepare to start this bus as well */ > - bus_bitmask_start |= (1 << priv->index); > - /* bring netdevs down */ > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - netdev = card->net[j]; > - if (!netdev) > - continue; > - priv = netdev_priv(netdev); > - > - if (dev != netdev) > - netif_stop_queue(netdev); > - > - if (netif_running(netdev)) { > - if (dev != netdev) > - bus_bitmask_start |= (1 << j); > - priv->tx.pending = 0; > - priv->tx.echo_put = 0; > - priv->tx.echo_get = 0; > - /* > - * this bus' may just have called open_candev() > - * which is rather stupid to call close_candev() > - * already > - * but we may come here from busoff recovery too > - * in which case the echo_skb _needs_ flushing too. > - * just be sure to call open_candev() again > - */ > - close_candev(netdev); > - } > - priv->can.state = CAN_STATE_STOPPED; > - } > - card->tx.pending = 0; > - > - softing_enable_irq(card, 0); > - ret = softing_reset_chip(card); > - if (ret) > - goto failed; > - if (!bus_bitmask_start) > - /* no buses to be brought up */ > - goto card_done; > - > - if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2) > - && (softing_error_reporting(card->net[0]) > - != softing_error_reporting(card->net[1]))) { > - dev_alert(&card->pdev->dev, > - "err_reporting flag differs for buses\n"); > - goto invalid; > - } > - error_reporting = 0; > - if (bus_bitmask_start & 1) { > - netdev = card->net[0]; > - priv = netdev_priv(netdev); > - error_reporting += softing_error_reporting(netdev); > - /* init chip 1 */ > - bt = &priv->can.bittiming; > - iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); > - iowrite16(bt->phase_seg1 + bt->prop_seg, > - &card->dpram[DPRAM_FCT_PARAM + 6]); > - iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); > - iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, > - &card->dpram[DPRAM_FCT_PARAM + 10]); > - ret = softing_fct_cmd(card, 1, "initialize_chip[0]"); > - if (ret < 0) > - goto failed; > - /* set mode */ > - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); > - ret = softing_fct_cmd(card, 3, "set_mode[0]"); > - if (ret < 0) > - goto failed; > - /* set filter */ > - /* 11bit id & mask */ > - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); > - /* 29bit id.lo & mask.lo & id.hi & mask.hi */ > - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); > - iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); > - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); > - iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); > - ret = softing_fct_cmd(card, 7, "set_filter[0]"); > - if (ret < 0) > - goto failed; > - /* set output control */ > - iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); > - ret = softing_fct_cmd(card, 5, "set_output[0]"); > - if (ret < 0) > - goto failed; > - } > - if (bus_bitmask_start & 2) { > - netdev = card->net[1]; > - priv = netdev_priv(netdev); > - error_reporting += softing_error_reporting(netdev); > - /* init chip2 */ > - bt = &priv->can.bittiming; > - iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); > - iowrite16(bt->phase_seg1 + bt->prop_seg, > - &card->dpram[DPRAM_FCT_PARAM + 6]); > - iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); > - iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, > - &card->dpram[DPRAM_FCT_PARAM + 10]); > - ret = softing_fct_cmd(card, 2, "initialize_chip[1]"); > - if (ret < 0) > - goto failed; > - /* set mode2 */ > - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); > - ret = softing_fct_cmd(card, 4, "set_mode[1]"); > - if (ret < 0) > - goto failed; > - /* set filter2 */ > - /* 11bit id & mask */ > - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); > - /* 29bit id.lo & mask.lo & id.hi & mask.hi */ > - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); > - iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); > - iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); > - iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); > - ret = softing_fct_cmd(card, 8, "set_filter[1]"); > - if (ret < 0) > - goto failed; > - /* set output control2 */ > - iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); > - ret = softing_fct_cmd(card, 6, "set_output[1]"); > - if (ret < 0) > - goto failed; > - } > - > - /* enable_error_frame > - * > - * Error reporting is switched off at the moment since > - * the receiving of them is not yet 100% verified > - * This should be enabled sooner or later > - */ > - if (0 && error_reporting) { > - ret = softing_fct_cmd(card, 51, "enable_error_frame"); > - if (ret < 0) > - goto failed; > - } > - > - /* initialize interface */ > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]); > - iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]); > - ret = softing_fct_cmd(card, 17, "initialize_interface"); > - if (ret < 0) > - goto failed; > - /* enable_fifo */ > - ret = softing_fct_cmd(card, 36, "enable_fifo"); > - if (ret < 0) > - goto failed; > - /* enable fifo tx ack */ > - ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]"); > - if (ret < 0) > - goto failed; > - /* enable fifo tx ack2 */ > - ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]"); > - if (ret < 0) > - goto failed; > - /* start_chip */ > - ret = softing_fct_cmd(card, 11, "start_chip"); > - if (ret < 0) > - goto failed; > - iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]); > - iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]); > - if (card->pdat->generation < 2) { > - iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); > - /* flush the DPRAM caches */ > - wmb(); > - } > - > - softing_initialize_timestamp(card); > - > - /* > - * do socketcan notifications/status changes > - * from here, no errors should occur, or the failed: part > - * must be reviewed > - */ > - memset(&msg, 0, sizeof(msg)); > - msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; > - msg.len = CAN_ERR_DLC; > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - if (!(bus_bitmask_start & (1 << j))) > - continue; > - netdev = card->net[j]; > - if (!netdev) > - continue; > - priv = netdev_priv(netdev); > - priv->can.state = CAN_STATE_ERROR_ACTIVE; > - open_candev(netdev); > - if (dev != netdev) { > - /* notify other buses on the restart */ > - softing_netdev_rx(netdev, &msg, 0); > - ++priv->can.can_stats.restarts; > - } > - netif_wake_queue(netdev); > - } > - > - /* enable interrupts */ > - ret = softing_enable_irq(card, 1); > - if (ret) > - goto failed; > -card_done: > - mutex_unlock(&card->fw.lock); > - return 0; > -invalid: > - ret = -EINVAL; > -failed: > - softing_enable_irq(card, 0); > - softing_reset_chip(card); > - mutex_unlock(&card->fw.lock); > - /* bring all other interfaces down */ > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - netdev = card->net[j]; > - if (!netdev) > - continue; > - dev_close(netdev); > - } > - return ret; > -} > - > -int softing_default_output(struct net_device *netdev) > -{ > - struct softing_priv *priv = netdev_priv(netdev); > - struct softing *card = priv->card; > - > - switch (priv->chip) { > - case 1000: > - return (card->pdat->generation < 2) ? 0xfb : 0xfa; > - case 5: > - return 0x60; > - default: > - return 0x40; > - } > -} > diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c > deleted file mode 100644 > index 519ab3097f86..000000000000 > --- a/drivers/net/can/softing/softing_main.c > +++ /dev/null > @@ -1,864 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-only > -/* > - * Copyright (C) 2008-2010 > - * > - * - Kurt Van Dijck, EIA Electronics > - */ > - > -#include <linux/ethtool.h> > -#include <linux/module.h> > -#include <linux/interrupt.h> > -#include <asm/io.h> > - > -#include "softing.h" > - > -#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1) > - > -/* > - * test is a specific CAN netdev > - * is online (ie. up 'n running, not sleeping, not busoff > - */ > -static inline int canif_is_active(struct net_device *netdev) > -{ > - struct can_priv *can = netdev_priv(netdev); > - > - if (!netif_running(netdev)) > - return 0; > - return (can->state <= CAN_STATE_ERROR_PASSIVE); > -} > - > -/* reset DPRAM */ > -static inline void softing_set_reset_dpram(struct softing *card) > -{ > - if (card->pdat->generation >= 2) { > - spin_lock_bh(&card->spin); > - iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1, > - &card->dpram[DPRAM_V2_RESET]); > - spin_unlock_bh(&card->spin); > - } > -} > - > -static inline void softing_clr_reset_dpram(struct softing *card) > -{ > - if (card->pdat->generation >= 2) { > - spin_lock_bh(&card->spin); > - iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1, > - &card->dpram[DPRAM_V2_RESET]); > - spin_unlock_bh(&card->spin); > - } > -} > - > -/* trigger the tx queue-ing */ > -static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb, > - struct net_device *dev) > -{ > - struct softing_priv *priv = netdev_priv(dev); > - struct softing *card = priv->card; > - int ret; > - uint8_t *ptr; > - uint8_t fifo_wr, fifo_rd; > - struct can_frame *cf = (struct can_frame *)skb->data; > - uint8_t buf[DPRAM_TX_SIZE]; > - > - if (can_dev_dropped_skb(dev, skb)) > - return NETDEV_TX_OK; > - > - spin_lock(&card->spin); > - > - ret = NETDEV_TX_BUSY; > - if (!card->fw.up || > - (card->tx.pending >= TXMAX) || > - (priv->tx.pending >= TX_ECHO_SKB_MAX)) > - goto xmit_done; > - fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]); > - fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]); > - if (fifo_wr == fifo_rd) > - /* fifo full */ > - goto xmit_done; > - memset(buf, 0, sizeof(buf)); > - ptr = buf; > - *ptr = CMD_TX; > - if (cf->can_id & CAN_RTR_FLAG) > - *ptr |= CMD_RTR; > - if (cf->can_id & CAN_EFF_FLAG) > - *ptr |= CMD_XTD; > - if (priv->index) > - *ptr |= CMD_BUS2; > - ++ptr; > - *ptr++ = cf->len; > - *ptr++ = (cf->can_id >> 0); > - *ptr++ = (cf->can_id >> 8); > - if (cf->can_id & CAN_EFF_FLAG) { > - *ptr++ = (cf->can_id >> 16); > - *ptr++ = (cf->can_id >> 24); > - } else { > - /* increment 1, not 2 as you might think */ > - ptr += 1; > - } > - if (!(cf->can_id & CAN_RTR_FLAG)) > - memcpy(ptr, &cf->data[0], cf->len); > - memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr], > - buf, DPRAM_TX_SIZE); > - if (++fifo_wr >= DPRAM_TX_CNT) > - fifo_wr = 0; > - iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]); > - card->tx.last_bus = priv->index; > - ++card->tx.pending; > - ++priv->tx.pending; > - can_put_echo_skb(skb, dev, priv->tx.echo_put, 0); > - ++priv->tx.echo_put; > - if (priv->tx.echo_put >= TX_ECHO_SKB_MAX) > - priv->tx.echo_put = 0; > - /* can_put_echo_skb() saves the skb, safe to return TX_OK */ > - ret = NETDEV_TX_OK; > -xmit_done: > - spin_unlock(&card->spin); > - if (card->tx.pending >= TXMAX) { > - int j; > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - if (card->net[j]) > - netif_stop_queue(card->net[j]); > - } > - } > - if (ret != NETDEV_TX_OK) > - netif_stop_queue(dev); > - > - return ret; > -} > - > -/* > - * shortcut for skb delivery > - */ > -int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, > - ktime_t ktime) > -{ > - struct sk_buff *skb; > - struct can_frame *cf; > - > - skb = alloc_can_skb(netdev, &cf); > - if (!skb) > - return -ENOMEM; > - memcpy(cf, msg, sizeof(*msg)); > - skb->tstamp = ktime; > - return netif_rx(skb); > -} > - > -/* > - * softing_handle_1 > - * pop 1 entry from the DPRAM queue, and process > - */ > -static int softing_handle_1(struct softing *card) > -{ > - struct net_device *netdev; > - struct softing_priv *priv; > - ktime_t ktime; > - struct can_frame msg; > - int cnt = 0, lost_msg; > - uint8_t fifo_rd, fifo_wr, cmd; > - uint8_t *ptr; > - uint32_t tmp_u32; > - uint8_t buf[DPRAM_RX_SIZE]; > - > - memset(&msg, 0, sizeof(msg)); > - /* test for lost msgs */ > - lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]); > - if (lost_msg) { > - int j; > - /* reset condition */ > - iowrite8(0, &card->dpram[DPRAM_RX_LOST]); > - /* prepare msg */ > - msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL; > - msg.len = CAN_ERR_DLC; > - msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW; > - /* > - * service to all buses, we don't know which it was applicable > - * but only service buses that are online > - */ > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - netdev = card->net[j]; > - if (!netdev) > - continue; > - if (!canif_is_active(netdev)) > - /* a dead bus has no overflows */ > - continue; > - ++netdev->stats.rx_over_errors; > - softing_netdev_rx(netdev, &msg, 0); > - } > - /* prepare for other use */ > - memset(&msg, 0, sizeof(msg)); > - ++cnt; > - } > - > - fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]); > - fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]); > - > - if (++fifo_rd >= DPRAM_RX_CNT) > - fifo_rd = 0; > - if (fifo_wr == fifo_rd) > - return cnt; > - > - memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd], > - DPRAM_RX_SIZE); > - mb(); > - /* trigger dual port RAM */ > - iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]); > - > - ptr = buf; > - cmd = *ptr++; > - if (cmd == 0xff) > - /* not quite useful, probably the card has got out */ > - return 0; > - netdev = card->net[0]; > - if (cmd & CMD_BUS2) > - netdev = card->net[1]; > - priv = netdev_priv(netdev); > - > - if (cmd & CMD_ERR) { > - uint8_t can_state, state; > - > - state = *ptr++; > - > - msg.can_id = CAN_ERR_FLAG; > - msg.len = CAN_ERR_DLC; > - > - if (state & SF_MASK_BUSOFF) { > - can_state = CAN_STATE_BUS_OFF; > - msg.can_id |= CAN_ERR_BUSOFF; > - state = STATE_BUSOFF; > - } else if (state & SF_MASK_EPASSIVE) { > - can_state = CAN_STATE_ERROR_PASSIVE; > - msg.can_id |= CAN_ERR_CRTL; > - msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE; > - state = STATE_EPASSIVE; > - } else { > - can_state = CAN_STATE_ERROR_ACTIVE; > - msg.can_id |= CAN_ERR_CRTL; > - state = STATE_EACTIVE; > - } > - /* update DPRAM */ > - iowrite8(state, &card->dpram[priv->index ? > - DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]); > - /* timestamp */ > - tmp_u32 = le32_to_cpup((void *)ptr); > - ktime = softing_raw2ktime(card, tmp_u32); > - > - ++netdev->stats.rx_errors; > - /* update internal status */ > - if (can_state != priv->can.state) { > - priv->can.state = can_state; > - if (can_state == CAN_STATE_ERROR_PASSIVE) > - ++priv->can.can_stats.error_passive; > - else if (can_state == CAN_STATE_BUS_OFF) { > - /* this calls can_close_cleanup() */ > - ++priv->can.can_stats.bus_off; > - can_bus_off(netdev); > - netif_stop_queue(netdev); > - } > - /* trigger socketcan */ > - softing_netdev_rx(netdev, &msg, ktime); > - } > - > - } else { > - if (cmd & CMD_RTR) > - msg.can_id |= CAN_RTR_FLAG; > - msg.len = can_cc_dlc2len(*ptr++); > - if (cmd & CMD_XTD) { > - msg.can_id |= CAN_EFF_FLAG; > - msg.can_id |= le32_to_cpup((void *)ptr); > - ptr += 4; > - } else { > - msg.can_id |= le16_to_cpup((void *)ptr); > - ptr += 2; > - } > - /* timestamp */ > - tmp_u32 = le32_to_cpup((void *)ptr); > - ptr += 4; > - ktime = softing_raw2ktime(card, tmp_u32); > - if (!(msg.can_id & CAN_RTR_FLAG)) > - memcpy(&msg.data[0], ptr, 8); > - /* update socket */ > - if (cmd & CMD_ACK) { > - /* acknowledge, was tx msg */ > - struct sk_buff *skb; > - skb = priv->can.echo_skb[priv->tx.echo_get]; > - if (skb) > - skb->tstamp = ktime; > - ++netdev->stats.tx_packets; > - netdev->stats.tx_bytes += > - can_get_echo_skb(netdev, priv->tx.echo_get, > - NULL); > - ++priv->tx.echo_get; > - if (priv->tx.echo_get >= TX_ECHO_SKB_MAX) > - priv->tx.echo_get = 0; > - if (priv->tx.pending) > - --priv->tx.pending; > - if (card->tx.pending) > - --card->tx.pending; > - } else { > - int ret; > - > - ret = softing_netdev_rx(netdev, &msg, ktime); > - if (ret == NET_RX_SUCCESS) { > - ++netdev->stats.rx_packets; > - if (!(msg.can_id & CAN_RTR_FLAG)) > - netdev->stats.rx_bytes += msg.len; > - } else { > - ++netdev->stats.rx_dropped; > - } > - } > - } > - ++cnt; > - return cnt; > -} > - > -/* > - * real interrupt handler > - */ > -static irqreturn_t softing_irq_thread(int irq, void *dev_id) > -{ > - struct softing *card = (struct softing *)dev_id; > - struct net_device *netdev; > - struct softing_priv *priv; > - int j, offset, work_done; > - > - work_done = 0; > - spin_lock_bh(&card->spin); > - while (softing_handle_1(card) > 0) { > - ++card->irq.svc_count; > - ++work_done; > - } > - spin_unlock_bh(&card->spin); > - /* resume tx queue's */ > - offset = card->tx.last_bus; > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - if (card->tx.pending >= TXMAX) > - break; > - netdev = card->net[(j + offset + 1) % card->pdat->nbus]; > - if (!netdev) > - continue; > - priv = netdev_priv(netdev); > - if (!canif_is_active(netdev)) > - /* it makes no sense to wake dead buses */ > - continue; > - if (priv->tx.pending >= TX_ECHO_SKB_MAX) > - continue; > - ++work_done; > - netif_wake_queue(netdev); > - } > - return work_done ? IRQ_HANDLED : IRQ_NONE; > -} > - > -/* > - * interrupt routines: > - * schedule the 'real interrupt handler' > - */ > -static irqreturn_t softing_irq_v2(int irq, void *dev_id) > -{ > - struct softing *card = (struct softing *)dev_id; > - uint8_t ir; > - > - ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]); > - iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); > - return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE; > -} > - > -static irqreturn_t softing_irq_v1(int irq, void *dev_id) > -{ > - struct softing *card = (struct softing *)dev_id; > - uint8_t ir; > - > - ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]); > - iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]); > - return ir ? IRQ_WAKE_THREAD : IRQ_NONE; > -} > - > -/* > - * netdev/candev interoperability > - */ > -static int softing_netdev_open(struct net_device *ndev) > -{ > - int ret; > - > - /* check or determine and set bittime */ > - ret = open_candev(ndev); > - if (ret) > - return ret; > - > - ret = softing_startstop(ndev, 1); > - if (ret < 0) > - close_candev(ndev); > - > - return ret; > -} > - > -static int softing_netdev_stop(struct net_device *ndev) > -{ > - netif_stop_queue(ndev); > - > - /* softing cycle does close_candev() */ > - return softing_startstop(ndev, 0); > -} > - > -static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode) > -{ > - int ret; > - > - switch (mode) { > - case CAN_MODE_START: > - /* softing_startstop does close_candev() */ > - ret = softing_startstop(ndev, 1); > - return ret; > - case CAN_MODE_STOP: > - case CAN_MODE_SLEEP: > - return -EOPNOTSUPP; > - } > - return 0; > -} > - > -/* > - * Softing device management helpers > - */ > -int softing_enable_irq(struct softing *card, int enable) > -{ > - int ret; > - > - if (!card->irq.nr) { > - return 0; > - } else if (card->irq.requested && !enable) { > - free_irq(card->irq.nr, card); > - card->irq.requested = 0; > - } else if (!card->irq.requested && enable) { > - ret = request_threaded_irq(card->irq.nr, > - (card->pdat->generation >= 2) ? > - softing_irq_v2 : softing_irq_v1, > - softing_irq_thread, IRQF_SHARED, > - dev_name(&card->pdev->dev), card); > - if (ret) { > - dev_alert(&card->pdev->dev, > - "request_threaded_irq(%u) failed\n", > - card->irq.nr); > - return ret; > - } > - card->irq.requested = 1; > - } > - return 0; > -} > - > -static void softing_card_shutdown(struct softing *card) > -{ > - int fw_up = 0; > - > - if (mutex_lock_interruptible(&card->fw.lock)) { > - /* return -ERESTARTSYS */; > - } > - fw_up = card->fw.up; > - card->fw.up = 0; > - > - if (card->irq.requested && card->irq.nr) { > - free_irq(card->irq.nr, card); > - card->irq.requested = 0; > - } > - if (fw_up) { > - if (card->pdat->enable_irq) > - card->pdat->enable_irq(card->pdev, 0); > - softing_set_reset_dpram(card); > - if (card->pdat->reset) > - card->pdat->reset(card->pdev, 1); > - } > - mutex_unlock(&card->fw.lock); > -} > - > -static int softing_card_boot(struct softing *card) > -{ > - int ret, j; > - static const uint8_t stream[] = { > - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; > - unsigned char back[sizeof(stream)]; > - > - if (mutex_lock_interruptible(&card->fw.lock)) > - return -ERESTARTSYS; > - if (card->fw.up) { > - mutex_unlock(&card->fw.lock); > - return 0; > - } > - /* reset board */ > - if (card->pdat->enable_irq) > - card->pdat->enable_irq(card->pdev, 1); > - /* boot card */ > - softing_set_reset_dpram(card); > - if (card->pdat->reset) > - card->pdat->reset(card->pdev, 1); > - for (j = 0; (j + sizeof(stream)) < card->dpram_size; > - j += sizeof(stream)) { > - > - memcpy_toio(&card->dpram[j], stream, sizeof(stream)); > - /* flush IO cache */ > - mb(); > - memcpy_fromio(back, &card->dpram[j], sizeof(stream)); > - > - if (!memcmp(back, stream, sizeof(stream))) > - continue; > - /* memory is not equal */ > - dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j); > - ret = -EIO; > - goto failed; > - } > - wmb(); > - /* load boot firmware */ > - ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram, > - card->dpram_size, > - card->pdat->boot.offs - card->pdat->boot.addr); > - if (ret < 0) > - goto failed; > - /* load loader firmware */ > - ret = softing_load_fw(card->pdat->load.fw, card, card->dpram, > - card->dpram_size, > - card->pdat->load.offs - card->pdat->load.addr); > - if (ret < 0) > - goto failed; > - > - if (card->pdat->reset) > - card->pdat->reset(card->pdev, 0); > - softing_clr_reset_dpram(card); > - ret = softing_bootloader_command(card, 0, "card boot"); > - if (ret < 0) > - goto failed; > - ret = softing_load_app_fw(card->pdat->app.fw, card); > - if (ret < 0) > - goto failed; > - > - ret = softing_chip_poweron(card); > - if (ret < 0) > - goto failed; > - > - card->fw.up = 1; > - mutex_unlock(&card->fw.lock); > - return 0; > -failed: > - card->fw.up = 0; > - if (card->pdat->enable_irq) > - card->pdat->enable_irq(card->pdev, 0); > - softing_set_reset_dpram(card); > - if (card->pdat->reset) > - card->pdat->reset(card->pdev, 1); > - mutex_unlock(&card->fw.lock); > - return ret; > -} > - > -/* > - * netdev sysfs > - */ > -static ssize_t show_chip(struct device *dev, struct device_attribute *attr, > - char *buf) > -{ > - struct net_device *ndev = to_net_dev(dev); > - struct softing_priv *priv = netdev2softing(ndev); > - > - return sprintf(buf, "%i\n", priv->chip); > -} > - > -static ssize_t show_output(struct device *dev, struct device_attribute *attr, > - char *buf) > -{ > - struct net_device *ndev = to_net_dev(dev); > - struct softing_priv *priv = netdev2softing(ndev); > - > - return sprintf(buf, "0x%02x\n", priv->output); > -} > - > -static ssize_t store_output(struct device *dev, struct device_attribute *attr, > - const char *buf, size_t count) > -{ > - struct net_device *ndev = to_net_dev(dev); > - struct softing_priv *priv = netdev2softing(ndev); > - struct softing *card = priv->card; > - unsigned long val; > - int ret; > - > - ret = kstrtoul(buf, 0, &val); > - if (ret < 0) > - return ret; > - val &= 0xFF; > - > - ret = mutex_lock_interruptible(&card->fw.lock); > - if (ret) > - return -ERESTARTSYS; > - if (netif_running(ndev)) { > - mutex_unlock(&card->fw.lock); > - return -EBUSY; > - } > - priv->output = val; > - mutex_unlock(&card->fw.lock); > - return count; > -} > - > -static const DEVICE_ATTR(chip, 0444, show_chip, NULL); > -static const DEVICE_ATTR(output, 0644, show_output, store_output); > - > -static const struct attribute *const netdev_sysfs_attrs[] = { > - &dev_attr_chip.attr, > - &dev_attr_output.attr, > - NULL, > -}; > -static const struct attribute_group netdev_sysfs_group = { > - .name = NULL, > - .attrs = (struct attribute **)netdev_sysfs_attrs, > -}; > - > -static const struct net_device_ops softing_netdev_ops = { > - .ndo_open = softing_netdev_open, > - .ndo_stop = softing_netdev_stop, > - .ndo_start_xmit = softing_netdev_start_xmit, > -}; > - > -static const struct ethtool_ops softing_ethtool_ops = { > - .get_ts_info = ethtool_op_get_ts_info, > -}; > - > -static const struct can_bittiming_const softing_btr_const = { > - .name = KBUILD_MODNAME, > - .tseg1_min = 1, > - .tseg1_max = 16, > - .tseg2_min = 1, > - .tseg2_max = 8, > - .sjw_max = 4, /* overruled */ > - .brp_min = 1, > - .brp_max = 32, /* overruled */ > - .brp_inc = 1, > -}; > - > - > -static struct net_device *softing_netdev_create(struct softing *card, > - uint16_t chip_id) > -{ > - struct net_device *netdev; > - struct softing_priv *priv; > - > - netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); > - if (!netdev) { > - dev_alert(&card->pdev->dev, "alloc_candev failed\n"); > - return NULL; > - } > - priv = netdev_priv(netdev); > - priv->netdev = netdev; > - priv->card = card; > - memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const)); > - priv->btr_const.brp_max = card->pdat->max_brp; > - priv->btr_const.sjw_max = card->pdat->max_sjw; > - priv->can.bittiming_const = &priv->btr_const; > - priv->can.clock.freq = 8000000; > - priv->chip = chip_id; > - priv->output = softing_default_output(netdev); > - SET_NETDEV_DEV(netdev, &card->pdev->dev); > - > - netdev->flags |= IFF_ECHO; > - netdev->netdev_ops = &softing_netdev_ops; > - netdev->ethtool_ops = &softing_ethtool_ops; > - priv->can.do_set_mode = softing_candev_set_mode; > - priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; > - > - return netdev; > -} > - > -static int softing_netdev_register(struct net_device *netdev) > -{ > - int ret; > - > - ret = register_candev(netdev); > - if (ret) { > - dev_alert(&netdev->dev, "register failed\n"); > - return ret; > - } > - if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0) > - netdev_alert(netdev, "sysfs group failed\n"); > - > - return 0; > -} > - > -static void softing_netdev_cleanup(struct net_device *netdev) > -{ > - sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group); > - unregister_candev(netdev); > - free_candev(netdev); > -} > - > -/* > - * sysfs for Platform device > - */ > -#define DEV_ATTR_RO(name, member) \ > -static ssize_t show_##name(struct device *dev, \ > - struct device_attribute *attr, char *buf) \ > -{ \ > - struct softing *card = dev_get_drvdata(dev); \ > - return sprintf(buf, "%u\n", card->member); \ > -} \ > -static DEVICE_ATTR(name, 0444, show_##name, NULL) > - > -#define DEV_ATTR_RO_STR(name, member) \ > -static ssize_t show_##name(struct device *dev, \ > - struct device_attribute *attr, char *buf) \ > -{ \ > - struct softing *card = dev_get_drvdata(dev); \ > - return sprintf(buf, "%s\n", card->member); \ > -} \ > -static DEVICE_ATTR(name, 0444, show_##name, NULL) > - > -DEV_ATTR_RO(serial, id.serial); > -DEV_ATTR_RO_STR(firmware, pdat->app.fw); > -DEV_ATTR_RO(firmware_version, id.fw_version); > -DEV_ATTR_RO_STR(hardware, pdat->name); > -DEV_ATTR_RO(hardware_version, id.hw_version); > -DEV_ATTR_RO(license, id.license); > - > -static struct attribute *softing_pdev_attrs[] = { > - &dev_attr_serial.attr, > - &dev_attr_firmware.attr, > - &dev_attr_firmware_version.attr, > - &dev_attr_hardware.attr, > - &dev_attr_hardware_version.attr, > - &dev_attr_license.attr, > - NULL, > -}; > - > -static const struct attribute_group softing_pdev_group = { > - .name = NULL, > - .attrs = softing_pdev_attrs, > -}; > - > -/* > - * platform driver > - */ > -static void softing_pdev_remove(struct platform_device *pdev) > -{ > - struct softing *card = platform_get_drvdata(pdev); > - int j; > - > - /* first, disable card*/ > - softing_card_shutdown(card); > - > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - if (!card->net[j]) > - continue; > - softing_netdev_cleanup(card->net[j]); > - card->net[j] = NULL; > - } > - sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); > - > - iounmap(card->dpram); > - kfree(card); > -} > - > -static int softing_pdev_probe(struct platform_device *pdev) > -{ > - const struct softing_platform_data *pdat = dev_get_platdata(&pdev->dev); > - struct softing *card; > - struct net_device *netdev; > - struct softing_priv *priv; > - struct resource *pres; > - int ret; > - int j; > - > - if (!pdat) { > - dev_warn(&pdev->dev, "no platform data\n"); > - return -EINVAL; > - } > - if (pdat->nbus > ARRAY_SIZE(card->net)) { > - dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus); > - return -EINVAL; > - } > - > - card = kzalloc_obj(*card); > - if (!card) > - return -ENOMEM; > - card->pdat = pdat; > - card->pdev = pdev; > - platform_set_drvdata(pdev, card); > - mutex_init(&card->fw.lock); > - spin_lock_init(&card->spin); > - > - ret = -EINVAL; > - pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); > - if (!pres) > - goto platform_resource_failed; > - card->dpram_phys = pres->start; > - card->dpram_size = resource_size(pres); > - card->dpram = ioremap(card->dpram_phys, card->dpram_size); > - if (!card->dpram) { > - dev_alert(&card->pdev->dev, "dpram ioremap failed\n"); > - goto ioremap_failed; > - } > - > - pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); > - if (pres) > - card->irq.nr = pres->start; > - > - /* reset card */ > - ret = softing_card_boot(card); > - if (ret < 0) { > - dev_alert(&pdev->dev, "failed to boot\n"); > - goto boot_failed; > - } > - > - /* only now, the chip's are known */ > - card->id.freq = card->pdat->freq; > - > - ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group); > - if (ret < 0) { > - dev_alert(&card->pdev->dev, "sysfs failed\n"); > - goto sysfs_failed; > - } > - > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - card->net[j] = netdev = > - softing_netdev_create(card, card->id.chip[j]); > - if (!netdev) { > - dev_alert(&pdev->dev, "failed to make can[%i]", j); > - ret = -ENOMEM; > - goto netdev_failed; > - } > - netdev->dev_id = j; > - priv = netdev_priv(card->net[j]); > - priv->index = j; > - ret = softing_netdev_register(netdev); > - if (ret) { > - free_candev(netdev); > - card->net[j] = NULL; > - dev_alert(&card->pdev->dev, > - "failed to register can[%i]\n", j); > - goto netdev_failed; > - } > - } > - dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name); > - return 0; > - > -netdev_failed: > - for (j = 0; j < ARRAY_SIZE(card->net); ++j) { > - if (!card->net[j]) > - continue; > - softing_netdev_cleanup(card->net[j]); > - } > - sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); > -sysfs_failed: > - softing_card_shutdown(card); > -boot_failed: > - iounmap(card->dpram); > -ioremap_failed: > -platform_resource_failed: > - kfree(card); > - return ret; > -} > - > -static struct platform_driver softing_driver = { > - .driver = { > - .name = KBUILD_MODNAME, > - }, > - .probe = softing_pdev_probe, > - .remove = softing_pdev_remove, > -}; > - > -module_platform_driver(softing_driver); > - > -MODULE_ALIAS("platform:softing"); > -MODULE_DESCRIPTION("Softing DPRAM CAN driver"); > -MODULE_AUTHOR("Kurt Van Dijck <[email protected]>"); > -MODULE_LICENSE("GPL v2"); > diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h > deleted file mode 100644 > index cd8d7904c5f0..000000000000 > --- a/drivers/net/can/softing/softing_platform.h > +++ /dev/null > @@ -1,41 +0,0 @@ > -/* SPDX-License-Identifier: GPL-2.0 */ > - > -#include <linux/platform_device.h> > - > -#ifndef _SOFTING_DEVICE_H_ > -#define _SOFTING_DEVICE_H_ > - > -/* softing firmware directory prefix */ > -#define fw_dir "softing-4.6/" > - > -struct softing_platform_data { > - unsigned int manf; > - unsigned int prod; > - /* > - * generation > - * 1st with NEC or SJA1000 > - * 8bit, exclusive interrupt, ... > - * 2nd only SJA1000 > - * 16bit, shared interrupt > - */ > - int generation; > - int nbus; /* # buses on device */ > - unsigned int freq; /* operating frequency in Hz */ > - unsigned int max_brp; > - unsigned int max_sjw; > - unsigned long dpram_size; > - const char *name; > - struct { > - unsigned long offs; > - unsigned long addr; > - const char *fw; > - } boot, load, app; > - /* > - * reset() function > - * bring pdev in or out of reset, depending on value > - */ > - int (*reset)(struct platform_device *pdev, int value); > - int (*enable_irq)(struct platform_device *pdev, int value); > -}; > - > -#endif