From 313819d4c25cdd46b42e85d70870b713bb9189ab Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 12 Jun 2012 12:04:29 +0200 Subject: ARM: remove linkup-l1110.h No file includes this header. Nothing seems interested in the things this header provides. It appears that it has never been included since at least v2.6.12-rc2. It can safely be removed. Signed-off-by: Paul Bolle Acked-by: Dmitry Artamonow Signed-off-by: Russell King diff --git a/arch/arm/include/asm/hardware/linkup-l1110.h b/arch/arm/include/asm/hardware/linkup-l1110.h deleted file mode 100644 index 7ec9116..0000000 --- a/arch/arm/include/asm/hardware/linkup-l1110.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* -* Definitions for H3600 Handheld Computer -* -* Copyright 2001 Compaq Computer Corporation. -* -* Use consistent with the GNU GPL is permitted, -* provided that this copyright notice is -* preserved in its entirety in all copies and derived works. -* -* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, -* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS -* FITNESS FOR ANY PARTICULAR PURPOSE. -* -* Author: Jamey Hicks. -* -*/ - -/* LinkUp Systems PCCard/CompactFlash Interface for SA-1100 */ - -/* PC Card Status Register */ -#define LINKUP_PRS_S1 (1 << 0) /* voltage control bits S1-S4 */ -#define LINKUP_PRS_S2 (1 << 1) -#define LINKUP_PRS_S3 (1 << 2) -#define LINKUP_PRS_S4 (1 << 3) -#define LINKUP_PRS_BVD1 (1 << 4) -#define LINKUP_PRS_BVD2 (1 << 5) -#define LINKUP_PRS_VS1 (1 << 6) -#define LINKUP_PRS_VS2 (1 << 7) -#define LINKUP_PRS_RDY (1 << 8) -#define LINKUP_PRS_CD1 (1 << 9) -#define LINKUP_PRS_CD2 (1 << 10) - -/* PC Card Command Register */ -#define LINKUP_PRC_S1 (1 << 0) -#define LINKUP_PRC_S2 (1 << 1) -#define LINKUP_PRC_S3 (1 << 2) -#define LINKUP_PRC_S4 (1 << 3) -#define LINKUP_PRC_RESET (1 << 4) -#define LINKUP_PRC_APOE (1 << 5) /* Auto Power Off Enable: clears S1-S4 when either nCD goes high */ -#define LINKUP_PRC_CFE (1 << 6) /* CompactFlash mode Enable: addresses A[10:0] only, A[25:11] high */ -#define LINKUP_PRC_SOE (1 << 7) /* signal output driver enable */ -#define LINKUP_PRC_SSP (1 << 8) /* sock select polarity: 0 for socket 0, 1 for socket 1 */ -#define LINKUP_PRC_MBZ (1 << 15) /* must be zero */ - -struct linkup_l1110 { - volatile short prc; -}; -- cgit v0.10.2 From 7f61d1e2b77a3c2c222a7ba5c751b63bfd5dbb37 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 12 Jun 2012 12:37:39 +0200 Subject: ARM: remove old SA-1111.h All (in tree) users of old mach/SA-1111.h were already updated to include asm/hardware/sa1111.h in v2.6.12-rc2. The old header can safely be removed now. Signed-off-by: Paul Bolle Signed-off-by: Russell King diff --git a/arch/arm/mach-sa1100/include/mach/SA-1111.h b/arch/arm/mach-sa1100/include/mach/SA-1111.h deleted file mode 100644 index c38f609..0000000 --- a/arch/arm/mach-sa1100/include/mach/SA-1111.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Moved to new location - */ -#warning using old SA-1111.h - update to -#include -- cgit v0.10.2 From c7530aac165ce3f43d3c32042692da52c9845e33 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 12 Jun 2012 14:49:46 +0200 Subject: ARM: pxa: remove eseries.h Commit e478fe4cd50b86e95fadc415438b63fa94060b7d ("[ARM] pxa: merge all eseries board code into eseries.c") removed all six files that included eseries.h. Everything that this header provides is now either local to eseries.c or entirely unused. It was apparently just an oversight to keep this header. This header can safely be removed. Signed-off-by: Paul Bolle Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h deleted file mode 100644 index b96949d..0000000 --- a/arch/arm/mach-pxa/eseries.h +++ /dev/null @@ -1,14 +0,0 @@ -void __init eseries_fixup(struct tag *tags, char **cmdline, struct meminfo *mi); - -extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info; -extern struct pxaficp_platform_data e7xx_ficp_platform_data; -extern int e7xx_irda_init(void); - -extern int eseries_tmio_enable(struct platform_device *dev); -extern int eseries_tmio_disable(struct platform_device *dev); -extern int eseries_tmio_suspend(struct platform_device *dev); -extern int eseries_tmio_resume(struct platform_device *dev); -extern void eseries_get_tmio_gpios(void); -extern struct resource eseries_tmio_resources[]; -extern struct platform_device e300_tc6387xb_device; - -- cgit v0.10.2 From c5dfdbe0c70c8c032a2962ccd51f163388def148 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 19 Jun 2012 12:46:27 +0200 Subject: ARM: sa1100: remove lart.h No file includes this header. It has never been included since at least v2.6.12-rc2. It can safely be removed. Signed-off-by: Paul Bolle Signed-off-by: Russell King diff --git a/arch/arm/mach-sa1100/include/mach/lart.h b/arch/arm/mach-sa1100/include/mach/lart.h deleted file mode 100644 index 8a5482d..0000000 --- a/arch/arm/mach-sa1100/include/mach/lart.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _INCLUDE_LART_H -#define _INCLUDE_LART_H - -#define LART_GPIO_ETH0 GPIO_GPIO0 -#define LART_IRQ_ETH0 IRQ_GPIO0 - -#define LART_GPIO_IDE GPIO_GPIO1 -#define LART_IRQ_IDE IRQ_GPIO1 - -#define LART_GPIO_UCB1200 GPIO_GPIO18 -#define LART_IRQ_UCB1200 IRQ_GPIO18 - -#endif -- cgit v0.10.2 From 5b7cc3df955cf510a0d4174553fe0410f9fbdd4a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 6 Aug 2012 18:55:28 +0100 Subject: ARM: 7485/1: EXYNOS: use SGI0 to wake secondary CPUs Signed-off-by: Stephen Boyd Acked-by: Kukjin Kim Signed-off-by: Russell King diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 36c3984..090e32b 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -139,7 +139,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) __raw_writel(virt_to_phys(exynos4_secondary_startup), CPU1_BOOT_REG); - gic_raise_softirq(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 0); if (pen_release == -1) break; -- cgit v0.10.2 From 7ac68a4c1de6aac5b0bb231fe6d8505ebe5686d9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Aug 2012 00:22:28 +0100 Subject: ARM: Allow arm_memblock_steal() to remove memory from any RAM region Allow arm_memblock_steal() to remove memory from any RAM region, including highmem areas. This allows memory to be stolen from the very top of declared memory, including highmem areas, rather than our precious lowmem. Acked-by: Sascha Hauer Acked-by: Santosh Shilimkar Signed-off-by: Russell King diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 9aec41f..ad722f1 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -324,7 +324,7 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align) BUG_ON(!arm_memblock_steal_permitted); - phys = memblock_alloc(size, align); + phys = memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ANYWHERE); memblock_free(phys, size); memblock_remove(phys, size); -- cgit v0.10.2 From 4a8052d8445a24771905d71d13f917146f9e822c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 15 Aug 2012 16:28:35 +0100 Subject: ARM: 7491/1: use generic version of identical asm headers Inspired by the AArgh64 claim that it should be separate from ARM and one reason was being able to use more asm-generic headers. Doing a diff of arch/arm/include/asm and include/asm-generic there are numerous asm headers which are functionally identical to their asm-generic counterparts. Delete the ARM version and use the generic ones. Signed-off-by: Rob Herring Reviewed-by: Nicolas Pitre Tested-by: Thomas Petazzoni Reviewed-by: Arnd Bergmann Signed-off-by: Russell King diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 960abce..6cc8a13 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -5,16 +5,31 @@ header-y += hwcap.h generic-y += auxvec.h generic-y += bitsperlong.h generic-y += cputime.h +generic-y += current.h generic-y += emergency-restart.h generic-y += errno.h +generic-y += exec.h generic-y += ioctl.h +generic-y += ipcbuf.h generic-y += irq_regs.h generic-y += kdebug.h generic-y += local.h generic-y += local64.h +generic-y += msgbuf.h +generic-y += param.h +generic-y += parport.h generic-y += percpu.h generic-y += poll.h generic-y += resource.h generic-y += sections.h +generic-y += segment.h +generic-y += sembuf.h +generic-y += serial.h +generic-y += shmbuf.h generic-y += siginfo.h generic-y += sizes.h +generic-y += socket.h +generic-y += sockios.h +generic-y += termbits.h +generic-y += timex.h +generic-y += types.h diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h deleted file mode 100644 index 75d21e2..0000000 --- a/arch/arm/include/asm/current.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _ASMARM_CURRENT_H -#define _ASMARM_CURRENT_H - -#include - -static inline struct task_struct *get_current(void) __attribute_const__; - -static inline struct task_struct *get_current(void) -{ - return current_thread_info()->task; -} - -#define current (get_current()) - -#endif /* _ASMARM_CURRENT_H */ diff --git a/arch/arm/include/asm/exec.h b/arch/arm/include/asm/exec.h deleted file mode 100644 index 7c4fbef..0000000 --- a/arch/arm/include/asm/exec.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_ARM_EXEC_H -#define __ASM_ARM_EXEC_H - -#define arch_align_stack(x) (x) - -#endif /* __ASM_ARM_EXEC_H */ diff --git a/arch/arm/include/asm/ipcbuf.h b/arch/arm/include/asm/ipcbuf.h deleted file mode 100644 index 84c7e51..0000000 --- a/arch/arm/include/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/arm/include/asm/msgbuf.h b/arch/arm/include/asm/msgbuf.h deleted file mode 100644 index 33b35b9..0000000 --- a/arch/arm/include/asm/msgbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _ASMARM_MSGBUF_H -#define _ASMARM_MSGBUF_H - -/* - * The msqid64_ds structure for arm architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct msqid64_ds { - struct ipc64_perm msg_perm; - __kernel_time_t msg_stime; /* last msgsnd time */ - unsigned long __unused1; - __kernel_time_t msg_rtime; /* last msgrcv time */ - unsigned long __unused2; - __kernel_time_t msg_ctime; /* last change time */ - unsigned long __unused3; - unsigned long msg_cbytes; /* current number of bytes on queue */ - unsigned long msg_qnum; /* number of messages in queue */ - unsigned long msg_qbytes; /* max number of bytes on queue */ - __kernel_pid_t msg_lspid; /* pid of last msgsnd */ - __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused4; - unsigned long __unused5; -}; - -#endif /* _ASMARM_MSGBUF_H */ diff --git a/arch/arm/include/asm/param.h b/arch/arm/include/asm/param.h deleted file mode 100644 index 8b24bf94..0000000 --- a/arch/arm/include/asm/param.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/arm/include/asm/param.h - * - * Copyright (C) 1995-1999 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PARAM_H -#define __ASM_PARAM_H - -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* User interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#else -# define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -/* max length of hostname */ -#define MAXHOSTNAMELEN 64 - -#endif - diff --git a/arch/arm/include/asm/parport.h b/arch/arm/include/asm/parport.h deleted file mode 100644 index 26e94b0..0000000 --- a/arch/arm/include/asm/parport.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/arm/include/asm/parport.h: ARM-specific parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef __ASMARM_PARPORT_H -#define __ASMARM_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASMARM_PARPORT_H) */ diff --git a/arch/arm/include/asm/segment.h b/arch/arm/include/asm/segment.h deleted file mode 100644 index 9e24c21..0000000 --- a/arch/arm/include/asm/segment.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __ASM_ARM_SEGMENT_H -#define __ASM_ARM_SEGMENT_H - -#define __KERNEL_CS 0x0 -#define __KERNEL_DS 0x0 - -#define __USER_CS 0x1 -#define __USER_DS 0x1 - -#endif /* __ASM_ARM_SEGMENT_H */ - diff --git a/arch/arm/include/asm/sembuf.h b/arch/arm/include/asm/sembuf.h deleted file mode 100644 index 1c02839..0000000 --- a/arch/arm/include/asm/sembuf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _ASMARM_SEMBUF_H -#define _ASMARM_SEMBUF_H - -/* - * The semid64_ds structure for arm architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct semid64_ds { - struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ - __kernel_time_t sem_otime; /* last semop time */ - unsigned long __unused1; - __kernel_time_t sem_ctime; /* last change time */ - unsigned long __unused2; - unsigned long sem_nsems; /* no. of semaphores in array */ - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _ASMARM_SEMBUF_H */ diff --git a/arch/arm/include/asm/serial.h b/arch/arm/include/asm/serial.h deleted file mode 100644 index ebb0490..0000000 --- a/arch/arm/include/asm/serial.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/include/asm/serial.h - * - * Copyright (C) 1996 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Changelog: - * 15-10-1996 RMK Created - */ - -#ifndef __ASM_SERIAL_H -#define __ASM_SERIAL_H - -#define BASE_BAUD (1843200 / 16) - -#endif diff --git a/arch/arm/include/asm/shmbuf.h b/arch/arm/include/asm/shmbuf.h deleted file mode 100644 index 2e5c67b..0000000 --- a/arch/arm/include/asm/shmbuf.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ASMARM_SHMBUF_H -#define _ASMARM_SHMBUF_H - -/* - * The shmid64_ds structure for arm architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct shmid64_ds { - struct ipc64_perm shm_perm; /* operation perms */ - size_t shm_segsz; /* size of segment (bytes) */ - __kernel_time_t shm_atime; /* last attach time */ - unsigned long __unused1; - __kernel_time_t shm_dtime; /* last detach time */ - unsigned long __unused2; - __kernel_time_t shm_ctime; /* last change time */ - unsigned long __unused3; - __kernel_pid_t shm_cpid; /* pid of creator */ - __kernel_pid_t shm_lpid; /* pid of last operator */ - unsigned long shm_nattch; /* no. of current attaches */ - unsigned long __unused4; - unsigned long __unused5; -}; - -struct shminfo64 { - unsigned long shmmax; - unsigned long shmmin; - unsigned long shmmni; - unsigned long shmseg; - unsigned long shmall; - unsigned long __unused1; - unsigned long __unused2; - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _ASMARM_SHMBUF_H */ diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h deleted file mode 100644 index 6433cad..0000000 --- a/arch/arm/include/asm/socket.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _ASMARM_SOCKET_H -#define _ASMARM_SOCKET_H - -#include - -/* For setsockopt(2) */ -#define SOL_SOCKET 1 - -#define SO_DEBUG 1 -#define SO_REUSEADDR 2 -#define SO_TYPE 3 -#define SO_ERROR 4 -#define SO_DONTROUTE 5 -#define SO_BROADCAST 6 -#define SO_SNDBUF 7 -#define SO_RCVBUF 8 -#define SO_SNDBUFFORCE 32 -#define SO_RCVBUFFORCE 33 -#define SO_KEEPALIVE 9 -#define SO_OOBINLINE 10 -#define SO_NO_CHECK 11 -#define SO_PRIORITY 12 -#define SO_LINGER 13 -#define SO_BSDCOMPAT 14 -/* To add :#define SO_REUSEPORT 15 */ -#define SO_PASSCRED 16 -#define SO_PEERCRED 17 -#define SO_RCVLOWAT 18 -#define SO_SNDLOWAT 19 -#define SO_RCVTIMEO 20 -#define SO_SNDTIMEO 21 - -/* Security levels - as per NRL IPv6 - don't actually do anything */ -#define SO_SECURITY_AUTHENTICATION 22 -#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 -#define SO_SECURITY_ENCRYPTION_NETWORK 24 - -#define SO_BINDTODEVICE 25 - -/* Socket filtering */ -#define SO_ATTACH_FILTER 26 -#define SO_DETACH_FILTER 27 - -#define SO_PEERNAME 28 -#define SO_TIMESTAMP 29 -#define SCM_TIMESTAMP SO_TIMESTAMP - -#define SO_ACCEPTCONN 30 - -#define SO_PEERSEC 31 -#define SO_PASSSEC 34 -#define SO_TIMESTAMPNS 35 -#define SCM_TIMESTAMPNS SO_TIMESTAMPNS - -#define SO_MARK 36 - -#define SO_TIMESTAMPING 37 -#define SCM_TIMESTAMPING SO_TIMESTAMPING - -#define SO_PROTOCOL 38 -#define SO_DOMAIN 39 - -#define SO_RXQ_OVFL 40 - -#define SO_WIFI_STATUS 41 -#define SCM_WIFI_STATUS SO_WIFI_STATUS -#define SO_PEEK_OFF 42 - -/* Instruct lower device to use last 4-bytes of skb data as FCS */ -#define SO_NOFCS 43 - -#endif /* _ASM_SOCKET_H */ diff --git a/arch/arm/include/asm/sockios.h b/arch/arm/include/asm/sockios.h deleted file mode 100644 index a2588a2..0000000 --- a/arch/arm/include/asm/sockios.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ARCH_ARM_SOCKIOS_H -#define __ARCH_ARM_SOCKIOS_H - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ -#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ - -#endif diff --git a/arch/arm/include/asm/termbits.h b/arch/arm/include/asm/termbits.h deleted file mode 100644 index 704135d..0000000 --- a/arch/arm/include/asm/termbits.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef __ASM_ARM_TERMBITS_H -#define __ASM_ARM_TERMBITS_H - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -struct termios2 { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -struct ktermios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define BOTHER 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define B460800 0010004 -#define B500000 0010005 -#define B576000 0010006 -#define B921600 0010007 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate */ -#define CMSPAR 010000000000 /* mark or space (stick) parity */ -#define CRTSCTS 020000000000 /* flow control */ - -#define IBSHIFT 16 - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 -#define EXTPROC 0200000 - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* __ASM_ARM_TERMBITS_H */ diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h index ce11944..5e71172 100644 --- a/arch/arm/include/asm/timex.h +++ b/arch/arm/include/asm/timex.h @@ -15,12 +15,10 @@ #include #include -typedef unsigned long cycles_t; - #ifdef ARCH_HAS_READ_CURRENT_TIMER #define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; }) -#else -#define get_cycles() (0) #endif +#include + #endif diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h deleted file mode 100644 index 28beab9..0000000 --- a/arch/arm/include/asm/types.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ASM_ARM_TYPES_H -#define __ASM_ARM_TYPES_H - -#include - -/* - * These aren't exported outside the kernel to avoid name space clashes - */ -#ifdef __KERNEL__ - -#define BITS_PER_LONG 32 - -#endif /* __KERNEL__ */ - -#endif - -- cgit v0.10.2 From ef1c2096fcf390f2f6a6a835d9d26105e82abda5 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 15 Aug 2012 16:28:36 +0100 Subject: ARM: 7492/1: add strstr declaration for decompressors With the generic unaligned.h, more kernel headers get pulled in including dynamic_debug.h which needs strstr. As it is not really used, we only need a declaration here. Signed-off-by: Rob Herring Tested-by: Thomas Petazzoni Reviewed-by: Arnd Bergmann Signed-off-by: Russell King diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index f41b38c..9deb56a 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -32,6 +32,9 @@ extern void error(char *); # define Tracecv(c,x) #endif +/* Not needed, but used in some headers pulled in by decompressors */ +extern char * strstr(const char * s1, const char *s2); + #ifdef CONFIG_KERNEL_GZIP #include "../../../../lib/decompress_inflate.c" #endif -- cgit v0.10.2 From d25c881aa3aeea447d0511e391a06c56783d173c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 15 Aug 2012 16:28:37 +0100 Subject: ARM: 7493/1: use generic unaligned.h This moves ARM over to the asm-generic/unaligned.h header. This has the benefit of better code generated especially for ARMv7 on gcc 4.7+ compilers. As Arnd Bergmann, points out: The asm-generic version uses the "struct" version for native-endian unaligned access and the "byteshift" version for the opposite endianess. The current ARM version however uses the "byteshift" implementation for both. Thanks to Nicolas Pitre for the excellent analysis: Test case: int foo (int *x) { return get_unaligned(x); } long long bar (long long *x) { return get_unaligned(x); } With the current ARM version: foo: ldrb r3, [r0, #2] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 2B], MEM[(const u8 *)x_1(D) + 2B] ldrb r1, [r0, #1] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 1B], MEM[(const u8 *)x_1(D) + 1B] ldrb r2, [r0, #0] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D)], MEM[(const u8 *)x_1(D)] mov r3, r3, asl #16 @ tmp154, MEM[(const u8 *)x_1(D) + 2B], ldrb r0, [r0, #3] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 3B], MEM[(const u8 *)x_1(D) + 3B] orr r3, r3, r1, asl #8 @, tmp155, tmp154, MEM[(const u8 *)x_1(D) + 1B], orr r3, r3, r2 @ tmp157, tmp155, MEM[(const u8 *)x_1(D)] orr r0, r3, r0, asl #24 @,, tmp157, MEM[(const u8 *)x_1(D) + 3B], bx lr @ bar: stmfd sp!, {r4, r5, r6, r7} @, mov r2, #0 @ tmp184, ldrb r5, [r0, #6] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 6B], MEM[(const u8 *)x_1(D) + 6B] ldrb r4, [r0, #5] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 5B], MEM[(const u8 *)x_1(D) + 5B] ldrb ip, [r0, #2] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 2B], MEM[(const u8 *)x_1(D) + 2B] ldrb r1, [r0, #4] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 4B], MEM[(const u8 *)x_1(D) + 4B] mov r5, r5, asl #16 @ tmp175, MEM[(const u8 *)x_1(D) + 6B], ldrb r7, [r0, #1] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 1B], MEM[(const u8 *)x_1(D) + 1B] orr r5, r5, r4, asl #8 @, tmp176, tmp175, MEM[(const u8 *)x_1(D) + 5B], ldrb r6, [r0, #7] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 7B], MEM[(const u8 *)x_1(D) + 7B] orr r5, r5, r1 @ tmp178, tmp176, MEM[(const u8 *)x_1(D) + 4B] ldrb r4, [r0, #0] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D)], MEM[(const u8 *)x_1(D)] mov ip, ip, asl #16 @ tmp188, MEM[(const u8 *)x_1(D) + 2B], ldrb r1, [r0, #3] @ zero_extendqisi2 @ MEM[(const u8 *)x_1(D) + 3B], MEM[(const u8 *)x_1(D) + 3B] orr ip, ip, r7, asl #8 @, tmp189, tmp188, MEM[(const u8 *)x_1(D) + 1B], orr r3, r5, r6, asl #24 @,, tmp178, MEM[(const u8 *)x_1(D) + 7B], orr ip, ip, r4 @ tmp191, tmp189, MEM[(const u8 *)x_1(D)] orr ip, ip, r1, asl #24 @, tmp194, tmp191, MEM[(const u8 *)x_1(D) + 3B], mov r1, r3 @, orr r0, r2, ip @ tmp171, tmp184, tmp194 ldmfd sp!, {r4, r5, r6, r7} bx lr In both cases the code is slightly suboptimal. One may wonder why wasting r2 with the constant 0 in the second case for example. And all the mov's could be folded in subsequent orr's, etc. Now with the asm-generic version: foo: ldr r0, [r0, #0] @ unaligned @,* x bx lr @ bar: mov r3, r0 @ x, x ldr r0, [r0, #0] @ unaligned @,* x ldr r1, [r3, #4] @ unaligned @, bx lr @ This is way better of course, but only because this was compiled for ARMv7. In this case the compiler knows that the hardware can do unaligned word access. This isn't that obvious for foo(), but if we remove the get_unaligned() from bar as follows: long long bar (long long *x) {return *x; } then the resulting code is: bar: ldmia r0, {r0, r1} @ x,, bx lr @ So this proves that the presumed aligned vs unaligned cases does have influence on the instructions the compiler may use and that the above unaligned code results are not just an accident. Still... this isn't fully conclusive without at least looking at the resulting assembly fron a pre ARMv6 compilation. Let's see with an ARMv5 target: foo: ldrb r3, [r0, #0] @ zero_extendqisi2 @ tmp139,* x ldrb r1, [r0, #1] @ zero_extendqisi2 @ tmp140, ldrb r2, [r0, #2] @ zero_extendqisi2 @ tmp143, ldrb r0, [r0, #3] @ zero_extendqisi2 @ tmp146, orr r3, r3, r1, asl #8 @, tmp142, tmp139, tmp140, orr r3, r3, r2, asl #16 @, tmp145, tmp142, tmp143, orr r0, r3, r0, asl #24 @,, tmp145, tmp146, bx lr @ bar: stmfd sp!, {r4, r5, r6, r7} @, ldrb r2, [r0, #0] @ zero_extendqisi2 @ tmp139,* x ldrb r7, [r0, #1] @ zero_extendqisi2 @ tmp140, ldrb r3, [r0, #4] @ zero_extendqisi2 @ tmp149, ldrb r6, [r0, #5] @ zero_extendqisi2 @ tmp150, ldrb r5, [r0, #2] @ zero_extendqisi2 @ tmp143, ldrb r4, [r0, #6] @ zero_extendqisi2 @ tmp153, ldrb r1, [r0, #7] @ zero_extendqisi2 @ tmp156, ldrb ip, [r0, #3] @ zero_extendqisi2 @ tmp146, orr r2, r2, r7, asl #8 @, tmp142, tmp139, tmp140, orr r3, r3, r6, asl #8 @, tmp152, tmp149, tmp150, orr r2, r2, r5, asl #16 @, tmp145, tmp142, tmp143, orr r3, r3, r4, asl #16 @, tmp155, tmp152, tmp153, orr r0, r2, ip, asl #24 @,, tmp145, tmp146, orr r1, r3, r1, asl #24 @,, tmp155, tmp156, ldmfd sp!, {r4, r5, r6, r7} bx lr Compared to the initial results, this is really nicely optimized and I couldn't do much better if I were to hand code it myself. Signed-off-by: Rob Herring Reviewed-by: Nicolas Pitre Tested-by: Thomas Petazzoni Reviewed-by: Arnd Bergmann Signed-off-by: Russell King diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 6cc8a13..a86cabf 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -33,3 +33,4 @@ generic-y += sockios.h generic-y += termbits.h generic-y += timex.h generic-y += types.h +generic-y += unaligned.h diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h deleted file mode 100644 index 44593a8..0000000 --- a/arch/arm/include/asm/unaligned.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ASM_ARM_UNALIGNED_H -#define _ASM_ARM_UNALIGNED_H - -#include -#include -#include - -/* - * Select endianness - */ -#ifndef __ARMEB__ -#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 /* _ASM_ARM_UNALIGNED_H */ -- cgit v0.10.2 From e780c452cfea10cbfae1c96dc16e506758138b6f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 15 Aug 2012 16:28:38 +0100 Subject: ARM: 7494/1: use generic termios.h As pointed out by Arnd Bergmann, this fixes a couple of issues but will increase code size: The original macro user_termio_to_kernel_termios was not endian safe. It used an unsigned short ptr to access the low bits in a 32-bit word. Both user_termio_to_kernel_termios and kernel_termios_to_user_termio are missing error checking on put_user/get_user and copy_to/from_user. Signed-off-by: Rob Herring Reviewed-by: Nicolas Pitre Tested-by: Thomas Petazzoni Reviewed-by: Arnd Bergmann Signed-off-by: Russell King diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index a86cabf..8a7196c 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -31,6 +31,7 @@ generic-y += sizes.h generic-y += socket.h generic-y += sockios.h generic-y += termbits.h +generic-y += termios.h generic-y += timex.h generic-y += types.h generic-y += unaligned.h diff --git a/arch/arm/include/asm/termios.h b/arch/arm/include/asm/termios.h deleted file mode 100644 index 293e3f1..0000000 --- a/arch/arm/include/asm/termios.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef __ASM_ARM_TERMIOS_H -#define __ASM_ARM_TERMIOS_H - -#include -#include - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -#ifdef __KERNEL__ -/* intr=^C quit=^| erase=del kill=^U - eof=^D vtime=\0 vmin=\1 sxtc=\0 - start=^Q stop=^S susp=^Z eol=\0 - reprint=^R discard=^U werase=^W lnext=^V - eol2=\0 -*/ -#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" -#endif - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ - unsigned short __tmp; \ - get_user(__tmp,&(termio)->x); \ - *(unsigned short *) &(termios)->x = __tmp; \ -} - -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) -#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* __KERNEL__ */ - -#endif /* __ASM_ARM_TERMIOS_H */ -- cgit v0.10.2 From 08928e7aea930e6822ce8f1b20068bf857ecf20d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 16 Aug 2012 18:43:04 +0100 Subject: ARM: 7495/1: mutex: use generic atomic_dec-based implementation for ARMv6+ Commit a76d7bd96d65 ("ARM: 7467/1: mutex: use generic xchg-based implementation for ARMv6+") removed the barrier-less, ARM-specific mutex implementation in favour of the generic xchg-based code. Since then, a bug was uncovered in the xchg code when running on SMP platforms, due to interactions between the locking paths and the MUTEX_SPIN_ON_OWNER code. This was fixed in 0bce9c46bf3b ("mutex: place lock in contended state after fastpath_lock failure"), however, the atomic_dec-based mutex algorithm is now marginally more efficient for ARM (~0.5% improvement in hackbench scores on dual A15). This patch moves ARMv6+ platforms to the atomic_dec-based mutex code. Acked-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h index b1479fd..87c0449 100644 --- a/arch/arm/include/asm/mutex.h +++ b/arch/arm/include/asm/mutex.h @@ -9,8 +9,13 @@ #define _ASM_MUTEX_H /* * On pre-ARMv6 hardware this results in a swp-based implementation, - * which is the most efficient. For ARMv6+, we emit a pair of exclusive - * accesses instead. + * which is the most efficient. For ARMv6+, we have exclusive memory + * accessors and use atomic_dec to avoid the extra xchg operations + * on the locking slowpaths. */ +#if __LINUX_ARM_ARCH__ < 6 #include +#else +#include #endif +#endif /* _ASM_MUTEX_H */ -- cgit v0.10.2 From e91d5d916f50ad2cf2394aba89d32833adce4303 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 22 Aug 2012 20:05:34 +0100 Subject: ARM: 7498/1: mach-shmobile: Use SGI0 to wake secondary CPUs Signed-off-by: Stephen Boyd Acked-by: Magnus Damm Signed-off-by: Russell King diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 6a35c4a..030558f 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -82,7 +82,7 @@ int __cpuinit emev2_boot_secondary(unsigned int cpu) /* Tell ROM loader about our vector (in headsmp.S) */ emev2_set_boot_vector(__pa(shmobile_secondary_vector)); - gic_raise_softirq(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 0); return 0; } -- cgit v0.10.2 From 195bbcac2e5c12f7fb99cdcc492c3000c5537f4a Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 24 Aug 2012 15:18:45 +0100 Subject: ARM: 7500/1: io: avoid writeback addressing modes for __raw_ accessors Data aborts taken to hyp mode do not provide a valid instruction syndrome field in the HSR if the faulting instruction is a memory access using a writeback addressing mode. For hypervisors emulating MMIO accesses to virtual peripherals, taking such an exception requires disassembling the faulting instruction in order to determine the behaviour of the access. Since this requires manually walking the two stages of translation, the world must be stopped to prevent races against page aging in the guest, where the first-stage translation is invalidated after the hypervisor has translated to an IPA and the physical page is reused for something else. This patch avoids taking this heavy performance penalty when running Linux as a guest by ensuring that our I/O accessors do not make use of writeback addressing modes. Cc: Marc Zyngier Reviewed-by: Arnd Bergmann Reviewed-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 815c669..09c4628 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -47,13 +47,68 @@ extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen); extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); -#define __raw_writeb(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))) -#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))) -#define __raw_writel(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))) +#if __LINUX_ARM_ARCH__ < 6 +/* + * Half-word accesses are problematic with RiscPC due to limitations of + * the bus. Rather than special-case the machine, just let the compiler + * generate the access for CPUs prior to ARMv6. + */ +#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) +#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))) +#else +/* + * When running under a hypervisor, we want to avoid I/O accesses with + * writeback addressing modes as these incur a significant performance + * overhead (the address generation must be emulated in software). + */ +static inline void __raw_writew(u16 val, volatile void __iomem *addr) +{ + asm volatile("strh %1, %0" + : "+Qo" (*(volatile u16 __force *)addr) + : "r" (val)); +} + +static inline u16 __raw_readw(const volatile void __iomem *addr) +{ + u16 val; + asm volatile("ldrh %1, %0" + : "+Qo" (*(volatile u16 __force *)addr), + "=r" (val)); + return val; +} +#endif -#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) -#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) -#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a)) +static inline void __raw_writeb(u8 val, volatile void __iomem *addr) +{ + asm volatile("strb %1, %0" + : "+Qo" (*(volatile u8 __force *)addr) + : "r" (val)); +} + +static inline void __raw_writel(u32 val, volatile void __iomem *addr) +{ + asm volatile("str %1, %0" + : "+Qo" (*(volatile u32 __force *)addr) + : "r" (val)); +} + +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ + u8 val; + asm volatile("ldrb %1, %0" + : "+Qo" (*(volatile u8 __force *)addr), + "=r" (val)); + return val; +} + +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ + u32 val; + asm volatile("ldr %1, %0" + : "+Qo" (*(volatile u32 __force *)addr), + "=r" (val)); + return val; +} /* * Architecture ioremap implementation. -- cgit v0.10.2 From 895576427dca617d0b1cc9dd2c450d82c58d67a9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Aug 2012 11:12:56 +0100 Subject: ARM: iMX: visstrim_m10: use arm_memblock_steal Use the provided function rather than re-coding this bit of code. This also gets us protection against using these functions from invalid contexts. Acked-by: Sascha Hauer Tested-by: Javier Martin Signed-off-by: Russell King diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index dff82eb..8036ad8 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -32,12 +32,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -219,10 +219,8 @@ static void __init visstrim_camera_init(void) static void __init visstrim_reserve(void) { /* reserve 4 MiB for mx2-camera */ - mx2_camera_base = memblock_alloc(MX2_CAMERA_BUF_SIZE, + mx2_camera_base = memblock_steal(MX2_CAMERA_BUF_SIZE, MX2_CAMERA_BUF_SIZE); - memblock_free(mx2_camera_base, MX2_CAMERA_BUF_SIZE); - memblock_remove(mx2_camera_base, MX2_CAMERA_BUF_SIZE); } /* GPIOs used as events for applications */ -- cgit v0.10.2 From 9fc31ddc70ac594b5a1d8a83303b65008221088c Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Aug 2012 11:16:59 +0100 Subject: ARM: Don't unconditionally bloat thread_info There is no point reserving space at the bottom of the kernel stack for per-thread crunch state, and per-thread VFP state if these are not being supported by the kernel being built. Remove these members from the thread union when these features are disabled. Reported-by: Tim Bird Signed-off-by: Russell King diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index b79f8e9..7b0a8f5 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -59,7 +59,9 @@ struct thread_info { __u32 syscall; /* syscall number */ __u8 used_cp[16]; /* thread used copro */ unsigned long tp_value; +#ifdef CONFIG_CRUNCH struct crunch_state crunchstate; +#endif union fp_state fpstate __attribute__((aligned(8))); union vfp_state vfpstate; #ifdef CONFIG_ARM_THUMBEE diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 1429d89..c985b48 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -59,10 +59,12 @@ int main(void) DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp)); DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); +#ifdef CONFIG_VFP DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); #ifdef CONFIG_SMP DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu)); #endif +#endif #ifdef CONFIG_ARM_THUMBEE DEFINE(TI_THUMBEE_STATE, offsetof(struct thread_info, thumbee_state)); #endif -- cgit v0.10.2 From a67e1ce145785d884b29b17e4d82a6ecd67bb97a Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 2 Sep 2012 09:17:09 +0100 Subject: ARM: Fix bad merge bd1274dc005 (Merge branch 'v6v7' into devel) Commit 774c096bf9e49 (ARM: v6/v7 cache: allow cache calls to be optimized) got dropped when the merge conflicts for moving the contents of the files in commit 753790e713d (ARM: move cache/processor/fault glue to separate include files) was fixed up in merge bd1274dc005 (Merge branch 'v6v7' into devel). This puts the change back. Signed-off-by: Russell King diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index 7e30874..4f8d2c0 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h @@ -110,19 +110,19 @@ #endif #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) -//# ifdef _CACHE +# ifdef _CACHE # define MULTI_CACHE 1 -//# else -//# define _CACHE v6 -//# endif +# else +# define _CACHE v6 +# endif #endif #if defined(CONFIG_CPU_V7) -//# ifdef _CACHE +# ifdef _CACHE # define MULTI_CACHE 1 -//# else -//# define _CACHE v7 -//# endif +# else +# define _CACHE v7 +# endif #endif #if !defined(_CACHE) && !defined(MULTI_CACHE) -- cgit v0.10.2 From aa783b6fd60b3844e199b1c2d2f4068f3caa1358 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sat, 1 Sep 2012 03:00:15 +0100 Subject: ARM: 7505/1: split out ATAGS parsing Make ATAGS parsing into a source file of its own, namely atags_parse.c. Also rename compat.c to atags_compat.c to make it clearer what it is about. Same for atags.c which is now atags_proc.c. Gather all the atags function declarations into a common atags.h. Signed-off-by: Nicolas Pitre Tested-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 7ad2d5c..086c9d3 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,11 +15,11 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ +obj-y := atags_parse.o elf.o entry-armv.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o sched_clock.o \ setup.o signal.o stacktrace.o sys_arm.o time.o traps.o -obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o +obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o obj-$(CONFIG_LEDS) += leds.o obj-$(CONFIG_OC_ETM) += etm.o @@ -52,7 +52,7 @@ test-kprobes-objs += kprobes-test-thumb.o else test-kprobes-objs += kprobes-test-arm.o endif -obj-$(CONFIG_ATAGS_PROC) += atags.o +obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c deleted file mode 100644 index 42a1a14..0000000 --- a/arch/arm/kernel/atags.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include -#include - -struct buffer { - size_t size; - char data[]; -}; - -static int -read_buffer(char* page, char** start, off_t off, int count, - int* eof, void* data) -{ - struct buffer *buffer = (struct buffer *)data; - - if (off >= buffer->size) { - *eof = 1; - return 0; - } - - count = min((int) (buffer->size - off), count); - - memcpy(page, &buffer->data[off], count); - - return count; -} - -#define BOOT_PARAMS_SIZE 1536 -static char __initdata atags_copy[BOOT_PARAMS_SIZE]; - -void __init save_atags(const struct tag *tags) -{ - memcpy(atags_copy, tags, sizeof(atags_copy)); -} - -static int __init init_atags_procfs(void) -{ - /* - * This cannot go into save_atags() because kmalloc and proc don't work - * yet when it is called. - */ - struct proc_dir_entry *tags_entry; - struct tag *tag = (struct tag *)atags_copy; - struct buffer *b; - size_t size; - - if (tag->hdr.tag != ATAG_CORE) { - printk(KERN_INFO "No ATAGs?"); - return -EINVAL; - } - - for (; tag->hdr.size; tag = tag_next(tag)) - ; - - /* include the terminating ATAG_NONE */ - size = (char *)tag - atags_copy + sizeof(struct tag_header); - - WARN_ON(tag->hdr.tag != ATAG_NONE); - - b = kmalloc(sizeof(*b) + size, GFP_KERNEL); - if (!b) - goto nomem; - - b->size = size; - memcpy(b->data, atags_copy, size); - - tags_entry = create_proc_read_entry("atags", 0400, - NULL, read_buffer, b); - - if (!tags_entry) - goto nomem; - - return 0; - -nomem: - kfree(b); - printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); - - return -ENOMEM; -} -arch_initcall(init_atags_procfs); diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index e5f028d..a888fdd 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h @@ -3,3 +3,6 @@ extern void save_atags(struct tag *tags); #else static inline void save_atags(struct tag *tags) { } #endif + +void convert_to_tag_list(struct tag *tags); +struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr); diff --git a/arch/arm/kernel/atags_compat.c b/arch/arm/kernel/atags_compat.c new file mode 100644 index 0000000..5236ad3 --- /dev/null +++ b/arch/arm/kernel/atags_compat.c @@ -0,0 +1,219 @@ +/* + * linux/arch/arm/kernel/atags_compat.c + * + * Copyright (C) 2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * We keep the old params compatibility cruft in one place (here) + * so we don't end up with lots of mess around other places. + * + * NOTE: + * The old struct param_struct is deprecated, but it will be kept in + * the kernel for 5 years from now (2001). This will allow boot loaders + * to convert to the new struct tag way. + */ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "atags.h" + +/* + * Usage: + * - do not go blindly adding fields, add them at the end + * - when adding fields, don't rely on the address until + * a patch from me has been released + * - unused fields should be zero (for future expansion) + * - this structure is relatively short-lived - only + * guaranteed to contain useful data in setup_arch() + * + * This is the old deprecated way to pass parameters to the kernel + */ +struct param_struct { + union { + struct { + unsigned long page_size; /* 0 */ + unsigned long nr_pages; /* 4 */ + unsigned long ramdisk_size; /* 8 */ + unsigned long flags; /* 12 */ +#define FLAG_READONLY 1 +#define FLAG_RDLOAD 4 +#define FLAG_RDPROMPT 8 + unsigned long rootdev; /* 16 */ + unsigned long video_num_cols; /* 20 */ + unsigned long video_num_rows; /* 24 */ + unsigned long video_x; /* 28 */ + unsigned long video_y; /* 32 */ + unsigned long memc_control_reg; /* 36 */ + unsigned char sounddefault; /* 40 */ + unsigned char adfsdrives; /* 41 */ + unsigned char bytes_per_char_h; /* 42 */ + unsigned char bytes_per_char_v; /* 43 */ + unsigned long pages_in_bank[4]; /* 44 */ + unsigned long pages_in_vram; /* 60 */ + unsigned long initrd_start; /* 64 */ + unsigned long initrd_size; /* 68 */ + unsigned long rd_start; /* 72 */ + unsigned long system_rev; /* 76 */ + unsigned long system_serial_low; /* 80 */ + unsigned long system_serial_high; /* 84 */ + unsigned long mem_fclk_21285; /* 88 */ + } s; + char unused[256]; + } u1; + union { + char paths[8][128]; + struct { + unsigned long magic; + char n[1024 - sizeof(unsigned long)]; + } s; + } u2; + char commandline[COMMAND_LINE_SIZE]; +}; + +static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size) +{ + tag = tag_next(tag); + tag->hdr.tag = ATAG_MEM; + tag->hdr.size = tag_size(tag_mem32); + tag->u.mem.size = size; + tag->u.mem.start = start; + + return tag; +} + +static void __init build_tag_list(struct param_struct *params, void *taglist) +{ + struct tag *tag = taglist; + + if (params->u1.s.page_size != PAGE_SIZE) { + printk(KERN_WARNING "Warning: bad configuration page, " + "trying to continue\n"); + return; + } + + printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); + +#ifdef CONFIG_ARCH_NETWINDER + if (params->u1.s.nr_pages != 0x02000 && + params->u1.s.nr_pages != 0x04000 && + params->u1.s.nr_pages != 0x08000 && + params->u1.s.nr_pages != 0x10000) { + printk(KERN_WARNING "Warning: bad NeTTrom parameters " + "detected, using defaults\n"); + + params->u1.s.nr_pages = 0x1000; /* 16MB */ + params->u1.s.ramdisk_size = 0; + params->u1.s.flags = FLAG_READONLY; + params->u1.s.initrd_start = 0; + params->u1.s.initrd_size = 0; + params->u1.s.rd_start = 0; + } +#endif + + tag->hdr.tag = ATAG_CORE; + tag->hdr.size = tag_size(tag_core); + tag->u.core.flags = params->u1.s.flags & FLAG_READONLY; + tag->u.core.pagesize = params->u1.s.page_size; + tag->u.core.rootdev = params->u1.s.rootdev; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_RAMDISK; + tag->hdr.size = tag_size(tag_ramdisk); + tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) | + (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0); + tag->u.ramdisk.size = params->u1.s.ramdisk_size; + tag->u.ramdisk.start = params->u1.s.rd_start; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_INITRD; + tag->hdr.size = tag_size(tag_initrd); + tag->u.initrd.start = params->u1.s.initrd_start; + tag->u.initrd.size = params->u1.s.initrd_size; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_SERIAL; + tag->hdr.size = tag_size(tag_serialnr); + tag->u.serialnr.low = params->u1.s.system_serial_low; + tag->u.serialnr.high = params->u1.s.system_serial_high; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_REVISION; + tag->hdr.size = tag_size(tag_revision); + tag->u.revision.rev = params->u1.s.system_rev; + +#ifdef CONFIG_ARCH_ACORN + if (machine_is_riscpc()) { + int i; + for (i = 0; i < 4; i++) + tag = memtag(tag, PHYS_OFFSET + (i << 26), + params->u1.s.pages_in_bank[i] * PAGE_SIZE); + } else +#endif + tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); + +#ifdef CONFIG_FOOTBRIDGE + if (params->u1.s.mem_fclk_21285) { + tag = tag_next(tag); + tag->hdr.tag = ATAG_MEMCLK; + tag->hdr.size = tag_size(tag_memclk); + tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285; + } +#endif + +#ifdef CONFIG_ARCH_EBSA285 + if (machine_is_ebsa285()) { + tag = tag_next(tag); + tag->hdr.tag = ATAG_VIDEOTEXT; + tag->hdr.size = tag_size(tag_videotext); + tag->u.videotext.x = params->u1.s.video_x; + tag->u.videotext.y = params->u1.s.video_y; + tag->u.videotext.video_page = 0; + tag->u.videotext.video_mode = 0; + tag->u.videotext.video_cols = params->u1.s.video_num_cols; + tag->u.videotext.video_ega_bx = 0; + tag->u.videotext.video_lines = params->u1.s.video_num_rows; + tag->u.videotext.video_isvga = 1; + tag->u.videotext.video_points = 8; + } +#endif + +#ifdef CONFIG_ARCH_ACORN + tag = tag_next(tag); + tag->hdr.tag = ATAG_ACORN; + tag->hdr.size = tag_size(tag_acorn); + tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg; + tag->u.acorn.vram_pages = params->u1.s.pages_in_vram; + tag->u.acorn.sounddefault = params->u1.s.sounddefault; + tag->u.acorn.adfsdrives = params->u1.s.adfsdrives; +#endif + + tag = tag_next(tag); + tag->hdr.tag = ATAG_CMDLINE; + tag->hdr.size = (strlen(params->commandline) + 3 + + sizeof(struct tag_header)) >> 2; + strcpy(tag->u.cmdline.cmdline, params->commandline); + + tag = tag_next(tag); + tag->hdr.tag = ATAG_NONE; + tag->hdr.size = 0; + + memmove(params, taglist, ((int)tag) - ((int)taglist) + + sizeof(struct tag_header)); +} + +void __init convert_to_tag_list(struct tag *tags) +{ + struct param_struct *params = (struct param_struct *)tags; + build_tag_list(params, ¶ms->u2); +} diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c new file mode 100644 index 0000000..14512e6 --- /dev/null +++ b/arch/arm/kernel/atags_parse.c @@ -0,0 +1,238 @@ +/* + * Tag parsing. + * + * Copyright (C) 1995-2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * This is the traditional way of passing data to the kernel at boot time. Rather + * than passing a fixed inflexible structure to the kernel, we pass a list + * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE + * tag for the list to be recognised (to distinguish the tagged list from + * a param_struct). The list is terminated with a zero-length tag (this tag + * is not parsed in any way). + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "atags.h" + +static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; + +#ifndef MEM_SIZE +#define MEM_SIZE (16*1024*1024) +#endif + +static struct { + struct tag_header hdr1; + struct tag_core core; + struct tag_header hdr2; + struct tag_mem32 mem; + struct tag_header hdr3; +} default_tags __initdata = { + { tag_size(tag_core), ATAG_CORE }, + { 1, PAGE_SIZE, 0xff }, + { tag_size(tag_mem32), ATAG_MEM }, + { MEM_SIZE }, + { 0, ATAG_NONE } +}; + +static int __init parse_tag_core(const struct tag *tag) +{ + if (tag->hdr.size > 2) { + if ((tag->u.core.flags & 1) == 0) + root_mountflags &= ~MS_RDONLY; + ROOT_DEV = old_decode_dev(tag->u.core.rootdev); + } + return 0; +} + +__tagtable(ATAG_CORE, parse_tag_core); + +static int __init parse_tag_mem32(const struct tag *tag) +{ + return arm_add_memory(tag->u.mem.start, tag->u.mem.size); +} + +__tagtable(ATAG_MEM, parse_tag_mem32); + +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) +static int __init parse_tag_videotext(const struct tag *tag) +{ + screen_info.orig_x = tag->u.videotext.x; + screen_info.orig_y = tag->u.videotext.y; + screen_info.orig_video_page = tag->u.videotext.video_page; + screen_info.orig_video_mode = tag->u.videotext.video_mode; + screen_info.orig_video_cols = tag->u.videotext.video_cols; + screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; + screen_info.orig_video_lines = tag->u.videotext.video_lines; + screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; + screen_info.orig_video_points = tag->u.videotext.video_points; + return 0; +} + +__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); +#endif + +#ifdef CONFIG_BLK_DEV_RAM +static int __init parse_tag_ramdisk(const struct tag *tag) +{ + extern int rd_size, rd_image_start, rd_prompt, rd_doload; + + rd_image_start = tag->u.ramdisk.start; + rd_doload = (tag->u.ramdisk.flags & 1) == 0; + rd_prompt = (tag->u.ramdisk.flags & 2) == 0; + + if (tag->u.ramdisk.size) + rd_size = tag->u.ramdisk.size; + + return 0; +} + +__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); +#endif + +static int __init parse_tag_serialnr(const struct tag *tag) +{ + system_serial_low = tag->u.serialnr.low; + system_serial_high = tag->u.serialnr.high; + return 0; +} + +__tagtable(ATAG_SERIAL, parse_tag_serialnr); + +static int __init parse_tag_revision(const struct tag *tag) +{ + system_rev = tag->u.revision.rev; + return 0; +} + +__tagtable(ATAG_REVISION, parse_tag_revision); + +static int __init parse_tag_cmdline(const struct tag *tag) +{ +#if defined(CONFIG_CMDLINE_EXTEND) + strlcat(default_command_line, " ", COMMAND_LINE_SIZE); + strlcat(default_command_line, tag->u.cmdline.cmdline, + COMMAND_LINE_SIZE); +#elif defined(CONFIG_CMDLINE_FORCE) + pr_warning("Ignoring tag cmdline (using the default kernel command line)\n"); +#else + strlcpy(default_command_line, tag->u.cmdline.cmdline, + COMMAND_LINE_SIZE); +#endif + return 0; +} + +__tagtable(ATAG_CMDLINE, parse_tag_cmdline); + +/* + * Scan the tag table for this tag, and call its parse function. + * The tag table is built by the linker from all the __tagtable + * declarations. + */ +static int __init parse_tag(const struct tag *tag) +{ + extern struct tagtable __tagtable_begin, __tagtable_end; + struct tagtable *t; + + for (t = &__tagtable_begin; t < &__tagtable_end; t++) + if (tag->hdr.tag == t->tag) { + t->parse(tag); + break; + } + + return t < &__tagtable_end; +} + +/* + * Parse all tags in the list, checking both the global and architecture + * specific tag tables. + */ +static void __init parse_tags(const struct tag *t) +{ + for (; t->hdr.size; t = tag_next(t)) + if (!parse_tag(t)) + printk(KERN_WARNING + "Ignoring unrecognised tag 0x%08x\n", + t->hdr.tag); +} + +static void __init squash_mem_tags(struct tag *tag) +{ + for (; tag->hdr.size; tag = tag_next(tag)) + if (tag->hdr.tag == ATAG_MEM) + tag->hdr.tag = ATAG_NONE; +} + +struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer, + unsigned int machine_nr) +{ + struct tag *tags = (struct tag *)&default_tags; + struct machine_desc *mdesc = NULL, *p; + char *from = default_command_line; + + default_tags.mem.start = PHYS_OFFSET; + + /* + * locate machine in the list of supported machines. + */ + for_each_machine_desc(p) + if (machine_nr == p->nr) { + printk("Machine: %s\n", p->name); + mdesc = p; + break; + } + + if (!mdesc) { + early_print("\nError: unrecognized/unsupported machine ID" + " (r1 = 0x%08x).\n\n", machine_nr); + dump_machine_table(); /* does not return */ + } + + if (__atags_pointer) + tags = phys_to_virt(__atags_pointer); + else if (mdesc->atag_offset) + tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); + +#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) + /* + * If we have the old style parameters, convert them to + * a tag list. + */ + if (tags->hdr.tag != ATAG_CORE) + convert_to_tag_list(tags); +#endif + if (tags->hdr.tag != ATAG_CORE) { + early_print("Warning: Neither atags nor dtb found\n"); + tags = (struct tag *)&default_tags; + } + + if (mdesc->fixup) + mdesc->fixup(tags, &from, &meminfo); + + if (tags->hdr.tag == ATAG_CORE) { + if (meminfo.nr_banks != 0) + squash_mem_tags(tags); + save_atags(tags); + parse_tags(tags); + } + + /* parse_early_param needs a boot_command_line */ + strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); + + return mdesc; +} diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c new file mode 100644 index 0000000..42a1a14 --- /dev/null +++ b/arch/arm/kernel/atags_proc.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +struct buffer { + size_t size; + char data[]; +}; + +static int +read_buffer(char* page, char** start, off_t off, int count, + int* eof, void* data) +{ + struct buffer *buffer = (struct buffer *)data; + + if (off >= buffer->size) { + *eof = 1; + return 0; + } + + count = min((int) (buffer->size - off), count); + + memcpy(page, &buffer->data[off], count); + + return count; +} + +#define BOOT_PARAMS_SIZE 1536 +static char __initdata atags_copy[BOOT_PARAMS_SIZE]; + +void __init save_atags(const struct tag *tags) +{ + memcpy(atags_copy, tags, sizeof(atags_copy)); +} + +static int __init init_atags_procfs(void) +{ + /* + * This cannot go into save_atags() because kmalloc and proc don't work + * yet when it is called. + */ + struct proc_dir_entry *tags_entry; + struct tag *tag = (struct tag *)atags_copy; + struct buffer *b; + size_t size; + + if (tag->hdr.tag != ATAG_CORE) { + printk(KERN_INFO "No ATAGs?"); + return -EINVAL; + } + + for (; tag->hdr.size; tag = tag_next(tag)) + ; + + /* include the terminating ATAG_NONE */ + size = (char *)tag - atags_copy + sizeof(struct tag_header); + + WARN_ON(tag->hdr.tag != ATAG_NONE); + + b = kmalloc(sizeof(*b) + size, GFP_KERNEL); + if (!b) + goto nomem; + + b->size = size; + memcpy(b->data, atags_copy, size); + + tags_entry = create_proc_read_entry("atags", 0400, + NULL, read_buffer, b); + + if (!tags_entry) + goto nomem; + + return 0; + +nomem: + kfree(b); + printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); + + return -ENOMEM; +} +arch_initcall(init_atags_procfs); diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/compat.c deleted file mode 100644 index 9256523..0000000 --- a/arch/arm/kernel/compat.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * linux/arch/arm/kernel/compat.c - * - * Copyright (C) 2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * We keep the old params compatibility cruft in one place (here) - * so we don't end up with lots of mess around other places. - * - * NOTE: - * The old struct param_struct is deprecated, but it will be kept in - * the kernel for 5 years from now (2001). This will allow boot loaders - * to convert to the new struct tag way. - */ -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "compat.h" - -/* - * Usage: - * - do not go blindly adding fields, add them at the end - * - when adding fields, don't rely on the address until - * a patch from me has been released - * - unused fields should be zero (for future expansion) - * - this structure is relatively short-lived - only - * guaranteed to contain useful data in setup_arch() - * - * This is the old deprecated way to pass parameters to the kernel - */ -struct param_struct { - union { - struct { - unsigned long page_size; /* 0 */ - unsigned long nr_pages; /* 4 */ - unsigned long ramdisk_size; /* 8 */ - unsigned long flags; /* 12 */ -#define FLAG_READONLY 1 -#define FLAG_RDLOAD 4 -#define FLAG_RDPROMPT 8 - unsigned long rootdev; /* 16 */ - unsigned long video_num_cols; /* 20 */ - unsigned long video_num_rows; /* 24 */ - unsigned long video_x; /* 28 */ - unsigned long video_y; /* 32 */ - unsigned long memc_control_reg; /* 36 */ - unsigned char sounddefault; /* 40 */ - unsigned char adfsdrives; /* 41 */ - unsigned char bytes_per_char_h; /* 42 */ - unsigned char bytes_per_char_v; /* 43 */ - unsigned long pages_in_bank[4]; /* 44 */ - unsigned long pages_in_vram; /* 60 */ - unsigned long initrd_start; /* 64 */ - unsigned long initrd_size; /* 68 */ - unsigned long rd_start; /* 72 */ - unsigned long system_rev; /* 76 */ - unsigned long system_serial_low; /* 80 */ - unsigned long system_serial_high; /* 84 */ - unsigned long mem_fclk_21285; /* 88 */ - } s; - char unused[256]; - } u1; - union { - char paths[8][128]; - struct { - unsigned long magic; - char n[1024 - sizeof(unsigned long)]; - } s; - } u2; - char commandline[COMMAND_LINE_SIZE]; -}; - -static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size) -{ - tag = tag_next(tag); - tag->hdr.tag = ATAG_MEM; - tag->hdr.size = tag_size(tag_mem32); - tag->u.mem.size = size; - tag->u.mem.start = start; - - return tag; -} - -static void __init build_tag_list(struct param_struct *params, void *taglist) -{ - struct tag *tag = taglist; - - if (params->u1.s.page_size != PAGE_SIZE) { - printk(KERN_WARNING "Warning: bad configuration page, " - "trying to continue\n"); - return; - } - - printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); - -#ifdef CONFIG_ARCH_NETWINDER - if (params->u1.s.nr_pages != 0x02000 && - params->u1.s.nr_pages != 0x04000 && - params->u1.s.nr_pages != 0x08000 && - params->u1.s.nr_pages != 0x10000) { - printk(KERN_WARNING "Warning: bad NeTTrom parameters " - "detected, using defaults\n"); - - params->u1.s.nr_pages = 0x1000; /* 16MB */ - params->u1.s.ramdisk_size = 0; - params->u1.s.flags = FLAG_READONLY; - params->u1.s.initrd_start = 0; - params->u1.s.initrd_size = 0; - params->u1.s.rd_start = 0; - } -#endif - - tag->hdr.tag = ATAG_CORE; - tag->hdr.size = tag_size(tag_core); - tag->u.core.flags = params->u1.s.flags & FLAG_READONLY; - tag->u.core.pagesize = params->u1.s.page_size; - tag->u.core.rootdev = params->u1.s.rootdev; - - tag = tag_next(tag); - tag->hdr.tag = ATAG_RAMDISK; - tag->hdr.size = tag_size(tag_ramdisk); - tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) | - (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0); - tag->u.ramdisk.size = params->u1.s.ramdisk_size; - tag->u.ramdisk.start = params->u1.s.rd_start; - - tag = tag_next(tag); - tag->hdr.tag = ATAG_INITRD; - tag->hdr.size = tag_size(tag_initrd); - tag->u.initrd.start = params->u1.s.initrd_start; - tag->u.initrd.size = params->u1.s.initrd_size; - - tag = tag_next(tag); - tag->hdr.tag = ATAG_SERIAL; - tag->hdr.size = tag_size(tag_serialnr); - tag->u.serialnr.low = params->u1.s.system_serial_low; - tag->u.serialnr.high = params->u1.s.system_serial_high; - - tag = tag_next(tag); - tag->hdr.tag = ATAG_REVISION; - tag->hdr.size = tag_size(tag_revision); - tag->u.revision.rev = params->u1.s.system_rev; - -#ifdef CONFIG_ARCH_ACORN - if (machine_is_riscpc()) { - int i; - for (i = 0; i < 4; i++) - tag = memtag(tag, PHYS_OFFSET + (i << 26), - params->u1.s.pages_in_bank[i] * PAGE_SIZE); - } else -#endif - tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); - -#ifdef CONFIG_FOOTBRIDGE - if (params->u1.s.mem_fclk_21285) { - tag = tag_next(tag); - tag->hdr.tag = ATAG_MEMCLK; - tag->hdr.size = tag_size(tag_memclk); - tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285; - } -#endif - -#ifdef CONFIG_ARCH_EBSA285 - if (machine_is_ebsa285()) { - tag = tag_next(tag); - tag->hdr.tag = ATAG_VIDEOTEXT; - tag->hdr.size = tag_size(tag_videotext); - tag->u.videotext.x = params->u1.s.video_x; - tag->u.videotext.y = params->u1.s.video_y; - tag->u.videotext.video_page = 0; - tag->u.videotext.video_mode = 0; - tag->u.videotext.video_cols = params->u1.s.video_num_cols; - tag->u.videotext.video_ega_bx = 0; - tag->u.videotext.video_lines = params->u1.s.video_num_rows; - tag->u.videotext.video_isvga = 1; - tag->u.videotext.video_points = 8; - } -#endif - -#ifdef CONFIG_ARCH_ACORN - tag = tag_next(tag); - tag->hdr.tag = ATAG_ACORN; - tag->hdr.size = tag_size(tag_acorn); - tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg; - tag->u.acorn.vram_pages = params->u1.s.pages_in_vram; - tag->u.acorn.sounddefault = params->u1.s.sounddefault; - tag->u.acorn.adfsdrives = params->u1.s.adfsdrives; -#endif - - tag = tag_next(tag); - tag->hdr.tag = ATAG_CMDLINE; - tag->hdr.size = (strlen(params->commandline) + 3 + - sizeof(struct tag_header)) >> 2; - strcpy(tag->u.cmdline.cmdline, params->commandline); - - tag = tag_next(tag); - tag->hdr.tag = ATAG_NONE; - tag->hdr.size = 0; - - memmove(params, taglist, ((int)tag) - ((int)taglist) + - sizeof(struct tag_header)); -} - -void __init convert_to_tag_list(struct tag *tags) -{ - struct param_struct *params = (struct param_struct *)tags; - build_tag_list(params, ¶ms->u2); -} diff --git a/arch/arm/kernel/compat.h b/arch/arm/kernel/compat.h deleted file mode 100644 index 39264ab..0000000 --- a/arch/arm/kernel/compat.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * linux/arch/arm/kernel/compat.h - * - * Copyright (C) 2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -extern void convert_to_tag_list(struct tag *tags); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a81dcec..0785472 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -21,11 +21,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -56,15 +54,9 @@ #include #include -#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) -#include "compat.h" -#endif #include "atags.h" #include "tcm.h" -#ifndef MEM_SIZE -#define MEM_SIZE (16*1024*1024) -#endif #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) char fpe_type[8]; @@ -145,7 +137,6 @@ static const char *machine_name; static char __initdata cmd_line[COMMAND_LINE_SIZE]; struct machine_desc *machine_desc __initdata; -static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; #define ENDIANNESS ((char)endian_test.l) @@ -583,21 +574,6 @@ static int __init early_mem(char *p) } early_param("mem", early_mem); -static void __init -setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) -{ -#ifdef CONFIG_BLK_DEV_RAM - extern int rd_size, rd_image_start, rd_prompt, rd_doload; - - rd_image_start = image_start; - rd_prompt = prompt; - rd_doload = doload; - - if (rd_sz) - rd_size = rd_sz; -#endif -} - static void __init request_standard_resources(struct machine_desc *mdesc) { struct memblock_region *region; @@ -643,35 +619,6 @@ static void __init request_standard_resources(struct machine_desc *mdesc) request_resource(&ioport_resource, &lp2); } -/* - * Tag parsing. - * - * This is the new way of passing data to the kernel at boot time. Rather - * than passing a fixed inflexible structure to the kernel, we pass a list - * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE - * tag for the list to be recognised (to distinguish the tagged list from - * a param_struct). The list is terminated with a zero-length tag (this tag - * is not parsed in any way). - */ -static int __init parse_tag_core(const struct tag *tag) -{ - if (tag->hdr.size > 2) { - if ((tag->u.core.flags & 1) == 0) - root_mountflags &= ~MS_RDONLY; - ROOT_DEV = old_decode_dev(tag->u.core.rootdev); - } - return 0; -} - -__tagtable(ATAG_CORE, parse_tag_core); - -static int __init parse_tag_mem32(const struct tag *tag) -{ - return arm_add_memory(tag->u.mem.start, tag->u.mem.size); -} - -__tagtable(ATAG_MEM, parse_tag_mem32); - #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) struct screen_info screen_info = { .orig_video_lines = 30, @@ -681,117 +628,8 @@ struct screen_info screen_info = { .orig_video_isVGA = 1, .orig_video_points = 8 }; - -static int __init parse_tag_videotext(const struct tag *tag) -{ - screen_info.orig_x = tag->u.videotext.x; - screen_info.orig_y = tag->u.videotext.y; - screen_info.orig_video_page = tag->u.videotext.video_page; - screen_info.orig_video_mode = tag->u.videotext.video_mode; - screen_info.orig_video_cols = tag->u.videotext.video_cols; - screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; - screen_info.orig_video_lines = tag->u.videotext.video_lines; - screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; - screen_info.orig_video_points = tag->u.videotext.video_points; - return 0; -} - -__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); #endif -static int __init parse_tag_ramdisk(const struct tag *tag) -{ - setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, - (tag->u.ramdisk.flags & 2) == 0, - tag->u.ramdisk.start, tag->u.ramdisk.size); - return 0; -} - -__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); - -static int __init parse_tag_serialnr(const struct tag *tag) -{ - system_serial_low = tag->u.serialnr.low; - system_serial_high = tag->u.serialnr.high; - return 0; -} - -__tagtable(ATAG_SERIAL, parse_tag_serialnr); - -static int __init parse_tag_revision(const struct tag *tag) -{ - system_rev = tag->u.revision.rev; - return 0; -} - -__tagtable(ATAG_REVISION, parse_tag_revision); - -static int __init parse_tag_cmdline(const struct tag *tag) -{ -#if defined(CONFIG_CMDLINE_EXTEND) - strlcat(default_command_line, " ", COMMAND_LINE_SIZE); - strlcat(default_command_line, tag->u.cmdline.cmdline, - COMMAND_LINE_SIZE); -#elif defined(CONFIG_CMDLINE_FORCE) - pr_warning("Ignoring tag cmdline (using the default kernel command line)\n"); -#else - strlcpy(default_command_line, tag->u.cmdline.cmdline, - COMMAND_LINE_SIZE); -#endif - return 0; -} - -__tagtable(ATAG_CMDLINE, parse_tag_cmdline); - -/* - * Scan the tag table for this tag, and call its parse function. - * The tag table is built by the linker from all the __tagtable - * declarations. - */ -static int __init parse_tag(const struct tag *tag) -{ - extern struct tagtable __tagtable_begin, __tagtable_end; - struct tagtable *t; - - for (t = &__tagtable_begin; t < &__tagtable_end; t++) - if (tag->hdr.tag == t->tag) { - t->parse(tag); - break; - } - - return t < &__tagtable_end; -} - -/* - * Parse all tags in the list, checking both the global and architecture - * specific tag tables. - */ -static void __init parse_tags(const struct tag *t) -{ - for (; t->hdr.size; t = tag_next(t)) - if (!parse_tag(t)) - printk(KERN_WARNING - "Ignoring unrecognised tag 0x%08x\n", - t->hdr.tag); -} - -/* - * This holds our defaults. - */ -static struct init_tags { - struct tag_header hdr1; - struct tag_core core; - struct tag_header hdr2; - struct tag_mem32 mem; - struct tag_header hdr3; -} init_tags __initdata = { - { tag_size(tag_core), ATAG_CORE }, - { 1, PAGE_SIZE, 0xff }, - { tag_size(tag_mem32), ATAG_MEM }, - { MEM_SIZE }, - { 0, ATAG_NONE } -}; - static int __init customize_machine(void) { /* customizes platform devices, or adds new ones */ @@ -858,78 +696,6 @@ static void __init reserve_crashkernel(void) static inline void reserve_crashkernel(void) {} #endif /* CONFIG_KEXEC */ -static void __init squash_mem_tags(struct tag *tag) -{ - for (; tag->hdr.size; tag = tag_next(tag)) - if (tag->hdr.tag == ATAG_MEM) - tag->hdr.tag = ATAG_NONE; -} - -static struct machine_desc * __init setup_machine_tags(unsigned int nr) -{ - struct tag *tags = (struct tag *)&init_tags; - struct machine_desc *mdesc = NULL, *p; - char *from = default_command_line; - - init_tags.mem.start = PHYS_OFFSET; - - /* - * locate machine in the list of supported machines. - */ - for_each_machine_desc(p) - if (nr == p->nr) { - printk("Machine: %s\n", p->name); - mdesc = p; - break; - } - - if (!mdesc) { - early_print("\nError: unrecognized/unsupported machine ID" - " (r1 = 0x%08x).\n\n", nr); - dump_machine_table(); /* does not return */ - } - - if (__atags_pointer) - tags = phys_to_virt(__atags_pointer); - else if (mdesc->atag_offset) - tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); - -#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) - /* - * If we have the old style parameters, convert them to - * a tag list. - */ - if (tags->hdr.tag != ATAG_CORE) - convert_to_tag_list(tags); -#endif - - if (tags->hdr.tag != ATAG_CORE) { -#if defined(CONFIG_OF) - /* - * If CONFIG_OF is set, then assume this is a reasonably - * modern system that should pass boot parameters - */ - early_print("Warning: Neither atags nor dtb found\n"); -#endif - tags = (struct tag *)&init_tags; - } - - if (mdesc->fixup) - mdesc->fixup(tags, &from, &meminfo); - - if (tags->hdr.tag == ATAG_CORE) { - if (meminfo.nr_banks != 0) - squash_mem_tags(tags); - save_atags(tags); - parse_tags(tags); - } - - /* parse_early_param needs a boot_command_line */ - strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); - - return mdesc; -} - static int __init meminfo_cmp(const void *_a, const void *_b) { const struct membank *a = _a, *b = _b; @@ -944,7 +710,7 @@ void __init setup_arch(char **cmdline_p) setup_processor(); mdesc = setup_machine_fdt(__atags_pointer); if (!mdesc) - mdesc = setup_machine_tags(machine_arch_type); + mdesc = setup_machine_tags(__atags_pointer, machine_arch_type); machine_desc = mdesc; machine_name = mdesc->name; -- cgit v0.10.2 From bd51e2f595580fb64bd8494badef746c4d626b25 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sat, 1 Sep 2012 03:03:25 +0100 Subject: ARM: 7506/1: allow for ATAGS to be configured out when DT support is selected Now that ATAGS support is well contained, we can easily remove it from the kernel build if so desired. It has to explicitly be disabled, and only when DT support is selected. Note: disabling kernel ATAGS support does not prevent the usage of CONFIG_ARM_ATAG_DTB_COMPAT. Signed-off-by: Nicolas Pitre Tested-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5..5c7302e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1891,12 +1891,6 @@ config CC_STACKPROTECTOR neutralized via a kernel panic. This feature requires gcc version 4.2 or above. -config DEPRECATED_PARAM_STRUCT - bool "Provide old way to pass kernel parameters" - help - This was deprecated in 2001 and announced to live on for 5 years. - Some old boot loaders still use this way. - endmenu menu "Boot options" @@ -1909,6 +1903,23 @@ config USE_OF help Include support for flattened device tree machine descriptions. +config ATAGS + bool "Support for the traditional ATAGS boot data passing" if USE_OF + default y + help + This is the traditional way of passing data to the kernel at boot + time. If you are solely relying on the flattened device tree (or + the ARM_ATAG_DTB_COMPAT option) then you may unselect this option + to remove ATAGS support from your kernel binary. If unsure, + leave this to y. + +config DEPRECATED_PARAM_STRUCT + bool "Provide old way to pass kernel parameters" + depends on ATAGS + help + This was deprecated in 2001 and announced to live on for 5 years. + Some old boot loaders still use this way. + # Compressed boot loader in ROM. Yes, we really want to ask about # TEXT and BSS so we preserve their values in the config files. config ZBOOT_ROM_TEXT @@ -2035,6 +2046,7 @@ config CMDLINE choice prompt "Kernel command line type" if CMDLINE != "" default CMDLINE_FROM_BOOTLOADER + depends on ATAGS config CMDLINE_FROM_BOOTLOADER bool "Use bootloader kernel arguments if available" @@ -2104,7 +2116,7 @@ config KEXEC config ATAGS_PROC bool "Export atags in procfs" - depends on KEXEC + depends on ATAGS && KEXEC default y help Should the atags used to boot the kernel be exported in an "atags" diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 086c9d3..79e346a 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,10 +15,12 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := atags_parse.o elf.o entry-armv.o entry-common.o irq.o opcodes.o \ +obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o sched_clock.o \ setup.o signal.o stacktrace.o sys_arm.o time.o traps.o +obj-$(CONFIG_ATAGS) += atags_parse.o +obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o obj-$(CONFIG_LEDS) += leds.o @@ -52,7 +54,6 @@ test-kprobes-objs += kprobes-test-thumb.o else test-kprobes-objs += kprobes-test-arm.o endif -obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index a888fdd..9edc969 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h @@ -5,4 +5,15 @@ static inline void save_atags(struct tag *tags) { } #endif void convert_to_tag_list(struct tag *tags); + +#ifdef CONFIG_ATAGS struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr); +#else +static inline struct machine_desc * +setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) +{ + early_print("no ATAGS support: can't continue\n"); + while (true); + unreachable(); +} +#endif -- cgit v0.10.2 From 57b9da32addd819b0baef5573a88fcfaf3e6699b Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 3 Sep 2012 13:49:22 +0100 Subject: ARM: 7508/1: opcodes: Don't define the thumb32 byteswapping macros for BE32 The existing __mem_to_opcode_thumb32() is incorrect for BE32 platforms. However, these don't support Thumb-2 kernels, so this option is not so relevant for those platforms anyway. This operation is complicated by the lack of unaligned memory access support prior to ARMv6. Rather than provide a "working" macro which will probably won't get used (or worse, will get misused), this patch removes the macro for BE32 kernels. People manipulating Thumb opcodes prior to ARMv6 should almost certainly be splitting these operations into halfwords anyway, using __opcode_thumb32_{first,second,compose}() and the 16-bit opcode transformations. Signed-off-by: Dave Martin Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index 19c48de..6bf54f9 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -49,18 +49,31 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); #include #ifdef CONFIG_CPU_ENDIAN_BE8 + #define __opcode_to_mem_arm(x) swab32(x) #define __opcode_to_mem_thumb16(x) swab16(x) #define __opcode_to_mem_thumb32(x) swahb32(x) -#else + +#else /* ! CONFIG_CPU_ENDIAN_BE8 */ + #define __opcode_to_mem_arm(x) ((u32)(x)) #define __opcode_to_mem_thumb16(x) ((u16)(x)) +#ifndef CONFIG_CPU_ENDIAN_BE32 +/* + * On BE32 systems, using 32-bit accesses to store Thumb instructions will not + * work in all cases, due to alignment constraints. For now, a correct + * version is not provided for BE32. + */ #define __opcode_to_mem_thumb32(x) swahw32(x) #endif +#endif /* ! CONFIG_CPU_ENDIAN_BE8 */ + #define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x) #define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) +#ifndef CONFIG_CPU_ENDIAN_BE32 #define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) +#endif /* Operations specific to Thumb opcodes */ -- cgit v0.10.2 From 0ce3de23f2a520a6ac8c2179fb8f88342c4992ef Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 3 Sep 2012 13:49:23 +0100 Subject: ARM: 7509/1: opcodes: Make opcode byteswapping macros assembly-compatible Most of the existing macros don't work with assembler, due to the use of type casts and C functions from . This patch abstracts out those operations and provides simple explicit versions for use in assembly code. __opcode_is_thumb32() and __opcode_is_thumb16() are also converted to do bitmask-based testing to avoid confusion if these are used in assembly code (the assembler typically treats all arithmetic values as signed). These changes avoid the need for the compiler to pre-evaluate constant expressions used to generate opcodes. By ensuring that the forms of these expressions can be evaluated directly by the assembler, we can just stringify the expressions directly into the asm during the preprocessing pass. The alternative approach (passing the evaluated expression via an inline asm "i" constraint) gets painful because the contents of the asm and the constraints must be kept in sync. This makes the resulting macros awkward to use. Retaining the C forms of the macros allows more efficient code to be generated when opcodes are generated programmatically at run- time, but there is no way to embed run-time-generated opcodes in asm() blocks. Signed-off-by: Dave Martin Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index 6bf54f9..f57e417 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -19,6 +19,33 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); /* + * Assembler opcode byteswap helpers. + * These are only intended for use by this header: don't use them directly, + * because they will be suboptimal in most cases. + */ +#define ___asm_opcode_swab32(x) ( \ + (((x) << 24) & 0xFF000000) \ + | (((x) << 8) & 0x00FF0000) \ + | (((x) >> 8) & 0x0000FF00) \ + | (((x) >> 24) & 0x000000FF) \ +) +#define ___asm_opcode_swab16(x) ( \ + (((x) << 8) & 0xFF00) \ + | (((x) >> 8) & 0x00FF) \ +) +#define ___asm_opcode_swahb32(x) ( \ + (((x) << 8) & 0xFF00FF00) \ + | (((x) >> 8) & 0x00FF00FF) \ +) +#define ___asm_opcode_swahw32(x) ( \ + (((x) << 16) & 0xFFFF0000) \ + | (((x) >> 16) & 0x0000FFFF) \ +) +#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF) +#define ___asm_opcode_identity16(x) ((x) & 0xFFFF) + + +/* * Opcode byteswap helpers * * These macros help with converting instructions between a canonical integer @@ -41,30 +68,58 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not * represent any valid Thumb-2 instruction. For this range, * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. + * + * The ___asm variants are intended only for use by this header, in situations + * involving inline assembler. For .S files, the normal __opcode_*() macros + * should do the right thing. */ +#ifdef __ASSEMBLY__ -#ifndef __ASSEMBLY__ +#define ___opcode_swab32(x) ___asm_opcode_swab32(x) +#define ___opcode_swab16(x) ___asm_opcode_swab16(x) +#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x) +#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x) +#define ___opcode_identity32(x) ___asm_opcode_identity32(x) +#define ___opcode_identity16(x) ___asm_opcode_identity16(x) + +#else /* ! __ASSEMBLY__ */ #include #include +#define ___opcode_swab32(x) swab32(x) +#define ___opcode_swab16(x) swab16(x) +#define ___opcode_swahb32(x) swahb32(x) +#define ___opcode_swahw32(x) swahw32(x) +#define ___opcode_identity32(x) ((u32)(x)) +#define ___opcode_identity16(x) ((u16)(x)) + +#endif /* ! __ASSEMBLY__ */ + + #ifdef CONFIG_CPU_ENDIAN_BE8 -#define __opcode_to_mem_arm(x) swab32(x) -#define __opcode_to_mem_thumb16(x) swab16(x) -#define __opcode_to_mem_thumb32(x) swahb32(x) +#define __opcode_to_mem_arm(x) ___opcode_swab32(x) +#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x) +#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x) +#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x) +#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x) #else /* ! CONFIG_CPU_ENDIAN_BE8 */ -#define __opcode_to_mem_arm(x) ((u32)(x)) -#define __opcode_to_mem_thumb16(x) ((u16)(x)) +#define __opcode_to_mem_arm(x) ___opcode_identity32(x) +#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x) +#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x) #ifndef CONFIG_CPU_ENDIAN_BE32 /* * On BE32 systems, using 32-bit accesses to store Thumb instructions will not * work in all cases, due to alignment constraints. For now, a correct * version is not provided for BE32. */ -#define __opcode_to_mem_thumb32(x) swahw32(x) +#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x) +#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x) #endif #endif /* ! CONFIG_CPU_ENDIAN_BE8 */ @@ -78,15 +133,27 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); /* Operations specific to Thumb opcodes */ /* Instruction size checks: */ -#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL) -#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL) +#define __opcode_is_thumb32(x) ( \ + ((x) & 0xF8000000) == 0xE8000000 \ + || ((x) & 0xF0000000) == 0xF0000000 \ +) +#define __opcode_is_thumb16(x) ( \ + ((x) & 0xFFFF0000) == 0 \ + && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000) \ +) /* Operations to construct or split 32-bit Thumb instructions: */ -#define __opcode_thumb32_first(x) ((u16)((x) >> 16)) -#define __opcode_thumb32_second(x) ((u16)(x)) -#define __opcode_thumb32_compose(first, second) \ - (((u32)(u16)(first) << 16) | (u32)(u16)(second)) - -#endif /* __ASSEMBLY__ */ +#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16)) +#define __opcode_thumb32_second(x) (___opcode_identity16(x)) +#define __opcode_thumb32_compose(first, second) ( \ + (___opcode_identity32(___opcode_identity16(first)) << 16) \ + | ___opcode_identity32(___opcode_identity16(second)) \ +) +#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16)) +#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x)) +#define ___asm_opcode_thumb32_compose(first, second) ( \ + (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \ + | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ +) #endif /* __ASM_ARM_OPCODES_H */ -- cgit v0.10.2 From a61a41a01822d48bbe53e6c1df56b88ee2f3de34 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 3 Sep 2012 13:49:24 +0100 Subject: ARM: 7510/1: opcodes: Add helpers for emitting custom opcodes This patch adds some __inst_() macros for injecting custom opcodes in assembler (both inline and in .S files). They should make it easier and cleaner to get things right in little-/big- endian/ARM/Thumb-2 kernels without a lot of #ifdefs. This pure-preprocessor approach is preferred over the alternative method of wedging extra assembler directives into the assembler input using top-level asm() blocks, since there is no way to guarantee that the compiler won't reorder those with respect to each other or with respect to non-toplevel asm() blocks, unless -fno-toplevel-reorder is passed (which is in itself somewhat undesirable because it defeats some potential optimisations). Currently _does_ silently rely on the compiler not reordering at the top level, but it seems better to avoid adding extra code which depends on this if the same result can be achieved in another way. Signed-off-by: Dave Martin Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index f57e417..f7937e1 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -156,4 +156,73 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ ) +/* + * Opcode injection helpers + * + * In rare cases it is necessary to assemble an opcode which the + * assembler does not support directly, or which would normally be + * rejected because of the CFLAGS or AFLAGS used to build the affected + * file. + * + * Before using these macros, consider carefully whether it is feasible + * instead to change the build flags for your file, or whether it really + * makes sense to support old assembler versions when building that + * particular kernel feature. + * + * The macros defined here should only be used where there is no viable + * alternative. + * + * + * __inst_arm(x): emit the specified ARM opcode + * __inst_thumb16(x): emit the specified 16-bit Thumb opcode + * __inst_thumb32(x): emit the specified 32-bit Thumb opcode + * + * __inst_arm_thumb16(arm, thumb): emit either the specified arm or + * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2 + * kernel is being built + * + * __inst_arm_thumb32(arm, thumb): emit either the specified arm or + * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2 + * kernel is being built + * + * + * Note that using these macros directly is poor practice. Instead, you + * should use them to define human-readable wrapper macros to encode the + * instructions that you care about. In code which might run on ARMv7 or + * above, you can usually use the __inst_arm_thumb{16,32} macros to + * specify the ARM and Thumb alternatives at the same time. This ensures + * that the correct opcode gets emitted depending on the instruction set + * used for the kernel build. + */ +#include + +#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) +#define __inst_thumb32(x) ___inst_thumb32( \ + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \ + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \ +) +#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) + +#ifdef CONFIG_THUMB2_KERNEL +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ + __inst_thumb16(thumb_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ + __inst_thumb32(thumb_opcode) +#else +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#endif + +/* Helpers for the helpers. Don't use these directly. */ +#ifdef __ASSEMBLY__ +#define ___inst_arm(x) .long x +#define ___inst_thumb16(x) .short x +#define ___inst_thumb32(first, second) .short first, second +#else +#define ___inst_arm(x) ".long " __stringify(x) "\n\t" +#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" +#define ___inst_thumb32(first, second) \ + ".short " __stringify(first) ", " __stringify(second) "\n\t" +#endif + #endif /* __ASM_ARM_OPCODES_H */ -- cgit v0.10.2 From 508514ed25315dd28340000831b17535d6f772da Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 3 Sep 2012 13:49:25 +0100 Subject: ARM: 7511/1: opcodes: Opcode definitions for the Virtualization Extensions For now, this patch just adds a definition for the HVC instruction. More can be added here later, as needed. Now that we have a real example of how to use the opcode injection macros properly, this patch also adds a cross-reference from the explanation in opcodes.h (since without an example, figuring out how to use the macros is not that easy). Signed-off-by: Dave Martin Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h new file mode 100644 index 0000000..b85665a --- /dev/null +++ b/arch/arm/include/asm/opcodes-virt.h @@ -0,0 +1,29 @@ +/* + * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions + * Copyright (C) 2012 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef __ASM_ARM_OPCODES_VIRT_H +#define __ASM_ARM_OPCODES_VIRT_H + +#include + +#define __HVC(imm16) __inst_arm_thumb32( \ + 0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F), \ + 0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF) \ +) + +#endif /* ! __ASM_ARM_OPCODES_VIRT_H */ diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index f7937e1..74e211a 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -193,6 +193,8 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); * specify the ARM and Thumb alternatives at the same time. This ensures * that the correct opcode gets emitted depending on the instruction set * used for the kernel build. + * + * Look at opcodes-virt.h for an example of how to use these macros. */ #include -- cgit v0.10.2 From 9d4876f039a086eeb599a8fac684c9a8daa64ab1 Mon Sep 17 00:00:00 2001 From: Yilu Mao Date: Mon, 3 Sep 2012 09:14:56 +0100 Subject: ARM: 7507/1: cache-l2x0.c: save the final aux ctrl value for resuming There is a bug if l2x0 controller has been enabled when calling l2x0_init, the aux ctrl register will not be saved in l2x0_saved_regs. Therefore we will use uninitialized l2x0_saved_regs.aux_ctrl for resuming later. In this patch, the aux ctrl value is read and saved after it is initialized. So we have the real value being set for resuming. Link: http://lkml.kernel.org/r/1336046857-24133-1-git-send-email-ylmao@marvell.com Signed-off-by: Yilu Mao Acked-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 2a8e380..97ec256 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -368,14 +368,18 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) /* l2x0 controller is disabled */ writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL); - l2x0_saved_regs.aux_ctrl = aux; - l2x0_inv_all(); /* enable L2X0 */ writel_relaxed(1, l2x0_base + L2X0_CTRL); } + /* Re-read it in case some bits are reserved. */ + aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); + + /* Save the value for resuming. */ + l2x0_saved_regs.aux_ctrl = aux; + outer_cache.inv_range = l2x0_inv_range; outer_cache.clean_range = l2x0_clean_range; outer_cache.flush_range = l2x0_flush_range; -- cgit v0.10.2 From a42c362980430be74b77ec8f374964f61062379f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 9 Sep 2012 18:39:28 +0100 Subject: ARM: Add irqtime accounting support Add support for irq time accounting. This commit prepares ARM by adding the call to enable_sched_clock_irqtime() in sched_clock(). We introduce a new kernel parameter - irqtime - which takes an integer. -1 for auto, 0 for disabled, and 1 for enabled. Auto mode selects IRQ accounting if we have a sched_clock() tick rate greater than 1MHz. Frederic Weisbecker is working on a patch set which moves the IRQ_TIME_ACCOUNTING into arch/, so that part is not incorporated into this patch; this facility becomes available on ARM only when both this patch and Frederic's patches are merged. Signed-off-by: Russell King diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 27d186a..9b8451a 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,9 @@ struct clock_data { static void sched_clock_poll(unsigned long wrap_ticks); static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); +static int irqtime = -1; + +core_param(irqtime, irqtime, int, 0400); static struct clock_data cd = { .mult = NSEC_PER_SEC / HZ, @@ -145,6 +149,10 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) */ cd.epoch_ns = 0; + /* Enable IRQ time accounting if we have a fast enough sched_clock */ + if (irqtime > 0 || (irqtime == -1 && rate >= 1000000)) + enable_sched_clock_irqtime(); + pr_debug("Registered %pF as sched_clock source\n", read); } -- cgit v0.10.2 From a761cebfd7cbeaf9a3a0c6960508ca1daaebb67e Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 10 Sep 2012 11:50:45 +0100 Subject: ARM: Fix build warning in arch/arm/mm/alignment.c Fix this harmless build warning: arch/arm/mm/alignment.c: In function 'do_alignment': arch/arm/mm/alignment.c:749:21: warning: 'offset.un' may be used uninitialized in this function This is caused by the compiler not being able to properly analyse the code to prove that offset.un is assigned in every case. The case it struggles with is where we assign the handler from the Thumb parser - do_alignment_t32_to_handler(). As this starts by zeroing this variable via a pointer, move it into the calling function. This fixes the warning. Signed-off-by: Russell King diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 9107231..b9f60eb 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -699,7 +699,6 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, unsigned long instr = *pinstr; u16 tinst1 = (instr >> 16) & 0xffff; u16 tinst2 = instr & 0xffff; - poffset->un = 0; switch (tinst1 & 0xffe0) { /* A6.3.5 Load/Store multiple */ @@ -854,9 +853,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) break; case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */ - if (thumb2_32b) + if (thumb2_32b) { + offset.un = 0; handler = do_alignment_t32_to_handler(&instr, regs, &offset); - else + } else handler = do_alignment_ldmstm; break; -- cgit v0.10.2 From e50a622deaf6b1a7dd2b9fb60975dd1d5406db37 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 6 Sep 2012 18:09:33 +0100 Subject: ARM: 7520/1: Build dtb files in all target Tools like kisskb are good at finding build regressions in the kernel sources. However, regressions in the DT desscriptions are not found, because generally these build systems don't build the DT binary blobs. Extend the ARM all target to build all enabled DTB files. Signed-off-by: Andrew Lunn Acked-by: Jason Cooper Reviewed-by: Dave Martin Acked-by: Olof Johansson Signed-off-by: Russell King diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 30eae87..0457ef4 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -268,7 +268,12 @@ else KBUILD_IMAGE := zImage endif -all: $(KBUILD_IMAGE) +# Build the DT binary blobs if we have OF configured +ifeq ($(CONFIG_USE_OF),y) +KBUILD_DTBS := dtbs +endif + +all: $(KBUILD_IMAGE) $(KBUILD_DTBS) boot := arch/arm/boot @@ -306,7 +311,7 @@ define archhelp echo ' uImage - U-Boot wrapped zImage' echo ' bootpImage - Combined zImage and initial RAM disk' echo ' (supply initrd image via make variable INITRD=)' - echo ' dtbs - Build device tree blobs for enabled boards' + echo '* dtbs - Build device tree blobs for enabled boards' echo ' install - Install uncompressed kernel' echo ' zinstall - Install compressed kernel' echo ' uinstall - Install U-Boot wrapped compressed kernel' -- cgit v0.10.2 From 38ef2ad5f1d704f1a41599fc70488ca51eb56d3f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 10 Sep 2012 16:36:37 +0100 Subject: ARM: 7531/1: mark kernelmode mem{cpy,set} non-experimental This feature was added in 2009, I've been using it off and on and never had any problems with it on my systems. I cannot see why it needs to be marked experimental, make it a normal feature and let us discover its possible shortcomings as people try to turn it on instead. Cc: Lennert Buytenhek Cc: Nicolas Pitre Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e91c7cd..aee8f3a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1855,8 +1855,8 @@ config ALIGNMENT_TRAP configuration it is safe to say N, otherwise say Y. config UACCESS_WITH_MEMCPY - bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)" - depends on MMU && EXPERIMENTAL + bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()" + depends on MMU default y if CPU_FEROCEON help Implement faster copy_to_user and clear_user methods for CPU -- cgit v0.10.2 From f48b5f12799dbabba4a9c799a9bef0775b2f977d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 7 Sep 2012 18:09:57 +0100 Subject: ARM: 7523/1: arch_timers: enable the use of the virtual timer At the moment, the arch_timer driver only uses the physical timer, which can cause problem if PL2 hasn't enabled PL1 access in CNTHCTL, which is likely in a virtualized environment. Instead, the virtual timer is always available. This patch enables the use of the virtual timer, unless no interrupt is provided in the DT for it, in which case it falls back to the physical timer. Signed-off-by: Marc Zyngier Signed-off-by: Russell King diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index cf25880..c4e20b6 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -27,13 +27,23 @@ #include static unsigned long arch_timer_rate; -static int arch_timer_ppi; -static int arch_timer_ppi2; + +enum ppi_nr { + PHYS_SECURE_PPI, + PHYS_NONSECURE_PPI, + VIRT_PPI, + HYP_PPI, + MAX_TIMER_PPI +}; + +static int arch_timer_ppi[MAX_TIMER_PPI]; static struct clock_event_device __percpu **arch_timer_evt; extern void init_current_timer_delay(unsigned long freq); +static bool arch_timer_use_virtual = true; + /* * Architected system timer support. */ @@ -46,50 +56,104 @@ extern void init_current_timer_delay(unsigned long freq); #define ARCH_TIMER_REG_FREQ 1 #define ARCH_TIMER_REG_TVAL 2 -static void arch_timer_reg_write(int reg, u32 val) +#define ARCH_TIMER_PHYS_ACCESS 0 +#define ARCH_TIMER_VIRT_ACCESS 1 + +/* + * These register accessors are marked inline so the compiler can + * nicely work out which register we want, and chuck away the rest of + * the code. At least it does so with a recent GCC (4.6.3). + */ +static inline void arch_timer_reg_write(const int access, const int reg, u32 val) { - switch (reg) { - case ARCH_TIMER_REG_CTRL: - asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); - break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); - break; + if (access == ARCH_TIMER_PHYS_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); + break; + } + } + + if (access == ARCH_TIMER_VIRT_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val)); + break; + } } isb(); } -static u32 arch_timer_reg_read(int reg) +static inline u32 arch_timer_reg_read(const int access, const int reg) { - u32 val; + u32 val = 0; + + if (access == ARCH_TIMER_PHYS_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); + break; + case ARCH_TIMER_REG_FREQ: + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val)); + break; + } + } - switch (reg) { - case ARCH_TIMER_REG_CTRL: - asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); - break; - case ARCH_TIMER_REG_FREQ: - asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val)); - break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); - break; - default: - BUG(); + if (access == ARCH_TIMER_VIRT_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val)); + break; + } } return val; } -static irqreturn_t arch_timer_handler(int irq, void *dev_id) +static inline cycle_t arch_timer_counter_read(const int access) { - struct clock_event_device *evt = *(struct clock_event_device **)dev_id; - unsigned long ctrl; + cycle_t cval = 0; + + if (access == ARCH_TIMER_PHYS_ACCESS) + asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval)); + + if (access == ARCH_TIMER_VIRT_ACCESS) + asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval)); + + return cval; +} - ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); +static inline cycle_t arch_counter_get_cntpct(void) +{ + return arch_timer_counter_read(ARCH_TIMER_PHYS_ACCESS); +} + +static inline cycle_t arch_counter_get_cntvct(void) +{ + return arch_timer_counter_read(ARCH_TIMER_VIRT_ACCESS); +} + +static irqreturn_t inline timer_handler(const int access, + struct clock_event_device *evt) +{ + unsigned long ctrl; + ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { ctrl |= ARCH_TIMER_CTRL_IT_MASK; - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); + arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); evt->event_handler(evt); return IRQ_HANDLED; } @@ -97,63 +161,100 @@ static irqreturn_t arch_timer_handler(int irq, void *dev_id) return IRQ_NONE; } -static void arch_timer_disable(void) +static irqreturn_t arch_timer_handler_virt(int irq, void *dev_id) { - unsigned long ctrl; + struct clock_event_device *evt = *(struct clock_event_device **)dev_id; - ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); - ctrl &= ~ARCH_TIMER_CTRL_ENABLE; - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); + return timer_handler(ARCH_TIMER_VIRT_ACCESS, evt); } -static void arch_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) +static irqreturn_t arch_timer_handler_phys(int irq, void *dev_id) { + struct clock_event_device *evt = *(struct clock_event_device **)dev_id; + + return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt); +} + +static inline void timer_set_mode(const int access, int mode) +{ + unsigned long ctrl; switch (mode) { case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: - arch_timer_disable(); + ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); + ctrl &= ~ARCH_TIMER_CTRL_ENABLE; + arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); break; default: break; } } -static int arch_timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) +static void arch_timer_set_mode_virt(enum clock_event_mode mode, + struct clock_event_device *clk) { - unsigned long ctrl; + timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode); +} + +static void arch_timer_set_mode_phys(enum clock_event_mode mode, + struct clock_event_device *clk) +{ + timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode); +} - ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); +static inline void set_next_event(const int access, unsigned long evt) +{ + unsigned long ctrl; + ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; + arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt); + arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); +} - arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt); - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); +static int arch_timer_set_next_event_virt(unsigned long evt, + struct clock_event_device *unused) +{ + set_next_event(ARCH_TIMER_VIRT_ACCESS, evt); + return 0; +} +static int arch_timer_set_next_event_phys(unsigned long evt, + struct clock_event_device *unused) +{ + set_next_event(ARCH_TIMER_PHYS_ACCESS, evt); return 0; } static int __cpuinit arch_timer_setup(struct clock_event_device *clk) { - /* Be safe... */ - arch_timer_disable(); - clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; clk->name = "arch_sys_timer"; clk->rating = 450; - clk->set_mode = arch_timer_set_mode; - clk->set_next_event = arch_timer_set_next_event; - clk->irq = arch_timer_ppi; + if (arch_timer_use_virtual) { + clk->irq = arch_timer_ppi[VIRT_PPI]; + clk->set_mode = arch_timer_set_mode_virt; + clk->set_next_event = arch_timer_set_next_event_virt; + } else { + clk->irq = arch_timer_ppi[PHYS_SECURE_PPI]; + clk->set_mode = arch_timer_set_mode_phys; + clk->set_next_event = arch_timer_set_next_event_phys; + } + + clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, NULL); clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); *__this_cpu_ptr(arch_timer_evt) = clk; - enable_percpu_irq(clk->irq, 0); - if (arch_timer_ppi2) - enable_percpu_irq(arch_timer_ppi2, 0); + if (arch_timer_use_virtual) + enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0); + else { + enable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], 0); + if (arch_timer_ppi[PHYS_NONSECURE_PPI]) + enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0); + } return 0; } @@ -173,8 +274,8 @@ static int arch_timer_available(void) return -ENXIO; if (arch_timer_rate == 0) { - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0); - freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ); + freq = arch_timer_reg_read(ARCH_TIMER_PHYS_ACCESS, + ARCH_TIMER_REG_FREQ); /* Check the timer frequency. */ if (freq == 0) { @@ -185,43 +286,42 @@ static int arch_timer_available(void) arch_timer_rate = freq; } - pr_info_once("Architected local timer running at %lu.%02luMHz.\n", - arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100); + pr_info_once("Architected local timer running at %lu.%02luMHz (%s).\n", + arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100, + arch_timer_use_virtual ? "virt" : "phys"); return 0; } -static inline cycle_t arch_counter_get_cntpct(void) +static u32 notrace arch_counter_get_cntpct32(void) { - u32 cvall, cvalh; - - asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh)); + cycle_t cnt = arch_counter_get_cntpct(); - return ((cycle_t) cvalh << 32) | cvall; -} - -static inline cycle_t arch_counter_get_cntvct(void) -{ - u32 cvall, cvalh; - - asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh)); - - return ((cycle_t) cvalh << 32) | cvall; + /* + * The sched_clock infrastructure only knows about counters + * with at most 32bits. Forget about the upper 24 bits for the + * time being... + */ + return (u32)cnt; } static u32 notrace arch_counter_get_cntvct32(void) { - cycle_t cntvct = arch_counter_get_cntvct(); + cycle_t cnt = arch_counter_get_cntvct(); /* * The sched_clock infrastructure only knows about counters * with at most 32bits. Forget about the upper 24 bits for the * time being... */ - return (u32)(cntvct & (u32)~0); + return (u32)cnt; } static cycle_t arch_counter_read(struct clocksource *cs) { + /* + * Always use the physical counter for the clocksource. + * CNTHCTL.PL1PCTEN must be set to 1. + */ return arch_counter_get_cntpct(); } @@ -245,10 +345,16 @@ static void __cpuinit arch_timer_stop(struct clock_event_device *clk) { pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", clk->irq, smp_processor_id()); - disable_percpu_irq(clk->irq); - if (arch_timer_ppi2) - disable_percpu_irq(arch_timer_ppi2); - arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk); + + if (arch_timer_use_virtual) + disable_percpu_irq(arch_timer_ppi[VIRT_PPI]); + else { + disable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI]); + if (arch_timer_ppi[PHYS_NONSECURE_PPI]) + disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]); + } + + clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk); } static struct local_timer_ops arch_timer_ops __cpuinitdata = { @@ -261,36 +367,44 @@ static struct clock_event_device arch_timer_global_evt; static int __init arch_timer_register(void) { int err; + int ppi; err = arch_timer_available(); if (err) - return err; + goto out; arch_timer_evt = alloc_percpu(struct clock_event_device *); - if (!arch_timer_evt) - return -ENOMEM; + if (!arch_timer_evt) { + err = -ENOMEM; + goto out; + } clocksource_register_hz(&clocksource_counter, arch_timer_rate); - err = request_percpu_irq(arch_timer_ppi, arch_timer_handler, - "arch_timer", arch_timer_evt); + if (arch_timer_use_virtual) { + ppi = arch_timer_ppi[VIRT_PPI]; + err = request_percpu_irq(ppi, arch_timer_handler_virt, + "arch_timer", arch_timer_evt); + } else { + ppi = arch_timer_ppi[PHYS_SECURE_PPI]; + err = request_percpu_irq(ppi, arch_timer_handler_phys, + "arch_timer", arch_timer_evt); + if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) { + ppi = arch_timer_ppi[PHYS_NONSECURE_PPI]; + err = request_percpu_irq(ppi, arch_timer_handler_phys, + "arch_timer", arch_timer_evt); + if (err) + free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], + arch_timer_evt); + } + } + if (err) { pr_err("arch_timer: can't register interrupt %d (%d)\n", - arch_timer_ppi, err); + ppi, err); goto out_free; } - if (arch_timer_ppi2) { - err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler, - "arch_timer", arch_timer_evt); - if (err) { - pr_err("arch_timer: can't register interrupt %d (%d)\n", - arch_timer_ppi2, err); - arch_timer_ppi2 = 0; - goto out_free_irq; - } - } - err = local_timer_register(&arch_timer_ops); if (err) { /* @@ -310,13 +424,19 @@ static int __init arch_timer_register(void) return 0; out_free_irq: - free_percpu_irq(arch_timer_ppi, arch_timer_evt); - if (arch_timer_ppi2) - free_percpu_irq(arch_timer_ppi2, arch_timer_evt); + if (arch_timer_use_virtual) + free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt); + else { + free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], + arch_timer_evt); + if (arch_timer_ppi[PHYS_NONSECURE_PPI]) + free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], + arch_timer_evt); + } out_free: free_percpu(arch_timer_evt); - +out: return err; } @@ -329,6 +449,7 @@ int __init arch_timer_of_register(void) { struct device_node *np; u32 freq; + int i; np = of_find_matching_node(NULL, arch_timer_of_match); if (!np) { @@ -340,22 +461,40 @@ int __init arch_timer_of_register(void) if (!of_property_read_u32(np, "clock-frequency", &freq)) arch_timer_rate = freq; - arch_timer_ppi = irq_of_parse_and_map(np, 0); - arch_timer_ppi2 = irq_of_parse_and_map(np, 1); - pr_info("arch_timer: found %s irqs %d %d\n", - np->name, arch_timer_ppi, arch_timer_ppi2); + for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++) + arch_timer_ppi[i] = irq_of_parse_and_map(np, i); + + /* + * If no interrupt provided for virtual timer, we'll have to + * stick to the physical timer. It'd better be accessible... + */ + if (!arch_timer_ppi[VIRT_PPI]) { + arch_timer_use_virtual = false; + + if (!arch_timer_ppi[PHYS_SECURE_PPI] || + !arch_timer_ppi[PHYS_NONSECURE_PPI]) { + pr_warn("arch_timer: No interrupt available, giving up\n"); + return -EINVAL; + } + } return arch_timer_register(); } int __init arch_timer_sched_clock_init(void) { + u32 (*cnt32)(void); int err; err = arch_timer_available(); if (err) return err; - setup_sched_clock(arch_counter_get_cntvct32, 32, arch_timer_rate); + if (arch_timer_use_virtual) + cnt32 = arch_counter_get_cntvct32; + else + cnt32 = arch_counter_get_cntpct32; + + setup_sched_clock(cnt32, 32, arch_timer_rate); return 0; } -- cgit v0.10.2 From a1b2dde70419ae947fd7c9c8fcad7da005dc600e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 7 Sep 2012 18:09:58 +0100 Subject: ARM: 7522/1: arch_timers: register a time/cycle counter Some subsystems (KVM for example) need access to a cycle counter. In the KVM case, this is used to measure the time delta between host and guest in order to accurately generate timer events for the guest. Signed-off-by: Marc Zyngier Signed-off-by: Russell King diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 62e7547..ad9b155 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -2,11 +2,13 @@ #define __ASMARM_ARCH_TIMER_H #include +#include #ifdef CONFIG_ARM_ARCH_TIMER #define ARCH_HAS_READ_CURRENT_TIMER int arch_timer_of_register(void); int arch_timer_sched_clock_init(void); +struct timecounter *arch_timer_get_timecounter(void); #else static inline int arch_timer_of_register(void) { @@ -17,6 +19,11 @@ static inline int arch_timer_sched_clock_init(void) { return -ENXIO; } + +static inline struct timecounter *arch_timer_get_timecounter(void) +{ + return NULL; +} #endif #endif diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index c4e20b6..c04c2a6 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -333,6 +333,15 @@ int read_current_timer(unsigned long *timer_val) return 0; } +static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) +{ + /* + * Always use the physical counter for the clocksource. + * CNTHCTL.PL1PCTEN must be set to 1. + */ + return arch_counter_get_cntpct(); +} + static struct clocksource clocksource_counter = { .name = "arch_sys_counter", .rating = 400, @@ -341,6 +350,18 @@ static struct clocksource clocksource_counter = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static struct cyclecounter cyclecounter = { + .read = arch_counter_read_cc, + .mask = CLOCKSOURCE_MASK(56), +}; + +static struct timecounter timecounter; + +struct timecounter *arch_timer_get_timecounter(void) +{ + return &timecounter; +} + static void __cpuinit arch_timer_stop(struct clock_event_device *clk) { pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", @@ -380,6 +401,10 @@ static int __init arch_timer_register(void) } clocksource_register_hz(&clocksource_counter, arch_timer_rate); + cyclecounter.mult = clocksource_counter.mult; + cyclecounter.shift = clocksource_counter.shift; + timecounter_init(&timecounter, &cyclecounter, + arch_counter_get_cntpct()); if (arch_timer_use_virtual) { ppi = arch_timer_ppi[VIRT_PPI]; -- cgit v0.10.2 From 9bf26a180578b92890ed77890d4e9e9807adcda3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 6 Sep 2012 09:06:52 +0100 Subject: ARM: 7514/1: integrator: call common init function from machine There is currently a common integrator_init() function set up to be called from an arch_initcall(). The problem is that it is using machine_is_integrator() which is not working with device tree, let's call this from respective machine initilization function and add a parameter to tell whether it's the Integrator/AP or Integrator/CP instead. There are still machine_is*() calls in the Integrator machines directory, but this one needs to be fixed lest we don't even get a UART console on the Integrator/AP after a Device Tree boot. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index 899561d..c4338e2 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1,3 +1,4 @@ void integrator_init_early(void); +int integrator_init(bool is_cp); void integrator_reserve(void); void integrator_restart(char, const char *); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 3fa6c51..5ba4bc8 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -61,7 +61,7 @@ static struct amba_device *amba_devs[] __initdata = { &kmi1_device, }; -static int __init integrator_init(void) +int __init integrator_init(bool is_cp) { int i; @@ -70,7 +70,7 @@ static int __init integrator_init(void) * hard-code them. The Integator/CP and forward have proper cell IDs. * Else we leave them undefined to the bus driver can autoprobe them. */ - if (machine_is_integrator()) { + if (!is_cp) { rtc_device.periphid = 0x00041030; uart0_device.periphid = 0x00041010; uart1_device.periphid = 0x00041010; @@ -86,8 +86,6 @@ static int __init integrator_init(void) return 0; } -arch_initcall(integrator_init); - /* * On the Integrator platform, the port RTS and DTR are provided by * bits in the following SC_CTRLS register bits: diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 3b22675..ff966d8 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -312,6 +312,8 @@ static void __init ap_init(void) lm_device_register(lmdev); } + + integrator_init(false); } /* diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 82d5c83..2b40bc1 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -366,6 +366,7 @@ static void __init intcp_init(void) struct amba_device *d = amba_devs[i]; amba_device_register(d, &iomem_resource); } + integrator_init(true); } #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) -- cgit v0.10.2 From 2c88543b953581f70f05bf133a1b8f196c48ef23 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 6 Sep 2012 09:07:27 +0100 Subject: ARM: 7515/1: integrator: check PL010 base address from resource In the PL010 UART callback a comparison against the location of the statically allocated PL010 device is done to figure out which UART is doing the callback. This does not play well with dynamic devices such as in device tree, so let's check the base address of the memory resource inside the amba_device instead. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 5ba4bc8..268eadf 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -99,11 +99,14 @@ int __init integrator_init(bool is_cp) static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl) { unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; + u32 phybase = dev->res.start; - if (dev == &uart0_device) { + if (phybase == INTEGRATOR_UART0_BASE) { + /* UART0 */ rts_mask = 1 << 4; dtr_mask = 1 << 5; } else { + /* UART1 */ rts_mask = 1 << 6; dtr_mask = 1 << 7; } -- cgit v0.10.2 From 9bc1503185a09930782012fda5601694caeec77a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 6 Sep 2012 09:07:57 +0100 Subject: ARM: 7516/1: plat-versatile: add DT support to FPGA IRQ This adds Device Tree probing support to the Versatile FPGA IRQ controller. Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt new file mode 100644 index 0000000..9989eda --- /dev/null +++ b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt @@ -0,0 +1,31 @@ +* ARM Versatile FPGA interrupt controller + +One or more FPGA IRQ controllers can be synthesized in an ARM reference board +such as the Integrator or Versatile family. The output of these different +controllers are OR:ed together and fed to the CPU tile's IRQ input. Each +instance can handle up to 32 interrupts. + +Required properties: +- compatible: "arm,versatile-fpga-irq" +- interrupt-controller: Identifies the node as an interrupt controller +- #interrupt-cells: The number of cells to define the interrupts. Must be 1 + as the FPGA IRQ controller has no configuration options for interrupt + sources. The cell is a u32 and defines the interrupt number. +- reg: The register bank for the FPGA interrupt controller. +- clear-mask: a u32 number representing the mask written to clear all IRQs + on the controller at boot for example. +- valid-mask: a u32 number representing a bit mask determining which of + the interrupts are valid. Unconnected/unused lines are set to 0, and + the system till not make it possible for devices to request these + interrupts. + +Example: + +pic: pic@14000000 { + compatible = "arm,versatile-fpga-irq"; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0x14000000 0x100>; + clear-mask = <0xffffffff>; + valid-mask = <0x003fffff>; +}; diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c index 6e70d03..091ae10 100644 --- a/arch/arm/plat-versatile/fpga-irq.c +++ b/arch/arm/plat-versatile/fpga-irq.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -14,11 +16,17 @@ #define IRQ_RAW_STATUS 0x04 #define IRQ_ENABLE_SET 0x08 #define IRQ_ENABLE_CLEAR 0x0c +#define INT_SOFT_SET 0x10 +#define INT_SOFT_CLEAR 0x14 +#define FIQ_STATUS 0x20 +#define FIQ_RAW_STATUS 0x24 +#define FIQ_ENABLE 0x28 +#define FIQ_ENABLE_SET 0x28 +#define FIQ_ENABLE_CLEAR 0x2C /** * struct fpga_irq_data - irq data container for the FPGA IRQ controller * @base: memory offset in virtual memory - * @irq_start: first IRQ number handled by this instance * @chip: chip container for this instance * @domain: IRQ domain for this instance * @valid: mask for valid IRQs on this controller @@ -26,7 +34,6 @@ */ struct fpga_irq_data { void __iomem *base; - unsigned int irq_start; struct irq_chip chip; u32 valid; struct irq_domain *domain; @@ -125,34 +132,79 @@ static struct irq_domain_ops fpga_irqdomain_ops = { .xlate = irq_domain_xlate_onetwocell, }; -void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, - int parent_irq, u32 valid, struct device_node *node) -{ +static __init struct fpga_irq_data * +fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) { struct fpga_irq_data *f; if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); - return; + return NULL; } - f = &fpga_irq_devices[fpga_irq_id]; f->base = base; - f->irq_start = irq_start; f->chip.name = name; f->chip.irq_ack = fpga_irq_mask; f->chip.irq_mask = fpga_irq_mask; f->chip.irq_unmask = fpga_irq_unmask; f->valid = valid; + fpga_irq_id++; + + return f; +} + +void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, + int parent_irq, u32 valid, struct device_node *node) +{ + struct fpga_irq_data *f; + + f = fpga_irq_prep_struct(base, name, valid); + if (!f) + return; if (parent_irq != -1) { irq_set_handler_data(parent_irq, f); irq_set_chained_handler(parent_irq, fpga_irq_handle); } - f->domain = irq_domain_add_legacy(node, fls(valid), f->irq_start, 0, + f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0, &fpga_irqdomain_ops, f); pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", fpga_irq_id, name, base, f->used_irqs); +} - fpga_irq_id++; +#ifdef CONFIG_OF +int __init fpga_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + struct fpga_irq_data *f; + void __iomem *base; + u32 clear_mask; + u32 valid_mask; + + if (WARN_ON(!node)) + return -ENODEV; + + base = of_iomap(node, 0); + WARN(!base, "unable to map fpga irq registers\n"); + + if (of_property_read_u32(node, "clear-mask", &clear_mask)) + clear_mask = 0; + + if (of_property_read_u32(node, "valid-mask", &valid_mask)) + valid_mask = 0; + + f = fpga_irq_prep_struct(base, node->name, valid_mask); + if (!f) + return -ENOMEM; + + writel(clear_mask, base + IRQ_ENABLE_CLEAR); + writel(clear_mask, base + FIQ_ENABLE_CLEAR); + + f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f); + f->used_irqs = hweight32(valid_mask); + + pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", + fpga_irq_id, node->name, base, f->used_irqs); + return 0; } +#endif diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h index 91bcfb6..1fac965 100644 --- a/arch/arm/plat-versatile/include/plat/fpga-irq.h +++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h @@ -7,5 +7,7 @@ struct pt_regs; void fpga_handle_irq(struct pt_regs *regs); void fpga_irq_init(void __iomem *, const char *, int, int, u32, struct device_node *node); +int fpga_irq_of_init(struct device_node *node, + struct device_node *parent); #endif -- cgit v0.10.2 From 4980f9bc2cec0f8ff0e0f2b021d46c7606ae1849 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 6 Sep 2012 09:08:24 +0100 Subject: ARM: 7517/1: integrator: initial device tree support This is initial device tree support for the ARM Integrator family, we create a very basic device tree, #ifdef out the non-DT machines when compiling for device tree. Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 91f2614..fc81a7d 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -1,3 +1,15 @@ +ARM Integrator/AP (Application Platform) and Integrator/CP (Compact Platform) +----------------------------------------------------------------------------- +ARM's oldest Linux-supported platform with connectors for different core +tiles of ARMv4, ARMv5 and ARMv6 type. + +Required properties (in root node): + compatible = "arm,integrator-ap"; /* Application Platform */ + compatible = "arm,integrator-cp"; /* Compact Platform */ + +FPGA type interrupt controllers, see the versatile-fpga-irq binding doc. + + ARM Versatile Application and Platform Baseboards ------------------------------------------------- ARM's development hardware platform with connectors for customizable diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi new file mode 100644 index 0000000..b464aba --- /dev/null +++ b/arch/arm/boot/dts/integrator.dtsi @@ -0,0 +1,33 @@ +/* + * SoC core Device Tree for the ARM Integrator platforms + */ + +/include/ "skeleton.dtsi" + +/ { + timer@13000000 { + reg = <0x13000000 0x100>; + interrupt-parent = <&pic>; + interrupts = <5>; + }; + + timer@13000100 { + reg = <0x13000100 0x100>; + interrupt-parent = <&pic>; + interrupts = <6>; + }; + + timer@13000200 { + reg = <0x13000200 0x100>; + interrupt-parent = <&pic>; + interrupts = <7>; + }; + + pic@14000000 { + compatible = "arm,versatile-fpga-irq"; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0x14000000 0x100>; + clear-mask = <0xffffffff>; + }; +}; diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts new file mode 100644 index 0000000..083ff39 --- /dev/null +++ b/arch/arm/boot/dts/integratorap.dts @@ -0,0 +1,36 @@ +/* + * Device Tree for the ARM Integrator/AP platform + */ + +/dts-v1/; +/include/ "integrator.dtsi" + +/ { + model = "ARM Integrator/AP"; + compatible = "arm,integrator-ap"; + + aliases { + arm,timer-primary = &timer2; + arm,timer-secondary = &timer1; + }; + + chosen { + bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; + }; + + timer0: timer@13000000 { + compatible = "arm,integrator-timer"; + }; + + timer1: timer@13000100 { + compatible = "arm,integrator-timer"; + }; + + timer2: timer@13000200 { + compatible = "arm,integrator-timer"; + }; + + pic: pic@14000000 { + valid-mask = <0x003fffff>; + }; +}; diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts new file mode 100644 index 0000000..6303314 --- /dev/null +++ b/arch/arm/boot/dts/integratorcp.dts @@ -0,0 +1,54 @@ +/* + * Device Tree for the ARM Integrator/CP platform + */ + +/dts-v1/; +/include/ "integrator.dtsi" + +/ { + model = "ARM Integrator/CP"; + compatible = "arm,integrator-cp"; + + aliases { + arm,timer-primary = &timer2; + arm,timer-secondary = &timer1; + }; + + chosen { + bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; + }; + + timer0: timer@13000000 { + compatible = "arm,sp804", "arm,primecell"; + }; + + timer1: timer@13000100 { + compatible = "arm,sp804", "arm,primecell"; + }; + + timer2: timer@13000200 { + compatible = "arm,sp804", "arm,primecell"; + }; + + pic: pic@14000000 { + valid-mask = <0x1fc003ff>; + }; + + cic: cic@10000040 { + compatible = "arm,versatile-fpga-irq"; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0x10000040 0x100>; + clear-mask = <0xffffffff>; + valid-mask = <0x00000007>; + }; + + sic: sic@ca000000 { + compatible = "arm,versatile-fpga-irq"; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0xca000000 0x100>; + clear-mask = <0x00000fff>; + valid-mask = <0x00000fff>; + }; +}; diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index ff966d8..57add86 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include