diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-12-19 09:08:03 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-12-19 09:08:32 -0500 |
commit | e23c34bb41da65f354fb7eee04300c56ee48f60c (patch) | |
tree | 549fbe449d55273b81ef104a9755109bf4ae7817 /drivers/char | |
parent | b481c2cb3534c85dca625973b33eba15f9af3e4c (diff) | |
parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) |
Merge branch 'master' into for-next
Sync with Linus' tree to be able to apply fixes on top of newer things
in tree (efi-stub).
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/char')
42 files changed, 2416 insertions, 592 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 14219972c745..fa3243d71c76 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -522,10 +522,16 @@ config HPET_MMAP | |||
522 | If you say Y here, user applications will be able to mmap | 522 | If you say Y here, user applications will be able to mmap |
523 | the HPET registers. | 523 | the HPET registers. |
524 | 524 | ||
525 | config HPET_MMAP_DEFAULT | ||
526 | bool "Enable HPET MMAP access by default" | ||
527 | default y | ||
528 | depends on HPET_MMAP | ||
529 | help | ||
525 | In some hardware implementations, the page containing HPET | 530 | In some hardware implementations, the page containing HPET |
526 | registers may also contain other things that shouldn't be | 531 | registers may also contain other things that shouldn't be |
527 | exposed to the user. If this applies to your hardware, | 532 | exposed to the user. This option selects the default (if |
528 | say N here. | 533 | kernel parameter hpet_mmap is not set) user access to the |
534 | registers for applications that require it. | ||
529 | 535 | ||
530 | config HANGCHECK_TIMER | 536 | config HANGCHECK_TIMER |
531 | tristate "Hangcheck timer" | 537 | tristate "Hangcheck timer" |
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 0671e45daa57..8fedbc250414 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_address.h> | ||
24 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
26 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 448ce5e29c56..5d9c31dfc905 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -367,12 +367,29 @@ static unsigned int hpet_poll(struct file *file, poll_table * wait) | |||
367 | return 0; | 367 | return 0; |
368 | } | 368 | } |
369 | 369 | ||
370 | #ifdef CONFIG_HPET_MMAP | ||
371 | #ifdef CONFIG_HPET_MMAP_DEFAULT | ||
372 | static int hpet_mmap_enabled = 1; | ||
373 | #else | ||
374 | static int hpet_mmap_enabled = 0; | ||
375 | #endif | ||
376 | |||
377 | static __init int hpet_mmap_enable(char *str) | ||
378 | { | ||
379 | get_option(&str, &hpet_mmap_enabled); | ||
380 | pr_info("HPET mmap %s\n", hpet_mmap_enabled ? "enabled" : "disabled"); | ||
381 | return 1; | ||
382 | } | ||
383 | __setup("hpet_mmap", hpet_mmap_enable); | ||
384 | |||
370 | static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | 385 | static int hpet_mmap(struct file *file, struct vm_area_struct *vma) |
371 | { | 386 | { |
372 | #ifdef CONFIG_HPET_MMAP | ||
373 | struct hpet_dev *devp; | 387 | struct hpet_dev *devp; |
374 | unsigned long addr; | 388 | unsigned long addr; |
375 | 389 | ||
390 | if (!hpet_mmap_enabled) | ||
391 | return -EACCES; | ||
392 | |||
376 | devp = file->private_data; | 393 | devp = file->private_data; |
377 | addr = devp->hd_hpets->hp_hpet_phys; | 394 | addr = devp->hd_hpets->hp_hpet_phys; |
378 | 395 | ||
@@ -381,10 +398,13 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
381 | 398 | ||
382 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 399 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
383 | return vm_iomap_memory(vma, addr, PAGE_SIZE); | 400 | return vm_iomap_memory(vma, addr, PAGE_SIZE); |
401 | } | ||
384 | #else | 402 | #else |
403 | static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | ||
404 | { | ||
385 | return -ENOSYS; | 405 | return -ENOSYS; |
386 | #endif | ||
387 | } | 406 | } |
407 | #endif | ||
388 | 408 | ||
389 | static int hpet_fasync(int fd, struct file *file, int on) | 409 | static int hpet_fasync(int fd, struct file *file, int on) |
390 | { | 410 | { |
@@ -486,8 +506,7 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
486 | } | 506 | } |
487 | 507 | ||
488 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); | 508 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); |
489 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ | 509 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : 0; |
490 | ? IRQF_SHARED : IRQF_DISABLED; | ||
491 | if (request_irq(irq, hpet_interrupt, irq_flags, | 510 | if (request_irq(irq, hpet_interrupt, irq_flags, |
492 | devp->hd_name, (void *)devp)) { | 511 | devp->hd_name, (void *)devp)) { |
493 | printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); | 512 | printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); |
@@ -971,8 +990,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
971 | struct acpi_resource_fixed_memory32 *fixmem32; | 990 | struct acpi_resource_fixed_memory32 *fixmem32; |
972 | 991 | ||
973 | fixmem32 = &res->data.fixed_memory32; | 992 | fixmem32 = &res->data.fixed_memory32; |
974 | if (!fixmem32) | ||
975 | return AE_NO_MEMORY; | ||
976 | 993 | ||
977 | hdp->hd_phys_address = fixmem32->address; | 994 | hdp->hd_phys_address = fixmem32->address; |
978 | hdp->hd_address = ioremap(fixmem32->address, | 995 | hdp->hd_address = ioremap(fixmem32->address, |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 40a865449f35..2f2b08457c67 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -153,18 +153,31 @@ config HW_RANDOM_IXP4XX | |||
153 | 153 | ||
154 | config HW_RANDOM_OMAP | 154 | config HW_RANDOM_OMAP |
155 | tristate "OMAP Random Number Generator support" | 155 | tristate "OMAP Random Number Generator support" |
156 | depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP2) | 156 | depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP2PLUS) |
157 | default HW_RANDOM | 157 | default HW_RANDOM |
158 | ---help--- | 158 | ---help--- |
159 | This driver provides kernel-side support for the Random Number | 159 | This driver provides kernel-side support for the Random Number |
160 | Generator hardware found on OMAP16xx and OMAP24xx multimedia | 160 | Generator hardware found on OMAP16xx, OMAP2/3/4/5 and AM33xx/AM43xx |
161 | processors. | 161 | multimedia processors. |
162 | 162 | ||
163 | To compile this driver as a module, choose M here: the | 163 | To compile this driver as a module, choose M here: the |
164 | module will be called omap-rng. | 164 | module will be called omap-rng. |
165 | 165 | ||
166 | If unsure, say Y. | 166 | If unsure, say Y. |
167 | 167 | ||
168 | config HW_RANDOM_OMAP3_ROM | ||
169 | tristate "OMAP3 ROM Random Number Generator support" | ||
170 | depends on HW_RANDOM && ARCH_OMAP3 | ||
171 | default HW_RANDOM | ||
172 | ---help--- | ||
173 | This driver provides kernel-side support for the Random Number | ||
174 | Generator hardware found on OMAP34xx processors. | ||
175 | |||
176 | To compile this driver as a module, choose M here: the | ||
177 | module will be called omap3-rom-rng. | ||
178 | |||
179 | If unsure, say Y. | ||
180 | |||
168 | config HW_RANDOM_OCTEON | 181 | config HW_RANDOM_OCTEON |
169 | tristate "Octeon Random Number Generator support" | 182 | tristate "Octeon Random Number Generator support" |
170 | depends on HW_RANDOM && CAVIUM_OCTEON_SOC | 183 | depends on HW_RANDOM && CAVIUM_OCTEON_SOC |
@@ -290,6 +303,19 @@ config HW_RANDOM_PSERIES | |||
290 | 303 | ||
291 | If unsure, say Y. | 304 | If unsure, say Y. |
292 | 305 | ||
306 | config HW_RANDOM_POWERNV | ||
307 | tristate "PowerNV Random Number Generator support" | ||
308 | depends on HW_RANDOM && PPC_POWERNV | ||
309 | default HW_RANDOM | ||
310 | ---help--- | ||
311 | This is the driver for Random Number Generator hardware found | ||
312 | in POWER7+ and above machines for PowerNV platform. | ||
313 | |||
314 | To compile this driver as a module, choose M here: the | ||
315 | module will be called powernv-rng. | ||
316 | |||
317 | If unsure, say Y. | ||
318 | |||
293 | config HW_RANDOM_EXYNOS | 319 | config HW_RANDOM_EXYNOS |
294 | tristate "EXYNOS HW random number generator support" | 320 | tristate "EXYNOS HW random number generator support" |
295 | depends on HW_RANDOM && HAS_IOMEM && HAVE_CLK | 321 | depends on HW_RANDOM && HAS_IOMEM && HAVE_CLK |
@@ -314,3 +340,15 @@ config HW_RANDOM_TPM | |||
314 | module will be called tpm-rng. | 340 | module will be called tpm-rng. |
315 | 341 | ||
316 | If unsure, say Y. | 342 | If unsure, say Y. |
343 | |||
344 | config HW_RANDOM_MSM | ||
345 | tristate "Qualcomm MSM Random Number Generator support" | ||
346 | depends on HW_RANDOM && ARCH_MSM | ||
347 | ---help--- | ||
348 | This driver provides kernel-side support for the Random Number | ||
349 | Generator hardware found on Qualcomm MSM SoCs. | ||
350 | |||
351 | To compile this driver as a module, choose M here. the | ||
352 | module will be called msm-rng. | ||
353 | |||
354 | If unsure, say Y. | ||
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index bed467c9300e..3ae7755a52e7 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile | |||
@@ -15,6 +15,7 @@ n2-rng-y := n2-drv.o n2-asm.o | |||
15 | obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o | 15 | obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o |
16 | obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o | 16 | obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o |
17 | obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o | 17 | obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o |
18 | obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o | ||
18 | obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o | 19 | obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o |
19 | obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o | 20 | obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o |
20 | obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o | 21 | obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o |
@@ -24,6 +25,8 @@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o | |||
24 | obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o | 25 | obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o |
25 | obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o | 26 | obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o |
26 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o | 27 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o |
28 | obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o | ||
27 | obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o | 29 | obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o |
28 | obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o | 30 | obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o |
29 | obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o | 31 | obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o |
32 | obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o | ||
diff --git a/drivers/char/hw_random/msm-rng.c b/drivers/char/hw_random/msm-rng.c new file mode 100644 index 000000000000..148521e51dc6 --- /dev/null +++ b/drivers/char/hw_random/msm-rng.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/hw_random.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | /* Device specific register offsets */ | ||
23 | #define PRNG_DATA_OUT 0x0000 | ||
24 | #define PRNG_STATUS 0x0004 | ||
25 | #define PRNG_LFSR_CFG 0x0100 | ||
26 | #define PRNG_CONFIG 0x0104 | ||
27 | |||
28 | /* Device specific register masks and config values */ | ||
29 | #define PRNG_LFSR_CFG_MASK 0x0000ffff | ||
30 | #define PRNG_LFSR_CFG_CLOCKS 0x0000dddd | ||
31 | #define PRNG_CONFIG_HW_ENABLE BIT(1) | ||
32 | #define PRNG_STATUS_DATA_AVAIL BIT(0) | ||
33 | |||
34 | #define MAX_HW_FIFO_DEPTH 16 | ||
35 | #define MAX_HW_FIFO_SIZE (MAX_HW_FIFO_DEPTH * 4) | ||
36 | #define WORD_SZ 4 | ||
37 | |||
38 | struct msm_rng { | ||
39 | void __iomem *base; | ||
40 | struct clk *clk; | ||
41 | struct hwrng hwrng; | ||
42 | }; | ||
43 | |||
44 | #define to_msm_rng(p) container_of(p, struct msm_rng, hwrng) | ||
45 | |||
46 | static int msm_rng_enable(struct hwrng *hwrng, int enable) | ||
47 | { | ||
48 | struct msm_rng *rng = to_msm_rng(hwrng); | ||
49 | u32 val; | ||
50 | int ret; | ||
51 | |||
52 | ret = clk_prepare_enable(rng->clk); | ||
53 | if (ret) | ||
54 | return ret; | ||
55 | |||
56 | if (enable) { | ||
57 | /* Enable PRNG only if it is not already enabled */ | ||
58 | val = readl_relaxed(rng->base + PRNG_CONFIG); | ||
59 | if (val & PRNG_CONFIG_HW_ENABLE) | ||
60 | goto already_enabled; | ||
61 | |||
62 | val = readl_relaxed(rng->base + PRNG_LFSR_CFG); | ||
63 | val &= ~PRNG_LFSR_CFG_MASK; | ||
64 | val |= PRNG_LFSR_CFG_CLOCKS; | ||
65 | writel(val, rng->base + PRNG_LFSR_CFG); | ||
66 | |||
67 | val = readl_relaxed(rng->base + PRNG_CONFIG); | ||
68 | val |= PRNG_CONFIG_HW_ENABLE; | ||
69 | writel(val, rng->base + PRNG_CONFIG); | ||
70 | } else { | ||
71 | val = readl_relaxed(rng->base + PRNG_CONFIG); | ||
72 | val &= ~PRNG_CONFIG_HW_ENABLE; | ||
73 | writel(val, rng->base + PRNG_CONFIG); | ||
74 | } | ||
75 | |||
76 | already_enabled: | ||
77 | clk_disable_unprepare(rng->clk); | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int msm_rng_read(struct hwrng *hwrng, void *data, size_t max, bool wait) | ||
82 | { | ||
83 | struct msm_rng *rng = to_msm_rng(hwrng); | ||
84 | size_t currsize = 0; | ||
85 | u32 *retdata = data; | ||
86 | size_t maxsize; | ||
87 | int ret; | ||
88 | u32 val; | ||
89 | |||
90 | /* calculate max size bytes to transfer back to caller */ | ||
91 | maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, max); | ||
92 | |||
93 | /* no room for word data */ | ||
94 | if (maxsize < WORD_SZ) | ||
95 | return 0; | ||
96 | |||
97 | ret = clk_prepare_enable(rng->clk); | ||
98 | if (ret) | ||
99 | return ret; | ||
100 | |||
101 | /* read random data from hardware */ | ||
102 | do { | ||
103 | val = readl_relaxed(rng->base + PRNG_STATUS); | ||
104 | if (!(val & PRNG_STATUS_DATA_AVAIL)) | ||
105 | break; | ||
106 | |||
107 | val = readl_relaxed(rng->base + PRNG_DATA_OUT); | ||
108 | if (!val) | ||
109 | break; | ||
110 | |||
111 | *retdata++ = val; | ||
112 | currsize += WORD_SZ; | ||
113 | |||
114 | /* make sure we stay on 32bit boundary */ | ||
115 | if ((maxsize - currsize) < WORD_SZ) | ||
116 | break; | ||
117 | } while (currsize < maxsize); | ||
118 | |||
119 | clk_disable_unprepare(rng->clk); | ||
120 | |||
121 | return currsize; | ||
122 | } | ||
123 | |||
124 | static int msm_rng_init(struct hwrng *hwrng) | ||
125 | { | ||
126 | return msm_rng_enable(hwrng, 1); | ||
127 | } | ||
128 | |||
129 | static void msm_rng_cleanup(struct hwrng *hwrng) | ||
130 | { | ||
131 | msm_rng_enable(hwrng, 0); | ||
132 | } | ||
133 | |||
134 | static int msm_rng_probe(struct platform_device *pdev) | ||
135 | { | ||
136 | struct resource *res; | ||
137 | struct msm_rng *rng; | ||
138 | int ret; | ||
139 | |||
140 | rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); | ||
141 | if (!rng) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | platform_set_drvdata(pdev, rng); | ||
145 | |||
146 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
147 | rng->base = devm_ioremap_resource(&pdev->dev, res); | ||
148 | if (IS_ERR(rng->base)) | ||
149 | return PTR_ERR(rng->base); | ||
150 | |||
151 | rng->clk = devm_clk_get(&pdev->dev, "core"); | ||
152 | if (IS_ERR(rng->clk)) | ||
153 | return PTR_ERR(rng->clk); | ||
154 | |||
155 | rng->hwrng.name = KBUILD_MODNAME, | ||
156 | rng->hwrng.init = msm_rng_init, | ||
157 | rng->hwrng.cleanup = msm_rng_cleanup, | ||
158 | rng->hwrng.read = msm_rng_read, | ||
159 | |||
160 | ret = hwrng_register(&rng->hwrng); | ||
161 | if (ret) { | ||
162 | dev_err(&pdev->dev, "failed to register hwrng\n"); | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int msm_rng_remove(struct platform_device *pdev) | ||
170 | { | ||
171 | struct msm_rng *rng = platform_get_drvdata(pdev); | ||
172 | |||
173 | hwrng_unregister(&rng->hwrng); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static const struct of_device_id msm_rng_of_match[] = { | ||
178 | { .compatible = "qcom,prng", }, | ||
179 | {} | ||
180 | }; | ||
181 | MODULE_DEVICE_TABLE(of, msm_rng_of_match); | ||
182 | |||
183 | static struct platform_driver msm_rng_driver = { | ||
184 | .probe = msm_rng_probe, | ||
185 | .remove = msm_rng_remove, | ||
186 | .driver = { | ||
187 | .name = KBUILD_MODNAME, | ||
188 | .owner = THIS_MODULE, | ||
189 | .of_match_table = of_match_ptr(msm_rng_of_match), | ||
190 | } | ||
191 | }; | ||
192 | module_platform_driver(msm_rng_driver); | ||
193 | |||
194 | MODULE_ALIAS("platform:" KBUILD_MODNAME); | ||
195 | MODULE_AUTHOR("The Linux Foundation"); | ||
196 | MODULE_DESCRIPTION("Qualcomm MSM random number generator driver"); | ||
197 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index 19a12ac64a9e..6a86b6f56af2 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c | |||
@@ -164,7 +164,9 @@ static int __init mxc_rnga_probe(struct platform_device *pdev) | |||
164 | goto out; | 164 | goto out; |
165 | } | 165 | } |
166 | 166 | ||
167 | clk_prepare_enable(mxc_rng->clk); | 167 | err = clk_prepare_enable(mxc_rng->clk); |
168 | if (err) | ||
169 | goto out; | ||
168 | 170 | ||
169 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 171 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
170 | mxc_rng->mem = devm_ioremap_resource(&pdev->dev, res); | 172 | mxc_rng->mem = devm_ioremap_resource(&pdev->dev, res); |
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 6843ec87b98b..9b89ff4881de 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -24,57 +24,131 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <linux/of.h> | ||
28 | #include <linux/of_device.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/interrupt.h> | ||
27 | 31 | ||
28 | #include <asm/io.h> | 32 | #include <asm/io.h> |
29 | 33 | ||
30 | #define RNG_OUT_REG 0x00 /* Output register */ | 34 | #define RNG_REG_STATUS_RDY (1 << 0) |
31 | #define RNG_STAT_REG 0x04 /* Status register | 35 | |
32 | [0] = STAT_BUSY */ | 36 | #define RNG_REG_INTACK_RDY_MASK (1 << 0) |
33 | #define RNG_ALARM_REG 0x24 /* Alarm register | 37 | #define RNG_REG_INTACK_SHUTDOWN_OFLO_MASK (1 << 1) |
34 | [7:0] = ALARM_COUNTER */ | 38 | #define RNG_SHUTDOWN_OFLO_MASK (1 << 1) |
35 | #define RNG_CONFIG_REG 0x28 /* Configuration register | 39 | |
36 | [11:6] = RESET_COUNT | 40 | #define RNG_CONTROL_STARTUP_CYCLES_SHIFT 16 |
37 | [5:3] = RING2_DELAY | 41 | #define RNG_CONTROL_STARTUP_CYCLES_MASK (0xffff << 16) |
38 | [2:0] = RING1_DELAY */ | 42 | #define RNG_CONTROL_ENABLE_TRNG_SHIFT 10 |
39 | #define RNG_REV_REG 0x3c /* Revision register | 43 | #define RNG_CONTROL_ENABLE_TRNG_MASK (1 << 10) |
40 | [7:0] = REV_NB */ | 44 | |
41 | #define RNG_MASK_REG 0x40 /* Mask and reset register | 45 | #define RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT 16 |
42 | [2] = IT_EN | 46 | #define RNG_CONFIG_MAX_REFIL_CYCLES_MASK (0xffff << 16) |
43 | [1] = SOFTRESET | 47 | #define RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT 0 |
44 | [0] = AUTOIDLE */ | 48 | #define RNG_CONFIG_MIN_REFIL_CYCLES_MASK (0xff << 0) |
45 | #define RNG_SYSSTATUS 0x44 /* System status | 49 | |
46 | [0] = RESETDONE */ | 50 | #define RNG_CONTROL_STARTUP_CYCLES 0xff |
51 | #define RNG_CONFIG_MIN_REFIL_CYCLES 0x21 | ||
52 | #define RNG_CONFIG_MAX_REFIL_CYCLES 0x22 | ||
53 | |||
54 | #define RNG_ALARMCNT_ALARM_TH_SHIFT 0x0 | ||
55 | #define RNG_ALARMCNT_ALARM_TH_MASK (0xff << 0) | ||
56 | #define RNG_ALARMCNT_SHUTDOWN_TH_SHIFT 16 | ||
57 | #define RNG_ALARMCNT_SHUTDOWN_TH_MASK (0x1f << 16) | ||
58 | #define RNG_ALARM_THRESHOLD 0xff | ||
59 | #define RNG_SHUTDOWN_THRESHOLD 0x4 | ||
60 | |||
61 | #define RNG_REG_FROENABLE_MASK 0xffffff | ||
62 | #define RNG_REG_FRODETUNE_MASK 0xffffff | ||
63 | |||
64 | #define OMAP2_RNG_OUTPUT_SIZE 0x4 | ||
65 | #define OMAP4_RNG_OUTPUT_SIZE 0x8 | ||
66 | |||
67 | enum { | ||
68 | RNG_OUTPUT_L_REG = 0, | ||
69 | RNG_OUTPUT_H_REG, | ||
70 | RNG_STATUS_REG, | ||
71 | RNG_INTMASK_REG, | ||
72 | RNG_INTACK_REG, | ||
73 | RNG_CONTROL_REG, | ||
74 | RNG_CONFIG_REG, | ||
75 | RNG_ALARMCNT_REG, | ||
76 | RNG_FROENABLE_REG, | ||
77 | RNG_FRODETUNE_REG, | ||
78 | RNG_ALARMMASK_REG, | ||
79 | RNG_ALARMSTOP_REG, | ||
80 | RNG_REV_REG, | ||
81 | RNG_SYSCONFIG_REG, | ||
82 | }; | ||
83 | |||
84 | static const u16 reg_map_omap2[] = { | ||
85 | [RNG_OUTPUT_L_REG] = 0x0, | ||
86 | [RNG_STATUS_REG] = 0x4, | ||
87 | [RNG_CONFIG_REG] = 0x28, | ||
88 | [RNG_REV_REG] = 0x3c, | ||
89 | [RNG_SYSCONFIG_REG] = 0x40, | ||
90 | }; | ||
47 | 91 | ||
92 | static const u16 reg_map_omap4[] = { | ||
93 | [RNG_OUTPUT_L_REG] = 0x0, | ||
94 | [RNG_OUTPUT_H_REG] = 0x4, | ||
95 | [RNG_STATUS_REG] = 0x8, | ||
96 | [RNG_INTMASK_REG] = 0xc, | ||
97 | [RNG_INTACK_REG] = 0x10, | ||
98 | [RNG_CONTROL_REG] = 0x14, | ||
99 | [RNG_CONFIG_REG] = 0x18, | ||
100 | [RNG_ALARMCNT_REG] = 0x1c, | ||
101 | [RNG_FROENABLE_REG] = 0x20, | ||
102 | [RNG_FRODETUNE_REG] = 0x24, | ||
103 | [RNG_ALARMMASK_REG] = 0x28, | ||
104 | [RNG_ALARMSTOP_REG] = 0x2c, | ||
105 | [RNG_REV_REG] = 0x1FE0, | ||
106 | [RNG_SYSCONFIG_REG] = 0x1FE4, | ||
107 | }; | ||
108 | |||
109 | struct omap_rng_dev; | ||
48 | /** | 110 | /** |
49 | * struct omap_rng_private_data - RNG IP block-specific data | 111 | * struct omap_rng_pdata - RNG IP block-specific data |
50 | * @base: virtual address of the beginning of the RNG IP block registers | 112 | * @regs: Pointer to the register offsets structure. |
51 | * @mem_res: struct resource * for the IP block registers physical memory | 113 | * @data_size: No. of bytes in RNG output. |
114 | * @data_present: Callback to determine if data is available. | ||
115 | * @init: Callback for IP specific initialization sequence. | ||
116 | * @cleanup: Callback for IP specific cleanup sequence. | ||
52 | */ | 117 | */ |
53 | struct omap_rng_private_data { | 118 | struct omap_rng_pdata { |
54 | void __iomem *base; | 119 | u16 *regs; |
55 | struct resource *mem_res; | 120 | u32 data_size; |
121 | u32 (*data_present)(struct omap_rng_dev *priv); | ||
122 | int (*init)(struct omap_rng_dev *priv); | ||
123 | void (*cleanup)(struct omap_rng_dev *priv); | ||
56 | }; | 124 | }; |
57 | 125 | ||
58 | static inline u32 omap_rng_read_reg(struct omap_rng_private_data *priv, int reg) | 126 | struct omap_rng_dev { |
127 | void __iomem *base; | ||
128 | struct device *dev; | ||
129 | const struct omap_rng_pdata *pdata; | ||
130 | }; | ||
131 | |||
132 | static inline u32 omap_rng_read(struct omap_rng_dev *priv, u16 reg) | ||
59 | { | 133 | { |
60 | return __raw_readl(priv->base + reg); | 134 | return __raw_readl(priv->base + priv->pdata->regs[reg]); |
61 | } | 135 | } |
62 | 136 | ||
63 | static inline void omap_rng_write_reg(struct omap_rng_private_data *priv, | 137 | static inline void omap_rng_write(struct omap_rng_dev *priv, u16 reg, |
64 | int reg, u32 val) | 138 | u32 val) |
65 | { | 139 | { |
66 | __raw_writel(val, priv->base + reg); | 140 | __raw_writel(val, priv->base + priv->pdata->regs[reg]); |
67 | } | 141 | } |
68 | 142 | ||
69 | static int omap_rng_data_present(struct hwrng *rng, int wait) | 143 | static int omap_rng_data_present(struct hwrng *rng, int wait) |
70 | { | 144 | { |
71 | struct omap_rng_private_data *priv; | 145 | struct omap_rng_dev *priv; |
72 | int data, i; | 146 | int data, i; |
73 | 147 | ||
74 | priv = (struct omap_rng_private_data *)rng->priv; | 148 | priv = (struct omap_rng_dev *)rng->priv; |
75 | 149 | ||
76 | for (i = 0; i < 20; i++) { | 150 | for (i = 0; i < 20; i++) { |
77 | data = omap_rng_read_reg(priv, RNG_STAT_REG) ? 0 : 1; | 151 | data = priv->pdata->data_present(priv); |
78 | if (data || !wait) | 152 | if (data || !wait) |
79 | break; | 153 | break; |
80 | /* RNG produces data fast enough (2+ MBit/sec, even | 154 | /* RNG produces data fast enough (2+ MBit/sec, even |
@@ -89,27 +163,212 @@ static int omap_rng_data_present(struct hwrng *rng, int wait) | |||
89 | 163 | ||
90 | static int omap_rng_data_read(struct hwrng *rng, u32 *data) | 164 | static int omap_rng_data_read(struct hwrng *rng, u32 *data) |
91 | { | 165 | { |
92 | struct omap_rng_private_data *priv; | 166 | struct omap_rng_dev *priv; |
167 | u32 data_size, i; | ||
168 | |||
169 | priv = (struct omap_rng_dev *)rng->priv; | ||
170 | data_size = priv->pdata->data_size; | ||
171 | |||
172 | for (i = 0; i < data_size / sizeof(u32); i++) | ||
173 | data[i] = omap_rng_read(priv, RNG_OUTPUT_L_REG + i); | ||
174 | |||
175 | if (priv->pdata->regs[RNG_INTACK_REG]) | ||
176 | omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_RDY_MASK); | ||
177 | return data_size; | ||
178 | } | ||
179 | |||
180 | static int omap_rng_init(struct hwrng *rng) | ||
181 | { | ||
182 | struct omap_rng_dev *priv; | ||
93 | 183 | ||
94 | priv = (struct omap_rng_private_data *)rng->priv; | 184 | priv = (struct omap_rng_dev *)rng->priv; |
185 | return priv->pdata->init(priv); | ||
186 | } | ||
95 | 187 | ||
96 | *data = omap_rng_read_reg(priv, RNG_OUT_REG); | 188 | static void omap_rng_cleanup(struct hwrng *rng) |
189 | { | ||
190 | struct omap_rng_dev *priv; | ||
97 | 191 | ||
98 | return sizeof(u32); | 192 | priv = (struct omap_rng_dev *)rng->priv; |
193 | priv->pdata->cleanup(priv); | ||
99 | } | 194 | } |
100 | 195 | ||
101 | static struct hwrng omap_rng_ops = { | 196 | static struct hwrng omap_rng_ops = { |
102 | .name = "omap", | 197 | .name = "omap", |
103 | .data_present = omap_rng_data_present, | 198 | .data_present = omap_rng_data_present, |
104 | .data_read = omap_rng_data_read, | 199 | .data_read = omap_rng_data_read, |
200 | .init = omap_rng_init, | ||
201 | .cleanup = omap_rng_cleanup, | ||
202 | }; | ||
203 | |||
204 | static inline u32 omap2_rng_data_present(struct omap_rng_dev *priv) | ||
205 | { | ||
206 | return omap_rng_read(priv, RNG_STATUS_REG) ? 0 : 1; | ||
207 | } | ||
208 | |||
209 | static int omap2_rng_init(struct omap_rng_dev *priv) | ||
210 | { | ||
211 | omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x1); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static void omap2_rng_cleanup(struct omap_rng_dev *priv) | ||
216 | { | ||
217 | omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x0); | ||
218 | } | ||
219 | |||
220 | static struct omap_rng_pdata omap2_rng_pdata = { | ||
221 | .regs = (u16 *)reg_map_omap2, | ||
222 | .data_size = OMAP2_RNG_OUTPUT_SIZE, | ||
223 | .data_present = omap2_rng_data_present, | ||
224 | .init = omap2_rng_init, | ||
225 | .cleanup = omap2_rng_cleanup, | ||
105 | }; | 226 | }; |
106 | 227 | ||
228 | #if defined(CONFIG_OF) | ||
229 | static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv) | ||
230 | { | ||
231 | return omap_rng_read(priv, RNG_STATUS_REG) & RNG_REG_STATUS_RDY; | ||
232 | } | ||
233 | |||
234 | static int omap4_rng_init(struct omap_rng_dev *priv) | ||
235 | { | ||
236 | u32 val; | ||
237 | |||
238 | /* Return if RNG is already running. */ | ||
239 | if (omap_rng_read(priv, RNG_CONFIG_REG) & RNG_CONTROL_ENABLE_TRNG_MASK) | ||
240 | return 0; | ||
241 | |||
242 | val = RNG_CONFIG_MIN_REFIL_CYCLES << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT; | ||
243 | val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT; | ||
244 | omap_rng_write(priv, RNG_CONFIG_REG, val); | ||
245 | |||
246 | omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0); | ||
247 | omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK); | ||
248 | val = RNG_ALARM_THRESHOLD << RNG_ALARMCNT_ALARM_TH_SHIFT; | ||
249 | val |= RNG_SHUTDOWN_THRESHOLD << RNG_ALARMCNT_SHUTDOWN_TH_SHIFT; | ||
250 | omap_rng_write(priv, RNG_ALARMCNT_REG, val); | ||
251 | |||
252 | val = RNG_CONTROL_STARTUP_CYCLES << RNG_CONTROL_STARTUP_CYCLES_SHIFT; | ||
253 | val |= RNG_CONTROL_ENABLE_TRNG_MASK; | ||
254 | omap_rng_write(priv, RNG_CONTROL_REG, val); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static void omap4_rng_cleanup(struct omap_rng_dev *priv) | ||
260 | { | ||
261 | int val; | ||
262 | |||
263 | val = omap_rng_read(priv, RNG_CONTROL_REG); | ||
264 | val &= ~RNG_CONTROL_ENABLE_TRNG_MASK; | ||
265 | omap_rng_write(priv, RNG_CONFIG_REG, val); | ||
266 | } | ||
267 | |||
268 | static irqreturn_t omap4_rng_irq(int irq, void *dev_id) | ||
269 | { | ||
270 | struct omap_rng_dev *priv = dev_id; | ||
271 | u32 fro_detune, fro_enable; | ||
272 | |||
273 | /* | ||
274 | * Interrupt raised by a fro shutdown threshold, do the following: | ||
275 | * 1. Clear the alarm events. | ||
276 | * 2. De tune the FROs which are shutdown. | ||
277 | * 3. Re enable the shutdown FROs. | ||
278 | */ | ||
279 | omap_rng_write(priv, RNG_ALARMMASK_REG, 0x0); | ||
280 | omap_rng_write(priv, RNG_ALARMSTOP_REG, 0x0); | ||
281 | |||
282 | fro_enable = omap_rng_read(priv, RNG_FROENABLE_REG); | ||
283 | fro_detune = ~fro_enable & RNG_REG_FRODETUNE_MASK; | ||
284 | fro_detune = fro_detune | omap_rng_read(priv, RNG_FRODETUNE_REG); | ||
285 | fro_enable = RNG_REG_FROENABLE_MASK; | ||
286 | |||
287 | omap_rng_write(priv, RNG_FRODETUNE_REG, fro_detune); | ||
288 | omap_rng_write(priv, RNG_FROENABLE_REG, fro_enable); | ||
289 | |||
290 | omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_SHUTDOWN_OFLO_MASK); | ||
291 | |||
292 | return IRQ_HANDLED; | ||
293 | } | ||
294 | |||
295 | static struct omap_rng_pdata omap4_rng_pdata = { | ||
296 | .regs = (u16 *)reg_map_omap4, | ||
297 | .data_size = OMAP4_RNG_OUTPUT_SIZE, | ||
298 | .data_present = omap4_rng_data_present, | ||
299 | .init = omap4_rng_init, | ||
300 | .cleanup = omap4_rng_cleanup, | ||
301 | }; | ||
302 | |||
303 | static const struct of_device_id omap_rng_of_match[] = { | ||
304 | { | ||
305 | .compatible = "ti,omap2-rng", | ||
306 | .data = &omap2_rng_pdata, | ||
307 | }, | ||
308 | { | ||
309 | .compatible = "ti,omap4-rng", | ||
310 | .data = &omap4_rng_pdata, | ||
311 | }, | ||
312 | {}, | ||
313 | }; | ||
314 | MODULE_DEVICE_TABLE(of, omap_rng_of_match); | ||
315 | |||
316 | static int of_get_omap_rng_device_details(struct omap_rng_dev *priv, | ||
317 | struct platform_device *pdev) | ||
318 | { | ||
319 | const struct of_device_id *match; | ||
320 | struct device *dev = &pdev->dev; | ||
321 | int irq, err; | ||
322 | |||
323 | match = of_match_device(of_match_ptr(omap_rng_of_match), dev); | ||
324 | if (!match) { | ||
325 | dev_err(dev, "no compatible OF match\n"); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | priv->pdata = match->data; | ||
329 | |||
330 | if (of_device_is_compatible(dev->of_node, "ti,omap4-rng")) { | ||
331 | irq = platform_get_irq(pdev, 0); | ||
332 | if (irq < 0) { | ||
333 | dev_err(dev, "%s: error getting IRQ resource - %d\n", | ||
334 | __func__, irq); | ||
335 | return irq; | ||
336 | } | ||
337 | |||
338 | err = devm_request_irq(dev, irq, omap4_rng_irq, | ||
339 | IRQF_TRIGGER_NONE, dev_name(dev), priv); | ||
340 | if (err) { | ||
341 | dev_err(dev, "unable to request irq %d, err = %d\n", | ||
342 | irq, err); | ||
343 | return err; | ||
344 | } | ||
345 | omap_rng_write(priv, RNG_INTMASK_REG, RNG_SHUTDOWN_OFLO_MASK); | ||
346 | } | ||
347 | return 0; | ||
348 | } | ||
349 | #else | ||
350 | static int of_get_omap_rng_device_details(struct omap_rng_dev *omap_rng, | ||
351 | struct platform_device *pdev) | ||
352 | { | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | #endif | ||
356 | |||
357 | static int get_omap_rng_device_details(struct omap_rng_dev *omap_rng) | ||
358 | { | ||
359 | /* Only OMAP2/3 can be non-DT */ | ||
360 | omap_rng->pdata = &omap2_rng_pdata; | ||
361 | return 0; | ||
362 | } | ||
363 | |||
107 | static int omap_rng_probe(struct platform_device *pdev) | 364 | static int omap_rng_probe(struct platform_device *pdev) |
108 | { | 365 | { |
109 | struct omap_rng_private_data *priv; | 366 | struct omap_rng_dev *priv; |
367 | struct resource *res; | ||
368 | struct device *dev = &pdev->dev; | ||
110 | int ret; | 369 | int ret; |
111 | 370 | ||
112 | priv = kzalloc(sizeof(struct omap_rng_private_data), GFP_KERNEL); | 371 | priv = devm_kzalloc(dev, sizeof(struct omap_rng_dev), GFP_KERNEL); |
113 | if (!priv) { | 372 | if (!priv) { |
114 | dev_err(&pdev->dev, "could not allocate memory\n"); | 373 | dev_err(&pdev->dev, "could not allocate memory\n"); |
115 | return -ENOMEM; | 374 | return -ENOMEM; |
@@ -117,26 +376,29 @@ static int omap_rng_probe(struct platform_device *pdev) | |||
117 | 376 | ||
118 | omap_rng_ops.priv = (unsigned long)priv; | 377 | omap_rng_ops.priv = (unsigned long)priv; |
119 | platform_set_drvdata(pdev, priv); | 378 | platform_set_drvdata(pdev, priv); |
379 | priv->dev = dev; | ||
120 | 380 | ||
121 | priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 381 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
122 | priv->base = devm_ioremap_resource(&pdev->dev, priv->mem_res); | 382 | priv->base = devm_ioremap_resource(dev, res); |
123 | if (IS_ERR(priv->base)) { | 383 | if (IS_ERR(priv->base)) { |
124 | ret = PTR_ERR(priv->base); | 384 | ret = PTR_ERR(priv->base); |
125 | goto err_ioremap; | 385 | goto err_ioremap; |
126 | } | 386 | } |
127 | platform_set_drvdata(pdev, priv); | ||
128 | 387 | ||
129 | pm_runtime_enable(&pdev->dev); | 388 | pm_runtime_enable(&pdev->dev); |
130 | pm_runtime_get_sync(&pdev->dev); | 389 | pm_runtime_get_sync(&pdev->dev); |
131 | 390 | ||
391 | ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) : | ||
392 | get_omap_rng_device_details(priv); | ||
393 | if (ret) | ||
394 | goto err_ioremap; | ||
395 | |||
132 | ret = hwrng_register(&omap_rng_ops); | 396 | ret = hwrng_register(&omap_rng_ops); |
133 | if (ret) | 397 | if (ret) |
134 | goto err_register; | 398 | goto err_register; |
135 | 399 | ||
136 | dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", | 400 | dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", |
137 | omap_rng_read_reg(priv, RNG_REV_REG)); | 401 | omap_rng_read(priv, RNG_REV_REG)); |
138 | |||
139 | omap_rng_write_reg(priv, RNG_MASK_REG, 0x1); | ||
140 | 402 | ||
141 | return 0; | 403 | return 0; |
142 | 404 | ||
@@ -144,26 +406,21 @@ err_register: | |||
144 | priv->base = NULL; | 406 | priv->base = NULL; |
145 | pm_runtime_disable(&pdev->dev); | 407 | pm_runtime_disable(&pdev->dev); |
146 | err_ioremap: | 408 | err_ioremap: |
147 | kfree(priv); | 409 | dev_err(dev, "initialization failed.\n"); |
148 | |||
149 | return ret; | 410 | return ret; |
150 | } | 411 | } |
151 | 412 | ||
152 | static int __exit omap_rng_remove(struct platform_device *pdev) | 413 | static int __exit omap_rng_remove(struct platform_device *pdev) |
153 | { | 414 | { |
154 | struct omap_rng_private_data *priv = platform_get_drvdata(pdev); | 415 | struct omap_rng_dev *priv = platform_get_drvdata(pdev); |
155 | 416 | ||
156 | hwrng_unregister(&omap_rng_ops); | 417 | hwrng_unregister(&omap_rng_ops); |
157 | 418 | ||
158 | omap_rng_write_reg(priv, RNG_MASK_REG, 0x0); | 419 | priv->pdata->cleanup(priv); |
159 | 420 | ||
160 | pm_runtime_put_sync(&pdev->dev); | 421 | pm_runtime_put_sync(&pdev->dev); |
161 | pm_runtime_disable(&pdev->dev); | 422 | pm_runtime_disable(&pdev->dev); |
162 | 423 | ||
163 | release_mem_region(priv->mem_res->start, resource_size(priv->mem_res)); | ||
164 | |||
165 | kfree(priv); | ||
166 | |||
167 | return 0; | 424 | return 0; |
168 | } | 425 | } |
169 | 426 | ||
@@ -171,9 +428,9 @@ static int __exit omap_rng_remove(struct platform_device *pdev) | |||
171 | 428 | ||
172 | static int omap_rng_suspend(struct device *dev) | 429 | static int omap_rng_suspend(struct device *dev) |
173 | { | 430 | { |
174 | struct omap_rng_private_data *priv = dev_get_drvdata(dev); | 431 | struct omap_rng_dev *priv = dev_get_drvdata(dev); |
175 | 432 | ||
176 | omap_rng_write_reg(priv, RNG_MASK_REG, 0x0); | 433 | priv->pdata->cleanup(priv); |
177 | pm_runtime_put_sync(dev); | 434 | pm_runtime_put_sync(dev); |
178 | 435 | ||
179 | return 0; | 436 | return 0; |
@@ -181,10 +438,10 @@ static int omap_rng_suspend(struct device *dev) | |||
181 | 438 | ||
182 | static int omap_rng_resume(struct device *dev) | 439 | static int omap_rng_resume(struct device *dev) |
183 | { | 440 | { |
184 | struct omap_rng_private_data *priv = dev_get_drvdata(dev); | 441 | struct omap_rng_dev *priv = dev_get_drvdata(dev); |
185 | 442 | ||
186 | pm_runtime_get_sync(dev); | 443 | pm_runtime_get_sync(dev); |
187 | omap_rng_write_reg(priv, RNG_MASK_REG, 0x1); | 444 | priv->pdata->init(priv); |
188 | 445 | ||
189 | return 0; | 446 | return 0; |
190 | } | 447 | } |
@@ -198,31 +455,18 @@ static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); | |||
198 | 455 | ||
199 | #endif | 456 | #endif |
200 | 457 | ||
201 | /* work with hotplug and coldplug */ | ||
202 | MODULE_ALIAS("platform:omap_rng"); | ||
203 | |||
204 | static struct platform_driver omap_rng_driver = { | 458 | static struct platform_driver omap_rng_driver = { |
205 | .driver = { | 459 | .driver = { |
206 | .name = "omap_rng", | 460 | .name = "omap_rng", |
207 | .owner = THIS_MODULE, | 461 | .owner = THIS_MODULE, |
208 | .pm = OMAP_RNG_PM, | 462 | .pm = OMAP_RNG_PM, |
463 | .of_match_table = of_match_ptr(omap_rng_of_match), | ||
209 | }, | 464 | }, |
210 | .probe = omap_rng_probe, | 465 | .probe = omap_rng_probe, |
211 | .remove = __exit_p(omap_rng_remove), | 466 | .remove = __exit_p(omap_rng_remove), |
212 | }; | 467 | }; |
213 | 468 | ||
214 | static int __init omap_rng_init(void) | 469 | module_platform_driver(omap_rng_driver); |
215 | { | 470 | MODULE_ALIAS("platform:omap_rng"); |
216 | return platform_driver_register(&omap_rng_driver); | ||
217 | } | ||
218 | |||
219 | static void __exit omap_rng_exit(void) | ||
220 | { | ||
221 | platform_driver_unregister(&omap_rng_driver); | ||
222 | } | ||
223 | |||
224 | module_init(omap_rng_init); | ||
225 | module_exit(omap_rng_exit); | ||
226 | |||
227 | MODULE_AUTHOR("Deepak Saxena (and others)"); | 471 | MODULE_AUTHOR("Deepak Saxena (and others)"); |
228 | MODULE_LICENSE("GPL"); | 472 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c new file mode 100644 index 000000000000..c853e9e68573 --- /dev/null +++ b/drivers/char/hw_random/omap3-rom-rng.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * omap3-rom-rng.c - RNG driver for TI OMAP3 CPU family | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Author: Juha Yrjola <juha.yrjola@solidboot.com> | ||
6 | * | ||
7 | * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/random.h> | ||
19 | #include <linux/hw_random.h> | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | |||
25 | #define RNG_RESET 0x01 | ||
26 | #define RNG_GEN_PRNG_HW_INIT 0x02 | ||
27 | #define RNG_GEN_HW 0x08 | ||
28 | |||
29 | /* param1: ptr, param2: count, param3: flag */ | ||
30 | static u32 (*omap3_rom_rng_call)(u32, u32, u32); | ||
31 | |||
32 | static struct timer_list idle_timer; | ||
33 | static int rng_idle; | ||
34 | static struct clk *rng_clk; | ||
35 | |||
36 | static void omap3_rom_rng_idle(unsigned long data) | ||
37 | { | ||
38 | int r; | ||
39 | |||
40 | r = omap3_rom_rng_call(0, 0, RNG_RESET); | ||
41 | if (r != 0) { | ||
42 | pr_err("reset failed: %d\n", r); | ||
43 | return; | ||
44 | } | ||
45 | clk_disable_unprepare(rng_clk); | ||
46 | rng_idle = 1; | ||
47 | } | ||
48 | |||
49 | static int omap3_rom_rng_get_random(void *buf, unsigned int count) | ||
50 | { | ||
51 | u32 r; | ||
52 | u32 ptr; | ||
53 | |||
54 | del_timer_sync(&idle_timer); | ||
55 | if (rng_idle) { | ||
56 | clk_prepare_enable(rng_clk); | ||
57 | r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT); | ||
58 | if (r != 0) { | ||
59 | clk_disable_unprepare(rng_clk); | ||
60 | pr_err("HW init failed: %d\n", r); | ||
61 | return -EIO; | ||
62 | } | ||
63 | rng_idle = 0; | ||
64 | } | ||
65 | |||
66 | ptr = virt_to_phys(buf); | ||
67 | r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW); | ||
68 | mod_timer(&idle_timer, jiffies + msecs_to_jiffies(500)); | ||
69 | if (r != 0) | ||
70 | return -EINVAL; | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int omap3_rom_rng_data_present(struct hwrng *rng, int wait) | ||
75 | { | ||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | static int omap3_rom_rng_data_read(struct hwrng *rng, u32 *data) | ||
80 | { | ||
81 | int r; | ||
82 | |||
83 | r = omap3_rom_rng_get_random(data, 4); | ||
84 | if (r < 0) | ||
85 | return r; | ||
86 | return 4; | ||
87 | } | ||
88 | |||
89 | static struct hwrng omap3_rom_rng_ops = { | ||
90 | .name = "omap3-rom", | ||
91 | .data_present = omap3_rom_rng_data_present, | ||
92 | .data_read = omap3_rom_rng_data_read, | ||
93 | }; | ||
94 | |||
95 | static int omap3_rom_rng_probe(struct platform_device *pdev) | ||
96 | { | ||
97 | pr_info("initializing\n"); | ||
98 | |||
99 | omap3_rom_rng_call = pdev->dev.platform_data; | ||
100 | if (!omap3_rom_rng_call) { | ||
101 | pr_err("omap3_rom_rng_call is NULL\n"); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | |||
105 | setup_timer(&idle_timer, omap3_rom_rng_idle, 0); | ||
106 | rng_clk = clk_get(&pdev->dev, "ick"); | ||
107 | if (IS_ERR(rng_clk)) { | ||
108 | pr_err("unable to get RNG clock\n"); | ||
109 | return PTR_ERR(rng_clk); | ||
110 | } | ||
111 | |||
112 | /* Leave the RNG in reset state. */ | ||
113 | clk_prepare_enable(rng_clk); | ||
114 | omap3_rom_rng_idle(0); | ||
115 | |||
116 | return hwrng_register(&omap3_rom_rng_ops); | ||
117 | } | ||
118 | |||
119 | static int omap3_rom_rng_remove(struct platform_device *pdev) | ||
120 | { | ||
121 | hwrng_unregister(&omap3_rom_rng_ops); | ||
122 | clk_disable_unprepare(rng_clk); | ||
123 | clk_put(rng_clk); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static struct platform_driver omap3_rom_rng_driver = { | ||
128 | .driver = { | ||
129 | .name = "omap3-rom-rng", | ||
130 | .owner = THIS_MODULE, | ||
131 | }, | ||
132 | .probe = omap3_rom_rng_probe, | ||
133 | .remove = omap3_rom_rng_remove, | ||
134 | }; | ||
135 | |||
136 | module_platform_driver(omap3_rom_rng_driver); | ||
137 | |||
138 | MODULE_ALIAS("platform:omap3-rom-rng"); | ||
139 | MODULE_AUTHOR("Juha Yrjola"); | ||
140 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); | ||
141 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index c6df5b29af08..c66279bb6ef3 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/hw_random.h> | 25 | #include <linux/hw_random.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/of_address.h> | ||
27 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
29 | 30 | ||
diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c index 973b95113edf..3d4c2293c6f5 100644 --- a/drivers/char/hw_random/picoxcell-rng.c +++ b/drivers/char/hw_random/picoxcell-rng.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | static void __iomem *rng_base; | 34 | static void __iomem *rng_base; |
35 | static struct clk *rng_clk; | 35 | static struct clk *rng_clk; |
36 | struct device *rng_dev; | 36 | static struct device *rng_dev; |
37 | 37 | ||
38 | static inline u32 picoxcell_trng_read_csr(void) | 38 | static inline u32 picoxcell_trng_read_csr(void) |
39 | { | 39 | { |
diff --git a/drivers/char/hw_random/powernv-rng.c b/drivers/char/hw_random/powernv-rng.c new file mode 100644 index 000000000000..3f4f63204560 --- /dev/null +++ b/drivers/char/hw_random/powernv-rng.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Michael Ellerman, Guo Chao, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/random.h> | ||
16 | #include <linux/hw_random.h> | ||
17 | |||
18 | static int powernv_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) | ||
19 | { | ||
20 | unsigned long *buf; | ||
21 | int i, len; | ||
22 | |||
23 | /* We rely on rng_buffer_size() being >= sizeof(unsigned long) */ | ||
24 | len = max / sizeof(unsigned long); | ||
25 | |||
26 | buf = (unsigned long *)data; | ||
27 | |||
28 | for (i = 0; i < len; i++) | ||
29 | powernv_get_random_long(buf++); | ||
30 | |||
31 | return len * sizeof(unsigned long); | ||
32 | } | ||
33 | |||
34 | static struct hwrng powernv_hwrng = { | ||
35 | .name = "powernv-rng", | ||
36 | .read = powernv_rng_read, | ||
37 | }; | ||
38 | |||
39 | static int powernv_rng_remove(struct platform_device *pdev) | ||
40 | { | ||
41 | hwrng_unregister(&powernv_hwrng); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static int powernv_rng_probe(struct platform_device *pdev) | ||
47 | { | ||
48 | int rc; | ||
49 | |||
50 | rc = hwrng_register(&powernv_hwrng); | ||
51 | if (rc) { | ||
52 | /* We only register one device, ignore any others */ | ||
53 | if (rc == -EEXIST) | ||
54 | rc = -ENODEV; | ||
55 | |||
56 | return rc; | ||
57 | } | ||
58 | |||
59 | pr_info("Registered powernv hwrng.\n"); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static struct of_device_id powernv_rng_match[] = { | ||
65 | { .compatible = "ibm,power-rng",}, | ||
66 | {}, | ||
67 | }; | ||
68 | MODULE_DEVICE_TABLE(of, powernv_rng_match); | ||
69 | |||
70 | static struct platform_driver powernv_rng_driver = { | ||
71 | .driver = { | ||
72 | .name = "powernv_rng", | ||
73 | .of_match_table = powernv_rng_match, | ||
74 | }, | ||
75 | .probe = powernv_rng_probe, | ||
76 | .remove = powernv_rng_remove, | ||
77 | }; | ||
78 | module_platform_driver(powernv_rng_driver); | ||
79 | |||
80 | MODULE_LICENSE("GPL"); | ||
81 | MODULE_DESCRIPTION("Bare metal HWRNG driver for POWER7+ and above"); | ||
diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c index 732c330805fd..521f76b0934b 100644 --- a/drivers/char/hw_random/ppc4xx-rng.c +++ b/drivers/char/hw_random/ppc4xx-rng.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/hw_random.h> | 14 | #include <linux/hw_random.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/of_address.h> | ||
16 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
18 | 19 | ||
diff --git a/drivers/char/hw_random/pseries-rng.c b/drivers/char/hw_random/pseries-rng.c index 5f1197929f0c..ab7ffdec0ec3 100644 --- a/drivers/char/hw_random/pseries-rng.c +++ b/drivers/char/hw_random/pseries-rng.c | |||
@@ -17,18 +17,25 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
22 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | 23 | #include <linux/module.h> |
21 | #include <linux/hw_random.h> | 24 | #include <linux/hw_random.h> |
22 | #include <asm/vio.h> | 25 | #include <asm/vio.h> |
23 | 26 | ||
24 | #define MODULE_NAME "pseries-rng" | ||
25 | 27 | ||
26 | static int pseries_rng_data_read(struct hwrng *rng, u32 *data) | 28 | static int pseries_rng_data_read(struct hwrng *rng, u32 *data) |
27 | { | 29 | { |
28 | if (plpar_hcall(H_RANDOM, (unsigned long *)data) != H_SUCCESS) { | 30 | int rc; |
29 | printk(KERN_ERR "pseries rng hcall error\n"); | 31 | |
30 | return 0; | 32 | rc = plpar_hcall(H_RANDOM, (unsigned long *)data); |
33 | if (rc != H_SUCCESS) { | ||
34 | pr_err_ratelimited("H_RANDOM call failed %d\n", rc); | ||
35 | return -EIO; | ||
31 | } | 36 | } |
37 | |||
38 | /* The hypervisor interface returns 64 bits */ | ||
32 | return 8; | 39 | return 8; |
33 | } | 40 | } |
34 | 41 | ||
@@ -47,7 +54,7 @@ static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev) | |||
47 | }; | 54 | }; |
48 | 55 | ||
49 | static struct hwrng pseries_rng = { | 56 | static struct hwrng pseries_rng = { |
50 | .name = MODULE_NAME, | 57 | .name = KBUILD_MODNAME, |
51 | .data_read = pseries_rng_data_read, | 58 | .data_read = pseries_rng_data_read, |
52 | }; | 59 | }; |
53 | 60 | ||
@@ -70,7 +77,7 @@ static struct vio_device_id pseries_rng_driver_ids[] = { | |||
70 | MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids); | 77 | MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids); |
71 | 78 | ||
72 | static struct vio_driver pseries_rng_driver = { | 79 | static struct vio_driver pseries_rng_driver = { |
73 | .name = MODULE_NAME, | 80 | .name = KBUILD_MODNAME, |
74 | .probe = pseries_rng_probe, | 81 | .probe = pseries_rng_probe, |
75 | .remove = pseries_rng_remove, | 82 | .remove = pseries_rng_remove, |
76 | .get_desired_dma = pseries_rng_get_desired_dma, | 83 | .get_desired_dma = pseries_rng_get_desired_dma, |
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index d2120ba8f3f9..73ce739f8e19 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c | |||
@@ -79,7 +79,7 @@ static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data) | |||
79 | priv->expires = cur + delay; | 79 | priv->expires = cur + delay; |
80 | priv->present = 0; | 80 | priv->present = 0; |
81 | 81 | ||
82 | INIT_COMPLETION(priv->completion); | 82 | reinit_completion(&priv->completion); |
83 | mod_timer(&priv->timer, priv->expires); | 83 | mod_timer(&priv->timer, priv->expires); |
84 | 84 | ||
85 | return 4; | 85 | return 4; |
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c index 00593c847cf0..09c5fbea2b93 100644 --- a/drivers/char/hw_random/tx4939-rng.c +++ b/drivers/char/hw_random/tx4939-rng.c | |||
@@ -110,12 +110,10 @@ static int __init tx4939_rng_probe(struct platform_device *dev) | |||
110 | struct resource *r; | 110 | struct resource *r; |
111 | int i; | 111 | int i; |
112 | 112 | ||
113 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
114 | if (!r) | ||
115 | return -EBUSY; | ||
116 | rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); | 113 | rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); |
117 | if (!rngdev) | 114 | if (!rngdev) |
118 | return -ENOMEM; | 115 | return -ENOMEM; |
116 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
119 | rngdev->base = devm_ioremap_resource(&dev->dev, r); | 117 | rngdev->base = devm_ioremap_resource(&dev->dev, r); |
120 | if (IS_ERR(rngdev->base)) | 118 | if (IS_ERR(rngdev->base)) |
121 | return PTR_ERR(rngdev->base); | 119 | return PTR_ERR(rngdev->base); |
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index d0387a84eec1..de5a6dcfb3e2 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/hw_random.h> | 30 | #include <linux/hw_random.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <asm/cpu_device_id.h> | ||
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | #include <asm/msr.h> | 34 | #include <asm/msr.h> |
34 | #include <asm/cpufeature.h> | 35 | #include <asm/cpufeature.h> |
@@ -220,5 +221,11 @@ static void __exit mod_exit(void) | |||
220 | module_init(mod_init); | 221 | module_init(mod_init); |
221 | module_exit(mod_exit); | 222 | module_exit(mod_exit); |
222 | 223 | ||
224 | static struct x86_cpu_id __maybe_unused via_rng_cpu_id[] = { | ||
225 | X86_FEATURE_MATCH(X86_FEATURE_XSTORE), | ||
226 | {} | ||
227 | }; | ||
228 | |||
223 | MODULE_DESCRIPTION("H/W RNG driver for VIA CPU with PadLock"); | 229 | MODULE_DESCRIPTION("H/W RNG driver for VIA CPU with PadLock"); |
224 | MODULE_LICENSE("GPL"); | 230 | MODULE_LICENSE("GPL"); |
231 | MODULE_DEVICE_TABLE(x86cpu, via_rng_cpu_id); | ||
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index ef46a9cfd832..c12398d1517c 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -133,7 +133,7 @@ static void virtrng_remove(struct virtio_device *vdev) | |||
133 | remove_common(vdev); | 133 | remove_common(vdev); |
134 | } | 134 | } |
135 | 135 | ||
136 | #ifdef CONFIG_PM | 136 | #ifdef CONFIG_PM_SLEEP |
137 | static int virtrng_freeze(struct virtio_device *vdev) | 137 | static int virtrng_freeze(struct virtio_device *vdev) |
138 | { | 138 | { |
139 | remove_common(vdev); | 139 | remove_common(vdev); |
@@ -157,7 +157,7 @@ static struct virtio_driver virtio_rng_driver = { | |||
157 | .id_table = id_table, | 157 | .id_table = id_table, |
158 | .probe = virtrng_probe, | 158 | .probe = virtrng_probe, |
159 | .remove = virtrng_remove, | 159 | .remove = virtrng_remove, |
160 | #ifdef CONFIG_PM | 160 | #ifdef CONFIG_PM_SLEEP |
161 | .freeze = virtrng_freeze, | 161 | .freeze = virtrng_freeze, |
162 | .restore = virtrng_restore, | 162 | .restore = virtrng_restore, |
163 | #endif | 163 | #endif |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 40cc0cf2ded6..e6939e13e338 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -664,6 +664,13 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = { | |||
664 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"), | 664 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"), |
665 | }, | 665 | }, |
666 | }, | 666 | }, |
667 | { | ||
668 | .ident = "Dell XPS421", | ||
669 | .matches = { | ||
670 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
671 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), | ||
672 | }, | ||
673 | }, | ||
667 | { } | 674 | { } |
668 | }; | 675 | }; |
669 | 676 | ||
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 190d4423653f..ffa97d261cf3 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -114,7 +114,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
114 | int minor = iminor(inode); | 114 | int minor = iminor(inode); |
115 | struct miscdevice *c; | 115 | struct miscdevice *c; |
116 | int err = -ENODEV; | 116 | int err = -ENODEV; |
117 | const struct file_operations *old_fops, *new_fops = NULL; | 117 | const struct file_operations *new_fops = NULL; |
118 | 118 | ||
119 | mutex_lock(&misc_mtx); | 119 | mutex_lock(&misc_mtx); |
120 | 120 | ||
@@ -141,17 +141,11 @@ static int misc_open(struct inode * inode, struct file * file) | |||
141 | } | 141 | } |
142 | 142 | ||
143 | err = 0; | 143 | err = 0; |
144 | old_fops = file->f_op; | 144 | replace_fops(file, new_fops); |
145 | file->f_op = new_fops; | ||
146 | if (file->f_op->open) { | 145 | if (file->f_op->open) { |
147 | file->private_data = c; | 146 | file->private_data = c; |
148 | err=file->f_op->open(inode,file); | 147 | err = file->f_op->open(inode,file); |
149 | if (err) { | ||
150 | fops_put(file->f_op); | ||
151 | file->f_op = fops_get(old_fops); | ||
152 | } | ||
153 | } | 148 | } |
154 | fops_put(old_fops); | ||
155 | fail: | 149 | fail: |
156 | mutex_unlock(&misc_mtx); | 150 | mutex_unlock(&misc_mtx); |
157 | return err; | 151 | return err; |
@@ -193,8 +187,8 @@ int misc_register(struct miscdevice * misc) | |||
193 | if (misc->minor == MISC_DYNAMIC_MINOR) { | 187 | if (misc->minor == MISC_DYNAMIC_MINOR) { |
194 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); | 188 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); |
195 | if (i >= DYNAMIC_MINORS) { | 189 | if (i >= DYNAMIC_MINORS) { |
196 | mutex_unlock(&misc_mtx); | 190 | err = -EBUSY; |
197 | return -EBUSY; | 191 | goto out; |
198 | } | 192 | } |
199 | misc->minor = DYNAMIC_MINORS - i - 1; | 193 | misc->minor = DYNAMIC_MINORS - i - 1; |
200 | set_bit(i, misc_minors); | 194 | set_bit(i, misc_minors); |
@@ -203,8 +197,8 @@ int misc_register(struct miscdevice * misc) | |||
203 | 197 | ||
204 | list_for_each_entry(c, &misc_list, list) { | 198 | list_for_each_entry(c, &misc_list, list) { |
205 | if (c->minor == misc->minor) { | 199 | if (c->minor == misc->minor) { |
206 | mutex_unlock(&misc_mtx); | 200 | err = -EBUSY; |
207 | return -EBUSY; | 201 | goto out; |
208 | } | 202 | } |
209 | } | 203 | } |
210 | } | 204 | } |
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index cfdfe493c6af..1fd00dc06897 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c | |||
@@ -220,7 +220,7 @@ static int __init nwbutton_init(void) | |||
220 | return -EBUSY; | 220 | return -EBUSY; |
221 | } | 221 | } |
222 | 222 | ||
223 | if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, IRQF_DISABLED, | 223 | if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, 0, |
224 | "nwbutton", NULL)) { | 224 | "nwbutton", NULL)) { |
225 | printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n", | 225 | printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n", |
226 | IRQ_NETWINDER_BUTTON); | 226 | IRQ_NETWINDER_BUTTON); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 0d91fe52f3f5..429b75bb60e8 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -255,10 +255,8 @@ | |||
255 | #include <linux/fips.h> | 255 | #include <linux/fips.h> |
256 | #include <linux/ptrace.h> | 256 | #include <linux/ptrace.h> |
257 | #include <linux/kmemcheck.h> | 257 | #include <linux/kmemcheck.h> |
258 | 258 | #include <linux/workqueue.h> | |
259 | #ifdef CONFIG_GENERIC_HARDIRQS | 259 | #include <linux/irq.h> |
260 | # include <linux/irq.h> | ||
261 | #endif | ||
262 | 260 | ||
263 | #include <asm/processor.h> | 261 | #include <asm/processor.h> |
264 | #include <asm/uaccess.h> | 262 | #include <asm/uaccess.h> |
@@ -272,14 +270,28 @@ | |||
272 | /* | 270 | /* |
273 | * Configuration information | 271 | * Configuration information |
274 | */ | 272 | */ |
275 | #define INPUT_POOL_WORDS 128 | 273 | #define INPUT_POOL_SHIFT 12 |
276 | #define OUTPUT_POOL_WORDS 32 | 274 | #define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5)) |
277 | #define SEC_XFER_SIZE 512 | 275 | #define OUTPUT_POOL_SHIFT 10 |
278 | #define EXTRACT_SIZE 10 | 276 | #define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5)) |
277 | #define SEC_XFER_SIZE 512 | ||
278 | #define EXTRACT_SIZE 10 | ||
279 | |||
280 | #define DEBUG_RANDOM_BOOT 0 | ||
279 | 281 | ||
280 | #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) | 282 | #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) |
281 | 283 | ||
282 | /* | 284 | /* |
285 | * To allow fractional bits to be tracked, the entropy_count field is | ||
286 | * denominated in units of 1/8th bits. | ||
287 | * | ||
288 | * 2*(ENTROPY_SHIFT + log2(poolbits)) must <= 31, or the multiply in | ||
289 | * credit_entropy_bits() needs to be 64 bits wide. | ||
290 | */ | ||
291 | #define ENTROPY_SHIFT 3 | ||
292 | #define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT) | ||
293 | |||
294 | /* | ||
283 | * The minimum number of bits of entropy before we wake up a read on | 295 | * The minimum number of bits of entropy before we wake up a read on |
284 | * /dev/random. Should be enough to do a significant reseed. | 296 | * /dev/random. Should be enough to do a significant reseed. |
285 | */ | 297 | */ |
@@ -290,108 +302,100 @@ static int random_read_wakeup_thresh = 64; | |||
290 | * should wake up processes which are selecting or polling on write | 302 | * should wake up processes which are selecting or polling on write |
291 | * access to /dev/random. | 303 | * access to /dev/random. |
292 | */ | 304 | */ |
293 | static int random_write_wakeup_thresh = 128; | 305 | static int random_write_wakeup_thresh = 28 * OUTPUT_POOL_WORDS; |
294 | 306 | ||
295 | /* | 307 | /* |
296 | * When the input pool goes over trickle_thresh, start dropping most | 308 | * The minimum number of seconds between urandom pool resending. We |
297 | * samples to avoid wasting CPU time and reduce lock contention. | 309 | * do this to limit the amount of entropy that can be drained from the |
310 | * input pool even if there are heavy demands on /dev/urandom. | ||
298 | */ | 311 | */ |
299 | 312 | static int random_min_urandom_seed = 60; | |
300 | static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28; | ||
301 | |||
302 | static DEFINE_PER_CPU(int, trickle_count); | ||
303 | 313 | ||
304 | /* | 314 | /* |
305 | * A pool of size .poolwords is stirred with a primitive polynomial | 315 | * Originally, we used a primitive polynomial of degree .poolwords |
306 | * of degree .poolwords over GF(2). The taps for various sizes are | 316 | * over GF(2). The taps for various sizes are defined below. They |
307 | * defined below. They are chosen to be evenly spaced (minimum RMS | 317 | * were chosen to be evenly spaced except for the last tap, which is 1 |
308 | * distance from evenly spaced; the numbers in the comments are a | 318 | * to get the twisting happening as fast as possible. |
309 | * scaled squared error sum) except for the last tap, which is 1 to | 319 | * |
310 | * get the twisting happening as fast as possible. | 320 | * For the purposes of better mixing, we use the CRC-32 polynomial as |
321 | * well to make a (modified) twisted Generalized Feedback Shift | ||
322 | * Register. (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR | ||
323 | * generators. ACM Transactions on Modeling and Computer Simulation | ||
324 | * 2(3):179-194. Also see M. Matsumoto & Y. Kurita, 1994. Twisted | ||
325 | * GFSR generators II. ACM Transactions on Mdeling and Computer | ||
326 | * Simulation 4:254-266) | ||
327 | * | ||
328 | * Thanks to Colin Plumb for suggesting this. | ||
329 | * | ||
330 | * The mixing operation is much less sensitive than the output hash, | ||
331 | * where we use SHA-1. All that we want of mixing operation is that | ||
332 | * it be a good non-cryptographic hash; i.e. it not produce collisions | ||
333 | * when fed "random" data of the sort we expect to see. As long as | ||
334 | * the pool state differs for different inputs, we have preserved the | ||
335 | * input entropy and done a good job. The fact that an intelligent | ||
336 | * attacker can construct inputs that will produce controlled | ||
337 | * alterations to the pool's state is not important because we don't | ||
338 | * consider such inputs to contribute any randomness. The only | ||
339 | * property we need with respect to them is that the attacker can't | ||
340 | * increase his/her knowledge of the pool's state. Since all | ||
341 | * additions are reversible (knowing the final state and the input, | ||
342 | * you can reconstruct the initial state), if an attacker has any | ||
343 | * uncertainty about the initial state, he/she can only shuffle that | ||
344 | * uncertainty about, but never cause any collisions (which would | ||
345 | * decrease the uncertainty). | ||
346 | * | ||
347 | * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and | ||
348 | * Videau in their paper, "The Linux Pseudorandom Number Generator | ||
349 | * Revisited" (see: http://eprint.iacr.org/2012/251.pdf). In their | ||
350 | * paper, they point out that we are not using a true Twisted GFSR, | ||
351 | * since Matsumoto & Kurita used a trinomial feedback polynomial (that | ||
352 | * is, with only three taps, instead of the six that we are using). | ||
353 | * As a result, the resulting polynomial is neither primitive nor | ||
354 | * irreducible, and hence does not have a maximal period over | ||
355 | * GF(2**32). They suggest a slight change to the generator | ||
356 | * polynomial which improves the resulting TGFSR polynomial to be | ||
357 | * irreducible, which we have made here. | ||
311 | */ | 358 | */ |
312 | static struct poolinfo { | 359 | static struct poolinfo { |
313 | int poolwords; | 360 | int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits; |
361 | #define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5) | ||
314 | int tap1, tap2, tap3, tap4, tap5; | 362 | int tap1, tap2, tap3, tap4, tap5; |
315 | } poolinfo_table[] = { | 363 | } poolinfo_table[] = { |
316 | /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ | 364 | /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */ |
317 | { 128, 103, 76, 51, 25, 1 }, | 365 | /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */ |
318 | /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ | 366 | { S(128), 104, 76, 51, 25, 1 }, |
319 | { 32, 26, 20, 14, 7, 1 }, | 367 | /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */ |
368 | /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */ | ||
369 | { S(32), 26, 19, 14, 7, 1 }, | ||
320 | #if 0 | 370 | #if 0 |
321 | /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ | 371 | /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ |
322 | { 2048, 1638, 1231, 819, 411, 1 }, | 372 | { S(2048), 1638, 1231, 819, 411, 1 }, |
323 | 373 | ||
324 | /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ | 374 | /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ |
325 | { 1024, 817, 615, 412, 204, 1 }, | 375 | { S(1024), 817, 615, 412, 204, 1 }, |
326 | 376 | ||
327 | /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ | 377 | /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ |
328 | { 1024, 819, 616, 410, 207, 2 }, | 378 | { S(1024), 819, 616, 410, 207, 2 }, |
329 | 379 | ||
330 | /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ | 380 | /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ |
331 | { 512, 411, 308, 208, 104, 1 }, | 381 | { S(512), 411, 308, 208, 104, 1 }, |
332 | 382 | ||
333 | /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ | 383 | /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ |
334 | { 512, 409, 307, 206, 102, 2 }, | 384 | { S(512), 409, 307, 206, 102, 2 }, |
335 | /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ | 385 | /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ |
336 | { 512, 409, 309, 205, 103, 2 }, | 386 | { S(512), 409, 309, 205, 103, 2 }, |
337 | 387 | ||
338 | /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ | 388 | /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ |
339 | { 256, 205, 155, 101, 52, 1 }, | 389 | { S(256), 205, 155, 101, 52, 1 }, |
340 | 390 | ||
341 | /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ | 391 | /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ |
342 | { 128, 103, 78, 51, 27, 2 }, | 392 | { S(128), 103, 78, 51, 27, 2 }, |
343 | 393 | ||
344 | /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ | 394 | /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ |
345 | { 64, 52, 39, 26, 14, 1 }, | 395 | { S(64), 52, 39, 26, 14, 1 }, |
346 | #endif | 396 | #endif |
347 | }; | 397 | }; |
348 | 398 | ||
349 | #define POOLBITS poolwords*32 | ||
350 | #define POOLBYTES poolwords*4 | ||
351 | |||
352 | /* | ||
353 | * For the purposes of better mixing, we use the CRC-32 polynomial as | ||
354 | * well to make a twisted Generalized Feedback Shift Reigster | ||
355 | * | ||
356 | * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM | ||
357 | * Transactions on Modeling and Computer Simulation 2(3):179-194. | ||
358 | * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators | ||
359 | * II. ACM Transactions on Mdeling and Computer Simulation 4:254-266) | ||
360 | * | ||
361 | * Thanks to Colin Plumb for suggesting this. | ||
362 | * | ||
363 | * We have not analyzed the resultant polynomial to prove it primitive; | ||
364 | * in fact it almost certainly isn't. Nonetheless, the irreducible factors | ||
365 | * of a random large-degree polynomial over GF(2) are more than large enough | ||
366 | * that periodicity is not a concern. | ||
367 | * | ||
368 | * The input hash is much less sensitive than the output hash. All | ||
369 | * that we want of it is that it be a good non-cryptographic hash; | ||
370 | * i.e. it not produce collisions when fed "random" data of the sort | ||
371 | * we expect to see. As long as the pool state differs for different | ||
372 | * inputs, we have preserved the input entropy and done a good job. | ||
373 | * The fact that an intelligent attacker can construct inputs that | ||
374 | * will produce controlled alterations to the pool's state is not | ||
375 | * important because we don't consider such inputs to contribute any | ||
376 | * randomness. The only property we need with respect to them is that | ||
377 | * the attacker can't increase his/her knowledge of the pool's state. | ||
378 | * Since all additions are reversible (knowing the final state and the | ||
379 | * input, you can reconstruct the initial state), if an attacker has | ||
380 | * any uncertainty about the initial state, he/she can only shuffle | ||
381 | * that uncertainty about, but never cause any collisions (which would | ||
382 | * decrease the uncertainty). | ||
383 | * | ||
384 | * The chosen system lets the state of the pool be (essentially) the input | ||
385 | * modulo the generator polymnomial. Now, for random primitive polynomials, | ||
386 | * this is a universal class of hash functions, meaning that the chance | ||
387 | * of a collision is limited by the attacker's knowledge of the generator | ||
388 | * polynomail, so if it is chosen at random, an attacker can never force | ||
389 | * a collision. Here, we use a fixed polynomial, but we *can* assume that | ||
390 | * ###--> it is unknown to the processes generating the input entropy. <-### | ||
391 | * Because of this important property, this is a good, collision-resistant | ||
392 | * hash; hash collisions will occur no more often than chance. | ||
393 | */ | ||
394 | |||
395 | /* | 399 | /* |
396 | * Static global variables | 400 | * Static global variables |
397 | */ | 401 | */ |
@@ -399,17 +403,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); | |||
399 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 403 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
400 | static struct fasync_struct *fasync; | 404 | static struct fasync_struct *fasync; |
401 | 405 | ||
402 | static bool debug; | ||
403 | module_param(debug, bool, 0644); | ||
404 | #define DEBUG_ENT(fmt, arg...) do { \ | ||
405 | if (debug) \ | ||
406 | printk(KERN_DEBUG "random %04d %04d %04d: " \ | ||
407 | fmt,\ | ||
408 | input_pool.entropy_count,\ | ||
409 | blocking_pool.entropy_count,\ | ||
410 | nonblocking_pool.entropy_count,\ | ||
411 | ## arg); } while (0) | ||
412 | |||
413 | /********************************************************************** | 406 | /********************************************************************** |
414 | * | 407 | * |
415 | * OS independent entropy store. Here are the functions which handle | 408 | * OS independent entropy store. Here are the functions which handle |
@@ -420,23 +413,26 @@ module_param(debug, bool, 0644); | |||
420 | struct entropy_store; | 413 | struct entropy_store; |
421 | struct entropy_store { | 414 | struct entropy_store { |
422 | /* read-only data: */ | 415 | /* read-only data: */ |
423 | struct poolinfo *poolinfo; | 416 | const struct poolinfo *poolinfo; |
424 | __u32 *pool; | 417 | __u32 *pool; |
425 | const char *name; | 418 | const char *name; |
426 | struct entropy_store *pull; | 419 | struct entropy_store *pull; |
427 | int limit; | 420 | struct work_struct push_work; |
428 | 421 | ||
429 | /* read-write data: */ | 422 | /* read-write data: */ |
423 | unsigned long last_pulled; | ||
430 | spinlock_t lock; | 424 | spinlock_t lock; |
431 | unsigned add_ptr; | 425 | unsigned short add_ptr; |
432 | unsigned input_rotate; | 426 | unsigned short input_rotate; |
433 | int entropy_count; | 427 | int entropy_count; |
434 | int entropy_total; | 428 | int entropy_total; |
435 | unsigned int initialized:1; | 429 | unsigned int initialized:1; |
436 | bool last_data_init; | 430 | unsigned int limit:1; |
431 | unsigned int last_data_init:1; | ||
437 | __u8 last_data[EXTRACT_SIZE]; | 432 | __u8 last_data[EXTRACT_SIZE]; |
438 | }; | 433 | }; |
439 | 434 | ||
435 | static void push_to_pool(struct work_struct *work); | ||
440 | static __u32 input_pool_data[INPUT_POOL_WORDS]; | 436 | static __u32 input_pool_data[INPUT_POOL_WORDS]; |
441 | static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; | 437 | static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; |
442 | static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; | 438 | static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; |
@@ -455,7 +451,9 @@ static struct entropy_store blocking_pool = { | |||
455 | .limit = 1, | 451 | .limit = 1, |
456 | .pull = &input_pool, | 452 | .pull = &input_pool, |
457 | .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), | 453 | .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), |
458 | .pool = blocking_pool_data | 454 | .pool = blocking_pool_data, |
455 | .push_work = __WORK_INITIALIZER(blocking_pool.push_work, | ||
456 | push_to_pool), | ||
459 | }; | 457 | }; |
460 | 458 | ||
461 | static struct entropy_store nonblocking_pool = { | 459 | static struct entropy_store nonblocking_pool = { |
@@ -463,7 +461,9 @@ static struct entropy_store nonblocking_pool = { | |||
463 | .name = "nonblocking", | 461 | .name = "nonblocking", |
464 | .pull = &input_pool, | 462 | .pull = &input_pool, |
465 | .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), | 463 | .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), |
466 | .pool = nonblocking_pool_data | 464 | .pool = nonblocking_pool_data, |
465 | .push_work = __WORK_INITIALIZER(nonblocking_pool.push_work, | ||
466 | push_to_pool), | ||
467 | }; | 467 | }; |
468 | 468 | ||
469 | static __u32 const twist_table[8] = { | 469 | static __u32 const twist_table[8] = { |
@@ -501,7 +501,7 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, | |||
501 | 501 | ||
502 | /* mix one byte at a time to simplify size handling and churn faster */ | 502 | /* mix one byte at a time to simplify size handling and churn faster */ |
503 | while (nbytes--) { | 503 | while (nbytes--) { |
504 | w = rol32(*bytes++, input_rotate & 31); | 504 | w = rol32(*bytes++, input_rotate); |
505 | i = (i - 1) & wordmask; | 505 | i = (i - 1) & wordmask; |
506 | 506 | ||
507 | /* XOR in the various taps */ | 507 | /* XOR in the various taps */ |
@@ -521,7 +521,7 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, | |||
521 | * rotation, so that successive passes spread the | 521 | * rotation, so that successive passes spread the |
522 | * input bits across the pool evenly. | 522 | * input bits across the pool evenly. |
523 | */ | 523 | */ |
524 | input_rotate += i ? 7 : 14; | 524 | input_rotate = (input_rotate + (i ? 7 : 14)) & 31; |
525 | } | 525 | } |
526 | 526 | ||
527 | ACCESS_ONCE(r->input_rotate) = input_rotate; | 527 | ACCESS_ONCE(r->input_rotate) = input_rotate; |
@@ -564,62 +564,151 @@ struct fast_pool { | |||
564 | * collector. It's hardcoded for an 128 bit pool and assumes that any | 564 | * collector. It's hardcoded for an 128 bit pool and assumes that any |
565 | * locks that might be needed are taken by the caller. | 565 | * locks that might be needed are taken by the caller. |
566 | */ | 566 | */ |
567 | static void fast_mix(struct fast_pool *f, const void *in, int nbytes) | 567 | static void fast_mix(struct fast_pool *f, __u32 input[4]) |
568 | { | 568 | { |
569 | const char *bytes = in; | ||
570 | __u32 w; | 569 | __u32 w; |
571 | unsigned i = f->count; | ||
572 | unsigned input_rotate = f->rotate; | 570 | unsigned input_rotate = f->rotate; |
573 | 571 | ||
574 | while (nbytes--) { | 572 | w = rol32(input[0], input_rotate) ^ f->pool[0] ^ f->pool[3]; |
575 | w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^ | 573 | f->pool[0] = (w >> 3) ^ twist_table[w & 7]; |
576 | f->pool[(i + 1) & 3]; | 574 | input_rotate = (input_rotate + 14) & 31; |
577 | f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7]; | 575 | w = rol32(input[1], input_rotate) ^ f->pool[1] ^ f->pool[0]; |
578 | input_rotate += (i++ & 3) ? 7 : 14; | 576 | f->pool[1] = (w >> 3) ^ twist_table[w & 7]; |
579 | } | 577 | input_rotate = (input_rotate + 7) & 31; |
580 | f->count = i; | 578 | w = rol32(input[2], input_rotate) ^ f->pool[2] ^ f->pool[1]; |
579 | f->pool[2] = (w >> 3) ^ twist_table[w & 7]; | ||
580 | input_rotate = (input_rotate + 7) & 31; | ||
581 | w = rol32(input[3], input_rotate) ^ f->pool[3] ^ f->pool[2]; | ||
582 | f->pool[3] = (w >> 3) ^ twist_table[w & 7]; | ||
583 | input_rotate = (input_rotate + 7) & 31; | ||
584 | |||
581 | f->rotate = input_rotate; | 585 | f->rotate = input_rotate; |
586 | f->count++; | ||
582 | } | 587 | } |
583 | 588 | ||
584 | /* | 589 | /* |
585 | * Credit (or debit) the entropy store with n bits of entropy | 590 | * Credit (or debit) the entropy store with n bits of entropy. |
591 | * Use credit_entropy_bits_safe() if the value comes from userspace | ||
592 | * or otherwise should be checked for extreme values. | ||
586 | */ | 593 | */ |
587 | static void credit_entropy_bits(struct entropy_store *r, int nbits) | 594 | static void credit_entropy_bits(struct entropy_store *r, int nbits) |
588 | { | 595 | { |
589 | int entropy_count, orig; | 596 | int entropy_count, orig; |
597 | const int pool_size = r->poolinfo->poolfracbits; | ||
598 | int nfrac = nbits << ENTROPY_SHIFT; | ||
590 | 599 | ||
591 | if (!nbits) | 600 | if (!nbits) |
592 | return; | 601 | return; |
593 | 602 | ||
594 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); | ||
595 | retry: | 603 | retry: |
596 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 604 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
597 | entropy_count += nbits; | 605 | if (nfrac < 0) { |
606 | /* Debit */ | ||
607 | entropy_count += nfrac; | ||
608 | } else { | ||
609 | /* | ||
610 | * Credit: we have to account for the possibility of | ||
611 | * overwriting already present entropy. Even in the | ||
612 | * ideal case of pure Shannon entropy, new contributions | ||
613 | * approach the full value asymptotically: | ||
614 | * | ||
615 | * entropy <- entropy + (pool_size - entropy) * | ||
616 | * (1 - exp(-add_entropy/pool_size)) | ||
617 | * | ||
618 | * For add_entropy <= pool_size/2 then | ||
619 | * (1 - exp(-add_entropy/pool_size)) >= | ||
620 | * (add_entropy/pool_size)*0.7869... | ||
621 | * so we can approximate the exponential with | ||
622 | * 3/4*add_entropy/pool_size and still be on the | ||
623 | * safe side by adding at most pool_size/2 at a time. | ||
624 | * | ||
625 | * The use of pool_size-2 in the while statement is to | ||
626 | * prevent rounding artifacts from making the loop | ||
627 | * arbitrarily long; this limits the loop to log2(pool_size)*2 | ||
628 | * turns no matter how large nbits is. | ||
629 | */ | ||
630 | int pnfrac = nfrac; | ||
631 | const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2; | ||
632 | /* The +2 corresponds to the /4 in the denominator */ | ||
633 | |||
634 | do { | ||
635 | unsigned int anfrac = min(pnfrac, pool_size/2); | ||
636 | unsigned int add = | ||
637 | ((pool_size - entropy_count)*anfrac*3) >> s; | ||
638 | |||
639 | entropy_count += add; | ||
640 | pnfrac -= anfrac; | ||
641 | } while (unlikely(entropy_count < pool_size-2 && pnfrac)); | ||
642 | } | ||
598 | 643 | ||
599 | if (entropy_count < 0) { | 644 | if (entropy_count < 0) { |
600 | DEBUG_ENT("negative entropy/overflow\n"); | 645 | pr_warn("random: negative entropy/overflow: pool %s count %d\n", |
646 | r->name, entropy_count); | ||
647 | WARN_ON(1); | ||
601 | entropy_count = 0; | 648 | entropy_count = 0; |
602 | } else if (entropy_count > r->poolinfo->POOLBITS) | 649 | } else if (entropy_count > pool_size) |
603 | entropy_count = r->poolinfo->POOLBITS; | 650 | entropy_count = pool_size; |
604 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | 651 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
605 | goto retry; | 652 | goto retry; |
606 | 653 | ||
607 | if (!r->initialized && nbits > 0) { | 654 | r->entropy_total += nbits; |
608 | r->entropy_total += nbits; | 655 | if (!r->initialized && r->entropy_total > 128) { |
609 | if (r->entropy_total > 128) | 656 | r->initialized = 1; |
610 | r->initialized = 1; | 657 | r->entropy_total = 0; |
658 | if (r == &nonblocking_pool) { | ||
659 | prandom_reseed_late(); | ||
660 | pr_notice("random: %s pool is initialized\n", r->name); | ||
661 | } | ||
611 | } | 662 | } |
612 | 663 | ||
613 | trace_credit_entropy_bits(r->name, nbits, entropy_count, | 664 | trace_credit_entropy_bits(r->name, nbits, |
665 | entropy_count >> ENTROPY_SHIFT, | ||
614 | r->entropy_total, _RET_IP_); | 666 | r->entropy_total, _RET_IP_); |
615 | 667 | ||
616 | /* should we wake readers? */ | 668 | if (r == &input_pool) { |
617 | if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { | 669 | int entropy_bytes = entropy_count >> ENTROPY_SHIFT; |
618 | wake_up_interruptible(&random_read_wait); | 670 | |
619 | kill_fasync(&fasync, SIGIO, POLL_IN); | 671 | /* should we wake readers? */ |
672 | if (entropy_bytes >= random_read_wakeup_thresh) { | ||
673 | wake_up_interruptible(&random_read_wait); | ||
674 | kill_fasync(&fasync, SIGIO, POLL_IN); | ||
675 | } | ||
676 | /* If the input pool is getting full, send some | ||
677 | * entropy to the two output pools, flipping back and | ||
678 | * forth between them, until the output pools are 75% | ||
679 | * full. | ||
680 | */ | ||
681 | if (entropy_bytes > random_write_wakeup_thresh && | ||
682 | r->initialized && | ||
683 | r->entropy_total >= 2*random_read_wakeup_thresh) { | ||
684 | static struct entropy_store *last = &blocking_pool; | ||
685 | struct entropy_store *other = &blocking_pool; | ||
686 | |||
687 | if (last == &blocking_pool) | ||
688 | other = &nonblocking_pool; | ||
689 | if (other->entropy_count <= | ||
690 | 3 * other->poolinfo->poolfracbits / 4) | ||
691 | last = other; | ||
692 | if (last->entropy_count <= | ||
693 | 3 * last->poolinfo->poolfracbits / 4) { | ||
694 | schedule_work(&last->push_work); | ||
695 | r->entropy_total = 0; | ||
696 | } | ||
697 | } | ||
620 | } | 698 | } |
621 | } | 699 | } |
622 | 700 | ||
701 | static void credit_entropy_bits_safe(struct entropy_store *r, int nbits) | ||
702 | { | ||
703 | const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); | ||
704 | |||
705 | /* Cap the value to avoid overflows */ | ||
706 | nbits = min(nbits, nbits_max); | ||
707 | nbits = max(nbits, -nbits_max); | ||
708 | |||
709 | credit_entropy_bits(r, nbits); | ||
710 | } | ||
711 | |||
623 | /********************************************************************* | 712 | /********************************************************************* |
624 | * | 713 | * |
625 | * Entropy input management | 714 | * Entropy input management |
@@ -633,6 +722,8 @@ struct timer_rand_state { | |||
633 | unsigned dont_count_entropy:1; | 722 | unsigned dont_count_entropy:1; |
634 | }; | 723 | }; |
635 | 724 | ||
725 | #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; | ||
726 | |||
636 | /* | 727 | /* |
637 | * Add device- or boot-specific data to the input and nonblocking | 728 | * Add device- or boot-specific data to the input and nonblocking |
638 | * pools to help initialize them to unique values. | 729 | * pools to help initialize them to unique values. |
@@ -643,16 +734,23 @@ struct timer_rand_state { | |||
643 | */ | 734 | */ |
644 | void add_device_randomness(const void *buf, unsigned int size) | 735 | void add_device_randomness(const void *buf, unsigned int size) |
645 | { | 736 | { |
646 | unsigned long time = get_cycles() ^ jiffies; | 737 | unsigned long time = random_get_entropy() ^ jiffies; |
738 | unsigned long flags; | ||
739 | |||
740 | trace_add_device_randomness(size, _RET_IP_); | ||
741 | spin_lock_irqsave(&input_pool.lock, flags); | ||
742 | _mix_pool_bytes(&input_pool, buf, size, NULL); | ||
743 | _mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); | ||
744 | spin_unlock_irqrestore(&input_pool.lock, flags); | ||
647 | 745 | ||
648 | mix_pool_bytes(&input_pool, buf, size, NULL); | 746 | spin_lock_irqsave(&nonblocking_pool.lock, flags); |
649 | mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); | 747 | _mix_pool_bytes(&nonblocking_pool, buf, size, NULL); |
650 | mix_pool_bytes(&nonblocking_pool, buf, size, NULL); | 748 | _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); |
651 | mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); | 749 | spin_unlock_irqrestore(&nonblocking_pool.lock, flags); |
652 | } | 750 | } |
653 | EXPORT_SYMBOL(add_device_randomness); | 751 | EXPORT_SYMBOL(add_device_randomness); |
654 | 752 | ||
655 | static struct timer_rand_state input_timer_state; | 753 | static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE; |
656 | 754 | ||
657 | /* | 755 | /* |
658 | * This function adds entropy to the entropy "pool" by using timing | 756 | * This function adds entropy to the entropy "pool" by using timing |
@@ -666,6 +764,7 @@ static struct timer_rand_state input_timer_state; | |||
666 | */ | 764 | */ |
667 | static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | 765 | static void add_timer_randomness(struct timer_rand_state *state, unsigned num) |
668 | { | 766 | { |
767 | struct entropy_store *r; | ||
669 | struct { | 768 | struct { |
670 | long jiffies; | 769 | long jiffies; |
671 | unsigned cycles; | 770 | unsigned cycles; |
@@ -674,15 +773,12 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
674 | long delta, delta2, delta3; | 773 | long delta, delta2, delta3; |
675 | 774 | ||
676 | preempt_disable(); | 775 | preempt_disable(); |
677 | /* if over the trickle threshold, use only 1 in 4096 samples */ | ||
678 | if (input_pool.entropy_count > trickle_thresh && | ||
679 | ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff)) | ||
680 | goto out; | ||
681 | 776 | ||
682 | sample.jiffies = jiffies; | 777 | sample.jiffies = jiffies; |
683 | sample.cycles = get_cycles(); | 778 | sample.cycles = random_get_entropy(); |
684 | sample.num = num; | 779 | sample.num = num; |
685 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); | 780 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; |
781 | mix_pool_bytes(r, &sample, sizeof(sample), NULL); | ||
686 | 782 | ||
687 | /* | 783 | /* |
688 | * Calculate number of bits of randomness we probably added. | 784 | * Calculate number of bits of randomness we probably added. |
@@ -716,10 +812,8 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
716 | * Round down by 1 bit on general principles, | 812 | * Round down by 1 bit on general principles, |
717 | * and limit entropy entimate to 12 bits. | 813 | * and limit entropy entimate to 12 bits. |
718 | */ | 814 | */ |
719 | credit_entropy_bits(&input_pool, | 815 | credit_entropy_bits(r, min_t(int, fls(delta>>1), 11)); |
720 | min_t(int, fls(delta>>1), 11)); | ||
721 | } | 816 | } |
722 | out: | ||
723 | preempt_enable(); | 817 | preempt_enable(); |
724 | } | 818 | } |
725 | 819 | ||
@@ -732,10 +826,10 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
732 | if (value == last_value) | 826 | if (value == last_value) |
733 | return; | 827 | return; |
734 | 828 | ||
735 | DEBUG_ENT("input event\n"); | ||
736 | last_value = value; | 829 | last_value = value; |
737 | add_timer_randomness(&input_timer_state, | 830 | add_timer_randomness(&input_timer_state, |
738 | (type << 4) ^ code ^ (code >> 4) ^ value); | 831 | (type << 4) ^ code ^ (code >> 4) ^ value); |
832 | trace_add_input_randomness(ENTROPY_BITS(&input_pool)); | ||
739 | } | 833 | } |
740 | EXPORT_SYMBOL_GPL(add_input_randomness); | 834 | EXPORT_SYMBOL_GPL(add_input_randomness); |
741 | 835 | ||
@@ -747,20 +841,21 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
747 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); | 841 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); |
748 | struct pt_regs *regs = get_irq_regs(); | 842 | struct pt_regs *regs = get_irq_regs(); |
749 | unsigned long now = jiffies; | 843 | unsigned long now = jiffies; |
750 | __u32 input[4], cycles = get_cycles(); | 844 | cycles_t cycles = random_get_entropy(); |
751 | 845 | __u32 input[4], c_high, j_high; | |
752 | input[0] = cycles ^ jiffies; | 846 | __u64 ip; |
753 | input[1] = irq; | 847 | |
754 | if (regs) { | 848 | c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; |
755 | __u64 ip = instruction_pointer(regs); | 849 | j_high = (sizeof(now) > 4) ? now >> 32 : 0; |
756 | input[2] = ip; | 850 | input[0] = cycles ^ j_high ^ irq; |
757 | input[3] = ip >> 32; | 851 | input[1] = now ^ c_high; |
758 | } | 852 | ip = regs ? instruction_pointer(regs) : _RET_IP_; |
853 | input[2] = ip; | ||
854 | input[3] = ip >> 32; | ||
759 | 855 | ||
760 | fast_mix(fast_pool, input, sizeof(input)); | 856 | fast_mix(fast_pool, input); |
761 | 857 | ||
762 | if ((fast_pool->count & 1023) && | 858 | if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ)) |
763 | !time_after(now, fast_pool->last + HZ)) | ||
764 | return; | 859 | return; |
765 | 860 | ||
766 | fast_pool->last = now; | 861 | fast_pool->last = now; |
@@ -789,10 +884,8 @@ void add_disk_randomness(struct gendisk *disk) | |||
789 | if (!disk || !disk->random) | 884 | if (!disk || !disk->random) |
790 | return; | 885 | return; |
791 | /* first major is 1, so we get >= 0x200 here */ | 886 | /* first major is 1, so we get >= 0x200 here */ |
792 | DEBUG_ENT("disk event %d:%d\n", | ||
793 | MAJOR(disk_devt(disk)), MINOR(disk_devt(disk))); | ||
794 | |||
795 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); | 887 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); |
888 | trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool)); | ||
796 | } | 889 | } |
797 | #endif | 890 | #endif |
798 | 891 | ||
@@ -810,30 +903,58 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
810 | * from the primary pool to the secondary extraction pool. We make | 903 | * from the primary pool to the secondary extraction pool. We make |
811 | * sure we pull enough for a 'catastrophic reseed'. | 904 | * sure we pull enough for a 'catastrophic reseed'. |
812 | */ | 905 | */ |
906 | static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes); | ||
813 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | 907 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
814 | { | 908 | { |
815 | __u32 tmp[OUTPUT_POOL_WORDS]; | 909 | if (r->limit == 0 && random_min_urandom_seed) { |
910 | unsigned long now = jiffies; | ||
816 | 911 | ||
817 | if (r->pull && r->entropy_count < nbytes * 8 && | 912 | if (time_before(now, |
818 | r->entropy_count < r->poolinfo->POOLBITS) { | 913 | r->last_pulled + random_min_urandom_seed * HZ)) |
819 | /* If we're limited, always leave two wakeup worth's BITS */ | 914 | return; |
820 | int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; | 915 | r->last_pulled = now; |
821 | int bytes = nbytes; | ||
822 | |||
823 | /* pull at least as many as BYTES as wakeup BITS */ | ||
824 | bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); | ||
825 | /* but never more than the buffer size */ | ||
826 | bytes = min_t(int, bytes, sizeof(tmp)); | ||
827 | |||
828 | DEBUG_ENT("going to reseed %s with %d bits " | ||
829 | "(%zu of %d requested)\n", | ||
830 | r->name, bytes * 8, nbytes * 8, r->entropy_count); | ||
831 | |||
832 | bytes = extract_entropy(r->pull, tmp, bytes, | ||
833 | random_read_wakeup_thresh / 8, rsvd); | ||
834 | mix_pool_bytes(r, tmp, bytes, NULL); | ||
835 | credit_entropy_bits(r, bytes*8); | ||
836 | } | 916 | } |
917 | if (r->pull && | ||
918 | r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) && | ||
919 | r->entropy_count < r->poolinfo->poolfracbits) | ||
920 | _xfer_secondary_pool(r, nbytes); | ||
921 | } | ||
922 | |||
923 | static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | ||
924 | { | ||
925 | __u32 tmp[OUTPUT_POOL_WORDS]; | ||
926 | |||
927 | /* For /dev/random's pool, always leave two wakeup worth's BITS */ | ||
928 | int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; | ||
929 | int bytes = nbytes; | ||
930 | |||
931 | /* pull at least as many as BYTES as wakeup BITS */ | ||
932 | bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); | ||
933 | /* but never more than the buffer size */ | ||
934 | bytes = min_t(int, bytes, sizeof(tmp)); | ||
935 | |||
936 | trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, | ||
937 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); | ||
938 | bytes = extract_entropy(r->pull, tmp, bytes, | ||
939 | random_read_wakeup_thresh / 8, rsvd); | ||
940 | mix_pool_bytes(r, tmp, bytes, NULL); | ||
941 | credit_entropy_bits(r, bytes*8); | ||
942 | } | ||
943 | |||
944 | /* | ||
945 | * Used as a workqueue function so that when the input pool is getting | ||
946 | * full, we can "spill over" some entropy to the output pools. That | ||
947 | * way the output pools can store some of the excess entropy instead | ||
948 | * of letting it go to waste. | ||
949 | */ | ||
950 | static void push_to_pool(struct work_struct *work) | ||
951 | { | ||
952 | struct entropy_store *r = container_of(work, struct entropy_store, | ||
953 | push_work); | ||
954 | BUG_ON(!r); | ||
955 | _xfer_secondary_pool(r, random_read_wakeup_thresh/8); | ||
956 | trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT, | ||
957 | r->pull->entropy_count >> ENTROPY_SHIFT); | ||
837 | } | 958 | } |
838 | 959 | ||
839 | /* | 960 | /* |
@@ -853,50 +974,48 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
853 | { | 974 | { |
854 | unsigned long flags; | 975 | unsigned long flags; |
855 | int wakeup_write = 0; | 976 | int wakeup_write = 0; |
977 | int have_bytes; | ||
978 | int entropy_count, orig; | ||
979 | size_t ibytes; | ||
856 | 980 | ||
857 | /* Hold lock while accounting */ | 981 | /* Hold lock while accounting */ |
858 | spin_lock_irqsave(&r->lock, flags); | 982 | spin_lock_irqsave(&r->lock, flags); |
859 | 983 | ||
860 | BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); | 984 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); |
861 | DEBUG_ENT("trying to extract %zu bits from %s\n", | ||
862 | nbytes * 8, r->name); | ||
863 | 985 | ||
864 | /* Can we pull enough? */ | 986 | /* Can we pull enough? */ |
865 | if (r->entropy_count / 8 < min + reserved) { | ||
866 | nbytes = 0; | ||
867 | } else { | ||
868 | int entropy_count, orig; | ||
869 | retry: | 987 | retry: |
870 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 988 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
989 | have_bytes = entropy_count >> (ENTROPY_SHIFT + 3); | ||
990 | ibytes = nbytes; | ||
991 | if (have_bytes < min + reserved) { | ||
992 | ibytes = 0; | ||
993 | } else { | ||
871 | /* If limited, never pull more than available */ | 994 | /* If limited, never pull more than available */ |
872 | if (r->limit && nbytes + reserved >= entropy_count / 8) | 995 | if (r->limit && ibytes + reserved >= have_bytes) |
873 | nbytes = entropy_count/8 - reserved; | 996 | ibytes = have_bytes - reserved; |
874 | |||
875 | if (entropy_count / 8 >= nbytes + reserved) { | ||
876 | entropy_count -= nbytes*8; | ||
877 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | ||
878 | goto retry; | ||
879 | } else { | ||
880 | entropy_count = reserved; | ||
881 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | ||
882 | goto retry; | ||
883 | } | ||
884 | 997 | ||
885 | if (entropy_count < random_write_wakeup_thresh) | 998 | if (have_bytes >= ibytes + reserved) |
886 | wakeup_write = 1; | 999 | entropy_count -= ibytes << (ENTROPY_SHIFT + 3); |
887 | } | 1000 | else |
1001 | entropy_count = reserved << (ENTROPY_SHIFT + 3); | ||
888 | 1002 | ||
889 | DEBUG_ENT("debiting %zu entropy credits from %s%s\n", | 1003 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
890 | nbytes * 8, r->name, r->limit ? "" : " (unlimited)"); | 1004 | goto retry; |
891 | 1005 | ||
1006 | if ((r->entropy_count >> ENTROPY_SHIFT) | ||
1007 | < random_write_wakeup_thresh) | ||
1008 | wakeup_write = 1; | ||
1009 | } | ||
892 | spin_unlock_irqrestore(&r->lock, flags); | 1010 | spin_unlock_irqrestore(&r->lock, flags); |
893 | 1011 | ||
1012 | trace_debit_entropy(r->name, 8 * ibytes); | ||
894 | if (wakeup_write) { | 1013 | if (wakeup_write) { |
895 | wake_up_interruptible(&random_write_wait); | 1014 | wake_up_interruptible(&random_write_wait); |
896 | kill_fasync(&fasync, SIGIO, POLL_OUT); | 1015 | kill_fasync(&fasync, SIGIO, POLL_OUT); |
897 | } | 1016 | } |
898 | 1017 | ||
899 | return nbytes; | 1018 | return ibytes; |
900 | } | 1019 | } |
901 | 1020 | ||
902 | static void extract_buf(struct entropy_store *r, __u8 *out) | 1021 | static void extract_buf(struct entropy_store *r, __u8 *out) |
@@ -904,7 +1023,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
904 | int i; | 1023 | int i; |
905 | union { | 1024 | union { |
906 | __u32 w[5]; | 1025 | __u32 w[5]; |
907 | unsigned long l[LONGS(EXTRACT_SIZE)]; | 1026 | unsigned long l[LONGS(20)]; |
908 | } hash; | 1027 | } hash; |
909 | __u32 workspace[SHA_WORKSPACE_WORDS]; | 1028 | __u32 workspace[SHA_WORKSPACE_WORDS]; |
910 | __u8 extract[64]; | 1029 | __u8 extract[64]; |
@@ -917,6 +1036,17 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
917 | sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); | 1036 | sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); |
918 | 1037 | ||
919 | /* | 1038 | /* |
1039 | * If we have a architectural hardware random number | ||
1040 | * generator, mix that in, too. | ||
1041 | */ | ||
1042 | for (i = 0; i < LONGS(20); i++) { | ||
1043 | unsigned long v; | ||
1044 | if (!arch_get_random_long(&v)) | ||
1045 | break; | ||
1046 | hash.l[i] ^= v; | ||
1047 | } | ||
1048 | |||
1049 | /* | ||
920 | * We mix the hash back into the pool to prevent backtracking | 1050 | * We mix the hash back into the pool to prevent backtracking |
921 | * attacks (where the attacker knows the state of the pool | 1051 | * attacks (where the attacker knows the state of the pool |
922 | * plus the current outputs, and attempts to find previous | 1052 | * plus the current outputs, and attempts to find previous |
@@ -945,17 +1075,6 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
945 | hash.w[1] ^= hash.w[4]; | 1075 | hash.w[1] ^= hash.w[4]; |
946 | hash.w[2] ^= rol32(hash.w[2], 16); | 1076 | hash.w[2] ^= rol32(hash.w[2], 16); |
947 | 1077 | ||
948 | /* | ||
949 | * If we have a architectural hardware random number | ||
950 | * generator, mix that in, too. | ||
951 | */ | ||
952 | for (i = 0; i < LONGS(EXTRACT_SIZE); i++) { | ||
953 | unsigned long v; | ||
954 | if (!arch_get_random_long(&v)) | ||
955 | break; | ||
956 | hash.l[i] ^= v; | ||
957 | } | ||
958 | |||
959 | memcpy(out, &hash, EXTRACT_SIZE); | 1078 | memcpy(out, &hash, EXTRACT_SIZE); |
960 | memset(&hash, 0, sizeof(hash)); | 1079 | memset(&hash, 0, sizeof(hash)); |
961 | } | 1080 | } |
@@ -971,10 +1090,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
971 | if (fips_enabled) { | 1090 | if (fips_enabled) { |
972 | spin_lock_irqsave(&r->lock, flags); | 1091 | spin_lock_irqsave(&r->lock, flags); |
973 | if (!r->last_data_init) { | 1092 | if (!r->last_data_init) { |
974 | r->last_data_init = true; | 1093 | r->last_data_init = 1; |
975 | spin_unlock_irqrestore(&r->lock, flags); | 1094 | spin_unlock_irqrestore(&r->lock, flags); |
976 | trace_extract_entropy(r->name, EXTRACT_SIZE, | 1095 | trace_extract_entropy(r->name, EXTRACT_SIZE, |
977 | r->entropy_count, _RET_IP_); | 1096 | ENTROPY_BITS(r), _RET_IP_); |
978 | xfer_secondary_pool(r, EXTRACT_SIZE); | 1097 | xfer_secondary_pool(r, EXTRACT_SIZE); |
979 | extract_buf(r, tmp); | 1098 | extract_buf(r, tmp); |
980 | spin_lock_irqsave(&r->lock, flags); | 1099 | spin_lock_irqsave(&r->lock, flags); |
@@ -983,7 +1102,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
983 | spin_unlock_irqrestore(&r->lock, flags); | 1102 | spin_unlock_irqrestore(&r->lock, flags); |
984 | } | 1103 | } |
985 | 1104 | ||
986 | trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); | 1105 | trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); |
987 | xfer_secondary_pool(r, nbytes); | 1106 | xfer_secondary_pool(r, nbytes); |
988 | nbytes = account(r, nbytes, min, reserved); | 1107 | nbytes = account(r, nbytes, min, reserved); |
989 | 1108 | ||
@@ -1016,7 +1135,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
1016 | ssize_t ret = 0, i; | 1135 | ssize_t ret = 0, i; |
1017 | __u8 tmp[EXTRACT_SIZE]; | 1136 | __u8 tmp[EXTRACT_SIZE]; |
1018 | 1137 | ||
1019 | trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_); | 1138 | trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); |
1020 | xfer_secondary_pool(r, nbytes); | 1139 | xfer_secondary_pool(r, nbytes); |
1021 | nbytes = account(r, nbytes, 0, 0); | 1140 | nbytes = account(r, nbytes, 0, 0); |
1022 | 1141 | ||
@@ -1056,6 +1175,14 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
1056 | */ | 1175 | */ |
1057 | void get_random_bytes(void *buf, int nbytes) | 1176 | void get_random_bytes(void *buf, int nbytes) |
1058 | { | 1177 | { |
1178 | #if DEBUG_RANDOM_BOOT > 0 | ||
1179 | if (unlikely(nonblocking_pool.initialized == 0)) | ||
1180 | printk(KERN_NOTICE "random: %pF get_random_bytes called " | ||
1181 | "with %d bits of entropy available\n", | ||
1182 | (void *) _RET_IP_, | ||
1183 | nonblocking_pool.entropy_total); | ||
1184 | #endif | ||
1185 | trace_get_random_bytes(nbytes, _RET_IP_); | ||
1059 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); | 1186 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); |
1060 | } | 1187 | } |
1061 | EXPORT_SYMBOL(get_random_bytes); | 1188 | EXPORT_SYMBOL(get_random_bytes); |
@@ -1074,7 +1201,7 @@ void get_random_bytes_arch(void *buf, int nbytes) | |||
1074 | { | 1201 | { |
1075 | char *p = buf; | 1202 | char *p = buf; |
1076 | 1203 | ||
1077 | trace_get_random_bytes(nbytes, _RET_IP_); | 1204 | trace_get_random_bytes_arch(nbytes, _RET_IP_); |
1078 | while (nbytes) { | 1205 | while (nbytes) { |
1079 | unsigned long v; | 1206 | unsigned long v; |
1080 | int chunk = min(nbytes, (int)sizeof(unsigned long)); | 1207 | int chunk = min(nbytes, (int)sizeof(unsigned long)); |
@@ -1108,13 +1235,11 @@ static void init_std_data(struct entropy_store *r) | |||
1108 | ktime_t now = ktime_get_real(); | 1235 | ktime_t now = ktime_get_real(); |
1109 | unsigned long rv; | 1236 | unsigned long rv; |
1110 | 1237 | ||
1111 | r->entropy_count = 0; | 1238 | r->last_pulled = jiffies; |
1112 | r->entropy_total = 0; | ||
1113 | r->last_data_init = false; | ||
1114 | mix_pool_bytes(r, &now, sizeof(now), NULL); | 1239 | mix_pool_bytes(r, &now, sizeof(now), NULL); |
1115 | for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { | 1240 | for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { |
1116 | if (!arch_get_random_long(&rv)) | 1241 | if (!arch_get_random_long(&rv)) |
1117 | break; | 1242 | rv = random_get_entropy(); |
1118 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); | 1243 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); |
1119 | } | 1244 | } |
1120 | mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); | 1245 | mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); |
@@ -1137,7 +1262,7 @@ static int rand_initialize(void) | |||
1137 | init_std_data(&nonblocking_pool); | 1262 | init_std_data(&nonblocking_pool); |
1138 | return 0; | 1263 | return 0; |
1139 | } | 1264 | } |
1140 | module_init(rand_initialize); | 1265 | early_initcall(rand_initialize); |
1141 | 1266 | ||
1142 | #ifdef CONFIG_BLOCK | 1267 | #ifdef CONFIG_BLOCK |
1143 | void rand_initialize_disk(struct gendisk *disk) | 1268 | void rand_initialize_disk(struct gendisk *disk) |
@@ -1149,8 +1274,10 @@ void rand_initialize_disk(struct gendisk *disk) | |||
1149 | * source. | 1274 | * source. |
1150 | */ | 1275 | */ |
1151 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); | 1276 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); |
1152 | if (state) | 1277 | if (state) { |
1278 | state->last_time = INITIAL_JIFFIES; | ||
1153 | disk->random = state; | 1279 | disk->random = state; |
1280 | } | ||
1154 | } | 1281 | } |
1155 | #endif | 1282 | #endif |
1156 | 1283 | ||
@@ -1167,8 +1294,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1167 | if (n > SEC_XFER_SIZE) | 1294 | if (n > SEC_XFER_SIZE) |
1168 | n = SEC_XFER_SIZE; | 1295 | n = SEC_XFER_SIZE; |
1169 | 1296 | ||
1170 | DEBUG_ENT("reading %zu bits\n", n*8); | ||
1171 | |||
1172 | n = extract_entropy_user(&blocking_pool, buf, n); | 1297 | n = extract_entropy_user(&blocking_pool, buf, n); |
1173 | 1298 | ||
1174 | if (n < 0) { | 1299 | if (n < 0) { |
@@ -1176,8 +1301,9 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1176 | break; | 1301 | break; |
1177 | } | 1302 | } |
1178 | 1303 | ||
1179 | DEBUG_ENT("read got %zd bits (%zd still needed)\n", | 1304 | trace_random_read(n*8, (nbytes-n)*8, |
1180 | n*8, (nbytes-n)*8); | 1305 | ENTROPY_BITS(&blocking_pool), |
1306 | ENTROPY_BITS(&input_pool)); | ||
1181 | 1307 | ||
1182 | if (n == 0) { | 1308 | if (n == 0) { |
1183 | if (file->f_flags & O_NONBLOCK) { | 1309 | if (file->f_flags & O_NONBLOCK) { |
@@ -1185,13 +1311,9 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1185 | break; | 1311 | break; |
1186 | } | 1312 | } |
1187 | 1313 | ||
1188 | DEBUG_ENT("sleeping?\n"); | ||
1189 | |||
1190 | wait_event_interruptible(random_read_wait, | 1314 | wait_event_interruptible(random_read_wait, |
1191 | input_pool.entropy_count >= | 1315 | ENTROPY_BITS(&input_pool) >= |
1192 | random_read_wakeup_thresh); | 1316 | random_read_wakeup_thresh); |
1193 | |||
1194 | DEBUG_ENT("awake\n"); | ||
1195 | 1317 | ||
1196 | if (signal_pending(current)) { | 1318 | if (signal_pending(current)) { |
1197 | retval = -ERESTARTSYS; | 1319 | retval = -ERESTARTSYS; |
@@ -1214,7 +1336,18 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1214 | static ssize_t | 1336 | static ssize_t |
1215 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 1337 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
1216 | { | 1338 | { |
1217 | return extract_entropy_user(&nonblocking_pool, buf, nbytes); | 1339 | int ret; |
1340 | |||
1341 | if (unlikely(nonblocking_pool.initialized == 0)) | ||
1342 | printk_once(KERN_NOTICE "random: %s urandom read " | ||
1343 | "with %d bits of entropy available\n", | ||
1344 | current->comm, nonblocking_pool.entropy_total); | ||
1345 | |||
1346 | ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); | ||
1347 | |||
1348 | trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool), | ||
1349 | ENTROPY_BITS(&input_pool)); | ||
1350 | return ret; | ||
1218 | } | 1351 | } |
1219 | 1352 | ||
1220 | static unsigned int | 1353 | static unsigned int |
@@ -1225,9 +1358,9 @@ random_poll(struct file *file, poll_table * wait) | |||
1225 | poll_wait(file, &random_read_wait, wait); | 1358 | poll_wait(file, &random_read_wait, wait); |
1226 | poll_wait(file, &random_write_wait, wait); | 1359 | poll_wait(file, &random_write_wait, wait); |
1227 | mask = 0; | 1360 | mask = 0; |
1228 | if (input_pool.entropy_count >= random_read_wakeup_thresh) | 1361 | if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_thresh) |
1229 | mask |= POLLIN | POLLRDNORM; | 1362 | mask |= POLLIN | POLLRDNORM; |
1230 | if (input_pool.entropy_count < random_write_wakeup_thresh) | 1363 | if (ENTROPY_BITS(&input_pool) < random_write_wakeup_thresh) |
1231 | mask |= POLLOUT | POLLWRNORM; | 1364 | mask |= POLLOUT | POLLWRNORM; |
1232 | return mask; | 1365 | return mask; |
1233 | } | 1366 | } |
@@ -1278,7 +1411,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1278 | switch (cmd) { | 1411 | switch (cmd) { |
1279 | case RNDGETENTCNT: | 1412 | case RNDGETENTCNT: |
1280 | /* inherently racy, no point locking */ | 1413 | /* inherently racy, no point locking */ |
1281 | if (put_user(input_pool.entropy_count, p)) | 1414 | ent_count = ENTROPY_BITS(&input_pool); |
1415 | if (put_user(ent_count, p)) | ||
1282 | return -EFAULT; | 1416 | return -EFAULT; |
1283 | return 0; | 1417 | return 0; |
1284 | case RNDADDTOENTCNT: | 1418 | case RNDADDTOENTCNT: |
@@ -1286,7 +1420,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1286 | return -EPERM; | 1420 | return -EPERM; |
1287 | if (get_user(ent_count, p)) | 1421 | if (get_user(ent_count, p)) |
1288 | return -EFAULT; | 1422 | return -EFAULT; |
1289 | credit_entropy_bits(&input_pool, ent_count); | 1423 | credit_entropy_bits_safe(&input_pool, ent_count); |
1290 | return 0; | 1424 | return 0; |
1291 | case RNDADDENTROPY: | 1425 | case RNDADDENTROPY: |
1292 | if (!capable(CAP_SYS_ADMIN)) | 1426 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1301,14 +1435,19 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1301 | size); | 1435 | size); |
1302 | if (retval < 0) | 1436 | if (retval < 0) |
1303 | return retval; | 1437 | return retval; |
1304 | credit_entropy_bits(&input_pool, ent_count); | 1438 | credit_entropy_bits_safe(&input_pool, ent_count); |
1305 | return 0; | 1439 | return 0; |
1306 | case RNDZAPENTCNT: | 1440 | case RNDZAPENTCNT: |
1307 | case RNDCLEARPOOL: | 1441 | case RNDCLEARPOOL: |
1308 | /* Clear the entropy pool counters. */ | 1442 | /* |
1443 | * Clear the entropy pool counters. We no longer clear | ||
1444 | * the entropy pool, as that's silly. | ||
1445 | */ | ||
1309 | if (!capable(CAP_SYS_ADMIN)) | 1446 | if (!capable(CAP_SYS_ADMIN)) |
1310 | return -EPERM; | 1447 | return -EPERM; |
1311 | rand_initialize(); | 1448 | input_pool.entropy_count = 0; |
1449 | nonblocking_pool.entropy_count = 0; | ||
1450 | blocking_pool.entropy_count = 0; | ||
1312 | return 0; | 1451 | return 0; |
1313 | default: | 1452 | default: |
1314 | return -EINVAL; | 1453 | return -EINVAL; |
@@ -1408,6 +1547,23 @@ static int proc_do_uuid(struct ctl_table *table, int write, | |||
1408 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); | 1547 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); |
1409 | } | 1548 | } |
1410 | 1549 | ||
1550 | /* | ||
1551 | * Return entropy available scaled to integral bits | ||
1552 | */ | ||
1553 | static int proc_do_entropy(ctl_table *table, int write, | ||
1554 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1555 | { | ||
1556 | ctl_table fake_table; | ||
1557 | int entropy_count; | ||
1558 | |||
1559 | entropy_count = *(int *)table->data >> ENTROPY_SHIFT; | ||
1560 | |||
1561 | fake_table.data = &entropy_count; | ||
1562 | fake_table.maxlen = sizeof(entropy_count); | ||
1563 | |||
1564 | return proc_dointvec(&fake_table, write, buffer, lenp, ppos); | ||
1565 | } | ||
1566 | |||
1411 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; | 1567 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; |
1412 | extern struct ctl_table random_table[]; | 1568 | extern struct ctl_table random_table[]; |
1413 | struct ctl_table random_table[] = { | 1569 | struct ctl_table random_table[] = { |
@@ -1422,7 +1578,7 @@ struct ctl_table random_table[] = { | |||
1422 | .procname = "entropy_avail", | 1578 | .procname = "entropy_avail", |
1423 | .maxlen = sizeof(int), | 1579 | .maxlen = sizeof(int), |
1424 | .mode = 0444, | 1580 | .mode = 0444, |
1425 | .proc_handler = proc_dointvec, | 1581 | .proc_handler = proc_do_entropy, |
1426 | .data = &input_pool.entropy_count, | 1582 | .data = &input_pool.entropy_count, |
1427 | }, | 1583 | }, |
1428 | { | 1584 | { |
@@ -1444,6 +1600,13 @@ struct ctl_table random_table[] = { | |||
1444 | .extra2 = &max_write_thresh, | 1600 | .extra2 = &max_write_thresh, |
1445 | }, | 1601 | }, |
1446 | { | 1602 | { |
1603 | .procname = "urandom_min_reseed_secs", | ||
1604 | .data = &random_min_urandom_seed, | ||
1605 | .maxlen = sizeof(int), | ||
1606 | .mode = 0644, | ||
1607 | .proc_handler = proc_dointvec, | ||
1608 | }, | ||
1609 | { | ||
1447 | .procname = "boot_id", | 1610 | .procname = "boot_id", |
1448 | .data = &sysctl_bootid, | 1611 | .data = &sysctl_bootid, |
1449 | .maxlen = 16, | 1612 | .maxlen = 16, |
@@ -1462,12 +1625,11 @@ struct ctl_table random_table[] = { | |||
1462 | 1625 | ||
1463 | static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | 1626 | static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
1464 | 1627 | ||
1465 | static int __init random_int_secret_init(void) | 1628 | int random_int_secret_init(void) |
1466 | { | 1629 | { |
1467 | get_random_bytes(random_int_secret, sizeof(random_int_secret)); | 1630 | get_random_bytes(random_int_secret, sizeof(random_int_secret)); |
1468 | return 0; | 1631 | return 0; |
1469 | } | 1632 | } |
1470 | late_initcall(random_int_secret_init); | ||
1471 | 1633 | ||
1472 | /* | 1634 | /* |
1473 | * Get a random word for internal kernel use only. Similar to urandom but | 1635 | * Get a random word for internal kernel use only. Similar to urandom but |
@@ -1486,7 +1648,7 @@ unsigned int get_random_int(void) | |||
1486 | 1648 | ||
1487 | hash = get_cpu_var(get_random_int_hash); | 1649 | hash = get_cpu_var(get_random_int_hash); |
1488 | 1650 | ||
1489 | hash[0] += current->pid + jiffies + get_cycles(); | 1651 | hash[0] += current->pid + jiffies + random_get_entropy(); |
1490 | md5_transform(hash, random_int_secret); | 1652 | md5_transform(hash, random_int_secret); |
1491 | ret = hash[0]; | 1653 | ret = hash[0]; |
1492 | put_cpu_var(get_random_int_hash); | 1654 | put_cpu_var(get_random_int_hash); |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index c0cbbd429bdc..35259961cc38 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -227,7 +227,7 @@ static inline unsigned char rtc_is_updating(void) | |||
227 | 227 | ||
228 | #ifdef RTC_IRQ | 228 | #ifdef RTC_IRQ |
229 | /* | 229 | /* |
230 | * A very tiny interrupt handler. It runs with IRQF_DISABLED set, | 230 | * A very tiny interrupt handler. It runs with interrupts disabled, |
231 | * but there is possibility of conflicting with the set_rtc_mmss() | 231 | * but there is possibility of conflicting with the set_rtc_mmss() |
232 | * call (the rtc irq and the timer irq can easily run at the same | 232 | * call (the rtc irq and the timer irq can easily run at the same |
233 | * time in two different CPUs). So we need to serialize | 233 | * time in two different CPUs). So we need to serialize |
@@ -1040,8 +1040,7 @@ no_irq: | |||
1040 | rtc_int_handler_ptr = rtc_interrupt; | 1040 | rtc_int_handler_ptr = rtc_interrupt; |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | if (request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, | 1043 | if (request_irq(RTC_IRQ, rtc_int_handler_ptr, 0, "rtc", NULL)) { |
1044 | "rtc", NULL)) { | ||
1045 | /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ | 1044 | /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ |
1046 | rtc_has_irq = 0; | 1045 | rtc_has_irq = 0; |
1047 | printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); | 1046 | printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 5816b39ff5a9..8bab59292a0d 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -108,8 +108,7 @@ scdrv_open(struct inode *inode, struct file *file) | |||
108 | /* hook this subchannel up to the system controller interrupt */ | 108 | /* hook this subchannel up to the system controller interrupt */ |
109 | mutex_lock(&scdrv_mutex); | 109 | mutex_lock(&scdrv_mutex); |
110 | rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, | 110 | rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, |
111 | IRQF_SHARED | IRQF_DISABLED, | 111 | IRQF_SHARED, SYSCTL_BASENAME, sd); |
112 | SYSCTL_BASENAME, sd); | ||
113 | if (rv) { | 112 | if (rv) { |
114 | ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); | 113 | ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); |
115 | kfree(sd); | 114 | kfree(sd); |
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index ee156948b9f8..59bcefd6ec7c 100644 --- a/drivers/char/snsc_event.c +++ b/drivers/char/snsc_event.c | |||
@@ -292,8 +292,7 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
292 | 292 | ||
293 | /* hook event subchannel up to the system controller interrupt */ | 293 | /* hook event subchannel up to the system controller interrupt */ |
294 | rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt, | 294 | rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt, |
295 | IRQF_SHARED | IRQF_DISABLED, | 295 | IRQF_SHARED, "system controller events", event_sd); |
296 | "system controller events", event_sd); | ||
297 | if (rv) { | 296 | if (rv) { |
298 | printk(KERN_WARNING "%s: irq request failed (%d)\n", | 297 | printk(KERN_WARNING "%s: irq request failed (%d)\n", |
299 | __func__, rv); | 298 | __func__, rv); |
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index e95e0ab0bd87..100cd1de9939 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
@@ -222,7 +222,7 @@ static int tlclk_open(struct inode *inode, struct file *filp) | |||
222 | /* This device is wired through the FPGA IO space of the ATCA blade | 222 | /* This device is wired through the FPGA IO space of the ATCA blade |
223 | * we can't share this IRQ */ | 223 | * we can't share this IRQ */ |
224 | result = request_irq(telclk_interrupt, &tlclk_interrupt, | 224 | result = request_irq(telclk_interrupt, &tlclk_interrupt, |
225 | IRQF_DISABLED, "telco_clock", tlclk_interrupt); | 225 | 0, "telco_clock", tlclk_interrupt); |
226 | if (result == -EBUSY) | 226 | if (result == -EBUSY) |
227 | printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); | 227 | printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); |
228 | else | 228 | else |
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 94c0c74434ea..1a65838888cd 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -33,6 +33,15 @@ config TCG_TIS | |||
33 | from within Linux. To compile this driver as a module, choose | 33 | from within Linux. To compile this driver as a module, choose |
34 | M here; the module will be called tpm_tis. | 34 | M here; the module will be called tpm_tis. |
35 | 35 | ||
36 | config TCG_TIS_I2C_ATMEL | ||
37 | tristate "TPM Interface Specification 1.2 Interface (I2C - Atmel)" | ||
38 | depends on I2C | ||
39 | ---help--- | ||
40 | If you have an Atmel I2C TPM security chip say Yes and it will be | ||
41 | accessible from within Linux. | ||
42 | To compile this driver as a module, choose M here; the module will | ||
43 | be called tpm_tis_i2c_atmel. | ||
44 | |||
36 | config TCG_TIS_I2C_INFINEON | 45 | config TCG_TIS_I2C_INFINEON |
37 | tristate "TPM Interface Specification 1.2 Interface (I2C - Infineon)" | 46 | tristate "TPM Interface Specification 1.2 Interface (I2C - Infineon)" |
38 | depends on I2C | 47 | depends on I2C |
@@ -42,7 +51,17 @@ config TCG_TIS_I2C_INFINEON | |||
42 | Specification 0.20 say Yes and it will be accessible from within | 51 | Specification 0.20 say Yes and it will be accessible from within |
43 | Linux. | 52 | Linux. |
44 | To compile this driver as a module, choose M here; the module | 53 | To compile this driver as a module, choose M here; the module |
45 | will be called tpm_tis_i2c_infineon. | 54 | will be called tpm_i2c_infineon. |
55 | |||
56 | config TCG_TIS_I2C_NUVOTON | ||
57 | tristate "TPM Interface Specification 1.2 Interface (I2C - Nuvoton)" | ||
58 | depends on I2C | ||
59 | ---help--- | ||
60 | If you have a TPM security chip with an I2C interface from | ||
61 | Nuvoton Technology Corp. say Yes and it will be accessible | ||
62 | from within Linux. | ||
63 | To compile this driver as a module, choose M here; the module | ||
64 | will be called tpm_i2c_nuvoton. | ||
46 | 65 | ||
47 | config TCG_NSC | 66 | config TCG_NSC |
48 | tristate "National Semiconductor TPM Interface" | 67 | tristate "National Semiconductor TPM Interface" |
@@ -82,14 +101,14 @@ config TCG_IBMVTPM | |||
82 | as a module, choose M here; the module will be called tpm_ibmvtpm. | 101 | as a module, choose M here; the module will be called tpm_ibmvtpm. |
83 | 102 | ||
84 | config TCG_ST33_I2C | 103 | config TCG_ST33_I2C |
85 | tristate "STMicroelectronics ST33 I2C TPM" | 104 | tristate "STMicroelectronics ST33 I2C TPM" |
86 | depends on I2C | 105 | depends on I2C |
87 | depends on GPIOLIB | 106 | depends on GPIOLIB |
88 | ---help--- | 107 | ---help--- |
89 | If you have a TPM security chip from STMicroelectronics working with | 108 | If you have a TPM security chip from STMicroelectronics working with |
90 | an I2C bus say Yes and it will be accessible from within Linux. | 109 | an I2C bus say Yes and it will be accessible from within Linux. |
91 | To compile this driver as a module, choose M here; the module will be | 110 | To compile this driver as a module, choose M here; the module will be |
92 | called tpm_stm_st33_i2c. | 111 | called tpm_stm_st33_i2c. |
93 | 112 | ||
94 | config TCG_XEN | 113 | config TCG_XEN |
95 | tristate "XEN TPM Interface" | 114 | tristate "XEN TPM Interface" |
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index eb41ff97d0ad..b80a4000daee 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile | |||
@@ -2,17 +2,20 @@ | |||
2 | # Makefile for the kernel tpm device drivers. | 2 | # Makefile for the kernel tpm device drivers. |
3 | # | 3 | # |
4 | obj-$(CONFIG_TCG_TPM) += tpm.o | 4 | obj-$(CONFIG_TCG_TPM) += tpm.o |
5 | tpm-y := tpm-interface.o | ||
6 | tpm-$(CONFIG_ACPI) += tpm_ppi.o | ||
7 | |||
5 | ifdef CONFIG_ACPI | 8 | ifdef CONFIG_ACPI |
6 | obj-$(CONFIG_TCG_TPM) += tpm_bios.o | 9 | tpm-y += tpm_eventlog.o tpm_acpi.o |
7 | tpm_bios-objs += tpm_eventlog.o tpm_acpi.o tpm_ppi.o | ||
8 | else | 10 | else |
9 | ifdef CONFIG_TCG_IBMVTPM | 11 | ifdef CONFIG_TCG_IBMVTPM |
10 | obj-$(CONFIG_TCG_TPM) += tpm_bios.o | 12 | tpm-y += tpm_eventlog.o tpm_of.o |
11 | tpm_bios-objs += tpm_eventlog.o tpm_of.o | ||
12 | endif | 13 | endif |
13 | endif | 14 | endif |
14 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o | 15 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o |
16 | obj-$(CONFIG_TCG_TIS_I2C_ATMEL) += tpm_i2c_atmel.o | ||
15 | obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o | 17 | obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o |
18 | obj-$(CONFIG_TCG_TIS_I2C_NUVOTON) += tpm_i2c_nuvoton.o | ||
16 | obj-$(CONFIG_TCG_NSC) += tpm_nsc.o | 19 | obj-$(CONFIG_TCG_NSC) += tpm_nsc.o |
17 | obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o | 20 | obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o |
18 | obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o | 21 | obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm-interface.c index e3c974a6c522..6ae41d337630 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm-interface.c | |||
@@ -10,13 +10,13 @@ | |||
10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
11 | * | 11 | * |
12 | * Device driver for TCG/TCPA TPM (trusted platform module). | 12 | * Device driver for TCG/TCPA TPM (trusted platform module). |
13 | * Specifications at www.trustedcomputinggroup.org | 13 | * Specifications at www.trustedcomputinggroup.org |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or | 15 | * This program is free software; you can redistribute it and/or |
16 | * modify it under the terms of the GNU General Public License as | 16 | * modify it under the terms of the GNU General Public License as |
17 | * published by the Free Software Foundation, version 2 of the | 17 | * published by the Free Software Foundation, version 2 of the |
18 | * License. | 18 | * License. |
19 | * | 19 | * |
20 | * Note, the TPM chip is not interrupt driven (only polling) | 20 | * Note, the TPM chip is not interrupt driven (only polling) |
21 | * and can have very long timeouts (minutes!). Hence the unusual | 21 | * and can have very long timeouts (minutes!). Hence the unusual |
22 | * calls to msleep. | 22 | * calls to msleep. |
@@ -371,13 +371,14 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
371 | return -ENODATA; | 371 | return -ENODATA; |
372 | if (count > bufsiz) { | 372 | if (count > bufsiz) { |
373 | dev_err(chip->dev, | 373 | dev_err(chip->dev, |
374 | "invalid count value %x %zx \n", count, bufsiz); | 374 | "invalid count value %x %zx\n", count, bufsiz); |
375 | return -E2BIG; | 375 | return -E2BIG; |
376 | } | 376 | } |
377 | 377 | ||
378 | mutex_lock(&chip->tpm_mutex); | 378 | mutex_lock(&chip->tpm_mutex); |
379 | 379 | ||
380 | if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { | 380 | rc = chip->vendor.send(chip, (u8 *) buf, count); |
381 | if (rc < 0) { | ||
381 | dev_err(chip->dev, | 382 | dev_err(chip->dev, |
382 | "tpm_transmit: tpm_send: error %zd\n", rc); | 383 | "tpm_transmit: tpm_send: error %zd\n", rc); |
383 | goto out; | 384 | goto out; |
@@ -444,7 +445,7 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, | |||
444 | { | 445 | { |
445 | int err; | 446 | int err; |
446 | 447 | ||
447 | len = tpm_transmit(chip,(u8 *) cmd, len); | 448 | len = tpm_transmit(chip, (u8 *) cmd, len); |
448 | if (len < 0) | 449 | if (len < 0) |
449 | return len; | 450 | return len; |
450 | else if (len < TPM_HEADER_SIZE) | 451 | else if (len < TPM_HEADER_SIZE) |
@@ -658,7 +659,7 @@ static int tpm_continue_selftest(struct tpm_chip *chip) | |||
658 | return rc; | 659 | return rc; |
659 | } | 660 | } |
660 | 661 | ||
661 | ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, | 662 | ssize_t tpm_show_enabled(struct device *dev, struct device_attribute *attr, |
662 | char *buf) | 663 | char *buf) |
663 | { | 664 | { |
664 | cap_t cap; | 665 | cap_t cap; |
@@ -674,7 +675,7 @@ ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, | |||
674 | } | 675 | } |
675 | EXPORT_SYMBOL_GPL(tpm_show_enabled); | 676 | EXPORT_SYMBOL_GPL(tpm_show_enabled); |
676 | 677 | ||
677 | ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, | 678 | ssize_t tpm_show_active(struct device *dev, struct device_attribute *attr, |
678 | char *buf) | 679 | char *buf) |
679 | { | 680 | { |
680 | cap_t cap; | 681 | cap_t cap; |
@@ -690,7 +691,7 @@ ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, | |||
690 | } | 691 | } |
691 | EXPORT_SYMBOL_GPL(tpm_show_active); | 692 | EXPORT_SYMBOL_GPL(tpm_show_active); |
692 | 693 | ||
693 | ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, | 694 | ssize_t tpm_show_owned(struct device *dev, struct device_attribute *attr, |
694 | char *buf) | 695 | char *buf) |
695 | { | 696 | { |
696 | cap_t cap; | 697 | cap_t cap; |
@@ -706,8 +707,8 @@ ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, | |||
706 | } | 707 | } |
707 | EXPORT_SYMBOL_GPL(tpm_show_owned); | 708 | EXPORT_SYMBOL_GPL(tpm_show_owned); |
708 | 709 | ||
709 | ssize_t tpm_show_temp_deactivated(struct device * dev, | 710 | ssize_t tpm_show_temp_deactivated(struct device *dev, |
710 | struct device_attribute * attr, char *buf) | 711 | struct device_attribute *attr, char *buf) |
711 | { | 712 | { |
712 | cap_t cap; | 713 | cap_t cap; |
713 | ssize_t rc; | 714 | ssize_t rc; |
@@ -769,10 +770,10 @@ static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) | |||
769 | 770 | ||
770 | /** | 771 | /** |
771 | * tpm_pcr_read - read a pcr value | 772 | * tpm_pcr_read - read a pcr value |
772 | * @chip_num: tpm idx # or ANY | 773 | * @chip_num: tpm idx # or ANY |
773 | * @pcr_idx: pcr idx to retrieve | 774 | * @pcr_idx: pcr idx to retrieve |
774 | * @res_buf: TPM_PCR value | 775 | * @res_buf: TPM_PCR value |
775 | * size of res_buf is 20 bytes (or NULL if you don't care) | 776 | * size of res_buf is 20 bytes (or NULL if you don't care) |
776 | * | 777 | * |
777 | * The TPM driver should be built-in, but for whatever reason it | 778 | * The TPM driver should be built-in, but for whatever reason it |
778 | * isn't, protect against the chip disappearing, by incrementing | 779 | * isn't, protect against the chip disappearing, by incrementing |
@@ -794,9 +795,9 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); | |||
794 | 795 | ||
795 | /** | 796 | /** |
796 | * tpm_pcr_extend - extend pcr value with hash | 797 | * tpm_pcr_extend - extend pcr value with hash |
797 | * @chip_num: tpm idx # or AN& | 798 | * @chip_num: tpm idx # or AN& |
798 | * @pcr_idx: pcr idx to extend | 799 | * @pcr_idx: pcr idx to extend |
799 | * @hash: hash value used to extend pcr value | 800 | * @hash: hash value used to extend pcr value |
800 | * | 801 | * |
801 | * The TPM driver should be built-in, but for whatever reason it | 802 | * The TPM driver should be built-in, but for whatever reason it |
802 | * isn't, protect against the chip disappearing, by incrementing | 803 | * isn't, protect against the chip disappearing, by incrementing |
@@ -847,8 +848,7 @@ int tpm_do_selftest(struct tpm_chip *chip) | |||
847 | unsigned long duration; | 848 | unsigned long duration; |
848 | struct tpm_cmd_t cmd; | 849 | struct tpm_cmd_t cmd; |
849 | 850 | ||
850 | duration = tpm_calc_ordinal_duration(chip, | 851 | duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST); |
851 | TPM_ORD_CONTINUE_SELFTEST); | ||
852 | 852 | ||
853 | loops = jiffies_to_msecs(duration) / delay_msec; | 853 | loops = jiffies_to_msecs(duration) / delay_msec; |
854 | 854 | ||
@@ -965,12 +965,12 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
965 | if (err) | 965 | if (err) |
966 | goto out; | 966 | goto out; |
967 | 967 | ||
968 | /* | 968 | /* |
969 | ignore header 10 bytes | 969 | ignore header 10 bytes |
970 | algorithm 32 bits (1 == RSA ) | 970 | algorithm 32 bits (1 == RSA ) |
971 | encscheme 16 bits | 971 | encscheme 16 bits |
972 | sigscheme 16 bits | 972 | sigscheme 16 bits |
973 | parameters (RSA 12->bytes: keybit, #primes, expbit) | 973 | parameters (RSA 12->bytes: keybit, #primes, expbit) |
974 | keylenbytes 32 bits | 974 | keylenbytes 32 bits |
975 | 256 byte modulus | 975 | 256 byte modulus |
976 | ignore checksum 20 bytes | 976 | ignore checksum 20 bytes |
@@ -1020,43 +1020,33 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, | |||
1020 | str += sprintf(str, "Manufacturer: 0x%x\n", | 1020 | str += sprintf(str, "Manufacturer: 0x%x\n", |
1021 | be32_to_cpu(cap.manufacturer_id)); | 1021 | be32_to_cpu(cap.manufacturer_id)); |
1022 | 1022 | ||
1023 | rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, | 1023 | /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ |
1024 | "attempting to determine the 1.1 version"); | ||
1025 | if (rc) | ||
1026 | return 0; | ||
1027 | str += sprintf(str, | ||
1028 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
1029 | cap.tpm_version.Major, cap.tpm_version.Minor, | ||
1030 | cap.tpm_version.revMajor, cap.tpm_version.revMinor); | ||
1031 | return str - buf; | ||
1032 | } | ||
1033 | EXPORT_SYMBOL_GPL(tpm_show_caps); | ||
1034 | |||
1035 | ssize_t tpm_show_caps_1_2(struct device * dev, | ||
1036 | struct device_attribute * attr, char *buf) | ||
1037 | { | ||
1038 | cap_t cap; | ||
1039 | ssize_t rc; | ||
1040 | char *str = buf; | ||
1041 | |||
1042 | rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, | ||
1043 | "attempting to determine the manufacturer"); | ||
1044 | if (rc) | ||
1045 | return 0; | ||
1046 | str += sprintf(str, "Manufacturer: 0x%x\n", | ||
1047 | be32_to_cpu(cap.manufacturer_id)); | ||
1048 | rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, | 1024 | rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, |
1049 | "attempting to determine the 1.2 version"); | 1025 | "attempting to determine the 1.2 version"); |
1050 | if (rc) | 1026 | if (!rc) { |
1051 | return 0; | 1027 | str += sprintf(str, |
1052 | str += sprintf(str, | 1028 | "TCG version: %d.%d\nFirmware version: %d.%d\n", |
1053 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | 1029 | cap.tpm_version_1_2.Major, |
1054 | cap.tpm_version_1_2.Major, cap.tpm_version_1_2.Minor, | 1030 | cap.tpm_version_1_2.Minor, |
1055 | cap.tpm_version_1_2.revMajor, | 1031 | cap.tpm_version_1_2.revMajor, |
1056 | cap.tpm_version_1_2.revMinor); | 1032 | cap.tpm_version_1_2.revMinor); |
1033 | } else { | ||
1034 | /* Otherwise just use TPM_STRUCT_VER */ | ||
1035 | rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, | ||
1036 | "attempting to determine the 1.1 version"); | ||
1037 | if (rc) | ||
1038 | return 0; | ||
1039 | str += sprintf(str, | ||
1040 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
1041 | cap.tpm_version.Major, | ||
1042 | cap.tpm_version.Minor, | ||
1043 | cap.tpm_version.revMajor, | ||
1044 | cap.tpm_version.revMinor); | ||
1045 | } | ||
1046 | |||
1057 | return str - buf; | 1047 | return str - buf; |
1058 | } | 1048 | } |
1059 | EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); | 1049 | EXPORT_SYMBOL_GPL(tpm_show_caps); |
1060 | 1050 | ||
1061 | ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr, | 1051 | ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr, |
1062 | char *buf) | 1052 | char *buf) |
@@ -1102,8 +1092,8 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | |||
1102 | } | 1092 | } |
1103 | EXPORT_SYMBOL_GPL(tpm_store_cancel); | 1093 | EXPORT_SYMBOL_GPL(tpm_store_cancel); |
1104 | 1094 | ||
1105 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, bool check_cancel, | 1095 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, |
1106 | bool *canceled) | 1096 | bool check_cancel, bool *canceled) |
1107 | { | 1097 | { |
1108 | u8 status = chip->vendor.status(chip); | 1098 | u8 status = chip->vendor.status(chip); |
1109 | 1099 | ||
@@ -1170,38 +1160,25 @@ EXPORT_SYMBOL_GPL(wait_for_tpm_stat); | |||
1170 | */ | 1160 | */ |
1171 | int tpm_open(struct inode *inode, struct file *file) | 1161 | int tpm_open(struct inode *inode, struct file *file) |
1172 | { | 1162 | { |
1173 | int minor = iminor(inode); | 1163 | struct miscdevice *misc = file->private_data; |
1174 | struct tpm_chip *chip = NULL, *pos; | 1164 | struct tpm_chip *chip = container_of(misc, struct tpm_chip, |
1175 | 1165 | vendor.miscdev); | |
1176 | rcu_read_lock(); | ||
1177 | list_for_each_entry_rcu(pos, &tpm_chip_list, list) { | ||
1178 | if (pos->vendor.miscdev.minor == minor) { | ||
1179 | chip = pos; | ||
1180 | get_device(chip->dev); | ||
1181 | break; | ||
1182 | } | ||
1183 | } | ||
1184 | rcu_read_unlock(); | ||
1185 | |||
1186 | if (!chip) | ||
1187 | return -ENODEV; | ||
1188 | 1166 | ||
1189 | if (test_and_set_bit(0, &chip->is_open)) { | 1167 | if (test_and_set_bit(0, &chip->is_open)) { |
1190 | dev_dbg(chip->dev, "Another process owns this TPM\n"); | 1168 | dev_dbg(chip->dev, "Another process owns this TPM\n"); |
1191 | put_device(chip->dev); | ||
1192 | return -EBUSY; | 1169 | return -EBUSY; |
1193 | } | 1170 | } |
1194 | 1171 | ||
1195 | chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); | 1172 | chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); |
1196 | if (chip->data_buffer == NULL) { | 1173 | if (chip->data_buffer == NULL) { |
1197 | clear_bit(0, &chip->is_open); | 1174 | clear_bit(0, &chip->is_open); |
1198 | put_device(chip->dev); | ||
1199 | return -ENOMEM; | 1175 | return -ENOMEM; |
1200 | } | 1176 | } |
1201 | 1177 | ||
1202 | atomic_set(&chip->data_pending, 0); | 1178 | atomic_set(&chip->data_pending, 0); |
1203 | 1179 | ||
1204 | file->private_data = chip; | 1180 | file->private_data = chip; |
1181 | get_device(chip->dev); | ||
1205 | return 0; | 1182 | return 0; |
1206 | } | 1183 | } |
1207 | EXPORT_SYMBOL_GPL(tpm_open); | 1184 | EXPORT_SYMBOL_GPL(tpm_open); |
@@ -1463,7 +1440,6 @@ void tpm_dev_vendor_release(struct tpm_chip *chip) | |||
1463 | chip->vendor.release(chip->dev); | 1440 | chip->vendor.release(chip->dev); |
1464 | 1441 | ||
1465 | clear_bit(chip->dev_num, dev_mask); | 1442 | clear_bit(chip->dev_num, dev_mask); |
1466 | kfree(chip->vendor.miscdev.name); | ||
1467 | } | 1443 | } |
1468 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | 1444 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); |
1469 | 1445 | ||
@@ -1487,7 +1463,7 @@ void tpm_dev_release(struct device *dev) | |||
1487 | EXPORT_SYMBOL_GPL(tpm_dev_release); | 1463 | EXPORT_SYMBOL_GPL(tpm_dev_release); |
1488 | 1464 | ||
1489 | /* | 1465 | /* |
1490 | * Called from tpm_<specific>.c probe function only for devices | 1466 | * Called from tpm_<specific>.c probe function only for devices |
1491 | * the driver has determined it should claim. Prior to calling | 1467 | * the driver has determined it should claim. Prior to calling |
1492 | * this function the specific probe function has called pci_enable_device | 1468 | * this function the specific probe function has called pci_enable_device |
1493 | * upon errant exit from this function specific probe function should call | 1469 | * upon errant exit from this function specific probe function should call |
@@ -1496,17 +1472,13 @@ EXPORT_SYMBOL_GPL(tpm_dev_release); | |||
1496 | struct tpm_chip *tpm_register_hardware(struct device *dev, | 1472 | struct tpm_chip *tpm_register_hardware(struct device *dev, |
1497 | const struct tpm_vendor_specific *entry) | 1473 | const struct tpm_vendor_specific *entry) |
1498 | { | 1474 | { |
1499 | #define DEVNAME_SIZE 7 | ||
1500 | |||
1501 | char *devname; | ||
1502 | struct tpm_chip *chip; | 1475 | struct tpm_chip *chip; |
1503 | 1476 | ||
1504 | /* Driver specific per-device data */ | 1477 | /* Driver specific per-device data */ |
1505 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1478 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
1506 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); | ||
1507 | 1479 | ||
1508 | if (chip == NULL || devname == NULL) | 1480 | if (chip == NULL) |
1509 | goto out_free; | 1481 | return NULL; |
1510 | 1482 | ||
1511 | mutex_init(&chip->buffer_mutex); | 1483 | mutex_init(&chip->buffer_mutex); |
1512 | mutex_init(&chip->tpm_mutex); | 1484 | mutex_init(&chip->tpm_mutex); |
@@ -1531,8 +1503,9 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
1531 | 1503 | ||
1532 | set_bit(chip->dev_num, dev_mask); | 1504 | set_bit(chip->dev_num, dev_mask); |
1533 | 1505 | ||
1534 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 1506 | scnprintf(chip->devname, sizeof(chip->devname), "%s%d", "tpm", |
1535 | chip->vendor.miscdev.name = devname; | 1507 | chip->dev_num); |
1508 | chip->vendor.miscdev.name = chip->devname; | ||
1536 | 1509 | ||
1537 | chip->vendor.miscdev.parent = dev; | 1510 | chip->vendor.miscdev.parent = dev; |
1538 | chip->dev = get_device(dev); | 1511 | chip->dev = get_device(dev); |
@@ -1558,7 +1531,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
1558 | goto put_device; | 1531 | goto put_device; |
1559 | } | 1532 | } |
1560 | 1533 | ||
1561 | chip->bios_dir = tpm_bios_log_setup(devname); | 1534 | chip->bios_dir = tpm_bios_log_setup(chip->devname); |
1562 | 1535 | ||
1563 | /* Make chip available */ | 1536 | /* Make chip available */ |
1564 | spin_lock(&driver_lock); | 1537 | spin_lock(&driver_lock); |
@@ -1571,7 +1544,6 @@ put_device: | |||
1571 | put_device(chip->dev); | 1544 | put_device(chip->dev); |
1572 | out_free: | 1545 | out_free: |
1573 | kfree(chip); | 1546 | kfree(chip); |
1574 | kfree(devname); | ||
1575 | return NULL; | 1547 | return NULL; |
1576 | } | 1548 | } |
1577 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | 1549 | EXPORT_SYMBOL_GPL(tpm_register_hardware); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index a7bfc176ed43..f32847872193 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -59,8 +59,6 @@ extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, | |||
59 | char *); | 59 | char *); |
60 | extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, | 60 | extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, |
61 | char *); | 61 | char *); |
62 | extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr, | ||
63 | char *); | ||
64 | extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, | 62 | extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, |
65 | const char *, size_t); | 63 | const char *, size_t); |
66 | extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, | 64 | extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, |
@@ -122,6 +120,7 @@ struct tpm_chip { | |||
122 | struct device *dev; /* Device stuff */ | 120 | struct device *dev; /* Device stuff */ |
123 | 121 | ||
124 | int dev_num; /* /dev/tpm# */ | 122 | int dev_num; /* /dev/tpm# */ |
123 | char devname[7]; | ||
125 | unsigned long is_open; /* only one allowed */ | 124 | unsigned long is_open; /* only one allowed */ |
126 | int time_expired; | 125 | int time_expired; |
127 | 126 | ||
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 99d6820c611d..c9a528d25d22 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -202,7 +202,7 @@ static int __init init_atmel(void) | |||
202 | 202 | ||
203 | have_region = | 203 | have_region = |
204 | (atmel_request_region | 204 | (atmel_request_region |
205 | (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; | 205 | (base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; |
206 | 206 | ||
207 | pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0); | 207 | pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0); |
208 | if (IS_ERR(pdev)) { | 208 | if (IS_ERR(pdev)) { |
diff --git a/drivers/char/tpm/tpm_eventlog.c b/drivers/char/tpm/tpm_eventlog.c index 84ddc557b8f8..59f7cb28260b 100644 --- a/drivers/char/tpm/tpm_eventlog.c +++ b/drivers/char/tpm/tpm_eventlog.c | |||
@@ -406,7 +406,6 @@ out_tpm: | |||
406 | out: | 406 | out: |
407 | return NULL; | 407 | return NULL; |
408 | } | 408 | } |
409 | EXPORT_SYMBOL_GPL(tpm_bios_log_setup); | ||
410 | 409 | ||
411 | void tpm_bios_log_teardown(struct dentry **lst) | 410 | void tpm_bios_log_teardown(struct dentry **lst) |
412 | { | 411 | { |
@@ -415,5 +414,3 @@ void tpm_bios_log_teardown(struct dentry **lst) | |||
415 | for (i = 0; i < 3; i++) | 414 | for (i = 0; i < 3; i++) |
416 | securityfs_remove(lst[i]); | 415 | securityfs_remove(lst[i]); |
417 | } | 416 | } |
418 | EXPORT_SYMBOL_GPL(tpm_bios_log_teardown); | ||
419 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c new file mode 100644 index 000000000000..c3cd7fe481a1 --- /dev/null +++ b/drivers/char/tpm/tpm_i2c_atmel.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * ATMEL I2C TPM AT97SC3204T | ||
3 | * | ||
4 | * Copyright (C) 2012 V Lab Technologies | ||
5 | * Teddy Reed <teddy@prosauce.org> | ||
6 | * Copyright (C) 2013, Obsidian Research Corp. | ||
7 | * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
8 | * Device driver for ATMEL I2C TPMs. | ||
9 | * | ||
10 | * Teddy Reed determined the basic I2C command flow, unlike other I2C TPM | ||
11 | * devices the raw TCG formatted TPM command data is written via I2C and then | ||
12 | * raw TCG formatted TPM command data is returned via I2C. | ||
13 | * | ||
14 | * TGC status/locality/etc functions seen in the LPC implementation do not | ||
15 | * seem to be present. | ||
16 | * | ||
17 | * This program is free software: you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License as published by | ||
19 | * the Free Software Foundation, either version 2 of the License, or | ||
20 | * (at your option) any later version. | ||
21 | * | ||
22 | * This program is distributed in the hope that it will be useful, | ||
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 | * GNU General Public License for more details. | ||
26 | * | ||
27 | * You should have received a copy of the GNU General Public License | ||
28 | * along with this program. If not, see http://www.gnu.org/licenses/>. | ||
29 | */ | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/moduleparam.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include "tpm.h" | ||
36 | |||
37 | #define I2C_DRIVER_NAME "tpm_i2c_atmel" | ||
38 | |||
39 | #define TPM_I2C_SHORT_TIMEOUT 750 /* ms */ | ||
40 | #define TPM_I2C_LONG_TIMEOUT 2000 /* 2 sec */ | ||
41 | |||
42 | #define ATMEL_STS_OK 1 | ||
43 | |||
44 | struct priv_data { | ||
45 | size_t len; | ||
46 | /* This is the amount we read on the first try. 25 was chosen to fit a | ||
47 | * fair number of read responses in the buffer so a 2nd retry can be | ||
48 | * avoided in small message cases. */ | ||
49 | u8 buffer[sizeof(struct tpm_output_header) + 25]; | ||
50 | }; | ||
51 | |||
52 | static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len) | ||
53 | { | ||
54 | struct priv_data *priv = chip->vendor.priv; | ||
55 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
56 | s32 status; | ||
57 | |||
58 | priv->len = 0; | ||
59 | |||
60 | if (len <= 2) | ||
61 | return -EIO; | ||
62 | |||
63 | status = i2c_master_send(client, buf, len); | ||
64 | |||
65 | dev_dbg(chip->dev, | ||
66 | "%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__, | ||
67 | (int)min_t(size_t, 64, len), buf, len, status); | ||
68 | return status; | ||
69 | } | ||
70 | |||
71 | static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count) | ||
72 | { | ||
73 | struct priv_data *priv = chip->vendor.priv; | ||
74 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
75 | struct tpm_output_header *hdr = | ||
76 | (struct tpm_output_header *)priv->buffer; | ||
77 | u32 expected_len; | ||
78 | int rc; | ||
79 | |||
80 | if (priv->len == 0) | ||
81 | return -EIO; | ||
82 | |||
83 | /* Get the message size from the message header, if we didn't get the | ||
84 | * whole message in read_status then we need to re-read the | ||
85 | * message. */ | ||
86 | expected_len = be32_to_cpu(hdr->length); | ||
87 | if (expected_len > count) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | if (priv->len >= expected_len) { | ||
91 | dev_dbg(chip->dev, | ||
92 | "%s early(buf=%*ph count=%0zx) -> ret=%d\n", __func__, | ||
93 | (int)min_t(size_t, 64, expected_len), buf, count, | ||
94 | expected_len); | ||
95 | memcpy(buf, priv->buffer, expected_len); | ||
96 | return expected_len; | ||
97 | } | ||
98 | |||
99 | rc = i2c_master_recv(client, buf, expected_len); | ||
100 | dev_dbg(chip->dev, | ||
101 | "%s reread(buf=%*ph count=%0zx) -> ret=%d\n", __func__, | ||
102 | (int)min_t(size_t, 64, expected_len), buf, count, | ||
103 | expected_len); | ||
104 | return rc; | ||
105 | } | ||
106 | |||
107 | static void i2c_atmel_cancel(struct tpm_chip *chip) | ||
108 | { | ||
109 | dev_err(chip->dev, "TPM operation cancellation was requested, but is not supported"); | ||
110 | } | ||
111 | |||
112 | static u8 i2c_atmel_read_status(struct tpm_chip *chip) | ||
113 | { | ||
114 | struct priv_data *priv = chip->vendor.priv; | ||
115 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
116 | int rc; | ||
117 | |||
118 | /* The TPM fails the I2C read until it is ready, so we do the entire | ||
119 | * transfer here and buffer it locally. This way the common code can | ||
120 | * properly handle the timeouts. */ | ||
121 | priv->len = 0; | ||
122 | memset(priv->buffer, 0, sizeof(priv->buffer)); | ||
123 | |||
124 | |||
125 | /* Once the TPM has completed the command the command remains readable | ||
126 | * until another command is issued. */ | ||
127 | rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer)); | ||
128 | dev_dbg(chip->dev, | ||
129 | "%s: sts=%d", __func__, rc); | ||
130 | if (rc <= 0) | ||
131 | return 0; | ||
132 | |||
133 | priv->len = rc; | ||
134 | |||
135 | return ATMEL_STS_OK; | ||
136 | } | ||
137 | |||
138 | static const struct file_operations i2c_atmel_ops = { | ||
139 | .owner = THIS_MODULE, | ||
140 | .llseek = no_llseek, | ||
141 | .open = tpm_open, | ||
142 | .read = tpm_read, | ||
143 | .write = tpm_write, | ||
144 | .release = tpm_release, | ||
145 | }; | ||
146 | |||
147 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
148 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
149 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
150 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
151 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
152 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
153 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
154 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
155 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
156 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
157 | |||
158 | static struct attribute *i2c_atmel_attrs[] = { | ||
159 | &dev_attr_pubek.attr, | ||
160 | &dev_attr_pcrs.attr, | ||
161 | &dev_attr_enabled.attr, | ||
162 | &dev_attr_active.attr, | ||
163 | &dev_attr_owned.attr, | ||
164 | &dev_attr_temp_deactivated.attr, | ||
165 | &dev_attr_caps.attr, | ||
166 | &dev_attr_cancel.attr, | ||
167 | &dev_attr_durations.attr, | ||
168 | &dev_attr_timeouts.attr, | ||
169 | NULL, | ||
170 | }; | ||
171 | |||
172 | static struct attribute_group i2c_atmel_attr_grp = { | ||
173 | .attrs = i2c_atmel_attrs | ||
174 | }; | ||
175 | |||
176 | static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status) | ||
177 | { | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static const struct tpm_vendor_specific i2c_atmel = { | ||
182 | .status = i2c_atmel_read_status, | ||
183 | .recv = i2c_atmel_recv, | ||
184 | .send = i2c_atmel_send, | ||
185 | .cancel = i2c_atmel_cancel, | ||
186 | .req_complete_mask = ATMEL_STS_OK, | ||
187 | .req_complete_val = ATMEL_STS_OK, | ||
188 | .req_canceled = i2c_atmel_req_canceled, | ||
189 | .attr_group = &i2c_atmel_attr_grp, | ||
190 | .miscdev.fops = &i2c_atmel_ops, | ||
191 | }; | ||
192 | |||
193 | static int i2c_atmel_probe(struct i2c_client *client, | ||
194 | const struct i2c_device_id *id) | ||
195 | { | ||
196 | int rc; | ||
197 | struct tpm_chip *chip; | ||
198 | struct device *dev = &client->dev; | ||
199 | |||
200 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
201 | return -ENODEV; | ||
202 | |||
203 | chip = tpm_register_hardware(dev, &i2c_atmel); | ||
204 | if (!chip) { | ||
205 | dev_err(dev, "%s() error in tpm_register_hardware\n", __func__); | ||
206 | return -ENODEV; | ||
207 | } | ||
208 | |||
209 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), | ||
210 | GFP_KERNEL); | ||
211 | |||
212 | /* Default timeouts */ | ||
213 | chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
214 | chip->vendor.timeout_b = msecs_to_jiffies(TPM_I2C_LONG_TIMEOUT); | ||
215 | chip->vendor.timeout_c = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
216 | chip->vendor.timeout_d = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
217 | chip->vendor.irq = 0; | ||
218 | |||
219 | /* There is no known way to probe for this device, and all version | ||
220 | * information seems to be read via TPM commands. Thus we rely on the | ||
221 | * TPM startup process in the common code to detect the device. */ | ||
222 | if (tpm_get_timeouts(chip)) { | ||
223 | rc = -ENODEV; | ||
224 | goto out_err; | ||
225 | } | ||
226 | |||
227 | if (tpm_do_selftest(chip)) { | ||
228 | rc = -ENODEV; | ||
229 | goto out_err; | ||
230 | } | ||
231 | |||
232 | return 0; | ||
233 | |||
234 | out_err: | ||
235 | tpm_dev_vendor_release(chip); | ||
236 | tpm_remove_hardware(chip->dev); | ||
237 | return rc; | ||
238 | } | ||
239 | |||
240 | static int i2c_atmel_remove(struct i2c_client *client) | ||
241 | { | ||
242 | struct device *dev = &(client->dev); | ||
243 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
244 | |||
245 | if (chip) | ||
246 | tpm_dev_vendor_release(chip); | ||
247 | tpm_remove_hardware(dev); | ||
248 | kfree(chip); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static const struct i2c_device_id i2c_atmel_id[] = { | ||
253 | {I2C_DRIVER_NAME, 0}, | ||
254 | {} | ||
255 | }; | ||
256 | MODULE_DEVICE_TABLE(i2c, i2c_atmel_id); | ||
257 | |||
258 | #ifdef CONFIG_OF | ||
259 | static const struct of_device_id i2c_atmel_of_match[] = { | ||
260 | {.compatible = "atmel,at97sc3204t"}, | ||
261 | {}, | ||
262 | }; | ||
263 | MODULE_DEVICE_TABLE(of, i2c_atmel_of_match); | ||
264 | #endif | ||
265 | |||
266 | static SIMPLE_DEV_PM_OPS(i2c_atmel_pm_ops, tpm_pm_suspend, tpm_pm_resume); | ||
267 | |||
268 | static struct i2c_driver i2c_atmel_driver = { | ||
269 | .id_table = i2c_atmel_id, | ||
270 | .probe = i2c_atmel_probe, | ||
271 | .remove = i2c_atmel_remove, | ||
272 | .driver = { | ||
273 | .name = I2C_DRIVER_NAME, | ||
274 | .owner = THIS_MODULE, | ||
275 | .pm = &i2c_atmel_pm_ops, | ||
276 | .of_match_table = of_match_ptr(i2c_atmel_of_match), | ||
277 | }, | ||
278 | }; | ||
279 | |||
280 | module_i2c_driver(i2c_atmel_driver); | ||
281 | |||
282 | MODULE_AUTHOR("Jason Gunthorpe <jgunthorpe@obsidianresearch.com>"); | ||
283 | MODULE_DESCRIPTION("Atmel TPM I2C Driver"); | ||
284 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index b8735de8ce95..fefd2aa5c81e 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c | |||
@@ -581,7 +581,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | |||
581 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | 581 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); |
582 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | 582 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); |
583 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | 583 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); |
584 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | 584 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); |
585 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 585 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
586 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | 586 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); |
587 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | 587 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); |
@@ -685,7 +685,6 @@ out_vendor: | |||
685 | chip->dev->release = NULL; | 685 | chip->dev->release = NULL; |
686 | chip->release = NULL; | 686 | chip->release = NULL; |
687 | tpm_dev.client = NULL; | 687 | tpm_dev.client = NULL; |
688 | dev_set_drvdata(chip->dev, chip); | ||
689 | out_err: | 688 | out_err: |
690 | return rc; | 689 | return rc; |
691 | } | 690 | } |
@@ -766,7 +765,6 @@ static int tpm_tis_i2c_remove(struct i2c_client *client) | |||
766 | chip->dev->release = NULL; | 765 | chip->dev->release = NULL; |
767 | chip->release = NULL; | 766 | chip->release = NULL; |
768 | tpm_dev.client = NULL; | 767 | tpm_dev.client = NULL; |
769 | dev_set_drvdata(chip->dev, chip); | ||
770 | 768 | ||
771 | return 0; | 769 | return 0; |
772 | } | 770 | } |
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c new file mode 100644 index 000000000000..6276fea01ff0 --- /dev/null +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c | |||
@@ -0,0 +1,710 @@ | |||
1 | /****************************************************************************** | ||
2 | * Nuvoton TPM I2C Device Driver Interface for WPCT301/NPCT501, | ||
3 | * based on the TCG TPM Interface Spec version 1.2. | ||
4 | * Specifications at www.trustedcomputinggroup.org | ||
5 | * | ||
6 | * Copyright (C) 2011, Nuvoton Technology Corporation. | ||
7 | * Dan Morav <dan.morav@nuvoton.com> | ||
8 | * Copyright (C) 2013, Obsidian Research Corp. | ||
9 | * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
10 | * | ||
11 | * This program is free software: you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program. If not, see http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | * Nuvoton contact information: APC.Support@nuvoton.com | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #include <linux/init.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/moduleparam.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/wait.h> | ||
33 | #include <linux/i2c.h> | ||
34 | #include "tpm.h" | ||
35 | |||
36 | /* I2C interface offsets */ | ||
37 | #define TPM_STS 0x00 | ||
38 | #define TPM_BURST_COUNT 0x01 | ||
39 | #define TPM_DATA_FIFO_W 0x20 | ||
40 | #define TPM_DATA_FIFO_R 0x40 | ||
41 | #define TPM_VID_DID_RID 0x60 | ||
42 | /* TPM command header size */ | ||
43 | #define TPM_HEADER_SIZE 10 | ||
44 | #define TPM_RETRY 5 | ||
45 | /* | ||
46 | * I2C bus device maximum buffer size w/o counting I2C address or command | ||
47 | * i.e. max size required for I2C write is 34 = addr, command, 32 bytes data | ||
48 | */ | ||
49 | #define TPM_I2C_MAX_BUF_SIZE 32 | ||
50 | #define TPM_I2C_RETRY_COUNT 32 | ||
51 | #define TPM_I2C_BUS_DELAY 1 /* msec */ | ||
52 | #define TPM_I2C_RETRY_DELAY_SHORT 2 /* msec */ | ||
53 | #define TPM_I2C_RETRY_DELAY_LONG 10 /* msec */ | ||
54 | |||
55 | #define I2C_DRIVER_NAME "tpm_i2c_nuvoton" | ||
56 | |||
57 | struct priv_data { | ||
58 | unsigned int intrs; | ||
59 | }; | ||
60 | |||
61 | static s32 i2c_nuvoton_read_buf(struct i2c_client *client, u8 offset, u8 size, | ||
62 | u8 *data) | ||
63 | { | ||
64 | s32 status; | ||
65 | |||
66 | status = i2c_smbus_read_i2c_block_data(client, offset, size, data); | ||
67 | dev_dbg(&client->dev, | ||
68 | "%s(offset=%u size=%u data=%*ph) -> sts=%d\n", __func__, | ||
69 | offset, size, (int)size, data, status); | ||
70 | return status; | ||
71 | } | ||
72 | |||
73 | static s32 i2c_nuvoton_write_buf(struct i2c_client *client, u8 offset, u8 size, | ||
74 | u8 *data) | ||
75 | { | ||
76 | s32 status; | ||
77 | |||
78 | status = i2c_smbus_write_i2c_block_data(client, offset, size, data); | ||
79 | dev_dbg(&client->dev, | ||
80 | "%s(offset=%u size=%u data=%*ph) -> sts=%d\n", __func__, | ||
81 | offset, size, (int)size, data, status); | ||
82 | return status; | ||
83 | } | ||
84 | |||
85 | #define TPM_STS_VALID 0x80 | ||
86 | #define TPM_STS_COMMAND_READY 0x40 | ||
87 | #define TPM_STS_GO 0x20 | ||
88 | #define TPM_STS_DATA_AVAIL 0x10 | ||
89 | #define TPM_STS_EXPECT 0x08 | ||
90 | #define TPM_STS_RESPONSE_RETRY 0x02 | ||
91 | #define TPM_STS_ERR_VAL 0x07 /* bit2...bit0 reads always 0 */ | ||
92 | |||
93 | #define TPM_I2C_SHORT_TIMEOUT 750 /* ms */ | ||
94 | #define TPM_I2C_LONG_TIMEOUT 2000 /* 2 sec */ | ||
95 | |||
96 | /* read TPM_STS register */ | ||
97 | static u8 i2c_nuvoton_read_status(struct tpm_chip *chip) | ||
98 | { | ||
99 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
100 | s32 status; | ||
101 | u8 data; | ||
102 | |||
103 | status = i2c_nuvoton_read_buf(client, TPM_STS, 1, &data); | ||
104 | if (status <= 0) { | ||
105 | dev_err(chip->dev, "%s() error return %d\n", __func__, | ||
106 | status); | ||
107 | data = TPM_STS_ERR_VAL; | ||
108 | } | ||
109 | |||
110 | return data; | ||
111 | } | ||
112 | |||
113 | /* write byte to TPM_STS register */ | ||
114 | static s32 i2c_nuvoton_write_status(struct i2c_client *client, u8 data) | ||
115 | { | ||
116 | s32 status; | ||
117 | int i; | ||
118 | |||
119 | /* this causes the current command to be aborted */ | ||
120 | for (i = 0, status = -1; i < TPM_I2C_RETRY_COUNT && status < 0; i++) { | ||
121 | status = i2c_nuvoton_write_buf(client, TPM_STS, 1, &data); | ||
122 | msleep(TPM_I2C_BUS_DELAY); | ||
123 | } | ||
124 | return status; | ||
125 | } | ||
126 | |||
127 | /* write commandReady to TPM_STS register */ | ||
128 | static void i2c_nuvoton_ready(struct tpm_chip *chip) | ||
129 | { | ||
130 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
131 | s32 status; | ||
132 | |||
133 | /* this causes the current command to be aborted */ | ||
134 | status = i2c_nuvoton_write_status(client, TPM_STS_COMMAND_READY); | ||
135 | if (status < 0) | ||
136 | dev_err(chip->dev, | ||
137 | "%s() fail to write TPM_STS.commandReady\n", __func__); | ||
138 | } | ||
139 | |||
140 | /* read burstCount field from TPM_STS register | ||
141 | * return -1 on fail to read */ | ||
142 | static int i2c_nuvoton_get_burstcount(struct i2c_client *client, | ||
143 | struct tpm_chip *chip) | ||
144 | { | ||
145 | unsigned long stop = jiffies + chip->vendor.timeout_d; | ||
146 | s32 status; | ||
147 | int burst_count = -1; | ||
148 | u8 data; | ||
149 | |||
150 | /* wait for burstcount to be non-zero */ | ||
151 | do { | ||
152 | /* in I2C burstCount is 1 byte */ | ||
153 | status = i2c_nuvoton_read_buf(client, TPM_BURST_COUNT, 1, | ||
154 | &data); | ||
155 | if (status > 0 && data > 0) { | ||
156 | burst_count = min_t(u8, TPM_I2C_MAX_BUF_SIZE, data); | ||
157 | break; | ||
158 | } | ||
159 | msleep(TPM_I2C_BUS_DELAY); | ||
160 | } while (time_before(jiffies, stop)); | ||
161 | |||
162 | return burst_count; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * WPCT301/NPCT501 SINT# supports only dataAvail | ||
167 | * any call to this function which is not waiting for dataAvail will | ||
168 | * set queue to NULL to avoid waiting for interrupt | ||
169 | */ | ||
170 | static bool i2c_nuvoton_check_status(struct tpm_chip *chip, u8 mask, u8 value) | ||
171 | { | ||
172 | u8 status = i2c_nuvoton_read_status(chip); | ||
173 | return (status != TPM_STS_ERR_VAL) && ((status & mask) == value); | ||
174 | } | ||
175 | |||
176 | static int i2c_nuvoton_wait_for_stat(struct tpm_chip *chip, u8 mask, u8 value, | ||
177 | u32 timeout, wait_queue_head_t *queue) | ||
178 | { | ||
179 | if (chip->vendor.irq && queue) { | ||
180 | s32 rc; | ||
181 | DEFINE_WAIT(wait); | ||
182 | struct priv_data *priv = chip->vendor.priv; | ||
183 | unsigned int cur_intrs = priv->intrs; | ||
184 | |||
185 | enable_irq(chip->vendor.irq); | ||
186 | rc = wait_event_interruptible_timeout(*queue, | ||
187 | cur_intrs != priv->intrs, | ||
188 | timeout); | ||
189 | if (rc > 0) | ||
190 | return 0; | ||
191 | /* At this point we know that the SINT pin is asserted, so we | ||
192 | * do not need to do i2c_nuvoton_check_status */ | ||
193 | } else { | ||
194 | unsigned long ten_msec, stop; | ||
195 | bool status_valid; | ||
196 | |||
197 | /* check current status */ | ||
198 | status_valid = i2c_nuvoton_check_status(chip, mask, value); | ||
199 | if (status_valid) | ||
200 | return 0; | ||
201 | |||
202 | /* use polling to wait for the event */ | ||
203 | ten_msec = jiffies + msecs_to_jiffies(TPM_I2C_RETRY_DELAY_LONG); | ||
204 | stop = jiffies + timeout; | ||
205 | do { | ||
206 | if (time_before(jiffies, ten_msec)) | ||
207 | msleep(TPM_I2C_RETRY_DELAY_SHORT); | ||
208 | else | ||
209 | msleep(TPM_I2C_RETRY_DELAY_LONG); | ||
210 | status_valid = i2c_nuvoton_check_status(chip, mask, | ||
211 | value); | ||
212 | if (status_valid) | ||
213 | return 0; | ||
214 | } while (time_before(jiffies, stop)); | ||
215 | } | ||
216 | dev_err(chip->dev, "%s(%02x, %02x) -> timeout\n", __func__, mask, | ||
217 | value); | ||
218 | return -ETIMEDOUT; | ||
219 | } | ||
220 | |||
221 | /* wait for dataAvail field to be set in the TPM_STS register */ | ||
222 | static int i2c_nuvoton_wait_for_data_avail(struct tpm_chip *chip, u32 timeout, | ||
223 | wait_queue_head_t *queue) | ||
224 | { | ||
225 | return i2c_nuvoton_wait_for_stat(chip, | ||
226 | TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
227 | TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
228 | timeout, queue); | ||
229 | } | ||
230 | |||
231 | /* Read @count bytes into @buf from TPM_RD_FIFO register */ | ||
232 | static int i2c_nuvoton_recv_data(struct i2c_client *client, | ||
233 | struct tpm_chip *chip, u8 *buf, size_t count) | ||
234 | { | ||
235 | s32 rc; | ||
236 | int burst_count, bytes2read, size = 0; | ||
237 | |||
238 | while (size < count && | ||
239 | i2c_nuvoton_wait_for_data_avail(chip, | ||
240 | chip->vendor.timeout_c, | ||
241 | &chip->vendor.read_queue) == 0) { | ||
242 | burst_count = i2c_nuvoton_get_burstcount(client, chip); | ||
243 | if (burst_count < 0) { | ||
244 | dev_err(chip->dev, | ||
245 | "%s() fail to read burstCount=%d\n", __func__, | ||
246 | burst_count); | ||
247 | return -EIO; | ||
248 | } | ||
249 | bytes2read = min_t(size_t, burst_count, count - size); | ||
250 | rc = i2c_nuvoton_read_buf(client, TPM_DATA_FIFO_R, | ||
251 | bytes2read, &buf[size]); | ||
252 | if (rc < 0) { | ||
253 | dev_err(chip->dev, | ||
254 | "%s() fail on i2c_nuvoton_read_buf()=%d\n", | ||
255 | __func__, rc); | ||
256 | return -EIO; | ||
257 | } | ||
258 | dev_dbg(chip->dev, "%s(%d):", __func__, bytes2read); | ||
259 | size += bytes2read; | ||
260 | } | ||
261 | |||
262 | return size; | ||
263 | } | ||
264 | |||
265 | /* Read TPM command results */ | ||
266 | static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count) | ||
267 | { | ||
268 | struct device *dev = chip->dev; | ||
269 | struct i2c_client *client = to_i2c_client(dev); | ||
270 | s32 rc; | ||
271 | int expected, status, burst_count, retries, size = 0; | ||
272 | |||
273 | if (count < TPM_HEADER_SIZE) { | ||
274 | i2c_nuvoton_ready(chip); /* return to idle */ | ||
275 | dev_err(dev, "%s() count < header size\n", __func__); | ||
276 | return -EIO; | ||
277 | } | ||
278 | for (retries = 0; retries < TPM_RETRY; retries++) { | ||
279 | if (retries > 0) { | ||
280 | /* if this is not the first trial, set responseRetry */ | ||
281 | i2c_nuvoton_write_status(client, | ||
282 | TPM_STS_RESPONSE_RETRY); | ||
283 | } | ||
284 | /* | ||
285 | * read first available (> 10 bytes), including: | ||
286 | * tag, paramsize, and result | ||
287 | */ | ||
288 | status = i2c_nuvoton_wait_for_data_avail( | ||
289 | chip, chip->vendor.timeout_c, &chip->vendor.read_queue); | ||
290 | if (status != 0) { | ||
291 | dev_err(dev, "%s() timeout on dataAvail\n", __func__); | ||
292 | size = -ETIMEDOUT; | ||
293 | continue; | ||
294 | } | ||
295 | burst_count = i2c_nuvoton_get_burstcount(client, chip); | ||
296 | if (burst_count < 0) { | ||
297 | dev_err(dev, "%s() fail to get burstCount\n", __func__); | ||
298 | size = -EIO; | ||
299 | continue; | ||
300 | } | ||
301 | size = i2c_nuvoton_recv_data(client, chip, buf, | ||
302 | burst_count); | ||
303 | if (size < TPM_HEADER_SIZE) { | ||
304 | dev_err(dev, "%s() fail to read header\n", __func__); | ||
305 | size = -EIO; | ||
306 | continue; | ||
307 | } | ||
308 | /* | ||
309 | * convert number of expected bytes field from big endian 32 bit | ||
310 | * to machine native | ||
311 | */ | ||
312 | expected = be32_to_cpu(*(__be32 *) (buf + 2)); | ||
313 | if (expected > count) { | ||
314 | dev_err(dev, "%s() expected > count\n", __func__); | ||
315 | size = -EIO; | ||
316 | continue; | ||
317 | } | ||
318 | rc = i2c_nuvoton_recv_data(client, chip, &buf[size], | ||
319 | expected - size); | ||
320 | size += rc; | ||
321 | if (rc < 0 || size < expected) { | ||
322 | dev_err(dev, "%s() fail to read remainder of result\n", | ||
323 | __func__); | ||
324 | size = -EIO; | ||
325 | continue; | ||
326 | } | ||
327 | if (i2c_nuvoton_wait_for_stat( | ||
328 | chip, TPM_STS_VALID | TPM_STS_DATA_AVAIL, | ||
329 | TPM_STS_VALID, chip->vendor.timeout_c, | ||
330 | NULL)) { | ||
331 | dev_err(dev, "%s() error left over data\n", __func__); | ||
332 | size = -ETIMEDOUT; | ||
333 | continue; | ||
334 | } | ||
335 | break; | ||
336 | } | ||
337 | i2c_nuvoton_ready(chip); | ||
338 | dev_dbg(chip->dev, "%s() -> %d\n", __func__, size); | ||
339 | return size; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Send TPM command. | ||
344 | * | ||
345 | * If interrupts are used (signaled by an irq set in the vendor structure) | ||
346 | * tpm.c can skip polling for the data to be available as the interrupt is | ||
347 | * waited for here | ||
348 | */ | ||
349 | static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len) | ||
350 | { | ||
351 | struct device *dev = chip->dev; | ||
352 | struct i2c_client *client = to_i2c_client(dev); | ||
353 | u32 ordinal; | ||
354 | size_t count = 0; | ||
355 | int burst_count, bytes2write, retries, rc = -EIO; | ||
356 | |||
357 | for (retries = 0; retries < TPM_RETRY; retries++) { | ||
358 | i2c_nuvoton_ready(chip); | ||
359 | if (i2c_nuvoton_wait_for_stat(chip, TPM_STS_COMMAND_READY, | ||
360 | TPM_STS_COMMAND_READY, | ||
361 | chip->vendor.timeout_b, NULL)) { | ||
362 | dev_err(dev, "%s() timeout on commandReady\n", | ||
363 | __func__); | ||
364 | rc = -EIO; | ||
365 | continue; | ||
366 | } | ||
367 | rc = 0; | ||
368 | while (count < len - 1) { | ||
369 | burst_count = i2c_nuvoton_get_burstcount(client, | ||
370 | chip); | ||
371 | if (burst_count < 0) { | ||
372 | dev_err(dev, "%s() fail get burstCount\n", | ||
373 | __func__); | ||
374 | rc = -EIO; | ||
375 | break; | ||
376 | } | ||
377 | bytes2write = min_t(size_t, burst_count, | ||
378 | len - 1 - count); | ||
379 | rc = i2c_nuvoton_write_buf(client, TPM_DATA_FIFO_W, | ||
380 | bytes2write, &buf[count]); | ||
381 | if (rc < 0) { | ||
382 | dev_err(dev, "%s() fail i2cWriteBuf\n", | ||
383 | __func__); | ||
384 | break; | ||
385 | } | ||
386 | dev_dbg(dev, "%s(%d):", __func__, bytes2write); | ||
387 | count += bytes2write; | ||
388 | rc = i2c_nuvoton_wait_for_stat(chip, | ||
389 | TPM_STS_VALID | | ||
390 | TPM_STS_EXPECT, | ||
391 | TPM_STS_VALID | | ||
392 | TPM_STS_EXPECT, | ||
393 | chip->vendor.timeout_c, | ||
394 | NULL); | ||
395 | if (rc < 0) { | ||
396 | dev_err(dev, "%s() timeout on Expect\n", | ||
397 | __func__); | ||
398 | rc = -ETIMEDOUT; | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | if (rc < 0) | ||
403 | continue; | ||
404 | |||
405 | /* write last byte */ | ||
406 | rc = i2c_nuvoton_write_buf(client, TPM_DATA_FIFO_W, 1, | ||
407 | &buf[count]); | ||
408 | if (rc < 0) { | ||
409 | dev_err(dev, "%s() fail to write last byte\n", | ||
410 | __func__); | ||
411 | rc = -EIO; | ||
412 | continue; | ||
413 | } | ||
414 | dev_dbg(dev, "%s(last): %02x", __func__, buf[count]); | ||
415 | rc = i2c_nuvoton_wait_for_stat(chip, | ||
416 | TPM_STS_VALID | TPM_STS_EXPECT, | ||
417 | TPM_STS_VALID, | ||
418 | chip->vendor.timeout_c, NULL); | ||
419 | if (rc) { | ||
420 | dev_err(dev, "%s() timeout on Expect to clear\n", | ||
421 | __func__); | ||
422 | rc = -ETIMEDOUT; | ||
423 | continue; | ||
424 | } | ||
425 | break; | ||
426 | } | ||
427 | if (rc < 0) { | ||
428 | /* retries == TPM_RETRY */ | ||
429 | i2c_nuvoton_ready(chip); | ||
430 | return rc; | ||
431 | } | ||
432 | /* execute the TPM command */ | ||
433 | rc = i2c_nuvoton_write_status(client, TPM_STS_GO); | ||
434 | if (rc < 0) { | ||
435 | dev_err(dev, "%s() fail to write Go\n", __func__); | ||
436 | i2c_nuvoton_ready(chip); | ||
437 | return rc; | ||
438 | } | ||
439 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); | ||
440 | rc = i2c_nuvoton_wait_for_data_avail(chip, | ||
441 | tpm_calc_ordinal_duration(chip, | ||
442 | ordinal), | ||
443 | &chip->vendor.read_queue); | ||
444 | if (rc) { | ||
445 | dev_err(dev, "%s() timeout command duration\n", __func__); | ||
446 | i2c_nuvoton_ready(chip); | ||
447 | return rc; | ||
448 | } | ||
449 | |||
450 | dev_dbg(dev, "%s() -> %zd\n", __func__, len); | ||
451 | return len; | ||
452 | } | ||
453 | |||
454 | static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status) | ||
455 | { | ||
456 | return (status == TPM_STS_COMMAND_READY); | ||
457 | } | ||
458 | |||
459 | static const struct file_operations i2c_nuvoton_ops = { | ||
460 | .owner = THIS_MODULE, | ||
461 | .llseek = no_llseek, | ||
462 | .open = tpm_open, | ||
463 | .read = tpm_read, | ||
464 | .write = tpm_write, | ||
465 | .release = tpm_release, | ||
466 | }; | ||
467 | |||
468 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
469 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
470 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
471 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
472 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
473 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
474 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
475 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
476 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
477 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
478 | |||
479 | static struct attribute *i2c_nuvoton_attrs[] = { | ||
480 | &dev_attr_pubek.attr, | ||
481 | &dev_attr_pcrs.attr, | ||
482 | &dev_attr_enabled.attr, | ||
483 | &dev_attr_active.attr, | ||
484 | &dev_attr_owned.attr, | ||
485 | &dev_attr_temp_deactivated.attr, | ||
486 | &dev_attr_caps.attr, | ||
487 | &dev_attr_cancel.attr, | ||
488 | &dev_attr_durations.attr, | ||
489 | &dev_attr_timeouts.attr, | ||
490 | NULL, | ||
491 | }; | ||
492 | |||
493 | static struct attribute_group i2c_nuvoton_attr_grp = { | ||
494 | .attrs = i2c_nuvoton_attrs | ||
495 | }; | ||
496 | |||
497 | static const struct tpm_vendor_specific tpm_i2c = { | ||
498 | .status = i2c_nuvoton_read_status, | ||
499 | .recv = i2c_nuvoton_recv, | ||
500 | .send = i2c_nuvoton_send, | ||
501 | .cancel = i2c_nuvoton_ready, | ||
502 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
503 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
504 | .req_canceled = i2c_nuvoton_req_canceled, | ||
505 | .attr_group = &i2c_nuvoton_attr_grp, | ||
506 | .miscdev.fops = &i2c_nuvoton_ops, | ||
507 | }; | ||
508 | |||
509 | /* The only purpose for the handler is to signal to any waiting threads that | ||
510 | * the interrupt is currently being asserted. The driver does not do any | ||
511 | * processing triggered by interrupts, and the chip provides no way to mask at | ||
512 | * the source (plus that would be slow over I2C). Run the IRQ as a one-shot, | ||
513 | * this means it cannot be shared. */ | ||
514 | static irqreturn_t i2c_nuvoton_int_handler(int dummy, void *dev_id) | ||
515 | { | ||
516 | struct tpm_chip *chip = dev_id; | ||
517 | struct priv_data *priv = chip->vendor.priv; | ||
518 | |||
519 | priv->intrs++; | ||
520 | wake_up(&chip->vendor.read_queue); | ||
521 | disable_irq_nosync(chip->vendor.irq); | ||
522 | return IRQ_HANDLED; | ||
523 | } | ||
524 | |||
525 | static int get_vid(struct i2c_client *client, u32 *res) | ||
526 | { | ||
527 | static const u8 vid_did_rid_value[] = { 0x50, 0x10, 0xfe }; | ||
528 | u32 temp; | ||
529 | s32 rc; | ||
530 | |||
531 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
532 | return -ENODEV; | ||
533 | rc = i2c_nuvoton_read_buf(client, TPM_VID_DID_RID, 4, (u8 *)&temp); | ||
534 | if (rc < 0) | ||
535 | return rc; | ||
536 | |||
537 | /* check WPCT301 values - ignore RID */ | ||
538 | if (memcmp(&temp, vid_did_rid_value, sizeof(vid_did_rid_value))) { | ||
539 | /* | ||
540 | * f/w rev 2.81 has an issue where the VID_DID_RID is not | ||
541 | * reporting the right value. so give it another chance at | ||
542 | * offset 0x20 (FIFO_W). | ||
543 | */ | ||
544 | rc = i2c_nuvoton_read_buf(client, TPM_DATA_FIFO_W, 4, | ||
545 | (u8 *) (&temp)); | ||
546 | if (rc < 0) | ||
547 | return rc; | ||
548 | |||
549 | /* check WPCT301 values - ignore RID */ | ||
550 | if (memcmp(&temp, vid_did_rid_value, | ||
551 | sizeof(vid_did_rid_value))) | ||
552 | return -ENODEV; | ||
553 | } | ||
554 | |||
555 | *res = temp; | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static int i2c_nuvoton_probe(struct i2c_client *client, | ||
560 | const struct i2c_device_id *id) | ||
561 | { | ||
562 | int rc; | ||
563 | struct tpm_chip *chip; | ||
564 | struct device *dev = &client->dev; | ||
565 | u32 vid = 0; | ||
566 | |||
567 | rc = get_vid(client, &vid); | ||
568 | if (rc) | ||
569 | return rc; | ||
570 | |||
571 | dev_info(dev, "VID: %04X DID: %02X RID: %02X\n", (u16) vid, | ||
572 | (u8) (vid >> 16), (u8) (vid >> 24)); | ||
573 | |||
574 | chip = tpm_register_hardware(dev, &tpm_i2c); | ||
575 | if (!chip) { | ||
576 | dev_err(dev, "%s() error in tpm_register_hardware\n", __func__); | ||
577 | return -ENODEV; | ||
578 | } | ||
579 | |||
580 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), | ||
581 | GFP_KERNEL); | ||
582 | init_waitqueue_head(&chip->vendor.read_queue); | ||
583 | init_waitqueue_head(&chip->vendor.int_queue); | ||
584 | |||
585 | /* Default timeouts */ | ||
586 | chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
587 | chip->vendor.timeout_b = msecs_to_jiffies(TPM_I2C_LONG_TIMEOUT); | ||
588 | chip->vendor.timeout_c = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
589 | chip->vendor.timeout_d = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
590 | |||
591 | /* | ||
592 | * I2C intfcaps (interrupt capabilitieis) in the chip are hard coded to: | ||
593 | * TPM_INTF_INT_LEVEL_LOW | TPM_INTF_DATA_AVAIL_INT | ||
594 | * The IRQ should be set in the i2c_board_info (which is done | ||
595 | * automatically in of_i2c_register_devices, for device tree users */ | ||
596 | chip->vendor.irq = client->irq; | ||
597 | |||
598 | if (chip->vendor.irq) { | ||
599 | dev_dbg(dev, "%s() chip-vendor.irq\n", __func__); | ||
600 | rc = devm_request_irq(dev, chip->vendor.irq, | ||
601 | i2c_nuvoton_int_handler, | ||
602 | IRQF_TRIGGER_LOW, | ||
603 | chip->vendor.miscdev.name, | ||
604 | chip); | ||
605 | if (rc) { | ||
606 | dev_err(dev, "%s() Unable to request irq: %d for use\n", | ||
607 | __func__, chip->vendor.irq); | ||
608 | chip->vendor.irq = 0; | ||
609 | } else { | ||
610 | /* Clear any pending interrupt */ | ||
611 | i2c_nuvoton_ready(chip); | ||
612 | /* - wait for TPM_STS==0xA0 (stsValid, commandReady) */ | ||
613 | rc = i2c_nuvoton_wait_for_stat(chip, | ||
614 | TPM_STS_COMMAND_READY, | ||
615 | TPM_STS_COMMAND_READY, | ||
616 | chip->vendor.timeout_b, | ||
617 | NULL); | ||
618 | if (rc == 0) { | ||
619 | /* | ||
620 | * TIS is in ready state | ||
621 | * write dummy byte to enter reception state | ||
622 | * TPM_DATA_FIFO_W <- rc (0) | ||
623 | */ | ||
624 | rc = i2c_nuvoton_write_buf(client, | ||
625 | TPM_DATA_FIFO_W, | ||
626 | 1, (u8 *) (&rc)); | ||
627 | if (rc < 0) | ||
628 | goto out_err; | ||
629 | /* TPM_STS <- 0x40 (commandReady) */ | ||
630 | i2c_nuvoton_ready(chip); | ||
631 | } else { | ||
632 | /* | ||
633 | * timeout_b reached - command was | ||
634 | * aborted. TIS should now be in idle state - | ||
635 | * only TPM_STS_VALID should be set | ||
636 | */ | ||
637 | if (i2c_nuvoton_read_status(chip) != | ||
638 | TPM_STS_VALID) { | ||
639 | rc = -EIO; | ||
640 | goto out_err; | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | |||
646 | if (tpm_get_timeouts(chip)) { | ||
647 | rc = -ENODEV; | ||
648 | goto out_err; | ||
649 | } | ||
650 | |||
651 | if (tpm_do_selftest(chip)) { | ||
652 | rc = -ENODEV; | ||
653 | goto out_err; | ||
654 | } | ||
655 | |||
656 | return 0; | ||
657 | |||
658 | out_err: | ||
659 | tpm_dev_vendor_release(chip); | ||
660 | tpm_remove_hardware(chip->dev); | ||
661 | return rc; | ||
662 | } | ||
663 | |||
664 | static int i2c_nuvoton_remove(struct i2c_client *client) | ||
665 | { | ||
666 | struct device *dev = &(client->dev); | ||
667 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
668 | |||
669 | if (chip) | ||
670 | tpm_dev_vendor_release(chip); | ||
671 | tpm_remove_hardware(dev); | ||
672 | kfree(chip); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | |||
677 | static const struct i2c_device_id i2c_nuvoton_id[] = { | ||
678 | {I2C_DRIVER_NAME, 0}, | ||
679 | {} | ||
680 | }; | ||
681 | MODULE_DEVICE_TABLE(i2c, i2c_nuvoton_id); | ||
682 | |||
683 | #ifdef CONFIG_OF | ||
684 | static const struct of_device_id i2c_nuvoton_of_match[] = { | ||
685 | {.compatible = "nuvoton,npct501"}, | ||
686 | {.compatible = "winbond,wpct301"}, | ||
687 | {}, | ||
688 | }; | ||
689 | MODULE_DEVICE_TABLE(of, i2c_nuvoton_of_match); | ||
690 | #endif | ||
691 | |||
692 | static SIMPLE_DEV_PM_OPS(i2c_nuvoton_pm_ops, tpm_pm_suspend, tpm_pm_resume); | ||
693 | |||
694 | static struct i2c_driver i2c_nuvoton_driver = { | ||
695 | .id_table = i2c_nuvoton_id, | ||
696 | .probe = i2c_nuvoton_probe, | ||
697 | .remove = i2c_nuvoton_remove, | ||
698 | .driver = { | ||
699 | .name = I2C_DRIVER_NAME, | ||
700 | .owner = THIS_MODULE, | ||
701 | .pm = &i2c_nuvoton_pm_ops, | ||
702 | .of_match_table = of_match_ptr(i2c_nuvoton_of_match), | ||
703 | }, | ||
704 | }; | ||
705 | |||
706 | module_i2c_driver(i2c_nuvoton_driver); | ||
707 | |||
708 | MODULE_AUTHOR("Dan Morav (dan.morav@nuvoton.com)"); | ||
709 | MODULE_DESCRIPTION("Nuvoton TPM I2C Driver"); | ||
710 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 5bb8e2ddd3b3..a0d6ceb5d005 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c | |||
@@ -584,7 +584,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | |||
584 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | 584 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); |
585 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | 585 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); |
586 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | 586 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); |
587 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | 587 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); |
588 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 588 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
589 | 589 | ||
590 | static struct attribute *stm_tpm_attrs[] = { | 590 | static struct attribute *stm_tpm_attrs[] = { |
@@ -746,8 +746,6 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
746 | 746 | ||
747 | tpm_get_timeouts(chip); | 747 | tpm_get_timeouts(chip); |
748 | 748 | ||
749 | i2c_set_clientdata(client, chip); | ||
750 | |||
751 | dev_info(chip->dev, "TPM I2C Initialized\n"); | 749 | dev_info(chip->dev, "TPM I2C Initialized\n"); |
752 | return 0; | 750 | return 0; |
753 | _irq_set: | 751 | _irq_set: |
@@ -807,24 +805,18 @@ static int tpm_st33_i2c_remove(struct i2c_client *client) | |||
807 | #ifdef CONFIG_PM_SLEEP | 805 | #ifdef CONFIG_PM_SLEEP |
808 | /* | 806 | /* |
809 | * tpm_st33_i2c_pm_suspend suspend the TPM device | 807 | * tpm_st33_i2c_pm_suspend suspend the TPM device |
810 | * Added: Work around when suspend and no tpm application is running, suspend | ||
811 | * may fail because chip->data_buffer is not set (only set in tpm_open in Linux | ||
812 | * TPM core) | ||
813 | * @param: client, the i2c_client drescription (TPM I2C description). | 808 | * @param: client, the i2c_client drescription (TPM I2C description). |
814 | * @param: mesg, the power management message. | 809 | * @param: mesg, the power management message. |
815 | * @return: 0 in case of success. | 810 | * @return: 0 in case of success. |
816 | */ | 811 | */ |
817 | static int tpm_st33_i2c_pm_suspend(struct device *dev) | 812 | static int tpm_st33_i2c_pm_suspend(struct device *dev) |
818 | { | 813 | { |
819 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
820 | struct st33zp24_platform_data *pin_infos = dev->platform_data; | 814 | struct st33zp24_platform_data *pin_infos = dev->platform_data; |
821 | int ret = 0; | 815 | int ret = 0; |
822 | 816 | ||
823 | if (power_mgt) { | 817 | if (power_mgt) { |
824 | gpio_set_value(pin_infos->io_lpcpd, 0); | 818 | gpio_set_value(pin_infos->io_lpcpd, 0); |
825 | } else { | 819 | } else { |
826 | if (chip->data_buffer == NULL) | ||
827 | chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; | ||
828 | ret = tpm_pm_suspend(dev); | 820 | ret = tpm_pm_suspend(dev); |
829 | } | 821 | } |
830 | return ret; | 822 | return ret; |
@@ -849,8 +841,6 @@ static int tpm_st33_i2c_pm_resume(struct device *dev) | |||
849 | TPM_STS_VALID) == TPM_STS_VALID, | 841 | TPM_STS_VALID) == TPM_STS_VALID, |
850 | chip->vendor.timeout_b); | 842 | chip->vendor.timeout_b); |
851 | } else { | 843 | } else { |
852 | if (chip->data_buffer == NULL) | ||
853 | chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; | ||
854 | ret = tpm_pm_resume(dev); | 844 | ret = tpm_pm_resume(dev); |
855 | if (!ret) | 845 | if (!ret) |
856 | tpm_do_selftest(chip); | 846 | tpm_do_selftest(chip); |
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 56b07c35a13e..2783a42aa732 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c | |||
@@ -98,7 +98,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
98 | 98 | ||
99 | if (count < len) { | 99 | if (count < len) { |
100 | dev_err(ibmvtpm->dev, | 100 | dev_err(ibmvtpm->dev, |
101 | "Invalid size in recv: count=%ld, crq_size=%d\n", | 101 | "Invalid size in recv: count=%zd, crq_size=%d\n", |
102 | count, len); | 102 | count, len); |
103 | return -EIO; | 103 | return -EIO; |
104 | } | 104 | } |
@@ -136,7 +136,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
136 | 136 | ||
137 | if (count > ibmvtpm->rtce_size) { | 137 | if (count > ibmvtpm->rtce_size) { |
138 | dev_err(ibmvtpm->dev, | 138 | dev_err(ibmvtpm->dev, |
139 | "Invalid size in send: count=%ld, rtce_size=%d\n", | 139 | "Invalid size in send: count=%zd, rtce_size=%d\n", |
140 | count, ibmvtpm->rtce_size); | 140 | count, ibmvtpm->rtce_size); |
141 | return -EIO; | 141 | return -EIO; |
142 | } | 142 | } |
@@ -419,7 +419,7 @@ static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | |||
419 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | 419 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); |
420 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | 420 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, |
421 | NULL); | 421 | NULL); |
422 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | 422 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); |
423 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 423 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
424 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | 424 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); |
425 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | 425 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); |
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index 2168d15bc728..8e562dc65601 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
@@ -452,12 +452,8 @@ int tpm_add_ppi(struct kobject *parent) | |||
452 | { | 452 | { |
453 | return sysfs_create_group(parent, &ppi_attr_grp); | 453 | return sysfs_create_group(parent, &ppi_attr_grp); |
454 | } | 454 | } |
455 | EXPORT_SYMBOL_GPL(tpm_add_ppi); | ||
456 | 455 | ||
457 | void tpm_remove_ppi(struct kobject *parent) | 456 | void tpm_remove_ppi(struct kobject *parent) |
458 | { | 457 | { |
459 | sysfs_remove_group(parent, &ppi_attr_grp); | 458 | sysfs_remove_group(parent, &ppi_attr_grp); |
460 | } | 459 | } |
461 | EXPORT_SYMBOL_GPL(tpm_remove_ppi); | ||
462 | |||
463 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 4519cb332987..1b74459c0723 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -448,7 +448,7 @@ static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | |||
448 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | 448 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); |
449 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | 449 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, |
450 | NULL); | 450 | NULL); |
451 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | 451 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); |
452 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 452 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
453 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | 453 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); |
454 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | 454 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); |
@@ -766,6 +766,25 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) | |||
766 | } | 766 | } |
767 | #endif | 767 | #endif |
768 | 768 | ||
769 | #ifdef CONFIG_PM_SLEEP | ||
770 | static int tpm_tis_resume(struct device *dev) | ||
771 | { | ||
772 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
773 | int ret; | ||
774 | |||
775 | if (chip->vendor.irq) | ||
776 | tpm_tis_reenable_interrupts(chip); | ||
777 | |||
778 | ret = tpm_pm_resume(dev); | ||
779 | if (!ret) | ||
780 | tpm_do_selftest(chip); | ||
781 | |||
782 | return ret; | ||
783 | } | ||
784 | #endif | ||
785 | |||
786 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); | ||
787 | |||
769 | #ifdef CONFIG_PNP | 788 | #ifdef CONFIG_PNP |
770 | static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | 789 | static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, |
771 | const struct pnp_device_id *pnp_id) | 790 | const struct pnp_device_id *pnp_id) |
@@ -787,26 +806,6 @@ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
787 | return tpm_tis_init(&pnp_dev->dev, start, len, irq); | 806 | return tpm_tis_init(&pnp_dev->dev, start, len, irq); |
788 | } | 807 | } |
789 | 808 | ||
790 | static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) | ||
791 | { | ||
792 | return tpm_pm_suspend(&dev->dev); | ||
793 | } | ||
794 | |||
795 | static int tpm_tis_pnp_resume(struct pnp_dev *dev) | ||
796 | { | ||
797 | struct tpm_chip *chip = pnp_get_drvdata(dev); | ||
798 | int ret; | ||
799 | |||
800 | if (chip->vendor.irq) | ||
801 | tpm_tis_reenable_interrupts(chip); | ||
802 | |||
803 | ret = tpm_pm_resume(&dev->dev); | ||
804 | if (!ret) | ||
805 | tpm_do_selftest(chip); | ||
806 | |||
807 | return ret; | ||
808 | } | ||
809 | |||
810 | static struct pnp_device_id tpm_pnp_tbl[] = { | 809 | static struct pnp_device_id tpm_pnp_tbl[] = { |
811 | {"PNP0C31", 0}, /* TPM */ | 810 | {"PNP0C31", 0}, /* TPM */ |
812 | {"ATM1200", 0}, /* Atmel */ | 811 | {"ATM1200", 0}, /* Atmel */ |
@@ -835,9 +834,12 @@ static struct pnp_driver tis_pnp_driver = { | |||
835 | .name = "tpm_tis", | 834 | .name = "tpm_tis", |
836 | .id_table = tpm_pnp_tbl, | 835 | .id_table = tpm_pnp_tbl, |
837 | .probe = tpm_tis_pnp_init, | 836 | .probe = tpm_tis_pnp_init, |
838 | .suspend = tpm_tis_pnp_suspend, | ||
839 | .resume = tpm_tis_pnp_resume, | ||
840 | .remove = tpm_tis_pnp_remove, | 837 | .remove = tpm_tis_pnp_remove, |
838 | #ifdef CONFIG_PM_SLEEP | ||
839 | .driver = { | ||
840 | .pm = &tpm_tis_pm, | ||
841 | }, | ||
842 | #endif | ||
841 | }; | 843 | }; |
842 | 844 | ||
843 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 | 845 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 |
@@ -846,20 +848,6 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | |||
846 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | 848 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); |
847 | #endif | 849 | #endif |
848 | 850 | ||
849 | #ifdef CONFIG_PM_SLEEP | ||
850 | static int tpm_tis_resume(struct device *dev) | ||
851 | { | ||
852 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
853 | |||
854 | if (chip->vendor.irq) | ||
855 | tpm_tis_reenable_interrupts(chip); | ||
856 | |||
857 | return tpm_pm_resume(dev); | ||
858 | } | ||
859 | #endif | ||
860 | |||
861 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); | ||
862 | |||
863 | static struct platform_driver tis_drv = { | 851 | static struct platform_driver tis_drv = { |
864 | .driver = { | 852 | .driver = { |
865 | .name = "tpm_tis", | 853 | .name = "tpm_tis", |
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 7a7929ba2658..c8ff4df81779 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <xen/xen.h> | ||
13 | #include <xen/events.h> | 14 | #include <xen/events.h> |
14 | #include <xen/interface/io/tpmif.h> | 15 | #include <xen/interface/io/tpmif.h> |
15 | #include <xen/grant_table.h> | 16 | #include <xen/grant_table.h> |
@@ -142,32 +143,6 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
142 | return length; | 143 | return length; |
143 | } | 144 | } |
144 | 145 | ||
145 | ssize_t tpm_show_locality(struct device *dev, struct device_attribute *attr, | ||
146 | char *buf) | ||
147 | { | ||
148 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
149 | struct tpm_private *priv = TPM_VPRIV(chip); | ||
150 | u8 locality = priv->shr->locality; | ||
151 | |||
152 | return sprintf(buf, "%d\n", locality); | ||
153 | } | ||
154 | |||
155 | ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr, | ||
156 | const char *buf, size_t len) | ||
157 | { | ||
158 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
159 | struct tpm_private *priv = TPM_VPRIV(chip); | ||
160 | u8 val; | ||
161 | |||
162 | int rv = kstrtou8(buf, 0, &val); | ||
163 | if (rv) | ||
164 | return rv; | ||
165 | |||
166 | priv->shr->locality = val; | ||
167 | |||
168 | return len; | ||
169 | } | ||
170 | |||
171 | static const struct file_operations vtpm_ops = { | 146 | static const struct file_operations vtpm_ops = { |
172 | .owner = THIS_MODULE, | 147 | .owner = THIS_MODULE, |
173 | .llseek = no_llseek, | 148 | .llseek = no_llseek, |
@@ -188,8 +163,6 @@ static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | |||
188 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 163 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
189 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | 164 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); |
190 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | 165 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); |
191 | static DEVICE_ATTR(locality, S_IRUGO | S_IWUSR, tpm_show_locality, | ||
192 | tpm_store_locality); | ||
193 | 166 | ||
194 | static struct attribute *vtpm_attrs[] = { | 167 | static struct attribute *vtpm_attrs[] = { |
195 | &dev_attr_pubek.attr, | 168 | &dev_attr_pubek.attr, |
@@ -202,7 +175,6 @@ static struct attribute *vtpm_attrs[] = { | |||
202 | &dev_attr_cancel.attr, | 175 | &dev_attr_cancel.attr, |
203 | &dev_attr_durations.attr, | 176 | &dev_attr_durations.attr, |
204 | &dev_attr_timeouts.attr, | 177 | &dev_attr_timeouts.attr, |
205 | &dev_attr_locality.attr, | ||
206 | NULL, | 178 | NULL, |
207 | }; | 179 | }; |
208 | 180 | ||
@@ -210,8 +182,6 @@ static struct attribute_group vtpm_attr_grp = { | |||
210 | .attrs = vtpm_attrs, | 182 | .attrs = vtpm_attrs, |
211 | }; | 183 | }; |
212 | 184 | ||
213 | #define TPM_LONG_TIMEOUT (10 * 60 * HZ) | ||
214 | |||
215 | static const struct tpm_vendor_specific tpm_vtpm = { | 185 | static const struct tpm_vendor_specific tpm_vtpm = { |
216 | .status = vtpm_status, | 186 | .status = vtpm_status, |
217 | .recv = vtpm_recv, | 187 | .recv = vtpm_recv, |
@@ -224,11 +194,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { | |||
224 | .miscdev = { | 194 | .miscdev = { |
225 | .fops = &vtpm_ops, | 195 | .fops = &vtpm_ops, |
226 | }, | 196 | }, |
227 | .duration = { | ||
228 | TPM_LONG_TIMEOUT, | ||
229 | TPM_LONG_TIMEOUT, | ||
230 | TPM_LONG_TIMEOUT, | ||
231 | }, | ||
232 | }; | 197 | }; |
233 | 198 | ||
234 | static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) | 199 | static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) |
@@ -386,8 +351,6 @@ static int tpmfront_probe(struct xenbus_device *dev, | |||
386 | 351 | ||
387 | tpm_get_timeouts(priv->chip); | 352 | tpm_get_timeouts(priv->chip); |
388 | 353 | ||
389 | dev_set_drvdata(&dev->dev, priv->chip); | ||
390 | |||
391 | return rv; | 354 | return rv; |
392 | } | 355 | } |
393 | 356 | ||
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index fc45567ad3ac..feea87cc6b8f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -577,7 +577,8 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, | |||
577 | spin_lock(&portdev->c_ovq_lock); | 577 | spin_lock(&portdev->c_ovq_lock); |
578 | if (virtqueue_add_outbuf(vq, sg, 1, &cpkt, GFP_ATOMIC) == 0) { | 578 | if (virtqueue_add_outbuf(vq, sg, 1, &cpkt, GFP_ATOMIC) == 0) { |
579 | virtqueue_kick(vq); | 579 | virtqueue_kick(vq); |
580 | while (!virtqueue_get_buf(vq, &len)) | 580 | while (!virtqueue_get_buf(vq, &len) |
581 | && !virtqueue_is_broken(vq)) | ||
581 | cpu_relax(); | 582 | cpu_relax(); |
582 | } | 583 | } |
583 | spin_unlock(&portdev->c_ovq_lock); | 584 | spin_unlock(&portdev->c_ovq_lock); |
@@ -650,7 +651,8 @@ static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, | |||
650 | * we need to kmalloc a GFP_ATOMIC buffer each time the | 651 | * we need to kmalloc a GFP_ATOMIC buffer each time the |
651 | * console driver writes something out. | 652 | * console driver writes something out. |
652 | */ | 653 | */ |
653 | while (!virtqueue_get_buf(out_vq, &len)) | 654 | while (!virtqueue_get_buf(out_vq, &len) |
655 | && !virtqueue_is_broken(out_vq)) | ||
654 | cpu_relax(); | 656 | cpu_relax(); |
655 | done: | 657 | done: |
656 | spin_unlock_irqrestore(&port->outvq_lock, flags); | 658 | spin_unlock_irqrestore(&port->outvq_lock, flags); |
@@ -1529,18 +1531,22 @@ static void remove_port_data(struct port *port) | |||
1529 | { | 1531 | { |
1530 | struct port_buffer *buf; | 1532 | struct port_buffer *buf; |
1531 | 1533 | ||
1534 | spin_lock_irq(&port->inbuf_lock); | ||
1532 | /* Remove unused data this port might have received. */ | 1535 | /* Remove unused data this port might have received. */ |
1533 | discard_port_data(port); | 1536 | discard_port_data(port); |
1534 | 1537 | ||
1535 | reclaim_consumed_buffers(port); | ||
1536 | |||
1537 | /* Remove buffers we queued up for the Host to send us data in. */ | 1538 | /* Remove buffers we queued up for the Host to send us data in. */ |
1538 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) | 1539 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) |
1539 | free_buf(buf, true); | 1540 | free_buf(buf, true); |
1541 | spin_unlock_irq(&port->inbuf_lock); | ||
1542 | |||
1543 | spin_lock_irq(&port->outvq_lock); | ||
1544 | reclaim_consumed_buffers(port); | ||
1540 | 1545 | ||
1541 | /* Free pending buffers from the out-queue. */ | 1546 | /* Free pending buffers from the out-queue. */ |
1542 | while ((buf = virtqueue_detach_unused_buf(port->out_vq))) | 1547 | while ((buf = virtqueue_detach_unused_buf(port->out_vq))) |
1543 | free_buf(buf, true); | 1548 | free_buf(buf, true); |
1549 | spin_unlock_irq(&port->outvq_lock); | ||
1544 | } | 1550 | } |
1545 | 1551 | ||
1546 | /* | 1552 | /* |
@@ -1554,6 +1560,7 @@ static void unplug_port(struct port *port) | |||
1554 | list_del(&port->list); | 1560 | list_del(&port->list); |
1555 | spin_unlock_irq(&port->portdev->ports_lock); | 1561 | spin_unlock_irq(&port->portdev->ports_lock); |
1556 | 1562 | ||
1563 | spin_lock_irq(&port->inbuf_lock); | ||
1557 | if (port->guest_connected) { | 1564 | if (port->guest_connected) { |
1558 | /* Let the app know the port is going down. */ | 1565 | /* Let the app know the port is going down. */ |
1559 | send_sigio_to_port(port); | 1566 | send_sigio_to_port(port); |
@@ -1564,6 +1571,7 @@ static void unplug_port(struct port *port) | |||
1564 | 1571 | ||
1565 | wake_up_interruptible(&port->waitqueue); | 1572 | wake_up_interruptible(&port->waitqueue); |
1566 | } | 1573 | } |
1574 | spin_unlock_irq(&port->inbuf_lock); | ||
1567 | 1575 | ||
1568 | if (is_console_port(port)) { | 1576 | if (is_console_port(port)) { |
1569 | spin_lock_irq(&pdrvdata_lock); | 1577 | spin_lock_irq(&pdrvdata_lock); |
@@ -1585,9 +1593,8 @@ static void unplug_port(struct port *port) | |||
1585 | device_destroy(pdrvdata.class, port->dev->devt); | 1593 | device_destroy(pdrvdata.class, port->dev->devt); |
1586 | cdev_del(port->cdev); | 1594 | cdev_del(port->cdev); |
1587 | 1595 | ||
1588 | kfree(port->name); | ||
1589 | |||
1590 | debugfs_remove(port->debugfs_file); | 1596 | debugfs_remove(port->debugfs_file); |
1597 | kfree(port->name); | ||
1591 | 1598 | ||
1592 | /* | 1599 | /* |
1593 | * Locks around here are not necessary - a port can't be | 1600 | * Locks around here are not necessary - a port can't be |
@@ -1681,7 +1688,9 @@ static void handle_control_message(struct ports_device *portdev, | |||
1681 | * If the guest is connected, it'll be interested in | 1688 | * If the guest is connected, it'll be interested in |
1682 | * knowing the host connection state changed. | 1689 | * knowing the host connection state changed. |
1683 | */ | 1690 | */ |
1691 | spin_lock_irq(&port->inbuf_lock); | ||
1684 | send_sigio_to_port(port); | 1692 | send_sigio_to_port(port); |
1693 | spin_unlock_irq(&port->inbuf_lock); | ||
1685 | break; | 1694 | break; |
1686 | case VIRTIO_CONSOLE_PORT_NAME: | 1695 | case VIRTIO_CONSOLE_PORT_NAME: |
1687 | /* | 1696 | /* |
@@ -1801,13 +1810,13 @@ static void in_intr(struct virtqueue *vq) | |||
1801 | if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) | 1810 | if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) |
1802 | discard_port_data(port); | 1811 | discard_port_data(port); |
1803 | 1812 | ||
1813 | /* Send a SIGIO indicating new data in case the process asked for it */ | ||
1814 | send_sigio_to_port(port); | ||
1815 | |||
1804 | spin_unlock_irqrestore(&port->inbuf_lock, flags); | 1816 | spin_unlock_irqrestore(&port->inbuf_lock, flags); |
1805 | 1817 | ||
1806 | wake_up_interruptible(&port->waitqueue); | 1818 | wake_up_interruptible(&port->waitqueue); |
1807 | 1819 | ||
1808 | /* Send a SIGIO indicating new data in case the process asked for it */ | ||
1809 | send_sigio_to_port(port); | ||
1810 | |||
1811 | if (is_console_port(port) && hvc_poll(port->cons.hvc)) | 1820 | if (is_console_port(port) && hvc_poll(port->cons.hvc)) |
1812 | hvc_kick(); | 1821 | hvc_kick(); |
1813 | } | 1822 | } |
@@ -1830,12 +1839,8 @@ static void config_intr(struct virtio_device *vdev) | |||
1830 | struct port *port; | 1839 | struct port *port; |
1831 | u16 rows, cols; | 1840 | u16 rows, cols; |
1832 | 1841 | ||
1833 | vdev->config->get(vdev, | 1842 | virtio_cread(vdev, struct virtio_console_config, cols, &cols); |
1834 | offsetof(struct virtio_console_config, cols), | 1843 | virtio_cread(vdev, struct virtio_console_config, rows, &rows); |
1835 | &cols, sizeof(u16)); | ||
1836 | vdev->config->get(vdev, | ||
1837 | offsetof(struct virtio_console_config, rows), | ||
1838 | &rows, sizeof(u16)); | ||
1839 | 1844 | ||
1840 | port = find_port_by_id(portdev, 0); | 1845 | port = find_port_by_id(portdev, 0); |
1841 | set_console_size(port, rows, cols); | 1846 | set_console_size(port, rows, cols); |
@@ -2007,10 +2012,9 @@ static int virtcons_probe(struct virtio_device *vdev) | |||
2007 | 2012 | ||
2008 | /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */ | 2013 | /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */ |
2009 | if (!is_rproc_serial(vdev) && | 2014 | if (!is_rproc_serial(vdev) && |
2010 | virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT, | 2015 | virtio_cread_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT, |
2011 | offsetof(struct virtio_console_config, | 2016 | struct virtio_console_config, max_nr_ports, |
2012 | max_nr_ports), | 2017 | &portdev->config.max_nr_ports) == 0) { |
2013 | &portdev->config.max_nr_ports) == 0) { | ||
2014 | multiport = true; | 2018 | multiport = true; |
2015 | } | 2019 | } |
2016 | 2020 | ||
@@ -2135,7 +2139,7 @@ static struct virtio_device_id rproc_serial_id_table[] = { | |||
2135 | static unsigned int rproc_serial_features[] = { | 2139 | static unsigned int rproc_serial_features[] = { |
2136 | }; | 2140 | }; |
2137 | 2141 | ||
2138 | #ifdef CONFIG_PM | 2142 | #ifdef CONFIG_PM_SLEEP |
2139 | static int virtcons_freeze(struct virtio_device *vdev) | 2143 | static int virtcons_freeze(struct virtio_device *vdev) |
2140 | { | 2144 | { |
2141 | struct ports_device *portdev; | 2145 | struct ports_device *portdev; |
@@ -2213,7 +2217,7 @@ static struct virtio_driver virtio_console = { | |||
2213 | .probe = virtcons_probe, | 2217 | .probe = virtcons_probe, |
2214 | .remove = virtcons_remove, | 2218 | .remove = virtcons_remove, |
2215 | .config_changed = config_intr, | 2219 | .config_changed = config_intr, |
2216 | #ifdef CONFIG_PM | 2220 | #ifdef CONFIG_PM_SLEEP |
2217 | .freeze = virtcons_freeze, | 2221 | .freeze = virtcons_freeze, |
2218 | .restore = virtcons_restore, | 2222 | .restore = virtcons_restore, |
2219 | #endif | 2223 | #endif |
@@ -2241,10 +2245,8 @@ static int __init init(void) | |||
2241 | } | 2245 | } |
2242 | 2246 | ||
2243 | pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL); | 2247 | pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL); |
2244 | if (!pdrvdata.debugfs_dir) { | 2248 | if (!pdrvdata.debugfs_dir) |
2245 | pr_warning("Error %ld creating debugfs dir for virtio-ports\n", | 2249 | pr_warning("Error creating debugfs dir for virtio-ports\n"); |
2246 | PTR_ERR(pdrvdata.debugfs_dir)); | ||
2247 | } | ||
2248 | INIT_LIST_HEAD(&pdrvdata.consoles); | 2250 | INIT_LIST_HEAD(&pdrvdata.consoles); |
2249 | INIT_LIST_HEAD(&pdrvdata.portdevs); | 2251 | INIT_LIST_HEAD(&pdrvdata.portdevs); |
2250 | 2252 | ||
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 5224da5202d3..f6345f932e46 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
@@ -721,7 +721,7 @@ static int hwicap_remove(struct device *dev) | |||
721 | { | 721 | { |
722 | struct hwicap_drvdata *drvdata; | 722 | struct hwicap_drvdata *drvdata; |
723 | 723 | ||
724 | drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev); | 724 | drvdata = dev_get_drvdata(dev); |
725 | 725 | ||
726 | if (!drvdata) | 726 | if (!drvdata) |
727 | return 0; | 727 | return 0; |
@@ -731,7 +731,6 @@ static int hwicap_remove(struct device *dev) | |||
731 | iounmap(drvdata->base_address); | 731 | iounmap(drvdata->base_address); |
732 | release_mem_region(drvdata->mem_start, drvdata->mem_size); | 732 | release_mem_region(drvdata->mem_start, drvdata->mem_size); |
733 | kfree(drvdata); | 733 | kfree(drvdata); |
734 | dev_set_drvdata(dev, NULL); | ||
735 | 734 | ||
736 | mutex_lock(&icap_sem); | 735 | mutex_lock(&icap_sem); |
737 | probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0; | 736 | probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0; |