Commit e0e170bd authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze

* 'next' of git://git.monstr.eu/linux-2.6-microblaze: (42 commits)
  microblaze: Fix build with make 3.82
  fbdev/xilinxfb: Microblaze driver support
  microblaze: Support C optimized lib functions for little-endian
  microblaze: Separate library optimized functions
  microblaze: Support timer on AXI lite
  microblaze: Add support for little-endian Microblaze
  microblaze: KGDB little endian support
  microblaze: Add PVR for endians plus detection
  net: emaclite: Add support for little-endian platforms
  microblaze: trivial: Add comment for AXI pvr
  microblaze: pci-common cleanup
  microblaze: Support early console on uart16550
  microblaze: Do not compile early console support for uartlite if is disabled
  microblaze: Setup early console dynamically
  microblaze: Rename all uartlite early printk functions
  microblaze: remove early printk uarlite console dependency from header
  microblaze: Remove additional compatible properties
  microblaze: Remove hardcoded asm instraction for PVR loading
  microblaze: Use static const char * const where possible
  microblaze: Define VMALLOC_START/END
  ...
parents b20f9e5b b843e4ec
......@@ -121,6 +121,23 @@ config CMDLINE_FORCE
Set this to have arguments from the default kernel command string
override those passed by the boot loader.
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
default y
help
This kernel feature is useful for number crunching applications
that may need to compute untrusted bytecode during their
execution. By using pipes or other transports made available to
the process as file descriptors supporting the read/write
syscalls, it's possible to isolate those applications in
their own address space using seccomp. Once seccomp is
enabled via /proc/<pid>/seccomp, it cannot be disabled
and the task is only allowed to execute a few safe syscalls
defined by each seccomp mode.
If unsure, say Y. Only embedded should say N here.
endmenu
menu "Advanced setup"
......
......@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"
config EARLY_PRINTK
bool "Early printk function for kernel"
depends on SERIAL_UARTLITE_CONSOLE
depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
default n
help
This option turns on/off early printk messages to console.
......
......@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
LDFLAGS :=
LDFLAGS_vmlinux :=
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
head-y := arch/microblaze/kernel/head.o
libs-y += arch/microblaze/lib/
libs-y += $(LIBGCC)
core-y += arch/microblaze/kernel/
core-y += arch/microblaze/mm/
core-y += arch/microblaze/platform/
......@@ -72,12 +69,16 @@ export MMU DTB
all: linux.bin
BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.%
# With make 3.82 we cannot mix normal and wildcard targets
BOOT_TARGETS1 = linux.bin linux.bin.gz
BOOT_TARGETS2 = simpleImage.%
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
$(BOOT_TARGETS): vmlinux
$(BOOT_TARGETS1): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
$(BOOT_TARGETS2): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
define archhelp
......
#ifndef _ASM_MICROBLAZE_BYTEORDER_H
#define _ASM_MICROBLAZE_BYTEORDER_H
#ifdef __MICROBLAZEEL__
#include <linux/byteorder/little_endian.h>
#else
#include <linux/byteorder/big_endian.h>
#endif
#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
......@@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
"addc %0, %0, %3\n\t"
"addc %0, %0, r0\n\t"
: "+&d" (sum)
: "d" (saddr), "d" (daddr), "d" (len + proto));
: "d" (saddr), "d" (daddr),
#ifdef __MICROBLAZEEL__
"d" ((len + proto) << 8)
#else
"d" (len + proto)
#endif
);
return sum;
}
......
......@@ -38,6 +38,7 @@ struct cpuinfo {
u32 use_exc;
u32 ver_code;
u32 mmu;
u32 endian;
/* CPU caches */
u32 use_icache;
......@@ -76,7 +77,6 @@ struct cpuinfo {
u32 num_rd_brk;
u32 num_wr_brk;
u32 cpu_clock_freq; /* store real freq of cpu */
u32 freq_div_hz; /* store freq/HZ */
/* FPGA family */
u32 fpga_family_code;
......@@ -97,7 +97,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
static inline unsigned int fcpu(struct device_node *cpu, char *n)
{
int *val;
return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
return (val = (int *) of_get_property(cpu, n, NULL)) ?
be32_to_cpup(val) : 0;
}
#endif /* _ASM_MICROBLAZE_CPUINFO_H */
......@@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_ET_DYN_BASE (0x08000000)
#ifdef __LITTLE_ENDIAN__
#ifdef __MICROBLAZEEL__
#define ELF_DATA ELFDATA2LSB
#else
#define ELF_DATA ELFDATA2MSB
......
......@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
return __gpio_cansleep(gpio);
}
/*
* Not implemented, yet.
*/
static inline int gpio_to_irq(unsigned int gpio)
{
return -ENOSYS;
return __gpio_to_irq(gpio);
}
static inline int irq_to_gpio(unsigned int irq)
......
......@@ -243,6 +243,8 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
#define out_8(a, v) __raw_writeb((v), (a))
#define in_8(a) __raw_readb(a)
#define mmiowb()
#define ioport_map(port, nr) ((void __iomem *)(port))
#define ioport_unmap(addr)
......
......@@ -205,9 +205,6 @@ extern int page_is_ram(unsigned long pfn);
#define TOPHYS(addr) __virt_to_phys(addr)
#ifdef CONFIG_MMU
#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
#define WANT_PAGE_VIRTUAL 1 /* page alloc 2 relies on this */
#endif
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
......
......@@ -165,5 +165,7 @@ extern void __init xilinx_pci_init(void);
static inline void __init xilinx_pci_init(void) { return; }
#endif
#include <asm-generic/pci-dma-compat.h>
#endif /* __KERNEL__ */
#endif /* __ASM_MICROBLAZE_PCI_H */
......@@ -165,7 +165,8 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage)
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
#define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = page_address(pte))
#define pmd_populate(mm, pmd, pte) \
(pmd_val(*(pmd)) = (unsigned long)page_address(pte))
#define pmd_populate_kernel(mm, pmd, pte) \
(pmd_val(*(pmd)) = (unsigned long) (pte))
......
......@@ -57,6 +57,13 @@ static inline int pte_file(pte_t pte) { return 0; }
#define pgprot_noncached_wc(prot) prot
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
*/
#define VMALLOC_START 0
#define VMALLOC_END 0xffffffff
#else /* CONFIG_MMU */
#include <asm-generic/4level-fixup.h>
......
......@@ -27,6 +27,7 @@
/* Other Prototypes */
extern int early_uartlite_console(void);
extern int early_uart16550_console(void);
#ifdef CONFIG_PCI
/*
......
......@@ -30,7 +30,9 @@ struct pvr_s {
#define PVR0_USE_EXC_MASK 0x04000000
#define PVR0_USE_ICACHE_MASK 0x02000000
#define PVR0_USE_DCACHE_MASK 0x01000000
#define PVR0_USE_MMU 0x00800000 /* new */
#define PVR0_USE_MMU 0x00800000
#define PVR0_USE_BTC 0x00400000
#define PVR0_ENDI 0x00200000
#define PVR0_VERSION_MASK 0x0000FF00
#define PVR0_USER1_MASK 0x000000FF
......@@ -38,9 +40,9 @@ struct pvr_s {
#define PVR1_USER2_MASK 0xFFFFFFFF
/* Configuration PVR masks */
#define PVR2_D_OPB_MASK 0x80000000
#define PVR2_D_OPB_MASK 0x80000000 /* or AXI */
#define PVR2_D_LMB_MASK 0x40000000
#define PVR2_I_OPB_MASK 0x20000000
#define PVR2_I_OPB_MASK 0x20000000 /* or AXI */
#define PVR2_I_LMB_MASK 0x10000000
#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
......@@ -63,8 +65,8 @@ struct pvr_s {
#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040
#define PVR2_UNALIGNED_EXC_MASK 0x00000020
#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010
#define PVR2_IOPB_BUS_EXC_MASK 0x00000008
#define PVR2_DOPB_BUS_EXC_MASK 0x00000004
#define PVR2_IOPB_BUS_EXC_MASK 0x00000008 /* or AXI */
#define PVR2_DOPB_BUS_EXC_MASK 0x00000004 /* or AXI */
#define PVR2_DIV_ZERO_EXC_MASK 0x00000002
#define PVR2_FPU_EXC_MASK 0x00000001
......@@ -208,6 +210,8 @@ struct pvr_s {
#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES)
/* endian */
#define PVR_ENDIAN(pvr) (pvr.pvr[0] & PVR0_ENDI)
int cpu_has_pvr(void);
void get_pvr(struct pvr_s *pvr);
......
#ifndef _ASM_MICROBLAZE_SECCOMP_H
#define _ASM_MICROBLAZE_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#endif /* _ASM_MICROBLAZE_SECCOMP_H */
......@@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...);
int setup_early_printk(char *opt);
void disable_early_printk(void);
#if defined(CONFIG_EARLY_PRINTK)
#define eprintk early_printk
#else
#define eprintk printk
#endif
void heartbeat(void);
void setup_heartbeat(void);
......
......@@ -127,23 +127,19 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SECCOMP 10 /* secure computing */
#define TIF_FREEZE 14 /* Freezing for suspend */
/* FIXME change in entry.S */
#define TIF_KERNEL_TRACE 8 /* kernel trace active */
/* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_POLLING_NRFLAG 16
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_IRET (1<<TIF_IRET)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_KERNEL_TRACE (1 << TIF_KERNEL_TRACE)
/* work to do in syscall trace */
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
......
......@@ -12,12 +12,18 @@
# ifdef __KERNEL__
# include <linux/unaligned/be_struct.h>
# include <linux/unaligned/be_byteshift.h>
# include <linux/unaligned/le_byteshift.h>
# include <linux/unaligned/generic.h>
# define get_unaligned __get_unaligned_be
# define put_unaligned __put_unaligned_be
# ifdef __MICROBLAZEEL__
# define get_unaligned __get_unaligned_le
# define put_unaligned __put_unaligned_le
# else
# define get_unaligned __get_unaligned_be
# define put_unaligned __put_unaligned_be
# endif
# endif /* __KERNEL__ */
#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
......@@ -383,8 +383,11 @@
#define __NR_rt_tgsigqueueinfo 365 /* new */
#define __NR_perf_event_open 366 /* new */
#define __NR_recvmmsg 367 /* new */
#define __NR_fanotify_init 368
#define __NR_fanotify_mark 369
#define __NR_prlimit64 370
#define __NR_syscalls 368
#define __NR_syscalls 371
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
......
......@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
CI(pvr_user2, USER2);
CI(mmu, USE_MMU);
CI(endian, ENDIAN);
CI(use_icache, USE_ICACHE);
CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
......
......@@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
ci->mmu = fcpu(cpu, "xlnx,use-mmu");
ci->endian = fcpu(cpu, "xlnx,endianness");
ci->ver_code = 0;
ci->fpga_family_code = 0;
......
......@@ -30,6 +30,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"7.20.c", 0x0e},
{"7.20.d", 0x0f},
{"7.30.a", 0x10},
{"7.30.b", 0x11},
{"8.00.a", 0x12},
{NULL, 0},
};
......
......@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
count = seq_printf(m,
"CPU-Family: MicroBlaze\n"
"FPGA-Arch: %s\n"
"CPU-Ver: %s\n"
"CPU-Ver: %s, %s endian\n"
"CPU-MHz: %d.%02d\n"
"BogoMips: %lu.%02lu\n",
fpga_family,
cpu_ver,
cpuinfo.endian ? "little" : "big",
cpuinfo.cpu_clock_freq /
1000000,
cpuinfo.cpu_clock_freq %
......
......@@ -27,7 +27,7 @@
register unsigned tmp __asm__("r3"); \
tmp = 0x0; /* Prevent warning about unused */ \
__asm__ __volatile__ ( \
".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \
"mfs %0, rpvr" #pvrid ";" \
: "=r" (tmp) : : "memory"); \
val = tmp; \
}
......
......@@ -24,7 +24,8 @@
static u32 early_console_initialized;
static u32 base_addr;
static void early_printk_putc(char c)
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
static void early_printk_uartlite_putc(char c)
{
/*
* Limit how many times we'll spin waiting for TX FIFO status.
......@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
out_be32(base_addr + 4, c & 0xff);
}
static void early_printk_write(struct console *unused,
static void early_printk_uartlite_write(struct console *unused,
const char *s, unsigned n)
{
while (*s && n-- > 0) {
early_printk_putc(*s);
early_printk_uartlite_putc(*s);
if (*s == '\n')
early_printk_putc('\r');
early_printk_uartlite_putc('\r');
s++;
}
}
static struct console early_serial_console = {
static struct console early_serial_uartlite_console = {
.name = "earlyser",
.write = early_printk_write,
.write = early_printk_uartlite_write,
.flags = CON_PRINTBUFFER,
.index = -1,
};
#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
static struct console *early_console = &early_serial_console;
#ifdef CONFIG_SERIAL_8250_CONSOLE
static void early_printk_uart16550_putc(char c)
{
/*
* Limit how many times we'll spin waiting for TX FIFO status.
* This will prevent lockups if the base address is incorrectly
* set, or any other issue on the UARTLITE.
* This limit is pretty arbitrary, unless we are at about 10 baud
* we'll never timeout on a working UART.
*/
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
unsigned retries = 10000;
while (--retries &&
!((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
;
if (retries)
out_be32(base_addr, c & 0xff);
}
static void early_printk_uart16550_write(struct console *unused,
const char *s, unsigned n)
{
while (*s && n-- > 0) {
early_printk_uart16550_putc(*s);
if (*s == '\n')
early_printk_uart16550_putc('\r');
s++;
}
}
static struct console early_serial_uart16550_console = {
.name = "earlyser",
.write = early_printk_uart16550_write,
.flags = CON_PRINTBUFFER,
.index = -1,
};
#endif /* CONFIG_SERIAL_8250_CONSOLE */
static struct console *early_console;
void early_printk(const char *fmt, ...)
{
......@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
if (early_console_initialized)
return 1;
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
base_addr = early_uartlite_console();
if (base_addr) {
early_console_initialized = 1;
#ifdef CONFIG_MMU
early_console_reg_tlb_alloc(base_addr);
#endif
early_console = &early_serial_uartlite_console;
early_printk("early_printk_console is enabled at 0x%08x\n",
base_addr);
/* register_console(early_console); */
return 0;
} else
return 1;
}
#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
#ifdef CONFIG_SERIAL_8250_CONSOLE
base_addr = early_uart16550_console();
base_addr &= ~3; /* clear register offset */
if (base_addr) {
early_console_initialized = 1;
#ifdef CONFIG_MMU
early_console_reg_tlb_alloc(base_addr);
#endif
early_console = &early_serial_uart16550_console;
early_printk("early_printk_console is enabled at 0x%08x\n",
base_addr);
/* register_console(early_console); */
return 0;
}
#endif /* CONFIG_SERIAL_8250_CONSOLE */
return 1;
}
void __init disable_early_printk(void)
......
......@@ -186,6 +186,8 @@
swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \
swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \
swi r15, r1, PTO+PT_R15; /* Save LP */ \
swi r16, r1, PTO+PT_R16; \
swi r17, r1, PTO+PT_R17; \
swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \
swi r19, r1, PTO+PT_R19; \
swi r20, r1, PTO+PT_R20; \
......@@ -220,6 +222,8 @@
lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \
lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
lwi r15, r1, PTO+PT_R15; /* restore LP */ \
lwi r16, r1, PTO+PT_R16; \
lwi r17, r1, PTO+PT_R17; \
lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \
lwi r19, r1, PTO+PT_R19; \
lwi r20, r1, PTO+PT_R20; \
......@@ -295,6 +299,8 @@ C_ENTRY(_user_exception):
/* addik r1, r1, -STATE_SAVE_SIZE; */
addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
SAVE_REGS
swi r0, r1, PTO + PT_R3
swi r0, r1, PTO + PT_R4
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
swi r11, r1, PTO+PT_R1; /* Store user SP. */
......@@ -458,14 +464,8 @@ C_ENTRY(sys_execve):
addik r8, r1, PTO; /* add user context as 4th arg */
C_ENTRY(sys_rt_sigreturn_wrapper):
swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
swi r4, r1, PTO+PT_R4;
brlid r15, sys_rt_sigreturn /* Do real work */
brid sys_rt_sigreturn /* Do real work */
addik r5, r1, PTO; /* add user context as 1st arg */
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
lwi r4, r1, PTO+PT_R4;
bri ret_from_trap /* fall through will not work here due to align */
nop;
/*
* HW EXCEPTION rutine start
......@@ -765,9 +765,7 @@ C_ENTRY(_debug_exception):
/* save all regs to pt_reg structure */
swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
swi r16, r1, PTO+PT_R16
swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
swi r17, r1, PTO+PT_R17
/* save special purpose registers to pt_regs */
mfs r11, rear;
swi r11, r1, PTO+PT_EAR;
......@@ -801,8 +799,6 @@ C_ENTRY(_debug_exception):
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
SAVE_REGS;
swi r17, r1, PTO+PT_R17;
swi r16, r1, PTO+PT_R16;
swi r16, r1, PTO+PT_PC; /* Save LP */
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
......@@ -848,8 +844,6 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
tophys(r1,r1);
/* MS: Restore all regs */
RESTORE_REGS
lwi r17, r1, PTO+PT_R17;
lwi r16, r1, PTO+PT_R16;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
DBTRAP_return_user: /* MS: Make global symbol for debugging */
......@@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
RESTORE_REGS
lwi r14, r1, PTO+PT_R14;
lwi r16, r1, PTO+PT_PC;
lwi r17, r1, PTO+PT_R17;
addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
tovirt(r1,r1);
DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
......
......@@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
int fsr, int addr)
{
#ifdef CONFIG_MMU
int code;
addr = regs->pc;
#endif
......@@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
switch (type & 0x1F) {
case MICROBLAZE_ILL_OPCODE_EXCEPTION:
if (user_mode(regs)) {
pr_debug(KERN_WARNING "Illegal opcode exception " \
"in user mode.\n");
pr_debug("Illegal opcode exception in user mode\n");
_exception(SIGILL, regs, ILL_ILLOPC, addr);
return;
}
......@@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
break;
case MICROBLAZE_IBUS_EXCEPTION:
if (user_mode(regs)) {
pr_debug(KERN_WARNING "Instruction bus error " \
"exception in user mode.\n");
pr_debug("Instruction bus error exception in user mode\n");
_exception(SIGBUS, regs, BUS_ADRERR, addr);
return;
}
......@@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
break;
case MICROBLAZE_DBUS_EXCEPTION:
if (user_mode(regs)) {
pr_debug(KERN_WARNING "Data bus error exception " \
"in user mode.\n");
pr_debug("Data bus error exception in user mode\n");
_exception(SIGBUS, regs, BUS_ADRERR, addr);
return;
}
......@@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
break;
case MICROBLAZE_DIV_ZERO_EXCEPTION:
if (user_mode(regs)) {
pr_debug(KERN_WARNING "Divide by zero exception " \
"in user mode\n");
pr_debug("Divide by zero exception in user mode\n");
_exception(SIGILL, regs, FPE_INTDIV, addr);
return;
}
......@@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
die("Divide by zero exception", regs, SIGBUS);
break;
case MICROBLAZE_FPU_EXCEPTION:
pr_debug(KERN_WARNING "FPU exception\n");
pr_debug("FPU exception\n");
/* IEEE FP exception */
/* I removed fsr variable and use code var for storing fsr */
if (fsr & FSR_IO)
......@@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
#ifdef CONFIG_MMU
case MICROBLAZE_PRIVILEGED_EXCEPTION:
pr_debug(KERN_WARNING "Privileged exception\n");
/* "brk r0,r0" - used as debug breakpoint - old toolchain */
if (get_user(code, (unsigned long *)regs->pc) == 0
&& code == 0x980c0000) {
_exception(SIGTRAP, regs, TRAP_BRKPT, addr);
} else {
_exception(SIGILL, regs, ILL_PRVOPC, addr);
}
pr_debug("Privileged exception\n");
_exception(SIGILL, regs, ILL_PRVOPC, addr);
break;
#endif
default:
......
......@@ -47,11 +47,10 @@ void setup_heartbeat(void)
struct device_node *gpio = NULL;
int *prop;
int j;
char *gpio_list[] = {
"xlnx,xps-gpio-1.00.a",
"xlnx,opb-gpio-1.00.a",
NULL
};
const char * const gpio_list[] = {
"xlnx,xps-gpio-1.00.a",
NULL
};
for (j = 0; gpio_list[j] != NULL; j++) {
gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
......@@ -60,7 +59,7 @@ void setup_heartbeat(void)
}
if (gpio) {
base_addr = *(int *) of_get_property(gpio, "reg", NULL);
base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
......
......@@ -126,11 +126,8 @@ void __init init_IRQ(void)
0
};
#endif
static char *intc_list[] = {
const char * const intc_list[] = {
"xlnx,xps-intc-1.00.a",
"xlnx,opb-intc-1.00.c",
"xlnx,opb-intc-1.00.b",
"xlnx,opb-intc-1.00.a",
NULL
};
......@@ -141,12 +138,15 @@ void __init init_IRQ(void)
}
BUG_ON(!intc);
intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
intc_baseaddr = be32_to_cpup(of_get_property(intc,
"reg", NULL));
intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
nr_irq = be32_to_cpup(of_get_property(intc,
"xlnx,num-intr-inputs", NULL));
intr_type =
*(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
be32_to_cpup(of_get_property(intc,
"xlnx,kind-of-intr", NULL));
if (intr_type >= (1 << (nr_irq + 1)))
printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
......
......@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
void microblaze_kgdb_break(struct pt_regs *regs)
{
if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
return 0;
return;
/* Jump over the first arch_kgdb_breakpoint which is barrier to
* get kgdb work. The same solution is used for powerpc */
......@@ -114,7 +114,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
{
char *ptr;
unsigned long address;
int cpu = smp_processor_id();
switch (remcom_in_buffer[0]) {
case 'c':
......@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
* Global data
*/
struct kgdb_arch arch_kgdb_ops = {
#ifdef __MICROBLAZEEL__
.gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
#else
.gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
#endif
};
......@@ -15,37 +15,13 @@
#include <linux/syscalls.h>
#include <asm/checksum.h>
#include <asm/cacheflush.h>
#include <linux/io.h>
#include <asm/page.h>
#include <asm/system.h>
#include <linux/ftrace.h>
#include <linux/uaccess.h>
/*
* libgcc functions - functions that are used internally by the
* compiler... (prototypes are not correct though, but that
* doesn't really matter since they're not versioned).
*/
extern void __ashldi3(void);
EXPORT_SYMBOL(__ashldi3);
extern void __ashrdi3(void);
EXPORT_SYMBOL(__ashrdi3);
extern void __divsi3(void);
EXPORT_SYMBOL(__divsi3);
extern void __lshrdi3(void);
EXPORT_SYMBOL(__lshrdi3);
extern void __modsi3(void);
EXPORT_SYMBOL(__modsi3);
extern void __mulsi3(void);
EXPORT_SYMBOL(__mulsi3);
extern void __muldi3(void);
EXPORT_SYMBOL(__muldi3);
extern void __ucmpdi2(void);
EXPORT_SYMBOL(__ucmpdi2);
extern void __udivsi3(void);
EXPORT_SYMBOL(__udivsi3);
extern void __umodsi3(void);
EXPORT_SYMBOL(__umodsi3);
extern char *_ebss;
EXPORT_SYMBOL_GPL(_ebss);
#ifdef CONFIG_FUNCTION_TRACER
......@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
#endif
#ifdef CONFIG_MMU
EXPORT_SYMBOL(empty_zero_page);
#endif
EXPORT_SYMBOL(mbc);
......@@ -72,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
/* find compatible node with uartlite */
p = of_get_flat_dt_prop(node, "compatible", &l);
if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
(strncmp(p, "xlnx,opb-uartlite", 17) != 0))
(strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
(strncmp(p, "xlnx,axi-uartlite", 17) != 0))
return 0;
addr = of_get_flat_dt_prop(node, "reg", &l);
return *addr; /* return address */
return be32_to_cpup(addr); /* return address */
}
/* this function is looking for early uartlite console - Microblaze specific */
......@@ -84,6 +85,40 @@ int __init early_uartlite_console(void)
{
return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
}
/* MS this is Microblaze specifig function */
static int __init early_init_dt_scan_serial_full(unsigned long node,
const char *uname, int depth, void *data)
{
unsigned long l;
char *p;
unsigned int addr;
pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
/* find all serial nodes */
if (strncmp(uname, "serial", 6) != 0)
return 0;
early_init_dt_check_for_initrd(node);
/* find compatible node with uartlite */
p = of_get_flat_dt_prop(node, "compatible", &l);
if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
(strncmp(p, "xlnx,axi-uart16550", 18) != 0))
return 0;
addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
return be32_to_cpu(addr); /* return address */
}
/* this function is looking for early uartlite console - Microblaze specific */
int __init early_uart16550_console(void)
{
return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
}
#endif
void __init early_init_devtree(void *params)
......
......@@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr)
}
#endif /* CONFIG_MTD_UCLINUX_EBSS */
#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
#define eprintk early_printk
#else
#define eprintk printk
#endif
void __init machine_early_init(const char *cmdline, unsigned int ram,
unsigned int fdt, unsigned int msr)
{
......
......@@ -372,3 +372,6 @@ ENTRY(sys_call_table)
.long sys_rt_tgsigqueueinfo /* 365 */
.long sys_perf_event_open
.long sys_recvmmsg
.long sys_fanotify_init
.long sys_fanotify_mark
.long sys_prlimit64 /* 370 */
......@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
#define TIMER_BASE timer_baseaddr
#endif
unsigned int freq_div_hz;
unsigned int timer_clock_freq;
#define TCSR0 (0x00)
#define TLR0 (0x04)
#define TCR0 (0x08)
......@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
printk(KERN_INFO "%s: periodic\n", __func__);
microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
microblaze_timer0_start_periodic(freq_div_hz);
break;
case CLOCK_EVT_MODE_ONESHOT:
printk(KERN_INFO "%s: oneshot\n", __func__);
......@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
static __init void microblaze_clockevent_init(void)
{
clockevent_microblaze_timer.mult =
div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
div_sc(timer_clock_freq, NSEC_PER_SEC,
clockevent_microblaze_timer.shift);
clockevent_microblaze_timer.max_delta_ns =
clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
......@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
int __init init_microblaze_timecounter(void)
{
microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
microblaze_cc.shift);
timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
......@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
static int __init microblaze_clocksource_init(void)
{
clocksource_microblaze.mult =
clocksource_hz2mult(cpuinfo.cpu_clock_freq,
clocksource_hz2mult(timer_clock_freq,
clocksource_microblaze.shift);
if (clocksource_register(&clocksource_microblaze))
panic("failed to register clocksource");
......@@ -247,6 +250,7 @@ void __init time_init(void)
u32 irq, i = 0;
u32 timer_num = 1;
struct device_node *timer = NULL;
const void *prop;
#ifdef CONFIG_SELFMOD_TIMER
unsigned int timer_baseaddr = 0;
int arr_func[] = {
......@@ -258,12 +262,10 @@ void __init time_init(void)
0
};
#endif
char *timer_list[] = {
"xlnx,xps-timer-1.00.a",
"xlnx,opb-timer-1.00.b",
"xlnx,opb-timer-1.00.a",
NULL
};
const char * const timer_list[] = {
"xlnx,xps-timer-1.00.a",
NULL
};
for (i = 0; timer_list[i] != NULL; i++) {
timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
......@@ -272,13 +274,13 @@ void __init time_init(void)
}
BUG_ON(!timer);
timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
irq = *(int *) of_get_property(timer, "interrupts", NULL);
timer_num =
*(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
timer_num = be32_to_cpup(of_get_property(timer,
"xlnx,one-timer-only", NULL));
if (timer_num) {
printk(KERN_EMERG "Please enable two timers in HW\n");
eprintk(KERN_EMERG "Please enable two timers in HW\n");
BUG();
}
......@@ -288,7 +290,14 @@ void __init time_init(void)
printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
timer_list[i], timer_baseaddr, irq);
cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ;
/* If there is clock-frequency property than use it */
prop = of_get_property(timer, "clock-frequency", NULL);
if (prop)
timer_clock_freq = be32_to_cpup(prop);
else
timer_clock_freq = cpuinfo.cpu_clock_freq;
freq_div_hz = timer_clock_freq / HZ;
setup_irq(irq, &timer_irqaction);
#ifdef CONFIG_HEART_BEAT
......
......@@ -8,7 +8,6 @@
* for more details.
*/
OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
OUTPUT_ARCH(microblaze)
ENTRY(microblaze_start)
......@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
#include <asm-generic/vmlinux.lds.h>
#include <asm/thread_info.h>
#ifdef __MICROBLAZEEL__
jiffies = jiffies_64;
#else
jiffies = jiffies_64 + 4;
#endif
SECTIONS {
. = CONFIG_KERNEL_START;
......
......@@ -11,3 +11,13 @@ lib-y += memcpy.o memmove.o
endif
lib-y += uaccess_old.o
lib-y += ashldi3.o
lib-y += ashrdi3.o
lib-y += divsi3.o
lib-y += lshrdi3.o
lib-y += modsi3.o
lib-y += muldi3.o
lib-y += mulsi3.o
lib-y += udivsi3.o
lib-y += umodsi3.o
#include <linux/module.h>
#include "libgcc.h"
long long __ashldi3(long long u, word_type b)
{
DWunion uu, w;
word_type bm;
if (b == 0)
return u;
uu.ll = u;
bm = 32 - b;
if (bm <= 0) {
w.s.low = 0;
w.s.high = (unsigned int) uu.s.low << -bm;
} else {
const unsigned int carries = (unsigned int) uu.s.low >> bm;
w.s.low = (unsigned int) uu.s.low << b;
w.s.high = ((unsigned int) uu.s.high << b) | carries;
}
return w.ll;
}
EXPORT_SYMBOL(__ashldi3);
#include <linux/module.h>
#include "libgcc.h"
long long __ashrdi3(long long u, word_type b)
{
DWunion uu, w;
word_type bm;
if (b == 0)
return u;
uu.ll = u;
bm = 32 - b;
if (bm <= 0) {
/* w.s.high = 1..1 or 0..0 */
w.s.high =
uu.s.high >> 31;
w.s.low = uu.s.high >> -bm;
} else {
const unsigned int carries = (unsigned int) uu.s.high << bm;
w.s.high = uu.s.high >> b;
w.s.low = ((unsigned int) uu.s.low >> b) | carries;
}
return w.ll;
}
EXPORT_SYMBOL(__ashrdi3);
#include <linux/linkage.h>
/*
* Divide operation for 32 bit integers.
* Input : Dividend in Reg r5
* Divisor in Reg r6
* Output: Result in Reg r3
*/
.text
.globl __divsi3
.type __divsi3, @function
.ent __divsi3
__divsi3:
.frame r1, 0, r15
addik r1, r1, -16
swi r28, r1, 0
swi r29, r1, 4
swi r30, r1, 8
swi r31, r1, 12
beqi r6, div_by_zero /* div_by_zero - division error */
beqi r5, result_is_zero /* result is zero */
bgeid r5, r5_pos
xor r28, r5, r6 /* get the sign of the result */
rsubi r5, r5, 0 /* make r5 positive */
r5_pos:
bgei r6, r6_pos
rsubi r6, r6, 0 /* make r6 positive */
r6_pos:
addik r30, r0, 0 /* clear mod */
addik r3, r0, 0 /* clear div */
addik r29, r0, 32 /* initialize the loop count */
/* first part try to find the first '1' in the r5 */
div0:
blti r5, div2 /* this traps r5 == 0x80000000 */
div1:
add r5, r5, r5 /* left shift logical r5 */
bgtid r5, div1
addik r29, r29, -1
div2:
/* left shift logical r5 get the '1' into the carry */
add r5, r5, r5
addc r30, r30, r30 /* move that bit into the mod register */
rsub r31, r6, r30 /* try to subtract (r30 a r6) */
blti r31, mod_too_small
/* move the r31 to mod since the result was positive */
or r30, r0, r31
addik r3, r3, 1
mod_too_small:
addik r29, r29, -1
beqi r29, loop_end
add r3, r3, r3 /* shift in the '1' into div */
bri div2 /* div2 */
loop_end:
bgei r28, return_here
brid return_here
rsubi r3, r3, 0 /* negate the result */
div_by_zero:
result_is_zero:
or r3, r0, r0 /* set result to 0 */
return_here:
/* restore values of csrs and that of r3 and the divisor and the dividend */
lwi r28, r1, 0
lwi r29, r1, 4
lwi r30, r1, 8
lwi r31, r1, 12
rtsd r15, 8
addik r1, r1, 16
.size __divsi3, . - __divsi3
.end __divsi3
#ifndef __ASM_LIBGCC_H
#define __ASM_LIBGCC_H
#include <asm/byteorder.h>
typedef int word_type __attribute__ ((mode (__word__)));
#ifdef __BIG_ENDIAN
struct DWstruct {
int high, low;
};
#elif defined(__LITTLE_ENDIAN)
struct DWstruct {
int low, high;
};
#else
#error I feel sick.
#endif
typedef union {
struct DWstruct s;
long long ll;
} DWunion;
#endif /* __ASM_LIBGCC_H */
#include <linux/module.h>
#include "libgcc.h"
long long __lshrdi3(long long u, word_type b)
{
DWunion uu, w;
word_type bm;
if (b == 0)
return u;
uu.ll = u;
bm = 32 - b;
if (bm <= 0) {
w.s.high = 0;
w.s.low = (unsigned int) uu.s.high >> -bm;
} else {
const unsigned int carries = (unsigned int) uu.s.high << bm;
w.s.high = (unsigned int) uu.s.high >> b;
w.s.low = ((unsigned int) uu.s.low >> b) | carries;
}
return w.ll;
}
EXPORT_SYMBOL(__lshrdi3);
......@@ -33,17 +33,24 @@
#include <asm/system.h>
#ifdef __HAVE_ARCH_MEMCPY
#ifndef CONFIG_OPT_LIB_FUNCTION
void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
{
const char *src = v_src;
char *dst = v_dst;
#ifndef CONFIG_OPT_LIB_FUNCTION
/* Simple, byte oriented memcpy. */
while (c--)
*dst++ = *src++;
return v_dst;
#else
}
#else /* CONFIG_OPT_LIB_FUNCTION */
void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
{
const char *src = v_src;
char *dst = v_dst;
/* The following code tries to optimize the copy by using unsigned
* alignment. This will work fine if both source and destination are
* aligned on the same boundary. However, if they are aligned on
......@@ -86,7 +93,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x1: /* Unaligned - Off by 1 */
/* Word align the source */
i_src = (const void *) ((unsigned)src & ~3);
#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *i_src++ << 8;
......@@ -95,7 +102,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
*i_dst++ = buf_hold | value >> 24;
buf_hold = value << 8;
}
#else
/* Load the holding buffer */
buf_hold = (*i_src++ & 0xFFFFFF00) >>8;
for (; c >= 4; c -= 4) {
value = *i_src++;
*i_dst++ = buf_hold | ((value & 0xFF) << 24);
buf_hold = (value & 0xFFFFFF00) >>8;
}
#endif
/* Realign the source */
src = (const void *)i_src;
src -= 3;
......@@ -103,7 +119,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x2: /* Unaligned - Off by 2 */
/* Word align the source */
i_src = (const void *) ((unsigned)src & ~3);
#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *i_src++ << 16;
......@@ -112,7 +128,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
*i_dst++ = buf_hold | value >> 16;
buf_hold = value << 16;
}
#else
/* Load the holding buffer */
buf_hold = (*i_src++ & 0xFFFF0000 )>>16;
for (; c >= 4; c -= 4) {
value = *i_src++;
*i_dst++ = buf_hold | ((value & 0xFFFF)<<16);
buf_hold = (value & 0xFFFF0000) >>16;
}
#endif
/* Realign the source */
src = (const void *)i_src;
src -= 2;
......@@ -120,7 +145,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x3: /* Unaligned - Off by 3 */
/* Word align the source */
i_src = (const void *) ((unsigned)src & ~3);
#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *i_src++ << 24;
......@@ -129,7 +154,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
*i_dst++ = buf_hold | value >> 8;
buf_hold = value << 24;
}
#else
/* Load the holding buffer */
buf_hold = (*i_src++ & 0xFF000000) >> 24;
for (; c >= 4; c -= 4) {
value = *i_src++;
*i_dst++ = buf_hold | ((value & 0xFFFFFF) << 8);
buf_hold = (value & 0xFF000000) >> 24;
}
#endif
/* Realign the source */
src = (const void *)i_src;
src -= 1;
......@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
}
return v_dst;
#endif
}
#endif /* CONFIG_OPT_LIB_FUNCTION */
EXPORT_SYMBOL(memcpy);
#endif /* __HAVE_ARCH_MEMCPY */
......@@ -31,16 +31,12 @@
#include <linux/string.h>
#ifdef __HAVE_ARCH_MEMMOVE
#ifndef CONFIG_OPT_LIB_FUNCTION
void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
{
const char *src = v_src;
char *dst = v_dst;
#ifdef CONFIG_OPT_LIB_FUNCTION
const uint32_t *i_src;
uint32_t *i_dst;
#endif
if (!c)
return v_dst;
......@@ -48,7 +44,6 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
if (v_dst <= v_src)
return memcpy(v_dst, v_src, c);
#ifndef CONFIG_OPT_LIB_FUNCTION
/* copy backwards, from end to beginning */
src += c;
dst += c;
......@@ -58,7 +53,22 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--dst = *--src;
return v_dst;
#else
}
#else /* CONFIG_OPT_LIB_FUNCTION */
void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
{
const char *src = v_src;
char *dst = v_dst;
const uint32_t *i_src;
uint32_t *i_dst;
if (!c)
return v_dst;
/* Use memcpy when source is higher than dest */
if (v_dst <= v_src)
return memcpy(v_dst, v_src, c);
/* The following code tries to optimize the copy by using unsigned
* alignment. This will work fine if both source and destination are
* aligned on the same boundary. However, if they are aligned on
......@@ -104,7 +114,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x1: /* Unaligned - Off by 1 */
/* Word align the source */
i_src = (const void *) (((unsigned)src + 4) & ~3);
#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *--i_src >> 24;
......@@ -113,7 +123,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--i_dst = buf_hold << 8 | value;
buf_hold = value >> 24;
}
#else
/* Load the holding buffer */
buf_hold = (*--i_src & 0xFF) << 24;
for (; c >= 4; c -= 4) {
value = *--i_src;
*--i_dst = buf_hold | ((value & 0xFFFFFF00)>>8);
buf_hold = (value & 0xFF) << 24;
}
#endif
/* Realign the source */
src = (const void *)i_src;
src += 1;
......@@ -121,7 +140,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x2: /* Unaligned - Off by 2 */
/* Word align the source */
i_src = (const void *) (((unsigned)src + 4) & ~3);
#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *--i_src >> 16;
......@@ -130,7 +149,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--i_dst = buf_hold << 16 | value;
buf_hold = value >> 16;
}
#else
/* Load the holding buffer */
buf_hold = (*--i_src & 0xFFFF) << 16;
for (; c >= 4; c -= 4) {
value = *--i_src;
*--i_dst = buf_hold | ((value & 0xFFFF0000)>>16);
buf_hold = (value & 0xFFFF) << 16;
}
#endif
/* Realign the source */
src = (const void *)i_src;
src += 2;
......@@ -138,7 +166,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x3: /* Unaligned - Off by 3 */
/* Word align the source */
i_src = (const void *) (((unsigned)src + 4) & ~3);
#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *--i_src >> 8;
......@@ -147,7 +175,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--i_dst = buf_hold << 24 | value;
buf_hold = value >> 8;
}
#else
/* Load the holding buffer */
buf_hold = (*--i_src & 0xFFFFFF) << 8;
for (; c >= 4; c -= 4) {
value = *--i_src;
*--i_dst = buf_hold | ((value & 0xFF000000)>> 24);
buf_hold = (value & 0xFFFFFF) << 8;;
}
#endif
/* Realign the source */
src = (const void *)i_src;
src += 3;
......@@ -169,7 +206,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--dst = *--src;
}
return v_dst;
#endif
}
#endif /* CONFIG_OPT_LIB_FUNCTION */
EXPORT_SYMBOL(memmove);
#endif /* __HAVE_ARCH_MEMMOVE */
......@@ -31,17 +31,30 @@
#include <linux/string.h>
#ifdef __HAVE_ARCH_MEMSET
#ifndef CONFIG_OPT_LIB_FUNCTION
void *memset(void *v_src, int c, __kernel_size_t n)
{
char *src = v_src;
/* Truncate c to 8 bits */
c = (c & 0xFF);
/* Simple, byte oriented memset or the rest of count. */
while (n--)
*src++ = c;
return v_src;
}
#else /* CONFIG_OPT_LIB_FUNCTION */
void *memset(void *v_src, int c, __kernel_size_t n)
{
char *src = v_src;
#ifdef CONFIG_OPT_LIB_FUNCTION
uint32_t *i_src;
uint32_t w32 = 0;
#endif
/* Truncate c to 8 bits */
c = (c & 0xFF);
#ifdef CONFIG_OPT_LIB_FUNCTION
if (unlikely(c)) {
/* Make a repeating word out of it */
w32 = c;
......@@ -72,12 +85,13 @@ void *memset(void *v_src, int c, __kernel_size_t n)
src = (void *)i_src;
}
#endif
/* Simple, byte oriented memset or the rest of count. */
while (n--)
*src++ = c;
return v_src;
}
#endif /* CONFIG_OPT_LIB_FUNCTION */
EXPORT_SYMBOL(memset);
#endif /* __HAVE_ARCH_MEMSET */
#include <linux/linkage.h>
/*
* modulo operation for 32 bit integers.
* Input : op1 in Reg r5
* op2 in Reg r6
* Output: op1 mod op2 in Reg r3
*/
.text
.globl __modsi3
.type __modsi3, @function
.ent __modsi3
__modsi3:
.frame r1, 0, r15
addik r1, r1, -16
swi r28, r1, 0
swi r29, r1, 4
swi r30, r1, 8
swi r31, r1, 12
beqi r6, div_by_zero /* div_by_zero division error */
beqi r5, result_is_zero /* result is zero */
bgeid r5, r5_pos
/* get the sign of the result [ depends only on the first arg] */
add r28, r5, r0
rsubi r5, r5, 0 /* make r5 positive */
r5_pos:
bgei r6, r6_pos
rsubi r6, r6, 0 /* make r6 positive */
r6_pos:
addik r3, r0, 0 /* clear mod */
addik r30, r0, 0 /* clear div */
addik r29, r0, 32 /* initialize the loop count */
/* first part try to find the first '1' in the r5 */
div1:
add r5, r5, r5 /* left shift logical r5 */
bgeid r5, div1
addik r29, r29, -1
div2:
/* left shift logical r5 get the '1' into the carry */
add r5, r5, r5
addc r3, r3, r3 /* move that bit into the mod register */
rsub r31, r6, r3 /* try to subtract (r30 a r6) */
blti r31, mod_too_small
/* move the r31 to mod since the result was positive */
or r3, r0, r31
addik r30, r30, 1
mod_too_small:
addik r29, r29, -1
beqi r29, loop_end
add r30, r30, r30 /* shift in the '1' into div */
bri div2 /* div2 */
loop_end:
bgei r28, return_here
brid return_here
rsubi r3, r3, 0 /* negate the result */
div_by_zero:
result_is_zero:
or r3, r0, r0 /* set result to 0 [both mod as well as div are 0] */
return_here:
/* restore values of csrs and that of r3 and the divisor and the dividend */
lwi r28, r1, 0
lwi r29, r1, 4
lwi r30, r1, 8
lwi r31, r1, 12
rtsd r15, 8
addik r1, r1, 16
.size __modsi3, . - __modsi3
.end __modsi3
#include <linux/linkage.h>
/*
* Multiply operation for 64 bit integers, for devices with hard multiply
* Input : Operand1[H] in Reg r5
* Operand1[L] in Reg r6
* Operand2[H] in Reg r7
* Operand2[L] in Reg r8
* Output: Result[H] in Reg r3
* Result[L] in Reg r4
*
* Explaination:
*
* Both the input numbers are divided into 16 bit number as follows
* op1 = A B C D
* op2 = E F G H
* result = D * H
* + (C * H + D * G) << 16
* + (B * H + C * G + D * F) << 32
* + (A * H + B * G + C * F + D * E) << 48
*
* Only 64 bits of the output are considered
*/
.text
.globl __muldi3
.type __muldi3, @function
.ent __muldi3
__muldi3:
addi r1, r1, -40
/* Save the input operands on the caller's stack */
swi r5, r1, 44
swi r6, r1, 48
swi r7, r1, 52
swi r8, r1, 56
/* Store all the callee saved registers */
sw r20, r1, r0
swi r21, r1, 4
swi r22, r1, 8
swi r23, r1, 12
swi r24, r1, 16
swi r25, r1, 20
swi r26, r1, 24
swi r27, r1, 28
/* Load all the 16 bit values for A thru H */
lhui r20, r1, 44 /* A */
lhui r21, r1, 46 /* B */
lhui r22, r1, 48 /* C */
lhui r23, r1, 50 /* D */
lhui r24, r1, 52 /* E */
lhui r25, r1, 54 /* F */
lhui r26, r1, 56 /* G */
lhui r27, r1, 58 /* H */
/* D * H ==> LSB of the result on stack ==> Store1 */
mul r9, r23, r27
swi r9, r1, 36 /* Pos2 and Pos3 */
/* Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2 */
/* Store the carry generated in position 2 for Pos 3 */
lhui r11, r1, 36 /* Pos2 */
mul r9, r22, r27 /* C * H */
mul r10, r23, r26 /* D * G */
add r9, r9, r10
addc r12, r0, r0
add r9, r9, r11
addc r12, r12, r0 /* Store the Carry */
shi r9, r1, 36 /* Store Pos2 */
swi r9, r1, 32
lhui r11, r1, 32
shi r11, r1, 34 /* Store Pos1 */
/* Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1 */
mul r9, r21, r27 /* B * H */
mul r10, r22, r26 /* C * G */
mul r7, r23, r25 /* D * F */
add r9, r9, r11
add r9, r9, r10
add r9, r9, r7
swi r9, r1, 32 /* Pos0 and Pos1 */
/* Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0 */
lhui r11, r1, 32 /* Pos0 */
mul r9, r20, r27 /* A * H */
mul r10, r21, r26 /* B * G */
mul r7, r22, r25 /* C * F */
mul r8, r23, r24 /* D * E */
add r9, r9, r11
add r9, r9, r10
add r9, r9, r7
add r9, r9, r8
sext16 r9, r9 /* Sign extend the MSB */
shi r9, r1, 32
/* Move results to r3 and r4 */
lhui r3, r1, 32
add r3, r3, r12
shi r3, r1, 32
lwi r3, r1, 32 /* Hi Part */
lwi r4, r1, 36 /* Lo Part */
/* Restore Callee saved registers */
lw r20, r1, r0
lwi r21, r1, 4
lwi r22, r1, 8
lwi r23, r1, 12
lwi r24, r1, 16
lwi r25, r1, 20
lwi r26, r1, 24
lwi r27, r1, 28
/* Restore Frame and return */
rtsd r15, 8
addi r1, r1, 40
.size __muldi3, . - __muldi3
.end __muldi3
#include <linux/linkage.h>
/*
* Multiply operation for 32 bit integers.
* Input : Operand1 in Reg r5
* Operand2 in Reg r6
* Output: Result [op1 * op2] in Reg r3
*/
.text
.globl __mulsi3
.type __mulsi3, @function
.ent __mulsi3
__mulsi3:
.frame r1, 0, r15
add r3, r0, r0
beqi r5, result_is_zero /* multiply by zero */
beqi r6, result_is_zero /* multiply by zero */
bgeid r5, r5_pos
xor r4, r5, r6 /* get the sign of the result */
rsubi r5, r5, 0 /* make r5 positive */
r5_pos:
bgei r6, r6_pos
rsubi r6, r6, 0 /* make r6 positive */
r6_pos:
bri l1
l2:
add r5, r5, r5
l1:
srl r6, r6
addc r7, r0, r0
beqi r7, l2
bneid r6, l2
add r3, r3, r5
blti r4, negateresult
rtsd r15, 8
nop
negateresult:
rtsd r15, 8
rsub r3, r3, r0
result_is_zero:
rtsd r15, 8
addi r3, r0, 0
.size __mulsi3, . - __mulsi3
.end __mulsi3
#include <linux/linkage.h>
/*
* Unsigned divide operation.
* Input : Divisor in Reg r5
* Dividend in Reg r6
* Output: Result in Reg r3
*/
.text
.globl __udivsi3
.type __udivsi3, @function
.ent __udivsi3
__udivsi3:
.frame r1, 0, r15
addik r1, r1, -12
swi r29, r1, 0
swi r30, r1, 4
swi r31, r1, 8
beqi r6, div_by_zero /* div_by_zero /* division error */
beqid r5, result_is_zero /* result is zero */
addik r30, r0, 0 /* clear mod */
addik r29, r0, 32 /* initialize the loop count */
/* check if r6 and r5 are equal - if yes, return 1 */
rsub r18, r5, r6
beqid r18, return_here
addik r3, r0, 1
/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */
xor r18, r5, r6
bgeid r18, 16
add r3, r0, r0 /* we would anyways clear r3 */
blti r6, return_here /* r6[bit 31 = 1] hence is greater */
bri checkr6
rsub r18, r6, r5 /* microblazecmp */
blti r18, return_here
/* if r6 [bit 31] is set, then return result as 1 */
checkr6:
bgti r6, div0
brid return_here
addik r3, r0, 1
/* first part try to find the first '1' in the r5 */
div0:
blti r5, div2
div1:
add r5, r5, r5 /* left shift logical r5 */
bgtid r5, div1
addik r29, r29, -1
div2:
/* left shift logical r5 get the '1' into the carry */
add r5, r5, r5
addc r30, r30, r30 /* move that bit into the mod register */
rsub r31, r6, r30 /* try to subtract (r30 a r6) */
blti r31, mod_too_small
/* move the r31 to mod since the result was positive */
or r30, r0, r31
addik r3, r3, 1
mod_too_small:
addik r29, r29, -1
beqi r29, loop_end
add r3, r3, r3 /* shift in the '1' into div */
bri div2 /* div2 */
loop_end:
bri return_here
div_by_zero:
result_is_zero:
or r3, r0, r0 /* set result to 0 */
return_here:
/* restore values of csrs and that of r3 and the divisor and the dividend */
lwi r29, r1, 0
lwi r30, r1, 4
lwi r31, r1, 8
rtsd r15, 8
addik r1, r1, 12
.size __udivsi3, . - __udivsi3
.end __udivsi3
#include <linux/linkage.h>
/*
* Unsigned modulo operation for 32 bit integers.
* Input : op1 in Reg r5
* op2 in Reg r6
* Output: op1 mod op2 in Reg r3
*/
.text
.globl __umodsi3
.type __umodsi3, @function
.ent __umodsi3
__umodsi3:
.frame r1, 0, r15
addik r1, r1, -12
swi r29, r1, 0
swi r30, r1, 4
swi r31, r1, 8
beqi r6, div_by_zero /* div_by_zero - division error */
beqid r5, result_is_zero /* result is zero */
addik r3, r0, 0 /* clear div */
addik r30, r0, 0 /* clear mod */
addik r29, r0, 32 /* initialize the loop count */
/* check if r6 and r5 are equal /* if yes, return 0 */
rsub r18, r5, r6
beqi r18, return_here
/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */
xor r18, r5, r6
bgeid r18, 16
addik r3, r5, 0
blti r6, return_here
bri $lcheckr6
rsub r18, r5, r6 /* microblazecmp */
bgti r18, return_here
/* if r6 [bit 31] is set, then return result as r5-r6 */
$lcheckr6:
bgtid r6, div0
addik r3, r0, 0
addik r18, r0, 0x7fffffff
and r5, r5, r18
and r6, r6, r18
brid return_here
rsub r3, r6, r5
/* first part: try to find the first '1' in the r5 */
div0:
blti r5, div2
div1:
add r5, r5, r5 /* left shift logical r5 */
bgeid r5, div1
addik r29, r29, -1
div2:
/* left shift logical r5 get the '1' into the carry */
add r5, r5, r5
addc r3, r3, r3 /* move that bit into the mod register */
rsub r31, r6, r3 /* try to subtract (r3 a r6) */
blti r31, mod_too_small
/* move the r31 to mod since the result was positive */
or r3, r0, r31
addik r30, r30, 1
mod_too_small:
addik r29, r29, -1
beqi r29, loop_end
add r30, r30, r30 /* shift in the '1' into div */
bri div2 /* div2 */
loop_end:
bri return_here
div_by_zero:
result_is_zero:
or r3, r0, r0 /* set result to 0 */
return_here:
/* restore values of csrs and that of r3 and the divisor and the dividend */
lwi r29, r1, 0
lwi r30, r1, 4
lwi r31, r1, 8
rtsd r15, 8
addik r1, r1, 12
.size __umodsi3, . - __umodsi3
.end __umodsi3
......@@ -60,21 +60,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
}
EXPORT_SYMBOL(get_pci_dma_ops);
int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
{
return dma_set_mask(&dev->dev, mask);
}
int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
{
int rc;
rc = dma_set_mask(&dev->dev, mask);
dev->dev.coherent_dma_mask = dev->dma_mask;
return rc;
}
struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
{
struct pci_controller *phb;
......@@ -1075,8 +1060,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
bus->number, bus->self ? pci_name(bus->self) : "PHB");
list_for_each_entry(dev, &bus->devices, bus_list) {
struct dev_archdata *sd = &dev->dev.archdata;
/* Setup OF node pointer in archdata */
dev->dev.of_node = pci_device_to_OF_node(dev);
......@@ -1086,8 +1069,8 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
/* Hook up default DMA ops */
sd->dma_ops = pci_dma_ops;
sd->dma_data = (void *)PCI_DRAM_OFFSET;
set_dma_ops(&dev->dev, pci_dma_ops);
dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;
/* Read default IRQs and fixup if necessary */
pci_read_irq_line(dev);
......
......@@ -85,6 +85,7 @@ microblaze_0: cpu@0 {
xlnx,dynamic-bus-sizing = <0x1>;
xlnx,edge-is-positive = <0x1>;
xlnx,family = "virtex5";
xlnx,endianness = <0x1>;
xlnx,fpu-exception = <0x1>;
xlnx,fsl-data-size = <0x20>;
xlnx,fsl-exception = <0x0>;
......@@ -218,6 +219,7 @@ Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,compound";
ranges ;
ethernet@81c00000 {
compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
device_type = "network";
......@@ -332,6 +334,7 @@ mpmc@90000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,mpmc-4.02.a";
ranges ;
PIM3: sdma@84600180 {
compatible = "xlnx,ll-dma-1.00.a";
interrupt-parent = <&xps_intc_0>;
......
......@@ -17,9 +17,6 @@
static struct of_device_id xilinx_of_bus_ids[] __initdata = {
{ .compatible = "simple-bus", },
{ .compatible = "xlnx,plb-v46-1.00.a", },
{ .compatible = "xlnx,opb-v20-1.10.c", },
{ .compatible = "xlnx,opb-v20-1.10.b", },
{ .compatible = "xlnx,compound", },
{}
};
......
......@@ -430,8 +430,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
}
/* Get the protocol type of the ethernet frame that arrived */
proto_type = ((in_be32(addr + XEL_HEADER_OFFSET +
XEL_RXBUFF_OFFSET) >> XEL_HEADER_SHIFT) &
proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET +
XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
XEL_RPLR_LENGTH_MASK);
/* Check if received ethernet frame is a raw ethernet frame
......@@ -439,9 +439,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
if (proto_type == ETH_P_IP) {
length = ((in_be32(addr +
length = ((ntohl(in_be32(addr +
XEL_HEADER_IP_LENGTH_OFFSET +
XEL_RXBUFF_OFFSET) >>
XEL_RXBUFF_OFFSET)) >>
XEL_HEADER_SHIFT) &
XEL_RPLR_LENGTH_MASK);
length += ETH_HLEN + ETH_FCS_LEN;
......
......@@ -32,10 +32,14 @@
#include <linux/dma-mapping.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/xilinxfb.h>
#include <linux/slab.h>
#ifdef CONFIG_PPC_DCR
#include <asm/dcr.h>
#endif
#define DRIVER_NAME "xilinxfb"
......@@ -123,10 +127,10 @@ struct xilinxfb_drvdata {
registers */
void __iomem *regs; /* virt. address of the control
registers */
#ifdef CONFIG_PPC_DCR
dcr_host_t dcr_host;
unsigned int dcr_len;
#endif
void *fb_virt; /* virt. address of the frame buffer */
dma_addr_t fb_phys; /* phys. address of the frame buffer */
int fb_alloced; /* Flag, was the fb memory alloced? */
......@@ -152,9 +156,10 @@ static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset,
{
if (drvdata->flags & PLB_ACCESS_FLAG)
out_be32(drvdata->regs + (offset << 2), val);
#ifdef CONFIG_PPC_DCR
else
dcr_write(drvdata->dcr_host, offset, val);
#endif
}
static int
......@@ -383,8 +388,11 @@ static int xilinxfb_release(struct device *dev)
if (drvdata->flags & PLB_ACCESS_FLAG) {
iounmap(drvdata->regs);
release_mem_region(drvdata->regs_phys, 8);
} else
}
#ifdef CONFIG_PPC_DCR
else
dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
#endif
kfree(drvdata);
dev_set_drvdata(dev, NULL);
......@@ -404,7 +412,7 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
u32 tft_access;
struct xilinxfb_platform_data pdata;
struct resource res;
int size, rc, start;
int size, rc;
struct xilinxfb_drvdata *drvdata;
/* Copy with the default pdata (not a ptr reference!) */
......@@ -437,7 +445,10 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
dev_err(&op->dev, "invalid address\n");
goto err;
}
} else {
}
#ifdef CONFIG_PPC_DCR
else {
int start;
res.start = 0;
start = dcr_resource_start(op->dev.of_node, 0);
drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0);
......@@ -447,6 +458,7 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
goto err;
}
}
#endif
prop = of_get_property(op->dev.of_node, "phys-size", &size);
if ((prop) && (size >= sizeof(u32)*2)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment