blob: 78ecb50bafc8653049ee563118ae8e48cdad1c49 [file] [log] [blame]
Mike Frysingerc8f36dc2009-05-14 14:55:50 +00001/* Load firmware into Core B on a BF561
Bryan Wu1394f032007-05-06 14:50:22 -07002 *
Mike Frysingerc8f36dc2009-05-14 14:55:50 +00003 * Copyright 2004-2009 Analog Devices Inc.
4 * Licensed under the GPL-2 or later.
Bryan Wu1394f032007-05-06 14:50:22 -07005 */
6
Mike Frysingerc8f36dc2009-05-14 14:55:50 +00007/* The Core B reset func requires code in the application that is loaded into
8 * Core B. In order to reset, the application needs to install an interrupt
9 * handler for Supplemental Interrupt 0, that sets RETI to 0xff600000 and
10 * writes bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0. This causes Core
11 * B to stall when Supplemental Interrupt 0 is set, and will reset PC to
12 * 0xff600000 when COREB_SRAM_INIT is cleared.
13 */
14
Bryan Wu1394f032007-05-06 14:50:22 -070015#include <linux/device.h>
Enrik Berkhan76a7f402007-12-24 19:51:31 +080016#include <linux/fs.h>
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000017#include <linux/kernel.h>
18#include <linux/miscdevice.h>
19#include <linux/module.h>
Bryan Wu1394f032007-05-06 14:50:22 -070020
Mike Frysinger7696eec2010-10-06 06:33:08 +000021#define CMD_COREB_START _IO('b', 0)
22#define CMD_COREB_STOP _IO('b', 1)
23#define CMD_COREB_RESET _IO('b', 2)
Bryan Wu1394f032007-05-06 14:50:22 -070024
Mike Frysinger17a1b5e2009-10-13 12:50:05 +000025static long
26coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Bryan Wu1394f032007-05-06 14:50:22 -070027{
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000028 int ret = 0;
Bryan Wu1394f032007-05-06 14:50:22 -070029
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000030 switch (cmd) {
31 case CMD_COREB_START:
Mike Frysinger39c99962010-10-19 18:44:23 +000032 bfin_write_SYSCR(bfin_read_SYSCR() & ~0x0020);
Bryan Wu1394f032007-05-06 14:50:22 -070033 break;
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000034 case CMD_COREB_STOP:
Mike Frysinger39c99962010-10-19 18:44:23 +000035 bfin_write_SYSCR(bfin_read_SYSCR() | 0x0020);
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000036 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
37 break;
38 case CMD_COREB_RESET:
39 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
40 break;
Bryan Wu1394f032007-05-06 14:50:22 -070041 default:
42 ret = -EINVAL;
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000043 break;
Bryan Wu1394f032007-05-06 14:50:22 -070044 }
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000045
46 CSYNC();
47
Bryan Wu1394f032007-05-06 14:50:22 -070048 return ret;
49}
50
Alexey Dobriyan828c0952009-10-01 15:43:56 -070051static const struct file_operations coreb_fops = {
Mike Frysinger17a1b5e2009-10-13 12:50:05 +000052 .owner = THIS_MODULE,
53 .unlocked_ioctl = coreb_ioctl,
Arnd Bergmann6038f372010-08-15 18:52:59 +020054 .llseek = noop_llseek,
Bryan Wu1394f032007-05-06 14:50:22 -070055};
56
57static struct miscdevice coreb_dev = {
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000058 .minor = MISC_DYNAMIC_MINOR,
59 .name = "coreb",
60 .fops = &coreb_fops,
Bryan Wu1394f032007-05-06 14:50:22 -070061};
62
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000063static int __init bf561_coreb_init(void)
Bryan Wu1394f032007-05-06 14:50:22 -070064{
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000065 return misc_register(&coreb_dev);
Bryan Wu1394f032007-05-06 14:50:22 -070066}
Bryan Wu1394f032007-05-06 14:50:22 -070067module_init(bf561_coreb_init);
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000068
69static void __exit bf561_coreb_exit(void)
70{
71 misc_deregister(&coreb_dev);
72}
Bryan Wu1394f032007-05-06 14:50:22 -070073module_exit(bf561_coreb_exit);
74
75MODULE_AUTHOR("Bas Vermeulen <bvermeul@blackstar.xs4all.nl>");
76MODULE_DESCRIPTION("BF561 Core B Support");
Mike Frysinger6cf4d0f2010-10-06 06:30:04 +000077MODULE_LICENSE("GPL");