From d405640539555b601e52f7d18f1f0b1345d18bf5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 Apr 2009 15:23:42 +0200 Subject: Driver Core: misc: add nodename support for misc devices. This adds support for misc devices to report their requested nodename to userspace. It also updates a number of misc drivers to provide the needed subdirectory and device name to be used for them. Signed-off-by: Kay Sievers Signed-off-by: Jan Blunck Signed-off-by: Greg Kroah-Hartman --- drivers/char/hw_random/core.c | 1 + drivers/char/misc.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index e5d583c84e4..fc93e2fc7c7 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -153,6 +153,7 @@ static const struct file_operations rng_chrdev_ops = { static struct miscdevice rng_miscdev = { .minor = RNG_MISCDEV_MINOR, .name = RNG_MODULE_NAME, + .devnode = "hwrng", .fops = &rng_chrdev_ops, }; diff --git a/drivers/char/misc.c b/drivers/char/misc.c index a5e0db9d766..62c99fa59e2 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -168,7 +168,6 @@ static const struct file_operations misc_fops = { .open = misc_open, }; - /** * misc_register - register a miscellaneous device * @misc: device structure @@ -217,8 +216,8 @@ int misc_register(struct miscdevice * misc) misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); dev = MKDEV(MISC_MAJOR, misc->minor); - misc->this_device = device_create(misc_class, misc->parent, dev, NULL, - "%s", misc->name); + misc->this_device = device_create(misc_class, misc->parent, dev, + misc, "%s", misc->name); if (IS_ERR(misc->this_device)) { err = PTR_ERR(misc->this_device); goto out; @@ -264,6 +263,15 @@ int misc_deregister(struct miscdevice *misc) EXPORT_SYMBOL(misc_register); EXPORT_SYMBOL(misc_deregister); +static char *misc_nodename(struct device *dev) +{ + struct miscdevice *c = dev_get_drvdata(dev); + + if (c->devnode) + return kstrdup(c->devnode, GFP_KERNEL); + return NULL; +} + static int __init misc_init(void) { int err; @@ -279,6 +287,7 @@ static int __init misc_init(void) err = -EIO; if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) goto fail_printk; + misc_class->nodename = misc_nodename; return 0; fail_printk: -- cgit v1.2.3 From 6fd4693375b6e1001c69e78f5aefd44bf5aa7084 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 Apr 2009 15:23:42 +0200 Subject: Driver Core: raw: add nodename for raw devices This adds support to the raw driver to report the proper device name to userspace for the raw devices. Signed-off-by: Kay Sievers Signed-off-by: Jan Blunck Signed-off-by: Greg Kroah-Hartman --- drivers/char/raw.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/char') diff --git a/drivers/char/raw.c b/drivers/char/raw.c index db32f0e4c7d..05f9d18b936 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -261,6 +261,11 @@ static const struct file_operations raw_ctl_fops = { static struct cdev raw_cdev; +static char *raw_nodename(struct device *dev) +{ + return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev)); +} + static int __init raw_init(void) { dev_t dev = MKDEV(RAW_MAJOR, 0); @@ -284,6 +289,7 @@ static int __init raw_init(void) ret = PTR_ERR(raw_class); goto error_region; } + raw_class->nodename = raw_nodename; device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); return 0; -- cgit v1.2.3 From 317ccc4246bf205807c4d2f270d7fc8f024a9dc3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 4 May 2009 12:40:54 -0700 Subject: hvcs: remove driver_data direct access of struct device In the near future, the driver core is going to not allow direct access to the driver_data pointer in struct device. Instead, the functions dev_get_drvdata() and dev_set_drvdata() should be used. These functions have been around since the beginning, so are backwards compatible with all older kernel versions. Cc: Paul Mackerras Acked-by: Stephen Rothwell Cc: Roel Kluin Cc: Benjamin Herrenschmidt Signed-off-by: Greg Kroah-Hartman --- drivers/char/hvcs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index c76bccf5354..7d64e4230e6 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -347,7 +347,7 @@ static void __exit hvcs_module_exit(void); static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) { - return viod->dev.driver_data; + return dev_get_drvdata(&viod->dev); } /* The sysfs interface for the driver and devices */ @@ -785,7 +785,7 @@ static int __devinit hvcs_probe( kref_init(&hvcsd->kref); hvcsd->vdev = dev; - dev->dev.driver_data = hvcsd; + dev_set_drvdata(&dev->dev, hvcsd); hvcsd->index = index; @@ -831,7 +831,7 @@ static int __devinit hvcs_probe( static int __devexit hvcs_remove(struct vio_dev *dev) { - struct hvcs_struct *hvcsd = dev->dev.driver_data; + struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev); unsigned long flags; struct tty_struct *tty; -- cgit v1.2.3 From 9de33df41f712712ccd3297c898e365b50fb91ef Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 4 May 2009 12:40:54 -0700 Subject: ipmi: remove driver_data direct access of struct device In the near future, the driver core is going to not allow direct access to the driver_data pointer in struct device. Instead, the functions dev_get_drvdata() and dev_set_drvdata() should be used. These functions have been around since the beginning, so are backwards compatible with all older kernel versions. Cc: openipmi-developer@lists.sourceforge.net Acked-by: Corey Minyard Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_si_intf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 259644646b8..d2e698096ac 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2375,14 +2375,14 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq); - dev->dev.driver_data = (void *) info; + dev_set_drvdata(&dev->dev, info); return try_smi_init(info); } static int __devexit ipmi_of_remove(struct of_device *dev) { - cleanup_one_si(dev->dev.driver_data); + cleanup_one_si(dev_get_drvdata(&dev->dev)); return 0; } -- cgit v1.2.3 From f324edc85e5c1137e49e3b36a58cf436ab5b1fb3 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 16 Jun 2009 15:33:52 -0700 Subject: console: make blank timeout value a boot option The console blank timer is currently hardcoded to 10*60 seconds which might be annoying on systems with no input devices attached to wake up the console again. Especially during development, disabling the screen saver can be handy - for example when debugging the root fs mount mechanism or other scenarios where no userspace program could be started to do that at runtime from userspace. This patch defines a core_param for the variable in charge which allows users to entirely disable the blank feature at boot time by setting it 0. The value can still be overwritten at runtime using the standard ioctl call - this just allows to conditionally change the default. Signed-off-by: Daniel Mack Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/vt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/vt.c b/drivers/char/vt.c index c796a86ab7f..d9113b4c76e 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -171,8 +171,9 @@ int do_poke_blanked_console; int console_blanked; static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ -static int blankinterval = 10*60*HZ; static int vesa_off_interval; +static int blankinterval = 10*60; +core_param(consoleblank, blankinterval, int, 0444); static DECLARE_WORK(console_work, console_callback); @@ -1485,7 +1486,7 @@ static void setterm_command(struct vc_data *vc) update_attr(vc); break; case 9: /* set blanking interval */ - blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ; + blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60; poke_blanked_console(); break; case 10: /* set bell frequency in Hz */ @@ -2871,7 +2872,7 @@ static int __init con_init(void) if (blankinterval) { blank_state = blank_normal_wait; - mod_timer(&console_timer, jiffies + blankinterval); + mod_timer(&console_timer, jiffies + (blankinterval * HZ)); } for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { @@ -3677,7 +3678,7 @@ void do_unblank_screen(int leaving_gfx) return; /* but leave console_blanked != 0 */ if (blankinterval) { - mod_timer(&console_timer, jiffies + blankinterval); + mod_timer(&console_timer, jiffies + (blankinterval * HZ)); blank_state = blank_normal_wait; } @@ -3711,7 +3712,7 @@ void unblank_screen(void) static void blank_screen_t(unsigned long dummy) { if (unlikely(!keventd_up())) { - mod_timer(&console_timer, jiffies + blankinterval); + mod_timer(&console_timer, jiffies + (blankinterval * HZ)); return; } blank_timer_expired = 1; @@ -3741,7 +3742,7 @@ void poke_blanked_console(void) if (console_blanked) unblank_screen(); else if (blankinterval) { - mod_timer(&console_timer, jiffies + blankinterval); + mod_timer(&console_timer, jiffies + (blankinterval * HZ)); blank_state = blank_normal_wait; } } -- cgit v1.2.3 From 049a947c611a19523eaaf193f698b897a62d0593 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 2 Jun 2009 23:54:21 +0900 Subject: MIPS: hwrng: Add TX4939 RNG driver This patch adds support for the integrated RNG of the TX4939 SoC. Signed-off-by: Atsushi Nemoto Acked-by: Matt Mackall Signed-off-by: Ralf Baechle --- drivers/char/hw_random/Kconfig | 13 +++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/tx4939-rng.c | 184 ++++++++++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 drivers/char/hw_random/tx4939-rng.c (limited to 'drivers/char') diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index f4b3f7293fe..ce66a70184f 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -149,6 +149,19 @@ config HW_RANDOM_VIRTIO To compile this driver as a module, choose M here: the module will be called virtio-rng. If unsure, say N. +config HW_RANDOM_TX4939 + tristate "TX4939 Random Number Generator support" + depends on HW_RANDOM && SOC_TX4939 + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the Random Number + Generator hardware found on TX4939 SoC. + + To compile this driver as a module, choose M here: the + module will be called tx4939-rng. + + If unsure, say Y. + config HW_RANDOM_MXC_RNGA tristate "Freescale i.MX RNGA Random Number Generator" depends on HW_RANDOM && ARCH_HAS_RNGA diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index fd1ecd2f673..676828ba812 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -15,4 +15,5 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o +obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c new file mode 100644 index 00000000000..544d9085a8e --- /dev/null +++ b/drivers/char/hw_random/tx4939-rng.c @@ -0,0 +1,184 @@ +/* + * RNG driver for TX4939 Random Number Generators (RNG) + * + * Copyright (C) 2009 Atsushi Nemoto + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#define TX4939_RNG_RCSR 0x00000000 +#define TX4939_RNG_ROR(n) (0x00000018 + (n) * 8) + +#define TX4939_RNG_RCSR_INTE 0x00000008 +#define TX4939_RNG_RCSR_RST 0x00000004 +#define TX4939_RNG_RCSR_FIN 0x00000002 +#define TX4939_RNG_RCSR_ST 0x00000001 + +struct tx4939_rng { + struct hwrng rng; + void __iomem *base; + u64 databuf[3]; + unsigned int data_avail; +}; + +static void rng_io_start(void) +{ +#ifndef CONFIG_64BIT + /* + * readq is reading a 64-bit register using a 64-bit load. On + * a 32-bit kernel however interrupts or any other processor + * exception would clobber the upper 32-bit of the processor + * register so interrupts need to be disabled. + */ + local_irq_disable(); +#endif +} + +static void rng_io_end(void) +{ +#ifndef CONFIG_64BIT + local_irq_enable(); +#endif +} + +static u64 read_rng(void __iomem *base, unsigned int offset) +{ + return ____raw_readq(base + offset); +} + +static void write_rng(u64 val, void __iomem *base, unsigned int offset) +{ + return ____raw_writeq(val, base + offset); +} + +static int tx4939_rng_data_present(struct hwrng *rng, int wait) +{ + struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng); + int i; + + if (rngdev->data_avail) + return rngdev->data_avail; + for (i = 0; i < 20; i++) { + rng_io_start(); + if (!(read_rng(rngdev->base, TX4939_RNG_RCSR) + & TX4939_RNG_RCSR_ST)) { + rngdev->databuf[0] = + read_rng(rngdev->base, TX4939_RNG_ROR(0)); + rngdev->databuf[1] = + read_rng(rngdev->base, TX4939_RNG_ROR(1)); + rngdev->databuf[2] = + read_rng(rngdev->base, TX4939_RNG_ROR(2)); + rngdev->data_avail = + sizeof(rngdev->databuf) / sizeof(u32); + /* Start RNG */ + write_rng(TX4939_RNG_RCSR_ST, + rngdev->base, TX4939_RNG_RCSR); + wait = 0; + } + rng_io_end(); + if (!wait) + break; + /* 90 bus clock cycles by default for generation */ + ndelay(90 * 5); + } + return rngdev->data_avail; +} + +static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer) +{ + struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng); + + rngdev->data_avail--; + *buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail); + return sizeof(u32); +} + +static int __init tx4939_rng_probe(struct platform_device *dev) +{ + struct tx4939_rng *rngdev; + struct resource *r; + int i; + + r = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!r) + return -EBUSY; + rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); + if (!rngdev) + return -ENOMEM; + if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r), + dev_name(&dev->dev))) + return -EBUSY; + rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r)); + if (!rngdev->base) + return -EBUSY; + + rngdev->rng.name = dev_name(&dev->dev); + rngdev->rng.data_present = tx4939_rng_data_present; + rngdev->rng.data_read = tx4939_rng_data_read; + + rng_io_start(); + /* Reset RNG */ + write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR); + write_rng(0, rngdev->base, TX4939_RNG_RCSR); + /* Start RNG */ + write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR); + rng_io_end(); + /* + * Drop first two results. From the datasheet: + * The quality of the random numbers generated immediately + * after reset can be insufficient. Therefore, do not use + * random numbers obtained from the first and second + * generations; use the ones from the third or subsequent + * generation. + */ + for (i = 0; i < 2; i++) { + rngdev->data_avail = 0; + if (!tx4939_rng_data_present(&rngdev->rng, 1)) + return -EIO; + } + + platform_set_drvdata(dev, rngdev); + return hwrng_register(&rngdev->rng); +} + +static int __exit tx4939_rng_remove(struct platform_device *dev) +{ + struct tx4939_rng *rngdev = platform_get_drvdata(dev); + + hwrng_unregister(&rngdev->rng); + platform_set_drvdata(dev, NULL); + return 0; +} + +static struct platform_driver tx4939_rng_driver = { + .driver = { + .name = "tx4939-rng", + .owner = THIS_MODULE, + }, + .remove = tx4939_rng_remove, +}; + +static int __init tx4939rng_init(void) +{ + return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe); +} + +static void __exit tx4939rng_exit(void) +{ + platform_driver_unregister(&tx4939_rng_driver); +} + +module_init(tx4939rng_init); +module_exit(tx4939rng_exit); + +MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3