summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 14:51:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 14:51:15 -0700
commitd87823813fe498fdd47894bd28e460a9dee8d771 (patch)
tree214eaf3babd0d61f08022fc1edd99a5128616548 /drivers/misc
parente382608254e06c8109f40044f5e693f2e04f3899 (diff)
parent3dc196eae1db548f05e53e5875ff87b8ff79f249 (diff)
Merge tag 'char-misc-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here's the big char/misc driver pull request for 4.2-rc1. Lots of mei, extcon, coresight, uio, mic, and other driver updates in here. Full details in the shortlog. All of these have been in linux-next for some time with no reported problems" * tag 'char-misc-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (176 commits) mei: me: wait for power gating exit confirmation mei: reset flow control on the last client disconnection MAINTAINERS: mei: add mei_cl_bus.h to maintained file list misc: sram: sort and clean up included headers misc: sram: move reserved block logic out of probe function misc: sram: add private struct device and virt_base members misc: sram: report correct SRAM pool size misc: sram: bump error message level on unclean driver unbinding misc: sram: fix device node reference leak on error misc: sram: fix enabled clock leak on error path misc: mic: Fix reported static checker warning misc: mic: Fix randconfig build error by including errno.h uio: pruss: Drop depends on ARCH_DAVINCI_DA850 from config uio: pruss: Add CONFIG_HAS_IOMEM dependence uio: pruss: Include <linux/sizes.h> extcon: Redefine the unique id of supported external connectors without 'enum extcon' type char:xilinx_hwicap:buffer_icap - change 1/0 to true/false for bool type variable in function buffer_icap_set_configuration(). Drivers: hv: vmbus: Allocate ring buffer memory in NUMA aware fashion parport: check exclusive access before register w1: use correct lock on error in w1_seq_show() ...
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/carma/Kconfig15
-rw-r--r--drivers/misc/carma/Makefile2
-rw-r--r--drivers/misc/carma/carma-fpga-program.c1182
-rw-r--r--drivers/misc/carma/carma-fpga.c1507
-rw-r--r--drivers/misc/mei/amthif.c28
-rw-r--r--drivers/misc/mei/bus.c150
-rw-r--r--drivers/misc/mei/client.c473
-rw-r--r--drivers/misc/mei/client.h114
-rw-r--r--drivers/misc/mei/debugfs.c15
-rw-r--r--drivers/misc/mei/hbm.c16
-rw-r--r--drivers/misc/mei/hw-me.c59
-rw-r--r--drivers/misc/mei/hw-txe.c33
-rw-r--r--drivers/misc/mei/init.c8
-rw-r--r--drivers/misc/mei/interrupt.c95
-rw-r--r--drivers/misc/mei/main.c57
-rw-r--r--drivers/misc/mei/mei_dev.h102
-rw-r--r--drivers/misc/mei/nfc.c223
-rw-r--r--drivers/misc/mei/pci-txe.c2
-rw-r--r--drivers/misc/mei/wd.c22
-rw-r--r--drivers/misc/mic/Kconfig40
-rw-r--r--drivers/misc/mic/Makefile3
-rw-r--r--drivers/misc/mic/bus/Makefile1
-rw-r--r--drivers/misc/mic/bus/scif_bus.c210
-rw-r--r--drivers/misc/mic/bus/scif_bus.h129
-rw-r--r--drivers/misc/mic/card/mic_device.c132
-rw-r--r--drivers/misc/mic/card/mic_device.h11
-rw-r--r--drivers/misc/mic/card/mic_x100.c61
-rw-r--r--drivers/misc/mic/card/mic_x100.h1
-rw-r--r--drivers/misc/mic/common/mic_dev.h3
-rw-r--r--drivers/misc/mic/host/mic_boot.c264
-rw-r--r--drivers/misc/mic/host/mic_debugfs.c13
-rw-r--r--drivers/misc/mic/host/mic_device.h11
-rw-r--r--drivers/misc/mic/host/mic_intr.h3
-rw-r--r--drivers/misc/mic/host/mic_main.c6
-rw-r--r--drivers/misc/mic/host/mic_smpt.c7
-rw-r--r--drivers/misc/mic/host/mic_smpt.h1
-rw-r--r--drivers/misc/mic/host/mic_virtio.c6
-rw-r--r--drivers/misc/mic/host/mic_x100.c3
-rw-r--r--drivers/misc/mic/scif/Makefile15
-rw-r--r--drivers/misc/mic/scif/scif_api.c1276
-rw-r--r--drivers/misc/mic/scif/scif_debugfs.c85
-rw-r--r--drivers/misc/mic/scif/scif_epd.c353
-rw-r--r--drivers/misc/mic/scif/scif_epd.h160
-rw-r--r--drivers/misc/mic/scif/scif_fd.c303
-rw-r--r--drivers/misc/mic/scif/scif_main.c388
-rw-r--r--drivers/misc/mic/scif/scif_main.h254
-rw-r--r--drivers/misc/mic/scif/scif_map.h113
-rw-r--r--drivers/misc/mic/scif/scif_nm.c237
-rw-r--r--drivers/misc/mic/scif/scif_nodeqp.c1312
-rw-r--r--drivers/misc/mic/scif/scif_nodeqp.h183
-rw-r--r--drivers/misc/mic/scif/scif_peer_bus.c124
-rw-r--r--drivers/misc/mic/scif/scif_peer_bus.h65
-rw-r--r--drivers/misc/mic/scif/scif_ports.c124
-rw-r--r--drivers/misc/mic/scif/scif_rb.c249
-rw-r--r--drivers/misc/mic/scif/scif_rb.h100
-rw-r--r--drivers/misc/sram.c137
-rw-r--r--drivers/misc/ti-st/st_kim.c3
59 files changed, 7022 insertions, 3469 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 006242c8bca0..42c38525904b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -520,7 +520,6 @@ source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig"
-source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig"
source "drivers/misc/mei/Kconfig"
source "drivers/misc/vmw_vmci/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7d5c4cd118c4..d056fb7186fe 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
obj-$(CONFIG_PCH_PHUB) += pch_phub.o
obj-y += ti-st/
obj-y += lis3lv02d/
-obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_INTEL_MEI) += mei/
diff --git a/drivers/misc/carma/Kconfig b/drivers/misc/carma/Kconfig
deleted file mode 100644
index 295882bfb14e..000000000000
--- a/drivers/misc/carma/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-config CARMA_FPGA
- tristate "CARMA DATA-FPGA Access Driver"
- depends on FSL_SOC && PPC_83xx && HAS_DMA && FSL_DMA
- default n
- help
- Say Y here to include support for communicating with the data
- processing FPGAs on the OVRO CARMA board.
-
-config CARMA_FPGA_PROGRAM
- tristate "CARMA DATA-FPGA Programmer"
- depends on FSL_SOC && PPC_83xx && HAS_DMA && FSL_DMA
- default n
- help
- Say Y here to include support for programming the data processing
- FPGAs on the OVRO CARMA board.
diff --git a/drivers/misc/carma/Makefile b/drivers/misc/carma/Makefile
deleted file mode 100644
index ff36ac2ce534..000000000000
--- a/drivers/misc/carma/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_CARMA_FPGA) += carma-fpga.o
-obj-$(CONFIG_CARMA_FPGA_PROGRAM) += carma-fpga-program.o
diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c
deleted file mode 100644
index 0b1bd85e4ae6..000000000000
--- a/drivers/misc/carma/carma-fpga-program.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/*
- * CARMA Board DATA-FPGA Programmer
- *
- * Copyright (c) 2009-2011 Ira W. Snyder <iws@ovro.caltech.edu>
- *
- * 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.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-#include <linux/completion.h>
-#include <linux/miscdevice.h>
-#include <linux/dmaengine.h>
-#include <linux/fsldma.h>
-#include <linux/interrupt.h>
-#include <linux/highmem.h>
-#include <linux/vmalloc.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/leds.h>
-#include <linux/slab.h>
-#include <linux/kref.h>
-#include <linux/fs.h>
-#include <linux/io.h>
-
-/* MPC8349EMDS specific get_immrbase() */
-#include <sysdev/fsl_soc.h>
-
-static const char drv_name[] = "carma-fpga-program";
-
-/*
- * Firmware images are always this exact size
- *
- * 12849552 bytes for a CARMA Digitizer Board (EP2S90 FPGAs)
- * 18662880 bytes for a CARMA Correlator Board (EP2S130 FPGAs)
- */
-#define FW_SIZE_EP2S90 12849552
-#define FW_SIZE_EP2S130 18662880
-
-struct fpga_dev {
- struct miscdevice miscdev;
-
- /* Reference count */
- struct kref ref;
-
- /* Device Registers */
- struct device *dev;
- void __iomem *regs;
- void __iomem *immr;
-
- /* Freescale DMA Device */
- struct dma_chan *chan;
-
- /* Interrupts */
- int irq, status;
- struct completion completion;
-
- /* FPGA Bitfile */
- struct mutex lock;
-
- void *vaddr;
- struct scatterlist *sglist;
- int sglen;
- int nr_pages;
- bool buf_allocated;
-
- /* max size and written bytes */
- size_t fw_size;
- size_t bytes;
-};
-
-static int fpga_dma_init(struct fpga_dev *priv, int nr_pages)
-{
- struct page *pg;
- int i;
-
- priv->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
- if (NULL == priv->vaddr) {
- pr_debug("vmalloc_32(%d pages) failed\n", nr_pages);
- return -ENOMEM;
- }
-
- pr_debug("vmalloc is at addr 0x%08lx, size=%d\n",
- (unsigned long)priv->vaddr,
- nr_pages << PAGE_SHIFT);
-
- memset(priv->vaddr, 0, nr_pages << PAGE_SHIFT);
- priv->nr_pages = nr_pages;
-
- priv->sglist = vzalloc(priv->nr_pages * sizeof(*priv->sglist));
- if (NULL == priv->sglist)
- goto vzalloc_err;
-
- sg_init_table(priv->sglist, priv->nr_pages);
- for (i = 0; i < priv->nr_pages; i++) {
- pg = vmalloc_to_page(priv->vaddr + i * PAGE_SIZE);
- if (NULL == pg)
- goto vmalloc_to_page_err;
- sg_set_page(&priv->sglist[i], pg, PAGE_SIZE, 0);
- }
- return 0;
-
-vmalloc_to_page_err:
- vfree(priv->sglist);
- priv->sglist = NULL;
-vzalloc_err:
- vfree(priv->vaddr);
- priv->vaddr = NULL;
- return -ENOMEM;
-}
-
-static int fpga_dma_map(struct fpga_dev *priv)
-{
- priv->sglen = dma_map_sg(priv->dev, priv->sglist,
- priv->nr_pages, DMA_TO_DEVICE);
-
- if (0 == priv->sglen) {
- pr_warn("%s: dma_map_sg failed\n", __func__);
- return -ENOMEM;
- }
- return 0;
-}
-
-static int fpga_dma_unmap(struct fpga_dev *priv)
-{
- if (!priv->sglen)
- return 0;
-
- dma_unmap_sg(priv->dev, priv->sglist, priv->sglen, DMA_TO_DEVICE);
- priv->sglen = 0;
- return 0;
-}
-
-/*
- * FPGA Bitfile Helpers
- */
-
-/**
- * fpga_drop_firmware_data() - drop the bitfile image from memory
- * @priv: the driver's private data structure
- *
- * LOCKING: must hold priv->lock
- */
-static void fpga_drop_firmware_data(struct fpga_dev *priv)
-{
- vfree(priv->sglist);
- vfree(priv->vaddr);
- priv->buf_allocated = false;
- priv->bytes = 0;
-}
-
-/*
- * Private Data Reference Count
- */
-
-static void fpga_dev_remove(struct kref *ref)
-{
- struct fpga_dev *priv = container_of(ref, struct fpga_dev, ref);
-
- /* free any firmware image that was not programmed */
- fpga_drop_firmware_data(priv);
-
- mutex_destroy(&priv->lock);
- kfree(priv);
-}
-
-/*
- * LED Trigger (could be a seperate module)
- */
-
-/*
- * NOTE: this whole thing does have the problem that whenever the led's are
- * NOTE: first set to use the fpga trigger, they could be in the wrong state
- */
-
-DEFINE_LED_TRIGGER(ledtrig_fpga);
-
-static void ledtrig_fpga_programmed(bool enabled)
-{
- if (enabled)
- led_trigger_event(ledtrig_fpga, LED_FULL);
- else
- led_trigger_event(ledtrig_fpga, LED_OFF);
-}
-
-/*
- * FPGA Register Helpers
- */
-
-/* Register Definitions */
-#define FPGA_CONFIG_CONTROL 0x40
-#define FPGA_CONFIG_STATUS 0x44
-#define FPGA_CONFIG_FIFO_SIZE 0x48
-#define FPGA_CONFIG_FIFO_USED 0x4C
-#define FPGA_CONFIG_TOTAL_BYTE_COUNT 0x50
-#define FPGA_CONFIG_CUR_BYTE_COUNT 0x54
-
-#define FPGA_FIFO_ADDRESS 0x3000
-
-static int fpga_fifo_size(void __iomem *regs)
-{
- return ioread32be(regs + FPGA_CONFIG_FIFO_SIZE);
-}
-
-#define CFG_STATUS_ERR_MASK 0xfffe
-
-static int fpga_config_error(void __iomem *regs)
-{
- return ioread32be(regs + FPGA_CONFIG_STATUS) & CFG_STATUS_ERR_MASK;
-}
-
-static int fpga_fifo_empty(void __iomem *regs)
-{
- return ioread32be(regs + FPGA_CONFIG_FIFO_USED) == 0;
-}
-
-static void fpga_fifo_write(void __iomem *regs, u32 val)
-{
- iowrite32be(val, regs + FPGA_FIFO_ADDRESS);
-}
-
-static void fpga_set_byte_count(void __iomem *regs, u32 count)
-{
- iowrite32be(count, regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
-}
-
-#define CFG_CTL_ENABLE (1 << 0)
-#define CFG_CTL_RESET (1 << 1)
-#define CFG_CTL_DMA (1 << 2)
-
-static void fpga_programmer_enable(struct fpga_dev *priv, bool dma)
-{
- u32 val;
-
- val = (dma) ? (CFG_CTL_ENABLE | CFG_CTL_DMA) : CFG_CTL_ENABLE;
- iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
-}
-
-static void fpga_programmer_disable(struct fpga_dev *priv)
-{
- iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);
-}
-
-static void fpga_dump_registers(struct fpga_dev *priv)
-{
- u32 control, status, size, used, total, curr;
-
- /* good status: do nothing */
- if (priv->status == 0)
- return;
-
- /* Dump all status registers */
- control = ioread32be(priv->regs + FPGA_CONFIG_CONTROL);
- status = ioread32be(priv->regs + FPGA_CONFIG_STATUS);
- size = ioread32be(priv->regs + FPGA_CONFIG_FIFO_SIZE);
- used = ioread32be(priv->regs + FPGA_CONFIG_FIFO_USED);
- total = ioread32be(priv->regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
- curr = ioread32be(priv->regs + FPGA_CONFIG_CUR_BYTE_COUNT);
-
- dev_err(priv->dev, "Configuration failed, dumping status registers\n");
- dev_err(priv->dev, "Control: 0x%.8x\n", control);
- dev_err(priv->dev, "Status: 0x%.8x\n", status);
- dev_err(priv->dev, "FIFO Size: 0x%.8x\n", size);
- dev_err(priv->dev, "FIFO Used: 0x%.8x\n", used);
- dev_err(priv->dev, "FIFO Total: 0x%.8x\n", total);
- dev_err(priv->dev, "FIFO Curr: 0x%.8x\n", curr);
-}
-
-/*
- * FPGA Power Supply Code
- */
-
-#define CTL_PWR_CONTROL 0x2006
-#define CTL_PWR_STATUS 0x200A
-#define CTL_PWR_FAIL 0x200B
-
-#define PWR_CONTROL_ENABLE 0x01
-
-#define PWR_STATUS_ERROR_MASK 0x10
-#define PWR_STATUS_GOOD 0x0f
-
-/*
- * Determine if the FPGA power is good for all supplies
- */
-static bool fpga_power_good(struct fpga_dev *priv)
-{
- u8 val;
-
- val = ioread8(priv->regs + CTL_PWR_STATUS);
- if (val & PWR_STATUS_ERROR_MASK)
- return false;
-
- return val == PWR_STATUS_GOOD;
-}
-
-/*
- * Disable the FPGA power supplies
- */
-static void fpga_disable_power_supplies(struct fpga_dev *priv)
-{
- unsigned long start;
- u8 val;
-
- iowrite8(0x0, priv->regs + CTL_PWR_CONTROL);
-
- /*
- * Wait 500ms for the power rails to discharge
- *
- * Without this delay, the CTL-CPLD state machine can get into a
- * state where it is waiting for the power-goods to assert, but they
- * never do. This only happens when enabling and disabling the
- * power sequencer very rapidly.
- *
- * The loop below will also wait for the power goods to de-assert,
- * but testing has shown that they are always disabled by the time
- * the sleep completes. However, omitting the sleep and only waiting
- * for the power-goods to de-assert was not sufficient to ensure
- * that the power sequencer would not wedge itself.
- */
- msleep(500);
-
- start = jiffies;
- while (time_before(jiffies, start + HZ)) {
- val = ioread8(priv->regs + CTL_PWR_STATUS);
- if (!(val & PWR_STATUS_GOOD))
- break;
-
- usleep_range(5000, 10000);
- }
-
- val = ioread8(priv->regs + CTL_PWR_STATUS);
- if (val & PWR_STATUS_GOOD) {
- dev_err(priv->dev, "power disable failed: "
- "power goods: status 0x%.2x\n", val);
- }
-
- if (val & PWR_STATUS_ERROR_MASK) {
- dev_err(priv->dev, "power disable failed: "
- "alarm bit set: status 0x%.2x\n", val);
- }
-}
-
-/**
- * fpga_enable_power_supplies() - enable the DATA-FPGA power supplies
- * @priv: the driver's private data structure
- *
- * Enable the DATA-FPGA power supplies, waiting up to 1 second for
- * them to enable successfully.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int fpga_enable_power_supplies(struct fpga_dev *priv)
-{
- unsigned long start = jiffies;
-
- if (fpga_power_good(priv)) {
- dev_dbg(priv->dev, "power was already good\n");
- return 0;
- }
-
- iowrite8(PWR_CONTROL_ENABLE, priv->regs + CTL_PWR_CONTROL);
- while (time_before(jiffies, start + HZ)) {
- if (fpga_power_good(priv))
- return 0;
-
- usleep_range(5000, 10000);
- }
-
- return fpga_power_good(priv) ? 0 : -ETIMEDOUT;
-}
-
-/*
- * Determine if the FPGA power supplies are all enabled
- */
-static bool fpga_power_enabled(struct fpga_dev *priv)
-{
- u8 val;
-
- val = ioread8(priv->regs + CTL_PWR_CONTROL);
- if (val & PWR_CONTROL_ENABLE)
- return true;
-
- return false;
-}
-
-/*
- * Determine if the FPGA's are programmed and running correctly
- */
-static bool fpga_running(struct fpga_dev *priv)
-{
- if (!fpga_power_good(priv))
- return false;
-
- /* Check the config done bit */
- return ioread32be(priv->regs + FPGA_CONFIG_STATUS) & (1 << 18);
-}
-
-/*
- * FPGA Programming Code
- */
-
-/**
- * fpga_program_block() - put a block of data into the programmer's FIFO
- * @priv: the driver's private data structure
- * @buf: the data to program
- * @count: the length of data to program (must be a multiple of 4 bytes)
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int fpga_program_block(struct fpga_dev *priv, void *buf, size_t count)
-{
- u32 *data = buf;
- int size = fpga_fifo_size(priv->regs);
- int i, len;
- unsigned long timeout;
-
- /* enforce correct data length for the FIFO */
- BUG_ON(count % 4 != 0);
-
- while (count > 0) {
-
- /* Get the size of the block to write (maximum is FIFO_SIZE) */
- len = min_t(size_t, count, size);
- timeout = jiffies + HZ / 4;
-
- /* Write the block */
- for (i = 0; i < len / 4; i++)
- fpga_fifo_write(priv->regs, data[i]);
-
- /* Update the amounts left */
- count -= len;
- data += len / 4;
-
- /* Wait for the fifo to empty */
- while (true) {
-
- if (fpga_fifo_empty(priv->regs)) {
- break;
- } else {
- dev_dbg(priv->dev, "Fifo not empty\n");
- cpu_relax();
- }
-
- if (fpga_config_error(priv->regs)) {
- dev_err(priv->dev, "Error detected\n");
- return -EIO;
- }
-
- if (time_after(jiffies, timeout)) {
- dev_err(priv->dev, "Fifo drain timeout\n");
- return -ETIMEDOUT;
- }
-
- usleep_range(5000, 10000);
- }
- }
-
- return 0;
-}
-
-/**
- * fpga_program_cpu() - program the DATA-FPGA's using the CPU
- * @priv: the driver's private data structure
- *
- * This is useful when the DMA programming method fails. It is possible to
- * wedge the Freescale DMA controller such that the DMA programming method
- * always fails. This method has always succeeded.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static noinline int fpga_program_cpu(struct fpga_dev *priv)
-{
- int ret;
- unsigned long timeout;
-
- /* Disable the programmer */
- fpga_programmer_disable(priv);
-
- /* Set the total byte count */
- fpga_set_byte_count(priv->regs, priv->bytes);
- dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);
-
- /* Enable the controller for programming */
- fpga_programmer_enable(priv, false);
- dev_dbg(priv->dev, "enabled the controller\n");
-
- /* Write each chunk of the FPGA bitfile to FPGA programmer */
- ret = fpga_program_block(priv, priv->vaddr, priv->bytes);
- if (ret)
- goto out_disable_controller;
-
- /* Wait for the interrupt handler to signal that programming finished */
- timeout = wait_for_completion_timeout(&priv->completion, 2 * HZ);
- if (!timeout) {
- dev_err(priv->dev, "Timed out waiting for completion\n");
- ret = -ETIMEDOUT;
- goto out_disable_controller;
- }
-
- /* Retrieve the status from the interrupt handler */
- ret = priv->status;
-
-out_disable_controller:
- fpga_programmer_disable(priv);
- return ret;
-}
-
-#define FIFO_DMA_ADDRESS 0xf0003000
-#define FIFO_MAX_LEN 4096
-
-/**
- * fpga_program_dma() - program the DATA-FPGA's using the DMA engine
- * @priv: the driver's private data structure
- *
- * Program the DATA-FPGA's using the Freescale DMA engine. This requires that
- * the engine is programmed such that the hardware DMA request lines can
- * control the entire DMA transaction. The system controller FPGA then
- * completely offloads the programming from the CPU.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static noinline int fpga_program_dma(struct fpga_dev *priv)
-{
- struct dma_chan *chan = priv->chan;
- struct dma_async_tx_descriptor *tx;
- size_t num_pages, len, avail = 0;
- struct dma_slave_config config;
- struct scatterlist *sg;
- struct sg_table table;
- dma_cookie_t cookie;
- int ret, i;
- unsigned long timeout;
-
- /* Disable the programmer */
- fpga_programmer_disable(priv);
-
- /* Allocate a scatterlist for the DMA destination */
- num_pages = DIV_ROUND_UP(priv->bytes, FIFO_MAX_LEN);
- ret = sg_alloc_table(&table, num_pages, GFP_KERNEL);
- if (ret) {
- dev_err(priv->dev, "Unable to allocate dst scatterlist\n");
- ret = -ENOMEM;
- goto out_return;
- }
-
- /*
- * This is an ugly hack
- *
- * We fill in a scatterlist as if it were mapped for DMA. This is
- * necessary because there exists no better structure for this
- * inside the kernel code.
- *
- * As an added bonus, we can use the DMAEngine API for all of this,
- * rather than inventing another extremely similar API.
- */
- avail = priv->bytes;
- for_each_sg(table.sgl, sg, num_pages, i) {
- len = min_t(size_t, avail, FIFO_MAX_LEN);
- sg_dma_address(sg) = FIFO_DMA_ADDRESS;
- sg_dma_len(sg) = len;
-
- avail -= len;
- }
-
- /* Map the buffer for DMA */
- ret = fpga_dma_map(priv);
- if (ret) {
- dev_err(priv->dev, "Unable to map buffer for DMA\n");
- goto out_free_table;
- }
-
- /*
- * Configure the DMA channel to transfer FIFO_SIZE / 2 bytes per
- * transaction, and then put it under external control
- */
- memset(&config, 0, sizeof(config));
- config.direction = DMA_MEM_TO_DEV;
- config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- config.dst_maxburst = fpga_fifo_size(priv->regs) / 2 / 4;
- ret = dmaengine_slave_config(chan, &config);
- if (ret) {
- dev_err(priv->dev, "DMA slave configuration failed\n");
- goto out_dma_unmap;
- }
-
- ret = fsl_dma_external_start(chan, 1);
- if (ret) {
- dev_err(priv->dev, "DMA external control setup failed\n");
- goto out_dma_unmap;
- }
-
- /* setup and submit the DMA transaction */
-
- tx = dmaengine_prep_dma_sg(chan, table.sgl, num_pages,
- priv-&g