aboutsummaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig32
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/bfin-otp.c189
-rw-r--r--drivers/char/drm/drmP.h1
-rw-r--r--drivers/char/drm/i915_drv.h4
-rw-r--r--drivers/char/generic_serial.c1
-rw-r--r--drivers/char/hpet.c51
-rw-r--r--drivers/char/hvc_beat.c4
-rw-r--r--drivers/char/hw_random/core.c14
-rw-r--r--drivers/char/hw_random/omap-rng.c26
-rw-r--r--drivers/char/ip2/i2lib.c12
-rw-r--r--drivers/char/keyboard.c3
-rw-r--r--drivers/char/misc.c13
-rw-r--r--drivers/char/pcmcia/synclink_cs.c10
-rw-r--r--drivers/char/rio/rioboot.c1
-rw-r--r--drivers/char/rio/riocmd.c1
-rw-r--r--drivers/char/rio/rioctrl.c1
-rw-r--r--drivers/char/rio/rioinit.c1
-rw-r--r--drivers/char/rio/riointr.c1
-rw-r--r--drivers/char/rio/rioparam.c1
-rw-r--r--drivers/char/rio/rioroute.c1
-rw-r--r--drivers/char/rio/riotable.c5
-rw-r--r--drivers/char/rio/riotty.c5
-rw-r--r--drivers/char/snsc.h2
-rw-r--r--drivers/char/sonypi.c2
-rw-r--r--drivers/char/specialix.c10
-rw-r--r--drivers/char/stallion.c2
-rw-r--r--drivers/char/synclink.c21
-rw-r--r--drivers/char/synclink_gt.c13
-rw-r--r--drivers/char/synclinkmp.c22
-rw-r--r--drivers/char/tpm/tpm_tis.c2
-rw-r--r--drivers/char/tty_io.c47
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.c22
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.h5
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.c31
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.h1
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c63
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.h24
38 files changed, 444 insertions, 201 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 47c6be84fc8..2906ee7bd29 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -481,6 +481,34 @@ config BRIQ_PANEL
It's safe to say N here.
+config BFIN_OTP
+ tristate "Blackfin On-Chip OTP Memory Support"
+ depends on BLACKFIN && (BF52x || BF54x)
+ default y
+ help
+ If you say Y here, you will get support for a character device
+ interface into the One Time Programmable memory pages that are
+ stored on the Blackfin processor. This will not get you access
+ to the secure memory pages however. You will need to write your
+ own secure code and reader for that.
+
+ To compile this driver as a module, choose M here: the module
+ will be called bfin-otp.
+
+ If unsure, it is safe to say Y.
+
+config BFIN_OTP_WRITE_ENABLE
+ bool "Enable writing support of OTP pages"
+ depends on BFIN_OTP
+ default n
+ help
+ If you say Y here, you will enable support for writing of the
+ OTP pages. This is dangerous by nature as you can only program
+ the pages once, so only enable this option when you actually
+ need it so as to not inadvertently clobber data.
+
+ If unsure, say N.
+
config PRINTER
tristate "Parallel printer support"
depends on PARPORT
@@ -706,7 +734,7 @@ config NVRAM
config RTC
tristate "Enhanced Real Time Clock Support"
- depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390
+ depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390 && !AVR32
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -776,7 +804,7 @@ config SGI_IP27_RTC
config GEN_RTC
tristate "Generic /dev/rtc emulation"
- depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH
+ depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH && !AVR32
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 5407b761561..4c1c584e9eb 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_VIOTAPE) += viotape.o
obj-$(CONFIG_HVCS) += hvcs.o
obj-$(CONFIG_SGI_MBCS) += mbcs.o
obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
+obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c
new file mode 100644
index 00000000000..0a01329451e
--- /dev/null
+++ b/drivers/char/bfin-otp.c
@@ -0,0 +1,189 @@
+/*
+ * Blackfin On-Chip OTP Memory Interface
+ * Supports BF52x/BF54x
+ *
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#include <asm/blackfin.h>
+#include <asm/uaccess.h>
+
+#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
+#define stampit() stamp("here i am")
+#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); })
+
+#define DRIVER_NAME "bfin-otp"
+#define PFX DRIVER_NAME ": "
+
+static DEFINE_MUTEX(bfin_otp_lock);
+
+/* OTP Boot ROM functions */
+#define _BOOTROM_OTP_COMMAND 0xEF000018
+#define _BOOTROM_OTP_READ 0xEF00001A
+#define _BOOTROM_OTP_WRITE 0xEF00001C
+
+static u32 (* const otp_command)(u32 command, u32 value) = (void *)_BOOTROM_OTP_COMMAND;
+static u32 (* const otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)_BOOTROM_OTP_READ;
+static u32 (* const otp_write)(u32 page, u32 flags, u64 *page_content) = (void *)_BOOTROM_OTP_WRITE;
+
+/* otp_command(): defines for "command" */
+#define OTP_INIT 0x00000001
+#define OTP_CLOSE 0x00000002
+
+/* otp_{read,write}(): defines for "flags" */
+#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */
+#define OTP_UPPER_HALF 0x00000001
+#define OTP_NO_ECC 0x00000010 /* do not use ECC */
+#define OTP_LOCK 0x00000020 /* sets page protection bit for page */
+#define OTP_ACCESS_READ 0x00001000
+#define OTP_ACCESS_READWRITE 0x00002000
+
+/* Return values for all functions */
+#define OTP_SUCCESS 0x00000000
+#define OTP_MASTER_ERROR 0x001
+#define OTP_WRITE_ERROR 0x003
+#define OTP_READ_ERROR 0x005
+#define OTP_ACC_VIO_ERROR 0x009
+#define OTP_DATA_MULT_ERROR 0x011
+#define OTP_ECC_MULT_ERROR 0x021
+#define OTP_PREV_WR_ERROR 0x041
+#define OTP_DATA_SB_WARN 0x100
+#define OTP_ECC_SB_WARN 0x200
+
+/**
+ * bfin_otp_read - Read OTP pages
+ *
+ * All reads must be in half page chunks (half page == 64 bits).
+ */
+static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, loff_t *pos)
+{
+ ssize_t bytes_done;
+ u32 page, flags, ret;
+ u64 content;
+
+ stampit();
+
+ if (count % sizeof(u64))
+ return -EMSGSIZE;
+
+ if (mutex_lock_interruptible(&bfin_otp_lock))
+ return -ERESTARTSYS;
+
+ bytes_done = 0;
+ page = *pos / (sizeof(u64) * 2);
+ while (bytes_done < count) {
+ flags = (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
+ stamp("processing page %i (%s)", page, (flags == OTP_UPPER_HALF ? "upper" : "lower"));
+ ret = otp_read(page, flags, &content);
+ if (ret & OTP_MASTER_ERROR) {
+ bytes_done = -EIO;
+ break;
+ }
+ if (copy_to_user(buff + bytes_done, &content, sizeof(content))) {
+ bytes_done = -EFAULT;
+ break;
+ }
+ if (flags == OTP_UPPER_HALF)
+ ++page;
+ bytes_done += sizeof(content);
+ *pos += sizeof(content);
+ }
+
+ mutex_unlock(&bfin_otp_lock);
+
+ return bytes_done;
+}
+
+#ifdef CONFIG_BFIN_OTP_WRITE_ENABLE
+/**
+ * bfin_otp_write - Write OTP pages
+ *
+ * All writes must be in half page chunks (half page == 64 bits).
+ */
+static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos)
+{
+ stampit();
+
+ if (count % sizeof(u64))
+ return -EMSGSIZE;
+
+ if (mutex_lock_interruptible(&bfin_otp_lock))
+ return -ERESTARTSYS;
+
+ /* need otp_init() documentation before this can be implemented */
+
+ mutex_unlock(&bfin_otp_lock);
+
+ return -EINVAL;
+}
+#else
+# define bfin_otp_write NULL
+#endif
+
+static struct file_operations bfin_otp_fops = {
+ .owner = THIS_MODULE,
+ .read = bfin_otp_read,
+ .write = bfin_otp_write,
+};
+
+static struct miscdevice bfin_otp_misc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = DRIVER_NAME,
+ .fops = &bfin_otp_fops,
+};
+
+/**
+ * bfin_otp_init - Initialize module
+ *
+ * Registers the device and notifier handler. Actual device
+ * initialization is handled by bfin_otp_open().
+ */
+static int __init bfin_otp_init(void)
+{
+ int ret;
+
+ stampit();
+
+ ret = misc_register(&bfin_otp_misc_device);
+ if (ret) {
+ pr_init(KERN_ERR PFX "unable to register a misc device\n");
+ return ret;
+ }
+
+ pr_init(KERN_INFO PFX "initialized\n");
+
+ return 0;
+}
+
+/**
+ * bfin_otp_exit - Deinitialize module
+ *
+ * Unregisters the device and notifier handler. Actual device
+ * deinitialization is handled by bfin_otp_close().
+ */
+static void __exit bfin_otp_exit(void)
+{
+ stampit();
+
+ misc_deregister(&bfin_otp_misc_device);
+}
+
+module_init(bfin_otp_init);
+module_exit(bfin_otp_exit);
+
+MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
+MODULE_DESCRIPTION("Blackfin OTP Memory Interface");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 8ea9dd1717a..6540948d517 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -640,7 +640,6 @@ struct drm_head {
struct drm_device *dev;
struct proc_dir_entry *dev_root; /**< proc directory entry */
dev_t device; /**< Device number for mknod */
- struct class_device *dev_class;
};
/**
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index c10d128e34d..675d88bda06 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -1092,8 +1092,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
-#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2)
-
+#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\
+ (dev)->pci_device == 0x27AE)
#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
(dev)->pci_device == 0x2982 || \
(dev)->pci_device == 0x2992 || \
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 8facf3e25c4..7ed7da1d99c 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -28,7 +28,6 @@
#include <linux/interrupt.h>
#include <linux/tty_flip.h>
#include <linux/delay.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#define DEBUG
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 465ad35ed38..1399971be68 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -731,14 +731,14 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
int hpet_alloc(struct hpet_data *hdp)
{
- u64 cap, mcfg, hpet_config;
+ u64 cap, mcfg;
struct hpet_dev *devp;
- u32 i, ntimer, irq;
+ u32 i, ntimer;
struct hpets *hpetp;
size_t siz;
struct hpet __iomem *hpet;
static struct hpets *last = NULL;
- unsigned long period, irq_bitmap;
+ unsigned long period;
unsigned long long temp;
/*
@@ -765,47 +765,11 @@ int hpet_alloc(struct hpet_data *hdp)
hpetp->hp_hpet_phys = hdp->hd_phys_address;
hpetp->hp_ntimer = hdp->hd_nirqs;
- hpet = hpetp->hp_hpet;
-
- /* Assign IRQs statically for legacy devices */
- hpetp->hp_dev[0].hd_hdwirq = hdp->hd_irq[0];
- hpetp->hp_dev[1].hd_hdwirq = hdp->hd_irq[1];
-
- /* Assign IRQs dynamically for the others */
- for (i = 2, devp = &hpetp->hp_dev[2]; i < hdp->hd_nirqs; i++, devp++) {
- struct hpet_timer __iomem *timer;
- timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
+ for (i = 0; i < hdp->hd_nirqs; i++)
+ hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i];
- /* Check if there's already an IRQ assigned to the timer */
- if (hdp->hd_irq[i]) {
- hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i];
- continue;
- }
-
- hpet_config = readq(&timer->hpet_config);
- irq_bitmap = (hpet_config & Tn_INT_ROUTE_CAP_MASK)
- >> Tn_INT_ROUTE_CAP_SHIFT;
- if (!irq_bitmap)
- irq = 0; /* No valid IRQ Assignable */
- else {
- irq = find_first_bit(&irq_bitmap, 32);
- do {
- hpet_config |= irq << Tn_INT_ROUTE_CNF_SHIFT;
- writeq(hpet_config, &timer->hpet_config);
-
- /*
- * Verify whether we have written a valid
- * IRQ number by reading it back again
- */
- hpet_config = readq(&timer->hpet_config);
- if (irq == (hpet_config & Tn_INT_ROUTE_CNF_MASK)
- >> Tn_INT_ROUTE_CNF_SHIFT)
- break; /* Success */
- } while ((irq = (find_next_bit(&irq_bitmap, 32, irq))));
- }
- hpetp->hp_dev[i].hd_hdwirq = irq;
- }
+ hpet = hpetp->hp_hpet;
cap = readq(&hpet->hpet_cap);
@@ -836,8 +800,7 @@ int hpet_alloc(struct hpet_data *hdp)
hpetp->hp_which, hdp->hd_phys_address,
hpetp->hp_ntimer > 1 ? "s" : "");
for (i = 0; i < hpetp->hp_ntimer; i++)
- printk("%s %d", i > 0 ? "," : "",
- hpetp->hp_dev[i].hd_hdwirq);
+ printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
printk("\n");
printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n",
diff --git a/drivers/char/hvc_beat.c b/drivers/char/hvc_beat.c
index e74bb949c28..91cdb35a920 100644
--- a/drivers/char/hvc_beat.c
+++ b/drivers/char/hvc_beat.c
@@ -78,8 +78,8 @@ static int hvc_beat_put_chars(uint32_t vtermno, const char *buf, int cnt)
for (rest = cnt; rest > 0; rest -= nlen) {
nlen = (rest > 16) ? 16 : rest;
memcpy(kb, buf, nlen);
- beat_put_term_char(vtermno, rest, kb[0], kb[1]);
- rest -= nlen;
+ beat_put_term_char(vtermno, nlen, kb[0], kb[1]);
+ buf += nlen;
}
return cnt;
}
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 84cdf902573..662d60e44e9 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -116,6 +116,10 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
err = -EAGAIN;
if (!bytes_read && (filp->f_flags & O_NONBLOCK))
goto out;
+ if (bytes_read < 0) {
+ err = bytes_read;
+ goto out;
+ }
err = -EFAULT;
while (bytes_read && size) {
@@ -234,11 +238,11 @@ static DEVICE_ATTR(rng_available, S_IRUGO,
NULL);
-static void unregister_miscdev(bool suspended)
+static void unregister_miscdev(void)
{
device_remove_file(rng_miscdev.this_device, &dev_attr_rng_available);
device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
- __misc_deregister(&rng_miscdev, suspended);
+ misc_deregister(&rng_miscdev);
}
static int register_miscdev(void)
@@ -313,7 +317,7 @@ out:
}
EXPORT_SYMBOL_GPL(hwrng_register);
-void __hwrng_unregister(struct hwrng *rng, bool suspended)
+void hwrng_unregister(struct hwrng *rng)
{
int err;
@@ -332,11 +336,11 @@ void __hwrng_unregister(struct hwrng *rng, bool suspended)
}
}
if (list_empty(&rng_list))
- unregister_miscdev(suspended);
+ unregister_miscdev();
mutex_unlock(&rng_mutex);
}
-EXPORT_SYMBOL_GPL(__hwrng_unregister);
+EXPORT_SYMBOL_GPL(hwrng_unregister);
MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 7e319951fa4..51738bdd834 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -1,7 +1,5 @@
/*
- * drivers/char/hw_random/omap-rng.c
- *
- * RNG driver for TI OMAP CPU family
+ * omap-rng.c - RNG driver for TI OMAP CPU family
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
@@ -15,11 +13,6 @@
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
- *
- * TODO:
- *
- * - Make status updated be interrupt driven so we don't poll
- *
*/
#include <linux/module.h>
@@ -55,17 +48,16 @@ static void __iomem *rng_base;
static struct clk *rng_ick;
static struct platform_device *rng_dev;
-static u32 omap_rng_read_reg(int reg)
+static inline u32 omap_rng_read_reg(int reg)
{
return __raw_readl(rng_base + reg);
}
-static void omap_rng_write_reg(int reg, u32 val)
+static inline void omap_rng_write_reg(int reg, u32 val)
{
__raw_writel(val, rng_base + reg);
}
-/* REVISIT: Does the status bit really work on 16xx? */
static int omap_rng_data_present(struct hwrng *rng, int wait)
{
int data, i;
@@ -74,6 +66,11 @@ static int omap_rng_data_present(struct hwrng *rng, int wait)
data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
if (data || !wait)
break;
+ /* RNG produces data fast enough (2+ MBit/sec, even
+ * during "rngtest" loads, that these delays don't
+ * seem to trigger. We *could* use the RNG IRQ, but
+ * that'd be higher overhead ... so why bother?
+ */
udelay(10);
}
return data;
@@ -101,7 +98,8 @@ static int __init omap_rng_probe(struct platform_device *pdev)
* A bit ugly, and it will never actually happen but there can
* be only one RNG and this catches any bork
*/
- BUG_ON(rng_dev);
+ if (rng_dev)
+ return -EBUSY;
if (cpu_is_omap24xx()) {
rng_ick = clk_get(NULL, "rng_ick");
@@ -124,7 +122,7 @@ static int __init omap_rng_probe(struct platform_device *pdev)
return -EBUSY;
dev_set_drvdata(&pdev->dev, mem);
- rng_base = (u32 __iomem *)io_p2v(res->start);
+ rng_base = (u32 __force __iomem *)io_p2v(res->start);
ret = hwrng_register(&omap_rng_ops);
if (ret) {
@@ -182,6 +180,8 @@ static int omap_rng_resume(struct platform_device *pdev)
#endif
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:omap_rng");
static struct platform_driver omap_rng_driver = {
.driver = {
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index d6567b32fb5..9c25320121e 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -644,12 +644,12 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
// Normal Expected path - We still hold LOCK
break; /* from for()- Enough room: goto proceed */
}
- }
-
- ip2trace (CHANN, ITRC_QUEUE, 3, 1, totalsize );
+ ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize);
+ WRITE_UNLOCK_IRQRESTORE(lock_var_p, flags);
+ } else
+ ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize);
- // Prepare to wait for buffers to empty
- WRITE_UNLOCK_IRQRESTORE(lock_var_p,flags);
+ /* Prepare to wait for buffers to empty */
serviceOutgoingFifo(pB); // Dump what we got
if (timeout == 0) {
@@ -1830,6 +1830,8 @@ i2StripFifo(i2eBordStrPtr pB)
default: // Neither packet? should be impossible
ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1,
PTYPE_OF(pB->i2eLeadoffWord) );
+ WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,
+ bflags);
break;
} // End of switch on type of packets
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 45806d27579..60b934adea6 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1035,7 +1035,8 @@ DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
- (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
+ (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
+ defined(CONFIG_AVR32)
#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index a39101feb2e..4d058dadbfc 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -232,9 +232,8 @@ int misc_register(struct miscdevice * misc)
}
/**
- * __misc_deregister - unregister a miscellaneous device
+ * misc_deregister - unregister a miscellaneous device
* @misc: device to unregister
- * @suspended: to be set if the function is used during suspend/resume
*
* Unregister a miscellaneous device that was previously
* successfully registered with misc_register(). Success
@@ -242,7 +241,7 @@ int misc_register(struct miscdevice * misc)
* indicates an error.
*/
-int __misc_deregister(struct miscdevice *misc, bool suspended)
+int misc_deregister(struct miscdevice *misc)
{
int i = misc->minor;
@@ -251,11 +250,7 @@ int __misc_deregister(struct miscdevice *misc, bool suspended)
mutex_lock(&misc_mtx);
list_del(&misc->list);
- if (suspended)
- destroy_suspended_device(misc_class,
- MKDEV(MISC_MAJOR, misc->minor));
- else
- device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
+ device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
if (i < DYNAMIC_MINORS && i>0) {
misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
}
@@ -264,7 +259,7 @@ int __misc_deregister(struct miscdevice *misc, bool suspended)
}
EXPORT_SYMBOL(misc_register);
-EXPORT_SYMBOL(__misc_deregister);
+EXPORT_SYMBOL(misc_deregister);
static int __init misc_init(void)
{
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 279ff5005ce..4e84d233e5a 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -1225,17 +1225,15 @@ static void ri_change(MGSLPC_INFO *info)
* irq interrupt number that caused interrupt
* dev_id device ID supplied during interrupt registration
*/
-static irqreturn_t mgslpc_isr(int irq, void *dev_id)
+static irqreturn_t mgslpc_isr(int dummy, void *dev_id)
{
- MGSLPC_INFO * info = (MGSLPC_INFO *)dev_id;
+ MGSLPC_INFO *info = dev_id;
unsigned short isr;
unsigned char gis, pis;
int count=0;
if (debug_level >= DEBUG_LEVEL_ISR)
- printk("mgslpc_isr(%d) entry.\n", irq);
- if (!info)
- return IRQ_NONE;
+ printk("mgslpc_isr(%d) entry.\n", info->irq_level);
if (!(info->p_dev->_locked))
return IRQ_HANDLED;
@@ -1327,7 +1325,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id)
if (debug_level >= DEBUG_LEVEL_ISR)
printk("%s(%d):mgslpc_isr(%d)exit.\n",
- __FILE__,__LINE__,irq);
+ __FILE__, __LINE__, info->irq_level);
return IRQ_HANDLED;
}
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
index eca2b95343e..d956dd31600 100644
--- a/drivers/char/rio/rioboot.c
+++ b/drivers/char/rio/rioboot.c
@@ -35,7 +35,6 @@
#include <linux/termios.h>
#include <linux/serial.h>
#include <linux/vmalloc.h>
-#include <asm/semaphore.h>
#include <linux/generic_serial.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 7321d002c34..bf36959fc12 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -41,7 +41,6 @@ static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index 7ce77619707..d8eb2bcbe01 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -40,7 +40,6 @@ static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index 0794844369d..add1718295e 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -40,7 +40,6 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index ebc76342712..4734e26e1cc 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -42,7 +42,6 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index bb498d24adc..da276ed57b3 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -41,7 +41,6 @@ static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index a99f3d9d7d6..85091ff74d9 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -39,7 +39,6 @@ static char *_rioroute_c_sccs_ = "@(#)rioroute.c 1.3";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
index 991119c9f47..2b24488e95f 100644
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -42,7 +42,6 @@ static char *_riotable_c_sccs_ = "@(#)riotable.c 1.2";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
@@ -425,8 +424,10 @@ int RIOApel(struct rio_info *p)
MapP = &p->RIOConnectTable[Next++];
MapP->HostUniqueNum = HostP->UniqueNum;
- if ((HostP->Flags & RUN_STATE) != RC_RUNNING)
+ if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
+ rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
continue;
+ }
MapP->RtaUniqueNum = 0;
MapP->ID = 0;
MapP->Flags = SLOT_IN_USE;
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index a4f0b1e3e7f..1cb8580a161 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -44,7 +44,6 @@ static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3";
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
-#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/termios.h>
@@ -319,6 +318,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
PortP->State |= RIO_WOPEN;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
/*
** ACTION: verify that this is a good thing
** to do here. -- ???
@@ -334,6 +334,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
func_exit();
return -EINTR;
}
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
}
PortP->State &= ~RIO_WOPEN;
}
@@ -493,6 +494,7 @@ int riotclose(void *ptr)
if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
RIOPreemptiveCmd(p, PortP, FCLOSE);
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
goto close_end;
}
@@ -508,6 +510,7 @@ int riotclose(void *ptr)
if (p->RIOHalted) {
RIOClearUp(PortP);
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
goto close_end;
}
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
diff --git a/drivers/char/snsc.h b/drivers/char/snsc.h
index 8a98169b60c..4be62eda9fb 100644
--- a/drivers/char/snsc.h
+++ b/drivers/char/snsc.h
@@ -22,8 +22,8 @@
#include <linux/kobject.h>
#include <linux/fs.h>
#include <linux/cdev.h>
+#include <linux/semaphore.h>
#include <asm/sn/types.h>
-#include <asm/semaphore.h>
#define CHUNKSIZE 127
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 921c6d2bc8f..c03ad164c39 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1147,7 +1147,7 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type)
return 0;
}
-const static struct acpi_device_id sonypi_device_ids[] = {
+static const struct acpi_device_id sonypi_device_ids[] = {
{"SNY6001", 0},
{"", 0},
};
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 5ff83df67b4..4b5b5b78acb 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -443,8 +443,7 @@ void missed_irq (unsigned long data)
spin_unlock_irqrestore(&bp->lock, flags);
if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
- sx_interrupt (((struct specialix_board *)data)->irq,
- (void*)data);
+ sx_interrupt (-1, bp);
}
mod_timer(&missed_irq_timer, jiffies + sx_poll);
}
@@ -862,23 +861,22 @@ static inline void sx_check_modem(struct specialix_board * bp)
/* The main interrupt processing routine */
-static irqreturn_t sx_interrupt(int irq, void *dev_id)
+static irqreturn_t sx_interrupt(int dummy, void *dev_id)
{
unsigned char status;
unsigned char ack;
- struct specialix_board *bp;
+ struct specialix_board *bp = dev_id;
unsigned long loop = 0;
int saved_reg;
unsigned long flags;
func_enter();
- bp = dev_id;
spin_lock_irqsave(&bp->lock, flags);
dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
if (!(bp->flags & SX_BOARD_ACTIVE)) {
- dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
+ dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq);
spin_unlock_irqrestore(&bp->lock, flags);
func_exit();
return IRQ_NONE;
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index feac54e32a1..874aaa08e95 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -1645,7 +1645,7 @@ static irqreturn_t stl_intr(int irq, void *dev_id)
{
struct stlbrd *brdp = dev_id;
- pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, irq);
+ pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, brdp->irq);
return IRQ_RETVAL((* brdp->isr)(brdp));
}
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ddc74d1f4f1..a3237d48a58 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1695,20 +1695,16 @@ static void mgsl_isr_transmit_dma( struct mgsl_struct *info )
*
* Return Value: None
*/
-static irqreturn_t mgsl_interrupt(int irq, void *dev_id)
+static irqreturn_t mgsl_interrupt(int dummy, void *dev_id)
{
- struct mgsl_struct * info;
+ struct mgsl_struct *info = dev_id;
u16 UscVector;
u16 DmaVector;
if ( debug_level >= DEBUG_LEVEL_ISR )
- printk("%s(%d):mgsl_interrupt(%d)entry.\n",
- __FILE__,__LINE__,irq);
+ printk(KERN_DEBUG "%s(%d):mgsl_interrupt(%d)entry.\n",
+ __FILE__, __LINE__, info->irq_level);
- info = (struct mgsl_struct *)dev_id;
- if (!info)
- return IRQ_NONE;
-
spin_lock(&info->irq_spinlock);
for(;;) {
@@ -1732,8 +1728,8 @@ static irqreturn_t mgsl_interrupt(int irq, void *dev_id)
mgsl_isr_receive_dma(info);
if ( info->isr_overflow ) {
- printk(KERN_ERR"%s(%d):%s isr overflow irq=%d\n",
- __FILE__,__LINE__,info->device_name, irq);
+ printk(KERN_ERR "%s(%d):%s isr overflow irq=%d\n",
+ __FILE__, __LINE__, info->device_name, info->irq_level);
usc_DisableMasterIrqBit(info);
usc_DisableDmaInterrupts(info,DICR_MASTER);
break;
@@ -1755,8 +1751,9 @@ static irqreturn_t mgsl_interrupt(int irq, void *dev_id)
spin_unlock(&info->irq_spinlock);
if ( debug_level >= DEBUG_LEVEL_ISR )
- printk("%s(%d):mgsl_interrupt(%d)exit.\n",
- __FILE__,__LINE__,irq);
+ printk(KERN_DEBUG "%s(%d):mgsl_interrupt(%d)exit.\n",
+ __FILE__, __LINE__, info->irq_level);
+
return IRQ_HANDLED;
} /* end of mgsl_interrupt() */
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 1f954acf2ba..3c89266c825 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -491,7 +491,6 @@ static void isr_serial(struct slgt_info *info);
static void isr_rdma(struct slgt_info *info);
static void isr_txeom(struct slgt_info *info, unsigned short status);
static void isr_tdma(struct slgt_info *info);
-static irqreturn_t slgt_interrupt(int irq, void *dev_id);
static int alloc_dma_bufs(struct slgt_info *info);
static void free_dma_bufs(struct slgt_info *info);
@@ -2326,17 +2325,13 @@ static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int
* irq interrupt number
* dev_id device ID supplied during interrupt registration
*/
-static irqreturn_t slgt_interrupt(int irq, void *dev_id)
+static irqreturn_t slgt_interrupt(int dummy, void *dev_id)
{
- struct slgt_info *info;
+ struct slgt_info *info = dev_id;
unsigned int gsr;
unsigned int i;
- DBGISR(("slgt_interrupt irq=%d entry\n", irq));
-
- info = dev_id;
- if (!info)
- return IRQ_NONE;
+ DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level));
spin_lock(&info->lock);
@@ -2385,7 +2380,7 @@ static irqreturn_t slgt_interrupt(int irq, void *dev_id)
spin_unlock(&info->lock);
- DBGISR(("slgt_interrupt irq=%d exit\n", irq));
+ DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level));
return IRQ_HANDLED;
}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index f3e7807f78d..c96062ea72b 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -2586,9 +2586,9 @@ void isr_io_pin( SLMP_INFO *info, u16 status )
* dev_id device ID supplied during interrupt registration
* regs interrupted processor context
*/
-static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id)
+static irqreturn_t synclinkmp_interrupt(int dummy, void *dev_id)
{
- SLMP_INFO * info;
+ SLMP_INFO *info = dev_id;
unsigned char status, status0, status1=0;
unsigned char dmastatus, dmastatus0, dmastatus1=0;
unsigned char timerstatus0, timerstatus1=0;
@@ -2597,12 +2597,8 @@ static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id)
unsigned short tmp;
if ( debug_level >= DEBUG_LEVEL_ISR )
- printk("%s(%d): synclinkmp_interrupt(%d)entry.\n",
- __FILE__,__LINE__,irq);
-
- info = (SLMP_INFO *)dev_id;
- if (!info)
- return IRQ_NONE;
+ printk(KERN_DEBUG "%s(%d): synclinkmp_interrupt(%d)entry.\n",
+ __FILE__, __LINE__, info->irq_level);
spin_lock(&info->lock);
@@ -2615,9 +2611,9 @@ static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id)
timerstatus0 = read_reg(info, ISR2);
if ( debug_level >= DEBUG_LEVEL_ISR )
- printk("%s(%d):%s status0=%02x, dmastatus0=%02x, timerstatus0=%02x\n",
- __FILE__,__LINE__,info->device_name,
- status0,dmastatus0,timerstatus0);
+ printk(KERN_DEBUG "%s(%d):%s status0=%02x, dmastatus0=%02x, timerstatus0=%02x\n",
+ __FILE__, __LINE__, info->device_name,
+ status0, dmastatus0, timerstatus0);
if (info->port_count == 4) {
/* get status for SCA1 (ports 2-3) */
@@ -2702,8 +2698,8 @@ static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id)
spin_unlock(&info->lock);
if ( debug_level >= DEBUG_LEVEL_ISR )
- printk("%s(%d):synclinkmp_interrupt(%d)exit.\n",
- __FILE__,__LINE__,irq);
+ printk(KERN_DEBUG "%s(%d):synclinkmp_interrupt(%d)exit.\n",
+ __FILE__, __LINE__, info->irq_level);
return IRQ_HANDLED;
}
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 81503d94fec..13a4bdd4e4d 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -399,7 +399,7 @@ static irqreturn_t tis_int_probe(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static irqreturn_t tis_int_handler(int irq, void *dev_id)
+static irqreturn_t tis_int_handler(int dummy, void *dev_id)
{
struct tpm_chip *chip = dev_id;
u32 interrupt;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 613ec816ce6..4d3c7018f0c 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1155,6 +1155,48 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index)
return NULL;
}
+#ifdef CONFIG_CONSOLE_POLL
+
+/**
+ * tty_find_polling_driver - find device of a polled tty
+ * @name: name string to match
+ * @line: pointer to resulting tty line nr
+ *
+ * This routine returns a tty driver structure, given a name
+ * and the condition that the tty driver is capable of polled
+ * operation.
+ */
+struct tty_driver *tty_find_polling_driver(char *name, int *line)
+{
+ struct tty_driver *p, *res = NULL;
+ int tty_line = 0;
+ char *str;
+
+ mutex_lock(&tty_mutex);
+ /* Search through the tty devices to look for a match */
+ list_for_each_entry(p, &tty_drivers, tty_drivers) {
+ str = name + strlen(p->name);
+ tty_line = simple_strtoul(str, &str, 10);
+ if (*str == ',')
+ str++;
+ if (*str == '\0')
+ str = 0;
+
+ if (tty_line >= 0 && tty_line <= p->num && p->poll_init &&
+ !p->poll_init(p, tty_line, str)) {
+
+ res = p;
+ *line = tty_line;
+ break;
+ }
+ }
+ mutex_unlock(&tty_mutex);
+
+ return res;
+}
+EXPORT_SYMBOL_GPL(tty_find_polling_driver);
+#endif
+
/**
* tty_check_change - check for POSIX terminal changes
* @tty: tty to check
@@ -3850,6 +3892,11 @@ void tty_set_operations(struct tty_driver *driver,
driver->write_proc = op->write_proc;
driver->tiocmget = op->tiocmget;
driver->tiocmset = op->tiocmset;
+#ifdef CONFIG_CONSOLE_POLL
+ driver->poll_init = op->poll_init;
+ driver->poll_get_char = op->poll_get_char;
+ driver->poll_put_char = op->poll_put_char;
+#endif
}
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c
index f577daedb63..aa7f7962a9a 100644
--- a/drivers/char/xilinx_hwicap/buffer_icap.c
+++ b/drivers/char/xilinx_hwicap/buffer_icap.c
@@ -74,7 +74,7 @@
/**
* buffer_icap_get_status - Get the contents of the status register.
- * @base_address: is the base address of the device
+ * @drvdata: a pointer to the drvdata.
*
* The status register contains the ICAP status and the done bit.
*
@@ -88,9 +88,9 @@
* D1 - Always 1
* D0 - Done bit
**/
-static inline u32 buffer_icap_get_status(void __iomem *base_address)
+u32 buffer_icap_get_status(struct hwicap_drvdata *drvdata)
{
- return in_be32(base_address + XHI_STATUS_REG_OFFSET);
+ return in_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET);
}
/**
@@ -117,20 +117,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address,
**/
static inline bool buffer_icap_busy(void __iomem *base_address)
{
- return (buffer_icap_get_status(base_address) & 1) == XHI_NOT_FINISHED;
-}
-
-/**
- * buffer_icap_busy - Return true if the icap device is not busy
- * @base_address: is the base address of the device
- *
- * The queries the low order bit of the status register, which
- * indicates whether the current configuration or readback operation
- * has completed.
- **/
-static inline bool buffer_icap_done(void __iomem *base_address)
-{
- return (buffer_icap_get_status(base_address) & 1) == XHI_FINISHED;
+ u32 status = in_be32(base_address + XHI_STATUS_REG_OFFSET);
+ return (status & 1) == XHI_NOT_FINISHED;
}
/**
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.h b/drivers/char/xilinx_hwicap/buffer_icap.h
index 03184959fa0..c5b1840906b 100644
--- a/drivers/char/xilinx_hwicap/buffer_icap.h
+++ b/drivers/char/xilinx_hwicap/buffer_icap.h
@@ -44,8 +44,6 @@
#include <asm/io.h>
#include "xilinx_hwicap.h"
-void buffer_icap_reset(struct hwicap_drvdata *drvdata);
-
/* Loads a partial bitstream from system memory. */
int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
u32 Size);
@@ -54,4 +52,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
u32 Size);
+u32 buffer_icap_get_status(struct hwicap_drvdata *drvdata);
+void buffer_icap_reset(struct hwicap_drvdata *drvdata);
+
#endif
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c
index 6f45dbd4712..776b5052847 100644
--- a/drivers/char/xilinx_hwicap/fifo_icap.c
+++ b/drivers/char/xilinx_hwicap/fifo_icap.c
@@ -78,13 +78,6 @@
#define XHI_CR_READ_MASK 0x00000002 /* Read from ICAP to FIFO */
#define XHI_CR_WRITE_MASK 0x00000001 /* Write from FIFO to ICAP */
-/* Status Register (SR) */
-#define XHI_SR_CFGERR_N_MASK 0x00000100 /* Config Error Mask */
-#define XHI_SR_DALIGN_MASK 0x00000080 /* Data Alignment Mask */
-#define XHI_SR_RIP_MASK 0x00000040 /* Read back Mask */
-#define XHI_SR_IN_ABORT_N_MASK 0x00000020 /* Select Map Abort Mask */
-#define XHI_SR_DONE_MASK 0x00000001 /* Done bit Mask */
-
#define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */
#define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */
@@ -152,13 +145,35 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
}
/**
+ * fifo_icap_get_status - Get the contents of the status register.
+ * @drvdata: a pointer to the drvdata.
+ *
+ * The status register contains the ICAP status and the done bit.
+ *
+ * D8 - cfgerr
+ * D7 - dalign
+ * D6 - rip
+ * D5 - in_abort_l
+ * D4 - Always 1
+ * D3 - Always 1
+ * D2 - Always 1
+ * D1 - Always 1
+ * D0 - Done bit
+ **/
+u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata)
+{
+ u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET);
+ dev_dbg(drvdata->dev, "Getting status = %x\n", status);
+ return status;
+}
+
+/**
* fifo_icap_busy - Return true if the ICAP is still processing a transaction.
* @drvdata: a pointer to the drvdata.
**/
static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
{
u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET);
- dev_dbg(drvdata->dev, "Getting status = %x\n", status);
return (status & XHI_SR_DONE_MASK) ? 0 : 1;
}
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.h b/drivers/char/xilinx_hwicap/fifo_icap.h
index 4d3068dd040..ffabd3ba2bd 100644
--- a/drivers/char/xilinx_hwicap/fifo_icap.h
+++ b/drivers/char/xilinx_hwicap/fifo_icap.h
@@ -56,6 +56,7 @@ int fifo_icap_set_configuration(
u32 *FrameBuffer,
u32 NumWords);
+u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata);
void fifo_icap_reset(struct hwicap_drvdata *drvdata);
void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata);
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 2284fa2a5a5..016f90567a5 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -36,7 +36,7 @@
*****************************************************************************/
/*
- * This is the code behind /dev/xilinx_icap -- it allows a user-space
+ * This is the code behind /dev/icap* -- it allows a user-space
* application to use the Xilinx ICAP subsystem.
*
* The following operations are possible:
@@ -67,7 +67,7 @@
* user-space application code that uses this device. The simplest
* way to use this interface is simply:
*
- * cp foo.bit /dev/xilinx_icap
+ * cp foo.bit /dev/icap0
*
* Note that unless foo.bit is an appropriately constructed partial
* bitstream, this has a high likelyhood of overwriting the design
@@ -105,18 +105,14 @@
#include "buffer_icap.h"
#include "fifo_icap.h"
-#define DRIVER_NAME "xilinx_icap"
+#define DRIVER_NAME "icap"
#define HWICAP_REGS (0x10000)
-/* dynamically allocate device number */
-static int xhwicap_major;
-static int xhwicap_minor;
+#define XHWICAP_MAJOR 259
+#define XHWICAP_MINOR 0
#define HWICAP_DEVICES 1
-module_param(xhwicap_major, int, S_IRUGO);
-module_param(xhwicap_minor, int, S_IRUGO);
-
/* An array, which is set to true when the device is registered. */
static bool probed_devices[HWICAP_DEVICES];
static struct mutex icap_sem;
@@ -250,8 +246,26 @@ static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
* Create the data to be written to the ICAP.
*/
buffer[index++] = XHI_DUMMY_PACKET;
+ buffer[index++] = XHI_NOOP_PACKET;
buffer[index++] = XHI_SYNC_PACKET;
buffer[index++] = XHI_NOOP_PACKET;
+ buffer[index++] = XHI_NOOP_PACKET;
+
+ /*
+ * Write the data to the FIFO and initiate the transfer of data present
+ * in the FIFO to the ICAP device.
+ */
+ status = drvdata->config->set_configuration(drvdata,
+ &buffer[0], index);
+ if (status)
+ return status;
+
+ /* If the syncword was not found, then we need to start over. */
+ status = drvdata->config->get_status(drvdata);
+ if ((status & XHI_SR_DALIGN_MASK) != XHI_SR_DALIGN_MASK)
+ return -EIO;
+
+ index = 0;
buffer[index++] = hwicap_type_1_read(reg) | 1;
buffer[index++] = XHI_NOOP_PACKET;
buffer[index++] = XHI_NOOP_PACKET;
@@ -587,7 +601,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
probed_devices[id] = 1;
mutex_unlock(&icap_sem);
- devt = MKDEV(xhwicap_major, xhwicap_minor + id);
+ devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR + id);
drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
if (!drvdata) {
@@ -664,12 +678,14 @@ static int __devinit hwicap_setup(struct device *dev, int id,
static struct hwicap_driver_config buffer_icap_config = {
.get_configuration = buffer_icap_get_configuration,
.set_configuration = buffer_icap_set_configuration,
+ .get_status = buffer_icap_get_status,
.reset = buffer_icap_reset,
};
static struct hwicap_driver_config fifo_icap_config = {
.get_configuration = fifo_icap_get_configuration,
.set_configuration = fifo_icap_set_configuration,
+ .get_status = fifo_icap_get_status,
.reset = fifo_icap_reset,
};
@@ -690,7 +706,7 @@ static int __devexit hwicap_remove(struct device *dev)
dev_set_drvdata(dev, NULL);
mutex_lock(&icap_sem);
- probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
+ probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
mutex_unlock(&icap_sem);
return 0; /* success */
}
@@ -830,23 +846,12 @@ static int __init hwicap_module_init(void)
icap_class = class_create(THIS_MODULE, "xilinx_config");
mutex_init(&icap_sem);
- if (xhwicap_major) {
- devt = MKDEV(xhwicap_major, xhwicap_minor);
- retval = register_chrdev_region(
- devt,
- HWICAP_DEVICES,
- DRIVER_NAME);
- if (retval < 0)
- return retval;
- } else {
- retval = alloc_chrdev_region(&devt,
- xhwicap_minor,
- HWICAP_DEVICES,
- DRIVER_NAME);
- if (retval < 0)
- return retval;
- xhwicap_major = MAJOR(devt);
- }
+ devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR);
+ retval = register_chrdev_region(devt,
+ HWICAP_DEVICES,
+ DRIVER_NAME);
+ if (retval < 0)
+ return retval;
retval = platform_driver_register(&hwicap_platform_driver);
@@ -871,7 +876,7 @@ static int __init hwicap_module_init(void)
static void __exit hwicap_module_cleanup(void)
{
- dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);
+ dev_t devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR);
class_destroy(icap_class);
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
index 405fee7e189..1f9c8b082db 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -65,10 +65,27 @@ struct hwicap_drvdata {
};
struct hwicap_driver_config {
+ /* Read configuration data given by size into the data buffer.
+ Return 0 if successful. */
int (*get_configuration)(struct hwicap_drvdata *drvdata, u32 *data,
u32 size);
+ /* Write configuration data given by size from the data buffer.
+ Return 0 if successful. */
int (*set_configuration)(struct hwicap_drvdata *drvdata, u32 *data,
u32 size);
+ /* Get the status register, bit pattern given by:
+ * D8 - 0 = configuration error
+ * D7 - 1 = alignment found
+ * D6 - 1 = readback in progress
+ * D5 - 0 = abort in progress
+ * D4 - Always 1
+ * D3 - Always 1
+ * D2 - Always 1
+ * D1 - Always 1
+ * D0 - 1 = operation completed
+ */
+ u32 (*get_status)(struct hwicap_drvdata *drvdata);
+ /* Reset the hw */
void (*reset)(struct hwicap_drvdata *drvdata);
};
@@ -163,6 +180,13 @@ struct config_registers {
/* Constant to use for CRC check when CRC has been disabled */
#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL
+/* Meanings of the bits returned by get_status */
+#define XHI_SR_CFGERR_N_MASK 0x00000100 /* Config Error Mask */
+#define XHI_SR_DALIGN_MASK 0x00000080 /* Data Alignment Mask */
+#define XHI_SR_RIP_MASK 0x00000040 /* Read back Mask */
+#define XHI_SR_IN_ABORT_N_MASK 0x00000020 /* Select Map Abort Mask */
+#define XHI_SR_DONE_MASK 0x00000001 /* Done bit Mask */
+
/**
* hwicap_type_1_read - Generates a Type 1 read packet header.
* @reg: is the address of the register to be read back.