diff options
Diffstat (limited to 'arch/blackfin/kernel')
36 files changed, 3333 insertions, 916 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index ca5ccc77777..703dc7cf2ec 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -2,12 +2,12 @@  # arch/blackfin/kernel/Makefile  # -extra-y := init_task.o vmlinux.lds +extra-y := vmlinux.lds  obj-y := \  	entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \  	sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ -	fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o \ +	fixed_code.o reboot.o bfin_dma.o \  	exception.o dumpstack.o  ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) @@ -16,6 +16,7 @@ else      obj-y += time.o  endif +obj-$(CONFIG_GPIO_ADI)               += bfin_gpio.o  obj-$(CONFIG_DYNAMIC_FTRACE)         += ftrace.o  obj-$(CONFIG_FUNCTION_TRACER)        += ftrace-entry.o  obj-$(CONFIG_FUNCTION_GRAPH_TRACER)  += ftrace.o @@ -33,7 +34,10 @@ obj-$(CONFIG_EARLY_PRINTK)           += shadow_console.o  obj-$(CONFIG_STACKTRACE)             += stacktrace.o  obj-$(CONFIG_DEBUG_VERBOSE)          += trace.o  obj-$(CONFIG_BFIN_PSEUDODBG_INSNS)   += pseudodbg.o +obj-$(CONFIG_PERF_EVENTS)            += perf_event.o  # the kgdb test puts code into L2 and without linker  # relaxation, we need to force long calls to/from it -CFLAGS_kgdb_test.o := -mlong-calls -O0 +CFLAGS_kgdb_test.o := -mlong-calls + +obj-$(CONFIG_DEBUG_MMRS)             += debug-mmrs.o diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c index bd32c09b934..37fcae95021 100644 --- a/arch/blackfin/kernel/asm-offsets.c +++ b/arch/blackfin/kernel/asm-offsets.c @@ -14,6 +14,7 @@  #include <linux/irq.h>  #include <linux/thread_info.h>  #include <linux/kbuild.h> +#include <asm/pda.h>  int main(void)  { @@ -138,6 +139,16 @@ int main(void)  	DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault));  	DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault));  #endif + +	/* PDA initial management */ +	DEFINE(PDA_INIT_RETX, offsetof(struct blackfin_initial_pda, retx)); +#ifdef CONFIG_DEBUG_DOUBLEFAULT +	DEFINE(PDA_INIT_DF_DCPLB, offsetof(struct blackfin_initial_pda, dcplb_doublefault_addr)); +	DEFINE(PDA_INIT_DF_ICPLB, offsetof(struct blackfin_initial_pda, icplb_doublefault_addr)); +	DEFINE(PDA_INIT_DF_SEQSTAT, offsetof(struct blackfin_initial_pda, seqstat_doublefault)); +	DEFINE(PDA_INIT_DF_RETX, offsetof(struct blackfin_initial_pda, retx_doublefault)); +#endif +  #ifdef CONFIG_SMP  	/* Inter-core lock (in L2 SRAM) */  	DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot)); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma.c index 1e485dfdc9f..4a32f2dd5dd 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma.c @@ -1,5 +1,5 @@  /* - * bfin_dma_5xx.c - Blackfin DMA implementation + * bfin_dma.c - Blackfin DMA implementation   *   * Copyright 2004-2008 Analog Devices Inc.   * @@ -36,13 +36,24 @@ static int __init blackfin_dma_init(void)  	printk(KERN_INFO "Blackfin DMA Controller\n"); + +#if ANOMALY_05000480 +	bfin_write_DMAC_TC_PER(0x0111); +#endif +  	for (i = 0; i < MAX_DMA_CHANNELS; i++) {  		atomic_set(&dma_ch[i].chan_status, 0);  		dma_ch[i].regs = dma_io_base_addr[i];  	} +#if defined(CH_MEM_STREAM3_SRC) && defined(CONFIG_BF60x) +	/* Mark MEMDMA Channel 3 as requested since we're using it internally */ +	request_dma(CH_MEM_STREAM3_DEST, "Blackfin dma_memcpy"); +	request_dma(CH_MEM_STREAM3_SRC, "Blackfin dma_memcpy"); +#else  	/* Mark MEMDMA Channel 0 as requested since we're using it internally */  	request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy");  	request_dma(CH_MEM_STREAM0_SRC, "Blackfin dma_memcpy"); +#endif  #if defined(CONFIG_DEB_DMA_URGENT)  	bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE() @@ -79,11 +90,30 @@ static const struct file_operations proc_dma_operations = {  static int __init proc_dma_init(void)  { -	return proc_create("dma", 0, NULL, &proc_dma_operations) != NULL; +	proc_create("dma", 0, NULL, &proc_dma_operations); +	return 0;  }  late_initcall(proc_dma_init);  #endif +static void set_dma_peripheral_map(unsigned int channel, const char *device_id) +{ +#ifdef CONFIG_BF54x +	unsigned int per_map; + +	switch (channel) { +		case CH_UART2_RX: per_map = 0xC << 12; break; +		case CH_UART2_TX: per_map = 0xD << 12; break; +		case CH_UART3_RX: per_map = 0xE << 12; break; +		case CH_UART3_TX: per_map = 0xF << 12; break; +		default:          return; +	} + +	if (strncmp(device_id, "BFIN_UART", 9) == 0) +		dma_ch[channel].regs->peripheral_map = per_map; +#endif +} +  /**   *	request_dma - request a DMA channel   * @@ -111,19 +141,7 @@ int request_dma(unsigned int channel, const char *device_id)  		return -EBUSY;  	} -#ifdef CONFIG_BF54x -	if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { -		unsigned int per_map; -		per_map = dma_ch[channel].regs->peripheral_map & 0xFFF; -		if (strncmp(device_id, "BFIN_UART", 9) == 0) -			dma_ch[channel].regs->peripheral_map = per_map | -				((channel - CH_UART2_RX + 0xC)<<12); -		else -			dma_ch[channel].regs->peripheral_map = per_map | -				((channel - CH_UART2_RX + 0x6)<<12); -	} -#endif - +	set_dma_peripheral_map(channel, device_id);  	dma_ch[channel].device_id = device_id;  	dma_ch[channel].irq = 0; @@ -193,6 +211,7 @@ EXPORT_SYMBOL(free_dma);  # ifndef MAX_DMA_SUSPEND_CHANNELS  #  define MAX_DMA_SUSPEND_CHANNELS MAX_DMA_CHANNELS  # endif +# ifndef CONFIG_BF60x  int blackfin_dma_suspend(void)  {  	int i; @@ -202,11 +221,13 @@ int blackfin_dma_suspend(void)  			printk(KERN_ERR "DMA Channel %d failed to suspend\n", i);  			return -EBUSY;  		} -  		if (i < MAX_DMA_SUSPEND_CHANNELS)  			dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map;  	} +#if ANOMALY_05000480 +	bfin_write_DMAC_TC_PER(0x0); +#endif  	return 0;  } @@ -216,11 +237,23 @@ void blackfin_dma_resume(void)  	for (i = 0; i < MAX_DMA_CHANNELS; ++i) {  		dma_ch[i].regs->cfg = 0; -  		if (i < MAX_DMA_SUSPEND_CHANNELS)  			dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;  	} +#if ANOMALY_05000480 +	bfin_write_DMAC_TC_PER(0x0111); +#endif  } +# else +int blackfin_dma_suspend(void) +{ +	return 0; +} + +void blackfin_dma_resume(void) +{ +} +#endif  #endif  /** @@ -262,10 +295,10 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)  			src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;  		} -		if (!bfin_read16(&src_ch->cfg)) +		if (!DMA_MMR_READ(&src_ch->cfg))  			break; -		else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) { -			bfin_write16(&src_ch->cfg, 0); +		else if (DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE) { +			DMA_MMR_WRITE(&src_ch->cfg, 0);  			break;  		}  	} @@ -278,22 +311,31 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)  	/* Destination */  	bfin_write32(&dst_ch->start_addr, dst); -	bfin_write16(&dst_ch->x_count, size >> 2); -	bfin_write16(&dst_ch->x_modify, 1 << 2); -	bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR); +	DMA_MMR_WRITE(&dst_ch->x_count, size >> 2); +	DMA_MMR_WRITE(&dst_ch->x_modify, 1 << 2); +	DMA_MMR_WRITE(&dst_ch->irq_status, DMA_DONE | DMA_ERR);  	/* Source */  	bfin_write32(&src_ch->start_addr, src); -	bfin_write16(&src_ch->x_count, size >> 2); -	bfin_write16(&src_ch->x_modify, 1 << 2); -	bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR); +	DMA_MMR_WRITE(&src_ch->x_count, size >> 2); +	DMA_MMR_WRITE(&src_ch->x_modify, 1 << 2); +	DMA_MMR_WRITE(&src_ch->irq_status, DMA_DONE | DMA_ERR);  	/* Enable */ -	bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32); -	bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32); +	DMA_MMR_WRITE(&src_ch->cfg, DMAEN | WDSIZE_32); +	DMA_MMR_WRITE(&dst_ch->cfg, WNR | DI_EN_X | DMAEN | WDSIZE_32);  	/* Since we are atomic now, don't use the workaround ssync */  	__builtin_bfin_ssync(); + +#ifdef CONFIG_BF60x +	/* Work around a possible MDMA anomaly. Running 2 MDMA channels to +	 * transfer DDR data to L1 SRAM may corrupt data. +	 * Should be reverted after this issue is root caused. +	 */ +	while (!(DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE)) +		continue; +#endif  }  void __init early_dma_memcpy_done(void) @@ -319,6 +361,42 @@ void __init early_dma_memcpy_done(void)  	__builtin_bfin_ssync();  } +#if defined(CH_MEM_STREAM3_SRC) && defined(CONFIG_BF60x) +#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S3_CONFIG +#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S3_CONFIG +#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S3_START_ADDR +#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S3_IRQ_STATUS +#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S3_X_COUNT +#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S3_X_MODIFY +#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S3_Y_COUNT +#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S3_Y_MODIFY +#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D3_CONFIG +#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D3_START_ADDR +#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D3_IRQ_STATUS +#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D3_IRQ_STATUS +#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D3_X_COUNT +#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D3_X_MODIFY +#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D3_Y_COUNT +#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D3_Y_MODIFY +#else +#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S0_CONFIG +#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S0_CONFIG +#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S0_START_ADDR +#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S0_IRQ_STATUS +#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S0_X_COUNT +#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S0_X_MODIFY +#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S0_Y_COUNT +#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S0_Y_MODIFY +#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D0_CONFIG +#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D0_START_ADDR +#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D0_IRQ_STATUS +#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D0_IRQ_STATUS +#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D0_X_COUNT +#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D0_X_MODIFY +#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D0_Y_COUNT +#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D0_Y_MODIFY +#endif +  /**   *	__dma_memcpy - program the MDMA registers   * @@ -341,8 +419,8 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u  	 */  	__builtin_bfin_ssync(); -	if (bfin_read_MDMA_S0_CONFIG()) -		while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) +	if (bfin_read_MDMA_S_CONFIG()) +		while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE))  			continue;  	if (conf & DMA2D) { @@ -357,39 +435,42 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u  		u32 shift = abs(dmod) >> 1;  		size_t ycnt = cnt >> (16 - shift);  		cnt = 1 << (16 - shift); -		bfin_write_MDMA_D0_Y_COUNT(ycnt); -		bfin_write_MDMA_S0_Y_COUNT(ycnt); -		bfin_write_MDMA_D0_Y_MODIFY(dmod); -		bfin_write_MDMA_S0_Y_MODIFY(smod); +		bfin_write_MDMA_D_Y_COUNT(ycnt); +		bfin_write_MDMA_S_Y_COUNT(ycnt); +		bfin_write_MDMA_D_Y_MODIFY(dmod); +		bfin_write_MDMA_S_Y_MODIFY(smod);  	} -	bfin_write_MDMA_D0_START_ADDR(daddr); -	bfin_write_MDMA_D0_X_COUNT(cnt); -	bfin_write_MDMA_D0_X_MODIFY(dmod); -	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); +	bfin_write_MDMA_D_START_ADDR(daddr); +	bfin_write_MDMA_D_X_COUNT(cnt); +	bfin_write_MDMA_D_X_MODIFY(dmod); +	bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR); -	bfin_write_MDMA_S0_START_ADDR(saddr); -	bfin_write_MDMA_S0_X_COUNT(cnt); -	bfin_write_MDMA_S0_X_MODIFY(smod); -	bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); +	bfin_write_MDMA_S_START_ADDR(saddr); +	bfin_write_MDMA_S_X_COUNT(cnt); +	bfin_write_MDMA_S_X_MODIFY(smod); +	bfin_write_MDMA_S_IRQ_STATUS(DMA_DONE | DMA_ERR); -	bfin_write_MDMA_S0_CONFIG(DMAEN | conf); -	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | conf); +	bfin_write_MDMA_S_CONFIG(DMAEN | conf); +	if (conf & DMA2D) +		bfin_write_MDMA_D_CONFIG(WNR | DI_EN_Y | DMAEN | conf); +	else +		bfin_write_MDMA_D_CONFIG(WNR | DI_EN_X | DMAEN | conf);  	spin_unlock_irqrestore(&mdma_lock, flags);  	SSYNC(); -	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) -		if (bfin_read_MDMA_S0_CONFIG()) +	while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE)) +		if (bfin_read_MDMA_S_CONFIG())  			continue;  		else  			return; -	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); +	bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR); -	bfin_write_MDMA_S0_CONFIG(0); -	bfin_write_MDMA_D0_CONFIG(0); +	bfin_write_MDMA_S_CONFIG(0); +	bfin_write_MDMA_D_CONFIG(0);  }  /** @@ -431,8 +512,10 @@ static void *_dma_memcpy(void *pdst, const void *psrc, size_t size)  	}  	size >>= shift; +#ifndef DMA_MMR_SIZE_32  	if (size > 0x10000)  		conf |= DMA2D; +#endif  	__dma_memcpy(dst, mod, src, mod, size, conf); @@ -471,6 +554,9 @@ EXPORT_SYMBOL(dma_memcpy);   */  void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size)  { +#ifdef DMA_MMR_SIZE_32 +	_dma_memcpy(pdst, psrc, size); +#else  	size_t bulk, rest;  	bulk = size & ~0xffff; @@ -478,6 +564,7 @@ void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size)  	if (bulk)  		_dma_memcpy(pdst, psrc, bulk);  	_dma_memcpy(pdst + bulk, psrc + bulk, rest); +#endif  	return pdst;  }  EXPORT_SYMBOL(dma_memcpy_nocache); @@ -497,14 +584,14 @@ void *safe_dma_memcpy(void *dst, const void *src, size_t size)  }  EXPORT_SYMBOL(safe_dma_memcpy); -static void _dma_out(unsigned long addr, unsigned long buf, unsigned short len, +static void _dma_out(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len,                       u16 size, u16 dma_size)  {  	blackfin_dcache_flush_range(buf, buf + len * size);  	__dma_memcpy(addr, 0, buf, size, len, dma_size);  } -static void _dma_in(unsigned long addr, unsigned long buf, unsigned short len, +static void _dma_in(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len,                      u16 size, u16 dma_size)  {  	blackfin_dcache_invalidate_range(buf, buf + len * size); @@ -512,7 +599,7 @@ static void _dma_in(unsigned long addr, unsigned long buf, unsigned short len,  }  #define MAKE_DMA_IO(io, bwl, isize, dmasize, cnst) \ -void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned short len) \ +void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned DMA_MMR_SIZE_TYPE len) \  { \  	_dma_##io(addr, (unsigned long)buf, len, isize, WDSIZE_##dmasize); \  } \ diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 170cf90735b..a017359c182 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -10,9 +10,8 @@  #include <linux/module.h>  #include <linux/err.h>  #include <linux/proc_fs.h> -#include <asm/blackfin.h> -#include <asm/gpio.h> -#include <asm/portmux.h> +#include <linux/seq_file.h> +#include <linux/gpio.h>  #include <linux/irq.h>  #if ANOMALY_05000311 || ANOMALY_05000323 @@ -56,17 +55,6 @@ static struct gpio_port_t * const gpio_array[] = {  	(struct gpio_port_t *) FIO0_FLAG_D,  	(struct gpio_port_t *) FIO1_FLAG_D,  	(struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(CONFIG_BF54x) -	(struct gpio_port_t *)PORTA_FER, -	(struct gpio_port_t *)PORTB_FER, -	(struct gpio_port_t *)PORTC_FER, -	(struct gpio_port_t *)PORTD_FER, -	(struct gpio_port_t *)PORTE_FER, -	(struct gpio_port_t *)PORTF_FER, -	(struct gpio_port_t *)PORTG_FER, -	(struct gpio_port_t *)PORTH_FER, -	(struct gpio_port_t *)PORTI_FER, -	(struct gpio_port_t *)PORTJ_FER,  #else  # error no gpio arrays defined  #endif @@ -116,6 +104,9 @@ static struct str_ident {  #if defined(CONFIG_PM)  static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; +# ifdef BF538_FAMILY +static unsigned short port_fer_saved[3]; +# endif  #endif  static void gpio_error(unsigned gpio) @@ -162,12 +153,6 @@ DECLARE_RESERVED_MAP(gpio_irq, GPIO_BANK_NUM);  inline int check_gpio(unsigned gpio)  { -#if defined(CONFIG_BF54x) -	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 -	    || gpio == GPIO_PH14 || gpio == GPIO_PH15 -	    || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) -		return -EINVAL; -#endif  	if (gpio >= MAX_BLACKFIN_GPIOS)  		return -EINVAL;  	return 0; @@ -205,12 +190,6 @@ static void port_setup(unsigned gpio, unsigned short usage)  	else  		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);  	SSYNC(); -#elif defined(CONFIG_BF54x) -	if (usage == GPIO_USAGE) -		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); -	else -		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); -	SSYNC();  #endif  } @@ -248,7 +227,7 @@ static int portmux_group_check(unsigned short per)  	u16 ident = P_IDENT(per);  	u16 function = P_FUNCT2MUX(per);  	s8 offset = port_mux[ident]; -	u16 m, pmux, pfunc; +	u16 m, pmux, pfunc, mask;  	if (offset < 0)  		return 0; @@ -263,10 +242,12 @@ static int portmux_group_check(unsigned short per)  			continue;  		if (offset == 1) -			pfunc = (pmux >> offset) & 3; +			mask = 3;  		else -			pfunc = (pmux >> offset) & 1; -		if (pfunc != function) { +			mask = 1; + +		pfunc = (pmux >> offset) & mask; +		if (pfunc != (function & mask)) {  			pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n",  				ident, function, m, pfunc);  			return -EINVAL; @@ -281,43 +262,21 @@ static void portmux_setup(unsigned short per)  	u16 ident = P_IDENT(per);  	u16 function = P_FUNCT2MUX(per);  	s8 offset = port_mux[ident]; -	u16 pmux; +	u16 pmux, mask;  	if (offset == -1)  		return;  	pmux = bfin_read_PORT_MUX(); -	if (offset != 1) -		pmux &= ~(1 << offset); +	if (offset == 1) +		mask = 3;  	else -		pmux &= ~(3 << 1); -	pmux |= (function << offset); -	bfin_write_PORT_MUX(pmux); -} -#elif defined(CONFIG_BF54x) -inline void portmux_setup(unsigned short per) -{ -	u16 ident = P_IDENT(per); -	u16 function = P_FUNCT2MUX(per); -	u32 pmux; - -	pmux = gpio_array[gpio_bank(ident)]->port_mux; +		mask = 1; -	pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); -	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); +	pmux &= ~(mask << offset); +	pmux |= ((function & mask) << offset); -	gpio_array[gpio_bank(ident)]->port_mux = pmux; -} - -inline u16 get_portmux(unsigned short per) -{ -	u16 ident = P_IDENT(per); -	u32 pmux = gpio_array[gpio_bank(ident)]->port_mux; -	return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); -} -static int portmux_group_check(unsigned short per) -{ -	return 0; +	bfin_write_PORT_MUX(pmux);  }  #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)  static int portmux_group_check(unsigned short per) @@ -372,7 +331,6 @@ static int portmux_group_check(unsigned short per)  }  #endif -#ifndef CONFIG_BF54x  /***********************************************************  *  * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -534,7 +492,7 @@ static const unsigned int sic_iwr_irqs[] = {  #if defined(BF533_FAMILY)  	IRQ_PROG_INTB  #elif defined(BF537_FAMILY) -	IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX +	IRQ_PF_INTB_WATCH, IRQ_PORTG_INTB, IRQ_PH_INTB_MAC_TX  #elif defined(BF538_FAMILY)  	IRQ_PORTF_INTB  #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) @@ -565,7 +523,7 @@ static const unsigned int sic_iwr_irqs[] = {  *************************************************************  * MODIFICATION HISTORY :  **************************************************************/ -int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) +int bfin_gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl)  {  	unsigned long flags; @@ -584,7 +542,7 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl)  	return 0;  } -int bfin_pm_standby_ctrl(unsigned ctrl) +int bfin_gpio_pm_standby_ctrl(unsigned ctrl)  {  	u16 bank, mask, i; @@ -602,6 +560,11 @@ void bfin_gpio_pm_hibernate_suspend(void)  {  	int i, bank; +#ifdef BF538_FAMILY +	for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i) +		port_fer_saved[i] = *port_fer[i]; +#endif +  	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {  		bank = gpio_bank(i); @@ -623,6 +586,10 @@ void bfin_gpio_pm_hibernate_suspend(void)  		gpio_bank_saved[bank].maska = gpio_array[bank]->maska;  	} +#ifdef BFIN_SPECIAL_GPIO_BANKS +	bfin_special_gpio_pm_hibernate_suspend(); +#endif +  	AWA_DUMMY_READ(maska);  } @@ -630,6 +597,11 @@ void bfin_gpio_pm_hibernate_restore(void)  {  	int i, bank; +#ifdef BF538_FAMILY +	for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i) +		*port_fer[i] = port_fer_saved[i]; +#endif +  	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {  		bank = gpio_bank(i); @@ -651,59 +623,17 @@ void bfin_gpio_pm_hibernate_restore(void)  		gpio_array[bank]->both  = gpio_bank_saved[bank].both;  		gpio_array[bank]->maska = gpio_bank_saved[bank].maska;  	} -	AWA_DUMMY_READ(maska); -} - +#ifdef BFIN_SPECIAL_GPIO_BANKS +	bfin_special_gpio_pm_hibernate_restore();  #endif -#else /* CONFIG_BF54x */ -#ifdef CONFIG_PM - -int bfin_pm_standby_ctrl(unsigned ctrl) -{ -	return 0; -} - -void bfin_gpio_pm_hibernate_suspend(void) -{ -	int i, bank; - -	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { -		bank = gpio_bank(i); -		gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; -		gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; -		gpio_bank_saved[bank].data = gpio_array[bank]->data; -		gpio_bank_saved[bank].inen = gpio_array[bank]->inen; -		gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; -	} +	AWA_DUMMY_READ(maska);  } -void bfin_gpio_pm_hibernate_restore(void) -{ -	int i, bank; - -	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { -		bank = gpio_bank(i); -		gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; -		gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; -		gpio_array[bank]->inen = gpio_bank_saved[bank].inen; -		gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; -		gpio_array[bank]->data_set = gpio_bank_saved[bank].data -						| gpio_bank_saved[bank].dir; -	} -}  #endif -unsigned short get_gpio_dir(unsigned gpio) -{ -	return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); -} -EXPORT_SYMBOL(get_gpio_dir); - -#endif /* CONFIG_BF54x */ -  /***********************************************************  *  * FUNCTIONS:	Blackfin Peripheral Resource Allocation @@ -759,11 +689,7 @@ int peripheral_request(unsigned short per, const char *label)  		 * be requested and used by several drivers  		 */ -#ifdef CONFIG_BF54x -		if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { -#else  		if (!(per & P_MAYSHARE)) { -#endif  			/*  			 * Allow that the identical pin function can  			 * be requested from the same driver twice @@ -912,12 +838,9 @@ int bfin_gpio_request(unsigned gpio, const char *label)  	if (unlikely(is_reserved(gpio_irq, gpio, 1))) {  		printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"  		       " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); -	} -#ifndef CONFIG_BF54x -	else {	/* Reset POLAR setting when acquiring a gpio for the first time */ +	} else {	/* Reset POLAR setting when acquiring a gpio for the first time */  		set_gpio_polar(gpio, 0);  	} -#endif  	reserve(gpio, gpio);  	set_label(gpio, label); @@ -1086,11 +1009,7 @@ void bfin_gpio_irq_free(unsigned gpio)  static inline void __bfin_gpio_direction_input(unsigned gpio)  { -#ifdef CONFIG_BF54x -	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); -#else  	gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); -#endif  	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);  } @@ -1114,17 +1033,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_input);  void bfin_gpio_irq_prepare(unsigned gpio)  { -#ifdef CONFIG_BF54x -	unsigned long flags; -#endif -  	port_setup(gpio, GPIO_USAGE); - -#ifdef CONFIG_BF54x -	flags = hard_local_irq_save(); -	__bfin_gpio_direction_input(gpio); -	hard_local_irq_restore(flags); -#endif  }  void bfin_gpio_set_value(unsigned gpio, int arg) @@ -1149,11 +1058,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)  	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);  	gpio_set_value(gpio, value); -#ifdef CONFIG_BF54x -	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); -#else  	gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); -#endif  	AWA_DUMMY_READ(dir);  	hard_local_irq_restore(flags); @@ -1164,9 +1069,6 @@ EXPORT_SYMBOL(bfin_gpio_direction_output);  int bfin_gpio_get_value(unsigned gpio)  { -#ifdef CONFIG_BF54x -	return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); -#else  	unsigned long flags;  	if (unlikely(get_gpio_edge(gpio))) { @@ -1179,7 +1081,6 @@ int bfin_gpio_get_value(unsigned gpio)  		return ret;  	} else  		return get_gpio_data(gpio); -#endif  }  EXPORT_SYMBOL(bfin_gpio_get_value); @@ -1203,36 +1104,44 @@ void bfin_reset_boot_spi_cs(unsigned short pin)  }  #if defined(CONFIG_PROC_FS) -static int gpio_proc_read(char *buf, char **start, off_t offset, -			  int len, int *unused_i, void *unused_v) +static int gpio_proc_show(struct seq_file *m, void *v)  { -	int c, irq, gpio, outlen = 0; +	int c, irq, gpio;  	for (c = 0; c < MAX_RESOURCES; c++) {  		irq = is_reserved(gpio_irq, c, 1);  		gpio = is_reserved(gpio, c, 1);  		if (!check_gpio(c) && (gpio || irq)) -			len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c, +			seq_printf(m, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c,  				 get_label(c), (gpio && irq) ? " *" : "",  				 get_gpio_dir(c) ? "OUTPUT" : "INPUT");  		else if (is_reserved(peri, c, 1)) -			len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c)); +			seq_printf(m, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c));  		else  			continue; -		buf += len; -		outlen += len;  	} -	return outlen; + +	return 0;  } +static int gpio_proc_open(struct inode *inode, struct file *file) +{ +	return single_open(file, gpio_proc_show, NULL); +} + +static const struct file_operations gpio_proc_ops = { +	.open		= gpio_proc_open, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= single_release, +}; +  static __init int gpio_register_proc(void)  {  	struct proc_dir_entry *proc_gpio; -	proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL); -	if (proc_gpio) -		proc_gpio->read_proc = gpio_proc_read; -	return proc_gpio != NULL; +	proc_gpio = proc_create("gpio", 0, NULL, &gpio_proc_ops); +	return proc_gpio == NULL;  }  __initcall(gpio_register_proc);  #endif diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c index 2c264b51566..c446591b961 100644 --- a/arch/blackfin/kernel/bfin_ksyms.c +++ b/arch/blackfin/kernel/bfin_ksyms.c @@ -11,6 +11,7 @@  #include <asm/cacheflush.h>  #include <asm/io.h> +#include <asm/irq_handler.h>  /* Allow people to have their own Blackfin exception handler in a module */  EXPORT_SYMBOL(bfin_return_from_exception); diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index 8de92299b3e..b56bd8514b7 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -120,6 +120,7 @@ MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)  		d_data = L2_DMEMORY;  	} else if (addr >= physical_mem_end) {  		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { +#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)  			mask = current_rwx_mask[cpu];  			if (mask) {  				int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT; @@ -129,6 +130,7 @@ MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)  				if (mask[idx] & bit)  					d_data |= CPLB_USER_RD;  			} +#endif  		} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH  		    && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {  			addr &= ~(1 * 1024 * 1024 - 1); diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index bfe75af4e8b..b49a53b583d 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -30,6 +30,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)  {  	int i_d, i_i;  	unsigned long addr; +	unsigned long cplb_pageflags, cplb_pagesize;  	struct cplb_entry *d_tbl = dcplb_tbl[cpu];  	struct cplb_entry *i_tbl = icplb_tbl[cpu]; @@ -49,21 +50,38 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)  	/* Cover kernel memory with 4M pages.  */  	addr = 0; -	for (; addr < memory_start; addr += 4 * 1024 * 1024) { +#ifdef PAGE_SIZE_16MB +	cplb_pageflags = PAGE_SIZE_16MB; +	cplb_pagesize = SIZE_16M; +#else +	cplb_pageflags = PAGE_SIZE_4MB; +	cplb_pagesize = SIZE_4M; +#endif + + +	for (; addr < memory_start; addr += cplb_pagesize) {  		d_tbl[i_d].addr = addr; -		d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB; +		d_tbl[i_d++].data = SDRAM_DGENERIC | cplb_pageflags;  		i_tbl[i_i].addr = addr; -		i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB; +		i_tbl[i_i++].data = SDRAM_IGENERIC | cplb_pageflags;  	}  #ifdef CONFIG_ROMKERNEL  	/* Cover kernel XIP flash area */ +#ifdef CONFIG_BF60x +	addr = CONFIG_ROM_BASE & ~(16 * 1024 * 1024 - 1); +	d_tbl[i_d].addr = addr; +	d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_16MB; +	i_tbl[i_i].addr = addr; +	i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_16MB; +#else  	addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);  	d_tbl[i_d].addr = addr;  	d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB;  	i_tbl[i_i].addr = addr;  	i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;  #endif +#endif  	/* Cover L1 memory.  One 4M area for code and data each is enough.  */  	if (cpu == 0) { @@ -116,7 +134,7 @@ void __init generate_cplb_tables_all(void)  	    ((_ramend - uncached_end) >= 1 * 1024 * 1024))  		dcplb_bounds[i_d].eaddr = uncached_end;  	else -		dcplb_bounds[i_d].eaddr = uncached_end & ~(1 * 1024 * 1024); +		dcplb_bounds[i_d].eaddr = uncached_end & ~(1 * 1024 * 1024 - 1);  	dcplb_bounds[i_d++].data = SDRAM_DGENERIC;  	/* DMA uncached region.  */  	if (DMA_UNCACHED_REGION) { @@ -139,7 +157,7 @@ void __init generate_cplb_tables_all(void)  	dcplb_bounds[i_d].eaddr = BOOT_ROM_START;  	dcplb_bounds[i_d++].data = 0;  	/* BootROM -- largest one should be less than 1 meg.  */ -	dcplb_bounds[i_d].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); +	dcplb_bounds[i_d].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH;  	dcplb_bounds[i_d++].data = SDRAM_DGENERIC;  	if (L2_LENGTH) {  		/* Addressing hole up to L2 SRAM.  */ @@ -178,7 +196,7 @@ void __init generate_cplb_tables_all(void)  	icplb_bounds[i_i].eaddr = BOOT_ROM_START;  	icplb_bounds[i_i++].data = 0;  	/* BootROM -- largest one should be less than 1 meg.  */ -	icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); +	icplb_bounds[i_i].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH;  	icplb_bounds[i_i++].data = SDRAM_IGENERIC;  	if (L2_LENGTH) { diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index 5b88861d618..79cc0f6dcdd 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c @@ -145,7 +145,7 @@ MGR_ATTR static int dcplb_miss(int cpu)  	unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();  	int status = bfin_read_DCPLB_STATUS();  	int idx; -	unsigned long d_data, base, addr1, eaddr; +	unsigned long d_data, base, addr1, eaddr, cplb_pagesize, cplb_pageflags;  	nr_dcplb_miss[cpu]++;  	if (unlikely(status & FAULT_USERSUPV)) @@ -167,18 +167,43 @@ MGR_ATTR static int dcplb_miss(int cpu)  	if (unlikely(d_data == 0))  		return CPLB_NO_ADDR_MATCH; -	addr1 = addr & ~(SIZE_4M - 1);  	addr &= ~(SIZE_1M - 1);  	d_data |= PAGE_SIZE_1MB; -	if (addr1 >= base && (addr1 + SIZE_4M) <= eaddr) { + +	/* BF60x support large than 4M CPLB page size */ +#ifdef PAGE_SIZE_16MB +	cplb_pageflags = PAGE_SIZE_16MB; +	cplb_pagesize = SIZE_16M; +#else +	cplb_pageflags = PAGE_SIZE_4MB; +	cplb_pagesize = SIZE_4M; +#endif + +find_pagesize: +	addr1 = addr & ~(cplb_pagesize - 1); +	if (addr1 >= base && (addr1 + cplb_pagesize) <= eaddr) {  		/*  		 * This works because  		 * (PAGE_SIZE_4MB & PAGE_SIZE_1MB) == PAGE_SIZE_1MB.  		 */ -		d_data |= PAGE_SIZE_4MB; +		d_data |= cplb_pageflags;  		addr = addr1; +		goto found_pagesize; +	} else { +		if (cplb_pagesize > SIZE_4M) { +			cplb_pageflags = PAGE_SIZE_4MB; +			cplb_pagesize = SIZE_4M; +			goto find_pagesize; +		}  	} +found_pagesize: +#ifdef CONFIG_BF60x +	if ((addr >= ASYNC_BANK0_BASE) +		&& (addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)) +		d_data |= PAGE_SIZE_64MB; +#endif +  	/* Pick entry to evict */  	idx = evict_one_dcplb(cpu); diff --git a/arch/blackfin/kernel/cplbinfo.c b/arch/blackfin/kernel/cplbinfo.c index 0bdaa517a50..5b80d59e66e 100644 --- a/arch/blackfin/kernel/cplbinfo.c +++ b/arch/blackfin/kernel/cplbinfo.c @@ -17,8 +17,13 @@  #include <asm/cplbinit.h>  #include <asm/blackfin.h> -static char const page_strtbl[][3] = { "1K", "4K", "1M", "4M" }; -#define page(flags)    (((flags) & 0x30000) >> 16) +static char const page_strtbl[][4] = { +	"1K", "4K", "1M", "4M", +#ifdef CONFIG_BF60x +	"16K", "64K", "16M", "64M", +#endif +}; +#define page(flags)    (((flags) & 0x70000) >> 16)  #define strpage(flags) page_strtbl[page(flags)]  struct cplbinfo_data { @@ -116,14 +121,12 @@ static const struct seq_operations cplbinfo_sops = {  static int cplbinfo_open(struct inode *inode, struct file *file)  { -	struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);  	char cplb_type; -	unsigned int cpu; +	unsigned int cpu = (unsigned long)PDE_DATA(file_inode(file));  	int ret;  	struct seq_file *m;  	struct cplbinfo_data *cdata; -	cpu = (unsigned int)pde->data;  	cplb_type = cpu & CPLBINFO_DCPLB_FLAG ? 'D' : 'I';  	cpu &= ~CPLBINFO_DCPLB_FLAG; diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c new file mode 100644 index 00000000000..947ad083233 --- /dev/null +++ b/arch/blackfin/kernel/debug-mmrs.c @@ -0,0 +1,1893 @@ +/* + * debugfs interface to core/system MMRs + * + * Copyright 2007-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include <linux/debugfs.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c/bfin_twi.h> + +#include <asm/blackfin.h> +#include <asm/gpio.h> +#include <asm/gptimers.h> +#include <asm/bfin_can.h> +#include <asm/bfin_dma.h> +#include <asm/bfin_ppi.h> +#include <asm/bfin_serial.h> +#include <asm/bfin5xx_spi.h> +#include <asm/bfin_twi.h> + +/* Common code defines PORT_MUX on us, so redirect the MMR back locally */ +#ifdef BFIN_PORT_MUX +#undef PORT_MUX +#define PORT_MUX BFIN_PORT_MUX +#endif + +#define _d(name, bits, addr, perms) debugfs_create_x##bits(name, perms, parent, (u##bits *)(addr)) +#define d(name, bits, addr)         _d(name, bits, addr, S_IRUSR|S_IWUSR) +#define d_RO(name, bits, addr)      _d(name, bits, addr, S_IRUSR) +#define d_WO(name, bits, addr)      _d(name, bits, addr, S_IWUSR) + +#define D_RO(name, bits) d_RO(#name, bits, name) +#define D_WO(name, bits) d_WO(#name, bits, name) +#define D32(name)        d(#name, 32, name) +#define D16(name)        d(#name, 16, name) + +#define REGS_OFF(peri, mmr) offsetof(struct bfin_##peri##_regs, mmr) +#define __REGS(peri, sname, rname) \ +	do { \ +		struct bfin_##peri##_regs r; \ +		void *addr = (void *)(base + REGS_OFF(peri, rname)); \ +		strcpy(_buf, sname); \ +		if (sizeof(r.rname) == 2) \ +			debugfs_create_x16(buf, S_IRUSR|S_IWUSR, parent, addr); \ +		else \ +			debugfs_create_x32(buf, S_IRUSR|S_IWUSR, parent, addr); \ +	} while (0) +#define REGS_STR_PFX(buf, pfx, num) \ +	({ \ +		buf + (num >= 0 ? \ +			sprintf(buf, #pfx "%i_", num) : \ +			sprintf(buf, #pfx "_")); \ +	}) +#define REGS_STR_PFX_C(buf, pfx, num) \ +	({ \ +		buf + (num >= 0 ? \ +			sprintf(buf, #pfx "%c_", 'A' + num) : \ +			sprintf(buf, #pfx "_")); \ +	}) + +/* + * Core registers (not memory mapped) + */ +extern u32 last_seqstat; + +static int debug_cclk_get(void *data, u64 *val) +{ +	*val = get_cclk(); +	return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_debug_cclk, debug_cclk_get, NULL, "0x%08llx\n"); + +static int debug_sclk_get(void *data, u64 *val) +{ +	*val = get_sclk(); +	return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_debug_sclk, debug_sclk_get, NULL, "0x%08llx\n"); + +#define DEFINE_SYSREG(sr, pre, post) \ +static int sysreg_##sr##_get(void *data, u64 *val) \ +{ \ +	unsigned long tmp; \ +	pre; \ +	__asm__ __volatile__("%0 = " #sr ";" : "=d"(tmp)); \ +	*val = tmp; \ +	return 0; \ +} \ +static int sysreg_##sr##_set(void *data, u64 val) \ +{ \ +	unsigned long tmp = val; \ +	__asm__ __volatile__(#sr " = %0;" : : "d"(tmp)); \ +	post; \ +	return 0; \ +} \ +DEFINE_SIMPLE_ATTRIBUTE(fops_sysreg_##sr, sysreg_##sr##_get, sysreg_##sr##_set, "0x%08llx\n") + +DEFINE_SYSREG(cycles, , ); +DEFINE_SYSREG(cycles2, __asm__ __volatile__("%0 = cycles;" : "=d"(tmp)), ); +DEFINE_SYSREG(emudat, , ); +DEFINE_SYSREG(seqstat, , ); +DEFINE_SYSREG(syscfg, , CSYNC()); +#define D_SYSREG(sr) debugfs_create_file(#sr, S_IRUSR|S_IWUSR, parent, NULL, &fops_sysreg_##sr) + +#ifndef CONFIG_BF60x +/* + * CAN + */ +#define CAN_OFF(mmr)  REGS_OFF(can, mmr) +#define __CAN(uname, lname) __REGS(can, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_can(struct dentry *parent, unsigned long base, int num) +{ +	static struct dentry *am, *mb; +	int i, j; +	char buf[32], *_buf = REGS_STR_PFX(buf, CAN, num); + +	if (!am) { +		am = debugfs_create_dir("am", parent); +		mb = debugfs_create_dir("mb", parent); +	} + +	__CAN(MC1, mc1); +	__CAN(MD1, md1); +	__CAN(TRS1, trs1); +	__CAN(TRR1, trr1); +	__CAN(TA1, ta1); +	__CAN(AA1, aa1); +	__CAN(RMP1, rmp1); +	__CAN(RML1, rml1); +	__CAN(MBTIF1, mbtif1); +	__CAN(MBRIF1, mbrif1); +	__CAN(MBIM1, mbim1); +	__CAN(RFH1, rfh1); +	__CAN(OPSS1, opss1); + +	__CAN(MC2, mc2); +	__CAN(MD2, md2); +	__CAN(TRS2, trs2); +	__CAN(TRR2, trr2); +	__CAN(TA2, ta2); +	__CAN(AA2, aa2); +	__CAN(RMP2, rmp2); +	__CAN(RML2, rml2); +	__CAN(MBTIF2, mbtif2); +	__CAN(MBRIF2, mbrif2); +	__CAN(MBIM2, mbim2); +	__CAN(RFH2, rfh2); +	__CAN(OPSS2, opss2); + +	__CAN(CLOCK, clock); +	__CAN(TIMING, timing); +	__CAN(DEBUG, debug); +	__CAN(STATUS, status); +	__CAN(CEC, cec); +	__CAN(GIS, gis); +	__CAN(GIM, gim); +	__CAN(GIF, gif); +	__CAN(CONTROL, control); +	__CAN(INTR, intr); +	__CAN(VERSION, version); +	__CAN(MBTD, mbtd); +	__CAN(EWR, ewr); +	__CAN(ESR, esr); +	/*__CAN(UCREG, ucreg); no longer exists */ +	__CAN(UCCNT, uccnt); +	__CAN(UCRC, ucrc); +	__CAN(UCCNF, uccnf); +	__CAN(VERSION2, version2); + +	for (i = 0; i < 32; ++i) { +		sprintf(_buf, "AM%02iL", i); +		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, am, +			(u16 *)(base + CAN_OFF(msk[i].aml))); +		sprintf(_buf, "AM%02iH", i); +		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, am, +			(u16 *)(base + CAN_OFF(msk[i].amh))); + +		for (j = 0; j < 3; ++j) { +			sprintf(_buf, "MB%02i_DATA%i", i, j); +			debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb, +				(u16 *)(base + CAN_OFF(chl[i].data[j*2]))); +		} +		sprintf(_buf, "MB%02i_LENGTH", i); +		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb, +			(u16 *)(base + CAN_OFF(chl[i].dlc))); +		sprintf(_buf, "MB%02i_TIMESTAMP", i); +		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb, +			(u16 *)(base + CAN_OFF(chl[i].tsv))); +		sprintf(_buf, "MB%02i_ID0", i); +		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb, +			(u16 *)(base + CAN_OFF(chl[i].id0))); +		sprintf(_buf, "MB%02i_ID1", i); +		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb, +			(u16 *)(base + CAN_OFF(chl[i].id1))); +	} +} +#define CAN(num) bfin_debug_mmrs_can(parent, CAN##num##_MC1, num) + +/* + * DMA + */ +#define __DMA(uname, lname) __REGS(dma, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_dma(struct dentry *parent, unsigned long base, int num, char mdma, const char *pfx) +{ +	char buf[32], *_buf; + +	if (mdma) +		_buf = buf + sprintf(buf, "%s_%c%i_", pfx, mdma, num); +	else +		_buf = buf + sprintf(buf, "%s%i_", pfx, num); + +	__DMA(NEXT_DESC_PTR, next_desc_ptr); +	__DMA(START_ADDR, start_addr); +	__DMA(CONFIG, config); +	__DMA(X_COUNT, x_count); +	__DMA(X_MODIFY, x_modify); +	__DMA(Y_COUNT, y_count); +	__DMA(Y_MODIFY, y_modify); +	__DMA(CURR_DESC_PTR, curr_desc_ptr); +	__DMA(CURR_ADDR, curr_addr); +	__DMA(IRQ_STATUS, irq_status); +#ifndef CONFIG_BF60x +	if (strcmp(pfx, "IMDMA") != 0) +		__DMA(PERIPHERAL_MAP, peripheral_map); +#endif +	__DMA(CURR_X_COUNT, curr_x_count); +	__DMA(CURR_Y_COUNT, curr_y_count); +} +#define _DMA(num, base, mdma, pfx) bfin_debug_mmrs_dma(parent, base, num, mdma, pfx "DMA") +#define DMA(num)  _DMA(num, DMA##num##_NEXT_DESC_PTR, 0, "") +#define _MDMA(num, x) \ +	do { \ +		_DMA(num, x##DMA_D##num##_NEXT_DESC_PTR, 'D', #x); \ +		_DMA(num, x##DMA_S##num##_NEXT_DESC_PTR, 'S', #x); \ +	} while (0) +#define MDMA(num) _MDMA(num, M) +#define IMDMA(num) _MDMA(num, IM) + +/* + * EPPI + */ +#define __EPPI(uname, lname) __REGS(eppi, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_eppi(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, EPPI, num); +	__EPPI(STATUS, status); +	__EPPI(HCOUNT, hcount); +	__EPPI(HDELAY, hdelay); +	__EPPI(VCOUNT, vcount); +	__EPPI(VDELAY, vdelay); +	__EPPI(FRAME, frame); +	__EPPI(LINE, line); +	__EPPI(CLKDIV, clkdiv); +	__EPPI(CONTROL, control); +	__EPPI(FS1W_HBL, fs1w_hbl); +	__EPPI(FS1P_AVPL, fs1p_avpl); +	__EPPI(FS2W_LVB, fs2w_lvb); +	__EPPI(FS2P_LAVF, fs2p_lavf); +	__EPPI(CLIP, clip); +} +#define EPPI(num) bfin_debug_mmrs_eppi(parent, EPPI##num##_STATUS, num) + +/* + * General Purpose Timers + */ +#define __GPTIMER(uname, lname) __REGS(gptimer, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_gptimer(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, TIMER, num); +	__GPTIMER(CONFIG, config); +	__GPTIMER(COUNTER, counter); +	__GPTIMER(PERIOD, period); +	__GPTIMER(WIDTH, width); +} +#define GPTIMER(num) bfin_debug_mmrs_gptimer(parent, TIMER##num##_CONFIG, num) + +#define GPTIMER_GROUP_OFF(mmr) REGS_OFF(gptimer_group, mmr) +#define __GPTIMER_GROUP(uname, lname) __REGS(gptimer_group, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_gptimer_group(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf; + +	if (num == -1) { +		_buf = buf + sprintf(buf, "TIMER_"); +		__GPTIMER_GROUP(ENABLE, enable); +		__GPTIMER_GROUP(DISABLE, disable); +		__GPTIMER_GROUP(STATUS, status); +	} else { +		/* These MMRs are a bit odd as the group # is a suffix */ +		_buf = buf + sprintf(buf, "TIMER_ENABLE%i", num); +		d(buf, 16, base + GPTIMER_GROUP_OFF(enable)); + +		_buf = buf + sprintf(buf, "TIMER_DISABLE%i", num); +		d(buf, 16, base + GPTIMER_GROUP_OFF(disable)); + +		_buf = buf + sprintf(buf, "TIMER_STATUS%i", num); +		d(buf, 32, base + GPTIMER_GROUP_OFF(status)); +	} +} +#define GPTIMER_GROUP(mmr, num) bfin_debug_mmrs_gptimer_group(parent, mmr, num) + +/* + * Handshake MDMA + */ +#define __HMDMA(uname, lname) __REGS(hmdma, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_hmdma(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, HMDMA, num); +	__HMDMA(CONTROL, control); +	__HMDMA(ECINIT, ecinit); +	__HMDMA(BCINIT, bcinit); +	__HMDMA(ECURGENT, ecurgent); +	__HMDMA(ECOVERFLOW, ecoverflow); +	__HMDMA(ECOUNT, ecount); +	__HMDMA(BCOUNT, bcount); +} +#define HMDMA(num) bfin_debug_mmrs_hmdma(parent, HMDMA##num##_CONTROL, num) + +/* + * Peripheral Interrupts (PINT/GPIO) + */ +#ifdef PINT0_MASK_SET +#define __PINT(uname, lname) __REGS(pint, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_pint(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, PINT, num); +	__PINT(MASK_SET, mask_set); +	__PINT(MASK_CLEAR, mask_clear); +	__PINT(REQUEST, request); +	__PINT(ASSIGN, assign); +	__PINT(EDGE_SET, edge_set); +	__PINT(EDGE_CLEAR, edge_clear); +	__PINT(INVERT_SET, invert_set); +	__PINT(INVERT_CLEAR, invert_clear); +	__PINT(PINSTATE, pinstate); +	__PINT(LATCH, latch); +} +#define PINT(num) bfin_debug_mmrs_pint(parent, PINT##num##_MASK_SET, num) +#endif + +/* + * Port/GPIO + */ +#define bfin_gpio_regs gpio_port_t +#define __PORT(uname, lname) __REGS(gpio, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_port(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf; +#ifdef __ADSPBF54x__ +	_buf = REGS_STR_PFX_C(buf, PORT, num); +	__PORT(FER, port_fer); +	__PORT(SET, data_set); +	__PORT(CLEAR, data_clear); +	__PORT(DIR_SET, dir_set); +	__PORT(DIR_CLEAR, dir_clear); +	__PORT(INEN, inen); +	__PORT(MUX, port_mux); +#else +	_buf = buf + sprintf(buf, "PORT%cIO_", num); +	__PORT(CLEAR, data_clear); +	__PORT(SET, data_set); +	__PORT(TOGGLE, toggle); +	__PORT(MASKA, maska); +	__PORT(MASKA_CLEAR, maska_clear); +	__PORT(MASKA_SET, maska_set); +	__PORT(MASKA_TOGGLE, maska_toggle); +	__PORT(MASKB, maskb); +	__PORT(MASKB_CLEAR, maskb_clear); +	__PORT(MASKB_SET, maskb_set); +	__PORT(MASKB_TOGGLE, maskb_toggle); +	__PORT(DIR, dir); +	__PORT(POLAR, polar); +	__PORT(EDGE, edge); +	__PORT(BOTH, both); +	__PORT(INEN, inen); +#endif +	_buf[-1] = '\0'; +	d(buf, 16, base + REGS_OFF(gpio, data)); +} +#define PORT(base, num) bfin_debug_mmrs_port(parent, base, num) + +/* + * PPI + */ +#define __PPI(uname, lname) __REGS(ppi, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_ppi(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, PPI, num); +	__PPI(CONTROL, control); +	__PPI(STATUS, status); +	__PPI(COUNT, count); +	__PPI(DELAY, delay); +	__PPI(FRAME, frame); +} +#define PPI(num) bfin_debug_mmrs_ppi(parent, PPI##num##_CONTROL, num) + +/* + * SPI + */ +#define __SPI(uname, lname) __REGS(spi, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_spi(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, SPI, num); +	__SPI(CTL, ctl); +	__SPI(FLG, flg); +	__SPI(STAT, stat); +	__SPI(TDBR, tdbr); +	__SPI(RDBR, rdbr); +	__SPI(BAUD, baud); +	__SPI(SHADOW, shadow); +} +#define SPI(num) bfin_debug_mmrs_spi(parent, SPI##num##_REGBASE, num) + +/* + * SPORT + */ +static inline int sport_width(void *mmr) +{ +	unsigned long lmmr = (unsigned long)mmr; +	if ((lmmr & 0xff) == 0x10) +		/* SPORT#_TX has 0x10 offset -> SPORT#_TCR2 has 0x04 offset */ +		lmmr -= 0xc; +	else +		/* SPORT#_RX has 0x18 offset -> SPORT#_RCR2 has 0x24 offset */ +		lmmr += 0xc; +	/* extract SLEN field from control register 2 and add 1 */ +	return (bfin_read16(lmmr) & 0x1f) + 1; +} +static int sport_set(void *mmr, u64 val) +{ +	unsigned long flags; +	local_irq_save(flags); +	if (sport_width(mmr) <= 16) +		bfin_write16(mmr, val); +	else +		bfin_write32(mmr, val); +	local_irq_restore(flags); +	return 0; +} +static int sport_get(void *mmr, u64 *val) +{ +	unsigned long flags; +	local_irq_save(flags); +	if (sport_width(mmr) <= 16) +		*val = bfin_read16(mmr); +	else +		*val = bfin_read32(mmr); +	local_irq_restore(flags); +	return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_sport, sport_get, sport_set, "0x%08llx\n"); +/*DEFINE_SIMPLE_ATTRIBUTE(fops_sport_ro, sport_get, NULL, "0x%08llx\n");*/ +DEFINE_SIMPLE_ATTRIBUTE(fops_sport_wo, NULL, sport_set, "0x%08llx\n"); +#define SPORT_OFF(mmr) (SPORT0_##mmr - SPORT0_TCR1) +#define _D_SPORT(name, perms, fops) \ +	do { \ +		strcpy(_buf, #name); \ +		debugfs_create_file(buf, perms, parent, (void *)(base + SPORT_OFF(name)), fops); \ +	} while (0) +#define __SPORT_RW(name) _D_SPORT(name, S_IRUSR|S_IWUSR, &fops_sport) +#define __SPORT_RO(name) _D_SPORT(name, S_IRUSR, &fops_sport_ro) +#define __SPORT_WO(name) _D_SPORT(name, S_IWUSR, &fops_sport_wo) +#define __SPORT(name, bits) \ +	do { \ +		strcpy(_buf, #name); \ +		debugfs_create_x##bits(buf, S_IRUSR|S_IWUSR, parent, (u##bits *)(base + SPORT_OFF(name))); \ +	} while (0) +static void __init __maybe_unused +bfin_debug_mmrs_sport(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, SPORT, num); +	__SPORT(CHNL, 16); +	__SPORT(MCMC1, 16); +	__SPORT(MCMC2, 16); +	__SPORT(MRCS0, 32); +	__SPORT(MRCS1, 32); +	__SPORT(MRCS2, 32); +	__SPORT(MRCS3, 32); +	__SPORT(MTCS0, 32); +	__SPORT(MTCS1, 32); +	__SPORT(MTCS2, 32); +	__SPORT(MTCS3, 32); +	__SPORT(RCLKDIV, 16); +	__SPORT(RCR1, 16); +	__SPORT(RCR2, 16); +	__SPORT(RFSDIV, 16); +	__SPORT_RW(RX); +	__SPORT(STAT, 16); +	__SPORT(TCLKDIV, 16); +	__SPORT(TCR1, 16); +	__SPORT(TCR2, 16); +	__SPORT(TFSDIV, 16); +	__SPORT_WO(TX); +} +#define SPORT(num) bfin_debug_mmrs_sport(parent, SPORT##num##_TCR1, num) + +/* + * TWI + */ +#define __TWI(uname, lname) __REGS(twi, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_twi(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, TWI, num); +	__TWI(CLKDIV, clkdiv); +	__TWI(CONTROL, control); +	__TWI(SLAVE_CTL, slave_ctl); +	__TWI(SLAVE_STAT, slave_stat); +	__TWI(SLAVE_ADDR, slave_addr); +	__TWI(MASTER_CTL, master_ctl); +	__TWI(MASTER_STAT, master_stat); +	__TWI(MASTER_ADDR, master_addr); +	__TWI(INT_STAT, int_stat); +	__TWI(INT_MASK, int_mask); +	__TWI(FIFO_CTL, fifo_ctl); +	__TWI(FIFO_STAT, fifo_stat); +	__TWI(XMT_DATA8, xmt_data8); +	__TWI(XMT_DATA16, xmt_data16); +	__TWI(RCV_DATA8, rcv_data8); +	__TWI(RCV_DATA16, rcv_data16); +} +#define TWI(num) bfin_debug_mmrs_twi(parent, TWI##num##_CLKDIV, num) + +/* + * UART + */ +#define __UART(uname, lname) __REGS(uart, #uname, lname) +static void __init __maybe_unused +bfin_debug_mmrs_uart(struct dentry *parent, unsigned long base, int num) +{ +	char buf[32], *_buf = REGS_STR_PFX(buf, UART, num); +#ifdef BFIN_UART_BF54X_STYLE +	__UART(DLL, dll); +	__UART(DLH, dlh); +	__UART(GCTL, gctl); +	__UART(LCR, lcr); +	__UART(MCR, mcr); +	__UART(LSR, lsr); +	__UART(MSR, msr); +	__UART(SCR, scr); +	__UART(IER_SET, ier_set); +	__UART(IER_CLEAR, ier_clear); +	__UART(THR, thr); +	__UART(RBR, rbr); +#else +	__UART(DLL, dll); +	__UART(THR, thr); +	__UART(RBR, rbr); +	__UART(DLH, dlh); +	__UART(IER, ier); +	__UART(IIR, iir); +	__UART(LCR, lcr); +	__UART(MCR, mcr); +	__UART(LSR, lsr); +	__UART(MSR, msr); +	__UART(SCR, scr); +	__UART(GCTL, gctl); +#endif +} +#define UART(num) bfin_debug_mmrs_uart(parent, UART##num##_DLL, num) +#endif /* CONFIG_BF60x */ +/* + * The actual debugfs generation + */ +static struct dentry *debug_mmrs_dentry; + +static int __init bfin_debug_mmrs_init(void) +{ +	struct dentry *top, *parent; + +	pr_info("debug-mmrs: setting up Blackfin MMR debugfs\n"); + +	top = debugfs_create_dir("blackfin", NULL); +	if (top == NULL) +		return -1; + +	parent = debugfs_create_dir("core_regs", top); +	debugfs_create_file("cclk", S_IRUSR, parent, NULL, &fops_debug_cclk); +	debugfs_create_file("sclk", S_IRUSR, parent, NULL, &fops_debug_sclk); +	debugfs_create_x32("last_seqstat", S_IRUSR, parent, &last_seqstat); +	D_SYSREG(cycles); +	D_SYSREG(cycles2); +	D_SYSREG(emudat); +	D_SYSREG(seqstat); +	D_SYSREG(syscfg); + +	/* Core MMRs */ +	parent = debugfs_create_dir("ctimer", top); +	D32(TCNTL); +	D32(TCOUNT); +	D32(TPERIOD); +	D32(TSCALE); + +	parent = debugfs_create_dir("cec", top); +	D32(EVT0); +	D32(EVT1); +	D32(EVT2); +	D32(EVT3); +	D32(EVT4); +	D32(EVT5); +	D32(EVT6); +	D32(EVT7); +	D32(EVT8); +	D32(EVT9); +	D32(EVT10); +	D32(EVT11); +	D32(EVT12); +	D32(EVT13); +	D32(EVT14); +	D32(EVT15); +	D32(EVT_OVERRIDE); +	D32(IMASK); +	D32(IPEND); +	D32(ILAT); +	D32(IPRIO); + +	parent = debugfs_create_dir("debug", top); +	D32(DBGSTAT); +	D32(DSPID); + +	parent = debugfs_create_dir("mmu", top); +	D32(SRAM_BASE_ADDRESS); +	D32(DCPLB_ADDR0); +	D32(DCPLB_ADDR10); +	D32(DCPLB_ADDR11); +	D32(DCPLB_ADDR12); +	D32(DCPLB_ADDR13); +	D32(DCPLB_ADDR14); +	D32(DCPLB_ADDR15); +	D32(DCPLB_ADDR1); +	D32(DCPLB_ADDR2); +	D32(DCPLB_ADDR3); +	D32(DCPLB_ADDR4); +	D32(DCPLB_ADDR5); +	D32(DCPLB_ADDR6); +	D32(DCPLB_ADDR7); +	D32(DCPLB_ADDR8); +	D32(DCPLB_ADDR9); +	D32(DCPLB_DATA0); +	D32(DCPLB_DATA10); +	D32(DCPLB_DATA11); +	D32(DCPLB_DATA12); +	D32(DCPLB_DATA13); +	D32(DCPLB_DATA14); +	D32(DCPLB_DATA15); +	D32(DCPLB_DATA1); +	D32(DCPLB_DATA2); +	D32(DCPLB_DATA3); +	D32(DCPLB_DATA4); +	D32(DCPLB_DATA5); +	D32(DCPLB_DATA6); +	D32(DCPLB_DATA7); +	D32(DCPLB_DATA8); +	D32(DCPLB_DATA9); +	D32(DCPLB_FAULT_ADDR); +	D32(DCPLB_STATUS); +	D32(DMEM_CONTROL); +	D32(DTEST_COMMAND); +	D32(DTEST_DATA0); +	D32(DTEST_DATA1); + +	D32(ICPLB_ADDR0); +	D32(ICPLB_ADDR1); +	D32(ICPLB_ADDR2); +	D32(ICPLB_ADDR3); +	D32(ICPLB_ADDR4); +	D32(ICPLB_ADDR5); +	D32(ICPLB_ADDR6); +	D32(ICPLB_ADDR7); +	D32(ICPLB_ADDR8); +	D32(ICPLB_ADDR9); +	D32(ICPLB_ADDR10); +	D32(ICPLB_ADDR11); +	D32(ICPLB_ADDR12); +	D32(ICPLB_ADDR13); +	D32(ICPLB_ADDR14); +	D32(ICPLB_ADDR15); +	D32(ICPLB_DATA0); +	D32(ICPLB_DATA1); +	D32(ICPLB_DATA2); +	D32(ICPLB_DATA3); +	D32(ICPLB_DATA4); +	D32(ICPLB_DATA5); +	D32(ICPLB_DATA6); +	D32(ICPLB_DATA7); +	D32(ICPLB_DATA8); +	D32(ICPLB_DATA9); +	D32(ICPLB_DATA10); +	D32(ICPLB_DATA11); +	D32(ICPLB_DATA12); +	D32(ICPLB_DATA13); +	D32(ICPLB_DATA14); +	D32(ICPLB_DATA15); +	D32(ICPLB_FAULT_ADDR); +	D32(ICPLB_STATUS); +	D32(IMEM_CONTROL); +	if (!ANOMALY_05000481) { +		D32(ITEST_COMMAND); +		D32(ITEST_DATA0); +		D32(ITEST_DATA1); +	} + +	parent = debugfs_create_dir("perf", top); +	D32(PFCNTR0); +	D32(PFCNTR1); +	D32(PFCTL); + +	parent = debugfs_create_dir("trace", top); +	D32(TBUF); +	D32(TBUFCTL); +	D32(TBUFSTAT); + +	parent = debugfs_create_dir("watchpoint", top); +	D32(WPIACTL); +	D32(WPIA0); +	D32(WPIA1); +	D32(WPIA2); +	D32(WPIA3); +	D32(WPIA4); +	D32(WPIA5); +	D32(WPIACNT0); +	D32(WPIACNT1); +	D32(WPIACNT2); +	D32(WPIACNT3); +	D32(WPIACNT4); +	D32(WPIACNT5); +	D32(WPDACTL); +	D32(WPDA0); +	D32(WPDA1); +	D32(WPDACNT0); +	D32(WPDACNT1); +	D32(WPSTAT); +#ifndef CONFIG_BF60x +	/* System MMRs */ +#ifdef ATAPI_CONTROL +	parent = debugfs_create_dir("atapi", top); +	D16(ATAPI_CONTROL); +	D16(ATAPI_DEV_ADDR); +	D16(ATAPI_DEV_RXBUF); +	D16(ATAPI_DEV_TXBUF); +	D16(ATAPI_DMA_TFRCNT); +	D16(ATAPI_INT_MASK); +	D16(ATAPI_INT_STATUS); +	D16(ATAPI_LINE_STATUS); +	D16(ATAPI_MULTI_TIM_0); +	D16(ATAPI_MULTI_TIM_1); +	D16(ATAPI_MULTI_TIM_2); +	D16(ATAPI_PIO_TFRCNT); +	D16(ATAPI_PIO_TIM_0); +	D16(ATAPI_PIO_TIM_1); +	D16(ATAPI_REG_TIM_0); +	D16(ATAPI_SM_STATE); +	D16(ATAPI_STATUS); +	D16(ATAPI_TERMINATE); +	D16(ATAPI_UDMAOUT_TFRCNT); +	D16(ATAPI_ULTRA_TIM_0); +	D16(ATAPI_ULTRA_TIM_1); +	D16(ATAPI_ULTRA_TIM_2); +	D16(ATAPI_ULTRA_TIM_3); +	D16(ATAPI_UMAIN_TFRCNT); +	D16(ATAPI_XFER_LEN); +#endif + +#if defined(CAN_MC1) || defined(CAN0_MC1) || defined(CAN1_MC1) +	parent = debugfs_create_dir("can", top); +# ifdef CAN_MC1 +	bfin_debug_mmrs_can(parent, CAN_MC1, -1); +# endif +# ifdef CAN0_MC1 +	CAN(0); +# endif +# ifdef CAN1_MC1 +	CAN(1); +# endif +#endif + +#ifdef CNT_COMMAND +	parent = debugfs_create_dir("counter", top); +	D16(CNT_COMMAND); +	D16(CNT_CONFIG); +	D32(CNT_COUNTER); +	D16(CNT_DEBOUNCE); +	D16(CNT_IMASK); +	D32(CNT_MAX); +	D32(CNT_MIN); +	D16(CNT_STATUS); +#endif + +	parent = debugfs_create_dir("dmac", top); +#ifdef DMAC_TC_CNT +	D16(DMAC_TC_CNT); +	D16(DMAC_TC_PER); +#endif +#ifdef DMAC0_TC_CNT +	D16(DMAC0_TC_CNT); +	D16(DMAC0_TC_PER); +#endif +#ifdef DMAC1_TC_CNT +	D16(DMAC1_TC_CNT); +	D16(DMAC1_TC_PER); +#endif +#ifdef DMAC1_PERIMUX +	D16(DMAC1_PERIMUX); +#endif + +#ifdef __ADSPBF561__ +	/* XXX: should rewrite the MMR map */ +# define DMA0_NEXT_DESC_PTR DMA2_0_NEXT_DESC_PTR +# define DMA1_NEXT_DESC_PTR DMA2_1_NEXT_DESC_PTR +# define DMA2_NEXT_DESC_PTR DMA2_2_NEXT_DESC_PTR +# define DMA3_NEXT_DESC_PTR DMA2_3_NEXT_DESC_PTR +# define DMA4_NEXT_DESC_PTR DMA2_4_NEXT_DESC_PTR +# define DMA5_NEXT_DESC_PTR DMA2_5_NEXT_DESC_PTR +# define DMA6_NEXT_DESC_PTR DMA2_6_NEXT_DESC_PTR +# define DMA7_NEXT_DESC_PTR DMA2_7_NEXT_DESC_PTR +# define DMA8_NEXT_DESC_PTR DMA2_8_NEXT_DESC_PTR +# define DMA9_NEXT_DESC_PTR DMA2_9_NEXT_DESC_PTR +# define DMA10_NEXT_DESC_PTR DMA2_10_NEXT_DESC_PTR +# define DMA11_NEXT_DESC_PTR DMA2_11_NEXT_DESC_PTR +# define DMA12_NEXT_DESC_PTR DMA1_0_NEXT_DESC_PTR +# define DMA13_NEXT_DESC_PTR DMA1_1_NEXT_DESC_PTR +# define DMA14_NEXT_DESC_PTR DMA1_2_NEXT_DESC_PTR +# define DMA15_NEXT_DESC_PTR DMA1_3_NEXT_DESC_PTR +# define DMA16_NEXT_DESC_PTR DMA1_4_NEXT_DESC_PTR +# define DMA17_NEXT_DESC_PTR DMA1_5_NEXT_DESC_PTR +# define DMA18_NEXT_DESC_PTR DMA1_6_NEXT_DESC_PTR +# define DMA19_NEXT_DESC_PTR DMA1_7_NEXT_DESC_PTR +# define DMA20_NEXT_DESC_PTR DMA1_8_NEXT_DESC_PTR +# define DMA21_NEXT_DESC_PTR DMA1_9_NEXT_DESC_PTR +# define DMA22_NEXT_DESC_PTR DMA1_10_NEXT_DESC_PTR +# define DMA23_NEXT_DESC_PTR DMA1_11_NEXT_DESC_PTR +#endif +	parent = debugfs_create_dir("dma", top); +	DMA(0); +	DMA(1); +	DMA(1); +	DMA(2); +	DMA(3); +	DMA(4); +	DMA(5); +	DMA(6); +	DMA(7); +#ifdef DMA8_NEXT_DESC_PTR +	DMA(8); +	DMA(9); +	DMA(10); +	DMA(11); +#endif +#ifdef DMA12_NEXT_DESC_PTR +	DMA(12); +	DMA(13); +	DMA(14); +	DMA(15); +	DMA(16); +	DMA(17); +	DMA(18); +	DMA(19); +#endif +#ifdef DMA20_NEXT_DESC_PTR +	DMA(20); +	DMA(21); +	DMA(22); +	DMA(23); +#endif + +	parent = debugfs_create_dir("ebiu_amc", top); +	D32(EBIU_AMBCTL0); +	D32(EBIU_AMBCTL1); +	D16(EBIU_AMGCTL); +#ifdef EBIU_MBSCTL +	D16(EBIU_MBSCTL); +	D32(EBIU_ARBSTAT); +	D32(EBIU_MODE); +	D16(EBIU_FCTL); +#endif + +#ifdef EBIU_SDGCTL +	parent = debugfs_create_dir("ebiu_sdram", top); +# ifdef __ADSPBF561__ +	D32(EBIU_SDBCTL); +# else +	D16(EBIU_SDBCTL); +# endif +	D32(EBIU_SDGCTL); +	D16(EBIU_SDRRC); +	D16(EBIU_SDSTAT); +#endif + +#ifdef EBIU_DDRACCT +	parent = debugfs_create_dir("ebiu_ddr", top); +	D32(EBIU_DDRACCT); +	D32(EBIU_DDRARCT); +	D32(EBIU_DDRBRC0); +	D32(EBIU_DDRBRC1); +	D32(EBIU_DDRBRC2); +	D32(EBIU_DDRBRC3); +	D32(EBIU_DDRBRC4); +	D32(EBIU_DDRBRC5); +	D32(EBIU_DDRBRC6); +	D32(EBIU_DDRBRC7); +	D32(EBIU_DDRBWC0); +	D32(EBIU_DDRBWC1); +	D32(EBIU_DDRBWC2); +	D32(EBIU_DDRBWC3); +	D32(EBIU_DDRBWC4); +	D32(EBIU_DDRBWC5); +	D32(EBIU_DDRBWC6); +	D32(EBIU_DDRBWC7); +	D32(EBIU_DDRCTL0); +	D32(EBIU_DDRCTL1); +	D32(EBIU_DDRCTL2); +	D32(EBIU_DDRCTL3); +	D32(EBIU_DDRGC0); +	D32(EBIU_DDRGC1); +	D32(EBIU_DDRGC2); +	D32(EBIU_DDRGC3); +	D32(EBIU_DDRMCCL); +	D32(EBIU_DDRMCEN); +	D32(EBIU_DDRQUE); +	D32(EBIU_DDRTACT); +	D32(EBIU_ERRADD); +	D16(EBIU_ERRMST); +	D16(EBIU_RSTCTL); +#endif + +#ifdef EMAC_ADDRHI +	parent = debugfs_create_dir("emac", top); +	D32(EMAC_ADDRHI); +	D32(EMAC_ADDRLO); +	D32(EMAC_FLC); +	D32(EMAC_HASHHI); +	D32(EMAC_HASHLO); +	D32(EMAC_MMC_CTL); +	D32(EMAC_MMC_RIRQE); +	D32(EMAC_MMC_RIRQS); +	D32(EMAC_MMC_TIRQE); +	D32(EMAC_MMC_TIRQS); +	D32(EMAC_OPMODE); +	D32(EMAC_RXC_ALIGN); +	D32(EMAC_RXC_ALLFRM); +	D32(EMAC_RXC_ALLOCT); +	D32(EMAC_RXC_BROAD); +	D32(EMAC_RXC_DMAOVF); +	D32(EMAC_RXC_EQ64); +	D32(EMAC_RXC_FCS); +	D32(EMAC_RXC_GE1024); +	D32(EMAC_RXC_LNERRI); +	D32(EMAC_RXC_LNERRO); +	D32(EMAC_RXC_LONG); +	D32(EMAC_RXC_LT1024); +	D32(EMAC_RXC_LT128); +	D32(EMAC_RXC_LT256); +	D32(EMAC_RXC_LT512); +	D32(EMAC_RXC_MACCTL); +	D32(EMAC_RXC_MULTI); +	D32(EMAC_RXC_OCTET); +	D32(EMAC_RXC_OK); +	D32(EMAC_RXC_OPCODE); +	D32(EMAC_RXC_PAUSE); +	D32(EMAC_RXC_SHORT); +	D32(EMAC_RXC_TYPED); +	D32(EMAC_RXC_UNICST); +	D32(EMAC_RX_IRQE); +	D32(EMAC_RX_STAT); +	D32(EMAC_RX_STKY); +	D32(EMAC_STAADD); +	D32(EMAC_STADAT); +	D32(EMAC_SYSCTL); +	D32(EMAC_SYSTAT); +	D32(EMAC_TXC_1COL); +	D32(EMAC_TXC_ABORT); +	D32(EMAC_TXC_ALLFRM); +	D32(EMAC_TXC_ALLOCT); +	D32(EMAC_TXC_BROAD); +	D32(EMAC_TXC_CRSERR); +	D32(EMAC_TXC_DEFER); +	D32(EMAC_TXC_DMAUND); +	D32(EMAC_TXC_EQ64); +	D32(EMAC_TXC_GE1024); +	D32(EMAC_TXC_GT1COL); +	D32(EMAC_TXC_LATECL); +	D32(EMAC_TXC_LT1024); +	D32(EMAC_TXC_LT128); +	D32(EMAC_TXC_LT256); +	D32(EMAC_TXC_LT512); +	D32(EMAC_TXC_MACCTL); +	D32(EMAC_TXC_MULTI); +	D32(EMAC_TXC_OCTET); +	D32(EMAC_TXC_OK); +	D32(EMAC_TXC_UNICST); +	D32(EMAC_TXC_XS_COL); +	D32(EMAC_TXC_XS_DFR); +	D32(EMAC_TX_IRQE); +	D32(EMAC_TX_STAT); +	D32(EMAC_TX_STKY); +	D32(EMAC_VLAN1); +	D32(EMAC_VLAN2); +	D32(EMAC_WKUP_CTL); +	D32(EMAC_WKUP_FFCMD); +	D32(EMAC_WKUP_FFCRC0); +	D32(EMAC_WKUP_FFCRC1); +	D32(EMAC_WKUP_FFMSK0); +	D32(EMAC_WKUP_FFMSK1); +	D32(EMAC_WKUP_FFMSK2); +	D32(EMAC_WKUP_FFMSK3); +	D32(EMAC_WKUP_FFOFF); +# ifdef EMAC_PTP_ACCR +	D32(EMAC_PTP_ACCR); +	D32(EMAC_PTP_ADDEND); +	D32(EMAC_PTP_ALARMHI); +	D32(EMAC_PTP_ALARMLO); +	D16(EMAC_PTP_CTL); +	D32(EMAC_PTP_FOFF); +	D32(EMAC_PTP_FV1); +	D32(EMAC_PTP_FV2); +	D32(EMAC_PTP_FV3); +	D16(EMAC_PTP_ID_OFF); +	D32(EMAC_PTP_ID_SNAP); +	D16(EMAC_PTP_IE); +	D16(EMAC_PTP_ISTAT); +	D32(EMAC_PTP_OFFSET); +	D32(EMAC_PTP_PPS_PERIOD); +	D32(EMAC_PTP_PPS_STARTHI); +	D32(EMAC_PTP_PPS_STARTLO); +	D32(EMAC_PTP_RXSNAPHI); +	D32(EMAC_PTP_RXSNAPLO); +	D32(EMAC_PTP_TIMEHI); +	D32(EMAC_PTP_TIMELO); +	D32(EMAC_PTP_TXSNAPHI); +	D32(EMAC_PTP_TXSNAPLO); +# endif +#endif + +#if defined(EPPI0_STATUS) || defined(EPPI1_STATUS) || defined(EPPI2_STATUS) +	parent = debugfs_create_dir("eppi", top); +# ifdef EPPI0_STATUS +	EPPI(0); +# endif +# ifdef EPPI1_STATUS +	EPPI(1); +# endif +# ifdef EPPI2_STATUS +	EPPI(2); +# endif +#endif + +	parent = debugfs_create_dir("gptimer", top); +#ifdef TIMER_ENABLE +	GPTIMER_GROUP(TIMER_ENABLE, -1); +#endif +#ifdef TIMER_ENABLE0 +	GPTIMER_GROUP(TIMER_ENABLE0, 0); +#endif +#ifdef TIMER_ENABLE1 +	GPTIMER_GROUP(TIMER_ENABLE1, 1); +#endif +	/* XXX: Should convert BF561 MMR names */ +#ifdef TMRS4_DISABLE +	GPTIMER_GROUP(TMRS4_ENABLE, 0); +	GPTIMER_GROUP(TMRS8_ENABLE, 1); +#endif +	GPTIMER(0); +	GPTIMER(1); +	GPTIMER(2); +#ifdef TIMER3_CONFIG +	GPTIMER(3); +	GPTIMER(4); +	GPTIMER(5); +	GPTIMER(6); +	GPTIMER(7); +#endif +#ifdef TIMER8_CONFIG +	GPTIMER(8); +	GPTIMER(9); +	GPTIMER(10); +#endif +#ifdef TIMER11_CONFIG +	GPTIMER(11); +#endif + +#ifdef HMDMA0_CONTROL +	parent = debugfs_create_dir("hmdma", top); +	HMDMA(0); +	HMDMA(1); +#endif + +#ifdef HOST_CONTROL +	parent = debugfs_create_dir("hostdp", top); +	D16(HOST_CONTROL); +	D16(HOST_STATUS); +	D16(HOST_TIMEOUT); +#endif + +#ifdef IMDMA_S0_CONFIG +	parent = debugfs_create_dir("imdma", top); +	IMDMA(0); +	IMDMA(1); +#endif + +#ifdef KPAD_CTL +	parent = debugfs_create_dir("keypad", top); +	D16(KPAD_CTL); +	D16(KPAD_PRESCALE); +	D16(KPAD_MSEL); +	D16(KPAD_ROWCOL); +	D16(KPAD_STAT); +	D16(KPAD_SOFTEVAL); +#endif + +	parent = debugfs_create_dir("mdma", top); +	MDMA(0); +	MDMA(1); +#ifdef MDMA_D2_CONFIG +	MDMA(2); +	MDMA(3); +#endif + +#ifdef MXVR_CONFIG +	parent = debugfs_create_dir("mxvr", top); +	D16(MXVR_CONFIG); +# ifdef MXVR_PLL_CTL_0 +	D32(MXVR_PLL_CTL_0); +# endif +	D32(MXVR_STATE_0); +	D32(MXVR_STATE_1); +	D32(MXVR_INT_STAT_0); +	D32(MXVR_INT_STAT_1); +	D32(MXVR_INT_EN_0); +	D32(MXVR_INT_EN_1); +	D16(MXVR_POSITION); +	D16(MXVR_MAX_POSITION); +	D16(MXVR_DELAY); +	D16(MXVR_MAX_DELAY); +	D32(MXVR_LADDR); +	D16(MXVR_GADDR); +	D32(MXVR_AADDR); +	D32(MXVR_ALLOC_0); +	D32(MXVR_ALLOC_1); +	D32(MXVR_ALLOC_2); +	D32(MXVR_ALLOC_3); +	D32(MXVR_ALLOC_4); +	D32(MXVR_ALLOC_5); +	D32(MXVR_ALLOC_6); +	D32(MXVR_ALLOC_7); +	D32(MXVR_ALLOC_8); +	D32(MXVR_ALLOC_9); +	D32(MXVR_ALLOC_10); +	D32(MXVR_ALLOC_11); +	D32(MXVR_ALLOC_12); +	D32(MXVR_ALLOC_13); +	D32(MXVR_ALLOC_14); +	D32(MXVR_SYNC_LCHAN_0); +	D32(MXVR_SYNC_LCHAN_1); +	D32(MXVR_SYNC_LCHAN_2); +	D32(MXVR_SYNC_LCHAN_3); +	D32(MXVR_SYNC_LCHAN_4); +	D32(MXVR_SYNC_LCHAN_5); +	D32(MXVR_SYNC_LCHAN_6); +	D32(MXVR_SYNC_LCHAN_7); +	D32(MXVR_DMA0_CONFIG); +	D32(MXVR_DMA0_START_ADDR); +	D16(MXVR_DMA0_COUNT); +	D32(MXVR_DMA0_CURR_ADDR); +	D16(MXVR_DMA0_CURR_COUNT); +	D32(MXVR_DMA1_CONFIG); +	D32(MXVR_DMA1_START_ADDR); +	D16(MXVR_DMA1_COUNT); +	D32(MXVR_DMA1_CURR_ADDR); +	D16(MXVR_DMA1_CURR_COUNT); +	D32(MXVR_DMA2_CONFIG); +	D32(MXVR_DMA2_START_ADDR); +	D16(MXVR_DMA2_COUNT); +	D32(MXVR_DMA2_CURR_ADDR); +	D16(MXVR_DMA2_CURR_COUNT); +	D32(MXVR_DMA3_CONFIG); +	D32(MXVR_DMA3_START_ADDR); +	D16(MXVR_DMA3_COUNT); +	D32(MXVR_DMA3_CURR_ADDR); +	D16(MXVR_DMA3_CURR_COUNT); +	D32(MXVR_DMA4_CONFIG); +	D32(MXVR_DMA4_START_ADDR); +	D16(MXVR_DMA4_COUNT); +	D32(MXVR_DMA4_CURR_ADDR); +	D16(MXVR_DMA4_CURR_COUNT); +	D32(MXVR_DMA5_CONFIG); +	D32(MXVR_DMA5_START_ADDR); +	D16(MXVR_DMA5_COUNT); +	D32(MXVR_DMA5_CURR_ADDR); +	D16(MXVR_DMA5_CURR_COUNT); +	D32(MXVR_DMA6_CONFIG); +	D32(MXVR_DMA6_START_ADDR); +	D16(MXVR_DMA6_COUNT); +	D32(MXVR_DMA6_CURR_ADDR); +	D16(MXVR_DMA6_CURR_COUNT); +	D32(MXVR_DMA7_CONFIG); +	D32(MXVR_DMA7_START_ADDR); +	D16(MXVR_DMA7_COUNT); +	D32(MXVR_DMA7_CURR_ADDR); +	D16(MXVR_DMA7_CURR_COUNT); +	D16(MXVR_AP_CTL); +	D32(MXVR_APRB_START_ADDR); +	D32(MXVR_APRB_CURR_ADDR); +	D32(MXVR_APTB_START_ADDR); +	D32(MXVR_APTB_CURR_ADDR); +	D32(MXVR_CM_CTL); +	D32(MXVR_CMRB_START_ADDR); +	D32(MXVR_CMRB_CURR_ADDR); +	D32(MXVR_CMTB_START_ADDR); +	D32(MXVR_CMTB_CURR_ADDR); +	D32(MXVR_RRDB_START_ADDR); +	D32(MXVR_RRDB_CURR_ADDR); +	D32(MXVR_PAT_DATA_0); +	D32(MXVR_PAT_EN_0); +	D32(MXVR_PAT_DATA_1); +	D32(MXVR_PAT_EN_1); +	D16(MXVR_FRAME_CNT_0); +	D16(MXVR_FRAME_CNT_1); +	D32(MXVR_ROUTING_0); +	D32(MXVR_ROUTING_1); +	D32(MXVR_ROUTING_2); +	D32(MXVR_ROUTING_3); +	D32(MXVR_ROUTING_4); +	D32(MXVR_ROUTING_5); +	D32(MXVR_ROUTING_6); +	D32(MXVR_ROUTING_7); +	D32(MXVR_ROUTING_8); +	D32(MXVR_ROUTING_9); +	D32(MXVR_ROUTING_10); +	D32(MXVR_ROUTING_11); +	D32(MXVR_ROUTING_12); +	D32(MXVR_ROUTING_13); +	D32(MXVR_ROUTING_14); +# ifdef MXVR_PLL_CTL_1 +	D32(MXVR_PLL_CTL_1); +# endif +	D16(MXVR_BLOCK_CNT); +# ifdef MXVR_CLK_CTL +	D32(MXVR_CLK_CTL); +# endif +# ifdef MXVR_CDRPLL_CTL +	D32(MXVR_CDRPLL_CTL); +# endif +# ifdef MXVR_FMPLL_CTL +	D32(MXVR_FMPLL_CTL); +# endif +# ifdef MXVR_PIN_CTL +	D16(MXVR_PIN_CTL); +# endif +# ifdef MXVR_SCLK_CNT +	D16(MXVR_SCLK_CNT); +# endif +#endif + +#ifdef NFC_ADDR +	parent = debugfs_create_dir("nfc", top); +	D_WO(NFC_ADDR, 16); +	D_WO(NFC_CMD, 16); +	D_RO(NFC_COUNT, 16); +	D16(NFC_CTL); +	D_WO(NFC_DATA_RD, 16); +	D_WO(NFC_DATA_WR, 16); +	D_RO(NFC_ECC0, 16); +	D_RO(NFC_ECC1, 16); +	D_RO(NFC_ECC2, 16); +	D_RO(NFC_ECC3, 16); +	D16(NFC_IRQMASK); +	D16(NFC_IRQSTAT); +	D_WO(NFC_PGCTL, 16); +	D_RO(NFC_READ, 16); +	D16(NFC_RST); +	D_RO(NFC_STAT, 16); +#endif + +#ifdef OTP_CONTROL +	parent = debugfs_create_dir("otp", top); +	D16(OTP_CONTROL); +	D16(OTP_BEN); +	D16(OTP_STATUS); +	D32(OTP_TIMING); +	D32(OTP_DATA0); +	D32(OTP_DATA1); +	D32(OTP_DATA2); +	D32(OTP_DATA3); +#endif + +#ifdef PINT0_MASK_SET +	parent = debugfs_create_dir("pint", top); +	PINT(0); +	PINT(1); +	PINT(2); +	PINT(3); +#endif + +#ifdef PIXC_CTL +	parent = debugfs_create_dir("pixc", top); +	D16(PIXC_CTL); +	D16(PIXC_PPL); +	D16(PIXC_LPF); +	D16(PIXC_AHSTART); +	D16(PIXC_AHEND); +	D16(PIXC_AVSTART); +	D16(PIXC_AVEND); +	D16(PIXC_ATRANSP); +	D16(PIXC_BHSTART); +	D16(PIXC_BHEND); +	D16(PIXC_BVSTART); +	D16(PIXC_BVEND); +	D16(PIXC_BTRANSP); +	D16(PIXC_INTRSTAT); +	D32(PIXC_RYCON); +	D32(PIXC_GUCON); +	D32(PIXC_BVCON); +	D32(PIXC_CCBIAS); +	D32(PIXC_TC); +#endif + +	parent = debugfs_create_dir("pll", top); +	D16(PLL_CTL); +	D16(PLL_DIV); +	D16(PLL_LOCKCNT); +	D16(PLL_STAT); +	D16(VR_CTL); +	D32(CHIPID);	/* it's part of this hardware block */ + +#if defined(PPI_CONTROL) || defined(PPI0_CONTROL) || defined(PPI1_CONTROL) +	parent = debugfs_create_dir("ppi", top); +# ifdef PPI_CONTROL +	bfin_debug_mmrs_ppi(parent, PPI_CONTROL, -1); +# endif +# ifdef PPI0_CONTROL +	PPI(0); +# endif +# ifdef PPI1_CONTROL +	PPI(1); +# endif +#endif + +#ifdef PWM_CTRL +	parent = debugfs_create_dir("pwm", top); +	D16(PWM_CTRL); +	D16(PWM_STAT); +	D16(PWM_TM); +	D16(PWM_DT); +	D16(PWM_GATE); +	D16(PWM_CHA); +	D16(PWM_CHB); +	D16(PWM_CHC); +	D16(PWM_SEG); +	D16(PWM_SYNCWT); +	D16(PWM_CHAL); +	D16(PWM_CHBL); +	D16(PWM_CHCL); +	D16(PWM_LSI); +	D16(PWM_STAT2); +#endif + +#ifdef RSI_CONFIG +	parent = debugfs_create_dir("rsi", top); +	D32(RSI_ARGUMENT); +	D16(RSI_CEATA_CONTROL); +	D16(RSI_CLK_CONTROL); +	D16(RSI_COMMAND); +	D16(RSI_CONFIG); +	D16(RSI_DATA_CNT); +	D16(RSI_DATA_CONTROL); +	D16(RSI_DATA_LGTH); +	D32(RSI_DATA_TIMER); +	D16(RSI_EMASK); +	D16(RSI_ESTAT); +	D32(RSI_FIFO); +	D16(RSI_FIFO_CNT); +	D32(RSI_MASK0); +	D32(RSI_MASK1); +	D16(RSI_PID0); +	D16(RSI_PID1); +	D16(RSI_PID2); +	D16(RSI_PID3); +	D16(RSI_PID4); +	D16(RSI_PID5); +	D16(RSI_PID6); +	D16(RSI_PID7); +	D16(RSI_PWR_CONTROL); +	D16(RSI_RD_WAIT_EN); +	D32(RSI_RESPONSE0); +	D32(RSI_RESPONSE1); +	D32(RSI_RESPONSE2); +	D32(RSI_RESPONSE3); +	D16(RSI_RESP_CMD); +	D32(RSI_STATUS); +	D_WO(RSI_STATUSCL, 16); +#endif + +#ifdef RTC_ALARM +	parent = debugfs_create_dir("rtc", top); +	D32(RTC_ALARM); +	D16(RTC_ICTL); +	D16(RTC_ISTAT); +	D16(RTC_PREN); +	D32(RTC_STAT); +	D16(RTC_SWCNT); +#endif + +#ifdef SDH_CFG +	parent = debugfs_create_dir("sdh", top); +	D32(SDH_ARGUMENT); +	D16(SDH_CFG); +	D16(SDH_CLK_CTL); +	D16(SDH_COMMAND); +	D_RO(SDH_DATA_CNT, 16); +	D16(SDH_DATA_CTL); +	D16(SDH_DATA_LGTH); +	D32(SDH_DATA_TIMER); +	D16(SDH_E_MASK); +	D16(SDH_E_STATUS); +	D32(SDH_FIFO); +	D_RO(SDH_FIFO_CNT, 16); +	D32(SDH_MASK0); +	D32(SDH_MASK1); +	D_RO(SDH_PID0, 16); +	D_RO(SDH_PID1, 16); +	D_RO(SDH_PID2, 16); +	D_RO(SDH_PID3, 16); +	D_RO(SDH_PID4, 16); +	D_RO(SDH_PID5, 16); +	D_RO(SDH_PID6, 16); +	D_RO(SDH_PID7, 16); +	D16(SDH_PWR_CTL); +	D16(SDH_RD_WAIT_EN); +	D_RO(SDH_RESPONSE0, 32); +	D_RO(SDH_RESPONSE1, 32); +	D_RO(SDH_RESPONSE2, 32); +	D_RO(SDH_RESPONSE3, 32); +	D_RO(SDH_RESP_CMD, 16); +	D_RO(SDH_STATUS, 32); +	D_WO(SDH_STATUS_CLR, 16); +#endif + +#ifdef SECURE_CONTROL +	parent = debugfs_create_dir("security", top); +	D16(SECURE_CONTROL); +	D16(SECURE_STATUS); +	D32(SECURE_SYSSWT); +#endif + +	parent = debugfs_create_dir("sic", top); +	D16(SWRST); +	D16(SYSCR); +	D16(SIC_RVECT); +	D32(SIC_IAR0); +	D32(SIC_IAR1); +	D32(SIC_IAR2); +#ifdef SIC_IAR3 +	D32(SIC_IAR3); +#endif +#ifdef SIC_IAR4 +	D32(SIC_IAR4); +	D32(SIC_IAR5); +	D32(SIC_IAR6); +#endif +#ifdef SIC_IAR7 +	D32(SIC_IAR7); +#endif +#ifdef SIC_IAR8 +	D32(SIC_IAR8); +	D32(SIC_IAR9); +	D32(SIC_IAR10); +	D32(SIC_IAR11); +#endif +#ifdef SIC_IMASK +	D32(SIC_IMASK); +	D32(SIC_ISR); +	D32(SIC_IWR); +#endif +#ifdef SIC_IMASK0 +	D32(SIC_IMASK0); +	D32(SIC_IMASK1); +	D32(SIC_ISR0); +	D32(SIC_ISR1); +	D32(SIC_IWR0); +	D32(SIC_IWR1); +#endif +#ifdef SIC_IMASK2 +	D32(SIC_IMASK2); +	D32(SIC_ISR2); +	D32(SIC_IWR2); +#endif +#ifdef SICB_RVECT +	D16(SICB_SWRST); +	D16(SICB_SYSCR); +	D16(SICB_RVECT); +	D32(SICB_IAR0); +	D32(SICB_IAR1); +	D32(SICB_IAR2); +	D32(SICB_IAR3); +	D32(SICB_IAR4); +	D32(SICB_IAR5); +	D32(SICB_IAR6); +	D32(SICB_IAR7); +	D32(SICB_IMASK0); +	D32(SICB_IMASK1); +	D32(SICB_ISR0); +	D32(SICB_ISR1); +	D32(SICB_IWR0); +	D32(SICB_IWR1); +#endif + +	parent = debugfs_create_dir("spi", top); +#ifdef SPI0_REGBASE +	SPI(0); +#endif +#ifdef SPI1_REGBASE +	SPI(1); +#endif +#ifdef SPI2_REGBASE +	SPI(2); +#endif + +	parent = debugfs_create_dir("sport", top); +#ifdef SPORT0_STAT +	SPORT(0); +#endif +#ifdef SPORT1_STAT +	SPORT(1); +#endif +#ifdef SPORT2_STAT +	SPORT(2); +#endif +#ifdef SPORT3_STAT +	SPORT(3); +#endif + +#if defined(TWI_CLKDIV) || defined(TWI0_CLKDIV) || defined(TWI1_CLKDIV) +	parent = debugfs_create_dir("twi", top); +# ifdef TWI_CLKDIV +	bfin_debug_mmrs_twi(parent, TWI_CLKDIV, -1); +# endif +# ifdef TWI0_CLKDIV +	TWI(0); +# endif +# ifdef TWI1_CLKDIV +	TWI(1); +# endif +#endif + +	parent = debugfs_create_dir("uart", top); +#ifdef BFIN_UART_DLL +	bfin_debug_mmrs_uart(parent, BFIN_UART_DLL, -1); +#endif +#ifdef UART0_DLL +	UART(0); +#endif +#ifdef UART1_DLL +	UART(1); +#endif +#ifdef UART2_DLL +	UART(2); +#endif +#ifdef UART3_DLL +	UART(3); +#endif + +#ifdef USB_FADDR +	parent = debugfs_create_dir("usb", top); +	D16(USB_FADDR); +	D16(USB_POWER); +	D16(USB_INTRTX); +	D16(USB_INTRRX); +	D16(USB_INTRTXE); +	D16(USB_INTRRXE); +	D16(USB_INTRUSB); +	D16(USB_INTRUSBE); +	D16(USB_FRAME); +	D16(USB_INDEX); +	D16(USB_TESTMODE); +	D16(USB_GLOBINTR); +	D16(USB_GLOBAL_CTL); +	D16(USB_TX_MAX_PACKET); +	D16(USB_CSR0); +	D16(USB_TXCSR); +	D16(USB_RX_MAX_PACKET); +	D16(USB_RXCSR); +	D16(USB_COUNT0); +	D16(USB_RXCOUNT); +	D16(USB_TXTYPE); +	D16(USB_NAKLIMIT0); +	D16(USB_TXINTERVAL); +	D16(USB_RXTYPE); +	D16(USB_RXINTERVAL); +	D16(USB_TXCOUNT); +	D16(USB_EP0_FIFO); +	D16(USB_EP1_FIFO); +	D16(USB_EP2_FIFO); +	D16(USB_EP3_FIFO); +	D16(USB_EP4_FIFO); +	D16(USB_EP5_FIFO); +	D16(USB_EP6_FIFO); +	D16(USB_EP7_FIFO); +	D16(USB_OTG_DEV_CTL); +	D16(USB_OTG_VBUS_IRQ); +	D16(USB_OTG_VBUS_MASK); +	D16(USB_LINKINFO); +	D16(USB_VPLEN); +	D16(USB_HS_EOF1); +	D16(USB_FS_EOF1); +	D16(USB_LS_EOF1); +	D16(USB_APHY_CNTRL); +	D16(USB_APHY_CALIB); +	D16(USB_APHY_CNTRL2); +	D16(USB_PHY_TEST); +	D16(USB_PLLOSC_CTRL); +	D16(USB_SRP_CLKDIV); +	D16(USB_EP_NI0_TXMAXP); +	D16(USB_EP_NI0_TXCSR); +	D16(USB_EP_NI0_RXMAXP); +	D16(USB_EP_NI0_RXCSR); +	D16(USB_EP_NI0_RXCOUNT); +	D16(USB_EP_NI0_TXTYPE); +	D16(USB_EP_NI0_TXINTERVAL); +	D16(USB_EP_NI0_RXTYPE); +	D16(USB_EP_NI0_RXINTERVAL); +	D16(USB_EP_NI0_TXCOUNT); +	D16(USB_EP_NI1_TXMAXP); +	D16(USB_EP_NI1_TXCSR); +	D16(USB_EP_NI1_RXMAXP); +	D16(USB_EP_NI1_RXCSR); +	D16(USB_EP_NI1_RXCOUNT); +	D16(USB_EP_NI1_TXTYPE); +	D16(USB_EP_NI1_TXINTERVAL); +	D16(USB_EP_NI1_RXTYPE); +	D16(USB_EP_NI1_RXINTERVAL); +	D16(USB_EP_NI1_TXCOUNT); +	D16(USB_EP_NI2_TXMAXP); +	D16(USB_EP_NI2_TXCSR); +	D16(USB_EP_NI2_RXMAXP); +	D16(USB_EP_NI2_RXCSR); +	D16(USB_EP_NI2_RXCOUNT); +	D16(USB_EP_NI2_TXTYPE); +	D16(USB_EP_NI2_TXINTERVAL); +	D16(USB_EP_NI2_RXTYPE); +	D16(USB_EP_NI2_RXINTERVAL); +	D16(USB_EP_NI2_TXCOUNT); +	D16(USB_EP_NI3_TXMAXP); +	D16(USB_EP_NI3_TXCSR); +	D16(USB_EP_NI3_RXMAXP); +	D16(USB_EP_NI3_RXCSR); +	D16(USB_EP_NI3_RXCOUNT); +	D16(USB_EP_NI3_TXTYPE); +	D16(USB_EP_NI3_TXINTERVAL); +	D16(USB_EP_NI3_RXTYPE); +	D16(USB_EP_NI3_RXINTERVAL); +	D16(USB_EP_NI3_TXCOUNT); +	D16(USB_EP_NI4_TXMAXP); +	D16(USB_EP_NI4_TXCSR); +	D16(USB_EP_NI4_RXMAXP); +	D16(USB_EP_NI4_RXCSR); +	D16(USB_EP_NI4_RXCOUNT); +	D16(USB_EP_NI4_TXTYPE); +	D16(USB_EP_NI4_TXINTERVAL); +	D16(USB_EP_NI4_RXTYPE); +	D16(USB_EP_NI4_RXINTERVAL); +	D16(USB_EP_NI4_TXCOUNT); +	D16(USB_EP_NI5_TXMAXP); +	D16(USB_EP_NI5_TXCSR); +	D16(USB_EP_NI5_RXMAXP); +	D16(USB_EP_NI5_RXCSR); +	D16(USB_EP_NI5_RXCOUNT); +	D16(USB_EP_NI5_TXTYPE); +	D16(USB_EP_NI5_TXINTERVAL); +	D16(USB_EP_NI5_RXTYPE); +	D16(USB_EP_NI5_RXINTERVAL); +	D16(USB_EP_NI5_TXCOUNT); +	D16(USB_EP_NI6_TXMAXP); +	D16(USB_EP_NI6_TXCSR); +	D16(USB_EP_NI6_RXMAXP); +	D16(USB_EP_NI6_RXCSR); +	D16(USB_EP_NI6_RXCOUNT); +	D16(USB_EP_NI6_TXTYPE); +	D16(USB_EP_NI6_TXINTERVAL); +	D16(USB_EP_NI6_RXTYPE); +	D16(USB_EP_NI6_RXINTERVAL); +	D16(USB_EP_NI6_TXCOUNT); +	D16(USB_EP_NI7_TXMAXP); +	D16(USB_EP_NI7_TXCSR); +	D16(USB_EP_NI7_RXMAXP); +	D16(USB_EP_NI7_RXCSR); +	D16(USB_EP_NI7_RXCOUNT); +	D16(USB_EP_NI7_TXTYPE); +	D16(USB_EP_NI7_TXINTERVAL); +	D16(USB_EP_NI7_RXTYPE); +	D16(USB_EP_NI7_RXINTERVAL); +	D16(USB_EP_NI7_TXCOUNT); +	D16(USB_DMA_INTERRUPT); +	D16(USB_DMA0CONTROL); +	D16(USB_DMA0ADDRLOW); +	D16(USB_DMA0ADDRHIGH); +	D16(USB_DMA0COUNTLOW); +	D16(USB_DMA0COUNTHIGH); +	D16(USB_DMA1CONTROL); +	D16(USB_DMA1ADDRLOW); +	D16(USB_DMA1ADDRHIGH); +	D16(USB_DMA1COUNTLOW); +	D16(USB_DMA1COUNTHIGH); +	D16(USB_DMA2CONTROL); +	D16(USB_DMA2ADDRLOW); +	D16(USB_DMA2ADDRHIGH); +	D16(USB_DMA2COUNTLOW); +	D16(USB_DMA2COUNTHIGH); +	D16(USB_DMA3CONTROL); +	D16(USB_DMA3ADDRLOW); +	D16(USB_DMA3ADDRHIGH); +	D16(USB_DMA3COUNTLOW); +	D16(USB_DMA3COUNTHIGH); +	D16(USB_DMA4CONTROL); +	D16(USB_DMA4ADDRLOW); +	D16(USB_DMA4ADDRHIGH); +	D16(USB_DMA4COUNTLOW); +	D16(USB_DMA4COUNTHIGH); +	D16(USB_DMA5CONTROL); +	D16(USB_DMA5ADDRLOW); +	D16(USB_DMA5ADDRHIGH); +	D16(USB_DMA5COUNTLOW); +	D16(USB_DMA5COUNTHIGH); +	D16(USB_DMA6CONTROL); +	D16(USB_DMA6ADDRLOW); +	D16(USB_DMA6ADDRHIGH); +	D16(USB_DMA6COUNTLOW); +	D16(USB_DMA6COUNTHIGH); +	D16(USB_DMA7CONTROL); +	D16(USB_DMA7ADDRLOW); +	D16(USB_DMA7ADDRHIGH); +	D16(USB_DMA7COUNTLOW); +	D16(USB_DMA7COUNTHIGH); +#endif + +#ifdef WDOG_CNT +	parent = debugfs_create_dir("watchdog", top); +	D32(WDOG_CNT); +	D16(WDOG_CTL); +	D32(WDOG_STAT); +#endif +#ifdef WDOGA_CNT +	parent = debugfs_create_dir("watchdog", top); +	D32(WDOGA_CNT); +	D16(WDOGA_CTL); +	D32(WDOGA_STAT); +	D32(WDOGB_CNT); +	D16(WDOGB_CTL); +	D32(WDOGB_STAT); +#endif + +	/* BF533 glue */ +#ifdef FIO_FLAG_D +#define PORTFIO FIO_FLAG_D +#endif +	/* BF561 glue */ +#ifdef FIO0_FLAG_D +#define PORTFIO FIO0_FLAG_D +#endif +#ifdef FIO1_FLAG_D +#define PORTGIO FIO1_FLAG_D +#endif +#ifdef FIO2_FLAG_D +#define PORTHIO FIO2_FLAG_D +#endif +	parent = debugfs_create_dir("port", top); +#ifdef PORTFIO +	PORT(PORTFIO, 'F'); +#endif +#ifdef PORTGIO +	PORT(PORTGIO, 'G'); +#endif +#ifdef PORTHIO +	PORT(PORTHIO, 'H'); +#endif + +#ifdef __ADSPBF51x__ +	D16(PORTF_FER); +	D16(PORTF_DRIVE); +	D16(PORTF_HYSTERESIS); +	D16(PORTF_MUX); + +	D16(PORTG_FER); +	D16(PORTG_DRIVE); +	D16(PORTG_HYSTERESIS); +	D16(PORTG_MUX); + +	D16(PORTH_FER); +	D16(PORTH_DRIVE); +	D16(PORTH_HYSTERESIS); +	D16(PORTH_MUX); + +	D16(MISCPORT_DRIVE); +	D16(MISCPORT_HYSTERESIS); +#endif	/* BF51x */ + +#ifdef __ADSPBF52x__ +	D16(PORTF_FER); +	D16(PORTF_DRIVE); +	D16(PORTF_HYSTERESIS); +	D16(PORTF_MUX); +	D16(PORTF_SLEW); + +	D16(PORTG_FER); +	D16(PORTG_DRIVE); +	D16(PORTG_HYSTERESIS); +	D16(PORTG_MUX); +	D16(PORTG_SLEW); + +	D16(PORTH_FER); +	D16(PORTH_DRIVE); +	D16(PORTH_HYSTERESIS); +	D16(PORTH_MUX); +	D16(PORTH_SLEW); + +	D16(MISCPORT_DRIVE); +	D16(MISCPORT_HYSTERESIS); +	D16(MISCPORT_SLEW); +#endif	/* BF52x */ + +#ifdef BF537_FAMILY +	D16(PORTF_FER); +	D16(PORTG_FER); +	D16(PORTH_FER); +	D16(PORT_MUX); +#endif	/* BF534 BF536 BF537 */ + +#ifdef BF538_FAMILY +	D16(PORTCIO_FER); +	D16(PORTCIO); +	D16(PORTCIO_CLEAR); +	D16(PORTCIO_SET); +	D16(PORTCIO_TOGGLE); +	D16(PORTCIO_DIR); +	D16(PORTCIO_INEN); + +	D16(PORTDIO); +	D16(PORTDIO_CLEAR); +	D16(PORTDIO_DIR); +	D16(PORTDIO_FER); +	D16(PORTDIO_INEN); +	D16(PORTDIO_SET); +	D16(PORTDIO_TOGGLE); + +	D16(PORTEIO); +	D16(PORTEIO_CLEAR); +	D16(PORTEIO_DIR); +	D16(PORTEIO_FER); +	D16(PORTEIO_INEN); +	D16(PORTEIO_SET); +	D16(PORTEIO_TOGGLE); +#endif	/* BF538 BF539 */ + +#ifdef __ADSPBF54x__ +	{ +		int num; +		unsigned long base; + +		base = PORTA_FER; +		for (num = 0; num < 10; ++num) { +			PORT(base, num); +			base += sizeof(struct bfin_gpio_regs); +		} + +	} +#endif	/* BF54x */ +#endif /* CONFIG_BF60x */ +	debug_mmrs_dentry = top; + +	return 0; +} +module_init(bfin_debug_mmrs_init); + +static void __exit bfin_debug_mmrs_exit(void) +{ +	debugfs_remove_recursive(debug_mmrs_dentry); +} +module_exit(bfin_debug_mmrs_exit); + +MODULE_LICENSE("GPL"); diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c index 04ddcfeb798..df437e52d9d 100644 --- a/arch/blackfin/kernel/dma-mapping.c +++ b/arch/blackfin/kernel/dma-mapping.c @@ -12,6 +12,8 @@  #include <linux/spinlock.h>  #include <linux/dma-mapping.h>  #include <linux/scatterlist.h> +#include <linux/export.h> +#include <linux/bitmap.h>  static spinlock_t dma_page_lock;  static unsigned long *dma_page; @@ -45,24 +47,17 @@ static inline unsigned int get_pages(size_t size)  static unsigned long __alloc_dma_pages(unsigned int pages)  {  	unsigned long ret = 0, flags; -	int i, count = 0; +	unsigned long start;  	if (dma_initialized == 0)  		dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend);  	spin_lock_irqsave(&dma_page_lock, flags); -	for (i = 0; i < dma_pages;) { -		if (test_bit(i++, dma_page) == 0) { -			if (++count == pages) { -				while (count--) -					__set_bit(--i, dma_page); - -				ret = dma_base + (i << PAGE_SHIFT); -				break; -			} -		} else -			count = 0; +	start = bitmap_find_next_zero_area(dma_page, dma_pages, 0, pages, 0); +	if (start < dma_pages) { +		ret = dma_base + (start << PAGE_SHIFT); +		bitmap_set(dma_page, start, pages);  	}  	spin_unlock_irqrestore(&dma_page_lock, flags);  	return ret; @@ -72,7 +67,6 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages)  {  	unsigned long page = (addr - dma_base) >> PAGE_SHIFT;  	unsigned long flags; -	int i;  	if ((page + pages) > dma_pages) {  		printk(KERN_ERR "%s: freeing outside range.\n", __func__); @@ -80,9 +74,7 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages)  	}  	spin_lock_irqsave(&dma_page_lock, flags); -	for (i = page; i < page + pages; i++) -		__clear_bit(i, dma_page); - +	bitmap_clear(dma_page, page, pages);  	spin_unlock_irqrestore(&dma_page_lock, flags);  } @@ -121,12 +113,13 @@ void __dma_sync(dma_addr_t addr, size_t size,  EXPORT_SYMBOL(__dma_sync);  int -dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, +dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents,  	   enum dma_data_direction direction)  { +	struct scatterlist *sg;  	int i; -	for (i = 0; i < nents; i++, sg++) { +	for_each_sg(sg_list, sg, nents, i) {  		sg->dma_address = (dma_addr_t) sg_virt(sg);  		__dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);  	} @@ -135,12 +128,13 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,  }  EXPORT_SYMBOL(dma_map_sg); -void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg_list,  			    int nelems, enum dma_data_direction direction)  { +	struct scatterlist *sg;  	int i; -	for (i = 0; i < nelems; i++, sg++) { +	for_each_sg(sg_list, sg, nelems, i) {  		sg->dma_address = (dma_addr_t) sg_virt(sg);  		__dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);  	} diff --git a/arch/blackfin/kernel/dumpstack.c b/arch/blackfin/kernel/dumpstack.c index 5cfbaa29821..95ba6d9e9a3 100644 --- a/arch/blackfin/kernel/dumpstack.c +++ b/arch/blackfin/kernel/dumpstack.c @@ -168,6 +168,7 @@ void dump_stack(void)  #endif  	trace_buffer_save(tflags);  	dump_bfin_trace_buffer(); +	dump_stack_print_info(KERN_DEFAULT);  	show_stack(current, &stack);  	trace_buffer_restore(tflags);  } diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 84ed8375113..61fbd2de993 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c @@ -25,8 +25,6 @@ extern struct console *bfin_earlyserial_init(unsigned int port,  extern struct console *bfin_jc_early_init(void);  #endif -static struct console *early_console; -  /* Default console */  #define DEFAULT_PORT 0  #define DEFAULT_CFLAG CS8|B57600 diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index 686478f5f66..4071265fc4f 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S @@ -46,63 +46,14 @@ ENTRY(_ret_from_fork)  	SP += -12;  	pseudo_long_call _schedule_tail, p5;  	SP += 12; -	r0 = [sp + PT_IPEND]; -	cc = bittst(r0,1); -	if cc jump .Lin_kernel; +	p1 = [sp++]; +	r0 = [sp++]; +	cc = p1 == 0; +	if cc jump .Lfork; +	sp += -12; +	call (p1); +	sp += 12; +.Lfork:  	RESTORE_CONTEXT  	rti; -.Lin_kernel: -	bitclr(r0,1); -	[sp + PT_IPEND] = r0; -	/* do a 'fake' RTI by jumping to [RETI] -	 * to avoid clearing supervisor mode in child -	 */ -	r0 = [sp + PT_PC]; -	[sp + PT_P0] = r0; - -	RESTORE_ALL_SYS -	jump (p0);  ENDPROC(_ret_from_fork) - -ENTRY(_sys_fork) -	r0 = -EINVAL; -#if (ANOMALY_05000371) -	nop; -	nop; -	nop; -#endif -	rts; -ENDPROC(_sys_fork) - -ENTRY(_sys_vfork) -	r0 = sp; -	r0 += 24; -	[--sp] = rets; -	SP += -12; -	pseudo_long_call _bfin_vfork, p2; -	SP += 12; -	rets = [sp++]; -	rts; -ENDPROC(_sys_vfork) - -ENTRY(_sys_clone) -	r0 = sp; -	r0 += 24; -	[--sp] = rets; -	SP += -12; -	pseudo_long_call _bfin_clone, p2; -	SP += 12; -	rets = [sp++]; -	rts; -ENDPROC(_sys_clone) - -ENTRY(_sys_rt_sigreturn) -	r0 = sp; -	r0 += 24; -	[--sp] = rets; -	SP += -12; -	pseudo_long_call _do_rt_sigreturn, p2; -	SP += 12; -	rets = [sp++]; -	rts; -ENDPROC(_sys_rt_sigreturn) diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c index 48808a12b42..095de0fa044 100644 --- a/arch/blackfin/kernel/ftrace.c +++ b/arch/blackfin/kernel/ftrace.c @@ -9,7 +9,7 @@  #include <linux/kernel.h>  #include <linux/sched.h>  #include <linux/uaccess.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/cacheflush.h>  #ifdef CONFIG_DYNAMIC_FTRACE @@ -65,11 +65,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)  	return ftrace_modify_code(ip, call, sizeof(call));  } -int __init ftrace_dyn_arch_init(void *data) +int __init ftrace_dyn_arch_init(void)  { -	/* return value is done indirectly via data */ -	*(unsigned long *)data = 0; -  	return 0;  } diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index cdbe075de1d..d776773d386 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c @@ -23,51 +23,39 @@  		printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__);  #endif -#define BFIN_TIMER_NUM_GROUP  (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) - -typedef struct { -	uint16_t config; -	uint16_t __pad; -	uint32_t counter; -	uint32_t period; -	uint32_t width; -} GPTIMER_timer_regs; - -typedef struct { -	uint16_t enable; -	uint16_t __pad0; -	uint16_t disable; -	uint16_t __pad1; -	uint32_t status; -} GPTIMER_group_regs; - -static volatile GPTIMER_timer_regs *const timer_regs[MAX_BLACKFIN_GPTIMERS] = -{ -	(GPTIMER_timer_regs *)TIMER0_CONFIG, -	(GPTIMER_timer_regs *)TIMER1_CONFIG, -	(GPTIMER_timer_regs *)TIMER2_CONFIG, +#ifndef CONFIG_BF60x +# define BFIN_TIMER_NUM_GROUP  (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) +#else +# define BFIN_TIMER_NUM_GROUP  1 +#endif + +static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = +{ +	(void *)TIMER0_CONFIG, +	(void *)TIMER1_CONFIG, +	(void *)TIMER2_CONFIG,  #if (MAX_BLACKFIN_GPTIMERS > 3) -	(GPTIMER_timer_regs *)TIMER3_CONFIG, -	(GPTIMER_timer_regs *)TIMER4_CONFIG, -	(GPTIMER_timer_regs *)TIMER5_CONFIG, -	(GPTIMER_timer_regs *)TIMER6_CONFIG, -	(GPTIMER_timer_regs *)TIMER7_CONFIG, +	(void *)TIMER3_CONFIG, +	(void *)TIMER4_CONFIG, +	(void *)TIMER5_CONFIG, +	(void *)TIMER6_CONFIG, +	(void *)TIMER7_CONFIG,  # if (MAX_BLACKFIN_GPTIMERS > 8) -	(GPTIMER_timer_regs *)TIMER8_CONFIG, -	(GPTIMER_timer_regs *)TIMER9_CONFIG, -	(GPTIMER_timer_regs *)TIMER10_CONFIG, +	(void *)TIMER8_CONFIG, +	(void *)TIMER9_CONFIG, +	(void *)TIMER10_CONFIG,  #  if (MAX_BLACKFIN_GPTIMERS > 11) -	(GPTIMER_timer_regs *)TIMER11_CONFIG, +	(void *)TIMER11_CONFIG,  #  endif  # endif  #endif  }; -static volatile GPTIMER_group_regs *const group_regs[BFIN_TIMER_NUM_GROUP] = +static struct bfin_gptimer_group_regs * const group_regs[BFIN_TIMER_NUM_GROUP] =  { -	(GPTIMER_group_regs *)TIMER0_GROUP_REG, +	(void *)TIMER0_GROUP_REG,  #if (MAX_BLACKFIN_GPTIMERS > 8) -	(GPTIMER_group_regs *)TIMER8_GROUP_REG, +	(void *)TIMER8_GROUP_REG,  #endif  }; @@ -140,7 +128,7 @@ static uint32_t const timil_mask[MAX_BLACKFIN_GPTIMERS] =  void set_gptimer_pwidth(unsigned int timer_id, uint32_t value)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	timer_regs[timer_id]->width = value; +	bfin_write(&timer_regs[timer_id]->width, value);  	SSYNC();  }  EXPORT_SYMBOL(set_gptimer_pwidth); @@ -148,14 +136,14 @@ EXPORT_SYMBOL(set_gptimer_pwidth);  uint32_t get_gptimer_pwidth(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return timer_regs[timer_id]->width; +	return bfin_read(&timer_regs[timer_id]->width);  }  EXPORT_SYMBOL(get_gptimer_pwidth);  void set_gptimer_period(unsigned int timer_id, uint32_t period)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	timer_regs[timer_id]->period = period; +	bfin_write(&timer_regs[timer_id]->period, period);  	SSYNC();  }  EXPORT_SYMBOL(set_gptimer_period); @@ -163,71 +151,145 @@ EXPORT_SYMBOL(set_gptimer_period);  uint32_t get_gptimer_period(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return timer_regs[timer_id]->period; +	return bfin_read(&timer_regs[timer_id]->period);  }  EXPORT_SYMBOL(get_gptimer_period);  uint32_t get_gptimer_count(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return timer_regs[timer_id]->counter; +	return bfin_read(&timer_regs[timer_id]->counter);  }  EXPORT_SYMBOL(get_gptimer_count); +#ifdef CONFIG_BF60x +void set_gptimer_delay(unsigned int timer_id, uint32_t delay) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	bfin_write(&timer_regs[timer_id]->delay, delay); +	SSYNC(); +} +EXPORT_SYMBOL(set_gptimer_delay); + +uint32_t get_gptimer_delay(unsigned int timer_id) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	return bfin_read(&timer_regs[timer_id]->delay); +} +EXPORT_SYMBOL(get_gptimer_delay); +#endif + +#ifdef CONFIG_BF60x +int get_gptimer_intr(unsigned int timer_id) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat) & timil_mask[timer_id]); +} +EXPORT_SYMBOL(get_gptimer_intr); + +void clear_gptimer_intr(unsigned int timer_id) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat, timil_mask[timer_id]); +} +EXPORT_SYMBOL(clear_gptimer_intr); + +int get_gptimer_over(unsigned int timer_id) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat) & tovf_mask[timer_id]); +} +EXPORT_SYMBOL(get_gptimer_over); + +void clear_gptimer_over(unsigned int timer_id) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat, tovf_mask[timer_id]); +} +EXPORT_SYMBOL(clear_gptimer_over); + +int get_gptimer_run(unsigned int timer_id) +{ +	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); +	return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->run) & trun_mask[timer_id]); +} +EXPORT_SYMBOL(get_gptimer_run); + +uint32_t get_gptimer_status(unsigned int group) +{ +	tassert(group < BFIN_TIMER_NUM_GROUP); +	return bfin_read(&group_regs[group]->data_ilat); +} +EXPORT_SYMBOL(get_gptimer_status); + +void set_gptimer_status(unsigned int group, uint32_t value) +{ +	tassert(group < BFIN_TIMER_NUM_GROUP); +	bfin_write(&group_regs[group]->data_ilat, value); +	SSYNC(); +} +EXPORT_SYMBOL(set_gptimer_status); +#else  uint32_t get_gptimer_status(unsigned int group)  {  	tassert(group < BFIN_TIMER_NUM_GROUP); -	return group_regs[group]->status; +	return bfin_read(&group_regs[group]->status);  }  EXPORT_SYMBOL(get_gptimer_status);  void set_gptimer_status(unsigned int group, uint32_t value)  {  	tassert(group < BFIN_TIMER_NUM_GROUP); -	group_regs[group]->status = value; +	bfin_write(&group_regs[group]->status, value);  	SSYNC();  }  EXPORT_SYMBOL(set_gptimer_status); +static uint32_t read_gptimer_status(unsigned int timer_id) +{ +	return bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->status); +} +  int get_gptimer_intr(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]); +	return !!(read_gptimer_status(timer_id) & timil_mask[timer_id]);  }  EXPORT_SYMBOL(get_gptimer_intr);  void clear_gptimer_intr(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	group_regs[BFIN_TIMER_OCTET(timer_id)]->status = timil_mask[timer_id]; +	bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->status, timil_mask[timer_id]);  }  EXPORT_SYMBOL(clear_gptimer_intr);  int get_gptimer_over(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]); +	return !!(read_gptimer_status(timer_id) & tovf_mask[timer_id]);  }  EXPORT_SYMBOL(get_gptimer_over);  void clear_gptimer_over(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	group_regs[BFIN_TIMER_OCTET(timer_id)]->status = tovf_mask[timer_id]; +	bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->status, tovf_mask[timer_id]);  }  EXPORT_SYMBOL(clear_gptimer_over);  int get_gptimer_run(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & trun_mask[timer_id]); +	return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]);  }  EXPORT_SYMBOL(get_gptimer_run); +#endif  void set_gptimer_config(unsigned int timer_id, uint16_t config)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	timer_regs[timer_id]->config = config; +	bfin_write(&timer_regs[timer_id]->config, config);  	SSYNC();  }  EXPORT_SYMBOL(set_gptimer_config); @@ -235,16 +297,22 @@ EXPORT_SYMBOL(set_gptimer_config);  uint16_t get_gptimer_config(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	return timer_regs[timer_id]->config; +	return bfin_read(&timer_regs[timer_id]->config);  }  EXPORT_SYMBOL(get_gptimer_config);  void enable_gptimers(uint16_t mask)  {  	int i; +#ifdef CONFIG_BF60x +	uint16_t imask; +	imask = bfin_read16(TIMER_DATA_IMSK); +	imask &= ~mask; +	bfin_write16(TIMER_DATA_IMSK, imask); +#endif  	tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);  	for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { -		group_regs[i]->enable = mask & 0xFF; +		bfin_write(&group_regs[i]->enable, mask & 0xFF);  		mask >>= 8;  	}  	SSYNC(); @@ -257,19 +325,23 @@ static void _disable_gptimers(uint16_t mask)  	uint16_t m = mask;  	tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);  	for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { -		group_regs[i]->disable = m & 0xFF; +		bfin_write(&group_regs[i]->disable, m & 0xFF);  		m >>= 8;  	}  }  void disable_gptimers(uint16_t mask)  { +#ifndef CONFIG_BF60x  	int i;  	_disable_gptimers(mask);  	for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)  		if (mask & (1 << i)) -			group_regs[BFIN_TIMER_OCTET(i)]->status |= trun_mask[i]; +			bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]);  	SSYNC(); +#else +	_disable_gptimers(mask); +#endif  }  EXPORT_SYMBOL(disable_gptimers); @@ -283,7 +355,7 @@ EXPORT_SYMBOL(disable_gptimers_sync);  void set_gptimer_pulse_hi(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	timer_regs[timer_id]->config |= TIMER_PULSE_HI; +	bfin_write_or(&timer_regs[timer_id]->config, TIMER_PULSE_HI);  	SSYNC();  }  EXPORT_SYMBOL(set_gptimer_pulse_hi); @@ -291,7 +363,7 @@ EXPORT_SYMBOL(set_gptimer_pulse_hi);  void clear_gptimer_pulse_hi(unsigned int timer_id)  {  	tassert(timer_id < MAX_BLACKFIN_GPTIMERS); -	timer_regs[timer_id]->config &= ~TIMER_PULSE_HI; +	bfin_write_and(&timer_regs[timer_id]->config, ~TIMER_PULSE_HI);  	SSYNC();  }  EXPORT_SYMBOL(clear_gptimer_pulse_hi); @@ -301,7 +373,7 @@ uint16_t get_enabled_gptimers(void)  	int i;  	uint16_t result = 0;  	for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) -		result |= (group_regs[i]->enable << (i << 3)); +		result |= (bfin_read(&group_regs[i]->enable) << (i << 3));  	return result;  }  EXPORT_SYMBOL(get_enabled_gptimers); diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c deleted file mode 100644 index d3970e8acd1..00000000000 --- a/arch/blackfin/kernel/init_task.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2004-2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later - */ - -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/init_task.h> -#include <linux/mqueue.h> -#include <linux/fs.h> - -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ -struct task_struct init_task = INIT_TASK(init_task); -EXPORT_SYMBOL(init_task); - -/* - * Initial thread structure. - * - * We need to make sure that this is 8192-byte aligned due to the - * way process stacks are handled. This is done by having a special - * "init_task" linker map entry. - */ -union thread_union init_thread_union -    __init_task_data = { -INIT_THREAD_INFO(init_task)}; diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index 3b1da4aff2a..f657b38163e 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -31,8 +31,8 @@  #include <linux/kthread.h>  #include <linux/unistd.h>  #include <linux/io.h> -#include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> +#include <asm/irq_handler.h>  DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); @@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)  	 * pending for it.  	 */  	if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) && -	    ipipe_head_cpudom_var(irqpend_himask) == 0) +	    !__ipipe_ipending_p(ipipe_head_cpudom_ptr()))  		goto out;  	__ipipe_walk_pipeline(head); @@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)  }  EXPORT_SYMBOL(__ipipe_disable_irqdesc); -int __ipipe_syscall_root(struct pt_regs *regs) +asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)  {  	struct ipipe_percpu_domain_data *p; -	unsigned long flags; +	void (*hook)(void);  	int ret; +	WARN_ON_ONCE(irqs_disabled_hw()); +  	/* -	 * We need to run the IRQ tail hook whenever we don't -	 * propagate a syscall to higher domains, because we know that -	 * important operations might be pending there (e.g. Xenomai -	 * deferred rescheduling). +	 * We need to run the IRQ tail hook each time we intercept a +	 * syscall, because we know that important operations might be +	 * pending there (e.g. Xenomai deferred rescheduling).  	 */ - -	if (regs->orig_p0 < NR_syscalls) { -		void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; -		hook(); -		if ((current->flags & PF_EVNOTIFY) == 0) -			return 0; -	} +	hook = (__typeof__(hook))__ipipe_irq_tail_hook; +	hook();  	/*  	 * This routine either returns: @@ -214,51 +210,47 @@ int __ipipe_syscall_root(struct pt_regs *regs)  	 * tail work has to be performed (for handling signals etc).  	 */ -	if (!__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) +	if (!__ipipe_syscall_watched_p(current, regs->orig_p0) || +	    !__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))  		return 0;  	ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs); -	flags = hard_local_irq_save(); +	hard_local_irq_disable(); -	if (!__ipipe_root_domain_p) { -		hard_local_irq_restore(flags); -		return 1; +	/* +	 * This is the end of the syscall path, so we may +	 * safely assume a valid Linux task stack here. +	 */ +	if (current->ipipe_flags & PF_EVTRET) { +		current->ipipe_flags &= ~PF_EVTRET; +		__ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs);  	} -	p = ipipe_root_cpudom_ptr(); -	if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0) -		__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT); +	if (!__ipipe_root_domain_p) +		ret = -1; +	else { +		p = ipipe_root_cpudom_ptr(); +		if (__ipipe_ipending_p(p)) +			__ipipe_sync_pipeline(); +	} -	hard_local_irq_restore(flags); +	hard_local_irq_enable();  	return -ret;  } -unsigned long ipipe_critical_enter(void (*syncfn) (void)) -{ -	unsigned long flags; - -	flags = hard_local_irq_save(); - -	return flags; -} - -void ipipe_critical_exit(unsigned long flags) -{ -	hard_local_irq_restore(flags); -} -  static void __ipipe_no_irqtail(void)  {  }  int ipipe_get_sysinfo(struct ipipe_sysinfo *info)  { -	info->ncpus = num_online_cpus(); -	info->cpufreq = ipipe_cpu_freq(); -	info->archdep.tmirq = IPIPE_TIMER_IRQ; -	info->archdep.tmfreq = info->cpufreq; +	info->sys_nr_cpus = num_online_cpus(); +	info->sys_cpu_freq = ipipe_cpu_freq(); +	info->sys_hrtimer_irq = IPIPE_TIMER_IRQ; +	info->sys_hrtimer_freq = __ipipe_core_clock; +	info->sys_hrclock_freq = __ipipe_core_clock;  	return 0;  } @@ -289,6 +281,7 @@ int ipipe_trigger_irq(unsigned irq)  asmlinkage void __ipipe_sync_root(void)  {  	void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; +	struct ipipe_percpu_domain_data *p;  	unsigned long flags;  	BUG_ON(irqs_disabled()); @@ -300,19 +293,20 @@ asmlinkage void __ipipe_sync_root(void)  	clear_thread_flag(TIF_IRQ_SYNC); -	if (ipipe_root_cpudom_var(irqpend_himask) != 0) -		__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY); +	p = ipipe_root_cpudom_ptr(); +	if (__ipipe_ipending_p(p)) +		__ipipe_sync_pipeline();  	hard_local_irq_restore(flags);  } -void ___ipipe_sync_pipeline(unsigned long syncmask) +void ___ipipe_sync_pipeline(void)  {  	if (__ipipe_root_domain_p &&  	    test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))  		return; -	__ipipe_sync_stage(syncmask); +	__ipipe_sync_stage();  }  void __ipipe_disable_root_irqs_hw(void) diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index 64cff54a8a5..0ba25764b8c 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c @@ -11,6 +11,8 @@  #include <linux/kallsyms.h>  #include <linux/interrupt.h>  #include <linux/irq.h> +#include <linux/seq_file.h> +#include <asm/irq_handler.h>  #include <asm/trace.h>  #include <asm/pda.h> @@ -32,35 +34,15 @@ static struct irq_desc bad_irq_desc = {  #endif  #ifdef CONFIG_PROC_FS -int show_interrupts(struct seq_file *p, void *v) +int arch_show_interrupts(struct seq_file *p, int prec)  { -	int i = *(loff_t *) v, j; -	struct irqaction *action; -	unsigned long flags; - -	if (i < NR_IRQS) { -		raw_spin_lock_irqsave(&irq_desc[i].lock, flags); -		action = irq_desc[i].action; -		if (!action) -			goto skip; -		seq_printf(p, "%3d: ", i); -		for_each_online_cpu(j) -			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); -		seq_printf(p, " %8s", irq_desc[i].chip->name); -		seq_printf(p, "  %s", action->name); -		for (action = action->next; action; action = action->next) -			seq_printf(p, "  %s", action->name); - -		seq_putc(p, '\n'); - skip: -		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); -	} else if (i == NR_IRQS) { -		seq_printf(p, "NMI: "); -		for_each_online_cpu(j) -			seq_printf(p, "%10u ", cpu_pda[j].__nmi_count); -		seq_printf(p, "     CORE  Non Maskable Interrupt\n"); -		seq_printf(p, "Err: %10u\n",  atomic_read(&irq_err_count)); -	} +	int j; + +	seq_printf(p, "%*s: ", prec, "NMI"); +	for_each_online_cpu(j) +		seq_printf(p, "%10u ", cpu_pda[j].__nmi_count); +	seq_printf(p, "  CORE  Non Maskable Interrupt\n"); +	seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));  	return 0;  }  #endif diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index edae461b1c5..fa53faeeb0e 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -9,6 +9,7 @@  #include <linux/ptrace.h>		/* for linux pt_regs struct */  #include <linux/kgdb.h>  #include <linux/uaccess.h> +#include <asm/irq_regs.h>  void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)  { @@ -181,7 +182,7 @@ static int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)  		return -ENOSPC;  	} -	/* Becasue hardware data watchpoint impelemented in current +	/* Because hardware data watchpoint impelemented in current  	 * Blackfin can not trigger an exception event as the hardware  	 * instrction watchpoint does, we ignaore all data watch point here.  	 * They can be turned on easily after future blackfin design @@ -329,6 +330,9 @@ static void bfin_disable_hw_debug(struct pt_regs *regs)  }  #ifdef CONFIG_SMP +extern void generic_exec_single(int cpu, struct call_single_data *data, int wait); +static struct call_single_data kgdb_smp_ipi_data[NR_CPUS]; +  void kgdb_passive_cpu_callback(void *info)  {  	kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); @@ -336,15 +340,38 @@ void kgdb_passive_cpu_callback(void *info)  void kgdb_roundup_cpus(unsigned long flags)  { -	smp_call_function(kgdb_passive_cpu_callback, NULL, 0); +	unsigned int cpu; + +	for (cpu = cpumask_first(cpu_online_mask); cpu < nr_cpu_ids; +		cpu = cpumask_next(cpu, cpu_online_mask)) { +		kgdb_smp_ipi_data[cpu].func = kgdb_passive_cpu_callback; +		generic_exec_single(cpu, &kgdb_smp_ipi_data[cpu], 0); +	}  }  void kgdb_roundup_cpu(int cpu, unsigned long flags)  { -	smp_call_function_single(cpu, kgdb_passive_cpu_callback, NULL, 0); +	generic_exec_single(cpu, &kgdb_smp_ipi_data[cpu], 0);  }  #endif +#ifdef CONFIG_IPIPE +static unsigned long kgdb_arch_imask; +#endif + +void kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code) +{ +	if (kgdb_single_step) +		preempt_enable(); + +#ifdef CONFIG_IPIPE +	if (kgdb_arch_imask) { +		cpu_pda[raw_smp_processor_id()].ex_imask = kgdb_arch_imask; +		kgdb_arch_imask = 0; +	} +#endif +} +  int kgdb_arch_handle_exception(int vector, int signo,  			       int err_code, char *remcom_in_buffer,  			       char *remcom_out_buffer, @@ -388,6 +415,12 @@ int kgdb_arch_handle_exception(int vector, int signo,  			 * kgdb_single_step > 0 means in single step mode  			 */  			kgdb_single_step = i + 1; + +			preempt_disable(); +#ifdef CONFIG_IPIPE +			kgdb_arch_imask = cpu_pda[raw_smp_processor_id()].ex_imask; +			cpu_pda[raw_smp_processor_id()].ex_imask = 0; +#endif  		}  		bfin_correct_hw_break(); @@ -399,11 +432,7 @@ int kgdb_arch_handle_exception(int vector, int signo,  struct kgdb_arch arch_kgdb_ops = {  	.gdb_bpt_instr = {0xa1}, -#ifdef CONFIG_SMP -	.flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP, -#else  	.flags = KGDB_HW_BREAKPOINT, -#endif  	.set_hw_breakpoint = bfin_set_hw_break,  	.remove_hw_breakpoint = bfin_remove_hw_break,  	.disable_hw_break = bfin_disable_hw_debug, @@ -448,6 +477,9 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)  int kgdb_arch_init(void)  {  	kgdb_single_step = 0; +#ifdef CONFIG_IPIPE +	kgdb_arch_imask = 0; +#endif  	bfin_remove_all_hw_break();  	return 0; diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c index 08c0236acf3..18ab004aea1 100644 --- a/arch/blackfin/kernel/kgdb_test.c +++ b/arch/blackfin/kernel/kgdb_test.c @@ -13,7 +13,6 @@  #include <asm/current.h>  #include <asm/uaccess.h> -#include <asm/system.h>  #include <asm/blackfin.h> @@ -50,8 +49,7 @@ void kgdb_l2_test(void)  #endif - -int kgdb_test(char *name, int len, int count, int z) +noinline int kgdb_test(char *name, int len, int count, int z)  {  	pr_alert("kgdb name(%d): %s, %d, %d\n", len, name, count, z);  	count = z; @@ -95,6 +93,10 @@ static int __init kgdbtest_init(void)  {  	struct proc_dir_entry *entry; +#if L2_LENGTH +	num2 = 0; +#endif +  	entry = proc_create("kgdbtest", 0, NULL, &kgdb_test_proc_fops);  	if (entry == NULL)  		return -ENOMEM; diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index a6dfa6b71e6..4489efc5288 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -4,7 +4,7 @@   * Licensed under the GPL-2 or later   */ -#define pr_fmt(fmt) "module %s: " fmt +#define pr_fmt(fmt) "module %s: " fmt, mod->name  #include <linux/moduleloader.h>  #include <linux/elf.h> @@ -16,19 +16,6 @@  #include <asm/cacheflush.h>  #include <asm/uaccess.h> -void *module_alloc(unsigned long size) -{ -	if (size == 0) -		return NULL; -	return vmalloc(size); -} - -/* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) -{ -	vfree(module_region); -} -  /* Transfer the section to the L1 memory */  int  module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -57,8 +44,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l1_inst_sram_alloc(s->sh_size);  			mod->arch.text_l1 = dest;  			if (dest == NULL) { -				pr_err("L1 inst memory allocation failed\n", -					mod->name); +				pr_err("L1 inst memory allocation failed\n");  				return -1;  			}  			dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -70,8 +56,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l1_data_sram_alloc(s->sh_size);  			mod->arch.data_a_l1 = dest;  			if (dest == NULL) { -				pr_err("L1 data memory allocation failed\n", -					mod->name); +				pr_err("L1 data memory allocation failed\n");  				return -1;  			}  			memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -83,8 +68,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l1_data_sram_zalloc(s->sh_size);  			mod->arch.bss_a_l1 = dest;  			if (dest == NULL) { -				pr_err("L1 data memory allocation failed\n", -					mod->name); +				pr_err("L1 data memory allocation failed\n");  				return -1;  			} @@ -93,8 +77,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l1_data_B_sram_alloc(s->sh_size);  			mod->arch.data_b_l1 = dest;  			if (dest == NULL) { -				pr_err("L1 data memory allocation failed\n", -					mod->name); +				pr_err("L1 data memory allocation failed\n");  				return -1;  			}  			memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -104,8 +87,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l1_data_B_sram_alloc(s->sh_size);  			mod->arch.bss_b_l1 = dest;  			if (dest == NULL) { -				pr_err("L1 data memory allocation failed\n", -					mod->name); +				pr_err("L1 data memory allocation failed\n");  				return -1;  			}  			memset(dest, 0, s->sh_size); @@ -117,8 +99,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l2_sram_alloc(s->sh_size);  			mod->arch.text_l2 = dest;  			if (dest == NULL) { -				pr_err("L2 SRAM allocation failed\n", -					mod->name); +				pr_err("L2 SRAM allocation failed\n");  				return -1;  			}  			memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -130,8 +111,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l2_sram_alloc(s->sh_size);  			mod->arch.data_l2 = dest;  			if (dest == NULL) { -				pr_err("L2 SRAM allocation failed\n", -					mod->name); +				pr_err("L2 SRAM allocation failed\n");  				return -1;  			}  			memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -143,8 +123,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  			dest = l2_sram_zalloc(s->sh_size);  			mod->arch.bss_l2 = dest;  			if (dest == NULL) { -				pr_err("L2 SRAM allocation failed\n", -					mod->name); +				pr_err("L2 SRAM allocation failed\n");  				return -1;  			} @@ -158,14 +137,6 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,  	return 0;  } -int -apply_relocate(Elf_Shdr * sechdrs, const char *strtab, -	       unsigned int symindex, unsigned int relsec, struct module *me) -{ -	pr_err(".rel unsupported\n", me->name); -	return -ENOEXEC; -} -  /*************************************************************************/  /* FUNCTION : apply_relocate_add                                         */  /* ABSTRACT : Blackfin specific relocation handling for the loadable     */ @@ -186,7 +157,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,  	Elf32_Sym *sym;  	unsigned long location, value, size; -	pr_debug("applying relocate section %u to %u\n", mod->name, +	pr_debug("applying relocate section %u to %u\n",  		relsec, sechdrs[relsec].sh_info);  	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { @@ -203,14 +174,14 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,  #ifdef CONFIG_SMP  		if (location >= COREB_L1_DATA_A_START) { -			pr_err("cannot relocate in L1: %u (SMP kernel)", -				mod->name, ELF32_R_TYPE(rel[i].r_info)); +			pr_err("cannot relocate in L1: %u (SMP kernel)\n", +				ELF32_R_TYPE(rel[i].r_info));  			return -ENOEXEC;  		}  #endif  		pr_debug("location is %lx, value is %lx type is %d\n", -			mod->name, location, value, ELF32_R_TYPE(rel[i].r_info)); +			location, value, ELF32_R_TYPE(rel[i].r_info));  		switch (ELF32_R_TYPE(rel[i].r_info)) { @@ -230,11 +201,11 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,  		case R_BFIN_PCREL12_JUMP_S:  		case R_BFIN_PCREL10:  			pr_err("unsupported relocation: %u (no -mlong-calls?)\n", -				mod->name, ELF32_R_TYPE(rel[i].r_info)); +				ELF32_R_TYPE(rel[i].r_info));  			return -ENOEXEC;  		default: -			pr_err("unknown relocation: %u\n", mod->name, +			pr_err("unknown relocation: %u\n",  				ELF32_R_TYPE(rel[i].r_info));  			return -ENOEXEC;  		} @@ -251,8 +222,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,  			isram_memcpy((void *)location, &value, size);  			break;  		default: -			pr_err("invalid relocation for %#lx\n", -				mod->name, location); +			pr_err("invalid relocation for %#lx\n", location);  			return -ENOEXEC;  		}  	} diff --git a/arch/blackfin/kernel/nmi.c b/arch/blackfin/kernel/nmi.c index 0b5f72f17fd..9919d29287d 100644 --- a/arch/blackfin/kernel/nmi.c +++ b/arch/blackfin/kernel/nmi.c @@ -12,13 +12,13 @@  #include <linux/bitops.h>  #include <linux/hardirq.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h>  #include <linux/pm.h>  #include <linux/nmi.h>  #include <linux/smp.h>  #include <linux/timer.h>  #include <asm/blackfin.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/cacheflush.h>  #include <asm/bfin_watchdog.h> @@ -145,16 +145,16 @@ int check_nmi_wdt_touched(void)  {  	unsigned int this_cpu = smp_processor_id();  	unsigned int cpu; +	cpumask_t mask; -	cpumask_t mask = cpu_online_map; - +	cpumask_copy(&mask, cpu_online_mask);  	if (!atomic_read(&nmi_touched[this_cpu]))  		return 0;  	atomic_set(&nmi_touched[this_cpu], 0); -	cpu_clear(this_cpu, mask); -	for_each_cpu_mask(cpu, mask) { +	cpumask_clear_cpu(this_cpu, &mask); +	for_each_cpu(cpu, &mask) {  		invalidate_dcache_range((unsigned long)(&nmi_touched[cpu]),  				(unsigned long)(&nmi_touched[cpu]));  		if (!atomic_read(&nmi_touched[cpu])) @@ -196,43 +196,31 @@ void touch_nmi_watchdog(void)  /* Suspend/resume support */  #ifdef CONFIG_PM -static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state) +static int nmi_wdt_suspend(void)  {  	nmi_wdt_stop();  	return 0;  } -static int nmi_wdt_resume(struct sys_device *dev) +static void nmi_wdt_resume(void)  {  	if (nmi_active)  		nmi_wdt_start(); -	return 0;  } -static struct sysdev_class nmi_sysclass = { -	.name		= DRV_NAME, +static struct syscore_ops nmi_syscore_ops = {  	.resume		= nmi_wdt_resume,  	.suspend	= nmi_wdt_suspend,  }; -static struct sys_device device_nmi_wdt = { -	.id	= 0, -	.cls	= &nmi_sysclass, -}; - -static int __init init_nmi_wdt_sysfs(void) +static int __init init_nmi_wdt_syscore(void)  { -	int error; - -	if (!nmi_active) -		return 0; +	if (nmi_active) +		register_syscore_ops(&nmi_syscore_ops); -	error = sysdev_class_register(&nmi_sysclass); -	if (!error) -		error = sysdev_register(&device_nmi_wdt); -	return error; +	return 0;  } -late_initcall(init_nmi_wdt_sysfs); +late_initcall(init_nmi_wdt_syscore);  #endif	/* CONFIG_PM */ diff --git a/arch/blackfin/kernel/perf_event.c b/arch/blackfin/kernel/perf_event.c new file mode 100644 index 00000000000..974e55496db --- /dev/null +++ b/arch/blackfin/kernel/perf_event.c @@ -0,0 +1,499 @@ +/* + * Blackfin performance counters + * + * Copyright 2011 Analog Devices Inc. + * + * Ripped from SuperH version: + * + *  Copyright (C) 2009  Paul Mundt + * + * Heavily based on the x86 and PowerPC implementations. + * + * x86: + *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de> + *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar + *  Copyright (C) 2009 Jaswinder Singh Rajput + *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter + *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> + *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com> + * + * ppc: + *  Copyright 2008-2009 Paul Mackerras, IBM Corporation. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/kernel.h> +#include <linux/export.h> +#include <linux/init.h> +#include <linux/perf_event.h> +#include <asm/bfin_pfmon.h> + +/* + * We have two counters, and each counter can support an event type. + * The 'o' is PFCNTx=1 and 's' is PFCNTx=0 + * + * 0x04 o pc invariant branches + * 0x06 o mispredicted branches + * 0x09 o predicted branches taken + * 0x0B o EXCPT insn + * 0x0C o CSYNC/SSYNC insn + * 0x0D o Insns committed + * 0x0E o Interrupts taken + * 0x0F o Misaligned address exceptions + * 0x80 o Code memory fetches stalled due to DMA + * 0x83 o 64bit insn fetches delivered + * 0x9A o data cache fills (bank a) + * 0x9B o data cache fills (bank b) + * 0x9C o data cache lines evicted (bank a) + * 0x9D o data cache lines evicted (bank b) + * 0x9E o data cache high priority fills + * 0x9F o data cache low priority fills + * 0x00 s loop 0 iterations + * 0x01 s loop 1 iterations + * 0x0A s CSYNC/SSYNC stalls + * 0x10 s DAG read/after write hazards + * 0x13 s RAW data hazards + * 0x81 s code TAG stalls + * 0x82 s code fill stalls + * 0x90 s processor to memory stalls + * 0x91 s data memory stalls not hidden by 0x90 + * 0x92 s data store buffer full stalls + * 0x93 s data memory write buffer full stalls due to high->low priority + * 0x95 s data memory fill buffer stalls + * 0x96 s data TAG collision stalls + * 0x97 s data collision stalls + * 0x98 s data stalls + * 0x99 s data stalls sent to processor + */ + +static const int event_map[] = { +	/* use CYCLES cpu register */ +	[PERF_COUNT_HW_CPU_CYCLES]          = -1, +	[PERF_COUNT_HW_INSTRUCTIONS]        = 0x0D, +	[PERF_COUNT_HW_CACHE_REFERENCES]    = -1, +	[PERF_COUNT_HW_CACHE_MISSES]        = 0x83, +	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x09, +	[PERF_COUNT_HW_BRANCH_MISSES]       = 0x06, +	[PERF_COUNT_HW_BUS_CYCLES]          = -1, +}; + +#define C(x)	PERF_COUNT_HW_CACHE_##x + +static const int cache_events[PERF_COUNT_HW_CACHE_MAX] +                             [PERF_COUNT_HW_CACHE_OP_MAX] +                             [PERF_COUNT_HW_CACHE_RESULT_MAX] = +{ +	[C(L1D)] = {	/* Data bank A */ +		[C(OP_READ)] = { +			[C(RESULT_ACCESS)] = 0, +			[C(RESULT_MISS)  ] = 0x9A, +		}, +		[C(OP_WRITE)] = { +			[C(RESULT_ACCESS)] = 0, +			[C(RESULT_MISS)  ] = 0, +		}, +		[C(OP_PREFETCH)] = { +			[C(RESULT_ACCESS)] = 0, +			[C(RESULT_MISS)  ] = 0, +		}, +	}, + +	[C(L1I)] = { +		[C(OP_READ)] = { +			[C(RESULT_ACCESS)] = 0, +			[C(RESULT_MISS)  ] = 0x83, +		}, +		[C(OP_WRITE)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_PREFETCH)] = { +			[C(RESULT_ACCESS)] = 0, +			[C(RESULT_MISS)  ] = 0, +		}, +	}, + +	[C(LL)] = { +		[C(OP_READ)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_WRITE)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_PREFETCH)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +	}, + +	[C(DTLB)] = { +		[C(OP_READ)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_WRITE)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_PREFETCH)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +	}, + +	[C(ITLB)] = { +		[C(OP_READ)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_WRITE)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_PREFETCH)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +	}, + +	[C(BPU)] = { +		[C(OP_READ)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_WRITE)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +		[C(OP_PREFETCH)] = { +			[C(RESULT_ACCESS)] = -1, +			[C(RESULT_MISS)  ] = -1, +		}, +	}, +}; + +const char *perf_pmu_name(void) +{ +	return "bfin"; +} +EXPORT_SYMBOL(perf_pmu_name); + +int perf_num_counters(void) +{ +	return ARRAY_SIZE(event_map); +} +EXPORT_SYMBOL(perf_num_counters); + +static u64 bfin_pfmon_read(int idx) +{ +	return bfin_read32(PFCNTR0 + (idx * 4)); +} + +static void bfin_pfmon_disable(struct hw_perf_event *hwc, int idx) +{ +	bfin_write_PFCTL(bfin_read_PFCTL() & ~PFCEN(idx, PFCEN_MASK)); +} + +static void bfin_pfmon_enable(struct hw_perf_event *hwc, int idx) +{ +	u32 val, mask; + +	val = PFPWR; +	if (idx) { +		mask = ~(PFCNT1 | PFMON1 | PFCEN1 | PEMUSW1); +		/* The packed config is for event0, so shift it to event1 slots */ +		val |= (hwc->config << (PFMON1_P - PFMON0_P)); +		val |= (hwc->config & PFCNT0) << (PFCNT1_P - PFCNT0_P); +		bfin_write_PFCNTR1(0); +	} else { +		mask = ~(PFCNT0 | PFMON0 | PFCEN0 | PEMUSW0); +		val |= hwc->config; +		bfin_write_PFCNTR0(0); +	} + +	bfin_write_PFCTL((bfin_read_PFCTL() & mask) | val); +} + +static void bfin_pfmon_disable_all(void) +{ +	bfin_write_PFCTL(bfin_read_PFCTL() & ~PFPWR); +} + +static void bfin_pfmon_enable_all(void) +{ +	bfin_write_PFCTL(bfin_read_PFCTL() | PFPWR); +} + +struct cpu_hw_events { +	struct perf_event *events[MAX_HWEVENTS]; +	unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; +}; +DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); + +static int hw_perf_cache_event(int config, int *evp) +{ +	unsigned long type, op, result; +	int ev; + +	/* unpack config */ +	type = config & 0xff; +	op = (config >> 8) & 0xff; +	result = (config >> 16) & 0xff; + +	if (type >= PERF_COUNT_HW_CACHE_MAX || +	    op >= PERF_COUNT_HW_CACHE_OP_MAX || +	    result >= PERF_COUNT_HW_CACHE_RESULT_MAX) +		return -EINVAL; + +	ev = cache_events[type][op][result]; +	if (ev == 0) +		return -EOPNOTSUPP; +	if (ev == -1) +		return -EINVAL; +	*evp = ev; +	return 0; +} + +static void bfin_perf_event_update(struct perf_event *event, +				   struct hw_perf_event *hwc, int idx) +{ +	u64 prev_raw_count, new_raw_count; +	s64 delta; +	int shift = 0; + +	/* +	 * Depending on the counter configuration, they may or may not +	 * be chained, in which case the previous counter value can be +	 * updated underneath us if the lower-half overflows. +	 * +	 * Our tactic to handle this is to first atomically read and +	 * exchange a new raw count - then add that new-prev delta +	 * count to the generic counter atomically. +	 * +	 * As there is no interrupt associated with the overflow events, +	 * this is the simplest approach for maintaining consistency. +	 */ +again: +	prev_raw_count = local64_read(&hwc->prev_count); +	new_raw_count = bfin_pfmon_read(idx); + +	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, +			     new_raw_count) != prev_raw_count) +		goto again; + +	/* +	 * Now we have the new raw value and have updated the prev +	 * timestamp already. We can now calculate the elapsed delta +	 * (counter-)time and add that to the generic counter. +	 * +	 * Careful, not all hw sign-extends above the physical width +	 * of the count. +	 */ +	delta = (new_raw_count << shift) - (prev_raw_count << shift); +	delta >>= shift; + +	local64_add(delta, &event->count); +} + +static void bfin_pmu_stop(struct perf_event *event, int flags) +{ +	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); +	struct hw_perf_event *hwc = &event->hw; +	int idx = hwc->idx; + +	if (!(event->hw.state & PERF_HES_STOPPED)) { +		bfin_pfmon_disable(hwc, idx); +		cpuc->events[idx] = NULL; +		event->hw.state |= PERF_HES_STOPPED; +	} + +	if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) { +		bfin_perf_event_update(event, &event->hw, idx); +		event->hw.state |= PERF_HES_UPTODATE; +	} +} + +static void bfin_pmu_start(struct perf_event *event, int flags) +{ +	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); +	struct hw_perf_event *hwc = &event->hw; +	int idx = hwc->idx; + +	if (WARN_ON_ONCE(idx == -1)) +		return; + +	if (flags & PERF_EF_RELOAD) +		WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); + +	cpuc->events[idx] = event; +	event->hw.state = 0; +	bfin_pfmon_enable(hwc, idx); +} + +static void bfin_pmu_del(struct perf_event *event, int flags) +{ +	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + +	bfin_pmu_stop(event, PERF_EF_UPDATE); +	__clear_bit(event->hw.idx, cpuc->used_mask); + +	perf_event_update_userpage(event); +} + +static int bfin_pmu_add(struct perf_event *event, int flags) +{ +	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); +	struct hw_perf_event *hwc = &event->hw; +	int idx = hwc->idx; +	int ret = -EAGAIN; + +	perf_pmu_disable(event->pmu); + +	if (__test_and_set_bit(idx, cpuc->used_mask)) { +		idx = find_first_zero_bit(cpuc->used_mask, MAX_HWEVENTS); +		if (idx == MAX_HWEVENTS) +			goto out; + +		__set_bit(idx, cpuc->used_mask); +		hwc->idx = idx; +	} + +	bfin_pfmon_disable(hwc, idx); + +	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; +	if (flags & PERF_EF_START) +		bfin_pmu_start(event, PERF_EF_RELOAD); + +	perf_event_update_userpage(event); +	ret = 0; +out: +	perf_pmu_enable(event->pmu); +	return ret; +} + +static void bfin_pmu_read(struct perf_event *event) +{ +	bfin_perf_event_update(event, &event->hw, event->hw.idx); +} + +static int bfin_pmu_event_init(struct perf_event *event) +{ +	struct perf_event_attr *attr = &event->attr; +	struct hw_perf_event *hwc = &event->hw; +	int config = -1; +	int ret; + +	if (attr->exclude_hv || attr->exclude_idle) +		return -EPERM; + +	/* +	 * All of the on-chip counters are "limited", in that they have +	 * no interrupts, and are therefore unable to do sampling without +	 * further work and timer assistance. +	 */ +	if (hwc->sample_period) +		return -EINVAL; + +	ret = 0; +	switch (attr->type) { +	case PERF_TYPE_RAW: +		config = PFMON(0, attr->config & PFMON_MASK) | +			PFCNT(0, !(attr->config & 0x100)); +		break; +	case PERF_TYPE_HW_CACHE: +		ret = hw_perf_cache_event(attr->config, &config); +		break; +	case PERF_TYPE_HARDWARE: +		if (attr->config >= ARRAY_SIZE(event_map)) +			return -EINVAL; + +		config = event_map[attr->config]; +		break; +	} + +	if (config == -1) +		return -EINVAL; + +	if (!attr->exclude_kernel) +		config |= PFCEN(0, PFCEN_ENABLE_SUPV); +	if (!attr->exclude_user) +		config |= PFCEN(0, PFCEN_ENABLE_USER); + +	hwc->config |= config; + +	return ret; +} + +static void bfin_pmu_enable(struct pmu *pmu) +{ +	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); +	struct perf_event *event; +	struct hw_perf_event *hwc; +	int i; + +	for (i = 0; i < MAX_HWEVENTS; ++i) { +		event = cpuc->events[i]; +		if (!event) +			continue; +		hwc = &event->hw; +		bfin_pfmon_enable(hwc, hwc->idx); +	} + +	bfin_pfmon_enable_all(); +} + +static void bfin_pmu_disable(struct pmu *pmu) +{ +	bfin_pfmon_disable_all(); +} + +static struct pmu pmu = { +	.pmu_enable  = bfin_pmu_enable, +	.pmu_disable = bfin_pmu_disable, +	.event_init  = bfin_pmu_event_init, +	.add         = bfin_pmu_add, +	.del         = bfin_pmu_del, +	.start       = bfin_pmu_start, +	.stop        = bfin_pmu_stop, +	.read        = bfin_pmu_read, +}; + +static void bfin_pmu_setup(int cpu) +{ +	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); + +	memset(cpuhw, 0, sizeof(struct cpu_hw_events)); +} + +static int +bfin_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) +{ +	unsigned int cpu = (long)hcpu; + +	switch (action & ~CPU_TASKS_FROZEN) { +	case CPU_UP_PREPARE: +		bfin_write_PFCTL(0); +		bfin_pmu_setup(cpu); +		break; + +	default: +		break; +	} + +	return NOTIFY_OK; +} + +static int __init bfin_pmu_init(void) +{ +	int ret; + +	ret = perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); +	if (!ret) +		perf_cpu_notifier(bfin_pmu_notifier); + +	return ret; +} +early_initcall(bfin_pmu_init); diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index cd0c090ebc5..4aa5545c4fd 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -7,7 +7,6 @@   */  #include <linux/module.h> -#include <linux/smp_lock.h>  #include <linux/unistd.h>  #include <linux/user.h>  #include <linux/uaccess.h> @@ -20,6 +19,7 @@  #include <asm/blackfin.h>  #include <asm/fixed_code.h>  #include <asm/mem_map.h> +#include <asm/irq.h>  asmlinkage void ret_from_fork(void); @@ -39,12 +39,6 @@ int nr_l1stack_tasks;  void *l1_stack_base;  unsigned long l1_stack_len; -/* - * Powermanagement idle function, if any.. - */ -void (*pm_idle)(void) = NULL; -EXPORT_SYMBOL(pm_idle); -  void (*pm_power_off)(void) = NULL;  EXPORT_SYMBOL(pm_power_off); @@ -52,15 +46,14 @@ EXPORT_SYMBOL(pm_power_off);   * The idle loop on BFIN   */  #ifdef CONFIG_IDLE_L1 -static void default_idle(void)__attribute__((l1_text)); -void cpu_idle(void)__attribute__((l1_text)); +void arch_cpu_idle(void)__attribute__((l1_text));  #endif  /*   * This is our default idle handler.  We need to disable   * interrupts here to ensure we don't miss a wakeup call.   */ -static void default_idle(void) +void arch_cpu_idle(void)  {  #ifdef CONFIG_IPIPE  	ipipe_suspend_domain(); @@ -72,66 +65,12 @@ static void default_idle(void)  	hard_local_irq_enable();  } -/* - * The idle thread.  We try to conserve power, while trying to keep - * overall latency low.  The architecture specific idle is passed - * a value to indicate the level of "idleness" of the system. - */ -void cpu_idle(void) -{ -	/* endless idle loop with no priority at all */ -	while (1) { -		void (*idle)(void) = pm_idle; -  #ifdef CONFIG_HOTPLUG_CPU -		if (cpu_is_offline(smp_processor_id())) -			cpu_die(); -#endif -		if (!idle) -			idle = default_idle; -		tick_nohz_stop_sched_tick(1); -		while (!need_resched()) -			idle(); -		tick_nohz_restart_sched_tick(); -		preempt_enable_no_resched(); -		schedule(); -		preempt_disable(); -	} -} - -/* - * This gets run with P1 containing the - * function to call, and R1 containing - * the "args".  Note P0 is clobbered on the way here. - */ -void kernel_thread_helper(void); -__asm__(".section .text\n" -	".align 4\n" -	"_kernel_thread_helper:\n\t" -	"\tsp += -12;\n\t" -	"\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) +void arch_cpu_idle_dead(void)  { -	struct pt_regs regs; - -	memset(®s, 0, sizeof(regs)); - -	regs.r1 = (unsigned long)arg; -	regs.p1 = (unsigned long)fn; -	regs.pc = (unsigned long)kernel_thread_helper; -	regs.orig_p0 = -1; -	/* Set bit 2 to tell ret_from_fork we should be returning to kernel -	   mode.  */ -	regs.ipend = 0x8002; -	__asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):); -	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, -		       NULL); +	cpu_die();  } -EXPORT_SYMBOL(kernel_thread); +#endif  /*   * Do necessary setup to start up a newly executed thread. @@ -141,7 +80,6 @@ EXPORT_SYMBOL(kernel_thread);   */  void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)  { -	set_fs(USER_DS);  	regs->pc = new_ip;  	if (current->mm)  		regs->p5 = current->mm->start_data; @@ -160,72 +98,48 @@ void flush_thread(void)  {  } -asmlinkage int bfin_vfork(struct pt_regs *regs) -{ -	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, -		       NULL); -} - -asmlinkage int bfin_clone(struct pt_regs *regs) +asmlinkage int bfin_clone(unsigned long clone_flags, unsigned long newsp)  { -	unsigned long clone_flags; -	unsigned long newsp; -  #ifdef __ARCH_SYNC_CORE_DCACHE -	if (current->rt.nr_cpus_allowed == num_possible_cpus()) { -		current->cpus_allowed = cpumask_of_cpu(smp_processor_id()); -		current->rt.nr_cpus_allowed = 1; -	} +	if (current->nr_cpus_allowed == num_possible_cpus()) +		set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id()));  #endif - -	/* syscall2 puts clone_flags in r0 and usp in r1 */ -	clone_flags = regs->r0; -	newsp = regs->r1; -	if (!newsp) -		newsp = rdusp(); -	else +	if (newsp)  		newsp -= 12; -	return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); +	return do_fork(clone_flags, newsp, 0, NULL, NULL);  }  int  copy_thread(unsigned long clone_flags,  	    unsigned long usp, unsigned long topstk, -	    struct task_struct *p, struct pt_regs *regs) +	    struct task_struct *p)  {  	struct pt_regs *childregs; +	unsigned long *v;  	childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; -	*childregs = *regs; -	childregs->r0 = 0; +	v = ((unsigned long *)childregs) - 2; +	if (unlikely(p->flags & PF_KTHREAD)) { +		memset(childregs, 0, sizeof(struct pt_regs)); +		v[0] = usp; +		v[1] = topstk; +		childregs->orig_p0 = -1; +		childregs->ipend = 0x8000; +		__asm__ __volatile__("%0 = syscfg;":"=da"(childregs->syscfg):); +		p->thread.usp = 0; +	} else { +		*childregs = *current_pt_regs(); +		childregs->r0 = 0; +		p->thread.usp = usp ? : rdusp(); +		v[0] = v[1] = 0; +	} -	p->thread.usp = usp; -	p->thread.ksp = (unsigned long)childregs; +	p->thread.ksp = (unsigned long)v;  	p->thread.pc = (unsigned long)ret_from_fork;  	return 0;  } -/* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(const char __user *name, -			  const char __user *const __user *argv, -			  const char __user *const __user *envp) -{ -	int error; -	char *filename; -	struct pt_regs *regs = (struct pt_regs *)((&name) + 6); - -	filename = getname(name); -	error = PTR_ERR(filename); -	if (IS_ERR(filename)) -		return error; -	error = do_execve(filename, argv, envp, regs); -	putname(filename); -	return error; -} -  unsigned long get_wchan(struct task_struct *p)  {  	unsigned long fp, pc; @@ -332,12 +246,16 @@ int in_mem_const(unsigned long addr, unsigned long size,  {  	return in_mem_const_off(addr, size, 0, const_addr, const_size);  } +#ifdef CONFIG_BF60x +#define ASYNC_ENABLED(bnum, bctlnum)	1 +#else  #define ASYNC_ENABLED(bnum, bctlnum) \  ({ \  	(bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \  	bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \  	1; \  }) +#endif  /*   * We can't read EBIU banks that aren't enabled or we end up hanging   * on the access to the async space.  Make sure we validate accesses diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 75089f80855..8b8fe671b1a 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -20,7 +20,6 @@  #include <asm/page.h>  #include <asm/pgtable.h> -#include <asm/system.h>  #include <asm/processor.h>  #include <asm/asm-offsets.h>  #include <asm/dma.h> @@ -118,6 +117,7 @@ put_reg(struct task_struct *task, unsigned long regno, unsigned long data)  int  is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long len)  { +	bool valid;  	struct vm_area_struct *vma;  	struct sram_list_struct *sraml; @@ -125,9 +125,12 @@ is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long  	if (start + len < start)  		return -EIO; +	down_read(&child->mm->mmap_sem);  	vma = find_vma(child->mm, start); -	if (vma && start >= vma->vm_start && start + len <= vma->vm_end) -			return 0; +	valid = vma && start >= vma->vm_start && start + len <= vma->vm_end; +	up_read(&child->mm->mmap_sem); +	if (valid) +		return 0;  	for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next)  		if (start >= (unsigned long)sraml->addr diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c index 53d08dee853..c4f50a32850 100644 --- a/arch/blackfin/kernel/reboot.c +++ b/arch/blackfin/kernel/reboot.c @@ -9,7 +9,6 @@  #include <linux/interrupt.h>  #include <asm/bfin-global.h>  #include <asm/reboot.h> -#include <asm/system.h>  #include <asm/bfrom.h>  /* A system soft reset makes external memory unusable so force @@ -23,6 +22,10 @@  __attribute__ ((__l1_text__, __noreturn__))  static void bfin_reset(void)  { +#ifndef CONFIG_BF60x +	if (!ANOMALY_05000353 && !ANOMALY_05000386) +		bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20)); +  	/* Wait for completion of "system" events such as cache line  	 * line fills so that we avoid infinite stalls later on as  	 * much as possible.  This code is in L1, so it won't trigger @@ -30,50 +33,49 @@ static void bfin_reset(void)  	 */  	__builtin_bfin_ssync(); -	/* The bootrom checks to see how it was reset and will -	 * automatically perform a software reset for us when -	 * it starts executing after the core reset. -	 */ -	if (ANOMALY_05000353 || ANOMALY_05000386) { -		/* Initiate System software reset. */ -		bfin_write_SWRST(0x7); +	/* Initiate System software reset. */ +	bfin_write_SWRST(0x7); -		/* Due to the way reset is handled in the hardware, we need -		 * to delay for 10 SCLKS.  The only reliable way to do this is -		 * to calculate the CCLK/SCLK ratio and multiply 10.  For now, -		 * we'll assume worse case which is a 1:15 ratio. -		 */ -		asm( -			"LSETUP (1f, 1f) LC0 = %0\n" -			"1: nop;" -			: -			: "a" (15 * 10) -			: "LC0", "LB0", "LT0" -		); +	/* Due to the way reset is handled in the hardware, we need +	 * to delay for 10 SCLKS.  The only reliable way to do this is +	 * to calculate the CCLK/SCLK ratio and multiply 10.  For now, +	 * we'll assume worse case which is a 1:15 ratio. +	 */ +	asm( +		"LSETUP (1f, 1f) LC0 = %0\n" +		"1: nop;" +		: +		: "a" (15 * 10) +		: "LC0", "LB0", "LT0" +	); -		/* Clear System software reset */ -		bfin_write_SWRST(0); +	/* Clear System software reset */ +	bfin_write_SWRST(0); -		/* The BF526 ROM will crash during reset */ +	/* The BF526 ROM will crash during reset */  #if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) +	/* Seems to be fixed with newer parts though ... */ +	if (__SILICON_REVISION__ < 1 && bfin_revid() < 1)  		bfin_read_SWRST();  #endif - -		/* Wait for the SWRST write to complete.  Cannot rely on SSYNC -		 * though as the System state is all reset now. -		 */ -		asm( -			"LSETUP (1f, 1f) LC1 = %0\n" -			"1: nop;" -			: -			: "a" (15 * 1) -			: "LC1", "LB1", "LT1" -		); -	} +	/* Wait for the SWRST write to complete.  Cannot rely on SSYNC +	 * though as the System state is all reset now. +	 */ +	asm( +		"LSETUP (1f, 1f) LC1 = %0\n" +		"1: nop;" +		: +		: "a" (15 * 1) +		: "LC1", "LB1", "LT1" +	);  	while (1)  		/* Issue core reset */  		asm("raise 1"); +#else +	while (1) +		bfin_write_RCU0_CTL(0x1); +#endif  }  __attribute__((weak)) @@ -84,7 +86,6 @@ void native_machine_restart(char *cmd)  void machine_restart(char *cmd)  {  	native_machine_restart(cmd); -	local_irq_disable();  	if (smp_processor_id())  		smp_call_function((void *)bfin_reset, 0, 1);  	else diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index ac71dc15cbd..4f424ae3b36 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -17,7 +17,7 @@  #ifdef CONFIG_MTD_UCLINUX  #include <linux/mtd/map.h>  #include <linux/ext2_fs.h> -#include <linux/cramfs_fs.h> +#include <uapi/linux/cramfs_fs.h>  #include <linux/romfs_fs.h>  #endif @@ -25,10 +25,19 @@  #include <asm/cacheflush.h>  #include <asm/blackfin.h>  #include <asm/cplbinit.h> +#include <asm/clocks.h>  #include <asm/div64.h>  #include <asm/cpu.h>  #include <asm/fixed_code.h>  #include <asm/early_printk.h> +#include <asm/irq_handler.h> +#include <asm/pda.h> +#ifdef CONFIG_BF60x +#include <mach/pm.h> +#endif +#ifdef CONFIG_SCB_PRIORITY +#include <asm/scb.h> +#endif  u16 _bfin_swrst;  EXPORT_SYMBOL(_bfin_swrst); @@ -46,15 +55,13 @@ EXPORT_SYMBOL(reserved_mem_dcache_on);  #ifdef CONFIG_MTD_UCLINUX  extern struct map_info uclinux_ram_map;  unsigned long memory_mtd_end, memory_mtd_start, mtd_size; -unsigned long _ebss;  EXPORT_SYMBOL(memory_mtd_end);  EXPORT_SYMBOL(memory_mtd_start);  EXPORT_SYMBOL(mtd_size);  #endif  char __initdata command_line[COMMAND_LINE_SIZE]; -void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, -	*init_saved_icplb_fault_addr, *init_saved_dcplb_fault_addr; +struct blackfin_initial_pda __initdata initial_pda;  /* boot memmap, for parsing "memmap=" */  #define BFIN_MEMMAP_MAX		128 /* number of entries in bfin_memmap */ @@ -95,7 +102,7 @@ void __init generate_cplb_tables(void)  }  #endif -void __cpuinit bfin_setup_caches(unsigned int cpu) +void bfin_setup_caches(unsigned int cpu)  {  #ifdef CONFIG_BFIN_ICACHE  	bfin_icache_init(icplb_tbl[cpu]); @@ -105,6 +112,8 @@ void __cpuinit bfin_setup_caches(unsigned int cpu)  	bfin_dcache_init(dcplb_tbl[cpu]);  #endif +	bfin_setup_cpudata(cpu); +  	/*  	 * In cache coherence emulation mode, we need to have the  	 * D-cache enabled before running any atomic operation which @@ -159,11 +168,10 @@ void __cpuinit bfin_setup_caches(unsigned int cpu)  #endif  } -void __cpuinit bfin_setup_cpudata(unsigned int cpu) +void bfin_setup_cpudata(unsigned int cpu)  {  	struct blackfin_cpudata *cpudata = &per_cpu(cpu_data, cpu); -	cpudata->idle = current;  	cpudata->imemctl = bfin_read_IMEM_CONTROL();  	cpudata->dmemctl = bfin_read_DMEM_CONTROL();  } @@ -215,11 +223,48 @@ void __init bfin_relocate_l1_mem(void)  	early_dma_memcpy_done(); +#if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1) +	blackfin_iflush_l1_entry[0] = (unsigned long)blackfin_icache_flush_range_l1; +#endif +  	/* if necessary, copy L2 text/data to L2 SRAM */  	if (L2_LENGTH && l2_len)  		memcpy(_stext_l2, _l2_lma, l2_len);  } +#ifdef CONFIG_SMP +void __init bfin_relocate_coreb_l1_mem(void) +{ +	unsigned long text_l1_len = (unsigned long)_text_l1_len; +	unsigned long data_l1_len = (unsigned long)_data_l1_len; +	unsigned long data_b_l1_len = (unsigned long)_data_b_l1_len; + +	blackfin_dma_early_init(); + +	/* if necessary, copy L1 text to L1 instruction SRAM */ +	if (L1_CODE_LENGTH && text_l1_len) +		early_dma_memcpy((void *)COREB_L1_CODE_START, _text_l1_lma, +				text_l1_len); + +	/* if necessary, copy L1 data to L1 data bank A SRAM */ +	if (L1_DATA_A_LENGTH && data_l1_len) +		early_dma_memcpy((void *)COREB_L1_DATA_A_START, _data_l1_lma, +				data_l1_len); + +	/* if necessary, copy L1 data B to L1 data bank B SRAM */ +	if (L1_DATA_B_LENGTH && data_b_l1_len) +		early_dma_memcpy((void *)COREB_L1_DATA_B_START, _data_b_l1_lma, +				data_b_l1_len); + +	early_dma_memcpy_done(); + +#ifdef CONFIG_ICACHE_FLUSH_L1 +	blackfin_iflush_l1_entry[1] = (unsigned long)blackfin_icache_flush_range_l1 - +			(unsigned long)_stext_l1 + COREB_L1_CODE_START; +#endif +} +#endif +  #ifdef CONFIG_ROMKERNEL  void __init bfin_relocate_xip_data(void)  { @@ -572,7 +617,8 @@ static __init void memory_setup(void)  		/* ROM_FS is XIP, so if we found it, we need to limit memory */  		if (memory_end > max_mem) { -			pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); +			pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", +				(max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20);  			memory_end = max_mem;  		}  	} @@ -602,7 +648,8 @@ static __init void memory_setup(void)  	 * doesn't exist, or we don't need to - then dont.  	 */  	if (memory_end > max_mem) { -		pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); +		pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", +				(max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20);  		memory_end = max_mem;  	} @@ -621,8 +668,8 @@ static __init void memory_setup(void)  	init_mm.end_data = (unsigned long)_edata;  	init_mm.brk = (unsigned long)0; -	printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); -	printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); +	printk(KERN_INFO "Board Memory: %ldMB\n", (physical_mem_end - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); +	printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20);  	printk(KERN_INFO "Memory map:\n"  	       "  fixedcode = 0x%p-0x%p\n" @@ -665,7 +712,7 @@ void __init find_min_max_pfn(void)  	int i;  	max_pfn = 0; -	min_low_pfn = memory_end; +	min_low_pfn = PFN_DOWN(memory_end);  	for (i = 0; i < bfin_memmap.nr_map; i++) {  		unsigned long start, end; @@ -708,8 +755,7 @@ static __init void setup_bootmem_allocator(void)  	/* pfn of the first usable page frame after kernel image*/  	if (min_low_pfn < memory_start >> PAGE_SHIFT)  		min_low_pfn = memory_start >> PAGE_SHIFT; - -	start_pfn = PAGE_OFFSET >> PAGE_SHIFT; +	start_pfn = CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT;  	end_pfn = memory_end >> PAGE_SHIFT;  	/* @@ -754,8 +800,8 @@ static __init void setup_bootmem_allocator(void)  	}  	/* reserve memory before memory_start, including bootmap */ -	reserve_bootmem(PAGE_OFFSET, -		memory_start + bootmap_size + PAGE_SIZE - 1 - PAGE_OFFSET, +	reserve_bootmem(CONFIG_PHY_RAM_BASE_ADDRESS, +		memory_start + bootmap_size + PAGE_SIZE - 1 - CONFIG_PHY_RAM_BASE_ADDRESS,  		BOOTMEM_DEFAULT);  } @@ -790,19 +836,54 @@ static inline int __init get_mem_size(void)  	u32 ddrctl = bfin_read_EBIU_DDRCTL1();  	int ret = 0;  	switch (ddrctl & 0xc0000) { -		case DEVSZ_64:  ret = 64 / 8; -		case DEVSZ_128: ret = 128 / 8; -		case DEVSZ_256: ret = 256 / 8; -		case DEVSZ_512: ret = 512 / 8; +	case DEVSZ_64: +		ret = 64 / 8; +		break; +	case DEVSZ_128: +		ret = 128 / 8; +		break; +	case DEVSZ_256: +		ret = 256 / 8; +		break; +	case DEVSZ_512: +		ret = 512 / 8; +		break;  	}  	switch (ddrctl & 0x30000) { -		case DEVWD_4:  ret *= 2; -		case DEVWD_8:  ret *= 2; -		case DEVWD_16: break; +	case DEVWD_4: +		ret *= 2; +	case DEVWD_8: +		ret *= 2; +	case DEVWD_16: +		break;  	}  	if ((ddrctl & 0xc000) == 0x4000)  		ret *= 2;  	return ret; +#elif defined(CONFIG_BF60x) +	u32 ddrctl = bfin_read_DMC0_CFG(); +	int ret; +	switch (ddrctl & 0xf00) { +	case DEVSZ_64: +		ret = 64 / 8; +		break; +	case DEVSZ_128: +		ret = 128 / 8; +		break; +	case DEVSZ_256: +		ret = 256 / 8; +		break; +	case DEVSZ_512: +		ret = 512 / 8; +		break; +	case DEVSZ_1G: +		ret = 1024 / 8; +		break; +	case DEVSZ_2G: +		ret = 2048 / 8; +		break; +	} +	return ret;  #endif  	BUG();  } @@ -812,8 +893,25 @@ void __init native_machine_early_platform_add_devices(void)  {  } +#ifdef CONFIG_BF60x +static inline u_long bfin_get_clk(char *name) +{ +	struct clk *clk; +	u_long clk_rate; + +	clk = clk_get(NULL, name); +	if (IS_ERR(clk)) +		return 0; + +	clk_rate = clk_get_rate(clk); +	clk_put(clk); +	return clk_rate; +} +#endif +  void __init setup_arch(char **cmdline_p)  { +	u32 mmr;  	unsigned long sclk, cclk;  	native_machine_early_platform_add_devices(); @@ -821,6 +919,7 @@ void __init setup_arch(char **cmdline_p)  	enable_shadow_console();  	/* Check to make sure we are running on the right processor */ +	mmr =  bfin_cpuid();  	if (unlikely(CPUID != bfin_cpuid()))  		printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n",  			CPU, bfin_cpuid(), bfin_revid()); @@ -841,6 +940,10 @@ void __init setup_arch(char **cmdline_p)  	memset(&bfin_memmap, 0, sizeof(bfin_memmap)); +#ifdef CONFIG_BF60x +	/* Should init clock device before parse command early */ +	clk_init(); +#endif  	/* If the user does not specify things on the command line, use  	 * what the bootloader set things up as  	 */ @@ -855,6 +958,7 @@ void __init setup_arch(char **cmdline_p)  	memory_setup(); +#ifndef CONFIG_BF60x  	/* Initialize Async memory banks */  	bfin_write_EBIU_AMBCTL0(AMBCTL0VAL);  	bfin_write_EBIU_AMBCTL1(AMBCTL1VAL); @@ -864,11 +968,12 @@ void __init setup_arch(char **cmdline_p)  	bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL);  	bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL);  #endif +#endif  #ifdef CONFIG_BFIN_HYSTERESIS_CONTROL -	bfin_write_PORTF_HYSTERISIS(HYST_PORTF_0_15); -	bfin_write_PORTG_HYSTERISIS(HYST_PORTG_0_15); -	bfin_write_PORTH_HYSTERISIS(HYST_PORTH_0_15); -	bfin_write_MISCPORT_HYSTERISIS((bfin_read_MISCPORT_HYSTERISIS() & +	bfin_write_PORTF_HYSTERESIS(HYST_PORTF_0_15); +	bfin_write_PORTG_HYSTERESIS(HYST_PORTG_0_15); +	bfin_write_PORTH_HYSTERESIS(HYST_PORTH_0_15); +	bfin_write_MISCPORT_HYSTERESIS((bfin_read_MISCPORT_HYSTERESIS() &  					~HYST_NONEGPIO_MASK) | HYST_NONEGPIO);  #endif @@ -884,17 +989,14 @@ void __init setup_arch(char **cmdline_p)  		bfin_read_IMDMA_D1_IRQ_STATUS();  	}  #endif -	printk(KERN_INFO "Hardware Trace "); -	if (bfin_read_TBUFCTL() & 0x1) -		printk(KERN_CONT "Active "); -	else -		printk(KERN_CONT "Off "); -	if (bfin_read_TBUFCTL() & 0x2) -		printk(KERN_CONT "and Enabled\n"); -	else -		printk(KERN_CONT "and Disabled\n"); -	printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); +	mmr = bfin_read_TBUFCTL(); +	printk(KERN_INFO "Hardware Trace %s and %sabled\n", +		(mmr & 0x1) ? "active" : "off", +		(mmr & 0x2) ? "en" : "dis"); +#ifndef CONFIG_BF60x +	mmr = bfin_read_SYSCR(); +	printk(KERN_INFO "Boot Mode: %i\n", mmr & 0xF);  	/* Newer parts mirror SWRST bits in SYSCR */  #if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \ @@ -902,7 +1004,7 @@ void __init setup_arch(char **cmdline_p)  	_bfin_swrst = bfin_read_SWRST();  #else  	/* Clear boot mode field */ -	_bfin_swrst = bfin_read_SYSCR() & ~0xf; +	_bfin_swrst = mmr & ~0xf;  #endif  #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT @@ -920,18 +1022,21 @@ void __init setup_arch(char **cmdline_p)  		printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n");  #ifdef CONFIG_DEBUG_DOUBLEFAULT  		/* We assume the crashing kernel, and the current symbol table match */ -		printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n", -			(int)init_saved_seqstat & SEQSTAT_EXCAUSE, init_saved_retx); -		printk(KERN_NOTICE "   DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr); -		printk(KERN_NOTICE "   ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr); +		printk(KERN_EMERG " While handling exception (EXCAUSE = %#x) at %pF\n", +			initial_pda.seqstat_doublefault & SEQSTAT_EXCAUSE, +			initial_pda.retx_doublefault); +		printk(KERN_NOTICE "   DCPLB_FAULT_ADDR: %pF\n", +			initial_pda.dcplb_doublefault_addr); +		printk(KERN_NOTICE "   ICPLB_FAULT_ADDR: %pF\n", +			initial_pda.icplb_doublefault_addr);  #endif  		printk(KERN_NOTICE " The instruction at %pF caused a double exception\n", -			init_retx); +			initial_pda.retx);  	} else if (_bfin_swrst & RESET_WDOG)  		printk(KERN_INFO "Recovering from Watchdog event\n");  	else if (_bfin_swrst & RESET_SOFTWARE)  		printk(KERN_NOTICE "Reset caused by Software reset\n"); - +#endif  	printk(KERN_INFO "Blackfin support (C) 2004-2010 Analog Devices, Inc.\n");  	if (bfin_compiled_revid() == 0xffff)  		printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid()); @@ -959,8 +1064,13 @@ void __init setup_arch(char **cmdline_p)  	printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); +#ifdef CONFIG_BF60x +	printk(KERN_INFO "Processor Speed: %lu MHz core clock, %lu MHz SCLk, %lu MHz SCLK0, %lu MHz SCLK1 and %lu MHz DCLK\n", +		cclk / 1000000, bfin_get_clk("SYSCLK") / 1000000, get_sclk0() / 1000000, get_sclk1() / 1000000, get_dclk() / 1000000); +#else  	printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n",  	       cclk / 1000000, sclk / 1000000); +#endif  	setup_bootmem_allocator(); @@ -994,13 +1104,14 @@ void __init setup_arch(char **cmdline_p)  #endif  	init_exception_vectors();  	bfin_cache_init();	/* Initialize caches for the boot CPU */ +#ifdef CONFIG_SCB_PRIORITY +	init_scb(); +#endif  }  static int __init topology_init(void)  {  	unsigned int cpu; -	/* Record CPU-private information for the boot processor. */ -	bfin_setup_cpudata(0);  	for_each_possible_cpu(cpu) {  		register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); @@ -1013,10 +1124,12 @@ subsys_initcall(topology_init);  /* Get the input clock frequency */  static u_long cached_clkin_hz = CONFIG_CLKIN_HZ; +#ifndef CONFIG_BF60x  static u_long get_clkin_hz(void)  {  	return cached_clkin_hz;  } +#endif  static int __init early_init_clkin_hz(char *buf)  {  	cached_clkin_hz = simple_strtoul(buf, NULL, 0); @@ -1028,6 +1141,7 @@ static int __init early_init_clkin_hz(char *buf)  }  early_param("clkin_hz=", early_init_clkin_hz); +#ifndef CONFIG_BF60x  /* Get the voltage input multiplier */  static u_long get_vco(void)  { @@ -1050,10 +1164,14 @@ static u_long get_vco(void)  	cached_vco *= msel;  	return cached_vco;  } +#endif  /* Get the Core clock */  u_long get_cclk(void)  { +#ifdef CONFIG_BF60x +	return bfin_get_clk("CCLK"); +#else  	static u_long cached_cclk_pll_div, cached_cclk;  	u_long csel, ssel; @@ -1073,12 +1191,39 @@ u_long get_cclk(void)  	else  		cached_cclk = get_vco() >> csel;  	return cached_cclk; +#endif  }  EXPORT_SYMBOL(get_cclk); -/* Get the System clock */ +#ifdef CONFIG_BF60x +/* Get the bf60x clock of SCLK0 domain */ +u_long get_sclk0(void) +{ +	return bfin_get_clk("SCLK0"); +} +EXPORT_SYMBOL(get_sclk0); + +/* Get the bf60x clock of SCLK1 domain */ +u_long get_sclk1(void) +{ +	return bfin_get_clk("SCLK1"); +} +EXPORT_SYMBOL(get_sclk1); + +/* Get the bf60x DRAM clock */ +u_long get_dclk(void) +{ +	return bfin_get_clk("DCLK"); +} +EXPORT_SYMBOL(get_dclk); +#endif + +/* Get the default system clock */  u_long get_sclk(void)  { +#ifdef CONFIG_BF60x +	return get_sclk0(); +#else  	static u_long cached_sclk;  	u_long ssel; @@ -1099,6 +1244,7 @@ u_long get_sclk(void)  	cached_sclk = get_vco() / ssel;  	return cached_sclk; +#endif  }  EXPORT_SYMBOL(get_sclk); @@ -1174,7 +1320,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)  			seq_printf(m, "(Compiled for Rev %d)", bfin_compiled_revid());  	} -	seq_printf(m, "\ncpu MHz\t\t: %lu.%03lu/%lu.%03lu\n", +	seq_printf(m, "\ncpu MHz\t\t: %lu.%06lu/%lu.%06lu\n",  		cclk/1000000, cclk%1000000,  		sclk/1000000, sclk%1000000);  	seq_printf(m, "bogomips\t: %lu.%02lu\n" @@ -1246,12 +1392,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)  		   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,  		   BFIN_DLINES);  #ifdef __ARCH_SYNC_CORE_DCACHE -	seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", dcache_invld_count[cpu_num]); +	seq_printf(m, "dcache flushes\t: %lu\n", dcache_invld_count[cpu_num]);  #endif  #ifdef __ARCH_SYNC_CORE_ICACHE -	seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", icache_invld_count[cpu_num]); +	seq_printf(m, "icache flushes\t: %lu\n", icache_invld_count[cpu_num]);  #endif +	seq_printf(m, "\n"); +  	if (cpu_num != num_possible_cpus() - 1)  		return 0; @@ -1275,13 +1423,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)  			      " in data cache\n");  	}  	seq_printf(m, "board name\t: %s\n", bfin_board_name); -	seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n", -		 physical_mem_end >> 10, (void *)0, (void *)physical_mem_end); -	seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n", +	seq_printf(m, "board memory\t: %ld kB (0x%08lx -> 0x%08lx)\n", +		physical_mem_end >> 10, 0ul, physical_mem_end); +	seq_printf(m, "kernel memory\t: %d kB (0x%08lx -> 0x%08lx)\n",  		((int)memory_end - (int)_rambase) >> 10, -		(void *)_rambase, -		(void *)memory_end); -	seq_printf(m, "\n"); +		_rambase, memory_end);  	return 0;  } @@ -1289,7 +1435,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)  static void *c_start(struct seq_file *m, loff_t *pos)  {  	if (*pos == 0) -		*pos = first_cpu(cpu_online_map); +		*pos = cpumask_first(cpu_online_mask);  	if (*pos >= num_online_cpus())  		return NULL; @@ -1298,7 +1444,7 @@ static void *c_start(struct seq_file *m, loff_t *pos)  static void *c_next(struct seq_file *m, void *v, loff_t *pos)  { -	*pos = next_cpu(*pos, cpu_online_map); +	*pos = cpumask_next(*pos, cpu_online_mask);  	return c_start(m, pos);  } diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c index 557e9fef406..aeb8343eeb0 100644 --- a/arch/blackfin/kernel/shadow_console.c +++ b/arch/blackfin/kernel/shadow_console.c @@ -15,9 +15,9 @@  #include <asm/irq_handler.h>  #include <asm/early_printk.h> -#define SHADOW_CONSOLE_START		(0x500) -#define SHADOW_CONSOLE_END		(0x1000) -#define SHADOW_CONSOLE_MAGIC_LOC	(0x4F0) +#define SHADOW_CONSOLE_START		(CONFIG_PHY_RAM_BASE_ADDRESS + 0x500) +#define SHADOW_CONSOLE_END		(CONFIG_PHY_RAM_BASE_ADDRESS + 0x1000) +#define SHADOW_CONSOLE_MAGIC_LOC	(CONFIG_PHY_RAM_BASE_ADDRESS + 0x4F0)  #define SHADOW_CONSOLE_MAGIC		(0xDEADBEEF)  static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START; diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index d536f35d1f4..b022af6c48f 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -10,7 +10,6 @@  #include <linux/tty.h>  #include <linux/personality.h>  #include <linux/binfmts.h> -#include <linux/freezer.h>  #include <linux/uaccess.h>  #include <linux/tracehook.h> @@ -19,8 +18,6 @@  #include <asm/fixed_code.h>  #include <asm/syscall.h> -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -  /* Location of the trace bit in SYSCFG. */  #define TRACE_BITS 0x0001 @@ -40,11 +37,6 @@ struct rt_sigframe {  	struct ucontext uc;  }; -asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) -{ -	return do_sigaltstack(uss, uoss, rdusp()); -} -  static inline int  rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *pr0)  { @@ -85,9 +77,9 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p  	return err;  } -asmlinkage int do_rt_sigreturn(unsigned long __unused) +asmlinkage int sys_rt_sigreturn(void)  { -	struct pt_regs *regs = (struct pt_regs *)__unused; +	struct pt_regs *regs = current_pt_regs();  	unsigned long usp = rdusp();  	struct rt_sigframe *frame = (struct rt_sigframe *)(usp);  	sigset_t set; @@ -98,16 +90,12 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)  	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))  		goto badframe; -	sigdelsetmask(&set, ~_BLOCKABLE); -	spin_lock_irq(¤t->sighand->siglock); -	current->blocked = set; -	recalc_sigpending(); -	spin_unlock_irq(¤t->sighand->siglock); +	set_current_blocked(&set);  	if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))  		goto badframe; -	if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->usp) == -EFAULT) +	if (restore_altstack(&frame->uc.uc_stack))  		goto badframe;  	return r0; @@ -185,25 +173,27 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,  	/* Create the ucontext.  */  	err |= __put_user(0, &frame->uc.uc_flags);  	err |= __put_user(0, &frame->uc.uc_link); -	err |= -	    __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); -	err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags); -	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); +	err |= __save_altstack(&frame->uc.uc_stack, rdusp());  	err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs);  	err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/* Set up registers for signal handler */ -	wrusp((unsigned long)frame);  	if (current->personality & FDPIC_FUNCPTRS) {  		struct fdpic_func_descriptor __user *funcptr =  			(struct fdpic_func_descriptor *) ka->sa.sa_handler; -		__get_user(regs->pc, &funcptr->text); -		__get_user(regs->p3, &funcptr->GOT); +		u32 pc, p3; +		err |= __get_user(pc, &funcptr->text); +		err |= __get_user(p3, &funcptr->GOT); +		if (err) +			return -EFAULT; +		regs->pc = pc; +		regs->p3 = p3;  	} else  		regs->pc = (unsigned long)ka->sa.sa_handler; +	wrusp((unsigned long)frame);  	regs->rets = SIGRETURN_STUB;  	regs->r0 = frame->sig; @@ -211,12 +201,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,  	regs->r2 = (unsigned long)(&frame->uc);  	return 0; - - give_sigsegv: -	if (sig == SIGSEGV) -		ka->sa.sa_handler = SIG_DFL; -	force_sig(SIGSEGV, current); -	return -EFAULT;  }  static inline void @@ -252,30 +236,21 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)  /*   * OK, we're invoking a handler   */ -static int +static void  handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, -	      sigset_t *oldset, struct pt_regs *regs) +	      struct pt_regs *regs)  { -	int ret; -  	/* are we from a system call? to see pt_regs->orig_p0 */  	if (regs->orig_p0 >= 0)  		/* If so, check system call restarting.. */  		handle_restart(regs, ka, 1);  	/* set up the stack frame */ -	ret = setup_rt_frame(sig, ka, info, oldset, regs); - -	if (ret == 0) { -		spin_lock_irq(¤t->sighand->siglock); -		sigorsets(¤t->blocked, ¤t->blocked, -			  &ka->sa.sa_mask); -		if (!(ka->sa.sa_flags & SA_NODEFER)) -			sigaddset(¤t->blocked, sig); -		recalc_sigpending(); -		spin_unlock_irq(¤t->sighand->siglock); -	} -	return ret; +	if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) +		force_sigsegv(sig, current); +	else  +		signal_delivered(sig, info, ka, regs, +				test_thread_flag(TIF_SINGLESTEP));  }  /* @@ -292,37 +267,16 @@ asmlinkage void do_signal(struct pt_regs *regs)  	siginfo_t info;  	int signr;  	struct k_sigaction ka; -	sigset_t *oldset;  	current->thread.esp0 = (unsigned long)regs; -	if (try_to_freeze()) -		goto no_signal; - -	if (test_thread_flag(TIF_RESTORE_SIGMASK)) -		oldset = ¤t->saved_sigmask; -	else -		oldset = ¤t->blocked; -  	signr = get_signal_to_deliver(&info, &ka, regs, NULL);  	if (signr > 0) {  		/* Whee!  Actually deliver the signal.  */ -		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { -			/* a signal was successfully delivered; the saved -			 * sigmask will have been stored in the signal frame, -			 * and will be restored by sigreturn, so we can simply -			 * clear the TIF_RESTORE_SIGMASK flag */ -			if (test_thread_flag(TIF_RESTORE_SIGMASK)) -				clear_thread_flag(TIF_RESTORE_SIGMASK); - -			tracehook_signal_handler(signr, &info, &ka, regs, -				test_thread_flag(TIF_SINGLESTEP)); -		} - +		handle_signal(signr, &info, &ka, regs);  		return;  	} - no_signal:  	/* Did we come from a system call? */  	if (regs->orig_p0 >= 0)  		/* Restart the system call - no handlers present */ @@ -330,10 +284,7 @@ asmlinkage void do_signal(struct pt_regs *regs)  	/* if there's no signal to deliver, we just put the saved sigmask  	 * back */ -	if (test_thread_flag(TIF_RESTORE_SIGMASK)) { -		clear_thread_flag(TIF_RESTORE_SIGMASK); -		sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); -	} +	restore_saved_sigmask();  }  /* @@ -341,14 +292,12 @@ asmlinkage void do_signal(struct pt_regs *regs)   */  asmlinkage void do_notify_resume(struct pt_regs *regs)  { -	if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK)) +	if (test_thread_flag(TIF_SIGPENDING))  		do_signal(regs);  	if (test_thread_flag(TIF_NOTIFY_RESUME)) {  		clear_thread_flag(TIF_NOTIFY_RESUME);  		tracehook_notify_resume(regs); -		if (current->replacement_session_keyring) -			key_replace_session_keyring();  	}  } diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index 89448ed7065..d998383cb95 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c @@ -41,6 +41,7 @@ asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)  #if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)  #include <linux/fb.h> +#include <linux/export.h>  unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr,  	unsigned long len, unsigned long pgoff, unsigned long flags)  { diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 8c9a43daf80..cb0a4845339 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -23,29 +23,6 @@  #include <asm/gptimers.h>  #include <asm/nmi.h> -/* Accelerators for sched_clock() - * convert from cycles(64bits) => nanoseconds (64bits) - *  basic equation: - *		ns = cycles / (freq / ns_per_sec) - *		ns = cycles * (ns_per_sec / freq) - *		ns = cycles * (10^9 / (cpu_khz * 10^3)) - *		ns = cycles * (10^6 / cpu_khz) - * - *	Then we use scaling math (suggested by george@mvista.com) to get: - *		ns = cycles * (10^6 * SC / cpu_khz) / SC - *		ns = cycles * cyc2ns_scale / SC - * - *	And since SC is a constant power of two, we can convert the div - *  into a shift. - * - *  We can use khz divisor instead of mhz to keep a better precision, since - *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. - *  (mathieu.desnoyers@polymtl.ca) - * - *			-johnstul@us.ibm.com "math is hard, lets go shopping!" - */ - -#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */  #if defined(CONFIG_CYCLES_CLOCKSOURCE) @@ -63,7 +40,6 @@ static struct clocksource bfin_cs_cycles = {  	.rating		= 400,  	.read		= bfin_read_cycles,  	.mask		= CLOCKSOURCE_MASK(64), -	.shift		= CYC2NS_SCALE_FACTOR,  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,  }; @@ -75,10 +51,7 @@ static inline unsigned long long bfin_cs_cycles_sched_clock(void)  static int __init bfin_cs_cycles_init(void)  { -	bfin_cs_cycles.mult = \ -		clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); - -	if (clocksource_register(&bfin_cs_cycles)) +	if (clocksource_register_hz(&bfin_cs_cycles, get_cclk()))  		panic("failed to register clocksource");  	return 0; @@ -93,8 +66,14 @@ void __init setup_gptimer0(void)  {  	disable_gptimers(TIMER0bit); +#ifdef CONFIG_BF60x +	bfin_write16(TIMER_DATA_IMSK, 0); +	set_gptimer_config(TIMER0_id,  TIMER_OUT_DIS +		| TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); +#else  	set_gptimer_config(TIMER0_id, \  		TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); +#endif  	set_gptimer_period(TIMER0_id, -1);  	set_gptimer_pwidth(TIMER0_id, -2);  	SSYNC(); @@ -111,7 +90,6 @@ static struct clocksource bfin_cs_gptimer0 = {  	.rating		= 350,  	.read		= bfin_read_gptimer0,  	.mask		= CLOCKSOURCE_MASK(32), -	.shift		= CYC2NS_SCALE_FACTOR,  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,  }; @@ -125,10 +103,7 @@ static int __init bfin_cs_gptimer0_init(void)  {  	setup_gptimer0(); -	bfin_cs_gptimer0.mult = \ -		clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0.shift); - -	if (clocksource_register(&bfin_cs_gptimer0)) +	if (clocksource_register_hz(&bfin_cs_gptimer0, get_sclk()))  		panic("failed to register clocksource");  	return 0; @@ -166,9 +141,15 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode,  {  	switch (mode) {  	case CLOCK_EVT_MODE_PERIODIC: { +#ifndef CONFIG_BF60x  		set_gptimer_config(TIMER0_id, \  			TIMER_OUT_DIS | TIMER_IRQ_ENA | \  			TIMER_PERIOD_CNT | TIMER_MODE_PWM); +#else +		set_gptimer_config(TIMER0_id,  TIMER_OUT_DIS +			| TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); +#endif +  		set_gptimer_period(TIMER0_id, get_sclk() / HZ);  		set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1);  		enable_gptimers(TIMER0bit); @@ -176,8 +157,14 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode,  	}  	case CLOCK_EVT_MODE_ONESHOT:  		disable_gptimers(TIMER0bit); +#ifndef CONFIG_BF60x  		set_gptimer_config(TIMER0_id, \  			TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); +#else +		set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM +			| TIMER_PULSE_HI | TIMER_IRQ_WID_DLY); +#endif +  		set_gptimer_period(TIMER0_id, 0);  		break;  	case CLOCK_EVT_MODE_UNUSED: @@ -191,7 +178,7 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode,  static void bfin_gptmr0_ack(void)  { -	set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); +	clear_gptimer_intr(TIMER0_id);  }  static void __init bfin_gptmr0_init(void) @@ -206,15 +193,20 @@ irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)  {  	struct clock_event_device *evt = dev_id;  	smp_mb(); -	evt->event_handler(evt); +	/* +	 * We want to ACK before we handle so that we can handle smaller timer +	 * intervals.  This way if the timer expires again while we're handling +	 * things, we're more likely to see that 2nd int rather than swallowing +	 * it by ACKing the int at the end of this handler. +	 */  	bfin_gptmr0_ack(); +	evt->event_handler(evt);  	return IRQ_HANDLED;  }  static struct irqaction gptmr0_irq = {  	.name		= "Blackfin GPTimer0", -	.flags		= IRQF_DISABLED | IRQF_TIMER | \ -			  IRQF_IRQPOLL | IRQF_PERCPU, +	.flags		= IRQF_TIMER | IRQF_IRQPOLL | IRQF_PERCPU,  	.handler	= bfin_gptmr0_interrupt,  }; @@ -223,7 +215,7 @@ static struct clock_event_device clockevent_gptmr0 = {  	.rating		= 300,  	.irq		= IRQ_TIMER0,  	.shift		= 32, -	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, +	.features 	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,  	.set_next_event = bfin_gptmr0_set_next_event,  	.set_mode	= bfin_gptmr0_set_mode,  }; @@ -245,7 +237,7 @@ static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)  #if defined(CONFIG_TICKSOURCE_CORETMR)  /* per-cpu local core timer */ -static DEFINE_PER_CPU(struct clock_event_device, coretmr_events); +DEFINE_PER_CPU(struct clock_event_device, coretmr_events);  static int bfin_coretmr_set_next_event(unsigned long cycles,  				struct clock_event_device *evt) @@ -307,6 +299,7 @@ void bfin_coretmr_init(void)  #ifdef CONFIG_CORE_TIMER_IRQ_L1  __attribute__((l1_text))  #endif +  irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)  {  	int cpu = smp_processor_id(); @@ -322,8 +315,7 @@ irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)  static struct irqaction coretmr_irq = {  	.name		= "Blackfin CoreTimer", -	.flags		= IRQF_DISABLED | IRQF_TIMER | \ -			  IRQF_IRQPOLL | IRQF_PERCPU, +	.flags		= IRQF_TIMER | IRQF_IRQPOLL | IRQF_PERCPU,  	.handler	= bfin_coretmr_interrupt,  }; @@ -333,6 +325,10 @@ void bfin_coretmr_clockevent_init(void)  	unsigned int cpu = smp_processor_id();  	struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); +#ifdef CONFIG_SMP +	evt->broadcast = smp_timer_broadcast; +#endif +  	evt->name = "bfin_core_timer";  	evt->rating = 350;  	evt->irq = -1; diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index c9113619029..3126b920a4a 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c @@ -25,7 +25,6 @@  static struct irqaction bfin_timer_irq = {  	.name = "Blackfin Timer Tick", -	.flags = IRQF_DISABLED  };  #if defined(CONFIG_IPIPE) @@ -51,7 +50,7 @@ void __init setup_core_timer(void)  	u32 tcount;  	/* power up the timer, but don't enable it just yet */ -	bfin_write_TCNTL(1); +	bfin_write_TCNTL(TMPWR);  	CSYNC();  	/* the TSCALE prescaler counter */ @@ -64,7 +63,7 @@ void __init setup_core_timer(void)  	/* now enable the timer */  	CSYNC(); -	bfin_write_TCNTL(7); +	bfin_write_TCNTL(TAUTORLD | TMREN | TMPWR);  }  #endif @@ -86,7 +85,7 @@ time_sched_init(irqreturn_t(*timer_routine) (int, void *))  /*   * Should return useconds since last timer tick   */ -u32 arch_gettimeoffset(void) +static u32 blackfin_gettimeoffset(void)  {  	unsigned long offset;  	unsigned long clocks_per_jiffy; @@ -114,16 +113,14 @@ u32 arch_gettimeoffset(void)  /*   * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick + * as well as call the "xtime_update()" routine every clocktick   */  #ifdef CONFIG_CORE_TIMER_IRQ_L1  __attribute__((l1_text))  #endif  irqreturn_t timer_interrupt(int irq, void *dummy)  { -	write_seqlock(&xtime_lock); -	do_timer(1); -	write_sequnlock(&xtime_lock); +	xtime_update(1);  #ifdef CONFIG_IPIPE  	update_root_process_times(get_irq_regs()); @@ -144,6 +141,10 @@ void read_persistent_clock(struct timespec *ts)  void __init time_init(void)  { +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET +	arch_gettimeoffset = blackfin_gettimeoffset; +#endif +  #ifdef CONFIG_RTC_DRV_BFIN  	/* [#2663] hack to filter junk RTC values that would cause  	 * userspace to have to deal with time values greater than diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 05b550891ce..c36efa0c716 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -10,6 +10,8 @@  #include <linux/hardirq.h>  #include <linux/thread_info.h>  #include <linux/mm.h> +#include <linux/oom.h> +#include <linux/sched.h>  #include <linux/uaccess.h>  #include <linux/module.h>  #include <linux/kallsyms.h> @@ -21,13 +23,13 @@  #include <asm/fixed_code.h>  #include <asm/traps.h>  #include <asm/irq_handler.h> +#include <asm/pda.h>  void decode_address(char *buf, unsigned long address)  {  	struct task_struct *p;  	struct mm_struct *mm; -	unsigned long flags, offset; -	unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); +	unsigned long offset;  	struct rb_node *n;  #ifdef CONFIG_KALLSYMS @@ -111,17 +113,17 @@ void decode_address(char *buf, unsigned long address)  	 * mappings of all our processes and see if we can't be a whee  	 * bit more specific  	 */ -	write_lock_irqsave(&tasklist_lock, flags); +	read_lock(&tasklist_lock);  	for_each_process(p) { -		mm = (in_atomic ? p->mm : get_task_mm(p)); -		if (!mm) -			continue; +		struct task_struct *t; -		if (!down_read_trylock(&mm->mmap_sem)) { -			if (!in_atomic) -				mmput(mm); +		t = find_lock_task_mm(p); +		if (!t)  			continue; -		} + +		mm = t->mm; +		if (!down_read_trylock(&mm->mmap_sem)) +			goto __continue;  		for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {  			struct vm_area_struct *vma; @@ -130,7 +132,7 @@ void decode_address(char *buf, unsigned long address)  			if (address >= vma->vm_start && address < vma->vm_end) {  				char _tmpbuf[256]; -				char *name = p->comm; +				char *name = t->comm;  				struct file *file = vma->vm_file;  				if (file) { @@ -163,8 +165,7 @@ void decode_address(char *buf, unsigned long address)  						name, vma->vm_start, vma->vm_end);  				up_read(&mm->mmap_sem); -				if (!in_atomic) -					mmput(mm); +				task_unlock(t);  				if (buf[0] == '\0')  					sprintf(buf, "[ %s ] dynamic memory", name); @@ -174,8 +175,8 @@ void decode_address(char *buf, unsigned long address)  		}  		up_read(&mm->mmap_sem); -		if (!in_atomic) -			mmput(mm); +__continue: +		task_unlock(t);  	}  	/* @@ -185,7 +186,7 @@ void decode_address(char *buf, unsigned long address)  	sprintf(buf, "/* kernel dynamic memory */");  done: -	write_unlock_irqrestore(&tasklist_lock, flags); +	read_unlock(&tasklist_lock);  }  #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) @@ -852,6 +853,8 @@ void show_regs(struct pt_regs *fp)  	unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();  	pr_notice("\n"); +	show_regs_print_info(KERN_NOTICE); +  	if (CPUID != bfin_cpuid())  		pr_notice("Compiled for cpu family 0x%04x (Rev %d), "  			"but running on:0x%04x (Rev %d)\n", @@ -912,10 +915,11 @@ void show_regs(struct pt_regs *fp)  	/* if no interrupts are going off, don't print this out */  	if (fp->ipend & ~0x3F) {  		for (i = 0; i < (NR_IRQS - 1); i++) { +			struct irq_desc *desc = irq_to_desc(i);  			if (!in_atomic) -				raw_spin_lock_irqsave(&irq_desc[i].lock, flags); +				raw_spin_lock_irqsave(&desc->lock, flags); -			action = irq_desc[i].action; +			action = desc->action;  			if (!action)  				goto unlock; @@ -928,7 +932,7 @@ void show_regs(struct pt_regs *fp)  			pr_cont("\n");  unlock:  			if (!in_atomic) -				raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); +				raw_spin_unlock_irqrestore(&desc->lock, flags);  		}  	} diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 59c1df75e4d..de5c2c3ebd9 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -17,6 +17,7 @@  #include <asm/trace.h>  #include <asm/fixed_code.h>  #include <asm/pseudo_instructions.h> +#include <asm/pda.h>  #ifdef CONFIG_KGDB  # include <linux/kgdb.h> @@ -98,7 +99,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)  	/* send the appropriate signal to the user program */  	switch (trapnr) { -	/* This table works in conjuction with the one in ./mach-common/entry.S +	/* This table works in conjunction with the one in ./mach-common/entry.S  	 * Some exceptions are handled there (in assembly, in exception space)  	 * Some are handled here, (in C, in interrupt space)  	 * Some, like CPLB, are handled in both, where the normal path is diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 4122678529c..c9eec84aa25 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -136,7 +136,7 @@ SECTIONS  	. = ALIGN(16);  	INIT_DATA_SECTION(16) -	PERCPU(4) +	PERCPU_SECTION(32)  	.exit.data :  	{ @@ -145,7 +145,7 @@ SECTIONS  	.text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data))  #else -	.init.data : AT(__data_lma + __data_len) +	.init.data : AT(__data_lma + __data_len + 32)  	{  		__sinitdata = .;  		INIT_DATA @@ -155,14 +155,9 @@ SECTIONS  		SECURITY_INITCALL  		INIT_RAM_FS -		. = ALIGN(4); +		. = ALIGN(PAGE_SIZE);  		___per_cpu_load = .; -		___per_cpu_start = .; -		*(.data.percpu.first) -		*(.data.percpu.page_aligned) -		*(.data.percpu) -		*(.data.percpu.shared_aligned) -		___per_cpu_end = .; +		PERCPU_INPUT(32)  		EXIT_DATA  		__einitdata = .; @@ -176,6 +171,7 @@ SECTIONS  	{  		. = ALIGN(4);  		__stext_l1 = .; +		*(.l1.text.head)  		*(.l1.text)  #ifdef CONFIG_SCHEDULE_L1  		SCHED_TEXT  | 
