commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=5406c1d8b96744b1bd289031d8297254d398fe28 branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/2012R1
add coreb start stub coreb control add icc machine spefific implementation Signed-off-by: Steven Miao <[email protected]> --- arch/blackfin/include/asm/icc.h | 18 ++++++ arch/blackfin/mach-bf561/Makefile | 2 +- arch/blackfin/mach-bf561/icc.c | 38 ------------ arch/blackfin/mach-bf561/include/mach/icc.h | 5 ++ arch/blackfin/mach-bf609/Makefile | 3 +- arch/blackfin/mach-bf609/coreb.c | 32 ++++++++++ arch/blackfin/mach-bf609/icc.c | 45 ++++++++++++++ .../{mach-bf561 => mach-bf609}/include/mach/icc.h | 9 ++- arch/blackfin/mach-bf609/include/mach/pm.h | 1 + arch/blackfin/mach-common/Makefile | 2 + arch/blackfin/mach-common/coreb.c | 62 ++++++++++++++++++++ arch/blackfin/mach-common/icc.c | 51 ++++++++++++++++ 12 files changed, 226 insertions(+), 42 deletions(-) diff --git a/arch/blackfin/include/asm/icc.h b/arch/blackfin/include/asm/icc.h new file mode 100644 index 0000000..7576bb2 --- /dev/null +++ b/arch/blackfin/include/asm/icc.h @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _BFIN_ICC_H +#define _BFIN_ICC_H + +#include <mach/icc.h> + +void platform_request_ipi(int irq, void *handler); +void platform_send_ipi(cpumask_t callmap, int irq); +void platform_send_ipi_cpu(unsigned int cpu, int irq); +void platform_clear_ipi(unsigned int cpu, int irq); + +void wakeup_icc_thread(void); +#endif diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile index a6c947a..c9c14bd 100644 --- a/arch/blackfin/mach-bf561/Makefile +++ b/arch/blackfin/mach-bf561/Makefile @@ -5,6 +5,6 @@ obj-y := ints-priority.o dma.o obj-$(CONFIG_BF561_COREB) += coreb.o -obj-$(CONFIG_ICC) += icc.o +obj-$(CONFIG_ICC:m=y) += icc.o obj-$(CONFIG_SMP) += smp.o secondary.o atomic.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/blackfin/mach-bf561/icc.c b/arch/blackfin/mach-bf561/icc.c index 27bb53d..4196309 100644 --- a/arch/blackfin/mach-bf561/icc.c +++ b/arch/blackfin/mach-bf561/icc.c @@ -6,7 +6,6 @@ static const char supple0[] = "IRQ_SUPPLE_0"; static const char supple1[] = "IRQ_SUPPLE_1"; -void wakeup_icc_thread(void); void platform_request_ipi(int irq, void *handler) { @@ -48,40 +47,3 @@ void platform_clear_ipi(unsigned int cpu, int irq) bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu))); SSYNC(); } - -void icc_send_ipi_cpu(unsigned int cpu, int irq) -{ - platform_send_ipi_cpu(cpu, irq); -} - -void icc_clear_ipi_cpu(unsigned int cpu, int irq) -{ - platform_clear_ipi(cpu, irq); -} - -irqreturn_t ipi_handler_int0(int irq, void *dev_instance) -{ - unsigned int cpu = blackfin_core_id(); - - platform_clear_ipi(cpu, IRQ_SUPPLE_0); - - wakeup_icc_thread(); - return IRQ_HANDLED; -} - -irqreturn_t ipi_handler_int1(int irq, void *dev_instance) -{ - unsigned int cpu = blackfin_core_id(); - - platform_clear_ipi(cpu, IRQ_SUPPLE_1); - return IRQ_HANDLED; -} - -static int __init icc_prepare_cpus(void) -{ - platform_request_ipi(IRQ_SUPPLE_0, ipi_handler_int0); - platform_request_ipi(IRQ_SUPPLE_1, ipi_handler_int1); - return 0; -} - -late_initcall(icc_prepare_cpus); diff --git a/arch/blackfin/mach-bf561/include/mach/icc.h b/arch/blackfin/mach-bf561/include/mach/icc.h index 80837dd..aa42a26 100644 --- a/arch/blackfin/mach-bf561/include/mach/icc.h +++ b/arch/blackfin/mach-bf561/include/mach/icc.h @@ -22,4 +22,9 @@ typedef sm_uint16_t sm_atomic_t; #define COREB_TASK_START 0x3C00000 #define COREB_MEMPOOL_START 0x3D00000 + +#define ICC_LOW_SEND IRQ_SUPPLE_0 +#define ICC_LOW_RECV IRQ_SUPPLE_0 +#define ICC_HIGH_SEND IRQ_SUPPLE_1 +#define ICC_HIGH_RECV IRQ_SUPPLE_1 #endif diff --git a/arch/blackfin/mach-bf609/Makefile b/arch/blackfin/mach-bf609/Makefile index 1bccf9e..1197501 100644 --- a/arch/blackfin/mach-bf609/Makefile +++ b/arch/blackfin/mach-bf609/Makefile @@ -4,4 +4,5 @@ obj-y := dma.o clock.o obj-$(CONFIG_PM) += pm.o hibernate.o -obj-$(CONFIG_BFIN_COREB) += coreb_start.o +obj-$(CONFIG_BFIN_COREB) += coreb.o coreb_start.o +obj-$(CONFIG_ICC:m=y) += icc.o diff --git a/arch/blackfin/mach-bf609/coreb.c b/arch/blackfin/mach-bf609/coreb.c new file mode 100644 index 0000000..ea69803 --- /dev/null +++ b/arch/blackfin/mach-bf609/coreb.c @@ -0,0 +1,32 @@ +#include <asm/blackfin.h> + +void coreb_enable(void) +{ + bfin_write32(RCU0_SVECT1, COREB_L1_CODE_START); + bfin_write32(RCU0_CRCTL, 0); +} + +void bfin_coreb_start(void) +{ + bfin_write32(RCU0_CRCTL, 0x2); + + while (!(bfin_read32(RCU0_CRSTAT) & 0x2)) + continue; + + bfin_write32(RCU0_CRCTL, 0); +} + +void bfin_coreb_stop(void) +{ + bfin_write32(RCU0_CRCTL, 0); +} + +void bfin_coreb_reset(void) +{ + bfin_write32(RCU0_CRCTL, 0x2); + + while (!(bfin_read32(RCU0_CRSTAT) & 0x2)) + continue; + + bfin_write32(RCU0_CRCTL, 0); +} diff --git a/arch/blackfin/mach-bf609/icc.c b/arch/blackfin/mach-bf609/icc.c new file mode 100644 index 0000000..fbeca2b --- /dev/null +++ b/arch/blackfin/mach-bf609/icc.c @@ -0,0 +1,45 @@ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <asm/icc.h> +#include <asm/pm.h> + +char icc_low_name[] = "icc low irq"; +char icc_high_name[] = "icc high irq"; + +void platform_request_ipi(int irq, void *handler) +{ + int ret; + const char *name = (irq == ICC_LOW_RECV) ? icc_low_name : icc_high_name; + + ret = request_irq(irq, handler, IRQF_DISABLED | IRQF_PERCPU, + name, handler); + if (ret) + panic("Cannot request %s for IPI service", name); +} + +void platform_send_ipi_cpu(unsigned int cpu, int irq) +{ + BUG_ON(cpu >= 2); + SSYNC(); + bfin_sec_raise_irq(irq); + SSYNC(); +} + +void platform_send_ipi(cpumask_t callmap, int irq) +{ + unsigned int cpu; + + for_each_cpu_mask(cpu, callmap) { + BUG_ON(cpu >= 2); + SSYNC(); + platform_send_ipi_cpu(cpu, irq); + SSYNC(); + } +} + +void platform_clear_ipi(unsigned int cpu, int irq) +{ + BUG_ON(cpu >= 2); +} diff --git a/arch/blackfin/mach-bf561/include/mach/icc.h b/arch/blackfin/mach-bf609/include/mach/icc.h similarity index 75% copy from arch/blackfin/mach-bf561/include/mach/icc.h copy to arch/blackfin/mach-bf609/include/mach/icc.h index 80837dd..f8b0fa9 100644 --- a/arch/blackfin/mach-bf561/include/mach/icc.h +++ b/arch/blackfin/mach-bf609/include/mach/icc.h @@ -4,8 +4,8 @@ * Licensed under the GPL-2 or later. */ -#ifndef _MACH_BF561_ICC_H -#define _MACH_BF561_ICC_H +#ifndef _MACH_BF609_ICC_H +#define _MACH_BF609_ICC_H /* arch specific */ #define sm_atomic_read(v) bfin_read16(v) @@ -22,4 +22,9 @@ typedef sm_uint16_t sm_atomic_t; #define COREB_TASK_START 0x3C00000 #define COREB_MEMPOOL_START 0x3D00000 + +#define ICC_LOW_SEND IRQ_SOFT1 +#define ICC_LOW_RECV IRQ_SOFT0 +#define ICC_HIGH_SEND IRQ_SOFT3 +#define ICC_HIGH_RECV IRQ_SOFT2 #endif diff --git a/arch/blackfin/mach-bf609/include/mach/pm.h b/arch/blackfin/mach-bf609/include/mach/pm.h index 65c9ba0..036d9bd 100644 --- a/arch/blackfin/mach-bf609/include/mach/pm.h +++ b/arch/blackfin/mach-bf609/include/mach/pm.h @@ -17,4 +17,5 @@ void bf609_pm_finish(void); void bf609_hibernate(void); void bfin_sec_raise_irq(unsigned int sid); +void coreb_enable(void); #endif diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index 75f0ba2..200ed38 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile @@ -14,3 +14,5 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_BFIN_KERNEL_CLOCK) += clocks-init.o +obj-$(CONFIG_BFIN_COREB) += coreb.o +obj-$(CONFIG_ICC:m=y) += icc.o diff --git a/arch/blackfin/mach-common/coreb.c b/arch/blackfin/mach-common/coreb.c new file mode 100644 index 0000000..5ea01f0 --- /dev/null +++ b/arch/blackfin/mach-common/coreb.c @@ -0,0 +1,62 @@ +/* + * Blackfin Core B control driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#include <linux/device.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/miscdevice.h> +#include <linux/module.h> +#include <asm/pm.h> + +#define CMD_COREB_START _IO('b', 0) +#define CMD_COREB_STOP _IO('b', 1) +#define CMD_COREB_RESET _IO('b', 2) + +static long coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + switch (cmd) { + case CMD_COREB_START: + bfin_coreb_start(); + break; + case CMD_COREB_STOP: + bfin_coreb_stop(); + break; + case CMD_COREB_RESET: + bfin_coreb_stop(); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static const struct file_operations coreb_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = coreb_ioctl, + .llseek = noop_llseek, +}; + +static struct miscdevice coreb_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "coreb", + .fops = &coreb_fops, +}; + +static int __init bfin_coreb_init(void) +{ + return misc_register(&coreb_dev); +} + +module_init(bfin_coreb_init); + +MODULE_DESCRIPTION("Bfin Core B Support"); +MODULE_LICENSE("GPL v2"); diff --git a/arch/blackfin/mach-common/icc.c b/arch/blackfin/mach-common/icc.c new file mode 100644 index 0000000..262b109 --- /dev/null +++ b/arch/blackfin/mach-common/icc.c @@ -0,0 +1,51 @@ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <asm/icc.h> + +void icc_send_ipi_cpu(unsigned int cpu, int irq) +{ + platform_send_ipi_cpu(cpu, irq); +} + +void icc_send_ipi_cpu_low(unsigned int cpu) +{ + platform_send_ipi_cpu(cpu, ICC_LOW_SEND); +} + +void icc_send_ipi_cpu_high(unsigned int cpu) +{ + platform_send_ipi_cpu(cpu, ICC_HIGH_SEND); +} + +void icc_clear_ipi_cpu(unsigned int cpu, int irq) +{ + platform_clear_ipi(cpu, irq); +} + +irqreturn_t ipi_handler_int0(int irq, void *dev_instance) +{ + unsigned int cpu = blackfin_core_id(); + + platform_clear_ipi(cpu, ICC_LOW_RECV); + + wakeup_icc_thread(); + return IRQ_HANDLED; +} + +irqreturn_t ipi_handler_int1(int irq, void *dev_instance) +{ + unsigned int cpu = blackfin_core_id(); + + platform_clear_ipi(cpu, ICC_HIGH_RECV); + return IRQ_HANDLED; +} + +static int __init icc_prepare_cpus(void) +{ + platform_request_ipi(ICC_LOW_RECV, ipi_handler_int0); + platform_request_ipi(ICC_HIGH_RECV, ipi_handler_int1); + return 0; +} + +late_initcall(icc_prepare_cpus);
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
