summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/apm-emulation.c5
-rw-r--r--drivers/char/bsr.c2
-rw-r--r--drivers/char/hpet.c6
-rw-r--r--drivers/char/hw_random/Kconfig2
-rw-r--r--drivers/char/hw_random/amd-rng.c9
-rw-r--r--drivers/char/hw_random/n2-drv.c7
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c7
-rw-r--r--drivers/char/mem.c42
-rw-r--r--drivers/char/raw.c34
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c14
11 files changed, 86 insertions, 44 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ad59b4e0a9b5..49502bc5360a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -523,7 +523,7 @@ config RAW_DRIVER
with the O_DIRECT flag.
config MAX_RAW_DEVS
- int "Maximum number of RAW devices to support (1-8192)"
+ int "Maximum number of RAW devices to support (1-65536)"
depends on RAW_DRIVER
default "256"
help
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index 45b987c9889e..548708c4b2b8 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -126,7 +126,6 @@ struct apm_user {
/*
* Local variables
*/
-static DEFINE_MUTEX(apm_mutex);
static atomic_t suspend_acks_pending = ATOMIC_INIT(0);
static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0);
static int apm_disabled;
@@ -275,7 +274,6 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg)
if (!as->suser || !as->writer)
return -EPERM;
- mutex_lock(&apm_mutex);
switch (cmd) {
case APM_IOC_SUSPEND:
mutex_lock(&state_lock);
@@ -336,7 +334,6 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg)
mutex_unlock(&state_lock);
break;
}
- mutex_unlock(&apm_mutex);
return err;
}
@@ -371,7 +368,6 @@ static int apm_open(struct inode * inode, struct file * filp)
{
struct apm_user *as;
- mutex_lock(&apm_mutex);
as = kzalloc(sizeof(*as), GFP_KERNEL);
if (as) {
/*
@@ -391,7 +387,6 @@ static int apm_open(struct inode * inode, struct file * filp)
filp->private_data = as;
}
- mutex_unlock(&apm_mutex);
return as ? 0 : -ENOMEM;
}
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index a4a6c2f044b5..cf39bc08ce08 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -295,7 +295,7 @@ static int bsr_create_devs(struct device_node *bn)
static int __init bsr_init(void)
{
struct device_node *np;
- dev_t bsr_dev = MKDEV(bsr_major, 0);
+ dev_t bsr_dev;
int ret = -ENODEV;
int result;
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 7066e801b9d3..051474c65b78 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -84,8 +84,6 @@ static struct clocksource clocksource_hpet = {
.rating = 250,
.read = read_hpet,
.mask = CLOCKSOURCE_MASK(64),
- .mult = 0, /* to be calculated */
- .shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static struct clocksource *hpet_clocksource;
@@ -934,9 +932,7 @@ int hpet_alloc(struct hpet_data *hdp)
if (!hpet_clocksource) {
hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc;
CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr);
- clocksource_hpet.mult = clocksource_hz2mult(hpetp->hp_tick_freq,
- clocksource_hpet.shift);
- clocksource_register(&clocksource_hpet);
+ clocksource_register_hz(&clocksource_hpet, hpetp->hp_tick_freq);
hpetp->hp_clocksource = &clocksource_hpet;
hpet_clocksource = &clocksource_hpet;
}
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index beecd1cf9b99..a60043b3e409 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -49,7 +49,7 @@ config HW_RANDOM_INTEL
config HW_RANDOM_AMD
tristate "AMD HW Random Number Generator support"
- depends on HW_RANDOM && X86 && PCI
+ depends on HW_RANDOM && (X86 || PPC_MAPLE) && PCI
default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index 0d8c5788b8e4..c6af038682f1 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -133,6 +133,12 @@ found:
pmbase &= 0x0000FF00;
if (pmbase == 0)
goto out;
+ if (!request_region(pmbase + 0xF0, 8, "AMD HWRNG")) {
+ dev_err(&pdev->dev, "AMD HWRNG region 0x%x already in use!\n",
+ pmbase + 0xF0);
+ err = -EBUSY;
+ goto out;
+ }
amd_rng.priv = (unsigned long)pmbase;
amd_pdev = pdev;
@@ -141,6 +147,7 @@ found:
if (err) {
printk(KERN_ERR PFX "RNG registering failed (%d)\n",
err);
+ release_region(pmbase + 0xF0, 8);
goto out;
}
out:
@@ -149,6 +156,8 @@ out:
static void __exit mod_exit(void)
{
+ u32 pmbase = (unsigned long)amd_rng.priv;
+ release_region(pmbase + 0xF0, 8);
hwrng_unregister(&amd_rng);
}
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 43ac61978d8b..ac6739e085e3 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -619,15 +619,18 @@ static void __devinit n2rng_driver_version(void)
pr_info("%s", version);
}
+static const struct of_device_id n2rng_match[];
static int __devinit n2rng_probe(struct platform_device *op)
{
+ const struct of_device_id *match;
int victoria_falls;
int err = -ENOMEM;
struct n2rng *np;
- if (!op->dev.of_match)
+ match = of_match_device(n2rng_match, &op->dev);
+ if (!match)
return -EINVAL;
- victoria_falls = (op->dev.of_match->data != NULL);
+ victoria_falls = (match->data != NULL);
n2rng_driver_version();
np = kzalloc(sizeof(*np), GFP_KERNEL);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index cc6c9b2546a3..64c6b8530615 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2554,9 +2554,11 @@ static struct pci_driver ipmi_pci_driver = {
};
#endif /* CONFIG_PCI */
+static struct of_device_id ipmi_match[];
static int __devinit ipmi_probe(struct platform_device *dev)
{
#ifdef CONFIG_OF
+ const struct of_device_id *match;
struct smi_info *info;
struct resource resource;
const __be32 *regsize, *regspacing, *regshift;
@@ -2566,7 +2568,8 @@ static int __devinit ipmi_probe(struct platform_device *dev)
dev_info(&dev->dev, "probing via device tree\n");
- if (!dev->dev.of_match)
+ match = of_match_device(ipmi_match, &dev->dev);
+ if (!match)
return -EINVAL;
ret = of_address_to_resource(np, 0, &resource);
@@ -2601,7 +2604,7 @@ static int __devinit ipmi_probe(struct platform_device *dev)
return -ENOMEM;
}
- info->si_type = (enum si_type) dev->dev.of_match->data;
+ info->si_type = (enum si_type) match->data;
info->addr_source = SI_DEVICETREE;
info->irq_setup = std_irq_setup;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 436a99017998..8fc04b4f311f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -806,29 +806,41 @@ static const struct file_operations oldmem_fops = {
};
#endif
-static ssize_t kmsg_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
+ unsigned long count, loff_t pos)
{
- char *tmp;
- ssize_t ret;
+ char *line, *p;
+ int i;
+ ssize_t ret = -EFAULT;
+ size_t len = iov_length(iv, count);
- tmp = kmalloc(count + 1, GFP_KERNEL);
- if (tmp == NULL)
+ line = kmalloc(len + 1, GFP_KERNEL);
+ if (line == NULL)
return -ENOMEM;
- ret = -EFAULT;
- if (!copy_from_user(tmp, buf, count)) {
- tmp[count] = 0;
- ret = printk("%s", tmp);
- if (ret > count)
- /* printk can add a prefix */
- ret = count;
+
+ /*
+ * 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;
}
- kfree(tmp);
+ 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 = {
- .write = kmsg_write,
+ .aio_write = kmsg_writev,
.llseek = noop_llseek,
};
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index b4b9d5a47885..b33e8ea314ed 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -21,6 +21,7 @@
#include <linux/mutex.h>
#include <linux/gfp.h>
#include <linux/compat.h>
+#include <linux/vmalloc.h>
#include <asm/uaccess.h>
@@ -30,10 +31,15 @@ struct raw_device_data {
};
static struct class *raw_class;
-static struct raw_device_data raw_devices[MAX_RAW_MINORS];
+static struct raw_device_data *raw_devices;
static DEFINE_MUTEX(raw_mutex);
static const struct file_operations raw_ctl_fops; /* forward declaration */
+static int max_raw_minors = MAX_RAW_MINORS;
+
+module_param(max_raw_minors, int, 0);
+MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");
+
/*
* Open/close code for raw IO.
*
@@ -125,7 +131,7 @@ static int bind_set(int number, u64 major, u64 minor)
struct raw_device_data *rawdev;
int err = 0;
- if (number <= 0 || number >= MAX_RAW_MINORS)
+ if (number <= 0 || number >= max_raw_minors)
return -EINVAL;
if (MAJOR(dev) != major || MINOR(dev) != minor)
@@ -312,14 +318,27 @@ static int __init raw_init(void)
dev_t dev = MKDEV(RAW_MAJOR, 0);
int ret;
- ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw");
+ if (max_raw_minors < 1 || max_raw_minors > 65536) {
+ printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
+ " between 1 and 65536), using %d\n", MAX_RAW_MINORS);
+ max_raw_minors = MAX_RAW_MINORS;
+ }
+
+ raw_devices = vmalloc(sizeof(struct raw_device_data) * max_raw_minors);
+ if (!raw_devices) {
+ printk(KERN_ERR "Not enough memory for raw device structures\n");
+ ret = -ENOMEM;
+ goto error;
+ }
+ memset(raw_devices, 0, sizeof(struct raw_device_data) * max_raw_minors);
+
+ ret = register_chrdev_region(dev, max_raw_minors, "raw");
if (ret)
goto error;
cdev_init(&raw_cdev, &raw_fops);
- ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS);
+ ret = cdev_add(&raw_cdev, dev, max_raw_minors);
if (ret) {
- kobject_put(&raw_cdev.kobj);
goto error_region;
}
@@ -336,8 +355,9 @@ static int __init raw_init(void)
return 0;
error_region:
- unregister_chrdev_region(dev, MAX_RAW_MINORS);
+ unregister_chrdev_region(dev, max_raw_minors);
error:
+ vfree(raw_devices);
return ret;
}
@@ -346,7 +366,7 @@ static void __exit raw_exit(void)
device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
class_destroy(raw_class);
cdev_del(&raw_cdev);
- unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
+ unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
}
module_init(raw_init);
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index d6412c16385f..39ccdeada791 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -715,13 +715,13 @@ static int __devexit hwicap_remove(struct device *dev)
}
#ifdef CONFIG_OF
-static int __devinit hwicap_of_probe(struct platform_device *op)
+static int __devinit hwicap_of_probe(struct platform_device *op,
+ const struct hwicap_driver_config *config)
{
struct resource res;
const unsigned int *id;
const char *family;
int rc;
- const struct hwicap_driver_config *config = op->dev.of_match->data;
const struct config_registers *regs;
@@ -751,20 +751,24 @@ static int __devinit hwicap_of_probe(struct platform_device *op)
regs);
}
#else
-static inline int hwicap_of_probe(struct platform_device *op)
+static inline int hwicap_of_probe(struct platform_device *op,
+ const struct hwicap_driver_config *config)
{
return -EINVAL;
}
#endif /* CONFIG_OF */
+static const struct of_device_id __devinitconst hwicap_of_match[];
static int __devinit hwicap_drv_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match;
struct resource *res;
const struct config_registers *regs;
const char *family;
- if (pdev->dev.of_match)
- return hwicap_of_probe(pdev);
+ match = of_match_device(hwicap_of_match, &pdev->dev);
+ if (match)
+ return hwicap_of_probe(pdev, match->data);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)