aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 12:33:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 12:33:34 -0400
commit346ad4b7fe392571f19314f153db9151dbc1d82b (patch)
tree2d4085338c9044bca2f6472893da60387db3c96f /drivers/char
parent845199f194306dbd69ca42d3b40a5125cdb50b89 (diff)
parent2dc63a84b2db23b9680646aff93917211613bf1a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (85 commits) Blackfin char driver for Blackfin on-chip OTP memory (v3) Blackfin Serial Driver: fix bug - use mod_timer to replace only add_timer. Blackfin Serial Driver: the uart break anomaly has been given its own number, so switch to it Blackfin Serial Driver: use BFIN_UART_NR_PORTS to help SIR driver in uart port. Blackfin Serial Driver: Fix bug - kernel hangs when accessing uart 0 on bf537 when booting u-boot and linux on uart 1 Blackfin Serial Driver: punt unused lsr variable Blackfin Serial Driver: Enable IR function when user application (irattach /dev/ttyBFx -s) call TIOCSETD ioctl with line discipline N_IRDA [Blackfin] arch: add include/boot .gitignore files [Blackfin] arch: Functional power management support: Add support for cpu frequency scaling [Blackfin] arch: Functional power management support: Remove broken cpu frequency scaling drivers [Blackfin] arch: Equalize include files: Add PLL_DIV Masks [Blackfin] arch: Add a warning about the value of CLKIN. [Blackfin] arch: take DDR DEVWD into consideration as well for BF548 [Blackfin] arch: Remove the circular buffering mechanism for exceptions [Blackfin] arch: lose unnecessary dependency on CONFIG_BFIN_ICACHE for MPU [Blackfin] arch: fix bug - before assign new channel to the map register, need clear the bits first. [Blackfin] arch: add Blackfin on-chip SIR IrDA driver support [Blackfin] arch: BF54x memsizes are in mbits, not mbytes [Blackfin] arch: try to remove condition that causes double fault, by checking current before it gets dereferenced [Blackfin] arch: Update anomaly list. ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig28
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/bfin-otp.c189
3 files changed, 218 insertions, 0 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index a87b89db08e9..2906ee7bd298 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -481,6 +481,34 @@ config BRIQ_PANEL
481 481
482 It's safe to say N here. 482 It's safe to say N here.
483 483
484config BFIN_OTP
485 tristate "Blackfin On-Chip OTP Memory Support"
486 depends on BLACKFIN && (BF52x || BF54x)
487 default y
488 help
489 If you say Y here, you will get support for a character device
490 interface into the One Time Programmable memory pages that are
491 stored on the Blackfin processor. This will not get you access
492 to the secure memory pages however. You will need to write your
493 own secure code and reader for that.
494
495 To compile this driver as a module, choose M here: the module
496 will be called bfin-otp.
497
498 If unsure, it is safe to say Y.
499
500config BFIN_OTP_WRITE_ENABLE
501 bool "Enable writing support of OTP pages"
502 depends on BFIN_OTP
503 default n
504 help
505 If you say Y here, you will enable support for writing of the
506 OTP pages. This is dangerous by nature as you can only program
507 the pages once, so only enable this option when you actually
508 need it so as to not inadvertently clobber data.
509
510 If unsure, say N.
511
484config PRINTER 512config PRINTER
485 tristate "Parallel printer support" 513 tristate "Parallel printer support"
486 depends on PARPORT 514 depends on PARPORT
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 5407b7615614..4c1c584e9eb6 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_VIOTAPE) += viotape.o
59obj-$(CONFIG_HVCS) += hvcs.o 59obj-$(CONFIG_HVCS) += hvcs.o
60obj-$(CONFIG_SGI_MBCS) += mbcs.o 60obj-$(CONFIG_SGI_MBCS) += mbcs.o
61obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o 61obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
62obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
62 63
63obj-$(CONFIG_PRINTER) += lp.o 64obj-$(CONFIG_PRINTER) += lp.o
64obj-$(CONFIG_TIPAR) += tipar.o 65obj-$(CONFIG_TIPAR) += tipar.o
diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c
new file mode 100644
index 000000000000..0a01329451e4
--- /dev/null
+++ b/drivers/char/bfin-otp.c
@@ -0,0 +1,189 @@
1/*
2 * Blackfin On-Chip OTP Memory Interface
3 * Supports BF52x/BF54x
4 *
5 * Copyright 2007-2008 Analog Devices Inc.
6 *
7 * Enter bugs at http://blackfin.uclinux.org/
8 *
9 * Licensed under the GPL-2 or later.
10 */
11
12#include <linux/device.h>
13#include <linux/errno.h>
14#include <linux/fs.h>
15#include <linux/init.h>
16#include <linux/miscdevice.h>
17#include <linux/module.h>
18#include <linux/mutex.h>
19#include <linux/types.h>
20
21#include <asm/blackfin.h>
22#include <asm/uaccess.h>
23
24#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
25#define stampit() stamp("here i am")
26#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); })
27
28#define DRIVER_NAME "bfin-otp"
29#define PFX DRIVER_NAME ": "
30
31static DEFINE_MUTEX(bfin_otp_lock);
32
33/* OTP Boot ROM functions */
34#define _BOOTROM_OTP_COMMAND 0xEF000018
35#define _BOOTROM_OTP_READ 0xEF00001A
36#define _BOOTROM_OTP_WRITE 0xEF00001C
37
38static u32 (* const otp_command)(u32 command, u32 value) = (void *)_BOOTROM_OTP_COMMAND;
39static u32 (* const otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)_BOOTROM_OTP_READ;
40static u32 (* const otp_write)(u32 page, u32 flags, u64 *page_content) = (void *)_BOOTROM_OTP_WRITE;
41
42/* otp_command(): defines for "command" */
43#define OTP_INIT 0x00000001
44#define OTP_CLOSE 0x00000002
45
46/* otp_{read,write}(): defines for "flags" */
47#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */
48#define OTP_UPPER_HALF 0x00000001
49#define OTP_NO_ECC 0x00000010 /* do not use ECC */
50#define OTP_LOCK 0x00000020 /* sets page protection bit for page */
51#define OTP_ACCESS_READ 0x00001000
52#define OTP_ACCESS_READWRITE 0x00002000
53
54/* Return values for all functions */
55#define OTP_SUCCESS 0x00000000
56#define OTP_MASTER_ERROR 0x001
57#define OTP_WRITE_ERROR 0x003
58#define OTP_READ_ERROR 0x005
59#define OTP_ACC_VIO_ERROR 0x009
60#define OTP_DATA_MULT_ERROR 0x011
61#define OTP_ECC_MULT_ERROR 0x021
62#define OTP_PREV_WR_ERROR 0x041
63#define OTP_DATA_SB_WARN 0x100
64#define OTP_ECC_SB_WARN 0x200
65
66/**
67 * bfin_otp_read - Read OTP pages
68 *
69 * All reads must be in half page chunks (half page == 64 bits).
70 */
71static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, loff_t *pos)
72{
73 ssize_t bytes_done;
74 u32 page, flags, ret;
75 u64 content;
76
77 stampit();
78
79 if (count % sizeof(u64))
80 return -EMSGSIZE;
81
82 if (mutex_lock_interruptible(&bfin_otp_lock))
83 return -ERESTARTSYS;
84
85 bytes_done = 0;
86 page = *pos / (sizeof(u64) * 2);
87 while (bytes_done < count) {
88 flags = (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
89 stamp("processing page %i (%s)", page, (flags == OTP_UPPER_HALF ? "upper" : "lower"));
90 ret = otp_read(page, flags, &content);
91 if (ret & OTP_MASTER_ERROR) {
92 bytes_done = -EIO;
93 break;
94 }
95 if (copy_to_user(buff + bytes_done, &content, sizeof(content))) {
96 bytes_done = -EFAULT;
97 break;
98 }
99 if (flags == OTP_UPPER_HALF)
100 ++page;
101 bytes_done += sizeof(content);
102 *pos += sizeof(content);
103 }
104
105 mutex_unlock(&bfin_otp_lock);
106
107 return bytes_done;
108}
109
110#ifdef CONFIG_BFIN_OTP_WRITE_ENABLE
111/**
112 * bfin_otp_write - Write OTP pages
113 *
114 * All writes must be in half page chunks (half page == 64 bits).
115 */
116static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos)
117{
118 stampit();
119
120 if (count % sizeof(u64))
121 return -EMSGSIZE;
122
123 if (mutex_lock_interruptible(&bfin_otp_lock))
124 return -ERESTARTSYS;
125
126 /* need otp_init() documentation before this can be implemented */
127
128 mutex_unlock(&bfin_otp_lock);
129
130 return -EINVAL;
131}
132#else
133# define bfin_otp_write NULL
134#endif
135
136static struct file_operations bfin_otp_fops = {
137 .owner = THIS_MODULE,
138 .read = bfin_otp_read,
139 .write = bfin_otp_write,
140};
141
142static struct miscdevice bfin_otp_misc_device = {
143 .minor = MISC_DYNAMIC_MINOR,
144 .name = DRIVER_NAME,
145 .fops = &bfin_otp_fops,
146};
147
148/**
149 * bfin_otp_init - Initialize module
150 *
151 * Registers the device and notifier handler. Actual device
152 * initialization is handled by bfin_otp_open().
153 */
154static int __init bfin_otp_init(void)
155{
156 int ret;
157
158 stampit();
159
160 ret = misc_register(&bfin_otp_misc_device);
161 if (ret) {
162 pr_init(KERN_ERR PFX "unable to register a misc device\n");
163 return ret;
164 }
165
166 pr_init(KERN_INFO PFX "initialized\n");
167
168 return 0;
169}
170
171/**
172 * bfin_otp_exit - Deinitialize module
173 *
174 * Unregisters the device and notifier handler. Actual device
175 * deinitialization is handled by bfin_otp_close().
176 */
177static void __exit bfin_otp_exit(void)
178{
179 stampit();
180
181 misc_deregister(&bfin_otp_misc_device);
182}
183
184module_init(bfin_otp_init);
185module_exit(bfin_otp_exit);
186
187MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
188MODULE_DESCRIPTION("Blackfin OTP Memory Interface");
189MODULE_LICENSE("GPL");