GNU Linux-libre 4.14.294-gnu1
[releases.git] / arch / blackfin / mach-bf561 / coreb.c
1 /* Load firmware into Core B on a BF561
2  *
3  * Author: Bas Vermeulen <bvermeul@blackstar.xs4all.nl>
4  *
5  * Copyright 2004-2009 Analog Devices Inc.
6  * Licensed under the GPL-2 or later.
7  */
8
9 /* The Core B reset func requires code in the application that is loaded into
10  * Core B.  In order to reset, the application needs to install an interrupt
11  * handler for Supplemental Interrupt 0, that sets RETI to 0xff600000 and
12  * writes bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0.  This causes Core
13  * B to stall when Supplemental Interrupt 0 is set, and will reset PC to
14  * 0xff600000 when COREB_SRAM_INIT is cleared.
15  */
16
17 #include <linux/device.h>
18 #include <linux/fs.h>
19 #include <linux/init.h>
20 #include <linux/kernel.h>
21 #include <linux/miscdevice.h>
22
23 #define CMD_COREB_START         _IO('b', 0)
24 #define CMD_COREB_STOP          _IO('b', 1)
25 #define CMD_COREB_RESET         _IO('b', 2)
26
27 static long
28 coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
29 {
30         int ret = 0;
31
32         switch (cmd) {
33         case CMD_COREB_START:
34                 bfin_write_SYSCR(bfin_read_SYSCR() & ~0x0020);
35                 break;
36         case CMD_COREB_STOP:
37                 bfin_write_SYSCR(bfin_read_SYSCR() | 0x0020);
38                 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
39                 break;
40         case CMD_COREB_RESET:
41                 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
42                 break;
43         default:
44                 ret = -EINVAL;
45                 break;
46         }
47
48         CSYNC();
49
50         return ret;
51 }
52
53 static const struct file_operations coreb_fops = {
54         .owner          = THIS_MODULE,
55         .unlocked_ioctl = coreb_ioctl,
56         .llseek         = noop_llseek,
57 };
58
59 static struct miscdevice coreb_dev = {
60         .minor = MISC_DYNAMIC_MINOR,
61         .name  = "coreb",
62         .fops  = &coreb_fops,
63 };
64 builtin_misc_device(coreb_dev);