summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/hw_random/Kconfig17
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/omap-rng.c22
-rw-r--r--drivers/char/hw_random/pseries-rng.c96
-rw-r--r--drivers/char/mem.c42
-rw-r--r--drivers/char/ramoops.c250
-rw-r--r--drivers/char/virtio_console.c7
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c30
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.h2
11 files changed, 155 insertions, 321 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ee946865d6c..ea6f6325f9b 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -585,14 +585,6 @@ config DEVPORT
source "drivers/s390/char/Kconfig"
-config RAMOOPS
- tristate "Log panic/oops to a RAM buffer"
- depends on HAS_IOMEM
- default n
- help
- This enables panic and oops messages to be logged to a circular
- buffer in RAM where it can be read back at some later point.
-
config MSM_SMD_PKT
bool "Enable device interface for some SMD packet ports"
default n
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 0dc5d7ce486..d0b27a39f1d 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -58,7 +58,6 @@ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
obj-$(CONFIG_TCG_TPM) += tpm/
obj-$(CONFIG_PS3_FLASH) += ps3flash.o
-obj-$(CONFIG_RAMOOPS) += ramoops.o
obj-$(CONFIG_JS_RTC) += js-rtc.o
js-rtc-y = rtc.o
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 0689bf6b018..f45dad39a18 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -62,8 +62,8 @@ config HW_RANDOM_AMD
config HW_RANDOM_ATMEL
tristate "Atmel Random Number Generator support"
- depends on HW_RANDOM && ARCH_AT91SAM9G45
- default HW_RANDOM
+ depends on HW_RANDOM && HAVE_CLK
+ default (HW_RANDOM && ARCH_AT91)
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on Atmel AT91 devices.
@@ -250,3 +250,16 @@ config UML_RANDOM
(check your distro, or download from
http://sourceforge.net/projects/gkernel/). rngd periodically reads
/dev/hwrng and injects the entropy into /dev/random.
+
+config HW_RANDOM_PSERIES
+ tristate "pSeries HW Random Number Generator support"
+ depends on HW_RANDOM && PPC64 && IBMVIO
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on POWER7+ machines and above
+
+ To compile this driver as a module, choose M here: the
+ module will be called pseries-rng.
+
+ If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index b2ff5265a99..d901dfa3032 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
+obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index a07a5caa599..1412565c01a 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -115,22 +115,12 @@ static int __devinit omap_rng_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENOENT;
- goto err_region;
- }
-
- if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
- ret = -EBUSY;
- goto err_region;
- }
-
- dev_set_drvdata(&pdev->dev, res);
- rng_base = ioremap(res->start, resource_size(res));
+ rng_base = devm_request_and_ioremap(&pdev->dev, res);
if (!rng_base) {
ret = -ENOMEM;
goto err_ioremap;
}
+ dev_set_drvdata(&pdev->dev, res);
ret = hwrng_register(&omap_rng_ops);
if (ret)
@@ -145,11 +135,8 @@ static int __devinit omap_rng_probe(struct platform_device *pdev)
return 0;
err_register:
- iounmap(rng_base);
rng_base = NULL;
err_ioremap:
- release_mem_region(res->start, resource_size(res));
-err_region:
if (cpu_is_omap24xx()) {
clk_disable(rng_ick);
clk_put(rng_ick);
@@ -159,20 +146,15 @@ err_region:
static int __exit omap_rng_remove(struct platform_device *pdev)
{
- struct resource *res = dev_get_drvdata(&pdev->dev);
-
hwrng_unregister(&omap_rng_ops);
omap_rng_write_reg(RNG_MASK_REG, 0x0);
- iounmap(rng_base);
-
if (cpu_is_omap24xx()) {
clk_disable(rng_ick);
clk_put(rng_ick);
}
- release_mem_region(res->start, resource_size(res));
rng_base = NULL;
return 0;
diff --git a/drivers/char/hw_random/pseries-rng.c b/drivers/char/hw_random/pseries-rng.c
new file mode 100644
index 00000000000..5f1197929f0
--- /dev/null
+++ b/drivers/char/hw_random/pseries-rng.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 Michael Neuling IBM Corporation
+ *
+ * Driver for the pseries hardware RNG for POWER7+ and above
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/hw_random.h>
+#include <asm/vio.h>
+
+#define MODULE_NAME "pseries-rng"
+
+static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ if (plpar_hcall(H_RANDOM, (unsigned long *)data) != H_SUCCESS) {
+ printk(KERN_ERR "pseries rng hcall error\n");
+ return 0;
+ }
+ return 8;
+}
+
+/**
+ * pseries_rng_get_desired_dma - Return desired DMA allocate for CMO operations
+ *
+ * This is a required function for a driver to operate in a CMO environment
+ * but this device does not make use of DMA allocations, return 0.
+ *
+ * Return value:
+ * Number of bytes of IO data the driver will need to perform well -> 0
+ */
+static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev)
+{
+ return 0;
+};
+
+static struct hwrng pseries_rng = {
+ .name = MODULE_NAME,
+ .data_read = pseries_rng_data_read,
+};
+
+static int __init pseries_rng_probe(struct vio_dev *dev,
+ const struct vio_device_id *id)
+{
+ return hwrng_register(&pseries_rng);
+}
+
+static int __exit pseries_rng_remove(struct vio_dev *dev)
+{
+ hwrng_unregister(&pseries_rng);
+ return 0;
+}
+
+static struct vio_device_id pseries_rng_driver_ids[] = {
+ { "ibm,random-v1", "ibm,random"},
+ { "", "" }
+};
+MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids);
+
+static struct vio_driver pseries_rng_driver = {
+ .name = MODULE_NAME,
+ .probe = pseries_rng_probe,
+ .remove = pseries_rng_remove,
+ .get_desired_dma = pseries_rng_get_desired_dma,
+ .id_table = pseries_rng_driver_ids
+};
+
+static int __init rng_init(void)
+{
+ printk(KERN_INFO "Registering IBM pSeries RNG driver\n");
+ return vio_register_driver(&pseries_rng_driver);
+}
+
+module_init(rng_init);
+
+static void __exit rng_exit(void)
+{
+ vio_unregister_driver(&pseries_rng_driver);
+}
+module_exit(rng_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Neuling <mikey@neuling.org>");
+MODULE_DESCRIPTION("H/W RNG driver for IBM pSeries processors");
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index d6e9d081c8b..67c3371723c 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -807,44 +807,6 @@ static const struct file_operations oldmem_fops = {
};
#endif
-static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
- unsigned long count, loff_t pos)
-{
- char *line, *p;
- int i;
- ssize_t ret = -EFAULT;
- size_t len = iov_length(iv, count);
-
- line = kmalloc(len + 1, GFP_KERNEL);
- if (line == NULL)
- return -ENOMEM;
-
- /*
- * copy all vectors into a single string, to ensure we do
- * not interleave our log line with other printk calls
- */
- p = line;
- for (i = 0; i < count; i++) {
- if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len))
- goto out;
- p += iv[i].iov_len;
- }
- p[0] = '\0';
-
- ret = printk("%s", line);
- /* printk can add a prefix */
- if (ret > len)
- ret = len;
-out:
- kfree(line);
- return ret;
-}
-
-static const struct file_operations kmsg_fops = {
- .aio_write = kmsg_writev,
- .llseek = noop_llseek,
-};
-
static const struct memdev {
const char *name;
umode_t mode;
@@ -863,7 +825,9 @@ static const struct memdev {
[7] = { "full", 0666, &full_fops, NULL },
[8] = { "random", 0666, &random_fops, NULL },
[9] = { "urandom", 0666, &urandom_fops, NULL },
- [11] = { "kmsg", 0, &kmsg_fops, NULL },
+#ifdef CONFIG_PRINTK
+ [11] = { "kmsg", 0644, &kmsg_fops, NULL },
+#endif
#ifdef CONFIG_CRASH_DUMP
[12] = { "oldmem", 0, &oldmem_fops, NULL },
#endif
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c
deleted file mode 100644
index 2a5e45d2a9f..00000000000
--- a/drivers/char/ramoops.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * RAM Oops/Panic logger
- *
- * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/kmsg_dump.h>
-#include <linux/time.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/ramoops.h>
-
-#define RAMOOPS_KERNMSG_HDR "===="
-#define MIN_MEM_SIZE 4096UL
-
-static ulong record_size = MIN_MEM_SIZE;
-module_param(record_size, ulong, 0400);
-MODULE_PARM_DESC(record_size,
- "size of each dump done on oops/panic");
-
-static ulong mem_address;
-module_param(mem_address, ulong, 0400);
-MODULE_PARM_DESC(mem_address,
- "start of reserved RAM used to store oops/panic logs");
-
-static ulong mem_size;
-module_param(mem_size, ulong, 0400);
-MODULE_PARM_DESC(mem_size,
- "size of reserved RAM used to store oops/panic logs");
-
-static int dump_oops = 1;
-module_param(dump_oops, int, 0600);
-MODULE_PARM_DESC(dump_oops,
- "set to 1 to dump oopses, 0 to only dump panics (default 1)");
-
-static struct ramoops_context {
- struct kmsg_dumper dump;
- void *virt_addr;
- phys_addr_t phys_addr;
- unsigned long size;
- unsigned long record_size;
- int dump_oops;
- int count;
- int max_count;
-} oops_cxt;
-
-static struct platform_device *dummy;
-static struct ramoops_platform_data *dummy_data;
-
-static void ramoops_do_dump(struct kmsg_dumper *dumper,
- enum kmsg_dump_reason reason, const char *s1, unsigned long l1,
- const char *s2, unsigned long l2)
-{
- struct ramoops_context *cxt = container_of(dumper,
- struct ramoops_context, dump);
- unsigned long s1_start, s2_start;
- unsigned long l1_cpy, l2_cpy;
- int res, hdr_size;
- char *buf, *buf_orig;
- struct timeval timestamp;
-
- if (reason != KMSG_DUMP_OOPS &&
- reason != KMSG_DUMP_PANIC)
- return;
-
- /* Only dump oopses if dump_oops is set */
- if (reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
- return;
-
- buf = cxt->virt_addr + (cxt->count * cxt->record_size);
- buf_orig = buf;
-
- memset(buf, '\0', cxt->record_size);
- res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR);
- buf += res;
- do_gettimeofday(&timestamp);
- res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec);
- buf += res;
-
- hdr_size = buf - buf_orig;
- l2_cpy = min(l2, cxt->record_size - hdr_size);
- l1_cpy = min(l1, cxt->record_size - hdr_size - l2_cpy);
-
- s2_start = l2 - l2_cpy;
- s1_start = l1 - l1_cpy;
-
- memcpy(buf, s1 + s1_start, l1_cpy);
- memcpy(buf + l1_cpy, s2 + s2_start, l2_cpy);
-
- cxt->count = (cxt->count + 1) % cxt->max_count;
-}
-
-static int __init ramoops_probe(struct platform_device *pdev)
-{
- struct ramoops_platform_data *pdata = pdev->dev.platform_data;
- struct ramoops_context *cxt = &oops_cxt;
- int err = -EINVAL;
-
- if (!pdata->mem_size || !pdata->record_size) {
- pr_err("The memory size and the record size must be "
- "non-zero\n");
- goto fail3;
- }
-
- pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
- pdata->record_size = rounddown_pow_of_two(pdata->record_size);
-
- /* Check for the minimum memory size */
- if (pdata->mem_size < MIN_MEM_SIZE &&
- pdata->record_size < MIN_MEM_SIZE) {
- pr_err("memory size too small, minium is %lu\n", MIN_MEM_SIZE);
- goto fail3;
- }
-
- if (pdata->mem_size < pdata->record_size) {
- pr_err("The memory size must be larger than the "
- "records size\n");
- goto fail3;
- }
-
- cxt->max_count = pdata->mem_size / pdata->record_size;
- cxt->count = 0;
- cxt->size = pdata->mem_size;
- cxt->phys_addr = pdata->mem_address;
- cxt->record_size = pdata->record_size;
- cxt->dump_oops = pdata->dump_oops;
-
- if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) {
- pr_err("request mem region failed\n");
- err = -EINVAL;
- goto fail3;
- }
-
- cxt->virt_addr = ioremap(cxt->phys_addr, cxt->size);
- if (!cxt->virt_addr) {
- pr_err("ioremap failed\n");
- goto fail2;
- }
-
- cxt->dump.dump = ramoops_do_dump;
- err = kmsg_dump_register(&cxt->dump);
- if (err) {
- pr_err("registering kmsg dumper failed\n");
- goto fail1;
- }
-
- /*
- * Update the module parameter variables as well so they are visible
- * through /sys/module/ramoops/parameters/
- */
- mem_size = pdata->mem_size;
- mem_address = pdata->mem_address;
- record_size = pdata->record_size;
- dump_oops = pdata->dump_oops;
-
- return 0;
-
-fail1:
- iounmap(cxt->virt_addr);
-fail2:
- release_mem_region(cxt->phys_addr, cxt->size);
-fail3:
- return err;
-}
-
-static int __exit ramoops_remove(struct platform_device *pdev)
-{
- struct ramoops_context *cxt = &oops_cxt;
-
- if (kmsg_dump_unregister(&cxt->dump) < 0)
- pr_warn("could not unregister kmsg_dumper\n");
-
- iounmap(cxt->virt_addr);
- release_mem_region(cxt->phys_addr, cxt->size);
- return 0;
-}
-
-static struct platform_driver ramoops_driver = {
- .remove = __exit_p(ramoops_remove),
- .driver = {
- .name = "ramoops",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init ramoops_init(void)
-{
- int ret;
- ret = platform_driver_probe(&ramoops_driver, ramoops_probe);
- if (ret == -ENODEV) {
- /*
- * If we didn't find a platform device, we use module parameters
- * building platform data on the fly.
- */
- pr_info("platform device not found, using module parameters\n");
- dummy_data = kzalloc(sizeof(struct ramoops_platform_data),
- GFP_KERNEL);
- if (!dummy_data)
- return -ENOMEM;
- dummy_data->mem_size = mem_size;
- dummy_data->mem_address = mem_address;
- dummy_data->record_size = record_size;
- dummy_data->dump_oops = dump_oops;
- dummy = platform_create_bundle(&ramoops_driver, ramoops_probe,
- NULL, 0, dummy_data,
- sizeof(struct ramoops_platform_data));
-
- if (IS_ERR(dummy))
- ret = PTR_ERR(dummy);
- else
- ret = 0;
- }
-
- return ret;
-}
-
-static void __exit ramoops_exit(void)
-{
- platform_driver_unregister(&ramoops_driver);
- kfree(dummy_data);
-}
-
-module_init(ramoops_init);
-module_exit(ramoops_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marco Stornelli <marco.stornelli@gmail.com>");
-MODULE_DESCRIPTION("RAM Oops/Panic logger/driver");
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index ddf86b6500b..cdf2f5451c7 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1895,6 +1895,13 @@ static int virtcons_restore(struct virtio_device *vdev)
/* Get port open/close status on the host */
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
+
+ /*
+ * If a port was open at the time of suspending, we
+ * have to let the host know that it's still open.
+ */
+ if (port->guest_connected)
+ send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
}
return 0;
}
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 31ba11ca75e..2c5d15beea3 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -167,6 +167,7 @@ static const struct config_registers v4_config_registers = {
.BOOTSTS = UNIMPLEMENTED,
.CTL_1 = UNIMPLEMENTED,
};
+
static const struct config_registers v5_config_registers = {
.CRC = 0,
.FAR = 1,
@@ -192,6 +193,31 @@ static const struct config_registers v5_config_registers = {
.CTL_1 = 19,
};
+static const struct config_registers v6_config_registers = {
+ .CRC = 0,
+ .FAR = 1,
+ .FDRI = 2,
+ .FDRO = 3,
+ .CMD = 4,
+ .CTL = 5,
+ .MASK = 6,
+ .STAT = 7,
+ .LOUT = 8,
+ .COR = 9,
+ .MFWR = 10,
+ .FLR = UNIMPLEMENTED,
+ .KEY = UNIMPLEMENTED,
+ .CBC = 11,
+ .IDCODE = 12,
+ .AXSS = 13,
+ .C0R_1 = 14,
+ .CSOB = 15,
+ .WBSTAR = 16,
+ .TIMER = 17,
+ .BOOTSTS = 22,
+ .CTL_1 = 24,
+};
+
/**
* hwicap_command_desync - Send a DESYNC command to the ICAP port.
* @drvdata: a pointer to the drvdata.
@@ -744,6 +770,8 @@ static int __devinit hwicap_of_probe(struct platform_device *op,
regs = &v4_config_registers;
} else if (!strcmp(family, "virtex5")) {
regs = &v5_config_registers;
+ } else if (!strcmp(family, "virtex6")) {
+ regs = &v6_config_registers;
}
}
return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
@@ -785,6 +813,8 @@ static int __devinit hwicap_drv_probe(struct platform_device *pdev)
regs = &v4_config_registers;
} else if (!strcmp(family, "virtex5")) {
regs = &v5_config_registers;
+ } else if (!strcmp(family, "virtex6")) {
+ regs = &v6_config_registers;
}
}
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
index 8cca11981c5..d31ee23c9f1 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -86,7 +86,7 @@ struct hwicap_driver_config {
};
/* Number of times to poll the done regsiter */
-#define XHI_MAX_RETRIES 10
+#define XHI_MAX_RETRIES 5000
/************ Constant Definitions *************/