aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/dsp56k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/dsp56k.c')
-rw-r--r--drivers/char/dsp56k.c100
1 files changed, 44 insertions, 56 deletions
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index a69c65283260..b9a30c30e2b8 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -33,6 +33,9 @@
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/smp_lock.h>
37#include <linux/firmware.h>
38#include <linux/platform_device.h>
36 39
37#include <asm/atarihw.h> 40#include <asm/atarihw.h>
38#include <asm/traps.h> 41#include <asm/traps.h>
@@ -92,49 +95,6 @@
92 } \ 95 } \
93} 96}
94 97
95/* DSP56001 bootstrap code */
96static char bootstrap[] = {
97 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4,
117 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47,
118 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00,
119 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe,
120 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0,
121 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a,
122 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4,
123 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01,
124 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08,
125 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46,
126 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa,
127 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00,
128 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9,
129 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80,
130 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a,
131 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0,
132 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4,
133 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a,
134 0xf0, 0x80, 0x00, 0x7e, 0xad};
135static int sizeof_bootstrap = 375;
136
137
138static struct dsp56k_device { 98static struct dsp56k_device {
139 unsigned long in_use; 99 unsigned long in_use;
140 long maxio, timeout; 100 long maxio, timeout;
@@ -164,18 +124,40 @@ static int dsp56k_reset(void)
164 124
165static int dsp56k_upload(u_char __user *bin, int len) 125static int dsp56k_upload(u_char __user *bin, int len)
166{ 126{
127 struct platform_device *pdev;
128 const struct firmware *fw;
129 const char fw_name[] = "dsp56k/bootstrap.bin";
130 int err;
167 int i; 131 int i;
168 u_char *p; 132
169
170 dsp56k_reset(); 133 dsp56k_reset();
171 134
172 p = bootstrap; 135 pdev = platform_device_register_simple("dsp56k", 0, NULL, 0);
173 for (i = 0; i < sizeof_bootstrap/3; i++) { 136 if (IS_ERR(pdev)) {
137 printk(KERN_ERR "Failed to register device for \"%s\"\n",
138 fw_name);
139 return -EINVAL;
140 }
141 err = request_firmware(&fw, fw_name, &pdev->dev);
142 platform_device_unregister(pdev);
143 if (err) {
144 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
145 fw_name, err);
146 return err;
147 }
148 if (fw->size % 3) {
149 printk(KERN_ERR "Bogus length %d in image \"%s\"\n",
150 fw->size, fw_name);
151 release_firmware(fw);
152 return -EINVAL;
153 }
154 for (i = 0; i < fw->size; i = i + 3) {
174 /* tx_wait(10); */ 155 /* tx_wait(10); */
175 dsp56k_host_interface.data.b[1] = *p++; 156 dsp56k_host_interface.data.b[1] = fw->data[i];
176 dsp56k_host_interface.data.b[2] = *p++; 157 dsp56k_host_interface.data.b[2] = fw->data[i + 1];
177 dsp56k_host_interface.data.b[3] = *p++; 158 dsp56k_host_interface.data.b[3] = fw->data[i + 2];
178 } 159 }
160 release_firmware(fw);
179 for (; i < 512; i++) { 161 for (; i < 512; i++) {
180 /* tx_wait(10); */ 162 /* tx_wait(10); */
181 dsp56k_host_interface.data.b[1] = 0; 163 dsp56k_host_interface.data.b[1] = 0;
@@ -436,13 +418,17 @@ static unsigned int dsp56k_poll(struct file *file, poll_table *wait)
436static int dsp56k_open(struct inode *inode, struct file *file) 418static int dsp56k_open(struct inode *inode, struct file *file)
437{ 419{
438 int dev = iminor(inode) & 0x0f; 420 int dev = iminor(inode) & 0x0f;
421 int ret = 0;
439 422
423 lock_kernel();
440 switch(dev) 424 switch(dev)
441 { 425 {
442 case DSP56K_DEV_56001: 426 case DSP56K_DEV_56001:
443 427
444 if (test_and_set_bit(0, &dsp56k.in_use)) 428 if (test_and_set_bit(0, &dsp56k.in_use)) {
445 return -EBUSY; 429 ret = -EBUSY;
430 goto out;
431 }
446 432
447 dsp56k.timeout = TIMEOUT; 433 dsp56k.timeout = TIMEOUT;
448 dsp56k.maxio = MAXIO; 434 dsp56k.maxio = MAXIO;
@@ -458,10 +444,11 @@ static int dsp56k_open(struct inode *inode, struct file *file)
458 break; 444 break;
459 445
460 default: 446 default:
461 return -ENODEV; 447 ret = -ENODEV;
462 } 448 }
463 449out:
464 return 0; 450 unlock_kernel();
451 return ret;
465} 452}
466 453
467static int dsp56k_release(struct inode *inode, struct file *file) 454static int dsp56k_release(struct inode *inode, struct file *file)
@@ -534,3 +521,4 @@ static void __exit dsp56k_cleanup_driver(void)
534module_exit(dsp56k_cleanup_driver); 521module_exit(dsp56k_cleanup_driver);
535 522
536MODULE_LICENSE("GPL"); 523MODULE_LICENSE("GPL");
524MODULE_FIRMWARE("dsp56k/bootstrap.bin");