diff --git a/[refs] b/[refs] index 24219c2af9b5..a5fbf24851a4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 976eb445e2051735346779dbdaeb681c7641fec4 +refs/heads/master: 8c3d4534a8da0dc6a2d52b61585e61f7e8143096 diff --git a/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc b/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc index e960cd027e1e..2a7f9a00cb0a 100644 --- a/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc +++ b/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc @@ -1,5 +1,5 @@ -What: /sys/bus/usb/drivers/usbtmc/*/interface_capabilities -What: /sys/bus/usb/drivers/usbtmc/*/device_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -12,8 +12,8 @@ Description: The files are read only. -What: /sys/bus/usb/drivers/usbtmc/*/usb488_interface_capabilities -What: /sys/bus/usb/drivers/usbtmc/*/usb488_device_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -27,7 +27,7 @@ Description: The files are read only. -What: /sys/bus/usb/drivers/usbtmc/*/TermChar +What: /sys/bus/usb/drivers/usbtmc/devices/*/TermChar Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -40,7 +40,7 @@ Description: sent to the device or not. -What: /sys/bus/usb/drivers/usbtmc/*/TermCharEnabled +What: /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -51,7 +51,7 @@ Description: published by the USB-IF. -What: /sys/bus/usb/drivers/usbtmc/*/auto_abort +What: /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort Date: August 2008 Contact: Greg Kroah-Hartman Description: diff --git a/trunk/Documentation/ABI/testing/sysfs-block-rssd b/trunk/Documentation/ABI/testing/sysfs-block-rssd deleted file mode 100644 index d535757799fe..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-block-rssd +++ /dev/null @@ -1,18 +0,0 @@ -What: /sys/block/rssd*/registers -Date: March 2012 -KernelVersion: 3.3 -Contact: Asai Thambi S P -Description: This is a read-only file. Dumps below driver information and - hardware registers. - - S ACTive - - Command Issue - - Allocated - - Completed - - PORT IRQ STAT - - HOST IRQ STAT - -What: /sys/block/rssd*/status -Date: April 2012 -KernelVersion: 3.4 -Contact: Asai Thambi S P -Description: This is a read-only file. Indicates the status of the device. diff --git a/trunk/Documentation/ABI/testing/sysfs-cfq-target-latency b/trunk/Documentation/ABI/testing/sysfs-cfq-target-latency deleted file mode 100644 index df0f7828c5e3..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-cfq-target-latency +++ /dev/null @@ -1,8 +0,0 @@ -What: /sys/block//iosched/target_latency -Date: March 2012 -contact: Tao Ma -Description: - The /sys/block//iosched/target_latency only exists - when the user sets cfq to /sys/block//scheduler. - It contains an estimated latency time for the cfq. cfq will - use it to calculate the time slice used for every task. diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml index 5274c24d11e0..3fd3ce5df270 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_NV12M ('NM12') + V4L2_PIX_FMT_NV12M ('NV12M') &manvol; diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index 60308f1eefdf..9957863daf18 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_YUV420M ('YM12') + V4L2_PIX_FMT_YUV420M ('YU12M') &manvol; diff --git a/trunk/Documentation/arm/00-INDEX b/trunk/Documentation/arm/00-INDEX index 36420e116c90..91c24a1e8a9e 100644 --- a/trunk/Documentation/arm/00-INDEX +++ b/trunk/Documentation/arm/00-INDEX @@ -4,6 +4,8 @@ Booting - requirements for booting Interrupts - ARM Interrupt subsystem documentation +IXP2000 + - Release Notes for Linux on Intel's IXP2000 Network Processor msm - MSM specific documentation Netwinder diff --git a/trunk/Documentation/arm/IXP2000 b/trunk/Documentation/arm/IXP2000 new file mode 100644 index 000000000000..68d21d92a30b --- /dev/null +++ b/trunk/Documentation/arm/IXP2000 @@ -0,0 +1,69 @@ + +------------------------------------------------------------------------- +Release Notes for Linux on Intel's IXP2000 Network Processor + +Maintained by Deepak Saxena +------------------------------------------------------------------------- + +1. Overview + +Intel's IXP2000 family of NPUs (IXP2400, IXP2800, IXP2850) is designed +for high-performance network applications such high-availability +telecom systems. In addition to an XScale core, it contains up to 8 +"MicroEngines" that run special code, several high-end networking +interfaces (UTOPIA, SPI, etc), a PCI host bridge, one serial port, +flash interface, and some other odds and ends. For more information, see: + +http://developer.intel.com + +2. Linux Support + +Linux currently supports the following features on the IXP2000 NPUs: + +- On-chip serial +- PCI +- Flash (MTD/JFFS2) +- I2C through GPIO +- Timers (watchdog, OS) + +That is about all we can support under Linux ATM b/c the core networking +components of the chip are accessed via Intel's closed source SDK. +Please contact Intel directly on issues with using those. There is +also a mailing list run by some folks at Princeton University that might +be of help: https://lists.cs.princeton.edu/mailman/listinfo/ixp2xxx + +WHATEVER YOU DO, DO NOT POST EMAIL TO THE LINUX-ARM OR LINUX-ARM-KERNEL +MAILING LISTS REGARDING THE INTEL SDK. + +3. Supported Platforms + +- Intel IXDP2400 Reference Platform +- Intel IXDP2800 Reference Platform +- Intel IXDP2401 Reference Platform +- Intel IXDP2801 Reference Platform +- RadiSys ENP-2611 + +4. Usage Notes + +- The IXP2000 platforms usually have rather complex PCI bus topologies + with large memory space requirements. In addition, b/c of the way the + Intel SDK is designed, devices are enumerated in a very specific + way. B/c of this this, we use "pci=firmware" option in the kernel + command line so that we do not re-enumerate the bus. + +- IXDP2x01 systems have variable clock tick rates that we cannot determine + via HW registers. The "ixdp2x01_clk=XXX" cmd line options allow you + to pass the clock rate to the board port. + +5. Thanks + +The IXP2000 work has been funded by Intel Corp. and MontaVista Software, Inc. + +The following people have contributed patches/comments/etc: + +Naeem F. Afzal +Lennert Buytenhek +Jeffrey Daly + +------------------------------------------------------------------------- +Last Update: 8/09/2004 diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 9b1067afb224..4c95c0034a4b 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -34,7 +34,8 @@ Current Status: linux-2.6.34-mmotm(development version of 2010/April) Features: - accounting anonymous pages, file caches, swap caches usage and limiting them. - - pages are linked to per-memcg LRU exclusively, and there is no global LRU. + - private LRU and reclaim routine. (system's global LRU and private LRU + work independently from each other) - optionally, memory+swap usage can be accounted and limited. - hierarchical accounting - soft limit @@ -153,7 +154,7 @@ updated. page_cgroup has its own LRU on cgroup. 2.2.1 Accounting details All mapped anon pages (RSS) and cache pages (Page Cache) are accounted. -Some pages which are never reclaimable and will not be on the LRU +Some pages which are never reclaimable and will not be on the global LRU are not accounted. We just account pages under usual VM management. RSS pages are accounted at page_fault unless they've already been accounted diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 03ca210406ed..709e08e9a222 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -531,11 +531,3 @@ Why: There appear to be no production users of the get_robust_list syscall, of ASLR. It was only ever intended for debugging, so it should be removed. Who: Kees Cook - ----------------------------- - -What: setitimer accepts user NULL pointer (value) -When: 3.6 -Why: setitimer is not returning -EFAULT if user pointer is NULL. This - violates the spec. -Who: Sasikantha Babu diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index 0d0492028082..e916e3d36488 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -114,7 +114,7 @@ members are defined: struct file_system_type { const char *name; int fs_flags; - struct dentry *(*mount) (struct file_system_type *, int, + struct dentry (*mount) (struct file_system_type *, int, const char *, void *); void (*kill_sb) (struct super_block *); struct module *owner; diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index 03f7897c6414..d97d992ced14 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -43,9 +43,7 @@ ALC680 ALC882/883/885/888/889 ====================== - acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G - acer-aspire-8930g Acer Aspire 8330G/6935G - acer-aspire Acer Aspire others + N/A ALC861/660 ========== diff --git a/trunk/Documentation/usb/URB.txt b/trunk/Documentation/usb/URB.txt index 00d2c644068e..8ffce746d496 100644 --- a/trunk/Documentation/usb/URB.txt +++ b/trunk/Documentation/usb/URB.txt @@ -168,28 +168,6 @@ that if the completion handler or anyone else tries to resubmit it they will get a -EPERM error. Thus you can be sure that when usb_kill_urb() returns, the URB is totally idle. -There is a lifetime issue to consider. An URB may complete at any -time, and the completion handler may free the URB. If this happens -while usb_unlink_urb or usb_kill_urb is running, it will cause a -memory-access violation. The driver is responsible for avoiding this, -which often means some sort of lock will be needed to prevent the URB -from being deallocated while it is still in use. - -On the other hand, since usb_unlink_urb may end up calling the -completion handler, the handler must not take any lock that is held -when usb_unlink_urb is invoked. The general solution to this problem -is to increment the URB's reference count while holding the lock, then -drop the lock and call usb_unlink_urb or usb_kill_urb, and then -decrement the URB's reference count. You increment the reference -count by calling - - struct urb *usb_get_urb(struct urb *urb) - -(ignore the return value; it is the same as the argument) and -decrement the reference count by calling usb_free_urb. Of course, -none of this is necessary if there's no danger of the URB being freed -by the completion handler. - 1.7. What about the completion handler? diff --git a/trunk/Documentation/usb/usbmon.txt b/trunk/Documentation/usb/usbmon.txt index c42bb9cd3b43..5335fa8b06eb 100644 --- a/trunk/Documentation/usb/usbmon.txt +++ b/trunk/Documentation/usb/usbmon.txt @@ -183,10 +183,10 @@ An input control transfer to get a port status. d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 -An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte -Bulk wrapper to a storage device at address 5: +An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper +to a storage device at address 5: -dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000 +dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 dd65f0e8 4128379808 C Bo:1:005:2 0 31 > * Raw binary format and API diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 069ec4030395..2dcfca850639 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -640,6 +640,13 @@ S: Maintained F: drivers/amba/ F: include/linux/amba/bus.h +ARM/ADI ROADRUNNER MACHINE SUPPORT +M: Lennert Buytenhek +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-ixp23xx/ +F: arch/arm/mach-ixp23xx/include/mach/ + ARM/ADS SPHERE MACHINE SUPPORT M: Lennert Buytenhek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -852,11 +859,21 @@ M: Dan Williams L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +ARM/INTEL IXP2000 ARM ARCHITECTURE +M: Lennert Buytenhek +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained + ARM/INTEL IXDP2850 MACHINE SUPPORT M: Lennert Buytenhek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +ARM/INTEL IXP23XX ARM ARCHITECTURE +M: Lennert Buytenhek +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained + ARM/INTEL IXP4XX ARM ARCHITECTURE M: Imre Kaloz M: Krzysztof Halasa @@ -1504,8 +1521,8 @@ M: Gustavo Padovan M: Johan Hedberg L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git S: Maintained F: drivers/bluetooth/ @@ -1515,8 +1532,8 @@ M: Gustavo Padovan M: Johan Hedberg L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git S: Maintained F: net/bluetooth/ F: include/net/bluetooth/ @@ -2304,9 +2321,9 @@ S: Supported F: drivers/acpi/dock.c DOCUMENTATION -M: Rob Landley +M: Randy Dunlap L: linux-doc@vger.kernel.org -T: TBD +T: quilt http://xenotime.net/kernel-doc-patches/current/ S: Maintained F: Documentation/ @@ -4516,7 +4533,8 @@ S: Supported F: drivers/net/ethernet/myricom/myri10ge/ NATSEMI ETHERNET DRIVER (DP8381x) -S: Orphan +M: Tim Hockin +S: Maintained F: drivers/net/ethernet/natsemi/natsemi.c NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER @@ -4785,7 +4803,6 @@ F: arch/arm/mach-omap2/clockdomain2xxx_3xxx.c F: arch/arm/mach-omap2/clockdomain44xx.c OMAP AUDIO SUPPORT -M: Peter Ujfalusi M: Jarkko Nikula L: alsa-devel@alsa-project.org (subscribers-only) L: linux-omap@vger.kernel.org @@ -5100,11 +5117,6 @@ F: drivers/i2c/busses/i2c-pca-* F: include/linux/i2c-algo-pca.h F: include/linux/i2c-pca-platform.h -PCDP - PRIMARY CONSOLE AND DEBUG PORT -M: Khalid Aziz -S: Maintained -F: drivers/firmware/pcdp.* - PCI ERROR RECOVERY M: Linas Vepstas L: linux-pci@vger.kernel.org @@ -6454,7 +6466,6 @@ S: Odd Fixes F: drivers/staging/olpc_dcon/ STAGING - OZMO DEVICES USB OVER WIFI DRIVER -M: Rupesh Gujare M: Chris Kelly S: Maintained F: drivers/staging/ozwpan/ @@ -7450,7 +7461,8 @@ F: include/linux/wm97xx.h WOLFSON MICROELECTRONICS DRIVERS M: Mark Brown -L: patches@opensource.wolfsonmicro.com +M: Ian Lartey +M: Dimitris Papastamos T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices diff --git a/trunk/Makefile b/trunk/Makefile index afc868e6c75d..0df3d003a079 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc2 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/alpha/include/asm/atomic.h b/trunk/arch/alpha/include/asm/atomic.h index 3bb7ffeae3bc..f62251e82ffa 100644 --- a/trunk/arch/alpha/include/asm/atomic.h +++ b/trunk/arch/alpha/include/asm/atomic.h @@ -3,7 +3,6 @@ #include #include -#include /* * Atomic operations that C can't guarantee us. Useful for @@ -169,6 +168,73 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) return result; } +/* + * Atomic exchange routines. + */ + +#define __ASM__MB +#define ____xchg(type, args...) __xchg ## type ## _local(args) +#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) +#include + +#define xchg_local(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ + }) + +#define cmpxchg_local(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, \ + sizeof(*(ptr))); \ + }) + +#define cmpxchg64_local(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_local((ptr), (o), (n)); \ + }) + +#ifdef CONFIG_SMP +#undef __ASM__MB +#define __ASM__MB "\tmb\n" +#endif +#undef ____xchg +#undef ____cmpxchg +#define ____xchg(type, args...) __xchg ##type(args) +#define ____cmpxchg(type, args...) __cmpxchg ##type(args) +#include + +#define xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ + }) + +#define cmpxchg(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr)));\ + }) + +#define cmpxchg64(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg((ptr), (o), (n)); \ + }) + +#undef __ASM__MB +#undef ____cmpxchg + +#define __HAVE_ARCH_CMPXCHG 1 + #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) diff --git a/trunk/arch/alpha/include/asm/cmpxchg.h b/trunk/arch/alpha/include/asm/cmpxchg.h deleted file mode 100644 index 429e8cd0d78e..000000000000 --- a/trunk/arch/alpha/include/asm/cmpxchg.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _ALPHA_CMPXCHG_H -#define _ALPHA_CMPXCHG_H - -/* - * Atomic exchange routines. - */ - -#define __ASM__MB -#define ____xchg(type, args...) __xchg ## type ## _local(args) -#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) -#include - -#define xchg_local(ptr, x) \ -({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ -}) - -#define cmpxchg_local(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, \ - sizeof(*(ptr))); \ -}) - -#define cmpxchg64_local(ptr, o, n) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg_local((ptr), (o), (n)); \ -}) - -#ifdef CONFIG_SMP -#undef __ASM__MB -#define __ASM__MB "\tmb\n" -#endif -#undef ____xchg -#undef ____cmpxchg -#define ____xchg(type, args...) __xchg ##type(args) -#define ____cmpxchg(type, args...) __cmpxchg ##type(args) -#include - -#define xchg(ptr, x) \ -({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ -}) - -#define cmpxchg(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, sizeof(*(ptr)));\ -}) - -#define cmpxchg64(ptr, o, n) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg((ptr), (o), (n)); \ -}) - -#undef __ASM__MB -#undef ____cmpxchg - -#define __HAVE_ARCH_CMPXCHG 1 - -#endif /* _ALPHA_CMPXCHG_H */ diff --git a/trunk/arch/alpha/include/asm/xchg.h b/trunk/arch/alpha/include/asm/xchg.h index 0ca9724597c1..1d1b436fbff2 100644 --- a/trunk/arch/alpha/include/asm/xchg.h +++ b/trunk/arch/alpha/include/asm/xchg.h @@ -1,10 +1,10 @@ -#ifndef _ALPHA_CMPXCHG_H +#ifndef _ALPHA_ATOMIC_H #error Do not include xchg.h directly! #else /* * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code * except that local version do not have the expensive memory barrier. - * So this file is included twice from asm/cmpxchg.h. + * So this file is included twice from asm/system.h. */ /* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index a231594ba44e..cf006d40342c 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -340,8 +340,8 @@ config ARCH_AT91 select IRQ_DOMAIN select NEED_MACH_IO_H if PCCARD help - This enables support for systems based on Atmel - AT91RM9200 and AT91SAM9* processors. + This enables support for systems based on the Atmel AT91RM9200, + AT91SAM9 processors. config ARCH_BCMRING bool "Broadcom BCMRING" @@ -528,6 +528,28 @@ config ARCH_IOP33X help Support for Intel's IOP33X (XScale) family of processors. +config ARCH_IXP23XX + bool "IXP23XX-based" + depends on MMU + select CPU_XSC3 + select PCI + select ARCH_USES_GETTIMEOFFSET + select NEED_MACH_IO_H + select NEED_MACH_MEMORY_H + help + Support for Intel's IXP23xx (XScale) family of processors. + +config ARCH_IXP2000 + bool "IXP2400/2800-based" + depends on MMU + select CPU_XSCALE + select PCI + select ARCH_USES_GETTIMEOFFSET + select NEED_MACH_IO_H + select NEED_MACH_MEMORY_H + help + Support for Intel's IXP2400/2800 (XScale) family of processors. + config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU @@ -1024,6 +1046,10 @@ source "arch/arm/mach-iop13xx/Kconfig" source "arch/arm/mach-ixp4xx/Kconfig" +source "arch/arm/mach-ixp2000/Kconfig" + +source "arch/arm/mach-ixp23xx/Kconfig" + source "arch/arm/mach-kirkwood/Kconfig" source "arch/arm/mach-ks8695/Kconfig" diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index a0c40a0986cd..047a20780fc1 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -149,6 +149,8 @@ machine-$(CONFIG_ARCH_INTEGRATOR) := integrator machine-$(CONFIG_ARCH_IOP13XX) := iop13xx machine-$(CONFIG_ARCH_IOP32X) := iop32x machine-$(CONFIG_ARCH_IOP33X) := iop33x +machine-$(CONFIG_ARCH_IXP2000) := ixp2000 +machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood machine-$(CONFIG_ARCH_KS8695) := ks8695 diff --git a/trunk/arch/arm/boot/compressed/atags_to_fdt.c b/trunk/arch/arm/boot/compressed/atags_to_fdt.c index 797f04bedb47..6ce11c481178 100644 --- a/trunk/arch/arm/boot/compressed/atags_to_fdt.c +++ b/trunk/arch/arm/boot/compressed/atags_to_fdt.c @@ -77,8 +77,6 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) } else if (atag->hdr.tag == ATAG_MEM) { if (memcount >= sizeof(mem_reg_property)/4) continue; - if (!atag->u.mem.size) - continue; mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); } else if (atag->hdr.tag == ATAG_INITRD2) { diff --git a/trunk/arch/arm/boot/compressed/head-xscale.S b/trunk/arch/arm/boot/compressed/head-xscale.S index 6ab0599c02dd..aa5ee49c5c5a 100644 --- a/trunk/arch/arm/boot/compressed/head-xscale.S +++ b/trunk/arch/arm/boot/compressed/head-xscale.S @@ -32,3 +32,10 @@ __XScale_start: bic r0, r0, #0x1000 @ clear Icache mcr p15, 0, r0, c1, c0, 0 +#ifdef CONFIG_ARCH_IXP2000 + mov r1, #-1 + mov r0, #0xd6000000 + str r1, [r0, #0x14] + str r1, [r0, #0x18] +#endif + diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index dc7e8ce8e6be..5f6045f1766c 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -273,7 +273,7 @@ restart: adr r0, LC0 add r0, r0, #0x100 mov r1, r6 sub r2, sp, r6 - bleq atags_to_fdt + blne atags_to_fdt ldmfd sp!, {r0-r3, ip, lr} sub sp, sp, #0x10000 diff --git a/trunk/arch/arm/boot/dts/at91sam9g20.dtsi b/trunk/arch/arm/boot/dts/at91sam9g20.dtsi index 773ef484037a..799ad1889b51 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g20.dtsi @@ -55,6 +55,7 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; + interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi index c8042147eaa2..9e6eb6ecea0e 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi @@ -56,6 +56,7 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; + interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi index dd4ed748469a..70ab3a4e026f 100644 --- a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi @@ -54,6 +54,7 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; + interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/trunk/arch/arm/boot/dts/db8500.dtsi b/trunk/arch/arm/boot/dts/db8500.dtsi index 14bc30705099..d73dce645667 100644 --- a/trunk/arch/arm/boot/dts/db8500.dtsi +++ b/trunk/arch/arm/boot/dts/db8500.dtsi @@ -24,6 +24,7 @@ #interrupt-cells = <3>; #address-cells = <1>; interrupt-controller; + interrupt-parent; reg = <0xa0411000 0x1000>, <0xa0410100 0x100>; }; diff --git a/trunk/arch/arm/boot/dts/highbank.dts b/trunk/arch/arm/boot/dts/highbank.dts index 83e72294aefb..37c0ff9c8b90 100644 --- a/trunk/arch/arm/boot/dts/highbank.dts +++ b/trunk/arch/arm/boot/dts/highbank.dts @@ -89,6 +89,7 @@ #size-cells = <0>; #address-cells = <1>; interrupt-controller; + interrupt-parent; reg = <0xfff11000 0x1000>, <0xfff10100 0x100>; }; diff --git a/trunk/arch/arm/common/Makefile b/trunk/arch/arm/common/Makefile index e8a4e58f1b82..215816f1775f 100644 --- a/trunk/arch/arm/common/Makefile +++ b/trunk/arch/arm/common/Makefile @@ -11,5 +11,7 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o +obj-$(CONFIG_ARCH_IXP2000) += uengine.o +obj-$(CONFIG_ARCH_IXP23XX) += uengine.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o diff --git a/trunk/arch/arm/common/uengine.c b/trunk/arch/arm/common/uengine.c new file mode 100644 index 000000000000..bef408f3d76c --- /dev/null +++ b/trunk/arch/arm/common/uengine.c @@ -0,0 +1,507 @@ +/* + * Generic library functions for the microengines found on the Intel + * IXP2000 series of network processors. + * + * Copyright (C) 2004, 2005 Lennert Buytenhek + * Dedicated to Marija Kulikova. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_ARCH_IXP2000) +#define IXP_UENGINE_CSR_VIRT_BASE IXP2000_UENGINE_CSR_VIRT_BASE +#define IXP_PRODUCT_ID IXP2000_PRODUCT_ID +#define IXP_MISC_CONTROL IXP2000_MISC_CONTROL +#define IXP_RESET1 IXP2000_RESET1 +#else +#if defined(CONFIG_ARCH_IXP23XX) +#define IXP_UENGINE_CSR_VIRT_BASE IXP23XX_UENGINE_CSR_VIRT_BASE +#define IXP_PRODUCT_ID IXP23XX_PRODUCT_ID +#define IXP_MISC_CONTROL IXP23XX_MISC_CONTROL +#define IXP_RESET1 IXP23XX_RESET1 +#else +#error unknown platform +#endif +#endif + +#define USTORE_ADDRESS 0x000 +#define USTORE_DATA_LOWER 0x004 +#define USTORE_DATA_UPPER 0x008 +#define CTX_ENABLES 0x018 +#define CC_ENABLE 0x01c +#define CSR_CTX_POINTER 0x020 +#define INDIRECT_CTX_STS 0x040 +#define ACTIVE_CTX_STS 0x044 +#define INDIRECT_CTX_SIG_EVENTS 0x048 +#define INDIRECT_CTX_WAKEUP_EVENTS 0x050 +#define NN_PUT 0x080 +#define NN_GET 0x084 +#define TIMESTAMP_LOW 0x0c0 +#define TIMESTAMP_HIGH 0x0c4 +#define T_INDEX_BYTE_INDEX 0x0f4 +#define LOCAL_CSR_STATUS 0x180 + +u32 ixp2000_uengine_mask; + +static void *ixp2000_uengine_csr_area(int uengine) +{ + return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10); +} + +/* + * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR + * space means that the microengine we tried to access was also trying + * to access its own CSR space on the same clock cycle as we did. When + * this happens, we lose the arbitration process by default, and the + * read or write we tried to do was not actually performed, so we try + * again until it succeeds. + */ +u32 ixp2000_uengine_csr_read(int uengine, int offset) +{ + void *uebase; + u32 *local_csr_status; + u32 *reg; + u32 value; + + uebase = ixp2000_uengine_csr_area(uengine); + + local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS); + reg = (u32 *)(uebase + offset); + do { + value = ixp2000_reg_read(reg); + } while (ixp2000_reg_read(local_csr_status) & 1); + + return value; +} +EXPORT_SYMBOL(ixp2000_uengine_csr_read); + +void ixp2000_uengine_csr_write(int uengine, int offset, u32 value) +{ + void *uebase; + u32 *local_csr_status; + u32 *reg; + + uebase = ixp2000_uengine_csr_area(uengine); + + local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS); + reg = (u32 *)(uebase + offset); + do { + ixp2000_reg_write(reg, value); + } while (ixp2000_reg_read(local_csr_status) & 1); +} +EXPORT_SYMBOL(ixp2000_uengine_csr_write); + +void ixp2000_uengine_reset(u32 uengine_mask) +{ + u32 value; + + value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask; + + uengine_mask &= ixp2000_uengine_mask; + ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask); + ixp2000_reg_wrb(IXP_RESET1, value); +} +EXPORT_SYMBOL(ixp2000_uengine_reset); + +void ixp2000_uengine_set_mode(int uengine, u32 mode) +{ + /* + * CTL_STR_PAR_EN: unconditionally enable parity checking on + * control store. + */ + mode |= 0x10000000; + ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode); + + /* + * Enable updating of condition codes. + */ + ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000); + + /* + * Initialise other per-microengine registers. + */ + ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00); + ixp2000_uengine_csr_write(uengine, NN_GET, 0x00); + ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0); +} +EXPORT_SYMBOL(ixp2000_uengine_set_mode); + +static int make_even_parity(u32 x) +{ + return hweight32(x) & 1; +} + +static void ustore_write(int uengine, u64 insn) +{ + /* + * Generate even parity for top and bottom 20 bits. + */ + insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41; + insn |= (u64)make_even_parity(insn & 0x000fffff) << 40; + + /* + * Write to microstore. The second write auto-increments + * the USTORE_ADDRESS index register. + */ + ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn); + ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32)); +} + +void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns) +{ + int i; + + /* + * Start writing to microstore at address 0. + */ + ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000); + for (i = 0; i < insns; i++) { + u64 insn; + + insn = (((u64)ucode[0]) << 32) | + (((u64)ucode[1]) << 24) | + (((u64)ucode[2]) << 16) | + (((u64)ucode[3]) << 8) | + ((u64)ucode[4]); + ucode += 5; + + ustore_write(uengine, insn); + } + + /* + * Pad with a few NOPs at the end (to avoid the microengine + * aborting as it prefetches beyond the last instruction), unless + * we run off the end of the instruction store first, at which + * point the address register will wrap back to zero. + */ + for (i = 0; i < 4; i++) { + u32 addr; + + addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS); + if (addr == 0x80000000) + break; + ustore_write(uengine, 0xf0000c0300ULL); + } + + /* + * End programming. + */ + ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000); +} +EXPORT_SYMBOL(ixp2000_uengine_load_microcode); + +void ixp2000_uengine_init_context(int uengine, int context, int pc) +{ + /* + * Select the right context for indirect access. + */ + ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context); + + /* + * Initialise signal masks to immediately go to Ready state. + */ + ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1); + ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1); + + /* + * Set program counter. + */ + ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc); +} +EXPORT_SYMBOL(ixp2000_uengine_init_context); + +void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask) +{ + u32 mask; + + /* + * Enable the specified context to go to Executing state. + */ + mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES); + mask |= ctx_mask << 8; + ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask); +} +EXPORT_SYMBOL(ixp2000_uengine_start_contexts); + +void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask) +{ + u32 mask; + + /* + * Disable the Ready->Executing transition. Note that this + * does not stop the context until it voluntarily yields. + */ + mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES); + mask &= ~(ctx_mask << 8); + ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask); +} +EXPORT_SYMBOL(ixp2000_uengine_stop_contexts); + +static int check_ixp_type(struct ixp2000_uengine_code *c) +{ + u32 product_id; + u32 rev; + + product_id = ixp2000_reg_read(IXP_PRODUCT_ID); + if (((product_id >> 16) & 0x1f) != 0) + return 0; + + switch ((product_id >> 8) & 0xff) { +#ifdef CONFIG_ARCH_IXP2000 + case 0: /* IXP2800 */ + if (!(c->cpu_model_bitmask & 4)) + return 0; + break; + + case 1: /* IXP2850 */ + if (!(c->cpu_model_bitmask & 8)) + return 0; + break; + + case 2: /* IXP2400 */ + if (!(c->cpu_model_bitmask & 2)) + return 0; + break; +#endif + +#ifdef CONFIG_ARCH_IXP23XX + case 4: /* IXP23xx */ + if (!(c->cpu_model_bitmask & 0x3f0)) + return 0; + break; +#endif + + default: + return 0; + } + + rev = product_id & 0xff; + if (rev < c->cpu_min_revision || rev > c->cpu_max_revision) + return 0; + + return 1; +} + +static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b) +{ + int offset; + int i; + + offset = 0; + + for (i = 0; i < 128; i++) { + u8 b3; + u8 b2; + u8 b1; + u8 b0; + + b3 = (gpr_a[i] >> 24) & 0xff; + b2 = (gpr_a[i] >> 16) & 0xff; + b1 = (gpr_a[i] >> 8) & 0xff; + b0 = gpr_a[i] & 0xff; + + /* immed[@ai, (b1 << 8) | b0] */ + /* 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII */ + ucode[offset++] = 0xf0; + ucode[offset++] = (b1 >> 4); + ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6); + ucode[offset++] = (b0 << 2); + ucode[offset++] = 0x80 | i; + + /* immed_w1[@ai, (b3 << 8) | b2] */ + /* 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII */ + ucode[offset++] = 0xf4; + ucode[offset++] = 0x40 | (b3 >> 4); + ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6); + ucode[offset++] = (b2 << 2); + ucode[offset++] = 0x80 | i; + } + + for (i = 0; i < 128; i++) { + u8 b3; + u8 b2; + u8 b1; + u8 b0; + + b3 = (gpr_b[i] >> 24) & 0xff; + b2 = (gpr_b[i] >> 16) & 0xff; + b1 = (gpr_b[i] >> 8) & 0xff; + b0 = gpr_b[i] & 0xff; + + /* immed[@bi, (b1 << 8) | b0] */ + /* 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV */ + ucode[offset++] = 0xf0; + ucode[offset++] = (b1 >> 4); + ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6); + ucode[offset++] = (i << 2) | 0x03; + ucode[offset++] = b0; + + /* immed_w1[@bi, (b3 << 8) | b2] */ + /* 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV */ + ucode[offset++] = 0xf4; + ucode[offset++] = 0x40 | (b3 >> 4); + ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6); + ucode[offset++] = (i << 2) | 0x03; + ucode[offset++] = b2; + } + + /* ctx_arb[kill] */ + ucode[offset++] = 0xe0; + ucode[offset++] = 0x00; + ucode[offset++] = 0x01; + ucode[offset++] = 0x00; + ucode[offset++] = 0x00; +} + +static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c) +{ + int per_ctx_regs; + u32 *gpr_a; + u32 *gpr_b; + u8 *ucode; + int i; + + gpr_a = kzalloc(128 * sizeof(u32), GFP_KERNEL); + gpr_b = kzalloc(128 * sizeof(u32), GFP_KERNEL); + ucode = kmalloc(513 * 5, GFP_KERNEL); + if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) { + kfree(ucode); + kfree(gpr_b); + kfree(gpr_a); + return 1; + } + + per_ctx_regs = 16; + if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS) + per_ctx_regs = 32; + + for (i = 0; i < 256; i++) { + struct ixp2000_reg_value *r = c->initial_reg_values + i; + u32 *bank; + int inc; + int j; + + if (r->reg == -1) + break; + + bank = (r->reg & 0x400) ? gpr_b : gpr_a; + inc = (r->reg & 0x80) ? 128 : per_ctx_regs; + + j = r->reg & 0x7f; + while (j < 128) { + bank[j] = r->value; + j += inc; + } + } + + generate_ucode(ucode, gpr_a, gpr_b); + ixp2000_uengine_load_microcode(uengine, ucode, 513); + ixp2000_uengine_init_context(uengine, 0, 0); + ixp2000_uengine_start_contexts(uengine, 0x01); + for (i = 0; i < 100; i++) { + u32 status; + + status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS); + if (!(status & 0x80000000)) + break; + } + ixp2000_uengine_stop_contexts(uengine, 0x01); + + kfree(ucode); + kfree(gpr_b); + kfree(gpr_a); + + return !!(i == 100); +} + +int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c) +{ + int ctx; + + if (!check_ixp_type(c)) + return 1; + + if (!(ixp2000_uengine_mask & (1 << uengine))) + return 1; + + ixp2000_uengine_reset(1 << uengine); + ixp2000_uengine_set_mode(uengine, c->uengine_parameters); + if (set_initial_registers(uengine, c)) + return 1; + ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns); + + for (ctx = 0; ctx < 8; ctx++) + ixp2000_uengine_init_context(uengine, ctx, 0); + + return 0; +} +EXPORT_SYMBOL(ixp2000_uengine_load); + + +static int __init ixp2000_uengine_init(void) +{ + int uengine; + u32 value; + + /* + * Determine number of microengines present. + */ + switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) { +#ifdef CONFIG_ARCH_IXP2000 + case 0: /* IXP2800 */ + case 1: /* IXP2850 */ + ixp2000_uengine_mask = 0x00ff00ff; + break; + + case 2: /* IXP2400 */ + ixp2000_uengine_mask = 0x000f000f; + break; +#endif + +#ifdef CONFIG_ARCH_IXP23XX + case 4: /* IXP23xx */ + ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf; + break; +#endif + + default: + printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n", + (unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID)); + ixp2000_uengine_mask = 0x00000000; + break; + } + + /* + * Reset microengines. + */ + ixp2000_uengine_reset(ixp2000_uengine_mask); + + /* + * Synchronise timestamp counters across all microengines. + */ + value = ixp2000_reg_read(IXP_MISC_CONTROL); + ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80); + for (uengine = 0; uengine < 32; uengine++) { + if (ixp2000_uengine_mask & (1 << uengine)) { + ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0); + ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0); + } + } + ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80); + + return 0; +} + +subsys_initcall(ixp2000_uengine_init); diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index 7e288f96cedf..7a66311f3066 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -427,18 +427,19 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) /* * Handle each interrupt in a single VIC. Returns non-zero if we've - * handled at least one interrupt. This reads the status register - * before handling each interrupt, which is necessary given that - * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. + * handled at least one interrupt. This does a single read of the + * status register and handles all interrupts in order from LSB first. */ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) { u32 stat, irq; int handled = 0; - while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); + while (stat) { irq = ffs(stat) - 1; handle_IRQ(irq_find_mapping(vic->domain, irq), regs); + stat &= ~(1 << irq); handled = 1; } diff --git a/trunk/arch/arm/configs/at91_dt_defconfig b/trunk/arch/arm/configs/at91_dt_defconfig deleted file mode 100644 index 67bc571ed0c3..000000000000 --- a/trunk/arch/arm/configs/at91_dt_defconfig +++ /dev/null @@ -1,196 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_KALLSYMS_ALL=y -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_SOC_AT91SAM9260=y -CONFIG_SOC_AT91SAM9263=y -CONFIG_SOC_AT91SAM9G45=y -CONFIG_SOC_AT91SAM9X5=y -CONFIG_MACH_AT91SAM_DT=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y -CONFIG_AT91_TIMER_HZ=128 -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y -CONFIG_UACCESS_WITH_MEMCPY=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_CMDLINE="mem=128M console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw" -CONFIG_KEXEC=y -CONFIG_AUTO_ZRELADDR=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_PNP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set -CONFIG_IPV6_SIT_6RD=y -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_PROC_DEVICETREE=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=4 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_ATMEL_PWM=y -CONFIG_ATMEL_TCLIB=y -CONFIG_EEPROM_93CX6=m -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_MII=y -CONFIG_MACB=y -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_CHELSIO is not set -# CONFIG_NET_VENDOR_FARADAY is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_STMICRO is not set -CONFIG_DAVICOM_PHY=y -CONFIG_MICREL_PHY=y -# CONFIG_WLAN is not set -CONFIG_INPUT_POLLDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=480 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=272 -CONFIG_INPUT_JOYDEV=y -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_SERIO is not set -CONFIG_LEGACY_PTY_COUNT=4 -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_SSB=m -CONFIG_FB=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_ATMEL=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_ATMEL_LCDC=y -# CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_ACORN_8x8=y -CONFIG_FONT_MINI_4x6=y -CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_ACM=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SERIAL=y -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_FTDI_SIO=y -CONFIG_USB_SERIAL_PL2303=y -CONFIG_USB_GADGET=y -CONFIG_USB_AT91=m -CONFIG_USB_ATMEL_USBA=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_USB_G_ACM_MS=m -CONFIG_USB_G_MULTI=m -CONFIG_USB_G_MULTI_CDC=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91RM9200=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_DMADEVICES=y -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_FANOTIFY=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_STRIP_ASM_SYMS=y -CONFIG_DEBUG_FS=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_FTRACE is not set -CONFIG_DEBUG_USER=y -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -# CONFIG_CRYPTO_HW is not set -CONFIG_CRC_CCITT=m -CONFIG_CRC_ITU_T=m -CONFIG_CRC7=m -CONFIG_AVERAGE=y diff --git a/trunk/arch/arm/configs/at91rm9200_defconfig b/trunk/arch/arm/configs/at91rm9200_defconfig index d54e2acd3ab1..bbe4e1a1f5d8 100644 --- a/trunk/arch/arm/configs/at91rm9200_defconfig +++ b/trunk/arch/arm/configs/at91rm9200_defconfig @@ -14,7 +14,6 @@ CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91RM9200=y CONFIG_MACH_ONEARM=y CONFIG_ARCH_AT91RM9200DK=y CONFIG_MACH_AT91RM9200EK=y diff --git a/trunk/arch/arm/configs/imx_v4_v5_defconfig b/trunk/arch/arm/configs/imx_v4_v5_defconfig index 6b31cb60daab..b5ac644e12af 100644 --- a/trunk/arch/arm/configs/imx_v4_v5_defconfig +++ b/trunk/arch/arm/configs/imx_v4_v5_defconfig @@ -112,7 +112,6 @@ CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MFD_MC13XXX=y CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y CONFIG_FB=y diff --git a/trunk/arch/arm/configs/ixp2000_defconfig b/trunk/arch/arm/configs/ixp2000_defconfig new file mode 100644 index 000000000000..8405aded97a3 --- /dev/null +++ b/trunk/arch/arm/configs/ixp2000_defconfig @@ -0,0 +1,99 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +# CONFIG_HOTPLUG is not set +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_ARCH_IXP2000=y +CONFIG_ARCH_ENP2611=y +CONFIG_ARCH_IXDP2400=y +CONFIG_ARCH_IXDP2800=y +CONFIG_ARCH_IXDP2401=y +CONFIG_ARCH_IXDP2801=y +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0" +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_SYN_COOKIES=y +CONFIG_IPV6=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_MTD=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_IXP2000=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_EEPROM_LEGACY=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_PCI=y +CONFIG_CS89x0=y +CONFIG_E100=y +CONFIG_ENP2611_MSF_NET=y +CONFIG_WAN=y +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y +CONFIG_DLCI=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_IXP2000=y +CONFIG_WATCHDOG=y +CONFIG_IXP2000_WATCHDOG=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_INOTIFY=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y diff --git a/trunk/arch/arm/configs/ixp23xx_defconfig b/trunk/arch/arm/configs/ixp23xx_defconfig new file mode 100644 index 000000000000..688717612e91 --- /dev/null +++ b/trunk/arch/arm/configs/ixp23xx_defconfig @@ -0,0 +1,105 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_ARCH_IXP23XX=y +CONFIG_MACH_ESPRESSO=y +CONFIG_MACH_IXDP2351=y +CONFIG_MACH_ROADRUNNER=y +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_SYN_COOKIES=y +CONFIG_IPV6=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +CONFIG_MTD=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_EEPROM_LEGACY=y +CONFIG_IDE=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_PCI=y +CONFIG_E100=y +CONFIG_E1000=y +CONFIG_WAN=y +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y +CONFIG_DLCI=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_WATCHDOG=y +# CONFIG_USB_HID is not set +CONFIG_USB=y +CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_INOTIFY=y +CONFIG_MSDOS_FS=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y diff --git a/trunk/arch/arm/configs/u8500_defconfig b/trunk/arch/arm/configs/u8500_defconfig index 7e84f453e8a6..889d73ac1ae1 100644 --- a/trunk/arch/arm/configs/u8500_defconfig +++ b/trunk/arch/arm/configs/u8500_defconfig @@ -8,6 +8,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_U8500=y +CONFIG_UX500_SOC_DB5500=y +CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_MACH_U5500=y @@ -37,6 +39,7 @@ CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_MISC_DEVICES=y CONFIG_AB8500_PWM=y CONFIG_SENSORS_BH1780=y CONFIG_NETDEVICES=y @@ -62,18 +65,16 @@ CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_NOMADIK=y +CONFIG_I2C=y +CONFIG_I2C_NOMADIK=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_GPIO_STMPE=y CONFIG_GPIO_TC3589X=y -CONFIG_POWER_SUPPLY=y -CONFIG_AB8500_BM=y -CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y CONFIG_MFD_STMPE=y CONFIG_MFD_TC3589X=y CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y -CONFIG_REGULATOR=y CONFIG_REGULATOR_AB8500=y # CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y diff --git a/trunk/arch/arm/include/asm/hardware/uengine.h b/trunk/arch/arm/include/asm/hardware/uengine.h new file mode 100644 index 000000000000..b442d65c6593 --- /dev/null +++ b/trunk/arch/arm/include/asm/hardware/uengine.h @@ -0,0 +1,62 @@ +/* + * Generic library functions for the microengines found on the Intel + * IXP2000 series of network processors. + * + * Copyright (C) 2004, 2005 Lennert Buytenhek + * Dedicated to Marija Kulikova. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + */ + +#ifndef __IXP2000_UENGINE_H +#define __IXP2000_UENGINE_H + +extern u32 ixp2000_uengine_mask; + +struct ixp2000_uengine_code +{ + u32 cpu_model_bitmask; + u8 cpu_min_revision; + u8 cpu_max_revision; + + u32 uengine_parameters; + + struct ixp2000_reg_value { + int reg; + u32 value; + } *initial_reg_values; + + int num_insns; + u8 *insns; +}; + +u32 ixp2000_uengine_csr_read(int uengine, int offset); +void ixp2000_uengine_csr_write(int uengine, int offset, u32 value); +void ixp2000_uengine_reset(u32 uengine_mask); +void ixp2000_uengine_set_mode(int uengine, u32 mode); +void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns); +void ixp2000_uengine_init_context(int uengine, int context, int pc); +void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask); +void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask); +int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c); + +#define IXP2000_UENGINE_8_CONTEXTS 0x00000000 +#define IXP2000_UENGINE_4_CONTEXTS 0x80000000 +#define IXP2000_UENGINE_PRN_UPDATE_EVERY 0x40000000 +#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS 0x00000000 +#define IXP2000_UENGINE_NN_FROM_SELF 0x00100000 +#define IXP2000_UENGINE_NN_FROM_PREVIOUS 0x00000000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3 0x000c0000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2 0x00080000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1 0x00040000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0 0x00000000 +#define IXP2000_UENGINE_LM_ADDR1_GLOBAL 0x00020000 +#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT 0x00000000 +#define IXP2000_UENGINE_LM_ADDR0_GLOBAL 0x00010000 +#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT 0x00000000 + + +#endif diff --git a/trunk/arch/arm/include/asm/jump_label.h b/trunk/arch/arm/include/asm/jump_label.h index bfc198c75913..5c5ca2ea62b0 100644 --- a/trunk/arch/arm/include/asm/jump_label.h +++ b/trunk/arch/arm/include/asm/jump_label.h @@ -14,7 +14,7 @@ #define JUMP_LABEL_NOP "nop" #endif -static __always_inline bool arch_static_branch(struct static_key *key) +static __always_inline bool arch_static_branch(struct jump_label_key *key) { asm goto("1:\n\t" JUMP_LABEL_NOP "\n\t" diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index ebfac782593f..b91411371ae1 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -523,21 +523,7 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size) */ size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); - -#ifndef CONFIG_LPAE - if (bank->start + size < bank->start) { - printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " - "32-bit physical address space\n", (long long)start); - /* - * To ensure bank->start + bank->size is representable in - * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. - * This means we lose a page after masking. - */ - size = ULONG_MAX - bank->start; - } -#endif - - bank->size = size & PAGE_MASK; + bank->size = size & PAGE_MASK; /* * Check whether this memory region has non-zero size or diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index 5b150afb995b..fef42b21cecb 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -118,14 +118,10 @@ static int twd_cpufreq_transition(struct notifier_block *nb, * The twd clock events must be reprogrammed to account for the new * frequency. The timer is local to a cpu, so cross-call to the * changing cpu. - * - * Only wait for it to finish, if the cpu is active to avoid - * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during - * booting of that cpu. */ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE) smp_call_function_single(freqs->cpu, twd_update_frequency, - NULL, cpu_active(freqs->cpu)); + NULL, 1); return NOTIFY_OK; } diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig index 98a42f3472d5..45db05d8d94c 100644 --- a/trunk/arch/arm/mach-at91/Kconfig +++ b/trunk/arch/arm/mach-at91/Kconfig @@ -9,6 +9,15 @@ config HAVE_AT91_DBGU0 config HAVE_AT91_DBGU1 bool +config HAVE_AT91_USART3 + bool + +config HAVE_AT91_USART4 + bool + +config HAVE_AT91_USART5 + bool + config AT91_SAM9_ALT_RESET bool default !ARCH_AT91X40 @@ -17,121 +26,87 @@ config AT91_SAM9G45_RESET bool default !ARCH_AT91X40 -config SOC_AT91SAM9 - bool - select GENERIC_CLOCKEVENTS - select CPU_ARM926T - menu "Atmel AT91 System-on-Chip" -comment "Atmel AT91 Processor" - -config SOC_AT91SAM9 - bool - select CPU_ARM926T - select AT91_SAM9_TIME - select AT91_SAM9_SMC +choice + prompt "Atmel AT91 Processor" -config SOC_AT91RM9200 +config ARCH_AT91RM9200 bool "AT91RM9200" select CPU_ARM920T select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 - -config SOC_AT91SAM9260 - bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20" - select SOC_AT91SAM9 - select HAVE_AT91_DBGU0 - select HAVE_NET_MACB - help - Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE - or AT91SAM9G20 SoC. - -config SOC_AT91SAM9261 - bool "AT91SAM9261 or AT91SAM9G10" - select SOC_AT91SAM9 - select HAVE_AT91_DBGU0 - select HAVE_FB_ATMEL - help - Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC. - -config SOC_AT91SAM9263 - bool "AT91SAM9263" - select SOC_AT91SAM9 - select HAVE_AT91_DBGU1 - select HAVE_FB_ATMEL - select HAVE_NET_MACB - -config SOC_AT91SAM9RL - bool "AT91SAM9RL" - select SOC_AT91SAM9 - select HAVE_AT91_DBGU0 - select HAVE_FB_ATMEL - -config SOC_AT91SAM9G45 - bool "AT91SAM9G45 or AT91SAM9M10 families" - select SOC_AT91SAM9 - select HAVE_AT91_DBGU1 - select HAVE_FB_ATMEL - select HAVE_NET_MACB - help - Select this if you are using one of Atmel's AT91SAM9G45 family SoC. - This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11. - -config SOC_AT91SAM9X5 - bool "AT91SAM9x5 family" - select SOC_AT91SAM9 - select HAVE_AT91_DBGU0 - select HAVE_FB_ATMEL - select HAVE_NET_MACB - help - Select this if you are using one of Atmel's AT91SAM9x5 family SoC. - This means that your SAM9 name finishes with a '5' (except if it is - AT91SAM9G45!). - This support covers AT91SAM9G15, AT91SAM9G25, AT91SAM9X25, AT91SAM9G35 - and AT91SAM9X35. - -choice - prompt "Atmel AT91 Processor Devices for non DT boards" - -config ARCH_AT91_NONE - bool "None" - -config ARCH_AT91RM9200 - bool "AT91RM9200" - select SOC_AT91RM9200 + select HAVE_AT91_USART3 config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE" - select SOC_AT91SAM9260 + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 + select HAVE_AT91_USART3 + select HAVE_AT91_USART4 + select HAVE_AT91_USART5 + select HAVE_NET_MACB config ARCH_AT91SAM9261 bool "AT91SAM9261" - select SOC_AT91SAM9261 + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + select HAVE_AT91_DBGU0 config ARCH_AT91SAM9G10 bool "AT91SAM9G10" - select SOC_AT91SAM9261 + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 + select HAVE_FB_ATMEL config ARCH_AT91SAM9263 bool "AT91SAM9263" - select SOC_AT91SAM9263 + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91SAM9RL bool "AT91SAM9RL" - select SOC_AT91SAM9RL + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + select HAVE_FB_ATMEL + select HAVE_AT91_DBGU0 config ARCH_AT91SAM9G20 bool "AT91SAM9G20" - select SOC_AT91SAM9260 + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 + select HAVE_AT91_USART3 + select HAVE_AT91_USART4 + select HAVE_AT91_USART5 + select HAVE_NET_MACB config ARCH_AT91SAM9G45 bool "AT91SAM9G45" - select SOC_AT91SAM9G45 + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + select HAVE_FB_ATMEL + select HAVE_NET_MACB + select HAVE_AT91_DBGU1 + +config ARCH_AT91SAM9X5 + bool "AT91SAM9x5 family" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + select HAVE_NET_MACB + select HAVE_AT91_DBGU0 config ARCH_AT91X40 bool "AT91x40" - depends on !MMU select ARCH_USES_GETTIMEOFFSET endchoice @@ -389,7 +364,6 @@ config MACH_AT91SAM9G20EK_2MMC Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and onwards. - config MACH_CPU9G20 bool "Eukrea CPU9G20 board" @@ -459,10 +433,9 @@ comment "AT91SAM9G45 Board Type" config MACH_AT91SAM9M10G45EK bool "Atmel AT91SAM9M10G45-EK Evaluation Kits" help - Select this if you are using Atmel's AT91SAM9M10G45-EK Evaluation Kit. - Those boards can be populated with any SoC of AT91SAM9G45 or AT91SAM9M10 - families: AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11. - + Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit. + "ES" at the end of the name means that this board is an + Engineering Sample. endif @@ -542,6 +515,41 @@ config AT91_TIMER_HZ system clock (of at least several MHz), rounding is less of a problem so it can be safer to use a decimal values like 100. +choice + prompt "Select a UART for early kernel messages" + +config AT91_EARLY_DBGU0 + bool "DBGU on rm9200, 9260/9g20, 9261/9g10 and 9rl" + depends on HAVE_AT91_DBGU0 + +config AT91_EARLY_DBGU1 + bool "DBGU on 9263 and 9g45" + depends on HAVE_AT91_DBGU1 + +config AT91_EARLY_USART0 + bool "USART0" + +config AT91_EARLY_USART1 + bool "USART1" + +config AT91_EARLY_USART2 + bool "USART2" + depends on ! ARCH_AT91X40 + +config AT91_EARLY_USART3 + bool "USART3" + depends on HAVE_AT91_USART3 + +config AT91_EARLY_USART4 + bool "USART4" + depends on HAVE_AT91_USART4 + +config AT91_EARLY_USART5 + bool "USART5" + depends on HAVE_AT91_USART5 + +endchoice + endmenu endif diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile index 79d0f60af0b2..8512e53bed93 100644 --- a/trunk/arch/arm/mach-at91/Makefile +++ b/trunk/arch/arm/mach-at91/Makefile @@ -10,25 +10,17 @@ obj- := obj-$(CONFIG_AT91_PMC_UNIT) += clock.o obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o -obj-$(CONFIG_SOC_AT91SAM9) += at91sam926x_time.o sam9_smc.o # CPU-specific support -obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o at91rm9200_time.o -obj-$(CONFIG_SOC_AT91SAM9260) += at91sam9260.o -obj-$(CONFIG_SOC_AT91SAM9261) += at91sam9261.o -obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o -obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o -obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o -obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o - -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261_devices.o -obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261_devices.o -obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263_devices.o -obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl_devices.o -obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260_devices.o -obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45_devices.o +obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o # AT91RM9200 board-specific support diff --git a/trunk/arch/arm/mach-at91/at91rm9200.c b/trunk/arch/arm/mach-at91/at91rm9200.c index d50da1a9d0bf..364c19357e60 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200.c +++ b/trunk/arch/arm/mach-at91/at91rm9200.c @@ -258,6 +258,18 @@ static void __init at91rm9200_register_clocks(void) clk_register(&pck3); } +static struct clk_lookup console_clock_lookup; + +void __init at91rm9200_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + /* -------------------------------------------------------------------- * GPIO * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91rm9200_devices.c b/trunk/arch/arm/mach-at91/at91rm9200_devices.c index 99affb5d0563..99ce5c955e39 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_devices.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_devices.c @@ -1152,6 +1152,14 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) at91_uarts[portnr] = pdev; } +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91rm9200_set_console_clock(at91_uarts[portnr]->id); + } +} + void __init at91_add_device_serial(void) { int i; @@ -1160,9 +1168,14 @@ void __init at91_add_device_serial(void) if (at91_uarts[i]) platform_device_register(at91_uarts[i]); } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else +void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91rm9200_time.c b/trunk/arch/arm/mach-at91/at91rm9200_time.c index 104ca40d8d18..dd7f782b0b91 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_time.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_time.c @@ -23,7 +23,6 @@ #include #include #include -#include #include @@ -177,7 +176,6 @@ static struct clock_event_device clkevt = { }; void __iomem *at91_st_base; -EXPORT_SYMBOL_GPL(at91_st_base); void __init at91rm9200_ioremap_st(u32 addr) { diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index a27bbec50ca3..46f774233298 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -268,6 +268,18 @@ static void __init at91sam9260_register_clocks(void) clk_register(&pck1); } +static struct clk_lookup console_clock_lookup; + +void __init at91sam9260_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + /* -------------------------------------------------------------------- * GPIO * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index ad00fe91d37d..5652dde4bbe2 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -1229,6 +1229,14 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) at91_uarts[portnr] = pdev; } +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9260_set_console_clock(at91_uarts[portnr]->id); + } +} + void __init at91_add_device_serial(void) { int i; @@ -1237,9 +1245,13 @@ void __init at91_add_device_serial(void) if (at91_uarts[i]) platform_device_register(at91_uarts[i]); } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index c77d503d09d1..7de81e6222f1 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -239,6 +239,18 @@ static void __init at91sam9261_register_clocks(void) clk_register(&hck1); } +static struct clk_lookup console_clock_lookup; + +void __init at91sam9261_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + /* -------------------------------------------------------------------- * GPIO * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index 9295e90b08ff..4db961a93085 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -1051,6 +1051,14 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) at91_uarts[portnr] = pdev; } +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9261_set_console_clock(at91_uarts[portnr]->id); + } +} + void __init at91_add_device_serial(void) { int i; @@ -1059,9 +1067,13 @@ void __init at91_add_device_serial(void) if (at91_uarts[i]) platform_device_register(at91_uarts[i]); } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index 7fae36502fbb..ef301be66575 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -255,6 +255,18 @@ static void __init at91sam9263_register_clocks(void) clk_register(&pck3); } +static struct clk_lookup console_clock_lookup; + +void __init at91sam9263_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + /* -------------------------------------------------------------------- * GPIO * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index dfe5bc006d5e..fe99206de880 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -1461,6 +1461,14 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) at91_uarts[portnr] = pdev; } +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9263_set_console_clock(at91_uarts[portnr]->id); + } +} + void __init at91_add_device_serial(void) { int i; @@ -1469,9 +1477,13 @@ void __init at91_add_device_serial(void) if (at91_uarts[i]) platform_device_register(at91_uarts[i]); } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c index f2054495a655..d222f8333dab 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45.c @@ -288,6 +288,18 @@ static void __init at91sam9g45_register_clocks(void) clk_register(&pck1); } +static struct clk_lookup console_clock_lookup; + +void __init at91sam9g45_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + /* -------------------------------------------------------------------- * GPIO * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c index db2f88c246ff..6b008aee1dff 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1741,6 +1741,14 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) at91_uarts[portnr] = pdev; } +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9g45_set_console_clock(at91_uarts[portnr]->id); + } +} + void __init at91_add_device_serial(void) { int i; @@ -1749,9 +1757,13 @@ void __init at91_add_device_serial(void) if (at91_uarts[i]) platform_device_register(at91_uarts[i]); } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c index e420085a57ef..d9f2774f385e 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl.c @@ -232,6 +232,18 @@ static void __init at91sam9rl_register_clocks(void) clk_register(&pck1); } +static struct clk_lookup console_clock_lookup; + +void __init at91sam9rl_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + /* -------------------------------------------------------------------- * GPIO * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c index 9c0b1481a9a7..fe4ae22e8561 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c @@ -1192,6 +1192,14 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) at91_uarts[portnr] = pdev; } +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9rl_set_console_clock(at91_uarts[portnr]->id); + } +} + void __init at91_add_device_serial(void) { int i; @@ -1200,9 +1208,13 @@ void __init at91_add_device_serial(void) if (at91_uarts[i]) platform_device_register(at91_uarts[i]); } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} #endif diff --git a/trunk/arch/arm/mach-at91/board-1arm.c b/trunk/arch/arm/mach-at91/board-1arm.c index 271f994314a4..2628384aaae1 100644 --- a/trunk/arch/arm/mach-at91/board-1arm.c +++ b/trunk/arch/arm/mach-at91/board-1arm.c @@ -47,6 +47,20 @@ static void __init onearm_init_early(void) /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata onearm_eth_data = { @@ -68,16 +82,6 @@ static struct at91_udc_data __initdata onearm_udc_data = { static void __init onearm_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&onearm_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-afeb-9260v1.c b/trunk/arch/arm/mach-at91/board-afeb-9260v1.c index b7d8aa7b81e6..161efbaa1029 100644 --- a/trunk/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/trunk/arch/arm/mach-at91/board-afeb-9260v1.c @@ -52,6 +52,22 @@ static void __init afeb9260_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -167,18 +183,6 @@ static struct at91_cf_data afeb9260_cf_data = { static void __init afeb9260_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR - | ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&afeb9260_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-cam60.c b/trunk/arch/arm/mach-at91/board-cam60.c index 29d3ef0a50fb..c6d44ee0c77e 100644 --- a/trunk/arch/arm/mach-at91/board-cam60.c +++ b/trunk/arch/arm/mach-at91/board-cam60.c @@ -49,6 +49,12 @@ static void __init cam60_init_early(void) { /* Initialize processor: 10 MHz crystal */ at91_initialize(10000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -169,8 +175,6 @@ static void __init cam60_add_device_nand(void) static void __init cam60_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* SPI */ at91_add_device_spi(cam60_spi_devices, ARRAY_SIZE(cam60_spi_devices)); diff --git a/trunk/arch/arm/mach-at91/board-carmeva.c b/trunk/arch/arm/mach-at91/board-carmeva.c index 44328a6d4609..59d9cf997537 100644 --- a/trunk/arch/arm/mach-at91/board-carmeva.c +++ b/trunk/arch/arm/mach-at91/board-carmeva.c @@ -44,6 +44,17 @@ static void __init carmeva_init_early(void) { /* Initialize processor: 20.000 MHz crystal */ at91_initialize(20000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata carmeva_eth_data = { @@ -128,13 +139,6 @@ static struct gpio_led carmeva_leds[] = { static void __init carmeva_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&carmeva_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-cpu9krea.c b/trunk/arch/arm/mach-at91/board-cpu9krea.c index 69951ec7dbf3..5f3680e7c883 100644 --- a/trunk/arch/arm/mach-at91/board-cpu9krea.c +++ b/trunk/arch/arm/mach-at91/board-cpu9krea.c @@ -52,6 +52,34 @@ static void __init cpu9krea_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | + ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | + ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* USART3 on ttyS4. (Rx, Tx) */ + at91_register_uart(AT91SAM9260_ID_US3, 4, 0); + + /* USART4 on ttyS5. (Rx, Tx) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx, Tx) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -324,30 +352,6 @@ static void __init cpu9krea_board_init(void) /* NOR */ cpu9krea_add_device_nor(); /* Serial */ - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | - ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | - ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | - ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | - ATMEL_UART_RTS); - - /* USART3 on ttyS4. (Rx, Tx) */ - at91_register_uart(AT91SAM9260_ID_US3, 4, 0); - - /* USART4 on ttyS5. (Rx, Tx) */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); - - /* USART5 on ttyS6. (Rx, Tx) */ - at91_register_uart(AT91SAM9260_ID_US5, 6, 0); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&cpu9krea_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-cpuat91.c b/trunk/arch/arm/mach-at91/board-cpuat91.c index 895cf2dba612..e094cc81fe25 100644 --- a/trunk/arch/arm/mach-at91/board-cpuat91.c +++ b/trunk/arch/arm/mach-at91/board-cpuat91.c @@ -59,6 +59,28 @@ static void __init cpuat91_init_early(void) /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | + ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | + ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART2 on ttyS3 (Rx, Tx) */ + at91_register_uart(AT91RM9200_ID_US2, 3, 0); + + /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata cpuat91_eth_data = { @@ -139,24 +161,6 @@ static struct platform_device *platform_devices[] __initdata = { static void __init cpuat91_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | - ATMEL_UART_RTS); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | - ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | - ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART2 on ttyS3 (Rx, Tx) */ - at91_register_uart(AT91RM9200_ID_US2, 3, 0); - - /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS | - ATMEL_UART_RTS); at91_add_device_serial(); /* LEDs. */ at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds)); diff --git a/trunk/arch/arm/mach-at91/board-csb337.c b/trunk/arch/arm/mach-at91/board-csb337.c index cd813361cd26..1a1547b1ce4e 100644 --- a/trunk/arch/arm/mach-at91/board-csb337.c +++ b/trunk/arch/arm/mach-at91/board-csb337.c @@ -47,6 +47,15 @@ static void __init csb337_init_early(void) { /* Initialize processor: 3.6864 MHz crystal */ at91_initialize(3686400); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); + + /* DBGU on ttyS0 */ + at91_register_uart(0, 0, 0); + + /* make console=ttyS0 the default */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata csb337_eth_data = { @@ -219,11 +228,7 @@ static struct gpio_led csb_leds[] = { static void __init csb337_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); /* Serial */ - /* DBGU on ttyS0 */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&csb337_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-csb637.c b/trunk/arch/arm/mach-at91/board-csb637.c index 7c8b05a57d7f..f650bf39455d 100644 --- a/trunk/arch/arm/mach-at91/board-csb637.c +++ b/trunk/arch/arm/mach-at91/board-csb637.c @@ -44,6 +44,12 @@ static void __init csb637_init_early(void) { /* Initialize processor: 3.6864 MHz crystal */ at91_initialize(3686400); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* make console=ttyS0 (ie, DBGU) the default */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata csb637_eth_data = { @@ -112,8 +118,6 @@ static void __init csb637_board_init(void) /* LED(s) */ at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds)); /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&csb637_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-dt.c b/trunk/arch/arm/mach-at91/board-dt.c index a1fce05aa7a5..c18d4d307801 100644 --- a/trunk/arch/arm/mach-at91/board-dt.c +++ b/trunk/arch/arm/mach-at91/board-dt.c @@ -1,6 +1,10 @@ /* * Setup code for AT91SAM Evaluation Kits with Device Tree support * + * Covers: * AT91SAM9G45-EKES board + * * AT91SAM9M10-EKES board + * * AT91SAM9M10G45-EK board + * * Copyright (C) 2011 Atmel, * 2011 Nicolas Ferre * @@ -45,7 +49,9 @@ static void __init at91_dt_device_init(void) } static const char *at91_dt_board_compat[] __initdata = { - "atmel,at91sam9", + "atmel,at91sam9m10g45ek", + "atmel,at91sam9x5ek", + "calao,usb-a9g20", NULL }; diff --git a/trunk/arch/arm/mach-at91/board-eb9200.c b/trunk/arch/arm/mach-at91/board-eb9200.c index bd1017297989..d302ca3eeb64 100644 --- a/trunk/arch/arm/mach-at91/board-eb9200.c +++ b/trunk/arch/arm/mach-at91/board-eb9200.c @@ -44,6 +44,20 @@ static void __init eb9200_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART2 on ttyS2. (Rx, Tx) - IRDA */ + at91_register_uart(AT91RM9200_ID_US2, 2, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata eb9200_eth_data = { @@ -87,16 +101,6 @@ static struct i2c_board_info __initdata eb9200_i2c_devices[] = { static void __init eb9200_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART2 on ttyS2. (Rx, Tx) - IRDA */ - at91_register_uart(AT91RM9200_ID_US2, 2, 0); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&eb9200_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-ecbat91.c b/trunk/arch/arm/mach-at91/board-ecbat91.c index 89cc3726a9ce..69966ce4d776 100644 --- a/trunk/arch/arm/mach-at91/board-ecbat91.c +++ b/trunk/arch/arm/mach-at91/board-ecbat91.c @@ -50,6 +50,18 @@ static void __init ecb_at91init_early(void) /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx & Tx only) */ + at91_register_uart(AT91RM9200_ID_US0, 1, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata ecb_at91eth_data = { @@ -139,15 +151,7 @@ static struct spi_board_info __initdata ecb_at91spi_devices[] = { static void __init ecb_at91board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx & Tx only) */ - at91_register_uart(AT91RM9200_ID_US0, 1, 0); at91_add_device_serial(); /* Ethernet */ diff --git a/trunk/arch/arm/mach-at91/board-eco920.c b/trunk/arch/arm/mach-at91/board-eco920.c index 558546cf63f4..f23aabef8551 100644 --- a/trunk/arch/arm/mach-at91/board-eco920.c +++ b/trunk/arch/arm/mach-at91/board-eco920.c @@ -37,6 +37,15 @@ static void __init eco920_init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); + + /* DBGU on ttyS0. (Rx & Tx only */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata eco920_eth_data = { @@ -94,10 +103,6 @@ static struct spi_board_info eco920_spi_devices[] = { static void __init eco920_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); - /* DBGU on ttyS0. (Rx & Tx only */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); at91_add_device_eth(&eco920_eth_data); at91_add_device_usbh(&eco920_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-flexibity.c b/trunk/arch/arm/mach-at91/board-flexibity.c index 47658f78105d..1815152001f7 100644 --- a/trunk/arch/arm/mach-at91/board-flexibity.c +++ b/trunk/arch/arm/mach-at91/board-flexibity.c @@ -41,6 +41,12 @@ static void __init flexibity_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* USB Host port */ @@ -137,8 +143,6 @@ static struct gpio_led flexibity_leds[] = { static void __init flexibity_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&flexibity_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-foxg20.c b/trunk/arch/arm/mach-at91/board-foxg20.c index 33411e6ecb1f..caf017f0f4ee 100644 --- a/trunk/arch/arm/mach-at91/board-foxg20.c +++ b/trunk/arch/arm/mach-at91/board-foxg20.c @@ -61,6 +61,44 @@ static void __init foxg20_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS + | ATMEL_UART_RTS + | ATMEL_UART_DTR + | ATMEL_UART_DSR + | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, 0); + + /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US3, 4, + ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART4 on ttyS5. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); + + /* Set the internal pull-up resistor on DRXD */ + at91_set_A_periph(AT91_PIN_PB14, 1); + } /* @@ -203,39 +241,6 @@ static struct i2c_board_info __initdata foxg20_i2c_devices[] = { static void __init foxg20_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS - | ATMEL_UART_RTS - | ATMEL_UART_DTR - | ATMEL_UART_DSR - | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS - | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx & Tx only) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, 0); - - /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US3, 4, - ATMEL_UART_CTS - | ATMEL_UART_RTS); - - /* USART4 on ttyS5. (Rx & Tx only) */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); - - /* USART5 on ttyS6. (Rx & Tx only) */ - at91_register_uart(AT91SAM9260_ID_US5, 6, 0); - - /* Set the internal pull-up resistor on DRXD */ - at91_set_A_periph(AT91_PIN_PB14, 1); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&foxg20_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-gsia18s.c b/trunk/arch/arm/mach-at91/board-gsia18s.c index 3e0dfa643a86..230e71969fb7 100644 --- a/trunk/arch/arm/mach-at91/board-gsia18s.c +++ b/trunk/arch/arm/mach-at91/board-gsia18s.c @@ -41,6 +41,38 @@ static void __init gsia18s_init_early(void) { stamp9g20_init_early(); + + /* + * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI). + * Used for Internal Analog Modem. + */ + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS | ATMEL_UART_RTS | + ATMEL_UART_DTR | ATMEL_UART_DSR | + ATMEL_UART_DCD | ATMEL_UART_RI); + /* + * USART1 on ttyS2 (Rx, Tx, CTS, RTS). + * Used for GPS or WiFi or Data stream. + */ + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS | ATMEL_UART_RTS); + /* + * USART2 on ttyS3 (Rx, Tx, CTS, RTS). + * Used for External Modem. + */ + at91_register_uart(AT91SAM9260_ID_US2, 3, + ATMEL_UART_CTS | ATMEL_UART_RTS); + /* + * USART3 on ttyS4 (Rx, Tx, RTS). + * Used for RS-485. + */ + at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS); + + /* + * USART4 on ttyS5 (Rx, Tx). + * Used for TRX433 Radio Module. + */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); } /* @@ -526,37 +558,6 @@ static int __init gsia18s_power_off_init(void) static void __init gsia18s_board_init(void) { - /* - * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI). - * Used for Internal Analog Modem. - */ - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS | ATMEL_UART_RTS | - ATMEL_UART_DTR | ATMEL_UART_DSR | - ATMEL_UART_DCD | ATMEL_UART_RI); - /* - * USART1 on ttyS2 (Rx, Tx, CTS, RTS). - * Used for GPS or WiFi or Data stream. - */ - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS | ATMEL_UART_RTS); - /* - * USART2 on ttyS3 (Rx, Tx, CTS, RTS). - * Used for External Modem. - */ - at91_register_uart(AT91SAM9260_ID_US2, 3, - ATMEL_UART_CTS | ATMEL_UART_RTS); - /* - * USART3 on ttyS4 (Rx, Tx, RTS). - * Used for RS-485. - */ - at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS); - - /* - * USART4 on ttyS5 (Rx, Tx). - * Used for TRX433 Radio Module. - */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); stamp9g20_board_init(); at91_add_device_usbh(&usbh_data); at91_add_device_udc(&udc_data); diff --git a/trunk/arch/arm/mach-at91/board-kafa.c b/trunk/arch/arm/mach-at91/board-kafa.c index f260657f32bc..efde1b2327c8 100644 --- a/trunk/arch/arm/mach-at91/board-kafa.c +++ b/trunk/arch/arm/mach-at91/board-kafa.c @@ -47,6 +47,18 @@ static void __init kafa_init_early(void) /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Set up the LEDs */ + at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata kafa_eth_data = { @@ -67,15 +79,7 @@ static struct at91_udc_data __initdata kafa_udc_data = { static void __init kafa_board_init(void) { - /* Set up the LEDs */ - at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&kafa_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-kb9202.c b/trunk/arch/arm/mach-at91/board-kb9202.c index ba39db5482b9..59b92aab9bcf 100644 --- a/trunk/arch/arm/mach-at91/board-kb9202.c +++ b/trunk/arch/arm/mach-at91/board-kb9202.c @@ -50,6 +50,24 @@ static void __init kb9202_init_early(void) /* Initialize processor: 10 MHz crystal */ at91_initialize(10000000); + + /* Set up the LEDs */ + at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1 (Rx & Tx only) */ + at91_register_uart(AT91RM9200_ID_US0, 1, 0); + + /* USART1 on ttyS2 (Rx & Tx only) - IRDA (optional) */ + at91_register_uart(AT91RM9200_ID_US1, 2, 0); + + /* USART3 on ttyS3 (Rx, Tx, CTS, RTS) - RS485 (optional) */ + at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata kb9202_eth_data = { @@ -97,21 +115,7 @@ static struct atmel_nand_data __initdata kb9202_nand_data = { static void __init kb9202_board_init(void) { - /* Set up the LEDs */ - at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1 (Rx & Tx only) */ - at91_register_uart(AT91RM9200_ID_US0, 1, 0); - - /* USART1 on ttyS2 (Rx & Tx only) - IRDA (optional) */ - at91_register_uart(AT91RM9200_ID_US1, 2, 0); - - /* USART3 on ttyS3 (Rx, Tx, CTS, RTS) - RS485 (optional) */ - at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&kb9202_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-neocore926.c b/trunk/arch/arm/mach-at91/board-neocore926.c index d2f4cc161766..57d5f6a4726a 100644 --- a/trunk/arch/arm/mach-at91/board-neocore926.c +++ b/trunk/arch/arm/mach-at91/board-neocore926.c @@ -55,6 +55,15 @@ static void __init neocore926_init_early(void) { /* Initialize processor: 20 MHz crystal */ at91_initialize(20000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -332,11 +341,6 @@ static struct ac97c_platform_data neocore926_ac97_data = { static void __init neocore926_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ diff --git a/trunk/arch/arm/mach-at91/board-pcontrol-g20.c b/trunk/arch/arm/mach-at91/board-pcontrol-g20.c index 7fe638342421..b4a12fc184c8 100644 --- a/trunk/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/trunk/arch/arm/mach-at91/board-pcontrol-g20.c @@ -40,6 +40,17 @@ static void __init pcontrol_g20_init_early(void) { stamp9g20_init_early(); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) isolated RS485 X5 */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ + at91_register_uart(AT91SAM9260_ID_US4, 3, 0); } static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { @@ -188,16 +199,6 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = { static void __init pcontrol_g20_board_init(void) { - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS - | ATMEL_UART_RTS); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) isolated RS485 X5 */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS - | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ - at91_register_uart(AT91SAM9260_ID_US4, 3, 0); stamp9g20_board_init(); at91_add_device_usbh(&usbh_data); at91_add_device_eth(&macb_data); diff --git a/trunk/arch/arm/mach-at91/board-picotux200.c b/trunk/arch/arm/mach-at91/board-picotux200.c index b45c0a5d5ca7..59e35dd14863 100644 --- a/trunk/arch/arm/mach-at91/board-picotux200.c +++ b/trunk/arch/arm/mach-at91/board-picotux200.c @@ -48,6 +48,17 @@ static void __init picotux200_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata picotux200_eth_data = { @@ -95,13 +106,6 @@ static struct platform_device picotux200_flash = { static void __init picotux200_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&picotux200_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-qil-a9260.c b/trunk/arch/arm/mach-at91/board-qil-a9260.c index 0c61bf0d272c..b6ed5ed7081a 100644 --- a/trunk/arch/arm/mach-at91/board-qil-a9260.c +++ b/trunk/arch/arm/mach-at91/board-qil-a9260.c @@ -52,6 +52,24 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ at91_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS1 (ie, USART0) */ + at91_set_serial_console(1); + } /* @@ -217,19 +235,6 @@ static struct gpio_led ek_leds[] = { static void __init ek_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-rm9200dk.c b/trunk/arch/arm/mach-at91/board-rm9200dk.c index afd7a4713766..01332aa538b2 100644 --- a/trunk/arch/arm/mach-at91/board-rm9200dk.c +++ b/trunk/arch/arm/mach-at91/board-rm9200dk.c @@ -50,6 +50,20 @@ static void __init dk_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata dk_eth_data = { @@ -176,17 +190,7 @@ static struct gpio_led dk_leds[] = { static void __init dk_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&dk_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-rm9200ek.c b/trunk/arch/arm/mach-at91/board-rm9200ek.c index 2b15b8adec4c..11cbaa8946fe 100644 --- a/trunk/arch/arm/mach-at91/board-rm9200ek.c +++ b/trunk/arch/arm/mach-at91/board-rm9200ek.c @@ -50,6 +50,20 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } static struct macb_platform_data __initdata ek_eth_data = { @@ -103,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { }; #define EK_FLASH_BASE AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE SZ_8M +#define EK_FLASH_SIZE SZ_2M static struct physmap_flash_data ek_flash_data = { .width = 2, @@ -147,17 +161,7 @@ static struct gpio_led ek_leds[] = { static void __init ek_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&ek_eth_data); diff --git a/trunk/arch/arm/mach-at91/board-rsi-ews.c b/trunk/arch/arm/mach-at91/board-rsi-ews.c index 24ab9be7510f..af0750fafa29 100644 --- a/trunk/arch/arm/mach-at91/board-rsi-ews.c +++ b/trunk/arch/arm/mach-at91/board-rsi-ews.c @@ -35,6 +35,26 @@ static void __init rsi_ews_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB6, AT91_PIN_PB9); + + /* DBGU on ttyS0. (Rx & Tx only) */ + /* This one is for debugging */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + /* Dialin/-out modem interface */ + at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART3 on ttyS4. (Rx, Tx, RTS) */ + /* RS485 communication */ + at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -184,23 +204,7 @@ static struct platform_device rsiews_nor_flash = { */ static void __init rsi_ews_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB6, AT91_PIN_PB9); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - /* This one is for debugging */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - /* Dialin/-out modem interface */ - at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART3 on ttyS4. (Rx, Tx, RTS) */ - /* RS485 communication */ - at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_RTS); at91_add_device_serial(); at91_set_gpio_output(AT91_PIN_PA21, 0); /* Ethernet */ diff --git a/trunk/arch/arm/mach-at91/board-sam9-l9260.c b/trunk/arch/arm/mach-at91/board-sam9-l9260.c index cdd21f2595d2..e8b116b6cba6 100644 --- a/trunk/arch/arm/mach-at91/board-sam9-l9260.c +++ b/trunk/arch/arm/mach-at91/board-sam9-l9260.c @@ -48,6 +48,23 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -167,20 +184,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { static void __init ek_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9260ek.c b/trunk/arch/arm/mach-at91/board-sam9260ek.c index 7b3c3913551a..d5aec55b0eb4 100644 --- a/trunk/arch/arm/mach-at91/board-sam9260ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9260ek.c @@ -54,6 +54,20 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -306,16 +320,6 @@ static void __init ek_add_device_buttons(void) {} static void __init ek_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c index 2736453821b0..c3f994462864 100644 --- a/trunk/arch/arm/mach-at91/board-sam9261ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c @@ -58,6 +58,15 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -76,6 +85,8 @@ static struct resource dm9000_resource[] = { .flags = IORESOURCE_MEM }, [2] = { + .start = AT91_PIN_PC11, + .end = AT91_PIN_PC11, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, } @@ -119,8 +130,6 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init ek_add_device_dm9000(void) { - struct resource *r = &dm9000_resource[2]; - /* Configure chip-select 2 (DM9000) */ sam9_smc_configure(0, 2, &dm9000_smc_config); @@ -130,7 +139,6 @@ static void __init ek_add_device_dm9000(void) /* Configure Interrupt pin as input, no pull-up */ at91_set_gpio_input(AT91_PIN_PC11, 0); - r->start = r->end = gpio_to_irq(AT91_PIN_PC11); platform_device_register(&dm9000_device); } #else @@ -568,12 +576,7 @@ static struct gpio_led ek_leds[] = { static void __init ek_board_init(void) { - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9263ek.c b/trunk/arch/arm/mach-at91/board-sam9263ek.c index 983cb98d2465..2ffe50f3a9e9 100644 --- a/trunk/arch/arm/mach-at91/board-sam9263ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9263ek.c @@ -57,6 +57,15 @@ static void __init ek_init_early(void) { /* Initialize processor: 16.367 MHz crystal */ at91_initialize(16367660); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -403,11 +412,6 @@ static struct at91_can_data ek_can_data = { static void __init ek_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9g20ek.c b/trunk/arch/arm/mach-at91/board-sam9g20ek.c index 3d615532ae5c..8923ec9f5831 100644 --- a/trunk/arch/arm/mach-at91/board-sam9g20ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9g20ek.c @@ -65,6 +65,20 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -358,16 +372,6 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { static void __init ek_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c b/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c index 9a87f0b072f8..c88e908ddd82 100644 --- a/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -53,6 +53,16 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ at91_initialize(12000000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 not connected on the -EK board */ + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -447,12 +457,6 @@ static struct platform_device *devices[] __initdata = { static void __init ek_board_init(void) { /* Serial */ - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 not connected on the -EK board */ - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB HS Host */ at91_add_device_usbh_ohci(&ek_usbh_hs_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9rlek.c b/trunk/arch/arm/mach-at91/board-sam9rlek.c index be3239f13daa..b109ce2ba864 100644 --- a/trunk/arch/arm/mach-at91/board-sam9rlek.c +++ b/trunk/arch/arm/mach-at91/board-sam9rlek.c @@ -42,6 +42,15 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ at91_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9RL_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -287,11 +296,6 @@ static void __init ek_add_device_buttons(void) {} static void __init ek_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9RL_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); at91_add_device_serial(); /* USB HS */ at91_add_device_usba(&ek_usba_udc_data); diff --git a/trunk/arch/arm/mach-at91/board-snapper9260.c b/trunk/arch/arm/mach-at91/board-snapper9260.c index 9d446f1bb45f..ebc9d01ce742 100644 --- a/trunk/arch/arm/mach-at91/board-snapper9260.c +++ b/trunk/arch/arm/mach-at91/board-snapper9260.c @@ -43,6 +43,16 @@ static void __init snapper9260_init_early(void) { at91_initialize(18432000); + + /* Debug on ttyS0 */ + at91_register_uart(0, 0, 0); + at91_set_serial_console(0); + + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS | ATMEL_UART_RTS); + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS | ATMEL_UART_RTS); + at91_register_uart(AT91SAM9260_ID_US2, 3, 0); } static struct at91_usbh_data __initdata snapper9260_usbh_data = { @@ -158,14 +168,6 @@ static void __init snapper9260_board_init(void) snapper9260_i2c_isl1208.irq = gpio_to_irq(AT91_PIN_PA31); i2c_register_board_info(0, &snapper9260_i2c_isl1208, 1); - /* Debug on ttyS0 */ - at91_register_uart(0, 0, 0); - - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_register_uart(AT91SAM9260_ID_US2, 3, 0); at91_add_device_serial(); at91_add_device_usbh(&snapper9260_usbh_data); at91_add_device_udc(&snapper9260_udc_data); diff --git a/trunk/arch/arm/mach-at91/board-stamp9g20.c b/trunk/arch/arm/mach-at91/board-stamp9g20.c index ee86f9d7ee72..7640049410a0 100644 --- a/trunk/arch/arm/mach-at91/board-stamp9g20.c +++ b/trunk/arch/arm/mach-at91/board-stamp9g20.c @@ -36,6 +36,44 @@ void __init stamp9g20_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init stamp9g20evb_init_early(void) +{ + stamp9g20_init_early(); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); +} + +static void __init portuxg20_init_early(void) +{ + stamp9g20_init_early(); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART4 on ttyS5. (Rx, Tx only) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx, Tx only) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); } /* @@ -216,8 +254,6 @@ void add_w1(void) void __init stamp9g20_board_init(void) { /* Serial */ - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* NAND */ add_device_nand(); @@ -233,22 +269,6 @@ void __init stamp9g20_board_init(void) static void __init portuxg20_board_init(void) { - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR - | ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART4 on ttyS5. (Rx, Tx only) */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); - - /* USART5 on ttyS6. (Rx, Tx only) */ - at91_register_uart(AT91SAM9260_ID_US5, 6, 0); stamp9g20_board_init(); /* USB Host */ at91_add_device_usbh(&usbh_data); @@ -266,10 +286,6 @@ static void __init portuxg20_board_init(void) static void __init stamp9g20evb_board_init(void) { - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR - | ATMEL_UART_DCD | ATMEL_UART_RI); stamp9g20_board_init(); /* USB Host */ at91_add_device_usbh(&usbh_data); @@ -287,7 +303,7 @@ MACHINE_START(PORTUXG20, "taskit PortuxG20") /* Maintainer: taskit GmbH */ .timer = &at91sam926x_timer, .map_io = at91_map_io, - .init_early = stamp9g20_init_early, + .init_early = portuxg20_init_early, .init_irq = at91_init_irq_default, .init_machine = portuxg20_board_init, MACHINE_END @@ -296,7 +312,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20") /* Maintainer: taskit GmbH */ .timer = &at91sam926x_timer, .map_io = at91_map_io, - .init_early = stamp9g20_init_early, + .init_early = stamp9g20evb_init_early, .init_irq = at91_init_irq_default, .init_machine = stamp9g20evb_board_init, MACHINE_END diff --git a/trunk/arch/arm/mach-at91/board-usb-a926x.c b/trunk/arch/arm/mach-at91/board-usb-a926x.c index 332ecd40bd02..b7483a3d0980 100644 --- a/trunk/arch/arm/mach-at91/board-usb-a926x.c +++ b/trunk/arch/arm/mach-at91/board-usb-a926x.c @@ -53,6 +53,12 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.00 MHz crystal */ at91_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -319,8 +325,6 @@ static void __init ek_add_device_leds(void) static void __init ek_board_init(void) { /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); at91_add_device_serial(); /* USB Host */ at91_add_device_usbh(&ek_usbh_data); diff --git a/trunk/arch/arm/mach-at91/board-yl-9200.c b/trunk/arch/arm/mach-at91/board-yl-9200.c index d56665ea4b55..38dd279d30b2 100644 --- a/trunk/arch/arm/mach-at91/board-yl-9200.c +++ b/trunk/arch/arm/mach-at91/board-yl-9200.c @@ -58,6 +58,26 @@ static void __init yl9200_init_early(void) /* Initialize processor: 18.432 MHz crystal */ at91_initialize(18432000); + + /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ + at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART0 on ttyS2. (Rx & Tx only to JP3) */ + at91_register_uart(AT91RM9200_ID_US0, 2, 0); + + /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */ + at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } /* @@ -540,23 +560,7 @@ void __init yl9200_add_device_video(void) {} static void __init yl9200_board_init(void) { - /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ - at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART0 on ttyS2. (Rx & Tx only to JP3) */ - at91_register_uart(AT91RM9200_ID_US0, 2, 0); - - /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */ - at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS); at91_add_device_serial(); /* Ethernet */ at91_add_device_eth(&yl9200_eth_data); diff --git a/trunk/arch/arm/mach-at91/clock.c b/trunk/arch/arm/mach-at91/clock.c index 6b692824c988..a0f4d7424cdc 100644 --- a/trunk/arch/arm/mach-at91/clock.c +++ b/trunk/arch/arm/mach-at91/clock.c @@ -35,7 +35,6 @@ #include "generic.h" void __iomem *at91_pmc_base; -EXPORT_SYMBOL_GPL(at91_pmc_base); /* * There's a lot more which can be done with clocks, including cpufreq diff --git a/trunk/arch/arm/mach-at91/cpuidle.c b/trunk/arch/arm/mach-at91/cpuidle.c index 0c6381516a5a..ece1f9aefb47 100644 --- a/trunk/arch/arm/mach-at91/cpuidle.c +++ b/trunk/arch/arm/mach-at91/cpuidle.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "pm.h" @@ -34,12 +33,7 @@ static int at91_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - if (cpu_is_at91rm9200()) - at91rm9200_standby(); - else if (cpu_is_at91sam9g45()) - at91sam9g45_standby(); - else - at91sam9_standby(); + at91_standby(); return index; } diff --git a/trunk/arch/arm/mach-at91/generic.h b/trunk/arch/arm/mach-at91/generic.h index 0a60bf837037..dd9b346c451d 100644 --- a/trunk/arch/arm/mach-at91/generic.h +++ b/trunk/arch/arm/mach-at91/generic.h @@ -40,6 +40,17 @@ extern struct sys_timer at91sam926x_timer; extern struct sys_timer at91x40_timer; /* Clocks */ +/* + * function to specify the clock of the default console. As we do not + * use the device/driver bus, the dev_name is not intialize. So we need + * to link the clock to a specific con_id only "usart" + */ +extern void __init at91rm9200_set_console_clock(int id); +extern void __init at91sam9260_set_console_clock(int id); +extern void __init at91sam9261_set_console_clock(int id); +extern void __init at91sam9263_set_console_clock(int id); +extern void __init at91sam9rl_set_console_clock(int id); +extern void __init at91sam9g45_set_console_clock(int id); #ifdef CONFIG_AT91_PMC_UNIT extern int __init at91_clock_init(unsigned long main_clock); extern int __init at91_dt_clock_init(void); diff --git a/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h b/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h index ea2c57a86ca6..36604782a78f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base; #define at91_pmc_write(field, value) \ __raw_writel(value, at91_pmc_base + field) #else -.extern at91_pmc_base +.extern at91_aic_base #endif #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91rm9200.h b/trunk/arch/arm/mach-at91/include/mach/at91rm9200.h index e67317c67761..603e6aac2a4f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -88,6 +88,11 @@ #define AT91RM9200_BASE_RTC 0xfffffe00 /* Real-Time Clock */ #define AT91RM9200_BASE_MC 0xffffff00 /* Memory Controllers */ +#define AT91_USART0 AT91RM9200_BASE_US0 +#define AT91_USART1 AT91RM9200_BASE_US1 +#define AT91_USART2 AT91RM9200_BASE_US2 +#define AT91_USART3 AT91RM9200_BASE_US3 + /* * Internal Memory. */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h index 416c7b6c56d3..08ae9afd00fe 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -95,6 +95,13 @@ #define AT91SAM9260_BASE_WDT 0xfffffd40 #define AT91SAM9260_BASE_GPBR 0xfffffd50 +#define AT91_USART0 AT91SAM9260_BASE_US0 +#define AT91_USART1 AT91SAM9260_BASE_US1 +#define AT91_USART2 AT91SAM9260_BASE_US2 +#define AT91_USART3 AT91SAM9260_BASE_US3 +#define AT91_USART4 AT91SAM9260_BASE_US4 +#define AT91_USART5 AT91SAM9260_BASE_US5 + /* * Internal Memory. diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h index a041406d06ee..44fbdc12ee62 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -79,6 +79,10 @@ #define AT91SAM9261_BASE_WDT 0xfffffd40 #define AT91SAM9261_BASE_GPBR 0xfffffd50 +#define AT91_USART0 AT91SAM9261_BASE_US0 +#define AT91_USART1 AT91SAM9261_BASE_US1 +#define AT91_USART2 AT91SAM9261_BASE_US2 + /* * Internal Memory. diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h index d201029d60b3..d96cbb2e03c4 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -95,6 +95,10 @@ #define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91SAM9263_BASE_GPBR 0xfffffd60 +#define AT91_USART0 AT91SAM9263_BASE_US0 +#define AT91_USART1 AT91SAM9263_BASE_US1 +#define AT91_USART2 AT91SAM9263_BASE_US2 + #define AT91_SMC AT91_SMC0 /* diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h index 3a4da24d5911..d052abcff852 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -106,6 +106,11 @@ #define AT91SAM9G45_BASE_RTC 0xfffffdb0 #define AT91SAM9G45_BASE_GPBR 0xfffffd60 +#define AT91_USART0 AT91SAM9G45_BASE_US0 +#define AT91_USART1 AT91SAM9G45_BASE_US1 +#define AT91_USART2 AT91SAM9G45_BASE_US2 +#define AT91_USART3 AT91SAM9G45_BASE_US3 + /* * Internal Memory. */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h index a15db56d33fa..e0073eb10144 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -89,6 +89,11 @@ #define AT91SAM9RL_BASE_GPBR 0xfffffd60 #define AT91SAM9RL_BASE_RTC 0xfffffe00 +#define AT91_USART0 AT91SAM9RL_BASE_US0 +#define AT91_USART1 AT91SAM9RL_BASE_US1 +#define AT91_USART2 AT91SAM9RL_BASE_US2 +#define AT91_USART3 AT91SAM9RL_BASE_US3 + /* * Internal Memory. diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9x5.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9x5.h index c75ee19b58d3..88e43d534cdf 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9x5.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -54,6 +54,14 @@ #define AT91SAM9X5_BASE_USART1 0xf8020000 #define AT91SAM9X5_BASE_USART2 0xf8024000 +/* + * Base addresses for early serial code (uncompress.h) + */ +#define AT91_DBGU AT91_BASE_DBGU0 +#define AT91_USART0 AT91SAM9X5_BASE_USART0 +#define AT91_USART1 AT91SAM9X5_BASE_USART1 +#define AT91_USART2 AT91SAM9X5_BASE_USART2 + /* * Internal Memory. */ diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index 369afc2ffc5b..49a821192c65 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -121,6 +121,7 @@ extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_de #define ATMEL_UART_RI 0x20 extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins); +extern void __init at91_set_serial_console(unsigned portnr); extern struct platform_device *atmel_default_console_device; diff --git a/trunk/arch/arm/mach-at91/include/mach/cpu.h b/trunk/arch/arm/mach-at91/include/mach/cpu.h index 73d2fd209ce4..0118c3338552 100644 --- a/trunk/arch/arm/mach-at91/include/mach/cpu.h +++ b/trunk/arch/arm/mach-at91/include/mach/cpu.h @@ -54,7 +54,6 @@ #define ARCH_REVISON_9200_BGA (0 << 0) #define ARCH_REVISON_9200_PQFP (1 << 0) -#ifndef __ASSEMBLY__ enum at91_soc_type { /* 920T */ AT91_SOC_RM9200, @@ -107,7 +106,7 @@ static inline int at91_soc_is_detected(void) return at91_soc_initdata.type != AT91_SOC_NONE; } -#ifdef CONFIG_SOC_AT91RM9200 +#ifdef CONFIG_ARCH_AT91RM9200 #define cpu_is_at91rm9200() (at91_soc_initdata.type == AT91_SOC_RM9200) #define cpu_is_at91rm9200_bga() (at91_soc_initdata.subtype == AT91_SOC_RM9200_BGA) #define cpu_is_at91rm9200_pqfp() (at91_soc_initdata.subtype == AT91_SOC_RM9200_PQFP) @@ -117,37 +116,45 @@ static inline int at91_soc_is_detected(void) #define cpu_is_at91rm9200_pqfp() (0) #endif -#ifdef CONFIG_SOC_AT91SAM9260 +#ifdef CONFIG_ARCH_AT91SAM9260 #define cpu_is_at91sam9xe() (at91_soc_initdata.subtype == AT91_SOC_SAM9XE) #define cpu_is_at91sam9260() (at91_soc_initdata.type == AT91_SOC_SAM9260) -#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20) #else #define cpu_is_at91sam9xe() (0) #define cpu_is_at91sam9260() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9G20 +#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20) +#else #define cpu_is_at91sam9g20() (0) #endif -#ifdef CONFIG_SOC_AT91SAM9261 +#ifdef CONFIG_ARCH_AT91SAM9261 #define cpu_is_at91sam9261() (at91_soc_initdata.type == AT91_SOC_SAM9261) -#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10) #else #define cpu_is_at91sam9261() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9G10 +#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10) +#else #define cpu_is_at91sam9g10() (0) #endif -#ifdef CONFIG_SOC_AT91SAM9263 +#ifdef CONFIG_ARCH_AT91SAM9263 #define cpu_is_at91sam9263() (at91_soc_initdata.type == AT91_SOC_SAM9263) #else #define cpu_is_at91sam9263() (0) #endif -#ifdef CONFIG_SOC_AT91SAM9RL +#ifdef CONFIG_ARCH_AT91SAM9RL #define cpu_is_at91sam9rl() (at91_soc_initdata.type == AT91_SOC_SAM9RL) #else #define cpu_is_at91sam9rl() (0) #endif -#ifdef CONFIG_SOC_AT91SAM9G45 +#ifdef CONFIG_ARCH_AT91SAM9G45 #define cpu_is_at91sam9g45() (at91_soc_initdata.type == AT91_SOC_SAM9G45) #define cpu_is_at91sam9g45es() (at91_soc_initdata.subtype == AT91_SOC_SAM9G45ES) #define cpu_is_at91sam9m10() (at91_soc_initdata.subtype == AT91_SOC_SAM9M10) @@ -161,7 +168,7 @@ static inline int at91_soc_is_detected(void) #define cpu_is_at91sam9m11() (0) #endif -#ifdef CONFIG_SOC_AT91SAM9X5 +#ifdef CONFIG_ARCH_AT91SAM9X5 #define cpu_is_at91sam9x5() (at91_soc_initdata.type == AT91_SOC_SAM9X5) #define cpu_is_at91sam9g15() (at91_soc_initdata.subtype == AT91_SOC_SAM9G15) #define cpu_is_at91sam9g35() (at91_soc_initdata.subtype == AT91_SOC_SAM9G35) @@ -182,6 +189,5 @@ static inline int at91_soc_is_detected(void) * definitions may reduce clutter in common drivers. */ #define cpu_is_at32ap7000() (0) -#endif /* __ASSEMBLY__ */ #endif /* __MACH_CPU_H__ */ diff --git a/trunk/arch/arm/mach-at91/include/mach/hardware.h b/trunk/arch/arm/mach-at91/include/mach/hardware.h index 3a01f8ff7e74..e9e29a6c3868 100644 --- a/trunk/arch/arm/mach-at91/include/mach/hardware.h +++ b/trunk/arch/arm/mach-at91/include/mach/hardware.h @@ -22,17 +22,27 @@ /* 9263, 9g45 */ #define AT91_BASE_DBGU1 0xffffee00 -#if defined(CONFIG_ARCH_AT91X40) -#include -#else +#if defined(CONFIG_ARCH_AT91RM9200) #include +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) #include +#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10) #include +#elif defined(CONFIG_ARCH_AT91SAM9263) #include +#elif defined(CONFIG_ARCH_AT91SAM9RL) #include +#elif defined(CONFIG_ARCH_AT91SAM9G45) #include +#elif defined(CONFIG_ARCH_AT91SAM9X5) #include +#elif defined(CONFIG_ARCH_AT91X40) +#include +#else +#error "Unsupported AT91 processor" +#endif +#if !defined(CONFIG_ARCH_AT91X40) /* * On all at91 except rm9200 and x40 have the System Controller starts * at address 0xffffc000 and has a size of 16KiB. diff --git a/trunk/arch/arm/mach-at91/include/mach/uncompress.h b/trunk/arch/arm/mach-at91/include/mach/uncompress.h index 6f6118d1576a..4218647c1fcd 100644 --- a/trunk/arch/arm/mach-at91/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-at91/include/mach/uncompress.h @@ -1,8 +1,7 @@ /* * arch/arm/mach-at91/include/mach/uncompress.h * - * Copyright (C) 2003 SAN People - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * Copyright (C) 2003 SAN People * * 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 @@ -26,147 +25,22 @@ #include #include -#include -#include - -void __iomem *at91_uart; - -#if !defined(CONFIG_ARCH_AT91X40) -static const u32 uarts_rm9200[] = { - AT91_BASE_DBGU0, - AT91RM9200_BASE_US0, - AT91RM9200_BASE_US1, - AT91RM9200_BASE_US2, - AT91RM9200_BASE_US3, - 0, -}; - -static const u32 uarts_sam9260[] = { - AT91_BASE_DBGU0, - AT91SAM9260_BASE_US0, - AT91SAM9260_BASE_US1, - AT91SAM9260_BASE_US2, - AT91SAM9260_BASE_US3, - AT91SAM9260_BASE_US4, - AT91SAM9260_BASE_US5, - 0, -}; - -static const u32 uarts_sam9261[] = { - AT91_BASE_DBGU0, - AT91SAM9261_BASE_US0, - AT91SAM9261_BASE_US1, - AT91SAM9261_BASE_US2, - 0, -}; - -static const u32 uarts_sam9263[] = { - AT91_BASE_DBGU1, - AT91SAM9263_BASE_US0, - AT91SAM9263_BASE_US1, - AT91SAM9263_BASE_US2, - 0, -}; - -static const u32 uarts_sam9g45[] = { - AT91_BASE_DBGU1, - AT91SAM9G45_BASE_US0, - AT91SAM9G45_BASE_US1, - AT91SAM9G45_BASE_US2, - AT91SAM9G45_BASE_US3, - 0, -}; - -static const u32 uarts_sam9rl[] = { - AT91_BASE_DBGU0, - AT91SAM9RL_BASE_US0, - AT91SAM9RL_BASE_US1, - AT91SAM9RL_BASE_US2, - AT91SAM9RL_BASE_US3, - 0, -}; - -static const u32 uarts_sam9x5[] = { - AT91_BASE_DBGU0, - AT91SAM9X5_BASE_USART0, - AT91SAM9X5_BASE_USART1, - AT91SAM9X5_BASE_USART2, - 0, -}; - -static inline const u32* decomp_soc_detect(u32 dbgu_base) -{ - u32 cidr, socid; - - cidr = __raw_readl(dbgu_base + AT91_DBGU_CIDR); - socid = cidr & ~AT91_CIDR_VERSION; - - switch (socid) { - case ARCH_ID_AT91RM9200: - return uarts_rm9200; - - case ARCH_ID_AT91SAM9G20: - case ARCH_ID_AT91SAM9260: - return uarts_sam9260; - - case ARCH_ID_AT91SAM9261: - return uarts_sam9261; - - case ARCH_ID_AT91SAM9263: - return uarts_sam9263; - - case ARCH_ID_AT91SAM9G45: - return uarts_sam9g45; - - case ARCH_ID_AT91SAM9RL64: - return uarts_sam9rl; - - case ARCH_ID_AT91SAM9X5: - return uarts_sam9x5; - } - - /* at91sam9g10 */ - if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { - return uarts_sam9261; - } - /* at91sam9xe */ - else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) { - return uarts_sam9260; - } - - return NULL; -} - -static inline void arch_decomp_setup(void) -{ - int i = 0; - const u32* usarts; - - usarts = decomp_soc_detect(AT91_BASE_DBGU0); - - if (!usarts) - usarts = decomp_soc_detect(AT91_BASE_DBGU1); - if (!usarts) { - at91_uart = NULL; - return; - } - - do { - /* physical address */ - at91_uart = (void __iomem *)usarts[i]; - - if (__raw_readl(at91_uart + ATMEL_US_BRGR)) - return; - i++; - } while (usarts[i]); - - at91_uart = NULL; -} -#else -static inline void arch_decomp_setup(void) -{ - at91_uart = NULL; -} +#if defined(CONFIG_AT91_EARLY_DBGU0) +#define UART_OFFSET AT91_BASE_DBGU0 +#elif defined(CONFIG_AT91_EARLY_DBGU1) +#define UART_OFFSET AT91_BASE_DBGU1 +#elif defined(CONFIG_AT91_EARLY_USART0) +#define UART_OFFSET AT91_USART0 +#elif defined(CONFIG_AT91_EARLY_USART1) +#define UART_OFFSET AT91_USART1 +#elif defined(CONFIG_AT91_EARLY_USART2) +#define UART_OFFSET AT91_USART2 +#elif defined(CONFIG_AT91_EARLY_USART3) +#define UART_OFFSET AT91_USART3 +#elif defined(CONFIG_AT91_EARLY_USART4) +#define UART_OFFSET AT91_USART4 +#elif defined(CONFIG_AT91_EARLY_USART5) +#define UART_OFFSET AT91_USART5 #endif /* @@ -178,24 +52,28 @@ static inline void arch_decomp_setup(void) */ static void putc(int c) { - if (!at91_uart) - return; +#ifdef UART_OFFSET + void __iomem *sys = (void __iomem *) UART_OFFSET; /* physical address */ - while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXRDY)) + while (!(__raw_readl(sys + ATMEL_US_CSR) & ATMEL_US_TXRDY)) barrier(); - __raw_writel(c, at91_uart + ATMEL_US_THR); + __raw_writel(c, sys + ATMEL_US_THR); +#endif } static inline void flush(void) { - if (!at91_uart) - return; +#ifdef UART_OFFSET + void __iomem *sys = (void __iomem *) UART_OFFSET; /* physical address */ /* wait for transmission to complete */ - while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXEMPTY)) + while (!(__raw_readl(sys + ATMEL_US_CSR) & ATMEL_US_TXEMPTY)) barrier(); +#endif } +#define arch_decomp_setup() + #define arch_decomp_wdog() #endif diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c index 1bfaad628731..f630250c6b87 100644 --- a/trunk/arch/arm/mach-at91/pm.c +++ b/trunk/arch/arm/mach-at91/pm.c @@ -261,12 +261,7 @@ static int at91_pm_enter(suspend_state_t state) * For ARM 926 based chips, this requirement is weaker * as at91sam9 can access a RAM in self-refresh mode. */ - if (cpu_is_at91rm9200()) - at91rm9200_standby(); - else if (cpu_is_at91sam9g45()) - at91sam9g45_standby(); - else - at91sam9_standby(); + at91_standby(); break; case PM_SUSPEND_ON: @@ -312,9 +307,10 @@ static int __init at91_pm_init(void) pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : "")); +#ifdef CONFIG_ARCH_AT91RM9200 /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ - if (cpu_is_at91rm9200()) - at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); + at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); +#endif suspend_set_ops(&at91_pm_ops); diff --git a/trunk/arch/arm/mach-at91/pm.h b/trunk/arch/arm/mach-at91/pm.h index 38f467c6b710..89f56f3a802e 100644 --- a/trunk/arch/arm/mach-at91/pm.h +++ b/trunk/arch/arm/mach-at91/pm.h @@ -12,6 +12,7 @@ #define __ARCH_ARM_MACH_AT91_PM #include +#ifdef CONFIG_ARCH_AT91RM9200 #include /* @@ -42,6 +43,10 @@ static inline void at91rm9200_standby(void) "r" (lpr)); } +#define at91_standby at91rm9200_standby + +#elif defined(CONFIG_ARCH_AT91SAM9G45) + /* We manage both DDRAM/SDRAM controllers, we need more than one value to * remember. */ @@ -70,7 +75,11 @@ static inline void at91sam9g45_standby(void) at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); } -#ifdef CONFIG_SOC_AT91SAM9263 +#define at91_standby at91sam9g45_standby + +#else + +#ifdef CONFIG_ARCH_AT91SAM9263 /* * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; * handle those cases both here and in the Suspend-To-RAM support. @@ -93,4 +102,8 @@ static inline void at91sam9_standby(void) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr); } +#define at91_standby at91sam9_standby + +#endif + #endif diff --git a/trunk/arch/arm/mach-at91/pm_slowclock.S b/trunk/arch/arm/mach-at91/pm_slowclock.S index 098c28ddf025..db5452123f17 100644 --- a/trunk/arch/arm/mach-at91/pm_slowclock.S +++ b/trunk/arch/arm/mach-at91/pm_slowclock.S @@ -18,7 +18,7 @@ #include -#ifdef CONFIG_SOC_AT91SAM9263 +#ifdef CONFIG_ARCH_AT91SAM9263 /* * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; * handle those cases both here and in the Suspend-To-RAM support. diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index f44a2e7272e3..97cc04dc8073 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -54,7 +54,6 @@ void __init at91_init_interrupts(unsigned int *priority) } void __iomem *at91_ramc_base[2]; -EXPORT_SYMBOL_GPL(at91_ramc_base); void __init at91_ioremap_ramc(int id, u32 addr, u32 size) { @@ -293,7 +292,6 @@ void __init at91_ioremap_rstc(u32 base_addr) } void __iomem *at91_matrix_base; -EXPORT_SYMBOL_GPL(at91_matrix_base); void __init at91_ioremap_matrix(u32 base_addr) { diff --git a/trunk/arch/arm/mach-at91/soc.h b/trunk/arch/arm/mach-at91/soc.h index 683dddfd8b13..5db4aa45404a 100644 --- a/trunk/arch/arm/mach-at91/soc.h +++ b/trunk/arch/arm/mach-at91/soc.h @@ -26,30 +26,30 @@ static inline int at91_soc_is_enabled(void) return at91_boot_soc.init != NULL; } -#if !defined(CONFIG_SOC_AT91RM9200) +#if !defined(CONFIG_ARCH_AT91RM9200) #define at91rm9200_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_AT91SAM9260) +#if !(defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)) #define at91sam9260_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_AT91SAM9261) +#if !(defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)) #define at91sam9261_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_AT91SAM9263) +#if !defined(CONFIG_ARCH_AT91SAM9263) #define at91sam9263_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_AT91SAM9G45) +#if !defined(CONFIG_ARCH_AT91SAM9G45) #define at91sam9g45_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_AT91SAM9RL) +#if !defined(CONFIG_ARCH_AT91SAM9RL) #define at91sam9rl_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_AT91SAM9X5) +#if !defined(CONFIG_ARCH_AT91SAM9X5) #define at91sam9x5_soc at91_boot_soc #endif diff --git a/trunk/arch/arm/mach-bcmring/core.c b/trunk/arch/arm/mach-bcmring/core.c index adbfb1994582..22e4e0a28ad1 100644 --- a/trunk/arch/arm/mach-bcmring/core.c +++ b/trunk/arch/arm/mach-bcmring/core.c @@ -52,8 +52,8 @@ #include #include -static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL); -static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL); +static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); +static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); static struct clk pll1_clk = { .name = "PLL1", diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index e81c35f936b5..0491ceef1cda 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -368,7 +368,6 @@ comment "Flattened Device Tree based board for EXYNOS SoCs" config MACH_EXYNOS4_DT bool "Samsung Exynos4 Machine using device tree" - depends on ARCH_EXYNOS4 select CPU_EXYNOS4210 select USE_OF select ARM_AMBA @@ -381,7 +380,6 @@ config MACH_EXYNOS4_DT config MACH_EXYNOS5_DT bool "SAMSUNG EXYNOS5 Machine using device tree" - depends on ARCH_EXYNOS5 select SOC_EXYNOS5250 select USE_OF select ARM_AMBA diff --git a/trunk/arch/arm/mach-exynos/include/mach/irqs.h b/trunk/arch/arm/mach-exynos/include/mach/irqs.h index 591e78521a9f..9bee8535d9e0 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/irqs.h +++ b/trunk/arch/arm/mach-exynos/include/mach/irqs.h @@ -212,8 +212,6 @@ #define IRQ_MFC EXYNOS4_IRQ_MFC #define IRQ_SDO EXYNOS4_IRQ_SDO -#define IRQ_I2S0 EXYNOS4_IRQ_I2S0 - #define IRQ_ADC EXYNOS4_IRQ_ADC0 #define IRQ_TC EXYNOS4_IRQ_PEN0 diff --git a/trunk/arch/arm/mach-exynos/include/mach/map.h b/trunk/arch/arm/mach-exynos/include/mach/map.h index 6e6d11ff352a..024d38ff1718 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/map.h +++ b/trunk/arch/arm/mach-exynos/include/mach/map.h @@ -89,10 +89,6 @@ #define EXYNOS4_PA_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 -#define EXYNOS5_PA_MDMA0 0x10800000 -#define EXYNOS5_PA_MDMA1 0x11C10000 -#define EXYNOS5_PA_PDMA0 0x121A0000 -#define EXYNOS5_PA_PDMA1 0x121B0000 #define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000 #define EXYNOS4_PA_SYSMMU_SSS 0x10A50000 diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h index d9578a58ae7f..e141c1fd68d8 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -255,15 +255,9 @@ /* For EXYNOS5250 */ -#define EXYNOS5_APLL_LOCK EXYNOS_CLKREG(0x00000) #define EXYNOS5_APLL_CON0 EXYNOS_CLKREG(0x00100) #define EXYNOS5_CLKSRC_CPU EXYNOS_CLKREG(0x00200) -#define EXYNOS5_CLKMUX_STATCPU EXYNOS_CLKREG(0x00400) #define EXYNOS5_CLKDIV_CPU0 EXYNOS_CLKREG(0x00500) -#define EXYNOS5_CLKDIV_CPU1 EXYNOS_CLKREG(0x00504) -#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) -#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) - #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) diff --git a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c index 4711c8920e37..0d26f50081ad 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -45,7 +45,7 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { "exynos4210-uart.3", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.2", NULL), {}, }; diff --git a/trunk/arch/arm/mach-exynos/mach-nuri.c b/trunk/arch/arm/mach-exynos/mach-nuri.c index b4f1f902ce6d..b3982c867c9c 100644 --- a/trunk/arch/arm/mach-exynos/mach-nuri.c +++ b/trunk/arch/arm/mach-exynos/mach-nuri.c @@ -307,7 +307,49 @@ static struct i2c_board_info i2c1_devs[] __initdata = { }; /* TSP */ +static u8 mxt_init_vals[] = { + /* MXT_GEN_COMMAND(6) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_GEN_POWER(7) */ + 0x20, 0xff, 0x32, + /* MXT_GEN_ACQUIRE(8) */ + 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, + /* MXT_TOUCH_MULTI(9) */ + 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + /* MXT_TOUCH_KEYARRAY(15) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, + /* MXT_SPT_GPIOPWM(19) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_PROCI_GRIPFACE(20) */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, + 0x0f, 0x0a, + /* MXT_PROCG_NOISE(22) */ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, + 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, + /* MXT_TOUCH_PROXIMITY(23) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_PROCI_ONETOUCH(24) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_SPT_SELFTEST(25) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* MXT_PROCI_TWOTOUCH(27) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_SPT_CTECONFIG(28) */ + 0x00, 0x00, 0x02, 0x08, 0x10, 0x00, +}; + static struct mxt_platform_data mxt_platform_data = { + .config = mxt_init_vals, + .config_length = ARRAY_SIZE(mxt_init_vals), + .x_line = 18, .y_line = 11, .x_size = 1024, @@ -529,7 +571,7 @@ static struct regulator_init_data __initdata max8997_ldo7_data = { static struct regulator_init_data __initdata max8997_ldo8_data = { .constraints = { - .name = "VUSB+VDAC_3.3V_C210", + .name = "VUSB/VDAC_3.3V_C210", .min_uV = 3300000, .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_STATUS, @@ -1305,7 +1347,6 @@ static struct platform_device *nuri_devices[] __initdata = { static void __init nuri_map_io(void) { - clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); @@ -1338,6 +1379,7 @@ static void __init nuri_machine_init(void) nuri_camera_init(); nuri_ehci_init(); + clk_xusbxti.rate = 24000000; /* Last */ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); diff --git a/trunk/arch/arm/mach-exynos/mach-universal_c210.c b/trunk/arch/arm/mach-exynos/mach-universal_c210.c index 7ebf79c2ab34..6bb9dbdd73fd 100644 --- a/trunk/arch/arm/mach-exynos/mach-universal_c210.c +++ b/trunk/arch/arm/mach-exynos/mach-universal_c210.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -1058,7 +1057,6 @@ static struct platform_device *universal_devices[] __initdata = { static void __init universal_map_io(void) { - clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index f72d399ff3d6..7561eca131b0 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -571,10 +571,8 @@ config MACH_MX35_3DS select MXC_DEBUG_BOARD select IMX_HAVE_PLATFORM_FSL_USB2_UDC select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_FB select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE select IMX_HAVE_PLATFORM_MXC_EHCI select IMX_HAVE_PLATFORM_MXC_NAND select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX diff --git a/trunk/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/trunk/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c index b46cab0ced53..5f2f91d1798b 100644 --- a/trunk/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c +++ b/trunk/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c @@ -243,7 +243,7 @@ static const struct imxuart_platform_data uart_pdata __initconst = { static void __maybe_unused ads7846_dev_init(void) { if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) { - printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); + printk(KERN_ERR "can't get ads746 pen down GPIO\n"); return; } gpio_direction_input(ADS7846_PENDOWN); diff --git a/trunk/arch/arm/mach-imx/imx27-dt.c b/trunk/arch/arm/mach-imx/imx27-dt.c index ed38d03c61f2..861ceb8232d6 100644 --- a/trunk/arch/arm/mach-imx/imx27-dt.c +++ b/trunk/arch/arm/mach-imx/imx27-dt.c @@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { static int __init imx27_avic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL); + irq_domain_add_simple(np, 0); return 0; } @@ -44,9 +44,7 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np, { static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, - NULL); + irq_domain_add_simple(np, gpio_irq_base); return 0; } diff --git a/trunk/arch/arm/mach-imx/mach-cpuimx35.c b/trunk/arch/arm/mach-imx/mach-cpuimx35.c index c515f8ede1a1..8ecc872b2547 100644 --- a/trunk/arch/arm/mach-imx/mach-cpuimx35.c +++ b/trunk/arch/arm/mach-imx/mach-cpuimx35.c @@ -194,7 +194,7 @@ static void __init eukrea_cpuimx35_timer_init(void) mx35_clocks_init(); } -static struct sys_timer eukrea_cpuimx35_timer = { +struct sys_timer eukrea_cpuimx35_timer = { .init = eukrea_cpuimx35_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-mx1ads.c b/trunk/arch/arm/mach-imx/mach-mx1ads.c index 7274e7928136..97046088ff1a 100644 --- a/trunk/arch/arm/mach-imx/mach-mx1ads.c +++ b/trunk/arch/arm/mach-imx/mach-mx1ads.c @@ -134,7 +134,7 @@ static void __init mx1ads_timer_init(void) mx1_clocks_init(32000); } -static struct sys_timer mx1ads_timer = { +struct sys_timer mx1ads_timer = { .init = mx1ads_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-mx21ads.c b/trunk/arch/arm/mach-imx/mach-mx21ads.c index d14bbe949a4f..e432d4acee1f 100644 --- a/trunk/arch/arm/mach-imx/mach-mx21ads.c +++ b/trunk/arch/arm/mach-imx/mach-mx21ads.c @@ -304,7 +304,8 @@ static void __init mx21ads_board_init(void) imx21_add_mxc_nand(&mx21ads_nand_board_info); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); - platform_device_register_full(&mx21ads_cs8900_devinfo); + platform_device_register_full( + (struct platform_device_info *)&mx21ads_cs8900_devinfo); } static void __init mx21ads_timer_init(void) diff --git a/trunk/arch/arm/mach-imx/mach-mx31lite.c b/trunk/arch/arm/mach-imx/mach-mx31lite.c index 686c60587980..0abef5f13df5 100644 --- a/trunk/arch/arm/mach-imx/mach-mx31lite.c +++ b/trunk/arch/arm/mach-imx/mach-mx31lite.c @@ -283,7 +283,7 @@ static void __init mx31lite_timer_init(void) mx31_clocks_init(26000000); } -static struct sys_timer mx31lite_timer = { +struct sys_timer mx31lite_timer = { .init = mx31lite_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-mx31moboard.c b/trunk/arch/arm/mach-imx/mach-mx31moboard.c index 1dfe3c7a7be1..f17a15f28316 100644 --- a/trunk/arch/arm/mach-imx/mach-mx31moboard.c +++ b/trunk/arch/arm/mach-imx/mach-mx31moboard.c @@ -580,7 +580,7 @@ static void __init mx31moboard_timer_init(void) mx31_clocks_init(26000000); } -static struct sys_timer mx31moboard_timer = { +struct sys_timer mx31moboard_timer = { .init = mx31moboard_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-mx35_3ds.c b/trunk/arch/arm/mach-imx/mach-mx35_3ds.c index c433187988a2..6ae51c6b95b7 100644 --- a/trunk/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/trunk/arch/arm/mach-imx/mach-mx35_3ds.c @@ -419,7 +419,7 @@ static void __init mx35pdk_timer_init(void) mx35_clocks_init(); } -static struct sys_timer mx35pdk_timer = { +struct sys_timer mx35pdk_timer = { .init = mx35pdk_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c b/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c index 86e96ef11f9d..586e9f822124 100644 --- a/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c +++ b/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c @@ -284,7 +284,8 @@ static struct sys_timer mx51_efikamx_timer = { .init = mx51_efikamx_timer_init, }; -MACHINE_START(MX51_EFIKAMX, "Genesi Efika MX (Smarttop)") +MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop") + /* Maintainer: Amit Kucheria */ .atag_offset = 0x100, .map_io = mx51_map_io, .init_early = imx51_init_early, diff --git a/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c b/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c index 88f837a6cc76..24aded9e109f 100644 --- a/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c +++ b/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c @@ -280,7 +280,7 @@ static struct sys_timer mx51_efikasb_timer = { .init = mx51_efikasb_timer_init, }; -MACHINE_START(MX51_EFIKASB, "Genesi Efika MX (Smartbook)") +MACHINE_START(MX51_EFIKASB, "Genesi Efika Smartbook") .atag_offset = 0x100, .map_io = mx51_map_io, .init_early = imx51_init_early, diff --git a/trunk/arch/arm/mach-imx/mach-pcm037.c b/trunk/arch/arm/mach-imx/mach-pcm037.c index 10c9795934a3..5fddf94cc969 100644 --- a/trunk/arch/arm/mach-imx/mach-pcm037.c +++ b/trunk/arch/arm/mach-imx/mach-pcm037.c @@ -683,7 +683,7 @@ static void __init pcm037_timer_init(void) mx31_clocks_init(26000000); } -static struct sys_timer pcm037_timer = { +struct sys_timer pcm037_timer = { .init = pcm037_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-pcm043.c b/trunk/arch/arm/mach-imx/mach-pcm043.c index 73585f55cca0..237474fcca23 100644 --- a/trunk/arch/arm/mach-imx/mach-pcm043.c +++ b/trunk/arch/arm/mach-imx/mach-pcm043.c @@ -399,7 +399,7 @@ static void __init pcm043_timer_init(void) mx35_clocks_init(); } -static struct sys_timer pcm043_timer = { +struct sys_timer pcm043_timer = { .init = pcm043_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mach-vpr200.c b/trunk/arch/arm/mach-imx/mach-vpr200.c index add8c69c6c1a..033257e553ef 100644 --- a/trunk/arch/arm/mach-imx/mach-vpr200.c +++ b/trunk/arch/arm/mach-imx/mach-vpr200.c @@ -310,7 +310,7 @@ static void __init vpr200_timer_init(void) mx35_clocks_init(); } -static struct sys_timer vpr200_timer = { +struct sys_timer vpr200_timer = { .init = vpr200_timer_init, }; diff --git a/trunk/arch/arm/mach-imx/mm-imx5.c b/trunk/arch/arm/mach-imx/mm-imx5.c index e10f3914fcfe..05250aed61fb 100644 --- a/trunk/arch/arm/mach-imx/mm-imx5.c +++ b/trunk/arch/arm/mach-imx/mm-imx5.c @@ -35,7 +35,7 @@ static void imx5_idle(void) } clk_enable(gpc_dvfs_clk); mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (!tzic_enable_wake()) + if (tzic_enable_wake() != 0) cpu_do_idle(); clk_disable(gpc_dvfs_clk); } diff --git a/trunk/arch/arm/mach-ixp2000/Kconfig b/trunk/arch/arm/mach-ixp2000/Kconfig new file mode 100644 index 000000000000..08d2707f6ca8 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/Kconfig @@ -0,0 +1,72 @@ + +if ARCH_IXP2000 + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + default y + +menu "Intel IXP2400/2800 Implementation Options" + +comment "IXP2400/2800 Platforms" + +config ARCH_ENP2611 + bool "Support Radisys ENP-2611" + help + Say 'Y' here if you want your kernel to support the Radisys + ENP2611 PCI network processing card. For more information on + this card, see . + +config ARCH_IXDP2400 + bool "Support Intel IXDP2400" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2400 reference platform. For more information on + this platform, see . + +config ARCH_IXDP2800 + bool "Support Intel IXDP2800" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2800 reference platform. For more information on + this platform, see . + +config ARCH_IXDP2X00 + bool + depends on ARCH_IXDP2400 || ARCH_IXDP2800 + default y + +config ARCH_IXDP2401 + bool "Support Intel IXDP2401" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2401 reference platform. For more information on + this platform, see . + +config ARCH_IXDP2801 + bool "Support Intel IXDP2801 and IXDP28x5" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2801/2805/2855 reference platforms. For more information on + this platform, see . + +config MACH_IXDP28X5 + bool + depends on ARCH_IXDP2801 + default y + +config ARCH_IXDP2X01 + bool + depends on ARCH_IXDP2401 || ARCH_IXDP2801 + default y + +config IXP2000_SUPPORT_BROKEN_PCI_IO + bool "Support broken PCI I/O on older IXP2000s" + default y + help + Say 'N' here if you only intend to run your kernel on an + IXP2000 B0 or later model and do not need the PCI I/O + byteswap workaround. Say 'Y' otherwise. + +endmenu + +endif diff --git a/trunk/arch/arm/mach-ixp2000/Makefile b/trunk/arch/arm/mach-ixp2000/Makefile new file mode 100644 index 000000000000..1e6139d42a92 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/Makefile @@ -0,0 +1,14 @@ +# +# Makefile for the linux kernel. +# +obj-y := core.o pci.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_ENP2611) += enp2611.o +obj-$(CONFIG_ARCH_IXDP2400) += ixdp2400.o +obj-$(CONFIG_ARCH_IXDP2800) += ixdp2800.o +obj-$(CONFIG_ARCH_IXDP2X00) += ixdp2x00.o +obj-$(CONFIG_ARCH_IXDP2X01) += ixdp2x01.o + diff --git a/trunk/arch/arm/mach-ixp2000/Makefile.boot b/trunk/arch/arm/mach-ixp2000/Makefile.boot new file mode 100644 index 000000000000..9c7af91d93da --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y += 0x00008000 +params_phys-y := 0x00000100 + diff --git a/trunk/arch/arm/mach-ixp2000/core.c b/trunk/arch/arm/mach-ixp2000/core.c new file mode 100644 index 000000000000..f214cdff01cb --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/core.c @@ -0,0 +1,520 @@ +/* + * arch/arm/mach-ixp2000/core.c + * + * Common routines used by all IXP2400/2800 based platforms. + * + * Author: Deepak Saxena + * + * Copyright 2004 (C) MontaVista Software, Inc. + * + * Based on work Copyright (C) 2002-2003 Intel Corporation + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +static DEFINE_SPINLOCK(ixp2000_slowport_lock); +static unsigned long ixp2000_slowport_irq_flags; + +/************************************************************************* + * Slowport access routines + *************************************************************************/ +void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg) +{ + spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags); + + old_cfg->CCR = *IXP2000_SLOWPORT_CCR; + old_cfg->WTC = *IXP2000_SLOWPORT_WTC2; + old_cfg->RTC = *IXP2000_SLOWPORT_RTC2; + old_cfg->PCR = *IXP2000_SLOWPORT_PCR; + old_cfg->ADC = *IXP2000_SLOWPORT_ADC; + + ixp2000_reg_write(IXP2000_SLOWPORT_CCR, new_cfg->CCR); + ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC); + ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC); + ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR); + ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC); +} + +void ixp2000_release_slowport(struct slowport_cfg *old_cfg) +{ + ixp2000_reg_write(IXP2000_SLOWPORT_CCR, old_cfg->CCR); + ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC); + ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC); + ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR); + ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC); + + spin_unlock_irqrestore(&ixp2000_slowport_lock, + ixp2000_slowport_irq_flags); +} + +/************************************************************************* + * Chip specific mappings shared by all IXP2000 systems + *************************************************************************/ +static struct map_desc ixp2000_io_desc[] __initdata = { + { + .virtual = IXP2000_CAP_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), + .length = IXP2000_CAP_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_INTCTL_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), + .length = IXP2000_INTCTL_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_PCI_CREG_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), + .length = IXP2000_PCI_CREG_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_PCI_CSR_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), + .length = IXP2000_PCI_CSR_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_MSF_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), + .length = IXP2000_MSF_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_SCRATCH_RING_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE), + .length = IXP2000_SCRATCH_RING_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_SRAM0_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE), + .length = IXP2000_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_PCI_IO_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), + .length = IXP2000_PCI_IO_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_PCI_CFG0_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), + .length = IXP2000_PCI_CFG0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = IXP2000_PCI_CFG1_VIRT_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), + .length = IXP2000_PCI_CFG1_SIZE, + .type = MT_DEVICE, + } +}; + +void __init ixp2000_map_io(void) +{ + iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); + + /* Set slowport to 8-bit mode. */ + ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1); +} + + +/************************************************************************* + * Serial port support for IXP2000 + *************************************************************************/ +static struct plat_serial8250_port ixp2000_serial_port[] = { + { + .mapbase = IXP2000_UART_PHYS_BASE, + .membase = (char *)(IXP2000_UART_VIRT_BASE + 3), + .irq = IRQ_IXP2000_UART, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 50000000, + }, + { }, +}; + +static struct resource ixp2000_uart_resource = { + .start = IXP2000_UART_PHYS_BASE, + .end = IXP2000_UART_PHYS_BASE + 0x1f, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixp2000_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = ixp2000_serial_port, + }, + .num_resources = 1, + .resource = &ixp2000_uart_resource, +}; + +void __init ixp2000_uart_init(void) +{ + platform_device_register(&ixp2000_serial_device); +} + + +/************************************************************************* + * Timer-tick functions for IXP2000 + *************************************************************************/ +static unsigned ticks_per_jiffy; +static unsigned ticks_per_usec; +static unsigned next_jiffy_time; +static volatile unsigned long *missing_jiffy_timer_csr; + +unsigned long ixp2000_gettimeoffset (void) +{ + unsigned long offset; + + offset = next_jiffy_time - *missing_jiffy_timer_csr; + + return offset / ticks_per_usec; +} + +static irqreturn_t ixp2000_timer_interrupt(int irq, void *dev_id) +{ + /* clear timer 1 */ + ixp2000_reg_wrb(IXP2000_T1_CLR, 1); + + while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr) + >= ticks_per_jiffy) { + timer_tick(); + next_jiffy_time -= ticks_per_jiffy; + } + + return IRQ_HANDLED; +} + +static struct irqaction ixp2000_timer_irq = { + .name = "IXP2000 Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = ixp2000_timer_interrupt, +}; + +void __init ixp2000_init_time(unsigned long tick_rate) +{ + ticks_per_jiffy = (tick_rate + HZ/2) / HZ; + ticks_per_usec = tick_rate / 1000000; + + /* + * We use timer 1 as our timer interrupt. + */ + ixp2000_reg_write(IXP2000_T1_CLR, 0); + ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1); + ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7)); + + /* + * We use a second timer as a monotonic counter for tracking + * missed jiffies. The IXP2000 has four timers, but if we're + * on an A-step IXP2800, timer 2 and 3 don't work, so on those + * chips we use timer 4. Timer 4 is the only timer that can + * be used for the watchdog, so we use timer 2 if we're on a + * non-buggy chip. + */ + if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) { + printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n"); + + ixp2000_reg_write(IXP2000_T4_CLR, 0); + ixp2000_reg_write(IXP2000_T4_CLD, -1); + ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7)); + missing_jiffy_timer_csr = IXP2000_T4_CSR; + } else { + ixp2000_reg_write(IXP2000_T2_CLR, 0); + ixp2000_reg_write(IXP2000_T2_CLD, -1); + ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7)); + missing_jiffy_timer_csr = IXP2000_T2_CSR; + } + next_jiffy_time = 0xffffffff; + + /* register for interrupt */ + setup_irq(IRQ_IXP2000_TIMER1, &ixp2000_timer_irq); +} + +/************************************************************************* + * GPIO helpers + *************************************************************************/ +static unsigned long GPIO_IRQ_falling_edge; +static unsigned long GPIO_IRQ_rising_edge; +static unsigned long GPIO_IRQ_level_low; +static unsigned long GPIO_IRQ_level_high; + +static void update_gpio_int_csrs(void) +{ + ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); + ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); + ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); + ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); +} + +void gpio_line_config(int line, int direction) +{ + unsigned long flags; + + local_irq_save(flags); + if (direction == GPIO_OUT) { + /* if it's an output, it ain't an interrupt anymore */ + GPIO_IRQ_falling_edge &= ~(1 << line); + GPIO_IRQ_rising_edge &= ~(1 << line); + GPIO_IRQ_level_low &= ~(1 << line); + GPIO_IRQ_level_high &= ~(1 << line); + update_gpio_int_csrs(); + + ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line); + } else if (direction == GPIO_IN) { + ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line); + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_line_config); + + +/************************************************************************* + * IRQ handling IXP2000 + *************************************************************************/ +static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + int i; + unsigned long status = *IXP2000_GPIO_INST; + + for (i = 0; i <= 7; i++) { + if (status & (1<irq - IRQ_IXP2000_GPIO0; + + /* + * First, configure this GPIO line as an input. + */ + ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line); + + /* + * Then, set the proper trigger type. + */ + if (type & IRQ_TYPE_EDGE_FALLING) + GPIO_IRQ_falling_edge |= 1 << line; + else + GPIO_IRQ_falling_edge &= ~(1 << line); + if (type & IRQ_TYPE_EDGE_RISING) + GPIO_IRQ_rising_edge |= 1 << line; + else + GPIO_IRQ_rising_edge &= ~(1 << line); + if (type & IRQ_TYPE_LEVEL_LOW) + GPIO_IRQ_level_low |= 1 << line; + else + GPIO_IRQ_level_low &= ~(1 << line); + if (type & IRQ_TYPE_LEVEL_HIGH) + GPIO_IRQ_level_high |= 1 << line; + else + GPIO_IRQ_level_high &= ~(1 << line); + update_gpio_int_csrs(); + + return 0; +} + +static void ixp2000_GPIO_irq_mask_ack(struct irq_data *d) +{ + unsigned int irq = d->irq; + + ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); + + ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); + ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); + ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); +} + +static void ixp2000_GPIO_irq_mask(struct irq_data *d) +{ + unsigned int irq = d->irq; + + ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); +} + +static void ixp2000_GPIO_irq_unmask(struct irq_data *d) +{ + unsigned int irq = d->irq; + + ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0))); +} + +static struct irq_chip ixp2000_GPIO_irq_chip = { + .irq_ack = ixp2000_GPIO_irq_mask_ack, + .irq_mask = ixp2000_GPIO_irq_mask, + .irq_unmask = ixp2000_GPIO_irq_unmask, + .irq_set_type = ixp2000_GPIO_irq_type, +}; + +static void ixp2000_pci_irq_mask(struct irq_data *d) +{ + unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE; + if (d->irq == IRQ_IXP2000_PCIA) + ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26))); + else if (d->irq == IRQ_IXP2000_PCIB) + ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27))); +} + +static void ixp2000_pci_irq_unmask(struct irq_data *d) +{ + unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE; + if (d->irq == IRQ_IXP2000_PCIA) + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26))); + else if (d->irq == IRQ_IXP2000_PCIB) + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27))); +} + +/* + * Error interrupts. These are used extensively by the microengine drivers + */ +static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + int i; + unsigned long status = *IXP2000_IRQ_ERR_STATUS; + + for(i = 31; i >= 0; i--) { + if(status & (1 << i)) { + generic_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i); + } + } +} + +static void ixp2000_err_irq_mask(struct irq_data *d) +{ + ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR, + (1 << (d->irq - IRQ_IXP2000_DRAM0_MIN_ERR))); +} + +static void ixp2000_err_irq_unmask(struct irq_data *d) +{ + ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET, + (1 << (d->irq - IRQ_IXP2000_DRAM0_MIN_ERR))); +} + +static struct irq_chip ixp2000_err_irq_chip = { + .irq_ack = ixp2000_err_irq_mask, + .irq_mask = ixp2000_err_irq_mask, + .irq_unmask = ixp2000_err_irq_unmask +}; + +static struct irq_chip ixp2000_pci_irq_chip = { + .irq_ack = ixp2000_pci_irq_mask, + .irq_mask = ixp2000_pci_irq_mask, + .irq_unmask = ixp2000_pci_irq_unmask +}; + +static void ixp2000_irq_mask(struct irq_data *d) +{ + ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << d->irq)); +} + +static void ixp2000_irq_unmask(struct irq_data *d) +{ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << d->irq)); +} + +static struct irq_chip ixp2000_irq_chip = { + .irq_ack = ixp2000_irq_mask, + .irq_mask = ixp2000_irq_mask, + .irq_unmask = ixp2000_irq_unmask +}; + +void __init ixp2000_init_irq(void) +{ + int irq; + + /* + * Mask all sources + */ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, 0xffffffff); + ixp2000_reg_write(IXP2000_FIQ_ENABLE_CLR, 0xffffffff); + + /* clear all GPIO edge/level detects */ + ixp2000_reg_write(IXP2000_GPIO_REDR, 0); + ixp2000_reg_write(IXP2000_GPIO_FEDR, 0); + ixp2000_reg_write(IXP2000_GPIO_LSHR, 0); + ixp2000_reg_write(IXP2000_GPIO_LSLR, 0); + ixp2000_reg_write(IXP2000_GPIO_INCR, -1); + + /* clear PCI interrupt sources */ + ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0); + + /* + * Certain bits in the IRQ status register of the + * IXP2000 are reserved. Instead of trying to map + * things non 1:1 from bit position to IRQ number, + * we mark the reserved IRQs as invalid. This makes + * our mask/unmask code much simpler. + */ + for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { + if ((1 << irq) & IXP2000_VALID_IRQ_MASK) { + irq_set_chip_and_handler(irq, &ixp2000_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } else set_irq_flags(irq, 0); + } + + for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) { + if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) & + IXP2000_VALID_ERR_IRQ_MASK) { + irq_set_chip_and_handler(irq, &ixp2000_err_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + else + set_irq_flags(irq, 0); + } + irq_set_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler); + + for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { + irq_set_chip_and_handler(irq, &ixp2000_GPIO_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + irq_set_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); + + /* + * Enable PCI irqs. The actual PCI[AB] decoding is done in + * entry-macro.S, so we don't need a chained handler for the + * PCI interrupt source. + */ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI)); + for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) { + irq_set_chip_and_handler(irq, &ixp2000_pci_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } +} + +void ixp2000_restart(char mode, const char *cmd) +{ + ixp2000_reg_wrb(IXP2000_RESET0, RSTALL); +} diff --git a/trunk/arch/arm/mach-ixp2000/enp2611.c b/trunk/arch/arm/mach-ixp2000/enp2611.c new file mode 100644 index 000000000000..4867f408617c --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/enp2611.c @@ -0,0 +1,265 @@ +/* + * arch/arm/mach-ixp2000/enp2611.c + * + * Radisys ENP-2611 support. + * + * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The + * original version carries the following notices: + * + * Original Author: Andrzej Mialkowski + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002-2003 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/************************************************************************* + * ENP-2611 timer tick configuration + *************************************************************************/ +static void __init enp2611_timer_init(void) +{ + ixp2000_init_time(50 * 1000 * 1000); +} + +static struct sys_timer enp2611_timer = { + .init = enp2611_timer_init, + .offset = ixp2000_gettimeoffset, +}; + + +/************************************************************************* + * ENP-2611 I/O + *************************************************************************/ +static struct map_desc enp2611_io_desc[] __initdata = { + { + .virtual = ENP2611_CALEB_VIRT_BASE, + .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE), + .length = ENP2611_CALEB_SIZE, + .type = MT_DEVICE, + }, { + .virtual = ENP2611_PM3386_0_VIRT_BASE, + .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE), + .length = ENP2611_PM3386_0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = ENP2611_PM3386_1_VIRT_BASE, + .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE), + .length = ENP2611_PM3386_1_SIZE, + .type = MT_DEVICE, + } +}; + +void __init enp2611_map_io(void) +{ + ixp2000_map_io(); + iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc)); +} + + +/************************************************************************* + * ENP-2611 PCI + *************************************************************************/ +static int enp2611_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0xe0000000; + ixp2000_pci_setup(nr, sys); + return 1; +} + +static void __init enp2611_pci_preinit(void) +{ + ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); + ixp2000_pci_preinit(); + pcibios_setup("firmware"); +} + +static inline int enp2611_pci_valid_device(struct pci_bus *bus, + unsigned int devfn) +{ + /* The 82559 ethernet controller appears at both PCI:1:0:0 and + * PCI:1:2:0, so let's pretend the second one isn't there. + */ + if (bus->number == 0x01 && devfn == 0x10) + return 0; + + return 1; +} + +static int enp2611_pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) +{ + if (enp2611_pci_valid_device(bus, devfn)) + return ixp2000_pci_read_config(bus, devfn, where, size, value); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static int enp2611_pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ + if (enp2611_pci_valid_device(bus, devfn)) + return ixp2000_pci_write_config(bus, devfn, where, size, value); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static struct pci_ops enp2611_pci_ops = { + .read = enp2611_pci_read_config, + .write = enp2611_pci_write_config +}; + +static struct pci_bus * __init enp2611_pci_scan_bus(int nr, + struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &enp2611_pci_ops, sys, + &sys->resources); +} + +static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) +{ + int irq; + + if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 0) { + /* IXP2400. */ + irq = IRQ_IXP2000_PCIA; + } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 1) { + /* 21555 non-transparent bridge. */ + irq = IRQ_IXP2000_PCIB; + } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 4) { + /* PCI2050B transparent bridge. */ + irq = -1; + } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 0) { + /* 82559 ethernet. */ + irq = IRQ_IXP2000_PCIA; + } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 1) { + /* SPI-3 option board. */ + irq = IRQ_IXP2000_PCIB; + } else { + printk(KERN_ERR "enp2611_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +struct hw_pci enp2611_pci __initdata = { + .nr_controllers = 1, + .setup = enp2611_pci_setup, + .preinit = enp2611_pci_preinit, + .scan = enp2611_pci_scan_bus, + .map_irq = enp2611_pci_map_irq, +}; + +int __init enp2611_pci_init(void) +{ + if (machine_is_enp2611()) + pci_common_init(&enp2611_pci); + + return 0; +} + +subsys_initcall(enp2611_pci_init); + + +/************************************************************************* + * ENP-2611 Machine Initialization + *************************************************************************/ +static struct flash_platform_data enp2611_flash_platform_data = { + .map_name = "cfi_probe", + .width = 1, +}; + +static struct ixp2000_flash_data enp2611_flash_data = { + .platform_data = &enp2611_flash_platform_data, + .nr_banks = 1 +}; + +static struct resource enp2611_flash_resource = { + .start = 0xc4000000, + .end = 0xc4000000 + 0x00ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device enp2611_flash = { + .name = "IXP2000-Flash", + .id = 0, + .dev = { + .platform_data = &enp2611_flash_data, + }, + .num_resources = 1, + .resource = &enp2611_flash_resource, +}; + +static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = { + .sda_pin = ENP2611_GPIO_SDA, + .scl_pin = ENP2611_GPIO_SCL, +}; + +static struct platform_device enp2611_i2c_controller = { + .name = "IXP2000-I2C", + .id = 0, + .dev = { + .platform_data = &enp2611_i2c_gpio_pins + }, + .num_resources = 0 +}; + +static struct platform_device *enp2611_devices[] __initdata = { + &enp2611_flash, + &enp2611_i2c_controller +}; + +static void __init enp2611_init_machine(void) +{ + platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices)); + ixp2000_uart_init(); +} + + +MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") + /* Maintainer: Lennert Buytenhek */ + .atag_offset = 0x100, + .map_io = enp2611_map_io, + .init_irq = ixp2000_init_irq, + .timer = &enp2611_timer, + .init_machine = enp2611_init_machine, + .restart = ixp2000_restart, +MACHINE_END + + diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/debug-macro.S b/trunk/arch/arm/mach-ixp2000/include/mach/debug-macro.S new file mode 100644 index 000000000000..bdd3ccdc2890 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/debug-macro.S @@ -0,0 +1,25 @@ +/* arch/arm/mach-ixp2000/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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. + * +*/ + + .macro addruart, rp, rv, tmp + mov \rp, #0x00030000 +#ifdef __ARMEB__ + orr \rp, \rp, #0x00000003 +#endif + orr \rv, \rp, #0xfe000000 @ virtual base + orr \rv, \rv, #0x00f00000 + orr \rp, \rp, #0xc0000000 @ Physical base + .endm + +#define UART_SHIFT 2 +#include diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/enp2611.h b/trunk/arch/arm/mach-ixp2000/include/mach/enp2611.h new file mode 100644 index 000000000000..9ce3690061d5 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/enp2611.h @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-ixp2000/include/mach/enp2611.h + * + * Register and other defines for Radisys ENP-2611 + * + * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The + * original version carries the following notices: + * + * Original Author: Naeem Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#ifndef __ENP2611_H +#define __ENP2611_H + +#define ENP2611_CALEB_PHYS_BASE 0xc5000000 +#define ENP2611_CALEB_VIRT_BASE 0xfe000000 +#define ENP2611_CALEB_SIZE 0x00100000 + +#define ENP2611_PM3386_0_PHYS_BASE 0xc6000000 +#define ENP2611_PM3386_0_VIRT_BASE 0xfe100000 +#define ENP2611_PM3386_0_SIZE 0x00100000 + +#define ENP2611_PM3386_1_PHYS_BASE 0xc6400000 +#define ENP2611_PM3386_1_VIRT_BASE 0xfe200000 +#define ENP2611_PM3386_1_SIZE 0x00100000 + +#define ENP2611_GPIO_SCL 7 +#define ENP2611_GPIO_SDA 6 + +#define IRQ_ENP2611_THERMAL IRQ_IXP2000_GPIO4 +#define IRQ_ENP2611_OPTION_BOARD IRQ_IXP2000_GPIO3 +#define IRQ_ENP2611_CALEB IRQ_IXP2000_GPIO2 +#define IRQ_ENP2611_PM3386_1 IRQ_IXP2000_GPIO1 +#define IRQ_ENP2611_PM3386_0 IRQ_IXP2000_GPIO0 + + +#endif diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/entry-macro.S b/trunk/arch/arm/mach-ixp2000/include/mach/entry-macro.S new file mode 100644 index 000000000000..c4444dff9202 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/entry-macro.S @@ -0,0 +1,54 @@ +/* + * arch/arm/mach-ixp2000/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for IXP2000-based platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + mov \irqnr, #0x0 @clear out irqnr as default + mov \base, #0xfe000000 + orr \base, \base, #0x00e00000 + orr \base, \base, #0x08 + ldr \irqstat, [\base] @ get interrupts + + cmp \irqstat, #0 + beq 1001f + + clz \irqnr, \irqstat + mov \base, #31 + subs \irqnr, \base, \irqnr + + /* + * We handle PCIA and PCIB here so we don't have an + * extra layer of code just to check these two bits. + */ + cmp \irqnr, #IRQ_IXP2000_PCI + bne 1001f + + mov \base, #0xfe000000 + orr \base, \base, #0x00c00000 + orr \base, \base, #0x00000100 + orr \base, \base, #0x00000058 + ldr \irqstat, [\base] + + mov \tmp, #(1<<26) + tst \irqstat, \tmp + movne \irqnr, #IRQ_IXP2000_PCIA + bne 1001f + + mov \tmp, #(1<<27) + tst \irqstat, \tmp + movne \irqnr, #IRQ_IXP2000_PCIB + +1001: + .endm + diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/gpio-ixp2000.h b/trunk/arch/arm/mach-ixp2000/include/mach/gpio-ixp2000.h new file mode 100644 index 000000000000..af836c76c3f1 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/gpio-ixp2000.h @@ -0,0 +1,48 @@ +/* + * arch/arm/mach-ixp2000/include/mach/gpio.h + * + * Copyright (C) 2002 Intel Corporation. + * + * 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. + */ + +/* + * IXP2000 GPIO in/out, edge/level detection for IRQs: + * IRQs are generated on Falling-edge, Rising-Edge, Level-low, Level-High + * or both Falling-edge and Rising-edge. + * This must be called *before* the corresponding IRQ is registerd. + * Use this instead of directly setting the GPIO registers. + * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb) + */ +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +#ifndef __ASSEMBLY__ + +#define GPIO_IN 0 +#define GPIO_OUT 1 + +#define IXP2000_GPIO_LOW 0 +#define IXP2000_GPIO_HIGH 1 + +extern void gpio_line_config(int line, int direction); + +static inline int gpio_line_get(int line) +{ + return (((*IXP2000_GPIO_PLR) >> line) & 1); +} + +static inline void gpio_line_set(int line, int value) +{ + if (value == IXP2000_GPIO_HIGH) { + ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line); + } else if (value == IXP2000_GPIO_LOW) { + ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line); + } +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* ASM_ARCH_IXP2000_GPIO_H_ */ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/hardware.h b/trunk/arch/arm/mach-ixp2000/include/mach/hardware.h new file mode 100644 index 000000000000..cdaf1db84003 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/hardware.h @@ -0,0 +1,36 @@ +/* + * arch/arm/mach-ixp2000/include/mach/hardware.h + * + * Hardware definitions for IXP2400/2800 based systems + * + * Original Author: Naeem M Afzal + * + * Maintainer: Deepak Saxena + * + * Copyright (C) 2001-2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#ifndef __ASM_ARCH_HARDWARE_H__ +#define __ASM_ARCH_HARDWARE_H__ + +#include "ixp2000-regs.h" /* Chipset Registers */ + +/* + * Platform helper functions + */ +#include "platform.h" + +/* + * Platform-specific bits + */ +#include "enp2611.h" /* ENP-2611 */ +#include "ixdp2x00.h" /* IXDP2400/2800 */ +#include "ixdp2x01.h" /* IXDP2401/2801 */ + +#endif /* _ASM_ARCH_HARDWARE_H__ */ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/io.h b/trunk/arch/arm/mach-ixp2000/include/mach/io.h new file mode 100644 index 000000000000..f6552d6f35ab --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/io.h @@ -0,0 +1,133 @@ +/* + * arch/arm/mach-ixp2000/include/mach/io.h + * + * Original Author: Naeem M Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyrgiht (C) 2003-2004 MontaVista Software, Inc. + * + * 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_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#include + +#define IO_SPACE_LIMIT 0xffffffff + +/* + * The A? revisions of the IXP2000s assert byte lanes for PCI I/O + * transactions the other way round (MEM transactions don't have this + * issue), so if we want to support those models, we need to override + * the standard I/O functions. + * + * B0 and later have a bit that can be set to 1 to get the proper + * behavior for I/O transactions, which then allows us to use the + * standard I/O functions. This is what we do if the user does not + * explicitly ask for support for pre-B0. + */ +#ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO +#define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) + +#define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3) +#define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2) + +#define outb(v,p) __raw_writeb((v),alignb(___io(p))) +#define outw(v,p) __raw_writew((v),alignw(___io(p))) +#define outl(v,p) __raw_writel((v),___io(p)) + +#define inb(p) ({ unsigned int __v = __raw_readb(alignb(___io(p))); __v; }) +#define inw(p) \ + ({ unsigned int __v = (__raw_readw(alignw(___io(p)))); __v; }) +#define inl(p) \ + ({ unsigned int __v = (__raw_readl(___io(p))); __v; }) + +#define outsb(p,d,l) __raw_writesb(alignb(___io(p)),d,l) +#define outsw(p,d,l) __raw_writesw(alignw(___io(p)),d,l) +#define outsl(p,d,l) __raw_writesl(___io(p),d,l) + +#define insb(p,d,l) __raw_readsb(alignb(___io(p)),d,l) +#define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l) +#define insl(p,d,l) __raw_readsl(___io(p),d,l) + +#define __is_io_address(p) ((((unsigned long)(p)) & ~(IXP2000_PCI_IO_SIZE - 1)) == IXP2000_PCI_IO_VIRT_BASE) + +#define ioread8(p) \ + ({ \ + unsigned int __v; \ + \ + if (__is_io_address(p)) { \ + __v = __raw_readb(alignb(p)); \ + } else { \ + __v = __raw_readb(p); \ + } \ + \ + __v; \ + }) \ + +#define ioread16(p) \ + ({ \ + unsigned int __v; \ + \ + if (__is_io_address(p)) { \ + __v = __raw_readw(alignw(p)); \ + } else { \ + __v = le16_to_cpu(__raw_readw(p)); \ + } \ + \ + __v; \ + }) + +#define ioread32(p) \ + ({ \ + unsigned int __v; \ + \ + if (__is_io_address(p)) { \ + __v = __raw_readl(p); \ + } else { \ + __v = le32_to_cpu(__raw_readl(p)); \ + } \ + \ + __v; \ + }) + +#define iowrite8(v,p) \ + ({ \ + if (__is_io_address(p)) { \ + __raw_writeb((v), alignb(p)); \ + } else { \ + __raw_writeb((v), p); \ + } \ + }) + +#define iowrite16(v,p) \ + ({ \ + if (__is_io_address(p)) { \ + __raw_writew((v), alignw(p)); \ + } else { \ + __raw_writew(cpu_to_le16(v), p); \ + } \ + }) + +#define iowrite32(v,p) \ + ({ \ + if (__is_io_address(p)) { \ + __raw_writel((v), p); \ + } else { \ + __raw_writel(cpu_to_le32(v), p); \ + } \ + }) + +#define ioport_map(port, nr) ___io(port) + +#define ioport_unmap(addr) +#else +#define __io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) +#endif + + +#endif diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/irqs.h b/trunk/arch/arm/mach-ixp2000/include/mach/irqs.h new file mode 100644 index 000000000000..bee96bcafdca --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/irqs.h @@ -0,0 +1,207 @@ +/* + * arch/arm/mach-ixp2000/include/mach/irqs.h + * + * Original Author: Naeem Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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 _IRQS_H +#define _IRQS_H + +/* + * Do NOT add #ifdef MACHINE_FOO in here. + * Simpy add your machine IRQs here and increase NR_IRQS if needed to + * hold your machine's IRQ table. + */ + +/* + * Some interrupt numbers go unused b/c the IRQ mask/ummask/status + * register has those bit reserved. We just mark those interrupts + * as invalid and this allows us to do mask/unmask with a single + * shift operation instead of having to map the IRQ number to + * a HW IRQ number. + */ +#define IRQ_IXP2000_SOFT_INT 0 /* soft interrupt */ +#define IRQ_IXP2000_ERRSUM 1 /* OR of all bits in ErrorStatus reg*/ +#define IRQ_IXP2000_UART 2 +#define IRQ_IXP2000_GPIO 3 +#define IRQ_IXP2000_TIMER1 4 +#define IRQ_IXP2000_TIMER2 5 +#define IRQ_IXP2000_TIMER3 6 +#define IRQ_IXP2000_TIMER4 7 +#define IRQ_IXP2000_PMU 8 +#define IRQ_IXP2000_SPF 9 /* Slow port framer IRQ */ +#define IRQ_IXP2000_DMA1 10 +#define IRQ_IXP2000_DMA2 11 +#define IRQ_IXP2000_DMA3 12 +#define IRQ_IXP2000_PCI_DOORBELL 13 +#define IRQ_IXP2000_ME_ATTN 14 +#define IRQ_IXP2000_PCI 15 /* PCI INTA or INTB */ +#define IRQ_IXP2000_THDA0 16 /* thread 0-31A */ +#define IRQ_IXP2000_THDA1 17 /* thread 32-63A, IXP2800 only */ +#define IRQ_IXP2000_THDA2 18 /* thread 64-95A */ +#define IRQ_IXP2000_THDA3 19 /* thread 96-127A, IXP2800 only */ +#define IRQ_IXP2000_THDB0 24 /* thread 0-31B */ +#define IRQ_IXP2000_THDB1 25 /* thread 32-63B, IXP2800 only */ +#define IRQ_IXP2000_THDB2 26 /* thread 64-95B */ +#define IRQ_IXP2000_THDB3 27 /* thread 96-127B, IXP2800 only */ + +/* define generic GPIOs */ +#define IRQ_IXP2000_GPIO0 32 +#define IRQ_IXP2000_GPIO1 33 +#define IRQ_IXP2000_GPIO2 34 +#define IRQ_IXP2000_GPIO3 35 +#define IRQ_IXP2000_GPIO4 36 +#define IRQ_IXP2000_GPIO5 37 +#define IRQ_IXP2000_GPIO6 38 +#define IRQ_IXP2000_GPIO7 39 + +/* split off the 2 PCI sources */ +#define IRQ_IXP2000_PCIA 40 +#define IRQ_IXP2000_PCIB 41 + +/* Int sources from IRQ_ERROR_STATUS */ +#define IRQ_IXP2000_DRAM0_MIN_ERR 42 +#define IRQ_IXP2000_DRAM0_MAJ_ERR 43 +#define IRQ_IXP2000_DRAM1_MIN_ERR 44 +#define IRQ_IXP2000_DRAM1_MAJ_ERR 45 +#define IRQ_IXP2000_DRAM2_MIN_ERR 46 +#define IRQ_IXP2000_DRAM2_MAJ_ERR 47 +/* 48-57 reserved */ +#define IRQ_IXP2000_SRAM0_ERR 58 +#define IRQ_IXP2000_SRAM1_ERR 59 +#define IRQ_IXP2000_SRAM2_ERR 60 +#define IRQ_IXP2000_SRAM3_ERR 61 +/* 62-65 reserved */ +#define IRQ_IXP2000_MEDIA_ERR 66 +#define IRQ_IXP2000_PCI_ERR 67 +#define IRQ_IXP2000_SP_INT 68 + +#define NR_IXP2000_IRQS 69 + +#define IXP2000_BOARD_IRQ(x) (NR_IXP2000_IRQS + (x)) + +#define IXP2000_BOARD_IRQ_MASK(irq) (1 << (irq - NR_IXP2000_IRQS)) + +#define IXP2000_ERR_IRQ_MASK(irq) ( 1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) +#define IXP2000_VALID_ERR_IRQ_MASK (\ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MIN_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MAJ_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MIN_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MAJ_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MIN_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MAJ_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM0_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM1_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM2_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM3_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_MEDIA_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_PCI_ERR) | \ + IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SP_INT) ) + +/* + * This allows for all the on-chip sources plus up to 32 CPLD based + * IRQs. Should be more than enough. + */ +#define IXP2000_BOARD_IRQS 32 +#define NR_IRQS (NR_IXP2000_IRQS + IXP2000_BOARD_IRQS) + + +/* + * IXDP2400 specific IRQs + */ +#define IRQ_IXDP2400_INGRESS_NPU IXP2000_BOARD_IRQ(0) +#define IRQ_IXDP2400_ENET IXP2000_BOARD_IRQ(1) +#define IRQ_IXDP2400_MEDIA_PCI IXP2000_BOARD_IRQ(2) +#define IRQ_IXDP2400_MEDIA_SP IXP2000_BOARD_IRQ(3) +#define IRQ_IXDP2400_SF_PCI IXP2000_BOARD_IRQ(4) +#define IRQ_IXDP2400_SF_SP IXP2000_BOARD_IRQ(5) +#define IRQ_IXDP2400_PMC IXP2000_BOARD_IRQ(6) +#define IRQ_IXDP2400_TVM IXP2000_BOARD_IRQ(7) + +#define NR_IXDP2400_IRQS ((IRQ_IXDP2400_TVM)+1) +#define IXDP2400_NR_IRQS NR_IXDP2400_IRQS - NR_IXP2000_IRQS + +/* IXDP2800 specific IRQs */ +#define IRQ_IXDP2800_EGRESS_ENET IXP2000_BOARD_IRQ(0) +#define IRQ_IXDP2800_INGRESS_NPU IXP2000_BOARD_IRQ(1) +#define IRQ_IXDP2800_PMC IXP2000_BOARD_IRQ(2) +#define IRQ_IXDP2800_FABRIC_PCI IXP2000_BOARD_IRQ(3) +#define IRQ_IXDP2800_FABRIC IXP2000_BOARD_IRQ(4) +#define IRQ_IXDP2800_MEDIA IXP2000_BOARD_IRQ(5) + +#define NR_IXDP2800_IRQS ((IRQ_IXDP2800_MEDIA)+1) +#define IXDP2800_NR_IRQS NR_IXDP2800_IRQS - NR_IXP2000_IRQS + +/* + * IRQs on both IXDP2x01 boards + */ +#define IRQ_IXDP2X01_SPCI_DB_0 IXP2000_BOARD_IRQ(2) +#define IRQ_IXDP2X01_SPCI_DB_1 IXP2000_BOARD_IRQ(3) +#define IRQ_IXDP2X01_SPCI_PMC_INTA IXP2000_BOARD_IRQ(4) +#define IRQ_IXDP2X01_SPCI_PMC_INTB IXP2000_BOARD_IRQ(5) +#define IRQ_IXDP2X01_SPCI_PMC_INTC IXP2000_BOARD_IRQ(6) +#define IRQ_IXDP2X01_SPCI_PMC_INTD IXP2000_BOARD_IRQ(7) +#define IRQ_IXDP2X01_SPCI_FIC_INT IXP2000_BOARD_IRQ(8) +#define IRQ_IXDP2X01_IPMI_FROM IXP2000_BOARD_IRQ(16) +#define IRQ_IXDP2X01_125US IXP2000_BOARD_IRQ(17) +#define IRQ_IXDP2X01_DB_0_ADD IXP2000_BOARD_IRQ(18) +#define IRQ_IXDP2X01_DB_1_ADD IXP2000_BOARD_IRQ(19) +#define IRQ_IXDP2X01_UART1 IXP2000_BOARD_IRQ(21) +#define IRQ_IXDP2X01_UART2 IXP2000_BOARD_IRQ(22) +#define IRQ_IXDP2X01_FIC_ADD_INT IXP2000_BOARD_IRQ(24) +#define IRQ_IXDP2X01_CS8900 IXP2000_BOARD_IRQ(25) +#define IRQ_IXDP2X01_BBSRAM IXP2000_BOARD_IRQ(26) + +#define IXDP2X01_VALID_IRQ_MASK ( \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_DB_0) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_DB_1) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTA) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTB) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTC) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTD) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_FIC_INT) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_IPMI_FROM) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_125US) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_DB_0_ADD) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_DB_1_ADD) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_UART1) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_UART2) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_FIC_ADD_INT) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_CS8900) | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_BBSRAM) ) + +/* + * IXDP2401 specific IRQs + */ +#define IRQ_IXDP2401_INTA_82546 IXP2000_BOARD_IRQ(0) +#define IRQ_IXDP2401_INTB_82546 IXP2000_BOARD_IRQ(1) + +#define IXDP2401_VALID_IRQ_MASK ( \ + IXDP2X01_VALID_IRQ_MASK | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2401_INTA_82546) |\ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2401_INTB_82546)) + +/* + * IXDP2801-specific IRQs + */ +#define IRQ_IXDP2801_RIV IXP2000_BOARD_IRQ(0) +#define IRQ_IXDP2801_CNFG_MEDIA IXP2000_BOARD_IRQ(27) +#define IRQ_IXDP2801_CLOCK_REF IXP2000_BOARD_IRQ(28) + +#define IXDP2801_VALID_IRQ_MASK ( \ + IXDP2X01_VALID_IRQ_MASK | \ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_RIV) |\ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_CNFG_MEDIA) |\ + IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_CLOCK_REF)) + +#define NR_IXDP2X01_IRQS ((IRQ_IXDP2801_CLOCK_REF) + 1) + +#endif /*_IRQS_H*/ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/ixdp2x00.h b/trunk/arch/arm/mach-ixp2000/include/mach/ixdp2x00.h new file mode 100644 index 000000000000..5df8479d9481 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/ixdp2x00.h @@ -0,0 +1,92 @@ +/* + * arch/arm/mach-ixp2000/include/mach/ixdp2x00.h + * + * Register and other defines for IXDP2[48]00 platforms + * + * Original Author: Naeem Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#ifndef _IXDP2X00_H_ +#define _IXDP2X00_H_ + +/* + * On board CPLD memory map + */ +#define IXDP2X00_PHYS_CPLD_BASE 0xc7000000 +#define IXDP2X00_VIRT_CPLD_BASE 0xfe000000 +#define IXDP2X00_CPLD_SIZE 0x00100000 + + +#define IXDP2X00_CPLD_REG(x) \ + (volatile unsigned long *)(IXDP2X00_VIRT_CPLD_BASE | x) + +/* + * IXDP2400 CPLD registers + */ +#define IXDP2400_CPLD_SYSLED IXDP2X00_CPLD_REG(0x0) +#define IXDP2400_CPLD_DISP_DATA IXDP2X00_CPLD_REG(0x4) +#define IXDP2400_CPLD_CLOCK_SPEED IXDP2X00_CPLD_REG(0x8) +#define IXDP2400_CPLD_INT_STAT IXDP2X00_CPLD_REG(0xc) +#define IXDP2400_CPLD_REV IXDP2X00_CPLD_REG(0x10) +#define IXDP2400_CPLD_SYS_CLK_M IXDP2X00_CPLD_REG(0x14) +#define IXDP2400_CPLD_SYS_CLK_N IXDP2X00_CPLD_REG(0x18) +#define IXDP2400_CPLD_INT_MASK IXDP2X00_CPLD_REG(0x48) + +/* + * IXDP2800 CPLD registers + */ +#define IXDP2800_CPLD_INT_STAT IXDP2X00_CPLD_REG(0x0) +#define IXDP2800_CPLD_INT_MASK IXDP2X00_CPLD_REG(0x140) + + +#define IXDP2X00_GPIO_I2C_ENABLE 0x02 +#define IXDP2X00_GPIO_SCL 0x07 +#define IXDP2X00_GPIO_SDA 0x06 + +/* + * PCI devfns for on-board devices. We need these to be able to + * properly translate IRQs and for device removal. + */ +#define IXDP2400_SLAVE_ENET_DEVFN 0x18 /* Bus 1 */ +#define IXDP2400_MASTER_ENET_DEVFN 0x20 /* Bus 1 */ +#define IXDP2400_MEDIA_DEVFN 0x28 /* Bus 1 */ +#define IXDP2400_SWITCH_FABRIC_DEVFN 0x30 /* Bus 1 */ + +#define IXDP2800_SLAVE_ENET_DEVFN 0x20 /* Bus 1 */ +#define IXDP2800_MASTER_ENET_DEVFN 0x18 /* Bus 1 */ +#define IXDP2800_SWITCH_FABRIC_DEVFN 0x30 /* Bus 1 */ + +#define IXDP2X00_P2P_DEVFN 0x20 /* Bus 0 */ +#define IXDP2X00_21555_DEVFN 0x30 /* Bus 0 */ +#define IXDP2X00_SLAVE_NPU_DEVFN 0x28 /* Bus 1 */ +#define IXDP2X00_PMC_DEVFN 0x38 /* Bus 1 */ +#define IXDP2X00_MASTER_NPU_DEVFN 0x38 /* Bus 1 */ + +#ifndef __ASSEMBLY__ +/* + * The master NPU is always PCI master. + */ +static inline unsigned int ixdp2x00_master_npu(void) +{ + return !!ixp2000_is_pcimaster(); +} + +/* + * Helper functions used by ixdp2400 and ixdp2800 specific code + */ +void ixdp2x00_init_irq(volatile unsigned long*, volatile unsigned long *, unsigned long); +void ixdp2x00_slave_pci_postinit(void); +void ixdp2x00_init_machine(void); +void ixdp2x00_map_io(void); + +#endif + +#endif /*_IXDP2X00_H_ */ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/ixdp2x01.h b/trunk/arch/arm/mach-ixp2000/include/mach/ixdp2x01.h new file mode 100644 index 000000000000..4c1f04083e54 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/ixdp2x01.h @@ -0,0 +1,57 @@ +/* + * arch/arm/mach-ixp2000/include/mach/ixdp2x01.h + * + * Platform definitions for IXDP2X01 && IXDP2801 systems + * + * Author: Deepak Saxena + * + * Copyright 2004 (c) MontaVista Software, Inc. + * + * Based on original code Copyright (c) 2002-2003 Intel Corporation + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __IXDP2X01_H__ +#define __IXDP2X01_H__ + +#define IXDP2X01_PHYS_CPLD_BASE 0xc6024000 +#define IXDP2X01_VIRT_CPLD_BASE 0xfe000000 +#define IXDP2X01_CPLD_REGION_SIZE 0x00100000 + +#define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg) +#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg) + +#define IXDP2X01_UART1_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x40) +#define IXDP2X01_UART1_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x40) + +#define IXDP2X01_UART2_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x60) +#define IXDP2X01_UART2_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x60) + +#define IXDP2X01_CS8900_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x80) +#define IXDP2X01_CS8900_VIRT_END (IXDP2X01_CS8900_VIRT_BASE + 16) + +#define IXDP2X01_CPLD_RESET_REG IXDP2X01_CPLD_VIRT_REG(0x00) +#define IXDP2X01_INT_MASK_SET_REG IXDP2X01_CPLD_VIRT_REG(0x08) +#define IXDP2X01_INT_STAT_REG IXDP2X01_CPLD_VIRT_REG(0x0C) +#define IXDP2X01_INT_RAW_REG IXDP2X01_CPLD_VIRT_REG(0x10) +#define IXDP2X01_INT_MASK_CLR_REG IXDP2X01_INT_RAW_REG +#define IXDP2X01_INT_SIM_REG IXDP2X01_CPLD_VIRT_REG(0x14) + +#define IXDP2X01_CPLD_FLASH_REG IXDP2X01_CPLD_VIRT_REG(0x20) + +#define IXDP2X01_CPLD_FLASH_INTERN 0x8000 +#define IXDP2X01_CPLD_FLASH_BANK_MASK 0xF +#define IXDP2X01_FLASH_WINDOW_BITS 25 +#define IXDP2X01_FLASH_WINDOW_SIZE (1 << IXDP2X01_FLASH_WINDOW_BITS) +#define IXDP2X01_FLASH_WINDOW_MASK (IXDP2X01_FLASH_WINDOW_SIZE - 1) + +#define IXDP2X01_UART_CLK 1843200 + +#define IXDP2X01_GPIO_I2C_ENABLE 0x02 +#define IXDP2X01_GPIO_SCL 0x07 +#define IXDP2X01_GPIO_SDA 0x06 + +#endif /* __IXDP2x01_H__ */ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h b/trunk/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h new file mode 100644 index 000000000000..822f63f2f4a2 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h @@ -0,0 +1,451 @@ +/* + * arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h + * + * Chipset register definitions for IXP2400/2800 based systems. + * + * Original Author: Naeem Afzal + * + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#ifndef _IXP2000_REGS_H_ +#define _IXP2000_REGS_H_ + +/* + * IXP2000 linux memory map: + * + * virt phys size + * fb000000 db000000 16M PCI CFG1 + * fc000000 da000000 16M PCI CFG0 + * fd000000 d8000000 16M PCI I/O + * fe[0-7]00000 8M per-platform mappings + * fe900000 80000000 1M SRAM #0 (first MB) + * fea00000 cb400000 1M SCRATCH ring get/put + * feb00000 c8000000 1M MSF + * fec00000 df000000 1M PCI CSRs + * fed00000 de000000 1M PCI CREG + * fee00000 d6000000 1M INTCTL + * fef00000 c0000000 1M CAP + */ + +/* + * Static I/O regions. + * + * Most of the registers are clumped in 4K regions spread throughout + * the 0xc0000000 -> 0xc0100000 address range, but we just map in + * the whole range using a single 1 MB section instead of small + * 4K pages. + * + * CAP stands for CSR Access Proxy. + * + * If you change the virtual address of this mapping, please propagate + * the change to arch/arm/kernel/debug.S, which hardcodes the virtual + * address of the UART located in this region. + */ + +#define IXP2000_CAP_PHYS_BASE 0xc0000000 +#define IXP2000_CAP_VIRT_BASE 0xfef00000 +#define IXP2000_CAP_SIZE 0x00100000 + +/* + * Addresses for specific on-chip peripherals. + */ +#define IXP2000_SLOWPORT_CSR_VIRT_BASE 0xfef80000 +#define IXP2000_GLOBAL_REG_VIRT_BASE 0xfef04000 +#define IXP2000_UART_PHYS_BASE 0xc0030000 +#define IXP2000_UART_VIRT_BASE 0xfef30000 +#define IXP2000_TIMER_VIRT_BASE 0xfef20000 +#define IXP2000_UENGINE_CSR_VIRT_BASE 0xfef18000 +#define IXP2000_GPIO_VIRT_BASE 0xfef10000 + +/* + * Devices outside of the 0xc0000000 -> 0xc0100000 range. The virtual + * addresses of the INTCTL and PCI_CSR mappings are hardcoded in + * entry-macro.S, so if you ever change these please propagate + * the change. + */ +#define IXP2000_INTCTL_PHYS_BASE 0xd6000000 +#define IXP2000_INTCTL_VIRT_BASE 0xfee00000 +#define IXP2000_INTCTL_SIZE 0x00100000 + +#define IXP2000_PCI_CREG_PHYS_BASE 0xde000000 +#define IXP2000_PCI_CREG_VIRT_BASE 0xfed00000 +#define IXP2000_PCI_CREG_SIZE 0x00100000 + +#define IXP2000_PCI_CSR_PHYS_BASE 0xdf000000 +#define IXP2000_PCI_CSR_VIRT_BASE 0xfec00000 +#define IXP2000_PCI_CSR_SIZE 0x00100000 + +#define IXP2000_MSF_PHYS_BASE 0xc8000000 +#define IXP2000_MSF_VIRT_BASE 0xfeb00000 +#define IXP2000_MSF_SIZE 0x00100000 + +#define IXP2000_SCRATCH_RING_PHYS_BASE 0xcb400000 +#define IXP2000_SCRATCH_RING_VIRT_BASE 0xfea00000 +#define IXP2000_SCRATCH_RING_SIZE 0x00100000 + +#define IXP2000_SRAM0_PHYS_BASE 0x80000000 +#define IXP2000_SRAM0_VIRT_BASE 0xfe900000 +#define IXP2000_SRAM0_SIZE 0x00100000 + +#define IXP2000_PCI_IO_PHYS_BASE 0xd8000000 +#define IXP2000_PCI_IO_VIRT_BASE 0xfd000000 +#define IXP2000_PCI_IO_SIZE 0x01000000 + +#define IXP2000_PCI_CFG0_PHYS_BASE 0xda000000 +#define IXP2000_PCI_CFG0_VIRT_BASE 0xfc000000 +#define IXP2000_PCI_CFG0_SIZE 0x01000000 + +#define IXP2000_PCI_CFG1_PHYS_BASE 0xdb000000 +#define IXP2000_PCI_CFG1_VIRT_BASE 0xfb000000 +#define IXP2000_PCI_CFG1_SIZE 0x01000000 + +/* + * Timers + */ +#define IXP2000_TIMER_REG(x) ((volatile unsigned long*)(IXP2000_TIMER_VIRT_BASE | (x))) +/* Timer control */ +#define IXP2000_T1_CTL IXP2000_TIMER_REG(0x00) +#define IXP2000_T2_CTL IXP2000_TIMER_REG(0x04) +#define IXP2000_T3_CTL IXP2000_TIMER_REG(0x08) +#define IXP2000_T4_CTL IXP2000_TIMER_REG(0x0c) +/* Store initial value */ +#define IXP2000_T1_CLD IXP2000_TIMER_REG(0x10) +#define IXP2000_T2_CLD IXP2000_TIMER_REG(0x14) +#define IXP2000_T3_CLD IXP2000_TIMER_REG(0x18) +#define IXP2000_T4_CLD IXP2000_TIMER_REG(0x1c) +/* Read current value */ +#define IXP2000_T1_CSR IXP2000_TIMER_REG(0x20) +#define IXP2000_T2_CSR IXP2000_TIMER_REG(0x24) +#define IXP2000_T3_CSR IXP2000_TIMER_REG(0x28) +#define IXP2000_T4_CSR IXP2000_TIMER_REG(0x2c) +/* Clear associated timer interrupt */ +#define IXP2000_T1_CLR IXP2000_TIMER_REG(0x30) +#define IXP2000_T2_CLR IXP2000_TIMER_REG(0x34) +#define IXP2000_T3_CLR IXP2000_TIMER_REG(0x38) +#define IXP2000_T4_CLR IXP2000_TIMER_REG(0x3c) +/* Timer watchdog enable for T4 */ +#define IXP2000_TWDE IXP2000_TIMER_REG(0x40) + +#define WDT_ENABLE 0x00000001 +#define TIMER_DIVIDER_256 0x00000008 +#define TIMER_ENABLE 0x00000080 +#define IRQ_MASK_TIMER1 (1 << 4) + +/* + * Interrupt controller registers + */ +#define IXP2000_INTCTL_REG(x) (volatile unsigned long*)(IXP2000_INTCTL_VIRT_BASE | (x)) +#define IXP2000_IRQ_STATUS IXP2000_INTCTL_REG(0x08) +#define IXP2000_IRQ_ENABLE IXP2000_INTCTL_REG(0x10) +#define IXP2000_IRQ_ENABLE_SET IXP2000_INTCTL_REG(0x10) +#define IXP2000_IRQ_ENABLE_CLR IXP2000_INTCTL_REG(0x18) +#define IXP2000_FIQ_ENABLE_CLR IXP2000_INTCTL_REG(0x14) +#define IXP2000_IRQ_ERR_STATUS IXP2000_INTCTL_REG(0x24) +#define IXP2000_IRQ_ERR_ENABLE_SET IXP2000_INTCTL_REG(0x2c) +#define IXP2000_FIQ_ERR_ENABLE_CLR IXP2000_INTCTL_REG(0x30) +#define IXP2000_IRQ_ERR_ENABLE_CLR IXP2000_INTCTL_REG(0x34) +#define IXP2000_IRQ_THD_RAW_STATUS_A_0 IXP2000_INTCTL_REG(0x60) +#define IXP2000_IRQ_THD_RAW_STATUS_A_1 IXP2000_INTCTL_REG(0x64) +#define IXP2000_IRQ_THD_RAW_STATUS_A_2 IXP2000_INTCTL_REG(0x68) +#define IXP2000_IRQ_THD_RAW_STATUS_A_3 IXP2000_INTCTL_REG(0x6c) +#define IXP2000_IRQ_THD_RAW_STATUS_B_0 IXP2000_INTCTL_REG(0x80) +#define IXP2000_IRQ_THD_RAW_STATUS_B_1 IXP2000_INTCTL_REG(0x84) +#define IXP2000_IRQ_THD_RAW_STATUS_B_2 IXP2000_INTCTL_REG(0x88) +#define IXP2000_IRQ_THD_RAW_STATUS_B_3 IXP2000_INTCTL_REG(0x8c) +#define IXP2000_IRQ_THD_STATUS_A_0 IXP2000_INTCTL_REG(0xe0) +#define IXP2000_IRQ_THD_STATUS_A_1 IXP2000_INTCTL_REG(0xe4) +#define IXP2000_IRQ_THD_STATUS_A_2 IXP2000_INTCTL_REG(0xe8) +#define IXP2000_IRQ_THD_STATUS_A_3 IXP2000_INTCTL_REG(0xec) +#define IXP2000_IRQ_THD_STATUS_B_0 IXP2000_INTCTL_REG(0x100) +#define IXP2000_IRQ_THD_STATUS_B_1 IXP2000_INTCTL_REG(0x104) +#define IXP2000_IRQ_THD_STATUS_B_2 IXP2000_INTCTL_REG(0x108) +#define IXP2000_IRQ_THD_STATUS_B_3 IXP2000_INTCTL_REG(0x10c) +#define IXP2000_IRQ_THD_ENABLE_SET_A_0 IXP2000_INTCTL_REG(0x160) +#define IXP2000_IRQ_THD_ENABLE_SET_A_1 IXP2000_INTCTL_REG(0x164) +#define IXP2000_IRQ_THD_ENABLE_SET_A_2 IXP2000_INTCTL_REG(0x168) +#define IXP2000_IRQ_THD_ENABLE_SET_A_3 IXP2000_INTCTL_REG(0x16c) +#define IXP2000_IRQ_THD_ENABLE_SET_B_0 IXP2000_INTCTL_REG(0x180) +#define IXP2000_IRQ_THD_ENABLE_SET_B_1 IXP2000_INTCTL_REG(0x184) +#define IXP2000_IRQ_THD_ENABLE_SET_B_2 IXP2000_INTCTL_REG(0x188) +#define IXP2000_IRQ_THD_ENABLE_SET_B_3 IXP2000_INTCTL_REG(0x18c) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_0 IXP2000_INTCTL_REG(0x1e0) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_1 IXP2000_INTCTL_REG(0x1e4) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_2 IXP2000_INTCTL_REG(0x1e8) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_3 IXP2000_INTCTL_REG(0x1ec) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_0 IXP2000_INTCTL_REG(0x200) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_1 IXP2000_INTCTL_REG(0x204) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_2 IXP2000_INTCTL_REG(0x208) +#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_3 IXP2000_INTCTL_REG(0x20c) + +/* + * Mask of valid IRQs in the 32-bit IRQ register. We use + * this to mark certain IRQs as being invalid. + */ +#define IXP2000_VALID_IRQ_MASK 0x0f0fffff + +/* + * PCI config register access from core + */ +#define IXP2000_PCI_CREG(x) (volatile unsigned long*)(IXP2000_PCI_CREG_VIRT_BASE | (x)) +#define IXP2000_PCI_CMDSTAT IXP2000_PCI_CREG(0x04) +#define IXP2000_PCI_CSR_BAR IXP2000_PCI_CREG(0x10) +#define IXP2000_PCI_SRAM_BAR IXP2000_PCI_CREG(0x14) +#define IXP2000_PCI_SDRAM_BAR IXP2000_PCI_CREG(0x18) + +/* + * PCI CSRs + */ +#define IXP2000_PCI_CSR(x) (volatile unsigned long*)(IXP2000_PCI_CSR_VIRT_BASE | (x)) + +/* + * PCI outbound interrupts + */ +#define IXP2000_PCI_OUT_INT_STATUS IXP2000_PCI_CSR(0x30) +#define IXP2000_PCI_OUT_INT_MASK IXP2000_PCI_CSR(0x34) +/* + * PCI communications + */ +#define IXP2000_PCI_MAILBOX0 IXP2000_PCI_CSR(0x50) +#define IXP2000_PCI_MAILBOX1 IXP2000_PCI_CSR(0x54) +#define IXP2000_PCI_MAILBOX2 IXP2000_PCI_CSR(0x58) +#define IXP2000_PCI_MAILBOX3 IXP2000_PCI_CSR(0x5C) +#define IXP2000_XSCALE_DOORBELL IXP2000_PCI_CSR(0x60) +#define IXP2000_XSCALE_DOORBELL_SETUP IXP2000_PCI_CSR(0x64) +#define IXP2000_PCI_DOORBELL IXP2000_PCI_CSR(0x70) +#define IXP2000_PCI_DOORBELL_SETUP IXP2000_PCI_CSR(0x74) + +/* + * DMA engines + */ +#define IXP2000_PCI_CH1_BYTE_CNT IXP2000_PCI_CSR(0x80) +#define IXP2000_PCI_CH1_ADDR IXP2000_PCI_CSR(0x84) +#define IXP2000_PCI_CH1_DRAM_ADDR IXP2000_PCI_CSR(0x88) +#define IXP2000_PCI_CH1_DESC_PTR IXP2000_PCI_CSR(0x8C) +#define IXP2000_PCI_CH1_CNTRL IXP2000_PCI_CSR(0x90) +#define IXP2000_PCI_CH1_ME_PARAM IXP2000_PCI_CSR(0x94) +#define IXP2000_PCI_CH2_BYTE_CNT IXP2000_PCI_CSR(0xA0) +#define IXP2000_PCI_CH2_ADDR IXP2000_PCI_CSR(0xA4) +#define IXP2000_PCI_CH2_DRAM_ADDR IXP2000_PCI_CSR(0xA8) +#define IXP2000_PCI_CH2_DESC_PTR IXP2000_PCI_CSR(0xAC) +#define IXP2000_PCI_CH2_CNTRL IXP2000_PCI_CSR(0xB0) +#define IXP2000_PCI_CH2_ME_PARAM IXP2000_PCI_CSR(0xB4) +#define IXP2000_PCI_CH3_BYTE_CNT IXP2000_PCI_CSR(0xC0) +#define IXP2000_PCI_CH3_ADDR IXP2000_PCI_CSR(0xC4) +#define IXP2000_PCI_CH3_DRAM_ADDR IXP2000_PCI_CSR(0xC8) +#define IXP2000_PCI_CH3_DESC_PTR IXP2000_PCI_CSR(0xCC) +#define IXP2000_PCI_CH3_CNTRL IXP2000_PCI_CSR(0xD0) +#define IXP2000_PCI_CH3_ME_PARAM IXP2000_PCI_CSR(0xD4) +#define IXP2000_DMA_INF_MODE IXP2000_PCI_CSR(0xE0) +/* + * Size masks for BARs + */ +#define IXP2000_PCI_SRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0xFC) +#define IXP2000_PCI_DRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0x100) +/* + * Control and uEngine related + */ +#define IXP2000_PCI_CONTROL IXP2000_PCI_CSR(0x13C) +#define IXP2000_PCI_ADDR_EXT IXP2000_PCI_CSR(0x140) +#define IXP2000_PCI_ME_PUSH_STATUS IXP2000_PCI_CSR(0x148) +#define IXP2000_PCI_ME_PUSH_EN IXP2000_PCI_CSR(0x14C) +#define IXP2000_PCI_ERR_STATUS IXP2000_PCI_CSR(0x150) +#define IXP2000_PCI_ERR_ENABLE IXP2000_PCI_CSR(0x154) +/* + * Inbound PCI interrupt control + */ +#define IXP2000_PCI_XSCALE_INT_STATUS IXP2000_PCI_CSR(0x158) +#define IXP2000_PCI_XSCALE_INT_ENABLE IXP2000_PCI_CSR(0x15C) + +#define IXP2000_PCICNTL_PNR (1<<17) /* PCI not Reset bit of PCI_CONTROL */ +#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Central function bit */ +#define IXP2000_XSCALE_INT (1<<1) /* Interrupt from XScale to PCI */ + +/* These are from the IRQ register in the PCI ISR register */ +#define PCI_CONTROL_BE_DEO (1 << 22) /* Big Endian Data Enable Out */ +#define PCI_CONTROL_BE_DEI (1 << 21) /* Big Endian Data Enable In */ +#define PCI_CONTROL_BE_BEO (1 << 20) /* Big Endian Byte Enable Out */ +#define PCI_CONTROL_BE_BEI (1 << 19) /* Big Endian Byte Enable In */ +#define PCI_CONTROL_IEE (1 << 17) /* I/O cycle Endian swap Enable */ + +#define IXP2000_PCI_RST_REL (1 << 2) +#define CFG_RST_DIR (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF) +#define CFG_PCI_BOOT_HOST (1 << 2) +#define CFG_BOOT_PROM (1 << 1) + +/* + * SlowPort CSRs + * + * The slowport is used to access things like flash, SONET framer control + * ports, slave microprocessors, CPLDs, and others of chip memory mapped + * peripherals. + */ +#define SLOWPORT_CSR(x) (volatile unsigned long*)(IXP2000_SLOWPORT_CSR_VIRT_BASE | (x)) + +#define IXP2000_SLOWPORT_CCR SLOWPORT_CSR(0x00) +#define IXP2000_SLOWPORT_WTC1 SLOWPORT_CSR(0x04) +#define IXP2000_SLOWPORT_WTC2 SLOWPORT_CSR(0x08) +#define IXP2000_SLOWPORT_RTC1 SLOWPORT_CSR(0x0c) +#define IXP2000_SLOWPORT_RTC2 SLOWPORT_CSR(0x10) +#define IXP2000_SLOWPORT_FSR SLOWPORT_CSR(0x14) +#define IXP2000_SLOWPORT_PCR SLOWPORT_CSR(0x18) +#define IXP2000_SLOWPORT_ADC SLOWPORT_CSR(0x1C) +#define IXP2000_SLOWPORT_FAC SLOWPORT_CSR(0x20) +#define IXP2000_SLOWPORT_FRM SLOWPORT_CSR(0x24) +#define IXP2000_SLOWPORT_FIN SLOWPORT_CSR(0x28) + +/* + * CCR values. + * The CCR configures the clock division for the slowport interface. + */ +#define SLOWPORT_CCR_DIV_1 0x00 +#define SLOWPORT_CCR_DIV_2 0x01 +#define SLOWPORT_CCR_DIV_4 0x02 +#define SLOWPORT_CCR_DIV_6 0x03 +#define SLOWPORT_CCR_DIV_8 0x04 +#define SLOWPORT_CCR_DIV_10 0x05 +#define SLOWPORT_CCR_DIV_12 0x06 +#define SLOWPORT_CCR_DIV_14 0x07 +#define SLOWPORT_CCR_DIV_16 0x08 +#define SLOWPORT_CCR_DIV_18 0x09 +#define SLOWPORT_CCR_DIV_20 0x0a +#define SLOWPORT_CCR_DIV_22 0x0b +#define SLOWPORT_CCR_DIV_24 0x0c +#define SLOWPORT_CCR_DIV_26 0x0d +#define SLOWPORT_CCR_DIV_28 0x0e +#define SLOWPORT_CCR_DIV_30 0x0f + +/* + * PCR values. PCR configure the mode of the interface. + */ +#define SLOWPORT_MODE_FLASH 0x00 +#define SLOWPORT_MODE_LUCENT 0x01 +#define SLOWPORT_MODE_PMC_SIERRA 0x02 +#define SLOWPORT_MODE_INTEL_UP 0x03 +#define SLOWPORT_MODE_MOTOROLA_UP 0x04 + +/* + * ADC values. Defines data and address bus widths. + */ +#define SLOWPORT_ADDR_WIDTH_8 0x00 +#define SLOWPORT_ADDR_WIDTH_16 0x01 +#define SLOWPORT_ADDR_WIDTH_24 0x02 +#define SLOWPORT_ADDR_WIDTH_32 0x03 +#define SLOWPORT_DATA_WIDTH_8 0x00 +#define SLOWPORT_DATA_WIDTH_16 0x10 +#define SLOWPORT_DATA_WIDTH_24 0x20 +#define SLOWPORT_DATA_WIDTH_32 0x30 + +/* + * Masks and shifts for various fields in the WTC and RTC registers. + */ +#define SLOWPORT_WRTC_MASK_HD 0x0003 +#define SLOWPORT_WRTC_MASK_PW 0x003c +#define SLOWPORT_WRTC_MASK_SU 0x03c0 + +#define SLOWPORT_WRTC_SHIFT_HD 0x00 +#define SLOWPORT_WRTC_SHIFT_SU 0x02 +#define SLOWPORT_WRTC_SHFIT_PW 0x06 + + +/* + * GPIO registers & GPIO interface. + */ +#define IXP2000_GPIO_REG(x) ((volatile unsigned long*)(IXP2000_GPIO_VIRT_BASE+(x))) +#define IXP2000_GPIO_PLR IXP2000_GPIO_REG(0x00) +#define IXP2000_GPIO_PDPR IXP2000_GPIO_REG(0x04) +#define IXP2000_GPIO_PDSR IXP2000_GPIO_REG(0x08) +#define IXP2000_GPIO_PDCR IXP2000_GPIO_REG(0x0c) +#define IXP2000_GPIO_POPR IXP2000_GPIO_REG(0x10) +#define IXP2000_GPIO_POSR IXP2000_GPIO_REG(0x14) +#define IXP2000_GPIO_POCR IXP2000_GPIO_REG(0x18) +#define IXP2000_GPIO_REDR IXP2000_GPIO_REG(0x1c) +#define IXP2000_GPIO_FEDR IXP2000_GPIO_REG(0x20) +#define IXP2000_GPIO_EDSR IXP2000_GPIO_REG(0x24) +#define IXP2000_GPIO_LSHR IXP2000_GPIO_REG(0x28) +#define IXP2000_GPIO_LSLR IXP2000_GPIO_REG(0x2c) +#define IXP2000_GPIO_LDSR IXP2000_GPIO_REG(0x30) +#define IXP2000_GPIO_INER IXP2000_GPIO_REG(0x34) +#define IXP2000_GPIO_INSR IXP2000_GPIO_REG(0x38) +#define IXP2000_GPIO_INCR IXP2000_GPIO_REG(0x3c) +#define IXP2000_GPIO_INST IXP2000_GPIO_REG(0x40) + +/* + * "Global" registers...whatever that's supposed to mean. + */ +#define GLOBAL_REG_BASE (IXP2000_GLOBAL_REG_VIRT_BASE + 0x0a00) +#define GLOBAL_REG(x) (volatile unsigned long*)(GLOBAL_REG_BASE | (x)) + +#define IXP2000_MAJ_PROD_TYPE_MASK 0x001F0000 +#define IXP2000_MAJ_PROD_TYPE_IXP2000 0x00000000 +#define IXP2000_MIN_PROD_TYPE_MASK 0x0000FF00 +#define IXP2000_MIN_PROD_TYPE_IXP2400 0x00000200 +#define IXP2000_MIN_PROD_TYPE_IXP2850 0x00000100 +#define IXP2000_MIN_PROD_TYPE_IXP2800 0x00000000 +#define IXP2000_MAJ_REV_MASK 0x000000F0 +#define IXP2000_MIN_REV_MASK 0x0000000F +#define IXP2000_PROD_ID_MASK 0xFFFFFFFF + +#define IXP2000_PRODUCT_ID GLOBAL_REG(0x00) +#define IXP2000_MISC_CONTROL GLOBAL_REG(0x04) +#define IXP2000_MSF_CLK_CNTRL GLOBAL_REG(0x08) +#define IXP2000_RESET0 GLOBAL_REG(0x0c) +#define IXP2000_RESET1 GLOBAL_REG(0x10) +#define IXP2000_CCR GLOBAL_REG(0x14) +#define IXP2000_STRAP_OPTIONS GLOBAL_REG(0x18) + +#define RSTALL (1 << 16) +#define WDT_RESET_ENABLE 0x01000000 + + +/* + * MSF registers. The IXP2400 and IXP2800 have somewhat different MSF + * units, but the registers that differ between the two don't overlap, + * so we can have one register list for both. + */ +#define IXP2000_MSF_REG(x) ((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x))) +#define IXP2000_MSF_RX_CONTROL IXP2000_MSF_REG(0x0000) +#define IXP2000_MSF_TX_CONTROL IXP2000_MSF_REG(0x0004) +#define IXP2000_MSF_INTERRUPT_STATUS IXP2000_MSF_REG(0x0008) +#define IXP2000_MSF_INTERRUPT_ENABLE IXP2000_MSF_REG(0x000c) +#define IXP2000_MSF_CSIX_TYPE_MAP IXP2000_MSF_REG(0x0010) +#define IXP2000_MSF_FC_EGRESS_STATUS IXP2000_MSF_REG(0x0014) +#define IXP2000_MSF_FC_INGRESS_STATUS IXP2000_MSF_REG(0x0018) +#define IXP2000_MSF_HWM_CONTROL IXP2000_MSF_REG(0x0024) +#define IXP2000_MSF_FC_STATUS_OVERRIDE IXP2000_MSF_REG(0x0028) +#define IXP2000_MSF_CLOCK_CONTROL IXP2000_MSF_REG(0x002c) +#define IXP2000_MSF_RX_PORT_MAP IXP2000_MSF_REG(0x0040) +#define IXP2000_MSF_RBUF_ELEMENT_DONE IXP2000_MSF_REG(0x0044) +#define IXP2000_MSF_RX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0048) +#define IXP2000_MSF_RX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0048) +#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0 IXP2000_MSF_REG(0x0050) +#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1 IXP2000_MSF_REG(0x0054) +#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2 IXP2000_MSF_REG(0x0058) +#define IXP2000_MSF_TX_SEQUENCE_0 IXP2000_MSF_REG(0x0060) +#define IXP2000_MSF_TX_SEQUENCE_1 IXP2000_MSF_REG(0x0064) +#define IXP2000_MSF_TX_SEQUENCE_2 IXP2000_MSF_REG(0x0068) +#define IXP2000_MSF_TX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0070) +#define IXP2000_MSF_TX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0070) +#define IXP2000_MSF_RX_UP_CONTROL_0 IXP2000_MSF_REG(0x0080) +#define IXP2000_MSF_RX_UP_CONTROL_1 IXP2000_MSF_REG(0x0084) +#define IXP2000_MSF_RX_UP_CONTROL_2 IXP2000_MSF_REG(0x0088) +#define IXP2000_MSF_RX_UP_CONTROL_3 IXP2000_MSF_REG(0x008c) +#define IXP2000_MSF_TX_UP_CONTROL_0 IXP2000_MSF_REG(0x0090) +#define IXP2000_MSF_TX_UP_CONTROL_1 IXP2000_MSF_REG(0x0094) +#define IXP2000_MSF_TX_UP_CONTROL_2 IXP2000_MSF_REG(0x0098) +#define IXP2000_MSF_TX_UP_CONTROL_3 IXP2000_MSF_REG(0x009c) +#define IXP2000_MSF_TRAIN_DATA IXP2000_MSF_REG(0x00a0) +#define IXP2000_MSF_TRAIN_CALENDAR IXP2000_MSF_REG(0x00a4) +#define IXP2000_MSF_TRAIN_FLOW_CONTROL IXP2000_MSF_REG(0x00a8) +#define IXP2000_MSF_TX_CALENDAR_0 IXP2000_MSF_REG(0x1000) +#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS IXP2000_MSF_REG(0x1400) + + +#endif /* _IXP2000_H_ */ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/memory.h b/trunk/arch/arm/mach-ixp2000/include/mach/memory.h new file mode 100644 index 000000000000..5f0c4fd4076a --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/memory.h @@ -0,0 +1,31 @@ +/* + * arch/arm/mach-ixp2000/include/mach/memory.h + * + * Copyright (c) 2002 Intel Corp. + * Copyright (c) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PLAT_PHYS_OFFSET UL(0x00000000) + +#include + +#define IXP2000_PCI_SDRAM_OFFSET (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0) + +#define __phys_to_bus(x) ((x) + (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET)) +#define __bus_to_phys(x) ((x) - (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET)) + +#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v)) +#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b)) +#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p)) +#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b)) + +#endif + diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/platform.h b/trunk/arch/arm/mach-ixp2000/include/mach/platform.h new file mode 100644 index 000000000000..bb0f8dcf9ee1 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/platform.h @@ -0,0 +1,153 @@ +/* + * arch/arm/mach-ixp2000/include/mach/platform.h + * + * Various bits of code used by platform-level code. + * + * Author: Deepak Saxena + * + * Copyright 2004 (c) MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + + +#ifndef __ASSEMBLY__ + +static inline unsigned long ixp2000_reg_read(volatile void *reg) +{ + return *((volatile unsigned long *)reg); +} + +static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) +{ + *((volatile unsigned long *)reg) = val; +} + +/* + * On the IXP2400, we can't use XCB=000 due to chip bugs. We use + * XCB=101 instead, but that makes all I/O accesses bufferable. This + * is not a problem in general, but we do have to be slightly more + * careful because I/O writes are no longer automatically flushed out + * of the write buffer. + * + * In cases where we want to make sure that a write has been flushed + * out of the write buffer before we proceed, for example when masking + * a device interrupt before re-enabling IRQs in CPSR, we can use this + * function, ixp2000_reg_wrb, which performs a write, a readback, and + * issues a dummy instruction dependent on the value of the readback + * (mov rX, rX) to make sure that the readback has completed before we + * continue. + */ +static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val) +{ + unsigned long dummy; + + *((volatile unsigned long *)reg) = val; + + dummy = *((volatile unsigned long *)reg); + __asm__ __volatile__("mov %0, %0" : "+r" (dummy)); +} + +/* + * Boards may multiplex different devices on the 2nd channel of + * the slowport interface that each need different configuration + * settings. For example, the IXDP2400 uses channel 2 on the interface + * to access the CPLD, the switch fabric card, and the media card. Each + * one needs a different mode so drivers must save/restore the mode + * before and after each operation. + * + * acquire_slowport(&your_config); + * ... + * do slowport operations + * ... + * release_slowport(); + * + * Note that while you have the slowport, you are holding a spinlock, + * so your code should be written as if you explicitly acquired a lock. + * + * The configuration only affects device 2 on the slowport, so the + * MTD map driver does not acquire/release the slowport. + */ +struct slowport_cfg { + unsigned long CCR; /* Clock divide */ + unsigned long WTC; /* Write Timing Control */ + unsigned long RTC; /* Read Timing Control */ + unsigned long PCR; /* Protocol Control Register */ + unsigned long ADC; /* Address/Data Width Control */ +}; + + +void ixp2000_acquire_slowport(struct slowport_cfg *, struct slowport_cfg *); +void ixp2000_release_slowport(struct slowport_cfg *); + +/* + * IXP2400 A0/A1 and IXP2800 A0/A1/A2 have broken slowport that requires + * tweaking of addresses in the MTD driver. + */ +static inline unsigned ixp2000_has_broken_slowport(void) +{ + unsigned long id = *IXP2000_PRODUCT_ID; + unsigned long id_prod = id & (IXP2000_MAJ_PROD_TYPE_MASK | + IXP2000_MIN_PROD_TYPE_MASK); + return (((id_prod == + /* fixed in IXP2400-B0 */ + (IXP2000_MAJ_PROD_TYPE_IXP2000 | + IXP2000_MIN_PROD_TYPE_IXP2400)) && + ((id & IXP2000_MAJ_REV_MASK) == 0)) || + ((id_prod == + /* fixed in IXP2800-B0 */ + (IXP2000_MAJ_PROD_TYPE_IXP2000 | + IXP2000_MIN_PROD_TYPE_IXP2800)) && + ((id & IXP2000_MAJ_REV_MASK) == 0)) || + ((id_prod == + /* fixed in IXP2850-B0 */ + (IXP2000_MAJ_PROD_TYPE_IXP2000 | + IXP2000_MIN_PROD_TYPE_IXP2850)) && + ((id & IXP2000_MAJ_REV_MASK) == 0))); +} + +static inline unsigned int ixp2000_has_flash(void) +{ + return ((*IXP2000_STRAP_OPTIONS) & (CFG_BOOT_PROM)); +} + +static inline unsigned int ixp2000_is_pcimaster(void) +{ + return ((*IXP2000_STRAP_OPTIONS) & (CFG_PCI_BOOT_HOST)); +} + +void ixp2000_map_io(void); +void ixp2000_uart_init(void); +void ixp2000_init_irq(void); +void ixp2000_init_time(unsigned long); +void ixp2000_restart(char, const char *); +unsigned long ixp2000_gettimeoffset(void); + +struct pci_sys_data; + +u32 *ixp2000_pci_config_addr(unsigned int bus, unsigned int devfn, int where); +void ixp2000_pci_preinit(void); +int ixp2000_pci_setup(int, struct pci_sys_data*); +struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*); +int ixp2000_pci_read_config(struct pci_bus*, unsigned int, int, int, u32 *); +int ixp2000_pci_write_config(struct pci_bus*, unsigned int, int, int, u32); + +/* + * Several of the IXP2000 systems have banked flash so we need to extend the + * flash_platform_data structure with some private pointers + */ +struct ixp2000_flash_data { + struct flash_platform_data *platform_data; + int nr_banks; + unsigned long (*bank_setup)(unsigned long); +}; + +struct ixp2000_i2c_pins { + unsigned long sda_pin; + unsigned long scl_pin; +}; + + +#endif /* !__ASSEMBLY__ */ diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/timex.h b/trunk/arch/arm/mach-ixp2000/include/mach/timex.h new file mode 100644 index 000000000000..835e659f93d4 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/timex.h @@ -0,0 +1,13 @@ +/* + * arch/arm/mach-ixp2000/include/mach/timex.h + * + * IXP2000 architecture timex specifications + */ + + +/* + * Default clock is 50MHz APB, but platform code can override this + */ +#define CLOCK_TICK_RATE 50000000 + + diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/uncompress.h b/trunk/arch/arm/mach-ixp2000/include/mach/uncompress.h new file mode 100644 index 000000000000..ce363087df78 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/include/mach/uncompress.h @@ -0,0 +1,47 @@ +/* + * arch/arm/mach-ixp2000/include/mach/uncompress.h + * + * + * Original Author: Naeem Afzal + * Maintainer: Deepak Saxena + * + * Copyright 2002 Intel Corp. + * + * 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. + * + */ + +#include + +#define UART_BASE 0xc0030000 + +#define PHYS(x) ((volatile unsigned long *)(UART_BASE + x)) + +#define UARTDR PHYS(0x00) /* Transmit reg dlab=0 */ +#define UARTDLL PHYS(0x00) /* Divisor Latch reg dlab=1*/ +#define UARTDLM PHYS(0x04) /* Divisor Latch reg dlab=1*/ +#define UARTIER PHYS(0x04) /* Interrupt enable reg */ +#define UARTFCR PHYS(0x08) /* FIFO control reg dlab =0*/ +#define UARTLCR PHYS(0x0c) /* Control reg */ +#define UARTSR PHYS(0x14) /* Status reg */ + + +static inline void putc(int c) +{ + int j = 0x1000; + + while (--j && !(*UARTSR & UART_LSR_THRE)) + barrier(); + + *UARTDR = c; +} + +static inline void flush(void) +{ +} + +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2400.c b/trunk/arch/arm/mach-ixp2000/ixdp2400.c new file mode 100644 index 000000000000..915ad49e3b8f --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/ixdp2400.c @@ -0,0 +1,180 @@ +/* + * arch/arm/mach-ixp2000/ixdp2400.c + * + * IXDP2400 platform support + * + * Original Author: Naeem Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/************************************************************************* + * IXDP2400 timer tick + *************************************************************************/ +static void __init ixdp2400_timer_init(void) +{ + int numerator, denominator; + int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8}; + + numerator = (*(IXDP2400_CPLD_SYS_CLK_M) & 0xFF) *2; + denominator = denom_array[(*(IXDP2400_CPLD_SYS_CLK_N) & 0x7)]; + + ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2); +} + +static struct sys_timer ixdp2400_timer = { + .init = ixdp2400_timer_init, + .offset = ixp2000_gettimeoffset, +}; + +/************************************************************************* + * IXDP2400 PCI + *************************************************************************/ +void __init ixdp2400_pci_preinit(void) +{ + ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); + ixp2000_pci_preinit(); + pcibios_setup("firmware"); +} + +int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0xe0000000; + + ixp2000_pci_setup(nr, sys); + + return 1; +} + +static int __init ixdp2400_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) +{ + if (ixdp2x00_master_npu()) { + + /* + * Root bus devices. Slave NPU is only one with interrupt. + * Everything else, we just return -1 b/c nothing else + * on the root bus has interrupts. + */ + if(!dev->bus->self) { + if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN ) + return IRQ_IXDP2400_INGRESS_NPU; + + return -1; + } + + /* + * Bridge behind the PMC slot. + * NOTE: Only INTA from the PMC slot is routed. VERY BAD. + */ + if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN && + dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN && + !dev->bus->parent->self->bus->parent) + return IRQ_IXDP2400_PMC; + + /* + * Device behind the first bridge + */ + if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) { + switch(dev->devfn) { + case IXDP2400_MASTER_ENET_DEVFN: + return IRQ_IXDP2400_ENET; + + case IXDP2400_MEDIA_DEVFN: + return IRQ_IXDP2400_MEDIA_PCI; + + case IXDP2400_SWITCH_FABRIC_DEVFN: + return IRQ_IXDP2400_SF_PCI; + + case IXDP2X00_PMC_DEVFN: + return IRQ_IXDP2400_PMC; + } + } + + return -1; + } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ +} + + +static void ixdp2400_pci_postinit(void) +{ + struct pci_dev *dev; + + if (ixdp2x00_master_npu()) { + dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); + } else { + dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); + + ixdp2x00_slave_pci_postinit(); + } +} + +static struct hw_pci ixdp2400_pci __initdata = { + .nr_controllers = 1, + .setup = ixdp2400_pci_setup, + .preinit = ixdp2400_pci_preinit, + .postinit = ixdp2400_pci_postinit, + .scan = ixp2000_pci_scan_bus, + .map_irq = ixdp2400_pci_map_irq, +}; + +int __init ixdp2400_pci_init(void) +{ + if (machine_is_ixdp2400()) + pci_common_init(&ixdp2400_pci); + + return 0; +} + +subsys_initcall(ixdp2400_pci_init); + +void __init ixdp2400_init_irq(void) +{ + ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS); +} + +MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") + /* Maintainer: MontaVista Software, Inc. */ + .atag_offset = 0x100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2400_init_irq, + .timer = &ixdp2400_timer, + .init_machine = ixdp2x00_init_machine, + .restart = ixp2000_restart, +MACHINE_END + diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2800.c b/trunk/arch/arm/mach-ixp2000/ixdp2800.c new file mode 100644 index 000000000000..a9f1819ea049 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/ixdp2800.c @@ -0,0 +1,295 @@ +/* + * arch/arm/mach-ixp2000/ixdp2800.c + * + * IXDP2800 platform support + * + * Original Author: Jeffrey Daly + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/************************************************************************* + * IXDP2800 timer tick + *************************************************************************/ + +static void __init ixdp2800_timer_init(void) +{ + ixp2000_init_time(50000000); +} + +static struct sys_timer ixdp2800_timer = { + .init = ixdp2800_timer_init, + .offset = ixp2000_gettimeoffset, +}; + +/************************************************************************* + * IXDP2800 PCI + *************************************************************************/ +static void __init ixdp2800_slave_disable_pci_master(void) +{ + *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); +} + +static void __init ixdp2800_master_wait_for_slave(void) +{ + volatile u32 *addr; + + printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure " + "its BAR sizes\n"); + + addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN, + PCI_BASE_ADDRESS_1); + do { + *addr = 0xffffffff; + cpu_relax(); + } while (*addr != 0xfe000008); + + addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN, + PCI_BASE_ADDRESS_2); + do { + *addr = 0xffffffff; + cpu_relax(); + } while (*addr != 0xc0000008); + + /* + * Configure the slave's SDRAM BAR by hand. + */ + *addr = 0x40000008; +} + +static void __init ixdp2800_slave_wait_for_master_enable(void) +{ + printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n"); + + while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0) + cpu_relax(); +} + +void __init ixdp2800_pci_preinit(void) +{ + printk("ixdp2x00_pci_preinit called\n"); + + *IXP2000_PCI_ADDR_EXT = 0x0001e000; + + if (!ixdp2x00_master_npu()) + ixdp2800_slave_disable_pci_master(); + + *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; + *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff; + + ixp2000_pci_preinit(); + + if (ixdp2x00_master_npu()) { + /* + * Wait until the slave set its SRAM/SDRAM BAR sizes + * correctly before we proceed to scan and enumerate + * the bus. + */ + ixdp2800_master_wait_for_slave(); + + /* + * We configure the SDRAM BARs by hand because they + * are 1G and fall outside of the regular allocated + * PCI address space. + */ + *IXP2000_PCI_SDRAM_BAR = 0x00000008; + } else { + /* + * Wait for the master to complete scanning the bus + * and assigning resources before we proceed to scan + * the bus ourselves. Set pci=firmware to honor the + * master's resource assignment. + */ + ixdp2800_slave_wait_for_master_enable(); + pcibios_setup("firmware"); + } +} + +/* + * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside + * of the regular PCI window, because there's only 512M of outbound PCI + * memory window on each IXP, while we need 1G for each of the BARs. + */ +static void __devinit ixp2800_pci_fixup(struct pci_dev *dev) +{ + if (machine_is_ixdp2800()) { + dev->resource[2].start = 0; + dev->resource[2].end = 0; + dev->resource[2].flags = 0; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup); + +static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0x00000000; + + ixp2000_pci_setup(nr, sys); + + return 1; +} + +static int __init ixdp2800_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) +{ + if (ixdp2x00_master_npu()) { + + /* + * Root bus devices. Slave NPU is only one with interrupt. + * Everything else, we just return -1 which is invalid. + */ + if(!dev->bus->self) { + if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN ) + return IRQ_IXDP2800_INGRESS_NPU; + + return -1; + } + + /* + * Bridge behind the PMC slot. + */ + if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN && + dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN && + !dev->bus->parent->self->bus->parent) + return IRQ_IXDP2800_PMC; + + /* + * Device behind the first bridge + */ + if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) { + switch(dev->devfn) { + case IXDP2X00_PMC_DEVFN: + return IRQ_IXDP2800_PMC; + + case IXDP2800_MASTER_ENET_DEVFN: + return IRQ_IXDP2800_EGRESS_ENET; + + case IXDP2800_SWITCH_FABRIC_DEVFN: + return IRQ_IXDP2800_FABRIC; + } + } + + return -1; + } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ +} + +static void __init ixdp2800_master_enable_slave(void) +{ + volatile u32 *addr; + + printk(KERN_INFO "IXDP2800: enabling slave NPU\n"); + + addr = (volatile u32 *)ixp2000_pci_config_addr(0, + IXDP2X00_SLAVE_NPU_DEVFN, + PCI_COMMAND); + + *addr |= PCI_COMMAND_MASTER; +} + +static void __init ixdp2800_master_wait_for_slave_bus_scan(void) +{ + volatile u32 *addr; + + printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n"); + + addr = (volatile u32 *)ixp2000_pci_config_addr(0, + IXDP2X00_SLAVE_NPU_DEVFN, + PCI_COMMAND); + while ((*addr & PCI_COMMAND_MEMORY) == 0) + cpu_relax(); +} + +static void __init ixdp2800_slave_signal_bus_scan_completion(void) +{ + printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n"); + *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY; +} + +static void __init ixdp2800_pci_postinit(void) +{ + if (!ixdp2x00_master_npu()) { + ixdp2x00_slave_pci_postinit(); + ixdp2800_slave_signal_bus_scan_completion(); + } +} + +struct __initdata hw_pci ixdp2800_pci __initdata = { + .nr_controllers = 1, + .setup = ixdp2800_pci_setup, + .preinit = ixdp2800_pci_preinit, + .postinit = ixdp2800_pci_postinit, + .scan = ixp2000_pci_scan_bus, + .map_irq = ixdp2800_pci_map_irq, +}; + +int __init ixdp2800_pci_init(void) +{ + if (machine_is_ixdp2800()) { + struct pci_dev *dev; + + pci_common_init(&ixdp2800_pci); + if (ixdp2x00_master_npu()) { + dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); + + ixdp2800_master_enable_slave(); + ixdp2800_master_wait_for_slave_bus_scan(); + } else { + dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); + } + } + + return 0; +} + +subsys_initcall(ixdp2800_pci_init); + +void __init ixdp2800_init_irq(void) +{ + ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS); +} + +MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") + /* Maintainer: MontaVista Software, Inc. */ + .atag_offset = 0x100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2800_init_irq, + .timer = &ixdp2800_timer, + .init_machine = ixdp2x00_init_machine, + .restart = ixp2000_restart, +MACHINE_END + diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x00.c b/trunk/arch/arm/mach-ixp2000/ixdp2x00.c new file mode 100644 index 000000000000..421e38dc0fac --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x00.c @@ -0,0 +1,306 @@ +/* + * arch/arm/mach-ixp2000/ixdp2x00.c + * + * Code common to IXDP2400 and IXDP2800 platforms. + * + * Original Author: Naeem Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/************************************************************************* + * IXDP2x00 IRQ Initialization + *************************************************************************/ +static volatile unsigned long *board_irq_mask; +static volatile unsigned long *board_irq_stat; +static unsigned long board_irq_count; + +#ifdef CONFIG_ARCH_IXDP2400 +/* + * Slowport configuration for accessing CPLD registers on IXDP2x00 + */ +static struct slowport_cfg slowport_cpld_cfg = { + .CCR = SLOWPORT_CCR_DIV_2, + .WTC = 0x00000070, + .RTC = 0x00000070, + .PCR = SLOWPORT_MODE_FLASH, + .ADC = SLOWPORT_ADDR_WIDTH_24 | SLOWPORT_DATA_WIDTH_8 +}; +#endif + +static void ixdp2x00_irq_mask(struct irq_data *d) +{ + unsigned long dummy; + static struct slowport_cfg old_cfg; + + /* + * This is ugly in common code but really don't know + * of a better way to handle it. :( + */ +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg); +#endif + + dummy = *board_irq_mask; + dummy |= IXP2000_BOARD_IRQ_MASK(d->irq); + ixp2000_reg_wrb(board_irq_mask, dummy); + +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_release_slowport(&old_cfg); +#endif +} + +static void ixdp2x00_irq_unmask(struct irq_data *d) +{ + unsigned long dummy; + static struct slowport_cfg old_cfg; + +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg); +#endif + + dummy = *board_irq_mask; + dummy &= ~IXP2000_BOARD_IRQ_MASK(d->irq); + ixp2000_reg_wrb(board_irq_mask, dummy); + + if (machine_is_ixdp2400()) + ixp2000_release_slowport(&old_cfg); +} + +static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + volatile u32 ex_interrupt = 0; + static struct slowport_cfg old_cfg; + int i; + + desc->irq_data.chip->irq_mask(&desc->irq_data); + +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg); +#endif + ex_interrupt = *board_irq_stat & 0xff; + if (machine_is_ixdp2400()) + ixp2000_release_slowport(&old_cfg); + + if(!ex_interrupt) { + printk(KERN_ERR "Spurious IXDP2x00 CPLD interrupt!\n"); + return; + } + + for(i = 0; i < board_irq_count; i++) { + if(ex_interrupt & (1 << i)) { + int cpld_irq = IXP2000_BOARD_IRQ(0) + i; + generic_handle_irq(cpld_irq); + } + } + + desc->irq_data.chip->irq_unmask(&desc->irq_data); +} + +static struct irq_chip ixdp2x00_cpld_irq_chip = { + .irq_ack = ixdp2x00_irq_mask, + .irq_mask = ixdp2x00_irq_mask, + .irq_unmask = ixdp2x00_irq_unmask +}; + +void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs) +{ + unsigned int irq; + + ixp2000_init_irq(); + + if (!ixdp2x00_master_npu()) + return; + + board_irq_stat = stat_reg; + board_irq_mask = mask_reg; + board_irq_count = nr_of_irqs; + + *board_irq_mask = 0xffffffff; + + for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) { + irq_set_chip_and_handler(irq, &ixdp2x00_cpld_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + + /* Hook into PCI interrupt */ + irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler); +} + +/************************************************************************* + * IXDP2x00 memory map + *************************************************************************/ +static struct map_desc ixdp2x00_io_desc __initdata = { + .virtual = IXDP2X00_VIRT_CPLD_BASE, + .pfn = __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE), + .length = IXDP2X00_CPLD_SIZE, + .type = MT_DEVICE +}; + +void __init ixdp2x00_map_io(void) +{ + ixp2000_map_io(); + + iotable_init(&ixdp2x00_io_desc, 1); +} + +/************************************************************************* + * IXDP2x00-common PCI init + * + * The IXDP2[48]00 has a horrid PCI bus layout. Basically the board + * contains two NPUs (ingress and egress) connected over PCI, both running + * instances of the kernel. So far so good. Peers on the PCI bus running + * Linux is a common design in telecom systems. The problem is that instead + * of all the devices being controlled by a single host, different + * devices are controlled by different NPUs on the same bus, leading to + * multiple hosts on the bus. The exact bus layout looks like: + * + * Bus 0 + * Master NPU <-------------------+-------------------> Slave NPU + * | + * | + * P2P + * | + * + * Bus 1 | + * <--+------+---------+---------+------+--> + * | | | | | + * | | | | | + * ... Dev PMC Media Eth0 Eth1 ... + * + * The master controls all but Eth1, which is controlled by the + * slave. What this means is that the both the master and the slave + * have to scan the bus, but only one of them can enumerate the bus. + * In addition, after the bus is scanned, each kernel must remove + * the device(s) it does not control from the PCI dev list otherwise + * a driver on each NPU will try to manage it and we will have horrible + * conflicts. Oh..and the slave NPU needs to see the master NPU + * for Intel's drivers to work properly. Closed source drivers... + * + * The way we deal with this is fairly simple but ugly: + * + * 1) Let master scan and enumerate the bus completely. + * 2) Master deletes Eth1 from device list. + * 3) Slave scans bus and then deletes all but Eth1 (Eth0 on slave) + * from device list. + * 4) Find HW designers and LART them. + * + * The boards also do not do normal PCI IRQ routing, or any sort of + * sensical swizzling, so we just need to check where on the bus a + * device sits and figure out to which CPLD pin the interrupt is routed. + * See ixdp2[48]00.c files. + * + *************************************************************************/ +void ixdp2x00_slave_pci_postinit(void) +{ + struct pci_dev *dev; + + /* + * Remove PMC device is there is one + */ + if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); + } + + dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); +} + +/************************************************************************** + * IXDP2x00 Machine Setup + *************************************************************************/ +static struct flash_platform_data ixdp2x00_platform_data = { + .map_name = "cfi_probe", + .width = 1, +}; + +static struct ixp2000_flash_data ixdp2x00_flash_data = { + .platform_data = &ixdp2x00_platform_data, + .nr_banks = 1 +}; + +static struct resource ixdp2x00_flash_resource = { + .start = 0xc4000000, + .end = 0xc4000000 + 0x00ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2x00_flash = { + .name = "IXP2000-Flash", + .id = 0, + .dev = { + .platform_data = &ixdp2x00_flash_data, + }, + .num_resources = 1, + .resource = &ixdp2x00_flash_resource, +}; + +static struct ixp2000_i2c_pins ixdp2x00_i2c_gpio_pins = { + .sda_pin = IXDP2X00_GPIO_SDA, + .scl_pin = IXDP2X00_GPIO_SCL, +}; + +static struct platform_device ixdp2x00_i2c_controller = { + .name = "IXP2000-I2C", + .id = 0, + .dev = { + .platform_data = &ixdp2x00_i2c_gpio_pins, + }, + .num_resources = 0 +}; + +static struct platform_device *ixdp2x00_devices[] __initdata = { + &ixdp2x00_flash, + &ixdp2x00_i2c_controller +}; + +void __init ixdp2x00_init_machine(void) +{ + gpio_line_set(IXDP2X00_GPIO_I2C_ENABLE, 1); + gpio_line_config(IXDP2X00_GPIO_I2C_ENABLE, GPIO_OUT); + + platform_add_devices(ixdp2x00_devices, ARRAY_SIZE(ixdp2x00_devices)); + ixp2000_uart_init(); +} + diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c new file mode 100644 index 000000000000..5196c39cdba4 --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c @@ -0,0 +1,483 @@ +/* + * arch/arm/mach-ixp2000/ixdp2x01.c + * + * Code common to Intel IXDP2401 and IXDP2801 platforms + * + * Original Author: Andrzej Mialkowski + * Maintainer: Deepak Saxena + * + * Copyright (C) 2002-2003 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/************************************************************************* + * IXDP2x01 IRQ Handling + *************************************************************************/ +static void ixdp2x01_irq_mask(struct irq_data *d) +{ + ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG, + IXP2000_BOARD_IRQ_MASK(d->irq)); +} + +static void ixdp2x01_irq_unmask(struct irq_data *d) +{ + ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG, + IXP2000_BOARD_IRQ_MASK(d->irq)); +} + +static u32 valid_irq_mask; + +static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + u32 ex_interrupt; + int i; + + desc->irq_data.chip->irq_mask(&desc->irq_data); + + ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask; + + if (!ex_interrupt) { + printk(KERN_ERR "Spurious IXDP2X01 CPLD interrupt!\n"); + return; + } + + for (i = 0; i < IXP2000_BOARD_IRQS; i++) { + if (ex_interrupt & (1 << i)) { + int cpld_irq = IXP2000_BOARD_IRQ(0) + i; + generic_handle_irq(cpld_irq); + } + } + + desc->irq_data.chip->irq_unmask(&desc->irq_data); +} + +static struct irq_chip ixdp2x01_irq_chip = { + .irq_mask = ixdp2x01_irq_mask, + .irq_ack = ixdp2x01_irq_mask, + .irq_unmask = ixdp2x01_irq_unmask +}; + +/* + * We only do anything if we are the master NPU on the board. + * The slave NPU only has the ethernet chip going directly to + * the PCIB interrupt input. + */ +void __init ixdp2x01_init_irq(void) +{ + int irq = 0; + + /* initialize chip specific interrupts */ + ixp2000_init_irq(); + + if (machine_is_ixdp2401()) + valid_irq_mask = IXDP2401_VALID_IRQ_MASK; + else + valid_irq_mask = IXDP2801_VALID_IRQ_MASK; + + /* Mask all interrupts from CPLD, disable simulation */ + ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff); + ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0); + + for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { + if (irq & valid_irq_mask) { + irq_set_chip_and_handler(irq, &ixdp2x01_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } else { + set_irq_flags(irq, 0); + } + } + + /* Hook into PCI interrupts */ + irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler); +} + + +/************************************************************************* + * IXDP2x01 memory map + *************************************************************************/ +static struct map_desc ixdp2x01_io_desc __initdata = { + .virtual = IXDP2X01_VIRT_CPLD_BASE, + .pfn = __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE), + .length = IXDP2X01_CPLD_REGION_SIZE, + .type = MT_DEVICE +}; + +static void __init ixdp2x01_map_io(void) +{ + ixp2000_map_io(); + iotable_init(&ixdp2x01_io_desc, 1); +} + + +/************************************************************************* + * IXDP2x01 serial ports + *************************************************************************/ +static struct plat_serial8250_port ixdp2x01_serial_port1[] = { + { + .mapbase = (unsigned long)IXDP2X01_UART1_PHYS_BASE, + .membase = (char *)IXDP2X01_UART1_VIRT_BASE, + .irq = IRQ_IXDP2X01_UART1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = IXDP2X01_UART_CLK, + }, + { } +}; + +static struct resource ixdp2x01_uart_resource1 = { + .start = IXDP2X01_UART1_PHYS_BASE, + .end = IXDP2X01_UART1_PHYS_BASE + 0xffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2x01_serial_device1 = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM1, + .dev = { + .platform_data = ixdp2x01_serial_port1, + }, + .num_resources = 1, + .resource = &ixdp2x01_uart_resource1, +}; + +static struct plat_serial8250_port ixdp2x01_serial_port2[] = { + { + .mapbase = (unsigned long)IXDP2X01_UART2_PHYS_BASE, + .membase = (char *)IXDP2X01_UART2_VIRT_BASE, + .irq = IRQ_IXDP2X01_UART2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = IXDP2X01_UART_CLK, + }, + { } +}; + +static struct resource ixdp2x01_uart_resource2 = { + .start = IXDP2X01_UART2_PHYS_BASE, + .end = IXDP2X01_UART2_PHYS_BASE + 0xffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2x01_serial_device2 = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM2, + .dev = { + .platform_data = ixdp2x01_serial_port2, + }, + .num_resources = 1, + .resource = &ixdp2x01_uart_resource2, +}; + +static void ixdp2x01_uart_init(void) +{ + platform_device_register(&ixdp2x01_serial_device1); + platform_device_register(&ixdp2x01_serial_device2); +} + + +/************************************************************************* + * IXDP2x01 timer tick configuration + *************************************************************************/ +static unsigned int ixdp2x01_clock; + +static int __init ixdp2x01_clock_setup(char *str) +{ + ixdp2x01_clock = simple_strtoul(str, NULL, 10); + + return 1; +} + +__setup("ixdp2x01_clock=", ixdp2x01_clock_setup); + +static void __init ixdp2x01_timer_init(void) +{ + if (!ixdp2x01_clock) + ixdp2x01_clock = 50000000; + + ixp2000_init_time(ixdp2x01_clock); +} + +static struct sys_timer ixdp2x01_timer = { + .init = ixdp2x01_timer_init, + .offset = ixp2000_gettimeoffset, +}; + +/************************************************************************* + * IXDP2x01 PCI + *************************************************************************/ +void __init ixdp2x01_pci_preinit(void) +{ + ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000); + ixp2000_pci_preinit(); + pcibios_setup("firmware"); +} + +#define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) + +static int __init ixdp2x01_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) +{ + u8 bus = dev->bus->number; + u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); + struct pci_bus *tmp_bus = dev->bus; + + /* Primary bus, no interrupts here */ + if (bus == 0) { + return -1; + } + + /* Lookup first leaf in bus tree */ + while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) { + tmp_bus = tmp_bus->parent; + } + + /* Select between known bridges */ + switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) { + /* Device is located after first MB bridge */ + case 0x0008: + if (tmp_bus == dev->bus) { + /* Device is located directly after first MB bridge */ + switch (devpin) { + case DEVPIN(1, 1): /* Onboard 82546 ch 0 */ + if (machine_is_ixdp2401()) + return IRQ_IXDP2401_INTA_82546; + return -1; + case DEVPIN(1, 2): /* Onboard 82546 ch 1 */ + if (machine_is_ixdp2401()) + return IRQ_IXDP2401_INTB_82546; + return -1; + case DEVPIN(0, 1): /* PMC INTA# */ + return IRQ_IXDP2X01_SPCI_PMC_INTA; + case DEVPIN(0, 2): /* PMC INTB# */ + return IRQ_IXDP2X01_SPCI_PMC_INTB; + case DEVPIN(0, 3): /* PMC INTC# */ + return IRQ_IXDP2X01_SPCI_PMC_INTC; + case DEVPIN(0, 4): /* PMC INTD# */ + return IRQ_IXDP2X01_SPCI_PMC_INTD; + } + } + break; + case 0x0010: + if (tmp_bus == dev->bus) { + /* Device is located directly after second MB bridge */ + /* Secondary bus of second bridge */ + switch (devpin) { + case DEVPIN(0, 1): /* DB#0 */ + return IRQ_IXDP2X01_SPCI_DB_0; + case DEVPIN(1, 1): /* DB#1 */ + return IRQ_IXDP2X01_SPCI_DB_1; + } + } else { + /* Device is located indirectly after second MB bridge */ + /* Not supported now */ + } + break; + } + + return -1; +} + + +static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0xe0000000; + + if (machine_is_ixdp2801() || machine_is_ixdp28x5()) + sys->mem_offset -= ((*IXP2000_PCI_ADDR_EXT & 0xE000) << 16); + + return ixp2000_pci_setup(nr, sys); +} + +struct hw_pci ixdp2x01_pci __initdata = { + .nr_controllers = 1, + .setup = ixdp2x01_pci_setup, + .preinit = ixdp2x01_pci_preinit, + .scan = ixp2000_pci_scan_bus, + .map_irq = ixdp2x01_pci_map_irq, +}; + +int __init ixdp2x01_pci_init(void) +{ + if (machine_is_ixdp2401() || machine_is_ixdp2801() ||\ + machine_is_ixdp28x5()) + pci_common_init(&ixdp2x01_pci); + + return 0; +} + +subsys_initcall(ixdp2x01_pci_init); + +/************************************************************************* + * IXDP2x01 Machine Initialization + *************************************************************************/ +static struct flash_platform_data ixdp2x01_flash_platform_data = { + .map_name = "cfi_probe", + .width = 1, +}; + +static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs) +{ + ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG, + ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN)); + return (ofs & IXDP2X01_FLASH_WINDOW_MASK); +} + +static struct ixp2000_flash_data ixdp2x01_flash_data = { + .platform_data = &ixdp2x01_flash_platform_data, + .bank_setup = ixdp2x01_flash_bank_setup +}; + +static struct resource ixdp2x01_flash_resource = { + .start = 0xc4000000, + .end = 0xc4000000 + 0x01ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2x01_flash = { + .name = "IXP2000-Flash", + .id = 0, + .dev = { + .platform_data = &ixdp2x01_flash_data, + }, + .num_resources = 1, + .resource = &ixdp2x01_flash_resource, +}; + +static struct ixp2000_i2c_pins ixdp2x01_i2c_gpio_pins = { + .sda_pin = IXDP2X01_GPIO_SDA, + .scl_pin = IXDP2X01_GPIO_SCL, +}; + +static struct platform_device ixdp2x01_i2c_controller = { + .name = "IXP2000-I2C", + .id = 0, + .dev = { + .platform_data = &ixdp2x01_i2c_gpio_pins, + }, + .num_resources = 0 +}; + +static struct platform_device *ixdp2x01_devices[] __initdata = { + &ixdp2x01_flash, + &ixdp2x01_i2c_controller +}; + +static void __init ixdp2x01_init_machine(void) +{ + ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG, + (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN)); + + ixdp2x01_flash_data.nr_banks = + ((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1); + + platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices)); + ixp2000_uart_init(); + ixdp2x01_uart_init(); +} + +static void ixdp2401_restart(char mode, const char *cmd) +{ + /* + * Reset flash banking register so that we are pointing at + * RedBoot bank. + */ + ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, + ((0 >> IXDP2X01_FLASH_WINDOW_BITS) + | IXDP2X01_CPLD_FLASH_INTERN)); + ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0xffffffff); + + ixp2000_restart(mode, cmd); +} + +static void ixdp280x_restart(char mode, const char *cmd) +{ + /* + * On IXDP2801 we need to write this magic sequence to the CPLD + * to cause a complete reset of the CPU and all external devices + * and move the flash bank register back to 0. + */ + unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG; + + reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF); + ixp2000_reg_write(IXDP2X01_CPLD_RESET_REG, reset_reg); + ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0x80000000); + + ixp2000_restart(mode, cmd); +} + +#ifdef CONFIG_ARCH_IXDP2401 +MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") + /* Maintainer: MontaVista Software, Inc. */ + .atag_offset = 0x100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, + .timer = &ixdp2x01_timer, + .init_machine = ixdp2x01_init_machine, + .restart = ixdp2401_restart, +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_IXDP2801 +MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") + /* Maintainer: MontaVista Software, Inc. */ + .atag_offset = 0x100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, + .timer = &ixdp2x01_timer, + .init_machine = ixdp2x01_init_machine, + .restart = ixdp280x_restart, +MACHINE_END + +/* + * IXDP28x5 is basically an IXDP2801 with a different CPU but Intel + * changed the machine ID in the bootloader + */ +MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform") + /* Maintainer: MontaVista Software, Inc. */ + .atag_offset = 0x100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, + .timer = &ixdp2x01_timer, + .init_machine = ixdp2x01_init_machine, + .restart = ixdp280x_restart, +MACHINE_END +#endif + + diff --git a/trunk/arch/arm/mach-ixp2000/pci.c b/trunk/arch/arm/mach-ixp2000/pci.c new file mode 100644 index 000000000000..9c02de932fac --- /dev/null +++ b/trunk/arch/arm/mach-ixp2000/pci.c @@ -0,0 +1,252 @@ +/* + * arch/arm/mach-ixp2000/pci.c + * + * PCI routines for IXDP2400/IXDP2800 boards + * + * Original Author: Naeem Afzal + * Maintained by: Deepak Saxena + * + * Copyright 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static volatile int pci_master_aborts = 0; + +static int clear_master_aborts(void); + +u32 * +ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) +{ + u32 *paddress; + + if (PCI_SLOT(devfn) > 7) + return 0; + + /* Must be dword aligned */ + where &= ~3; + + /* + * For top bus, generate type 0, else type 1 + */ + if (!bus_nr) { + /* only bits[23:16] are used for IDSEL */ + paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE + | (1 << (PCI_SLOT(devfn) + 16)) + | (PCI_FUNC(devfn) << 8) | where); + } else { + paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE + | (bus_nr << 16) + | (PCI_SLOT(devfn) << 11) + | (PCI_FUNC(devfn) << 8) | where); + } + + return paddress; +} + +/* + * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. + * 0 and 3 are not valid indexes... + */ +static u32 bytemask[] = { + /*0*/ 0, + /*1*/ 0xff, + /*2*/ 0xffff, + /*3*/ 0, + /*4*/ 0xffffffff, +}; + + +int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + u32 n; + u32 *addr; + + n = where % 4; + + addr = ixp2000_pci_config_addr(bus->number, devfn, where); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + + pci_master_aborts = 0; + *value = (*addr >> (8*n)) & bytemask[size]; + if (pci_master_aborts) { + pci_master_aborts = 0; + *value = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return PCIBIOS_SUCCESSFUL; +} + +/* + * We don't do error checks by calling clear_master_aborts() b/c the + * assumption is that the caller did a read first to make sure a device + * exists. + */ +int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + u32 mask; + u32 *addr; + u32 temp; + + mask = ~(bytemask[size] << ((where % 0x4) * 8)); + addr = ixp2000_pci_config_addr(bus->number, devfn, where); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + temp = (u32) (value) << ((where % 0x4) * 8); + *addr = (*addr & mask) | temp; + + clear_master_aborts(); + + return PCIBIOS_SUCCESSFUL; +} + + +static struct pci_ops ixp2000_pci_ops = { + .read = ixp2000_pci_read_config, + .write = ixp2000_pci_write_config +}; + +struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops, + sysdata, &sysdata->resources); +} + + +int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + + volatile u32 temp; + unsigned long flags; + + pci_master_aborts = 1; + + local_irq_save(flags); + temp = *(IXP2000_PCI_CONTROL); + if (temp & ((1 << 8) | (1 << 5))) { + ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp); + } + + temp = *(IXP2000_PCI_CMDSTAT); + if (temp & (1 << 29)) { + while (temp & (1 << 29)) { + ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); + temp = *(IXP2000_PCI_CMDSTAT); + } + } + local_irq_restore(flags); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +int +clear_master_aborts(void) +{ + volatile u32 temp; + unsigned long flags; + + local_irq_save(flags); + temp = *(IXP2000_PCI_CONTROL); + if (temp & ((1 << 8) | (1 << 5))) { + ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp); + } + + temp = *(IXP2000_PCI_CMDSTAT); + if (temp & (1 << 29)) { + while (temp & (1 << 29)) { + ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); + temp = *(IXP2000_PCI_CMDSTAT); + } + } + local_irq_restore(flags); + + return 0; +} + +void __init +ixp2000_pci_preinit(void) +{ + pci_set_flags(0); + + pcibios_min_io = 0; + pcibios_min_mem = 0; + +#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO + /* + * Configure the PCI unit to properly byteswap I/O transactions, + * and verify that it worked. + */ + ixp2000_reg_write(IXP2000_PCI_CONTROL, + (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE)); + + if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0) + panic("IXP2000: PCI I/O is broken on this ixp model, and " + "the needed workaround has not been configured in"); +#endif + + hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0, + "PCI config cycle to non-existent device"); +} + + +/* + * IXP2000 systems often have large resource requirements, so we just + * use our own resource space. + */ +static struct resource ixp2000_pci_mem_space = { + .start = 0xe0000000, + .end = 0xffffffff, + .flags = IORESOURCE_MEM, + .name = "PCI Mem Space" +}; + +static struct resource ixp2000_pci_io_space = { + .start = 0x00010000, + .end = 0x0001ffff, + .flags = IORESOURCE_IO, + .name = "PCI I/O Space" +}; + +int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) +{ + if (nr >= 1) + return 0; + + pci_add_resource_offset(&sys->resources, + &ixp2000_pci_io_space, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &ixp2000_pci_mem_space, sys->mem_offset); + + return 1; +} + diff --git a/trunk/arch/arm/mach-ixp23xx/Kconfig b/trunk/arch/arm/mach-ixp23xx/Kconfig new file mode 100644 index 000000000000..982670ec3866 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/Kconfig @@ -0,0 +1,25 @@ +if ARCH_IXP23XX + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + default y + +menu "Intel IXP23xx Implementation Options" + +comment "IXP23xx Platforms" + +config MACH_ESPRESSO + bool "Support IP Fabrics Double Espresso platform" + help + +config MACH_IXDP2351 + bool "Support Intel IXDP2351 platform" + help + +config MACH_ROADRUNNER + bool "Support ADI RoadRunner platform" + help + +endmenu + +endif diff --git a/trunk/arch/arm/mach-ixp23xx/Makefile b/trunk/arch/arm/mach-ixp23xx/Makefile new file mode 100644 index 000000000000..288b371b6d03 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# +obj-y := core.o pci.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_MACH_ESPRESSO) += espresso.o +obj-$(CONFIG_MACH_IXDP2351) += ixdp2351.o +obj-$(CONFIG_MACH_ROADRUNNER) += roadrunner.o diff --git a/trunk/arch/arm/mach-ixp23xx/Makefile.boot b/trunk/arch/arm/mach-ixp23xx/Makefile.boot new file mode 100644 index 000000000000..44fb4a717c3f --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y += 0x00008000 +params_phys-y := 0x00000100 diff --git a/trunk/arch/arm/mach-ixp23xx/core.c b/trunk/arch/arm/mach-ixp23xx/core.c new file mode 100644 index 000000000000..d34542425990 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/core.c @@ -0,0 +1,455 @@ +/* + * arch/arm/mach-ixp23xx/core.c + * + * Core routines for IXP23xx chips + * + * Author: Deepak Saxena + * + * Copyright 2005 (c) MontaVista Software, Inc. + * + * Based on 2.4 code Copyright 2004 (c) Intel Corporation + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +/************************************************************************* + * Chip specific mappings shared by all IXP23xx systems + *************************************************************************/ +static struct map_desc ixp23xx_io_desc[] __initdata = { + { /* XSI-CPP CSRs */ + .virtual = IXP23XX_XSI2CPP_CSR_VIRT, + .pfn = __phys_to_pfn(IXP23XX_XSI2CPP_CSR_PHYS), + .length = IXP23XX_XSI2CPP_CSR_SIZE, + .type = MT_DEVICE, + }, { /* Expansion Bus Config */ + .virtual = IXP23XX_EXP_CFG_VIRT, + .pfn = __phys_to_pfn(IXP23XX_EXP_CFG_PHYS), + .length = IXP23XX_EXP_CFG_SIZE, + .type = MT_DEVICE, + }, { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACS,.... */ + .virtual = IXP23XX_PERIPHERAL_VIRT, + .pfn = __phys_to_pfn(IXP23XX_PERIPHERAL_PHYS), + .length = IXP23XX_PERIPHERAL_SIZE, + .type = MT_DEVICE, + }, { /* CAP CSRs */ + .virtual = IXP23XX_CAP_CSR_VIRT, + .pfn = __phys_to_pfn(IXP23XX_CAP_CSR_PHYS), + .length = IXP23XX_CAP_CSR_SIZE, + .type = MT_DEVICE, + }, { /* MSF CSRs */ + .virtual = IXP23XX_MSF_CSR_VIRT, + .pfn = __phys_to_pfn(IXP23XX_MSF_CSR_PHYS), + .length = IXP23XX_MSF_CSR_SIZE, + .type = MT_DEVICE, + }, { /* PCI I/O Space */ + .virtual = IXP23XX_PCI_IO_VIRT, + .pfn = __phys_to_pfn(IXP23XX_PCI_IO_PHYS), + .length = IXP23XX_PCI_IO_SIZE, + .type = MT_DEVICE, + }, { /* PCI Config Space */ + .virtual = IXP23XX_PCI_CFG_VIRT, + .pfn = __phys_to_pfn(IXP23XX_PCI_CFG_PHYS), + .length = IXP23XX_PCI_CFG_SIZE, + .type = MT_DEVICE, + }, { /* PCI local CFG CSRs */ + .virtual = IXP23XX_PCI_CREG_VIRT, + .pfn = __phys_to_pfn(IXP23XX_PCI_CREG_PHYS), + .length = IXP23XX_PCI_CREG_SIZE, + .type = MT_DEVICE, + }, { /* PCI MEM Space */ + .virtual = IXP23XX_PCI_MEM_VIRT, + .pfn = __phys_to_pfn(IXP23XX_PCI_MEM_PHYS), + .length = IXP23XX_PCI_MEM_SIZE, + .type = MT_DEVICE, + } +}; + +void __init ixp23xx_map_io(void) +{ + iotable_init(ixp23xx_io_desc, ARRAY_SIZE(ixp23xx_io_desc)); +} + + +/*************************************************************************** + * IXP23xx Interrupt Handling + ***************************************************************************/ +enum ixp23xx_irq_type { + IXP23XX_IRQ_LEVEL, IXP23XX_IRQ_EDGE +}; + +static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type); + +static int ixp23xx_irq_set_type(struct irq_data *d, unsigned int type) +{ + int line = d->irq - IRQ_IXP23XX_GPIO6 + 6; + u32 int_style; + enum ixp23xx_irq_type irq_type; + volatile u32 *int_reg; + + /* + * Only GPIOs 6-15 are wired to interrupts on IXP23xx + */ + if (line < 6 || line > 15) + return -EINVAL; + + switch (type) { + case IRQ_TYPE_EDGE_BOTH: + int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL; + irq_type = IXP23XX_IRQ_EDGE; + break; + case IRQ_TYPE_EDGE_RISING: + int_style = IXP23XX_GPIO_STYLE_RISING_EDGE; + irq_type = IXP23XX_IRQ_EDGE; + break; + case IRQ_TYPE_EDGE_FALLING: + int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE; + irq_type = IXP23XX_IRQ_EDGE; + break; + case IRQ_TYPE_LEVEL_HIGH: + int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH; + irq_type = IXP23XX_IRQ_LEVEL; + break; + case IRQ_TYPE_LEVEL_LOW: + int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW; + irq_type = IXP23XX_IRQ_LEVEL; + break; + default: + return -EINVAL; + } + + ixp23xx_config_irq(d->irq, irq_type); + + if (line >= 8) { /* pins 8-15 */ + line -= 8; + int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT2R; + } else { /* pins 0-7 */ + int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT1R; + } + + /* + * Clear pending interrupts + */ + *IXP23XX_GPIO_GPISR = (1 << line); + + /* Clear the style for the appropriate pin */ + *int_reg &= ~(IXP23XX_GPIO_STYLE_MASK << + (line * IXP23XX_GPIO_STYLE_SIZE)); + + /* Set the new style */ + *int_reg |= (int_style << (line * IXP23XX_GPIO_STYLE_SIZE)); + + return 0; +} + +static void ixp23xx_irq_mask(struct irq_data *d) +{ + volatile unsigned long *intr_reg; + unsigned int irq = d->irq; + + if (irq >= 56) + irq += 8; + + intr_reg = IXP23XX_INTR_EN1 + (irq / 32); + *intr_reg &= ~(1 << (irq % 32)); +} + +static void ixp23xx_irq_ack(struct irq_data *d) +{ + int line = d->irq - IRQ_IXP23XX_GPIO6 + 6; + + if ((line < 6) || (line > 15)) + return; + + *IXP23XX_GPIO_GPISR = (1 << line); +} + +/* + * Level triggered interrupts on GPIO lines can only be cleared when the + * interrupt condition disappears. + */ +static void ixp23xx_irq_level_unmask(struct irq_data *d) +{ + volatile unsigned long *intr_reg; + unsigned int irq = d->irq; + + ixp23xx_irq_ack(d); + + if (irq >= 56) + irq += 8; + + intr_reg = IXP23XX_INTR_EN1 + (irq / 32); + *intr_reg |= (1 << (irq % 32)); +} + +static void ixp23xx_irq_edge_unmask(struct irq_data *d) +{ + volatile unsigned long *intr_reg; + unsigned int irq = d->irq; + + if (irq >= 56) + irq += 8; + + intr_reg = IXP23XX_INTR_EN1 + (irq / 32); + *intr_reg |= (1 << (irq % 32)); +} + +static struct irq_chip ixp23xx_irq_level_chip = { + .irq_ack = ixp23xx_irq_mask, + .irq_mask = ixp23xx_irq_mask, + .irq_unmask = ixp23xx_irq_level_unmask, + .irq_set_type = ixp23xx_irq_set_type +}; + +static struct irq_chip ixp23xx_irq_edge_chip = { + .irq_ack = ixp23xx_irq_ack, + .irq_mask = ixp23xx_irq_mask, + .irq_unmask = ixp23xx_irq_edge_unmask, + .irq_set_type = ixp23xx_irq_set_type +}; + +static void ixp23xx_pci_irq_mask(struct irq_data *d) +{ + unsigned int irq = d->irq; + + *IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq)); +} + +static void ixp23xx_pci_irq_unmask(struct irq_data *d) +{ + unsigned int irq = d->irq; + + *IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq)); +} + +/* + * TODO: Should this just be done at ASM level? + */ +static void pci_handler(unsigned int irq, struct irq_desc *desc) +{ + u32 pci_interrupt; + unsigned int irqno; + + pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS; + + desc->irq_data.chip->irq_ack(&desc->irq_data); + + /* See which PCI_INTA, or PCI_INTB interrupted */ + if (pci_interrupt & (1 << 26)) { + irqno = IRQ_IXP23XX_INTB; + } else if (pci_interrupt & (1 << 27)) { + irqno = IRQ_IXP23XX_INTA; + } else { + BUG(); + } + + generic_handle_irq(irqno); + + desc->irq_data.chip->irq_unmask(&desc->irq_data); +} + +static struct irq_chip ixp23xx_pci_irq_chip = { + .irq_ack = ixp23xx_pci_irq_mask, + .irq_mask = ixp23xx_pci_irq_mask, + .irq_unmask = ixp23xx_pci_irq_unmask +}; + +static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type) +{ + switch (type) { + case IXP23XX_IRQ_LEVEL: + irq_set_chip_and_handler(irq, &ixp23xx_irq_level_chip, + handle_level_irq); + break; + case IXP23XX_IRQ_EDGE: + irq_set_chip_and_handler(irq, &ixp23xx_irq_edge_chip, + handle_edge_irq); + break; + } + set_irq_flags(irq, IRQF_VALID); +} + +void __init ixp23xx_init_irq(void) +{ + int irq; + + /* Route everything to IRQ */ + *IXP23XX_INTR_SEL1 = 0x0; + *IXP23XX_INTR_SEL2 = 0x0; + *IXP23XX_INTR_SEL3 = 0x0; + *IXP23XX_INTR_SEL4 = 0x0; + + /* Mask all sources */ + *IXP23XX_INTR_EN1 = 0x0; + *IXP23XX_INTR_EN2 = 0x0; + *IXP23XX_INTR_EN3 = 0x0; + *IXP23XX_INTR_EN4 = 0x0; + + /* + * Configure all IRQs for level-sensitive operation + */ + for (irq = 0; irq <= NUM_IXP23XX_RAW_IRQS; irq++) { + ixp23xx_config_irq(irq, IXP23XX_IRQ_LEVEL); + } + + for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) { + irq_set_chip_and_handler(irq, &ixp23xx_pci_irq_chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + + irq_set_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler); +} + + +/************************************************************************* + * Timer-tick functions for IXP23xx + *************************************************************************/ +#define CLOCK_TICKS_PER_USEC (CLOCK_TICK_RATE / USEC_PER_SEC) + +static unsigned long next_jiffy_time; + +static unsigned long +ixp23xx_gettimeoffset(void) +{ + unsigned long elapsed; + + elapsed = *IXP23XX_TIMER_CONT - (next_jiffy_time - LATCH); + + return elapsed / CLOCK_TICKS_PER_USEC; +} + +static irqreturn_t +ixp23xx_timer_interrupt(int irq, void *dev_id) +{ + /* Clear Pending Interrupt by writing '1' to it */ + *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND; + while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) { + timer_tick(); + next_jiffy_time += LATCH; + } + + return IRQ_HANDLED; +} + +static struct irqaction ixp23xx_timer_irq = { + .name = "IXP23xx Timer Tick", + .handler = ixp23xx_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, +}; + +void __init ixp23xx_init_timer(void) +{ + /* Clear Pending Interrupt by writing '1' to it */ + *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND; + + /* Setup the Timer counter value */ + *IXP23XX_TIMER1_RELOAD = + (LATCH & ~IXP23XX_TIMER_RELOAD_MASK) | IXP23XX_TIMER_ENABLE; + + *IXP23XX_TIMER_CONT = 0; + next_jiffy_time = LATCH; + + /* Connect the interrupt handler and enable the interrupt */ + setup_irq(IRQ_IXP23XX_TIMER1, &ixp23xx_timer_irq); +} + +struct sys_timer ixp23xx_timer = { + .init = ixp23xx_init_timer, + .offset = ixp23xx_gettimeoffset, +}; + + +/************************************************************************* + * IXP23xx Platform Initialization + *************************************************************************/ +static struct resource ixp23xx_uart_resources[] = { + { + .start = IXP23XX_UART1_PHYS, + .end = IXP23XX_UART1_PHYS + 0x0fff, + .flags = IORESOURCE_MEM + }, { + .start = IXP23XX_UART2_PHYS, + .end = IXP23XX_UART2_PHYS + 0x0fff, + .flags = IORESOURCE_MEM + } +}; + +static struct plat_serial8250_port ixp23xx_uart_data[] = { + { + .mapbase = IXP23XX_UART1_PHYS, + .membase = (char *)(IXP23XX_UART1_VIRT + 3), + .irq = IRQ_IXP23XX_UART1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP23XX_UART_XTAL, + }, { + .mapbase = IXP23XX_UART2_PHYS, + .membase = (char *)(IXP23XX_UART2_VIRT + 3), + .irq = IRQ_IXP23XX_UART2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP23XX_UART_XTAL, + }, + { }, +}; + +static struct platform_device ixp23xx_uart = { + .name = "serial8250", + .id = 0, + .dev.platform_data = ixp23xx_uart_data, + .num_resources = 2, + .resource = ixp23xx_uart_resources, +}; + +static struct platform_device *ixp23xx_devices[] __initdata = { + &ixp23xx_uart, +}; + +void __init ixp23xx_sys_init(void) +{ + /* by default, the idle code is disabled */ + disable_hlt(); + + *IXP23XX_EXP_UNIT_FUSE |= 0xf; + platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices)); +} + +void ixp23xx_restart(char mode, const char *cmd) +{ + /* Use on-chip reset capability */ + *IXP23XX_RESET0 |= IXP23XX_RST_ALL; +} diff --git a/trunk/arch/arm/mach-ixp23xx/espresso.c b/trunk/arch/arm/mach-ixp23xx/espresso.c new file mode 100644 index 000000000000..d142d45dea12 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/espresso.c @@ -0,0 +1,93 @@ +/* + * arch/arm/mach-ixp23xx/espresso.c + * + * Double Espresso-specific routines + * + * Author: Lennert Buytenhek + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static int __init espresso_pci_init(void) +{ + if (machine_is_espresso()) + ixp23xx_pci_slave_init(); + + return 0; +}; +subsys_initcall(espresso_pci_init); + +static struct physmap_flash_data espresso_flash_data = { + .width = 2, +}; + +static struct resource espresso_flash_resource = { + .start = 0x90000000, + .end = 0x91ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device espresso_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &espresso_flash_data, + }, + .num_resources = 1, + .resource = &espresso_flash_resource, +}; + +static void __init espresso_init(void) +{ + platform_device_register(&espresso_flash); + + /* + * Mark flash as writeable. + */ + IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE; + + ixp23xx_sys_init(); +} + +MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso") + /* Maintainer: Lennert Buytenhek */ + .map_io = ixp23xx_map_io, + .init_irq = ixp23xx_init_irq, + .timer = &ixp23xx_timer, + .atag_offset = 0x100, + .init_machine = espresso_init, + .restart = ixp23xx_restart, +MACHINE_END diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/debug-macro.S b/trunk/arch/arm/mach-ixp23xx/include/mach/debug-macro.S new file mode 100644 index 000000000000..5ff524c13744 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/debug-macro.S @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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. + */ +#include + + .macro addruart, rp, rv, tmp + ldr \rp, =IXP23XX_PERIPHERAL_PHYS @ physical + ldr \rv, =IXP23XX_PERIPHERAL_VIRT @ virtual +#ifdef __ARMEB__ + orr \rp, \rp, #0x00000003 + orr \rv, \rv, #0x00000003 +#endif + .endm + +#define UART_SHIFT 2 +#include diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/entry-macro.S b/trunk/arch/arm/mach-ixp23xx/include/mach/entry-macro.S new file mode 100644 index 000000000000..3fd2cb984e42 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/entry-macro.S @@ -0,0 +1,31 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/entry-macro.S + */ + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET) + ldr \irqnr, [\irqnr] @ get interrupt number + cmp \irqnr, #0x0 @ spurious interrupt ? + movne \irqnr, \irqnr, lsr #2 @ skip unwanted low order bits + subne \irqnr, \irqnr, #1 @ convert to 0 based + +#if 0 + cmp \irqnr, #IRQ_IXP23XX_PCI_INT_RPH + bne 1001f + mov \irqnr, #IRQ_IXP23XX_INTA + + ldr \irqnr, =0xf5000030 + + mov \tmp, #(1<<26) + tst \irqnr, \tmp + movne \irqnr, #IRQ_IXP23XX_INTB + + mov \tmp, #(1<<27) + tst \irqnr, \tmp + movne \irqnr, #IRQ_IXP23XX_INTA +1001: +#endif + .endm diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/hardware.h b/trunk/arch/arm/mach-ixp23xx/include/mach/hardware.h new file mode 100644 index 000000000000..60e55fa10238 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/hardware.h @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/hardware.h + * + * Copyright (C) 2002-2004 Intel Corporation. + * Copyricht (C) 2005 MontaVista Software, Inc. + * + * 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. + * + * Hardware definitions for IXP23XX based systems + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* PCI IO info */ + +#include "ixp23xx.h" + +/* + * Platform helper functions + */ +#include "platform.h" + +/* + * Platform-specific headers + */ +#include "ixdp2351.h" + + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/io.h b/trunk/arch/arm/mach-ixp23xx/include/mach/io.h new file mode 100644 index 000000000000..a7aceb55c130 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/io.h @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/io.h + * + * Original Author: Naeem M Afzal + * Maintainer: Deepak Saxena + * + * Copyright (C) 2003-2005 Intel Corp. + * Copyright (C) 2005 MontaVista Software, Inc + * + * 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_ARCH_IO_H +#define __ASM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(p) ((void __iomem*)((p) + IXP23XX_PCI_IO_VIRT)) + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/irqs.h b/trunk/arch/arm/mach-ixp23xx/include/mach/irqs.h new file mode 100644 index 000000000000..3af33a04b8a2 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/irqs.h @@ -0,0 +1,223 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/irqs.h + * + * IRQ definitions for IXP23XX based systems + * + * Author: Naeem Afzal + * + * Copyright (C) 2003-2004 Intel Corporation. + * + * 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_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H + +#define NR_IXP23XX_IRQS IRQ_IXP23XX_INTB+1 +#define IRQ_IXP23XX_EXTIRQS NR_IXP23XX_IRQS + + +#define IRQ_IXP23XX_DBG0 0 /* Debug/Execution/MBox */ +#define IRQ_IXP23XX_DBG1 1 /* Debug/Execution/MBox */ +#define IRQ_IXP23XX_NPE_TRG 2 /* npe_trigger */ +#define IRQ_IXP23XX_TIMER1 3 /* Timer[0] */ +#define IRQ_IXP23XX_TIMER2 4 /* Timer[1] */ +#define IRQ_IXP23XX_TIMESTAMP 5 /* Timer[2], Time-stamp */ +#define IRQ_IXP23XX_WDOG 6 /* Time[3], Watchdog Timer */ +#define IRQ_IXP23XX_PCI_DBELL 7 /* PCI Doorbell */ +#define IRQ_IXP23XX_PCI_DMA1 8 /* PCI DMA Channel 1 */ +#define IRQ_IXP23XX_PCI_DMA2 9 /* PCI DMA Channel 2 */ +#define IRQ_IXP23XX_PCI_DMA3 10 /* PCI DMA Channel 3 */ +#define IRQ_IXP23XX_PCI_INT_RPH 11 /* pcxg_pci_int_rph */ +#define IRQ_IXP23XX_CPP_PMU 12 /* xpxg_pm_int_rpl */ +#define IRQ_IXP23XX_SWINT0 13 /* S/W Interrupt0 */ +#define IRQ_IXP23XX_SWINT1 14 /* S/W Interrupt1 */ +#define IRQ_IXP23XX_UART2 15 /* UART1 Interrupt */ +#define IRQ_IXP23XX_UART1 16 /* UART0 Interrupt */ +#define IRQ_IXP23XX_XSI_PMU_ROLLOVER 17 /* AHB Performance M. Unit counter rollover */ +#define IRQ_IXP23XX_XSI_AHB_PM0 18 /* intr_pm_o */ +#define IRQ_IXP23XX_XSI_AHB_ECE0 19 /* intr_ece_o */ +#define IRQ_IXP23XX_XSI_AHB_GASKET 20 /* gas_intr_o */ +#define IRQ_IXP23XX_XSI_CPP 21 /* xsi2cpp_int */ +#define IRQ_IXP23XX_CPP_XSI 22 /* cpp2xsi_int */ +#define IRQ_IXP23XX_ME_ATTN0 23 /* ME_ATTN */ +#define IRQ_IXP23XX_ME_ATTN1 24 /* ME_ATTN */ +#define IRQ_IXP23XX_ME_ATTN2 25 /* ME_ATTN */ +#define IRQ_IXP23XX_ME_ATTN3 26 /* ME_ATTN */ +#define IRQ_IXP23XX_PCI_ERR_RPH 27 /* PCXG_PCI_ERR_RPH */ +#define IRQ_IXP23XX_D0XG_ECC_CORR 28 /* D0XG_DRAM_ECC_CORR */ +#define IRQ_IXP23XX_D0XG_ECC_UNCORR 29 /* D0XG_DRAM_ECC_UNCORR */ +#define IRQ_IXP23XX_SRAM_ERR1 30 /* SRAM1_ERR */ +#define IRQ_IXP23XX_SRAM_ERR0 31 /* SRAM0_ERR */ +#define IRQ_IXP23XX_MEDIA_ERR 32 /* MEDIA_ERR */ +#define IRQ_IXP23XX_STH_DRAM_ECC_MAJ 33 /* STH_DRAM0_ECC_MAJ */ +#define IRQ_IXP23XX_GPIO6 34 /* GPIO0 interrupts */ +#define IRQ_IXP23XX_GPIO7 35 /* GPIO1 interrupts */ +#define IRQ_IXP23XX_GPIO8 36 /* GPIO2 interrupts */ +#define IRQ_IXP23XX_GPIO9 37 /* GPIO3 interrupts */ +#define IRQ_IXP23XX_GPIO10 38 /* GPIO4 interrupts */ +#define IRQ_IXP23XX_GPIO11 39 /* GPIO5 interrupts */ +#define IRQ_IXP23XX_GPIO12 40 /* GPIO6 interrupts */ +#define IRQ_IXP23XX_GPIO13 41 /* GPIO7 interrupts */ +#define IRQ_IXP23XX_GPIO14 42 /* GPIO8 interrupts */ +#define IRQ_IXP23XX_GPIO15 43 /* GPIO9 interrupts */ +#define IRQ_IXP23XX_SHAC_RING0 44 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING1 45 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING2 46 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING3 47 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING4 48 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING5 49 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING6 50 /* SHAC RING Full */ +#define IRQ_IXP23XX_SHAC_RING7 51 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING8 52 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING9 53 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING10 54 /* SHAC Ring Full */ +#define IRQ_IXP23XX_SHAC_RING11 55 /* SHAC Ring Full */ +#define IRQ_IXP23XX_ME_THREAD_A0_ME0 56 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A1_ME0 57 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A2_ME0 58 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A3_ME0 59 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A4_ME0 60 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A5_ME0 61 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A6_ME0 62 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A7_ME0 63 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A8_ME1 64 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A9_ME1 65 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A10_ME1 66 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A11_ME1 67 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A12_ME1 68 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A13_ME1 69 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A14_ME1 70 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A15_ME1 71 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A16_ME2 72 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A17_ME2 73 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A18_ME2 74 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A19_ME2 75 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A20_ME2 76 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A21_ME2 77 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A22_ME2 78 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A23_ME2 79 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A24_ME3 80 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A25_ME3 81 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A26_ME3 82 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A27_ME3 83 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A28_ME3 84 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A29_ME3 85 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A30_ME3 86 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_A31_ME3 87 /* ME_THREAD_A */ +#define IRQ_IXP23XX_ME_THREAD_B0_ME0 88 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B1_ME0 89 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B2_ME0 90 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B3_ME0 91 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B4_ME0 92 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B5_ME0 93 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B6_ME0 94 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B7_ME0 95 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B8_ME1 96 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B9_ME1 97 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B10_ME1 98 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B11_ME1 99 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B12_ME1 100 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B13_ME1 101 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B14_ME1 102 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B15_ME1 103 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B16_ME2 104 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B17_ME2 105 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B18_ME2 106 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B19_ME2 107 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B20_ME2 108 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B21_ME2 109 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B22_ME2 110 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B23_ME2 111 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B24_ME3 112 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B25_ME3 113 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B26_ME3 114 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B27_ME3 115 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B28_ME3 116 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B29_ME3 117 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B30_ME3 118 /* ME_THREAD_B */ +#define IRQ_IXP23XX_ME_THREAD_B31_ME3 119 /* ME_THREAD_B */ + +#define NUM_IXP23XX_RAW_IRQS 120 + +#define IRQ_IXP23XX_INTA 120 /* Indirect pcxg_pci_int_rph */ +#define IRQ_IXP23XX_INTB 121 /* Indirect pcxg_pci_int_rph */ + +#define NR_IXP23XX_IRQ (IRQ_IXP23XX_INTB + 1) + +/* + * We default to 32 per-board IRQs. Increase this number if you need + * more, but keep it realistic. + */ +#define NR_IXP23XX_MACH_IRQS 32 + +#define NR_IRQS (NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS) + +#define IXP23XX_MACH_IRQ(irq) (NR_IXP23XX_IRQ + (irq)) + + +/* + * IXDP2351-specific interrupts + */ + +/* + * External PCI interrupts signaled through INTB + * + */ +#define IXDP2351_INTB_IRQ_BASE 0 +#define IRQ_IXDP2351_INTA_82546 IXP23XX_MACH_IRQ(0) +#define IRQ_IXDP2351_INTB_82546 IXP23XX_MACH_IRQ(1) +#define IRQ_IXDP2351_SPCI_DB_0 IXP23XX_MACH_IRQ(2) +#define IRQ_IXDP2351_SPCI_DB_1 IXP23XX_MACH_IRQ(3) +#define IRQ_IXDP2351_SPCI_PMC_INTA IXP23XX_MACH_IRQ(4) +#define IRQ_IXDP2351_SPCI_PMC_INTB IXP23XX_MACH_IRQ(5) +#define IRQ_IXDP2351_SPCI_PMC_INTC IXP23XX_MACH_IRQ(6) +#define IRQ_IXDP2351_SPCI_PMC_INTD IXP23XX_MACH_IRQ(7) +#define IRQ_IXDP2351_SPCI_FIC IXP23XX_MACH_IRQ(8) + +#define IXDP2351_INTB_IRQ_BIT(irq) (irq - IXP23XX_MACH_IRQ(0)) +#define IXDP2351_INTB_IRQ_MASK(irq) (1 << IXDP2351_INTB_IRQ_BIT(irq)) +#define IXDP2351_INTB_IRQ_VALID 0x01FF +#define IXDP2351_INTB_IRQ_NUM 16 + +/* + * Other external interrupts signaled through INTA + */ +#define IXDP2351_INTA_IRQ_BASE 16 +#define IRQ_IXDP2351_IPMI_FROM IXP23XX_MACH_IRQ(16) +#define IRQ_IXDP2351_125US IXP23XX_MACH_IRQ(17) +#define IRQ_IXDP2351_DB_0_ADD IXP23XX_MACH_IRQ(18) +#define IRQ_IXDP2351_DB_1_ADD IXP23XX_MACH_IRQ(19) +#define IRQ_IXDP2351_DEBUG1 IXP23XX_MACH_IRQ(20) +#define IRQ_IXDP2351_ADD_UART IXP23XX_MACH_IRQ(21) +#define IRQ_IXDP2351_FIC_ADD IXP23XX_MACH_IRQ(24) +#define IRQ_IXDP2351_CS8900 IXP23XX_MACH_IRQ(25) +#define IRQ_IXDP2351_BBSRAM IXP23XX_MACH_IRQ(26) +#define IRQ_IXDP2351_CONFIG_MEDIA IXP23XX_MACH_IRQ(27) +#define IRQ_IXDP2351_CLOCK_REF IXP23XX_MACH_IRQ(28) +#define IRQ_IXDP2351_A10_NP IXP23XX_MACH_IRQ(29) +#define IRQ_IXDP2351_A11_NP IXP23XX_MACH_IRQ(30) +#define IRQ_IXDP2351_DEBUG_NP IXP23XX_MACH_IRQ(31) + +#define IXDP2351_INTA_IRQ_BIT(irq) (irq - IXP23XX_MACH_IRQ(16)) +#define IXDP2351_INTA_IRQ_MASK(irq) (1 << IXDP2351_INTA_IRQ_BIT(irq)) +#define IXDP2351_INTA_IRQ_VALID 0xFF3F +#define IXDP2351_INTA_IRQ_NUM 16 + + +/* + * ADI RoadRunner IRQs + */ +#define IRQ_ROADRUNNER_PCI_INTA IRQ_IXP23XX_INTA +#define IRQ_ROADRUNNER_PCI_INTB IRQ_IXP23XX_INTB +#define IRQ_ROADRUNNER_PCI_INTC IRQ_IXP23XX_GPIO11 +#define IRQ_ROADRUNNER_PCI_INTD IRQ_IXP23XX_GPIO12 + +/* + * Put new board definitions here + */ + + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/ixdp2351.h b/trunk/arch/arm/mach-ixp23xx/include/mach/ixdp2351.h new file mode 100644 index 000000000000..663951027de5 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/ixdp2351.h @@ -0,0 +1,89 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/ixdp2351.h + * + * Register and other defines for IXDP2351 + * + * Copyright (c) 2002-2004 Intel Corp. + * Copytight (c) 2005 MontaVista Software, Inc. + * + * 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. + */ + +#ifndef __ASM_ARCH_IXDP2351_H +#define __ASM_ARCH_IXDP2351_H + +/* + * NP module memory map + */ +#define IXDP2351_NP_PHYS_BASE (IXP23XX_EXP_BUS_CS4_BASE) +#define IXDP2351_NP_PHYS_SIZE 0x00100000 +#define IXDP2351_NP_VIRT_BASE 0xeff00000 + +#define IXDP2351_VIRT_CS8900_BASE (IXDP2351_NP_VIRT_BASE) +#define IXDP2351_VIRT_CS8900_END (IXDP2351_VIRT_CS8900_BASE + 16) + +#define IXDP2351_VIRT_NP_CPLD_BASE (IXP23XX_EXP_BUS_CS4_BASE_VIRT + 0x00010000) + +#define IXDP2351_NP_CPLD_REG(reg) ((volatile u16 *)(IXDP2351_VIRT_NP_CPLD_BASE + reg)) + +#define IXDP2351_NP_CPLD_RESET1_REG IXDP2351_NP_CPLD_REG(0x00) +#define IXDP2351_NP_CPLD_LED_REG IXDP2351_NP_CPLD_REG(0x02) +#define IXDP2351_NP_CPLD_VERSION_REG IXDP2351_NP_CPLD_REG(0x04) + +/* + * Base board module memory map + */ + +#define IXDP2351_BB_BASE_PHYS (IXP23XX_EXP_BUS_CS5_BASE) +#define IXDP2351_BB_SIZE 0x01000000 +#define IXDP2351_BB_BASE_VIRT (0xee000000) + +#define IXDP2351_BB_AREA_BASE(offset) (IXDP2351_BB_BASE_VIRT + offset) + +#define IXDP2351_VIRT_NVRAM_BASE IXDP2351_BB_AREA_BASE(0x0) +#define IXDP2351_NVRAM_SIZE (0x20000) + +#define IXDP2351_VIRT_MB_IXF1104_BASE IXDP2351_BB_AREA_BASE(0x00020000) +#define IXDP2351_VIRT_ADD_UART_BASE IXDP2351_BB_AREA_BASE(0x000240C0) +#define IXDP2351_VIRT_FIC_BASE IXDP2351_BB_AREA_BASE(0x00200000) +#define IXDP2351_VIRT_DB0_BASE IXDP2351_BB_AREA_BASE(0x00400000) +#define IXDP2351_VIRT_DB1_BASE IXDP2351_BB_AREA_BASE(0x00600000) +#define IXDP2351_VIRT_CPLD_BASE IXDP2351_BB_AREA_BASE(0x00024000) + +/* + * On board CPLD registers + */ +#define IXDP2351_CPLD_BB_REG(reg) ((volatile u16 *)(IXDP2351_VIRT_CPLD_BASE + reg)) + +#define IXDP2351_CPLD_RESET0_REG IXDP2351_CPLD_BB_REG(0x00) +#define IXDP2351_CPLD_RESET1_REG IXDP2351_CPLD_BB_REG(0x04) + +#define IXDP2351_CPLD_RESET1_MAGIC 0x55AA +#define IXDP2351_CPLD_RESET1_ENABLE 0x8000 + +#define IXDP2351_CPLD_FPGA_CONFIG_REG IXDP2351_CPLD_BB_REG(0x08) +#define IXDP2351_CPLD_INTB_MASK_SET_REG IXDP2351_CPLD_BB_REG(0x10) +#define IXDP2351_CPLD_INTA_MASK_SET_REG IXDP2351_CPLD_BB_REG(0x14) +#define IXDP2351_CPLD_INTB_STAT_REG IXDP2351_CPLD_BB_REG(0x18) +#define IXDP2351_CPLD_INTA_STAT_REG IXDP2351_CPLD_BB_REG(0x1C) +#define IXDP2351_CPLD_INTB_RAW_REG IXDP2351_CPLD_BB_REG(0x20) /* read */ +#define IXDP2351_CPLD_INTA_RAW_REG IXDP2351_CPLD_BB_REG(0x24) /* read */ +#define IXDP2351_CPLD_INTB_MASK_CLR_REG IXDP2351_CPLD_INTB_RAW_REG /* write */ +#define IXDP2351_CPLD_INTA_MASK_CLR_REG IXDP2351_CPLD_INTA_RAW_REG /* write */ +#define IXDP2351_CPLD_INTB_SIM_REG IXDP2351_CPLD_BB_REG(0x28) +#define IXDP2351_CPLD_INTA_SIM_REG IXDP2351_CPLD_BB_REG(0x2C) + /* Interrupt bits are defined in irqs.h */ +#define IXDP2351_CPLD_BB_GBE0_REG IXDP2351_CPLD_BB_REG(0x30) +#define IXDP2351_CPLD_BB_GBE1_REG IXDP2351_CPLD_BB_REG(0x34) + +/* #define IXDP2351_CPLD_BB_MISC_REG IXDP2351_CPLD_REG(0x1C) */ +/* #define IXDP2351_CPLD_BB_MISC_REV_MASK 0xFF */ +/* #define IXDP2351_CPLD_BB_GDXCS0_REG IXDP2351_CPLD_REG(0x24) */ +/* #define IXDP2351_CPLD_BB_GDXCS1_REG IXDP2351_CPLD_REG(0x28) */ +/* #define IXDP2351_CPLD_BB_CLOCK_REG IXDP2351_CPLD_REG(0x04) */ + + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/ixp23xx.h b/trunk/arch/arm/mach-ixp23xx/include/mach/ixp23xx.h new file mode 100644 index 000000000000..6d02481b1d6d --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/ixp23xx.h @@ -0,0 +1,298 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/ixp23xx.h + * + * Register definitions for IXP23XX + * + * Copyright (C) 2003-2005 Intel Corporation. + * Copyright (C) 2005 MontaVista Software, Inc. + * + * Maintainer: Deepak Saxena + * + * 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_ARCH_IXP23XX_H +#define __ASM_ARCH_IXP23XX_H + +/* + * IXP2300 linux memory map: + * + * virt phys size + * fffd0000 a0000000 64K XSI2CPP_CSR + * fffc0000 c4000000 4K EXP_CFG + * fff00000 c8000000 64K PERIPHERAL + * fe000000 1c0000000 16M CAP_CSR + * fd000000 1c8000000 16M MSF_CSR + * fb000000 16M --- + * fa000000 1d8000000 32M PCI_IO + * f8000000 1da000000 32M PCI_CFG + * f6000000 1de000000 32M PCI_CREG + * f4000000 32M --- + * f0000000 1e0000000 64M PCI_MEM + * e[c-f]000000 per-platform mappings + */ + + +/**************************************************************************** + * Static mappings. + ****************************************************************************/ +#define IXP23XX_XSI2CPP_CSR_PHYS 0xa0000000 +#define IXP23XX_XSI2CPP_CSR_VIRT 0xfffd0000 +#define IXP23XX_XSI2CPP_CSR_SIZE 0x00010000 + +#define IXP23XX_EXP_CFG_PHYS 0xc4000000 +#define IXP23XX_EXP_CFG_VIRT 0xfffc0000 +#define IXP23XX_EXP_CFG_SIZE 0x00001000 + +#define IXP23XX_PERIPHERAL_PHYS 0xc8000000 +#define IXP23XX_PERIPHERAL_VIRT 0xfff00000 +#define IXP23XX_PERIPHERAL_SIZE 0x00010000 + +#define IXP23XX_CAP_CSR_PHYS 0x1c0000000ULL +#define IXP23XX_CAP_CSR_VIRT 0xfe000000 +#define IXP23XX_CAP_CSR_SIZE 0x01000000 + +#define IXP23XX_MSF_CSR_PHYS 0x1c8000000ULL +#define IXP23XX_MSF_CSR_VIRT 0xfd000000 +#define IXP23XX_MSF_CSR_SIZE 0x01000000 + +#define IXP23XX_PCI_IO_PHYS 0x1d8000000ULL +#define IXP23XX_PCI_IO_VIRT 0xfa000000 +#define IXP23XX_PCI_IO_SIZE 0x02000000 + +#define IXP23XX_PCI_CFG_PHYS 0x1da000000ULL +#define IXP23XX_PCI_CFG_VIRT 0xf8000000 +#define IXP23XX_PCI_CFG_SIZE 0x02000000 +#define IXP23XX_PCI_CFG0_VIRT IXP23XX_PCI_CFG_VIRT +#define IXP23XX_PCI_CFG1_VIRT (IXP23XX_PCI_CFG_VIRT + 0x01000000) + +#define IXP23XX_PCI_CREG_PHYS 0x1de000000ULL +#define IXP23XX_PCI_CREG_VIRT 0xf6000000 +#define IXP23XX_PCI_CREG_SIZE 0x02000000 +#define IXP23XX_PCI_CSR_VIRT (IXP23XX_PCI_CREG_VIRT + 0x01000000) + +#define IXP23XX_PCI_MEM_START 0xe0000000 +#define IXP23XX_PCI_MEM_PHYS 0x1e0000000ULL +#define IXP23XX_PCI_MEM_VIRT 0xf0000000 +#define IXP23XX_PCI_MEM_SIZE 0x04000000 + + +/**************************************************************************** + * XSI2CPP CSRs. + ****************************************************************************/ +#define IXP23XX_XSI2CPP_REG(x) ((volatile unsigned long *)(IXP23XX_XSI2CPP_CSR_VIRT + (x))) +#define IXP23XX_CPP2XSI_CURR_XFER_REG3 IXP23XX_XSI2CPP_REG(0xf8) +#define IXP23XX_CPP2XSI_ADDR_31 (1 << 19) +#define IXP23XX_CPP2XSI_PSH_OFF (1 << 20) +#define IXP23XX_CPP2XSI_COH_OFF (1 << 21) + + +/**************************************************************************** + * Expansion Bus Config. + ****************************************************************************/ +#define IXP23XX_EXP_CFG_REG(x) ((volatile unsigned long *)(IXP23XX_EXP_CFG_VIRT + (x))) +#define IXP23XX_EXP_CS0 IXP23XX_EXP_CFG_REG(0x00) +#define IXP23XX_EXP_CS1 IXP23XX_EXP_CFG_REG(0x04) +#define IXP23XX_EXP_CS2 IXP23XX_EXP_CFG_REG(0x08) +#define IXP23XX_EXP_CS3 IXP23XX_EXP_CFG_REG(0x0c) +#define IXP23XX_EXP_CS4 IXP23XX_EXP_CFG_REG(0x10) +#define IXP23XX_EXP_CS5 IXP23XX_EXP_CFG_REG(0x14) +#define IXP23XX_EXP_CS6 IXP23XX_EXP_CFG_REG(0x18) +#define IXP23XX_EXP_CS7 IXP23XX_EXP_CFG_REG(0x1c) +#define IXP23XX_FLASH_WRITABLE (0x2) +#define IXP23XX_FLASH_BUS8 (0x1) + +#define IXP23XX_EXP_CFG0 IXP23XX_EXP_CFG_REG(0x20) +#define IXP23XX_EXP_CFG1 IXP23XX_EXP_CFG_REG(0x24) +#define IXP23XX_EXP_CFG0_MEM_MAP (1 << 31) +#define IXP23XX_EXP_CFG0_XSCALE_SPEED_SEL (3 << 22) +#define IXP23XX_EXP_CFG0_XSCALE_SPEED_EN (1 << 21) +#define IXP23XX_EXP_CFG0_CPP_SPEED_SEL (3 << 19) +#define IXP23XX_EXP_CFG0_CPP_SPEED_EN (1 << 18) +#define IXP23XX_EXP_CFG0_PCI_SWIN (3 << 16) +#define IXP23XX_EXP_CFG0_PCI_DWIN (3 << 14) +#define IXP23XX_EXP_CFG0_PCI33_MODE (1 << 13) +#define IXP23XX_EXP_CFG0_QDR_SPEED_SEL (1 << 12) +#define IXP23XX_EXP_CFG0_CPP_DIV_SEL (1 << 5) +#define IXP23XX_EXP_CFG0_XSI_NOT_PRES (1 << 4) +#define IXP23XX_EXP_CFG0_PROM_BOOT (1 << 3) +#define IXP23XX_EXP_CFG0_PCI_ARB (1 << 2) +#define IXP23XX_EXP_CFG0_PCI_HOST (1 << 1) +#define IXP23XX_EXP_CFG0_FLASH_WIDTH (1 << 0) + +#define IXP23XX_EXP_UNIT_FUSE IXP23XX_EXP_CFG_REG(0x28) +#define IXP23XX_EXP_MSF_MUX IXP23XX_EXP_CFG_REG(0x30) +#define IXP23XX_EXP_CFG_FUSE IXP23XX_EXP_CFG_REG(0x34) + +#define IXP23XX_EXP_BUS_PHYS 0x90000000 +#define IXP23XX_EXP_BUS_WINDOW_SIZE 0x01000000 + +#define IXP23XX_EXP_BUS_CS0_BASE (IXP23XX_EXP_BUS_PHYS + 0x00000000) +#define IXP23XX_EXP_BUS_CS1_BASE (IXP23XX_EXP_BUS_PHYS + 0x01000000) +#define IXP23XX_EXP_BUS_CS2_BASE (IXP23XX_EXP_BUS_PHYS + 0x02000000) +#define IXP23XX_EXP_BUS_CS3_BASE (IXP23XX_EXP_BUS_PHYS + 0x03000000) +#define IXP23XX_EXP_BUS_CS4_BASE (IXP23XX_EXP_BUS_PHYS + 0x04000000) +#define IXP23XX_EXP_BUS_CS5_BASE (IXP23XX_EXP_BUS_PHYS + 0x05000000) +#define IXP23XX_EXP_BUS_CS6_BASE (IXP23XX_EXP_BUS_PHYS + 0x06000000) +#define IXP23XX_EXP_BUS_CS7_BASE (IXP23XX_EXP_BUS_PHYS + 0x07000000) + + +/**************************************************************************** + * Peripherals. + ****************************************************************************/ +#define IXP23XX_UART1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x0000) +#define IXP23XX_UART2_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x1000) +#define IXP23XX_PMU_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x2000) +#define IXP23XX_INTC_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x3000) +#define IXP23XX_GPIO_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x4000) +#define IXP23XX_TIMER_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x5000) +#define IXP23XX_NPE0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x6000) +#define IXP23XX_DSR_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x7000) +#define IXP23XX_NPE1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x8000) +#define IXP23XX_ETH0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x9000) +#define IXP23XX_ETH1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xA000) +#define IXP23XX_GIG0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xB000) +#define IXP23XX_GIG1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xC000) +#define IXP23XX_DDRS_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xD000) + +#define IXP23XX_UART1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x0000) +#define IXP23XX_UART2_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x1000) +#define IXP23XX_PMU_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x2000) +#define IXP23XX_INTC_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x3000) +#define IXP23XX_GPIO_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x4000) +#define IXP23XX_TIMER_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x5000) +#define IXP23XX_NPE0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x6000) +#define IXP23XX_DSR_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x7000) +#define IXP23XX_NPE1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x8000) +#define IXP23XX_ETH0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x9000) +#define IXP23XX_ETH1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xA000) +#define IXP23XX_GIG0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xB000) +#define IXP23XX_GIG1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xC000) +#define IXP23XX_DDRS_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xD000) + + +/**************************************************************************** + * Interrupt controller. + ****************************************************************************/ +#define IXP23XX_INTC_REG(x) ((volatile unsigned long *)(IXP23XX_INTC_VIRT + (x))) +#define IXP23XX_INTR_ST1 IXP23XX_INTC_REG(0x00) +#define IXP23XX_INTR_ST2 IXP23XX_INTC_REG(0x04) +#define IXP23XX_INTR_ST3 IXP23XX_INTC_REG(0x08) +#define IXP23XX_INTR_ST4 IXP23XX_INTC_REG(0x0c) +#define IXP23XX_INTR_EN1 IXP23XX_INTC_REG(0x10) +#define IXP23XX_INTR_EN2 IXP23XX_INTC_REG(0x14) +#define IXP23XX_INTR_EN3 IXP23XX_INTC_REG(0x18) +#define IXP23XX_INTR_EN4 IXP23XX_INTC_REG(0x1c) +#define IXP23XX_INTR_SEL1 IXP23XX_INTC_REG(0x20) +#define IXP23XX_INTR_SEL2 IXP23XX_INTC_REG(0x24) +#define IXP23XX_INTR_SEL3 IXP23XX_INTC_REG(0x28) +#define IXP23XX_INTR_SEL4 IXP23XX_INTC_REG(0x2c) +#define IXP23XX_INTR_IRQ_ST1 IXP23XX_INTC_REG(0x30) +#define IXP23XX_INTR_IRQ_ST2 IXP23XX_INTC_REG(0x34) +#define IXP23XX_INTR_IRQ_ST3 IXP23XX_INTC_REG(0x38) +#define IXP23XX_INTR_IRQ_ST4 IXP23XX_INTC_REG(0x3c) +#define IXP23XX_INTR_IRQ_ENC_ST_OFFSET 0x54 + + +/**************************************************************************** + * GPIO. + ****************************************************************************/ +#define IXP23XX_GPIO_REG(x) ((volatile unsigned long *)(IXP23XX_GPIO_VIRT + (x))) +#define IXP23XX_GPIO_GPOUTR IXP23XX_GPIO_REG(0x00) +#define IXP23XX_GPIO_GPOER IXP23XX_GPIO_REG(0x04) +#define IXP23XX_GPIO_GPINR IXP23XX_GPIO_REG(0x08) +#define IXP23XX_GPIO_GPISR IXP23XX_GPIO_REG(0x0c) +#define IXP23XX_GPIO_GPIT1R IXP23XX_GPIO_REG(0x10) +#define IXP23XX_GPIO_GPIT2R IXP23XX_GPIO_REG(0x14) +#define IXP23XX_GPIO_GPCLKR IXP23XX_GPIO_REG(0x18) +#define IXP23XX_GPIO_GPDBSELR IXP23XX_GPIO_REG(0x1c) + +#define IXP23XX_GPIO_STYLE_MASK 0x7 +#define IXP23XX_GPIO_STYLE_ACTIVE_HIGH 0x0 +#define IXP23XX_GPIO_STYLE_ACTIVE_LOW 0x1 +#define IXP23XX_GPIO_STYLE_RISING_EDGE 0x2 +#define IXP23XX_GPIO_STYLE_FALLING_EDGE 0x3 +#define IXP23XX_GPIO_STYLE_TRANSITIONAL 0x4 + +#define IXP23XX_GPIO_STYLE_SIZE 3 + + +/**************************************************************************** + * Timer. + ****************************************************************************/ +#define IXP23XX_TIMER_REG(x) ((volatile unsigned long *)(IXP23XX_TIMER_VIRT + (x))) +#define IXP23XX_TIMER_CONT IXP23XX_TIMER_REG(0x00) +#define IXP23XX_TIMER1_TIMESTAMP IXP23XX_TIMER_REG(0x04) +#define IXP23XX_TIMER1_RELOAD IXP23XX_TIMER_REG(0x08) +#define IXP23XX_TIMER2_TIMESTAMP IXP23XX_TIMER_REG(0x0c) +#define IXP23XX_TIMER2_RELOAD IXP23XX_TIMER_REG(0x10) +#define IXP23XX_TIMER_WDOG IXP23XX_TIMER_REG(0x14) +#define IXP23XX_TIMER_WDOG_EN IXP23XX_TIMER_REG(0x18) +#define IXP23XX_TIMER_WDOG_KEY IXP23XX_TIMER_REG(0x1c) +#define IXP23XX_TIMER_WDOG_KEY_MAGIC 0x482e +#define IXP23XX_TIMER_STATUS IXP23XX_TIMER_REG(0x20) +#define IXP23XX_TIMER_SOFT_RESET IXP23XX_TIMER_REG(0x24) +#define IXP23XX_TIMER_SOFT_RESET_EN IXP23XX_TIMER_REG(0x28) + +#define IXP23XX_TIMER_ENABLE (1 << 0) +#define IXP23XX_TIMER_ONE_SHOT (1 << 1) +/* Low order bits of reload value ignored */ +#define IXP23XX_TIMER_RELOAD_MASK (0x3) +#define IXP23XX_TIMER_DISABLED (0x0) +#define IXP23XX_TIMER1_INT_PEND (1 << 0) +#define IXP23XX_TIMER2_INT_PEND (1 << 1) +#define IXP23XX_TIMER_STATUS_TS_PEND (1 << 2) +#define IXP23XX_TIMER_STATUS_WDOG_PEND (1 << 3) +#define IXP23XX_TIMER_STATUS_WARM_RESET (1 << 4) + + +/**************************************************************************** + * CAP CSRs. + ****************************************************************************/ +#define IXP23XX_GLOBAL_REG(x) ((volatile unsigned long *)(IXP23XX_CAP_CSR_VIRT + 0x4a00 + (x))) +#define IXP23XX_PRODUCT_ID IXP23XX_GLOBAL_REG(0x00) +#define IXP23XX_MISC_CONTROL IXP23XX_GLOBAL_REG(0x04) +#define IXP23XX_MSF_CLK_CNTRL IXP23XX_GLOBAL_REG(0x08) +#define IXP23XX_RESET0 IXP23XX_GLOBAL_REG(0x0c) +#define IXP23XX_RESET1 IXP23XX_GLOBAL_REG(0x10) +#define IXP23XX_STRAP_OPTIONS IXP23XX_GLOBAL_REG(0x18) + +#define IXP23XX_ENABLE_WATCHDOG (1 << 24) +#define IXP23XX_SHPC_INIT_COMP (1 << 21) +#define IXP23XX_RST_ALL (1 << 16) +#define IXP23XX_RESET_PCI (1 << 2) +#define IXP23XX_PCI_UNIT_RESET (1 << 1) +#define IXP23XX_XSCALE_RESET (1 << 0) + +#define IXP23XX_UENGINE_CSR_VIRT_BASE (IXP23XX_CAP_CSR_VIRT + 0x18000) + + +/**************************************************************************** + * PCI CSRs. + ****************************************************************************/ +#define IXP23XX_PCI_CREG(x) ((volatile unsigned long *)(IXP23XX_PCI_CREG_VIRT + (x))) +#define IXP23XX_PCI_CMDSTAT IXP23XX_PCI_CREG(0x04) +#define IXP23XX_PCI_SRAM_BAR IXP23XX_PCI_CREG(0x14) +#define IXP23XX_PCI_SDRAM_BAR IXP23XX_PCI_CREG(0x18) + + +#define IXP23XX_PCI_CSR(x) ((volatile unsigned long *)(IXP23XX_PCI_CREG_VIRT + 0x01000000 + (x))) +#define IXP23XX_PCI_OUT_INT_STATUS IXP23XX_PCI_CSR(0x0030) +#define IXP23XX_PCI_OUT_INT_MASK IXP23XX_PCI_CSR(0x0034) +#define IXP23XX_PCI_SRAM_BASE_ADDR_MASK IXP23XX_PCI_CSR(0x00fc) +#define IXP23XX_PCI_DRAM_BASE_ADDR_MASK IXP23XX_PCI_CSR(0x0100) +#define IXP23XX_PCI_CONTROL IXP23XX_PCI_CSR(0x013c) +#define IXP23XX_PCI_ADDR_EXT IXP23XX_PCI_CSR(0x0140) +#define IXP23XX_PCI_ME_PUSH_STATUS IXP23XX_PCI_CSR(0x0148) +#define IXP23XX_PCI_ME_PUSH_EN IXP23XX_PCI_CSR(0x014c) +#define IXP23XX_PCI_ERR_STATUS IXP23XX_PCI_CSR(0x0150) +#define IXP23XX_PCI_ERROR_STATUS IXP23XX_PCI_CSR(0x0150) +#define IXP23XX_PCI_ERR_ENABLE IXP23XX_PCI_CSR(0x0154) +#define IXP23XX_PCI_XSCALE_INT_STATUS IXP23XX_PCI_CSR(0x0158) +#define IXP23XX_PCI_XSCALE_INT_ENABLE IXP23XX_PCI_CSR(0x015c) +#define IXP23XX_PCI_CPP_ADDR_BITS IXP23XX_PCI_CSR(0x0160) + + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/memory.h b/trunk/arch/arm/mach-ixp23xx/include/mach/memory.h new file mode 100644 index 000000000000..6cf0704e946a --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/memory.h @@ -0,0 +1,34 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/memory.h + * + * Copyright (c) 2003-2004 Intel Corp. + * + * 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. + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#include + +/* + * Physical DRAM offset. + */ +#define PLAT_PHYS_OFFSET (0x00000000) + +#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0) + +#define __phys_to_bus(x) ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET)) +#define __bus_to_phys(x) ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET)) + +#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v)) +#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b)) +#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p)) +#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b)) + +#define arch_is_coherent() 1 + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h b/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h new file mode 100644 index 000000000000..50de558e722e --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h @@ -0,0 +1,58 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/platform.h + * + * Various bits of code used by platform-level code. + * + * Author: Deepak Saxena + * + * Copyright 2005 (c) MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASSEMBLY__ + +static inline unsigned long ixp2000_reg_read(volatile void *reg) +{ + return *((volatile unsigned long *)reg); +} + +static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) +{ + *((volatile unsigned long *)reg) = val; +} + +static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val) +{ + *((volatile unsigned long *)reg) = val; +} + +struct pci_sys_data; + +void ixp23xx_map_io(void); +void ixp23xx_init_irq(void); +void ixp23xx_sys_init(void); +void ixp23xx_restart(char, const char *); +int ixp23xx_pci_setup(int, struct pci_sys_data *); +void ixp23xx_pci_preinit(void); +struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*); +void ixp23xx_pci_slave_init(void); + +extern struct sys_timer ixp23xx_timer; + +#define IXP23XX_UART_XTAL 14745600 + +#ifndef __ASSEMBLY__ +/* + * Is system memory on the XSI or CPP bus? + */ +static inline unsigned ixp23xx_cpp_boot(void) +{ + return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES); +} +#endif + + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/time.h b/trunk/arch/arm/mach-ixp23xx/include/mach/time.h new file mode 100644 index 000000000000..b61dafc884ac --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/time.h @@ -0,0 +1,3 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/time.h + */ diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/timex.h b/trunk/arch/arm/mach-ixp23xx/include/mach/timex.h new file mode 100644 index 000000000000..e341e9cf9c37 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/timex.h @@ -0,0 +1,7 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/timex.h + * + * XScale architecture timex specifications + */ + +#define CLOCK_TICK_RATE 75000000 diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/uncompress.h b/trunk/arch/arm/mach-ixp23xx/include/mach/uncompress.h new file mode 100644 index 000000000000..8b4c358d2c04 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/uncompress.h @@ -0,0 +1,40 @@ +/* + * arch/arm/mach-ixp23xx/include/mach/uncompress.h + * + * Copyright (C) 2002-2004 Intel Corporation. + * + * 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_ARCH_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include +#include + +#define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS) + +static inline void putc(char c) +{ + int j; + + for (j = 0; j < 0x1000; j++) { + if (UART_BASE[UART_LSR] & UART_LSR_THRE) + break; + barrier(); + } + + UART_BASE[UART_TX] = c; +} + +static inline void flush(void) +{ +} + +#define arch_decomp_setup() +#define arch_decomp_wdog() + + +#endif diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c new file mode 100644 index 000000000000..b0e07db5ceaf --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -0,0 +1,347 @@ +/* + * arch/arm/mach-ixp23xx/ixdp2351.c + * + * IXDP2351 board-specific routines + * + * Author: Deepak Saxena + * + * Copyright 2005 (c) MontaVista Software, Inc. + * + * Based on 2.4 code Copyright 2004 (c) Intel Corporation + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * IXDP2351 Interrupt Handling + */ +static void ixdp2351_inta_mask(struct irq_data *d) +{ + *IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(d->irq); +} + +static void ixdp2351_inta_unmask(struct irq_data *d) +{ + *IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(d->irq); +} + +static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc) +{ + u16 ex_interrupt = + *IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID; + int i; + + desc->irq_data.chip->irq_mask(&desc->irq_data); + + for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) { + if (ex_interrupt & (1 << i)) { + int cpld_irq = + IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i); + generic_handle_irq(cpld_irq); + } + } + + desc->irq_data.chip->irq_unmask(&desc->irq_data); +} + +static struct irq_chip ixdp2351_inta_chip = { + .irq_ack = ixdp2351_inta_mask, + .irq_mask = ixdp2351_inta_mask, + .irq_unmask = ixdp2351_inta_unmask +}; + +static void ixdp2351_intb_mask(struct irq_data *d) +{ + *IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(d->irq); +} + +static void ixdp2351_intb_unmask(struct irq_data *d) +{ + *IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(d->irq); +} + +static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc) +{ + u16 ex_interrupt = + *IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID; + int i; + + desc->irq_data.chip->irq_ack(&desc->irq_data); + + for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) { + if (ex_interrupt & (1 << i)) { + int cpld_irq = + IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i); + generic_handle_irq(cpld_irq); + } + } + + desc->irq_data.chip->irq_unmask(&desc->irq_data); +} + +static struct irq_chip ixdp2351_intb_chip = { + .irq_ack = ixdp2351_intb_mask, + .irq_mask = ixdp2351_intb_mask, + .irq_unmask = ixdp2351_intb_unmask +}; + +void __init ixdp2351_init_irq(void) +{ + int irq; + + /* Mask all interrupts from CPLD, disable simulation */ + *IXDP2351_CPLD_INTA_MASK_SET_REG = (u16) -1; + *IXDP2351_CPLD_INTB_MASK_SET_REG = (u16) -1; + *IXDP2351_CPLD_INTA_SIM_REG = 0; + *IXDP2351_CPLD_INTB_SIM_REG = 0; + + ixp23xx_init_irq(); + + for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE); + irq < + IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + IXDP2351_INTA_IRQ_NUM); + irq++) { + if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) { + set_irq_flags(irq, IRQF_VALID); + irq_set_chip_and_handler(irq, &ixdp2351_inta_chip, + handle_level_irq); + } + } + + for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE); + irq < + IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + IXDP2351_INTB_IRQ_NUM); + irq++) { + if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) { + set_irq_flags(irq, IRQF_VALID); + irq_set_chip_and_handler(irq, &ixdp2351_intb_chip, + handle_level_irq); + } + } + + irq_set_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler); + irq_set_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler); +} + +/* + * IXDP2351 PCI + */ + +/* + * This board does not do normal PCI IRQ routing, or any + * sort of swizzling, so we just need to check where on the + * bus the device is and figure out what CPLD pin it is + * being routed to. + */ +#define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) + +static int __init ixdp2351_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + u8 bus = dev->bus->number; + u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); + struct pci_bus *tmp_bus = dev->bus; + + /* Primary bus, no interrupts here */ + if (!bus) + return -1; + + /* Lookup first leaf in bus tree */ + while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) + tmp_bus = tmp_bus->parent; + + /* Select between known bridges */ + switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) { + /* Device is located after first bridge */ + case 0x0008: + if (tmp_bus == dev->bus) { + /* Device is located directy after first bridge */ + switch (devpin) { + /* Onboard 82546 */ + case DEVPIN(1, 1): /* Onboard 82546 ch 0 */ + return IRQ_IXDP2351_INTA_82546; + case DEVPIN(1, 2): /* Onboard 82546 ch 1 */ + return IRQ_IXDP2351_INTB_82546; + /* PMC SLOT */ + case DEVPIN(0, 1): /* PMCP INTA# */ + case DEVPIN(2, 4): /* PMCS INTD# */ + return IRQ_IXDP2351_SPCI_PMC_INTA; + case DEVPIN(0, 2): /* PMCP INTB# */ + case DEVPIN(2, 1): /* PMCS INTA# */ + return IRQ_IXDP2351_SPCI_PMC_INTB; + case DEVPIN(0, 3): /* PMCP INTC# */ + case DEVPIN(2, 2): /* PMCS INTB# */ + return IRQ_IXDP2351_SPCI_PMC_INTC; + case DEVPIN(0, 4): /* PMCP INTD# */ + case DEVPIN(2, 3): /* PMCS INTC# */ + return IRQ_IXDP2351_SPCI_PMC_INTD; + } + } else { + /* Device is located indirectly after first bridge */ + /* Not supported now */ + return -1; + } + break; + case 0x0010: + if (tmp_bus == dev->bus) { + /* Device is located directy after second bridge */ + /* Secondary bus of second bridge */ + switch (devpin) { + case DEVPIN(0, 1): /* DB#0 */ + case DEVPIN(0, 2): + case DEVPIN(0, 3): + case DEVPIN(0, 4): + return IRQ_IXDP2351_SPCI_DB_0; + case DEVPIN(1, 1): /* DB#1 */ + case DEVPIN(1, 2): + case DEVPIN(1, 3): + case DEVPIN(1, 4): + return IRQ_IXDP2351_SPCI_DB_1; + case DEVPIN(2, 1): /* FIC1 */ + case DEVPIN(2, 2): + case DEVPIN(2, 3): + case DEVPIN(2, 4): + case DEVPIN(3, 1): /* FIC2 */ + case DEVPIN(3, 2): + case DEVPIN(3, 3): + case DEVPIN(3, 4): + return IRQ_IXDP2351_SPCI_FIC; + } + } else { + /* Device is located indirectly after second bridge */ + /* Not supported now */ + return -1; + } + break; + } + + return -1; +} + +struct hw_pci ixdp2351_pci __initdata = { + .nr_controllers = 1, + .preinit = ixp23xx_pci_preinit, + .setup = ixp23xx_pci_setup, + .scan = ixp23xx_pci_scan_bus, + .map_irq = ixdp2351_map_irq, +}; + +int __init ixdp2351_pci_init(void) +{ + if (machine_is_ixdp2351()) + pci_common_init(&ixdp2351_pci); + + return 0; +} + +subsys_initcall(ixdp2351_pci_init); + +/* + * IXDP2351 Static Mapped I/O + */ +static struct map_desc ixdp2351_io_desc[] __initdata = { + { + .virtual = IXDP2351_NP_VIRT_BASE, + .pfn = __phys_to_pfn((u64)IXDP2351_NP_PHYS_BASE), + .length = IXDP2351_NP_PHYS_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXDP2351_BB_BASE_VIRT, + .pfn = __phys_to_pfn((u64)IXDP2351_BB_BASE_PHYS), + .length = IXDP2351_BB_SIZE, + .type = MT_DEVICE + } +}; + +static void __init ixdp2351_map_io(void) +{ + ixp23xx_map_io(); + iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc)); +} + +static struct physmap_flash_data ixdp2351_flash_data = { + .width = 1, +}; + +static struct resource ixdp2351_flash_resource = { + .start = 0x90000000, + .end = 0x93ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2351_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ixdp2351_flash_data, + }, + .num_resources = 1, + .resource = &ixdp2351_flash_resource, +}; + +static void __init ixdp2351_init(void) +{ + platform_device_register(&ixdp2351_flash); + + /* + * Mark flash as writeable + */ + IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE; + + ixp23xx_sys_init(); +} + +static void ixdp2351_restart(char mode, const char *cmd) +{ + /* First try machine specific support */ + + *IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_MAGIC; + (void) *IXDP2351_CPLD_RESET1_REG; + *IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_ENABLE; + + ixp23xx_restart(mode, cmd); +} + +MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform") + /* Maintainer: MontaVista Software, Inc. */ + .map_io = ixdp2351_map_io, + .init_irq = ixdp2351_init_irq, + .timer = &ixp23xx_timer, + .atag_offset = 0x100, + .init_machine = ixdp2351_init, + .restart = ixdp2351_restart, +MACHINE_END diff --git a/trunk/arch/arm/mach-ixp23xx/pci.c b/trunk/arch/arm/mach-ixp23xx/pci.c new file mode 100644 index 000000000000..911f5a58e006 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/pci.c @@ -0,0 +1,294 @@ +/* + * arch/arm/mach-ixp23xx/pci.c + * + * PCI routines for IXP23XX based systems + * + * Copyright (c) 2005 MontaVista Software, Inc. + * + * based on original code: + * + * Author: Naeem Afzal + * Copyright 2002-2005 Intel Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern int (*external_fault) (unsigned long, struct pt_regs *); + +static volatile int pci_master_aborts = 0; + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +int clear_master_aborts(void); + +static u32 +*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) +{ + u32 *paddress; + + /* + * Must be dword aligned + */ + where &= ~3; + + /* + * For top bus, generate type 0, else type 1 + */ + if (!bus_nr) { + if (PCI_SLOT(devfn) >= 8) + return 0; + + paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT + | (1 << (PCI_SLOT(devfn) + 16)) + | (PCI_FUNC(devfn) << 8) | where); + } else { + paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT + | (bus_nr << 16) + | (PCI_SLOT(devfn) << 11) + | (PCI_FUNC(devfn) << 8) | where); + } + + return paddress; +} + +/* + * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. + * 0 and 3 are not valid indexes... + */ +static u32 bytemask[] = { + /*0*/ 0, + /*1*/ 0xff, + /*2*/ 0xffff, + /*3*/ 0, + /*4*/ 0xffffffff, +}; + +static int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) +{ + u32 n; + u32 *addr; + + n = where % 4; + + DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where, + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + addr = ixp23xx_pci_config_addr(bus->number, devfn, where); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + + pci_master_aborts = 0; + *value = (*addr >> (8*n)) & bytemask[size]; + if (pci_master_aborts) { + pci_master_aborts = 0; + *value = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return PCIBIOS_SUCCESSFUL; +} + +/* + * We don't do error checking on the address for writes. + * It's assumed that the user checked for the device existing first + * by doing a read first. + */ +static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ + u32 mask; + u32 *addr; + u32 temp; + + mask = ~(bytemask[size] << ((where % 0x4) * 8)); + addr = ixp23xx_pci_config_addr(bus->number, devfn, where); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + temp = (u32) (value) << ((where % 0x4) * 8); + *addr = (*addr & mask) | temp; + + clear_master_aborts(); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops ixp23xx_pci_ops = { + .read = ixp23xx_pci_read_config, + .write = ixp23xx_pci_write_config, +}; + +struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + return pci_scan_root_bus(NULL, sysdata->busnr, &ixp23xx_pci_ops, + sysdata, &sysdata->resources); +} + +int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + volatile unsigned long temp; + unsigned long flags; + + pci_master_aborts = 1; + + local_irq_save(flags); + temp = *IXP23XX_PCI_CONTROL; + + /* + * master abort and cmd tgt err + */ + if (temp & ((1 << 8) | (1 << 5))) + *IXP23XX_PCI_CONTROL = temp; + + temp = *IXP23XX_PCI_CMDSTAT; + + if (temp & (1 << 29)) + *IXP23XX_PCI_CMDSTAT = temp; + local_irq_restore(flags); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +int clear_master_aborts(void) +{ + volatile u32 temp; + + temp = *IXP23XX_PCI_CONTROL; + + /* + * master abort and cmd tgt err + */ + if (temp & ((1 << 8) | (1 << 5))) + *IXP23XX_PCI_CONTROL = temp; + + temp = *IXP23XX_PCI_CMDSTAT; + + if (temp & (1 << 29)) + *IXP23XX_PCI_CMDSTAT = temp; + + return 0; +} + +static void __init ixp23xx_pci_common_init(void) +{ +#ifdef __ARMEB__ + *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */ +#endif + /* + * ADDR_31 needs to be clear for PCI memory access to CPP memory + */ + *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31; + *IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF; + + /* + * Select correct memory for PCI inbound transactions + */ + if (ixp23xx_cpp_boot()) { + *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1); + } else { + *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1); + + /* + * Enable coherency on A2 silicon. + */ + if (arch_is_coherent()) + *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF; + } +} + +void __init ixp23xx_pci_preinit(void) +{ + pcibios_min_io = 0; + pcibios_min_mem = 0xe0000000; + + pci_set_flags(0); + + ixp23xx_pci_common_init(); + + hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0, + "PCI config cycle to non-existent device"); + + *IXP23XX_PCI_ADDR_EXT = 0x0000e000; +} + +/* + * Prevent PCI layer from seeing the inbound host-bridge resources + */ +static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev) +{ + int i; + + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx); + +/* + * IXP2300 systems often have large resource requirements, so we just + * use our own resource space. + */ +static struct resource ixp23xx_pci_mem_space = { + .start = IXP23XX_PCI_MEM_START, + .end = IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + .name = "PCI Mem Space" +}; + +static struct resource ixp23xx_pci_io_space = { + .start = 0x00000100, + .end = 0x01ffffff, + .flags = IORESOURCE_IO, + .name = "PCI I/O Space" +}; + +int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) +{ + if (nr >= 1) + return 0; + + pci_add_resource_offset(&sys->resources, + &ixp23xx_pci_io_space, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &ixp23xx_pci_mem_space, sys->mem_offset); + + return 1; +} + +void __init ixp23xx_pci_slave_init(void) +{ + ixp23xx_pci_common_init(); +} diff --git a/trunk/arch/arm/mach-ixp23xx/roadrunner.c b/trunk/arch/arm/mach-ixp23xx/roadrunner.c new file mode 100644 index 000000000000..eaaa3fa9fd05 --- /dev/null +++ b/trunk/arch/arm/mach-ixp23xx/roadrunner.c @@ -0,0 +1,180 @@ +/* + * arch/arm/mach-ixp23xx/roadrunner.c + * + * RoadRunner board-specific routines + * + * Author: Deepak Saxena + * + * Copyright 2005 (c) MontaVista Software, Inc. + * + * Based on 2.4 code Copyright 2005 (c) ADI Engineering Corporation + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * Interrupt mapping + */ +#define INTA IRQ_ROADRUNNER_PCI_INTA +#define INTB IRQ_ROADRUNNER_PCI_INTB +#define INTC IRQ_ROADRUNNER_PCI_INTC +#define INTD IRQ_ROADRUNNER_PCI_INTD + +#define INTC_PIN IXP23XX_GPIO_PIN_11 +#define INTD_PIN IXP23XX_GPIO_PIN_12 + +static int __init roadrunner_map_irq(const struct pci_dev *dev, u8 idsel, + u8 pin) +{ + static int pci_card_slot_irq[] = {INTB, INTC, INTD, INTA}; + static int pmc_card_slot_irq[] = {INTA, INTB, INTC, INTD}; + static int usb_irq[] = {INTB, INTC, INTD, -1}; + static int mini_pci_1_irq[] = {INTB, INTC, -1, -1}; + static int mini_pci_2_irq[] = {INTC, INTD, -1, -1}; + + switch(dev->bus->number) { + case 0: + switch(dev->devfn) { + case 0x0: // PCI-PCI bridge + break; + case 0x8: // PCI Card Slot + return pci_card_slot_irq[pin - 1]; + case 0x10: // PMC Slot + return pmc_card_slot_irq[pin - 1]; + case 0x18: // PMC Slot Secondary Agent + break; + case 0x20: // IXP Processor + break; + default: + return NO_IRQ; + } + break; + + case 1: + switch(dev->devfn) { + case 0x0: // IDE Controller + return (pin == 1) ? INTC : -1; + case 0x8: // USB fun 0 + case 0x9: // USB fun 1 + case 0xa: // USB fun 2 + return usb_irq[pin - 1]; + case 0x10: // Mini PCI 1 + return mini_pci_1_irq[pin-1]; + case 0x18: // Mini PCI 2 + return mini_pci_2_irq[pin-1]; + case 0x20: // MEM slot + return (pin == 1) ? INTA : -1; + default: + return NO_IRQ; + } + break; + + default: + return NO_IRQ; + } + + return NO_IRQ; +} + +static void __init roadrunner_pci_preinit(void) +{ + irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW); + + ixp23xx_pci_preinit(); +} + +static struct hw_pci roadrunner_pci __initdata = { + .nr_controllers = 1, + .preinit = roadrunner_pci_preinit, + .setup = ixp23xx_pci_setup, + .scan = ixp23xx_pci_scan_bus, + .map_irq = roadrunner_map_irq, +}; + +static int __init roadrunner_pci_init(void) +{ + if (machine_is_roadrunner()) + pci_common_init(&roadrunner_pci); + + return 0; +}; + +subsys_initcall(roadrunner_pci_init); + +static struct physmap_flash_data roadrunner_flash_data = { + .width = 2, +}; + +static struct resource roadrunner_flash_resource = { + .start = 0x90000000, + .end = 0x93ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device roadrunner_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &roadrunner_flash_data, + }, + .num_resources = 1, + .resource = &roadrunner_flash_resource, +}; + +static void __init roadrunner_init(void) +{ + platform_device_register(&roadrunner_flash); + + /* + * Mark flash as writeable + */ + IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE; + IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE; + + ixp23xx_sys_init(); +} + +MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform") + /* Maintainer: Deepak Saxena */ + .map_io = ixp23xx_map_io, + .init_irq = ixp23xx_init_irq, + .timer = &ixp23xx_timer, + .atag_offset = 0x100, + .init_machine = roadrunner_init, + .restart = ixp23xx_restart, +MACHINE_END diff --git a/trunk/arch/arm/mach-msm/board-halibut.c b/trunk/arch/arm/mach-msm/board-halibut.c index 26aac363a064..3698a370d636 100644 --- a/trunk/arch/arm/mach-msm/board-halibut.c +++ b/trunk/arch/arm/mach-msm/board-halibut.c @@ -86,6 +86,9 @@ static void __init halibut_init(void) static void __init halibut_fixup(struct tag *tags, char **cmdline, struct meminfo *mi) { + mi->nr_banks=1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].size = (101*1024*1024); } static void __init halibut_map_io(void) diff --git a/trunk/arch/arm/mach-msm/board-trout-panel.c b/trunk/arch/arm/mach-msm/board-trout-panel.c index 89bf6b426699..25105c1027fe 100644 --- a/trunk/arch/arm/mach-msm/board-trout-panel.c +++ b/trunk/arch/arm/mach-msm/board-trout-panel.c @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-msm/board-trout.c b/trunk/arch/arm/mach-msm/board-trout.c index d4060a37e23d..5414f76ec0a9 100644 --- a/trunk/arch/arm/mach-msm/board-trout.c +++ b/trunk/arch/arm/mach-msm/board-trout.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-msm/proc_comm.c b/trunk/arch/arm/mach-msm/proc_comm.c index 9980dc736e7b..67e701c7f183 100644 --- a/trunk/arch/arm/mach-msm/proc_comm.c +++ b/trunk/arch/arm/mach-msm/proc_comm.c @@ -121,7 +121,7 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) * and unknown state. This function should be called early to * wait on the ARM9. */ -void __devinit proc_comm_boot_wait(void) +void __init proc_comm_boot_wait(void) { void __iomem *base = MSM_SHARED_RAM_BASE; diff --git a/trunk/arch/arm/mach-omap1/fpga.c b/trunk/arch/arm/mach-omap1/fpga.c index 76c67b3f9f61..29ec50fc688d 100644 --- a/trunk/arch/arm/mach-omap1/fpga.c +++ b/trunk/arch/arm/mach-omap1/fpga.c @@ -87,7 +87,7 @@ static void fpga_mask_ack_irq(struct irq_data *d) fpga_ack_irq(d); } -void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc) +static void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc) { u32 stat; int fpga_irq; diff --git a/trunk/arch/arm/mach-omap1/mux.c b/trunk/arch/arm/mach-omap1/mux.c index e9cc52d4cb28..087dba0df47e 100644 --- a/trunk/arch/arm/mach-omap1/mux.c +++ b/trunk/arch/arm/mach-omap1/mux.c @@ -27,7 +27,6 @@ #include #include -#include #include diff --git a/trunk/arch/arm/mach-omap1/timer.c b/trunk/arch/arm/mach-omap1/timer.c index fb202af01d0d..5536e0456fb7 100644 --- a/trunk/arch/arm/mach-omap1/timer.c +++ b/trunk/arch/arm/mach-omap1/timer.c @@ -47,15 +47,14 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev, int n = (pdev->id - 1) << 1; u32 l; - l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); + l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); l |= source << n; - omap_writel(l, MOD_CONF_CTRL_1); + __raw_writel(l, MOD_CONF_CTRL_1); return 0; } - -int __init omap1_dm_timer_init(void) +static int __init omap1_dm_timer_init(void) { int i; int ret; diff --git a/trunk/arch/arm/mach-omap2/board-4430sdp.c b/trunk/arch/arm/mach-omap2/board-4430sdp.c index 130ab00c09a2..a39fc4bbd2b8 100644 --- a/trunk/arch/arm/mach-omap2/board-4430sdp.c +++ b/trunk/arch/arm/mach-omap2/board-4430sdp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -561,7 +560,7 @@ static struct regulator_init_data sdp4430_vusim = { }, }; -static struct twl6040_codec_data twl6040_codec = { +static struct twl4030_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -569,7 +568,7 @@ static struct twl6040_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl6040_vibra_data twl6040_vibra = { +static struct twl4030_vibra_data twl6040_vibra = { .vibldrv_res = 8, .vibrdrv_res = 3, .viblmotor_res = 10, @@ -578,14 +577,16 @@ static struct twl6040_vibra_data twl6040_vibra = { .vddvibr_uV = 0, /* fixed volt supply - VBAT */ }; -static struct twl6040_platform_data twl6040_data = { +static struct twl4030_audio_data twl6040_audio = { .codec = &twl6040_codec, .vibra = &twl6040_vibra, .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; static struct twl4030_platform_data sdp4430_twldata = { + .audio = &twl6040_audio, /* Regulators */ .vusim = &sdp4430_vusim, .vaux1 = &sdp4430_vaux1, @@ -616,8 +617,7 @@ static int __init omap4_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &sdp4430_twldata, - &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap4_pmic_init("twl6030", &sdp4430_twldata); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); diff --git a/trunk/arch/arm/mach-omap2/board-generic.c b/trunk/arch/arm/mach-omap2/board-generic.c index 098d183a0086..74e1687b5170 100644 --- a/trunk/arch/arm/mach-omap2/board-generic.c +++ b/trunk/arch/arm/mach-omap2/board-generic.c @@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = { static void __init omap4_i2c_init(void) { - omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0); + omap4_pmic_init("twl6030", &sdp4430_twldata); } static void __init omap4_init(void) diff --git a/trunk/arch/arm/mach-omap2/board-omap4panda.c b/trunk/arch/arm/mach-omap2/board-omap4panda.c index 1b782ba53433..f864065cc1fe 100644 --- a/trunk/arch/arm/mach-omap2/board-omap4panda.c +++ b/trunk/arch/arm/mach-omap2/board-omap4panda.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -231,7 +230,7 @@ static struct platform_device omap_vwlan_device = { }, }; -struct wl12xx_platform_data omap_panda_wlan_data __initdata = { +static struct wl12xx_platform_data omap_panda_wlan_data __initdata = { /* PANDA ref clock is 38.4 MHz */ .board_ref_clock = 2, }; @@ -285,7 +284,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) return 0; } -static struct twl6040_codec_data twl6040_codec = { +static struct twl4030_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -293,14 +292,17 @@ static struct twl6040_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl6040_platform_data twl6040_data = { +static struct twl4030_audio_data twl6040_audio = { .codec = &twl6040_codec, .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; /* Panda board uses the common PMIC configuration */ -static struct twl4030_platform_data omap4_panda_twldata; +static struct twl4030_platform_data omap4_panda_twldata = { + .audio = &twl6040_audio, +}; /* * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM @@ -324,8 +326,7 @@ static int __init omap4_panda_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &omap4_panda_twldata, - &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap4_pmic_init("twl6030", &omap4_panda_twldata); omap_register_i2c_bus(2, 400, NULL, 0); /* * Bus 3 is attached to the DVI port where devices like the pico DLP @@ -438,7 +439,7 @@ static struct panel_dvi_platform_data omap4_dvi_panel = { .i2c_bus_num = 3, }; -struct omap_dss_device omap4_panda_dvi_device = { +static struct omap_dss_device omap4_panda_dvi_device = { .type = OMAP_DISPLAY_TYPE_DPI, .name = "dvi", .driver_name = "dvi", @@ -448,7 +449,7 @@ struct omap_dss_device omap4_panda_dvi_device = { .channel = OMAP_DSS_CHANNEL_LCD2, }; -int __init omap4_panda_dvi_init(void) +static int __init omap4_panda_dvi_init(void) { int r; @@ -509,7 +510,7 @@ static struct omap_dss_board_info omap4_panda_dss_data = { .default_device = &omap4_panda_dvi_device, }; -void __init omap4_panda_display_init(void) +static void __init omap4_panda_display_init(void) { int r; diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index d87ee0612098..ae957c92081b 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -872,11 +872,11 @@ static struct twl4030_power_data rx51_t2scripts_data __initdata = { .resource_config = twl4030_rconfig, }; -struct twl4030_vibra_data rx51_vibra_data __initdata = { +static struct twl4030_vibra_data rx51_vibra_data __initdata = { .coexist = 0, }; -struct twl4030_audio_data rx51_audio_data __initdata = { +static struct twl4030_audio_data rx51_audio_data __initdata = { .audio_mclk = 26000000, .vibra = &rx51_vibra_data, }; diff --git a/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 3d9d746b221a..7072e0d651b1 100644 --- a/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -165,3 +165,83 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) return 0; } + +#ifdef CONFIG_CPU_FREQ +/* + * Walk PRCM rate table and fillout cpufreq freq_table + * XXX This should be replaced by an OPP layer in the near future + */ +static struct cpufreq_frequency_table *freq_table; + +void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) +{ + const struct prcm_config *prcm; + int i = 0; + int tbl_sz = 0; + + if (!cpu_is_omap24xx()) + return; + + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sclk->rate) + continue; + + /* don't put bypass rates in table */ + if (prcm->dpll_speed == prcm->xtal_speed) + continue; + + tbl_sz++; + } + + /* + * XXX Ensure that we're doing what CPUFreq expects for this error + * case and the following one + */ + if (tbl_sz == 0) { + pr_warning("%s: no matching entries in rate_table\n", + __func__); + return; + } + + /* Include the CPUFREQ_TABLE_END terminator entry */ + tbl_sz++; + + freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz, + GFP_ATOMIC); + if (!freq_table) { + pr_err("%s: could not kzalloc frequency table\n", __func__); + return; + } + + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sclk->rate) + continue; + + /* don't put bypass rates in table */ + if (prcm->dpll_speed == prcm->xtal_speed) + continue; + + freq_table[i].index = i; + freq_table[i].frequency = prcm->mpu_speed / 1000; + i++; + } + + freq_table[i].index = i; + freq_table[i].frequency = CPUFREQ_TABLE_END; + + *table = &freq_table[0]; +} + +void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + if (!cpu_is_omap24xx()) + return; + + kfree(freq_table); +} + +#endif diff --git a/trunk/arch/arm/mach-omap2/clock.c b/trunk/arch/arm/mach-omap2/clock.c index d9f4931513f9..f57ed5baeccf 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -536,5 +536,10 @@ struct clk_functions omap2_clk_functions = { .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, .clk_disable_unused = omap2_clk_disable_unused, +#ifdef CONFIG_CPU_FREQ + /* These will be removed when the OPP code is integrated */ + .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, + .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, +#endif }; diff --git a/trunk/arch/arm/mach-omap2/clock.h b/trunk/arch/arm/mach-omap2/clock.h index a1bb23a23351..b8c2a686481c 100644 --- a/trunk/arch/arm/mach-omap2/clock.h +++ b/trunk/arch/arm/mach-omap2/clock.h @@ -146,6 +146,14 @@ extern const struct clksel_rate gpt_sys_rates[]; extern const struct clksel_rate gfx_l3_rates[]; extern const struct clksel_rate dsp_ick_rates[]; +#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) +extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); +#else +#define omap2_clk_init_cpufreq_table 0 +#define omap2_clk_exit_cpufreq_table 0 +#endif + extern const struct clkops clkops_omap2_iclk_dflt_wait; extern const struct clkops clkops_omap2_iclk_dflt; extern const struct clkops clkops_omap2_iclk_idle_only; diff --git a/trunk/arch/arm/mach-omap2/hwspinlock.c b/trunk/arch/arm/mach-omap2/hwspinlock.c index 454dfce125ca..8763c8520dc2 100644 --- a/trunk/arch/arm/mach-omap2/hwspinlock.c +++ b/trunk/arch/arm/mach-omap2/hwspinlock.c @@ -28,7 +28,7 @@ static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = { .base_id = 0, }; -int __init hwspinlocks_init(void) +static int __init hwspinlocks_init(void) { int retval = 0; struct omap_hwmod *oh; diff --git a/trunk/arch/arm/mach-omap2/omap-wakeupgen.c b/trunk/arch/arm/mach-omap2/omap-wakeupgen.c index 42cd7fb52414..d811c7790350 100644 --- a/trunk/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/trunk/arch/arm/mach-omap2/omap-wakeupgen.c @@ -259,7 +259,7 @@ static void irq_save_context(void) /* * Clear WakeupGen SAR backup status. */ -void irq_sar_clear(void) +static void irq_sar_clear(void) { u32 val; val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index 7144ae651d3d..2c27fdb61e66 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -1422,9 +1422,6 @@ static int _ocp_softreset(struct omap_hwmod *oh) goto dis_opt_clks; _write_sysconfig(v, oh); - if (oh->class->sysc->srst_udelay) - udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) @@ -1906,20 +1903,10 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) */ int omap_hwmod_softreset(struct omap_hwmod *oh) { - u32 v; - int ret; - - if (!oh || !(oh->_sysc_cache)) + if (!oh) return -EINVAL; - v = oh->_sysc_cache; - ret = _set_softreset(oh, &v); - if (ret) - goto error; - _write_sysconfig(v, oh); - -error: - return ret; + return _ocp_softreset(oh); } /** diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a6bde34e443a..a5409ce3f323 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1000,6 +1000,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 04a3885f4475..c4f56cb60d7d 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1049,6 +1049,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { .slave = &omap2430_dss_venc_hwmod, .clk = "dss_ick", .addr = omap2_dss_venc_addrs, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index db86ce90c69f..34b9766d1d23 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1676,6 +1676,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 6abc75753e42..cc9bd106a854 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2594,15 +2594,6 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - /* - * ISS needs 100 OCP clk cycles delay after a softreset before - * accessing sysconfig again. - * The lowest frequency at the moment for L3 bus is 100 MHz, so - * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). - * - * TODO: Indicate errata when available. - */ - .srst_udelay = 2, .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | diff --git a/trunk/arch/arm/mach-omap2/serial.c b/trunk/arch/arm/mach-omap2/serial.c index 9fc2f44188cb..8d22e29d8293 100644 --- a/trunk/arch/arm/mach-omap2/serial.c +++ b/trunk/arch/arm/mach-omap2/serial.c @@ -108,14 +108,8 @@ static void omap_uart_set_noidle(struct platform_device *pdev) static void omap_uart_set_smartidle(struct platform_device *pdev) { struct omap_device *od = to_omap_device(pdev); - u8 idlemode; - if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) - idlemode = HWMOD_IDLEMODE_SMART_WKUP; - else - idlemode = HWMOD_IDLEMODE_SMART; - - omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode); + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); } #else @@ -126,14 +120,130 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX +static struct omap_device_pad default_uart1_pads[] __initdata = { + { + .name = "uart1_cts.uart1_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rts.uart1_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_tx.uart1_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rx.uart1_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart2_pads[] __initdata = { + { + .name = "uart2_cts.uart2_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rts.uart2_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_tx.uart2_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rx.uart2_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart3_pads[] __initdata = { + { + .name = "uart3_cts_rctx.uart3_cts_rctx", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rts_sd.uart3_rts_sd", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_tx_irtx.uart3_tx_irtx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rx_irrx.uart3_rx_irrx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { + { + .name = "gpmc_wait2.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "gpmc_wait3.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + }, +}; + +static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { + { + .name = "uart4_tx.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart4_rx.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + static void omap_serial_fill_default_pads(struct omap_board_data *bdata) { + switch (bdata->id) { + case 0: + bdata->pads = default_uart1_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); + break; + case 1: + bdata->pads = default_uart2_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); + break; + case 2: + bdata->pads = default_uart3_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); + break; + case 3: + if (cpu_is_omap44xx()) { + bdata->pads = default_omap4_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap4_uart4_pads); + } else if (cpu_is_omap3630()) { + bdata->pads = default_omap36xx_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap36xx_uart4_pads); + } + break; + default: + break; + } } #else static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} #endif -char *cmdline_find_option(char *str) +static char *cmdline_find_option(char *str) { extern char *saved_command_line; diff --git a/trunk/arch/arm/mach-omap2/twl-common.c b/trunk/arch/arm/mach-omap2/twl-common.c index 7a7b89304c48..4b57757bf9d1 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.c +++ b/trunk/arch/arm/mach-omap2/twl-common.c @@ -37,16 +37,6 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = { .flags = I2C_CLIENT_WAKE, }; -static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { - { - .addr = 0x48, - .flags = I2C_CLIENT_WAKE, - }, - { - I2C_BOARD_INFO("twl6040", 0x4b), - }, -}; - void __init omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data) @@ -59,31 +49,14 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } -void __init omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data, - struct twl6040_platform_data *twl6040_data, int twl6040_irq) -{ - /* PMIC part*/ - strncpy(omap4_i2c1_board_info[0].type, pmic_type, - sizeof(omap4_i2c1_board_info[0].type)); - omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N; - omap4_i2c1_board_info[0].platform_data = pmic_data; - - /* TWL6040 audio IC part */ - omap4_i2c1_board_info[1].irq = twl6040_irq; - omap4_i2c1_board_info[1].platform_data = twl6040_data; - - omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2); - -} - void __init omap_pmic_late_init(void) { /* Init the OMAP TWL parameters (if PMIC has been registerd) */ - if (pmic_i2c_board_info.irq) - omap3_twl_init(); - if (omap4_i2c1_board_info[0].irq) - omap4_twl_init(); + if (!pmic_i2c_board_info.irq) + return; + + omap3_twl_init(); + omap4_twl_init(); } #if defined(CONFIG_ARCH_OMAP3) diff --git a/trunk/arch/arm/mach-omap2/twl-common.h b/trunk/arch/arm/mach-omap2/twl-common.h index 09627483a57f..275dde8cb27a 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.h +++ b/trunk/arch/arm/mach-omap2/twl-common.h @@ -29,7 +29,6 @@ struct twl4030_platform_data; -struct twl6040_platform_data; void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data); @@ -47,9 +46,12 @@ static inline void omap3_pmic_init(const char *pmic_type, omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data); } -void omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data, - struct twl6040_platform_data *audio_data, int twl6040_irq); +static inline void omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data) +{ + /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */ + omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data); +} void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags); diff --git a/trunk/arch/arm/mach-s5pv210/dma.c b/trunk/arch/arm/mach-s5pv210/dma.c index b8337e248b09..86ce62f66190 100644 --- a/trunk/arch/arm/mach-s5pv210/dma.c +++ b/trunk/arch/arm/mach-s5pv210/dma.c @@ -33,6 +33,8 @@ #include #include +static u64 dma_dmamask = DMA_BIT_MASK(32); + static u8 pdma0_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, diff --git a/trunk/arch/arm/mach-s5pv210/mach-aquila.c b/trunk/arch/arm/mach-s5pv210/mach-aquila.c index 48d018f2332b..a9ea64e0da0d 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-aquila.c +++ b/trunk/arch/arm/mach-s5pv210/mach-aquila.c @@ -484,8 +484,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ diff --git a/trunk/arch/arm/mach-s5pv210/mach-goni.c b/trunk/arch/arm/mach-s5pv210/mach-goni.c index a8933de3d627..2cf5ed75f390 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-goni.c +++ b/trunk/arch/arm/mach-s5pv210/mach-goni.c @@ -674,8 +674,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig index 0e8470a3fbeb..880d02ec89d4 100644 --- a/trunk/arch/arm/mach-ux500/Kconfig +++ b/trunk/arch/arm/mach-ux500/Kconfig @@ -10,10 +10,13 @@ config UX500_SOC_COMMON select ARM_ERRATA_764369 select CACHE_L2X0 +config UX500_SOC_DB5500 + bool + select MFD_DB5500_PRCMU + config UX500_SOC_DB8500 bool select MFD_DB8500_PRCMU - select REGULATOR select REGULATOR_DB8500_PRCMU select CPU_FREQ_TABLE if CPU_FREQ @@ -41,8 +44,15 @@ config MACH_SNOWBALL help Include support for the snowball development platform. +config MACH_U5500 + bool "U5500 Development platform" + select UX500_SOC_DB5500 + help + Include support for the U5500 development platform. + config UX500_AUTO_PLATFORM def_bool y + depends on !MACH_U5500 select MACH_MOP500 help At least one platform needs to be selected in order to build @@ -63,4 +73,18 @@ config UX500_DEBUG_UART Choose the UART on which kernel low-level debug messages should be output. +config U5500_MODEM_IRQ + bool "Modem IRQ support" + depends on UX500_SOC_DB5500 + default y + help + Add support for handling IRQ:s from modem side + +config U5500_MBOX + bool "Mailbox support" + depends on U5500_MODEM_IRQ + default y + help + Add support for U5500 mailbox communication with modem side + endif diff --git a/trunk/arch/arm/mach-ux500/Makefile b/trunk/arch/arm/mach-ux500/Makefile index fc7db5df970b..465b9ec9510a 100644 --- a/trunk/arch/arm/mach-ux500/Makefile +++ b/trunk/arch/arm/mach-ux500/Makefile @@ -5,11 +5,16 @@ obj-y := clock.o cpu.o devices.o devices-common.o \ id.o usb.o timer.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o +obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ board-mop500-regulators.o \ board-mop500-uib.o board-mop500-stuib.o \ board-mop500-u8500uib.o \ board-mop500-pins.o +obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o +obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o +obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o + diff --git a/trunk/arch/arm/mach-ux500/board-u5500-sdi.c b/trunk/arch/arm/mach-ux500/board-u5500-sdi.c new file mode 100644 index 000000000000..836112eedde7 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/board-u5500-sdi.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Hanumath Prasad + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include + +#include +#include +#include +#include + +#include "pins-db5500.h" +#include "devices-db5500.h" +#include "ste-dma40-db5500.h" + +static pin_cfg_t u5500_sdi_pins[] = { + /* SDI0 (POP eMMC) */ + GPIO5_MC0_DAT0 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO6_MC0_DAT1 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO7_MC0_DAT2 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO8_MC0_DAT3 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO9_MC0_DAT4 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO10_MC0_DAT5 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO11_MC0_DAT6 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO12_MC0_DAT7 | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO13_MC0_CMD | PIN_DIR_INPUT | PIN_PULL_UP, + GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW, +}; + +#ifdef CONFIG_STE_DMA40 +struct stedma40_chan_cfg u5500_sdi0_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB5500_DMA_DEV24_SDMMC0_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; + +static struct stedma40_chan_cfg u5500_sdi0_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB5500_DMA_DEV24_SDMMC0_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; +#endif + +static struct mmci_platform_data u5500_sdi0_data = { + .ocr_mask = MMC_VDD_165_195, + .f_max = 50000000, + .capabilities = MMC_CAP_4_BIT_DATA | + MMC_CAP_8_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED, + .gpio_cd = -1, + .gpio_wp = -1, +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &u5500_sdi0_dma_cfg_rx, + .dma_tx_param = &u5500_sdi0_dma_cfg_tx, +#endif +}; + +void __init u5500_sdi_init(struct device *parent) +{ + nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); + + db5500_add_sdi0(parent, &u5500_sdi0_data); +} diff --git a/trunk/arch/arm/mach-ux500/board-u5500.c b/trunk/arch/arm/mach-ux500/board-u5500.c new file mode 100644 index 000000000000..0ff4be72a809 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/board-u5500.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "pins-db5500.h" +#include "devices-db5500.h" +#include + +/* + * GPIO + */ + +static pin_cfg_t u5500_pins[] = { + /* I2C */ + GPIO218_I2C2_SCL | PIN_INPUT_PULLUP, + GPIO219_I2C2_SDA | PIN_INPUT_PULLUP, + + /* DISPLAY_ENABLE */ + GPIO226_GPIO | PIN_OUTPUT_LOW, + + /* Backlight Enbale */ + GPIO224_GPIO | PIN_OUTPUT_HIGH, +}; +/* + * I2C + */ + +#define U5500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ +static struct nmk_i2c_controller u5500_i2c##id##_data = { \ + /* \ + * slave data setup time, which is \ + * 250 ns,100ns,10ns which is 14,6,2 \ + * respectively for a 48 Mhz \ + * i2c clock \ + */ \ + .slsu = _slsu, \ + /* Tx FIFO threshold */ \ + .tft = _tft, \ + /* Rx FIFO threshold */ \ + .rft = _rft, \ + /* std. mode operation */ \ + .clk_freq = clk, \ + .sm = _sm, \ +} +/* + * The board uses TODO <3> i2c controllers, initialize all of + * them with slave data setup time of 250 ns, + * Tx & Rx FIFO threshold values as 1 and standard + * mode of operation + */ + +U5500_I2C_CONTROLLER(2, 0xe, 1, 1, 400000, I2C_FREQ_MODE_FAST); + +static struct lm3530_platform_data u5500_als_platform_data = { + .mode = LM3530_BL_MODE_MANUAL, + .als_input_mode = LM3530_INPUT_ALS1, + .max_current = LM3530_FS_CURR_26mA, + .pwm_pol_hi = true, + .als_avrg_time = LM3530_ALS_AVRG_TIME_512ms, + .brt_ramp_law = 1, /* Linear */ + .brt_ramp_fall = LM3530_RAMP_TIME_8s, + .brt_ramp_rise = LM3530_RAMP_TIME_8s, + .als1_resistor_sel = LM3530_ALS_IMPD_13_53kOhm, + .als2_resistor_sel = LM3530_ALS_IMPD_Z, + .als_vmin = 730, /* mV */ + .als_vmax = 1020, /* mV */ + .brt_val = 0x7F, /* Max brightness */ +}; + +static struct i2c_board_info __initdata u5500_i2c2_devices[] = { + { + /* Backlight */ + I2C_BOARD_INFO("lm3530-led", 0x36), + .platform_data = &u5500_als_platform_data, + }, +}; + +static void __init u5500_i2c_init(struct device *parent) +{ + db5500_add_i2c2(parent, &u5500_i2c2_data); + i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); +} + +static struct ab5500_platform_data ab5500_plf_data = { + .irq = { + .base = 0, + .count = 0, + }, + .init_settings = NULL, + .init_settings_sz = 0, + .pm_power_off = false, +}; + +static struct platform_device ab5500_device = { + .name = "ab5500-core", + .id = 0, + .dev = { + .platform_data = &ab5500_plf_data, + }, + .num_resources = 0, +}; + +static struct platform_device *u5500_platform_devices[] __initdata = { + &ab5500_device, +}; + +static void __init u5500_uart_init(struct device *parent) +{ + db5500_add_uart0(parent, NULL); + db5500_add_uart1(parent, NULL); + db5500_add_uart2(parent, NULL); +} + +static void __init u5500_init_machine(void) +{ + struct device *parent = NULL; + int i; + + parent = u5500_init_devices(); + nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins)); + + u5500_i2c_init(parent); + u5500_sdi_init(parent); + u5500_uart_init(parent); + + for (i = 0; i < ARRAY_SIZE(u5500_platform_devices); i++) + u5500_platform_devices[i]->dev.parent = parent; + + platform_add_devices(u5500_platform_devices, + ARRAY_SIZE(u5500_platform_devices)); +} + +MACHINE_START(U5500, "ST-Ericsson U5500 Platform") + .atag_offset = 0x100, + .map_io = u5500_map_io, + .init_irq = ux500_init_irq, + .timer = &ux500_timer, + .handle_irq = gic_handle_irq, + .init_machine = u5500_init_machine, +MACHINE_END diff --git a/trunk/arch/arm/mach-ux500/cache-l2x0.c b/trunk/arch/arm/mach-ux500/cache-l2x0.c index df91344aa2db..77a75ed0df67 100644 --- a/trunk/arch/arm/mach-ux500/cache-l2x0.c +++ b/trunk/arch/arm/mach-ux500/cache-l2x0.c @@ -36,7 +36,9 @@ static int __init ux500_l2x0_unlock(void) static int __init ux500_l2x0_init(void) { - if (cpu_is_u8500()) + if (cpu_is_u5500()) + l2x0_base = __io_address(U5500_L2CC_BASE); + else if (cpu_is_u8500()) l2x0_base = __io_address(U8500_L2CC_BASE); else ux500_unknown_soc(); diff --git a/trunk/arch/arm/mach-ux500/clock.c b/trunk/arch/arm/mach-ux500/clock.c index 9feb6bc7f20e..ec35f0aa5665 100644 --- a/trunk/arch/arm/mach-ux500/clock.c +++ b/trunk/arch/arm/mach-ux500/clock.c @@ -149,7 +149,9 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) unsigned long mturate; unsigned long retclk; - if (cpu_is_u8500()) + if (cpu_is_u5500()) + addr = __io_address(U5500_PRCMU_BASE); + else if (cpu_is_u8500()) addr = __io_address(U8500_PRCMU_BASE); else ux500_unknown_soc(); @@ -703,6 +705,14 @@ late_initcall(clk_init_smp_twd_cpufreq); int __init clk_init(void) { + if (cpu_is_u5500()) { + /* Clock tree for U5500 not implemented yet */ + clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; + clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; + clk_uartclk.rate = 36360000; + clk_sdmmcclk.rate = 99900000; + } + clkdev_add_table(u8500_clks, ARRAY_SIZE(u8500_clks)); clkdev_add(&clk_smp_twd_lookup); diff --git a/trunk/arch/arm/mach-ux500/cpu-db5500.c b/trunk/arch/arm/mach-ux500/cpu-db5500.c new file mode 100644 index 000000000000..bca47f32082f --- /dev/null +++ b/trunk/arch/arm/mach-ux500/cpu-db5500.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "devices-db5500.h" +#include "ste-dma40-db5500.h" + +static struct map_desc u5500_uart_io_desc[] __initdata = { + __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_UART2_BASE, SZ_4K), +}; + +static struct map_desc u5500_io_desc[] __initdata = { + /* SCU base also covers GIC CPU BASE and TWD with its 4K page */ + __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K), + __IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K), + __IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K), + + __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K), + __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_PRCMU_TCDM_BASE, SZ_4K), +}; + +static struct resource mbox0_resources[] = { + { + .name = "mbox_peer", + .start = U5500_MBOX0_PEER_START, + .end = U5500_MBOX0_PEER_END, + .flags = IORESOURCE_MEM, + }, + { + .name = "mbox_local", + .start = U5500_MBOX0_LOCAL_START, + .end = U5500_MBOX0_LOCAL_END, + .flags = IORESOURCE_MEM, + }, + { + .name = "mbox_irq", + .start = MBOX_PAIR0_VIRT_IRQ, + .end = MBOX_PAIR0_VIRT_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource mbox1_resources[] = { + { + .name = "mbox_peer", + .start = U5500_MBOX1_PEER_START, + .end = U5500_MBOX1_PEER_END, + .flags = IORESOURCE_MEM, + }, + { + .name = "mbox_local", + .start = U5500_MBOX1_LOCAL_START, + .end = U5500_MBOX1_LOCAL_END, + .flags = IORESOURCE_MEM, + }, + { + .name = "mbox_irq", + .start = MBOX_PAIR1_VIRT_IRQ, + .end = MBOX_PAIR1_VIRT_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource mbox2_resources[] = { + { + .name = "mbox_peer", + .start = U5500_MBOX2_PEER_START, + .end = U5500_MBOX2_PEER_END, + .flags = IORESOURCE_MEM, + }, + { + .name = "mbox_local", + .start = U5500_MBOX2_LOCAL_START, + .end = U5500_MBOX2_LOCAL_END, + .flags = IORESOURCE_MEM, + }, + { + .name = "mbox_irq", + .start = MBOX_PAIR2_VIRT_IRQ, + .end = MBOX_PAIR2_VIRT_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device mbox0_device = { + .id = 0, + .name = "mbox", + .resource = mbox0_resources, + .num_resources = ARRAY_SIZE(mbox0_resources), +}; + +static struct platform_device mbox1_device = { + .id = 1, + .name = "mbox", + .resource = mbox1_resources, + .num_resources = ARRAY_SIZE(mbox1_resources), +}; + +static struct platform_device mbox2_device = { + .id = 2, + .name = "mbox", + .resource = mbox2_resources, + .num_resources = ARRAY_SIZE(mbox2_resources), +}; + +static struct platform_device *db5500_platform_devs[] __initdata = { + &mbox0_device, + &mbox1_device, + &mbox2_device, +}; + +static resource_size_t __initdata db5500_gpio_base[] = { + U5500_GPIOBANK0_BASE, + U5500_GPIOBANK1_BASE, + U5500_GPIOBANK2_BASE, + U5500_GPIOBANK3_BASE, + U5500_GPIOBANK4_BASE, + U5500_GPIOBANK5_BASE, + U5500_GPIOBANK6_BASE, + U5500_GPIOBANK7_BASE, +}; + +static void __init db5500_add_gpios(struct device *parent) +{ + struct nmk_gpio_platform_data pdata = { + /* No custom data yet */ + }; + + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base), + IRQ_DB5500_GPIO0, &pdata); +} + +void __init u5500_map_io(void) +{ + /* + * Map the UARTs early so that the DEBUG_LL stuff continues to work. + */ + iotable_init(u5500_uart_io_desc, ARRAY_SIZE(u5500_uart_io_desc)); + + ux500_map_io(); + + iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); + + _PRCMU_BASE = __io_address(U5500_PRCMU_BASE); +} + +static void __init db5500_pmu_init(void) +{ + struct resource res[] = { + [0] = { + .start = IRQ_DB5500_PMU0, + .end = IRQ_DB5500_PMU0, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_DB5500_PMU1, + .end = IRQ_DB5500_PMU1, + .flags = IORESOURCE_IRQ, + }, + }; + + platform_device_register_simple("arm-pmu", ARM_PMU_DEVICE_CPU, + res, ARRAY_SIZE(res)); +} + +static int usb_db5500_rx_dma_cfg[] = { + DB5500_DMA_DEV4_USB_OTG_IEP_1_9, + DB5500_DMA_DEV5_USB_OTG_IEP_2_10, + DB5500_DMA_DEV6_USB_OTG_IEP_3_11, + DB5500_DMA_DEV20_USB_OTG_IEP_4_12, + DB5500_DMA_DEV21_USB_OTG_IEP_5_13, + DB5500_DMA_DEV22_USB_OTG_IEP_6_14, + DB5500_DMA_DEV23_USB_OTG_IEP_7_15, + DB5500_DMA_DEV38_USB_OTG_IEP_8 +}; + +static int usb_db5500_tx_dma_cfg[] = { + DB5500_DMA_DEV4_USB_OTG_OEP_1_9, + DB5500_DMA_DEV5_USB_OTG_OEP_2_10, + DB5500_DMA_DEV6_USB_OTG_OEP_3_11, + DB5500_DMA_DEV20_USB_OTG_OEP_4_12, + DB5500_DMA_DEV21_USB_OTG_OEP_5_13, + DB5500_DMA_DEV22_USB_OTG_OEP_6_14, + DB5500_DMA_DEV23_USB_OTG_OEP_7_15, + DB5500_DMA_DEV38_USB_OTG_OEP_8 +}; + +static const char *db5500_read_soc_id(void) +{ + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + int i; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); + db5500_pmu_init(); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + + for (i = 0; i < ARRAY_SIZE(db5500_platform_devs); i++) + db5500_platform_devs[i]->dev.parent = parent; + + platform_add_devices(db5500_platform_devs, + ARRAY_SIZE(db5500_platform_devs)); + + return parent; +} diff --git a/trunk/arch/arm/mach-ux500/cpu.c b/trunk/arch/arm/mach-ux500/cpu.c index 4b4e59b30d81..d11f3892a27d 100644 --- a/trunk/arch/arm/mach-ux500/cpu.c +++ b/trunk/arch/arm/mach-ux500/cpu.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,10 @@ void __init ux500_init_irq(void) void __iomem *dist_base; void __iomem *cpu_base; - if (cpu_is_u8500()) { + if (cpu_is_u5500()) { + dist_base = __io_address(U5500_GIC_DIST_BASE); + cpu_base = __io_address(U5500_GIC_CPU_BASE); + } else if (cpu_is_u8500()) { dist_base = __io_address(U8500_GIC_DIST_BASE); cpu_base = __io_address(U8500_GIC_CPU_BASE); } else @@ -56,6 +60,8 @@ void __init ux500_init_irq(void) * Init clocks here so that they are available for system timer * initialization. */ + if (cpu_is_u5500()) + db5500_prcmu_early_init(); if (cpu_is_u8500()) db8500_prcmu_early_init(); clk_init(); diff --git a/trunk/arch/arm/mach-ux500/devices-db5500.h b/trunk/arch/arm/mach-ux500/devices-db5500.h new file mode 100644 index 000000000000..e70955502c35 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/devices-db5500.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef __DEVICES_DB5500_H +#define __DEVICES_DB5500_H + +#include "devices-common.h" + +#define db5500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) +#define db5500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) +#define db5500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) + +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) + +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) + +#define db5500_add_rtc(parent) \ + dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC); + +#define db5500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U5500_USBOTG_BASE, \ + IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) + +#define db5500_add_sdi0(parent, pdata) \ + dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \ + IRQ_DB5500_SDMMC0, pdata, \ + 0x10480180) +#define db5500_add_sdi1(parent, pdata) \ + dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \ + IRQ_DB5500_SDMMC1, pdata, \ + 0x10480180) +#define db5500_add_sdi2(parent, pdata) \ + dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \ + IRQ_DB5500_SDMMC2, pdata \ + 0x10480180) +#define db5500_add_sdi3(parent, pdata) \ + dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \ + IRQ_DB5500_SDMMC3, pdata \ + 0x10480180) +#define db5500_add_sdi4(parent, pdata) \ + dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \ + IRQ_DB5500_SDMMC4, pdata \ + 0x10480180) + +/* This one has a bad peripheral ID in the U5500 silicon */ +#define db5500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \ + IRQ_DB5500_SPI0, pdata, \ + 0x10080023) +#define db5500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \ + IRQ_DB5500_SPI1, pdata, \ + 0x10080023) +#define db5500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \ + IRQ_DB5500_SPI2, pdata \ + 0x10080023) +#define db5500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \ + IRQ_DB5500_SPI3, pdata \ + 0x10080023) + +#define db5500_add_uart0(parent, plat) \ + dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \ + IRQ_DB5500_UART0, plat) +#define db5500_add_uart1(parent, plat) \ + dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \ + IRQ_DB5500_UART1, plat) +#define db5500_add_uart2(parent, plat) \ + dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \ + IRQ_DB5500_UART2, plat) +#define db5500_add_uart3(parent, plat) \ + dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \ + IRQ_DB5500_UART3, plat) + +#endif diff --git a/trunk/arch/arm/mach-ux500/dma-db5500.c b/trunk/arch/arm/mach-ux500/dma-db5500.c new file mode 100644 index 000000000000..41e9470fa0e6 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/dma-db5500.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Per Forlin for ST-Ericsson + * Author: Jonas Aaberg for ST-Ericsson + * Author: Rabin Vincent for ST-Ericsson + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include + +#include +#include +#include + +#include "ste-dma40-db5500.h" + +static struct resource dma40_resources[] = { + [0] = { + .start = U5500_DMA_BASE, + .end = U5500_DMA_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "base", + }, + [1] = { + .start = U5500_DMA_LCPA_BASE, + .end = U5500_DMA_LCPA_BASE + 2 * SZ_1K - 1, + .flags = IORESOURCE_MEM, + .name = "lcpa", + }, + [2] = { + .start = IRQ_DB5500_DMA, + .end = IRQ_DB5500_DMA, + .flags = IORESOURCE_IRQ + } +}; + +/* Default configuration for physical memcpy */ +static struct stedma40_chan_cfg dma40_memcpy_conf_phy = { + .mode = STEDMA40_MODE_PHYSICAL, + .dir = STEDMA40_MEM_TO_MEM, + + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.psize = STEDMA40_PSIZE_PHY_1, + .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + + .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.psize = STEDMA40_PSIZE_PHY_1, + .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +}; + +/* Default configuration for logical memcpy */ +static struct stedma40_chan_cfg dma40_memcpy_conf_log = { + .dir = STEDMA40_MEM_TO_MEM, + + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.psize = STEDMA40_PSIZE_LOG_1, + .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + + .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.psize = STEDMA40_PSIZE_LOG_1, + .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +}; + +/* + * Mapping between soruce event lines and physical device address This was + * created assuming that the event line is tied to a device and therefore the + * address is constant, however this is not true for at least USB, and the + * values are just placeholders for USB. This table is preserved and used for + * now. + */ +static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = { + [DB5500_DMA_DEV24_SDMMC0_RX] = -1, + [DB5500_DMA_DEV38_USB_OTG_IEP_8] = -1, + [DB5500_DMA_DEV23_USB_OTG_IEP_7_15] = -1, + [DB5500_DMA_DEV22_USB_OTG_IEP_6_14] = -1, + [DB5500_DMA_DEV21_USB_OTG_IEP_5_13] = -1, + [DB5500_DMA_DEV20_USB_OTG_IEP_4_12] = -1, + [DB5500_DMA_DEV6_USB_OTG_IEP_3_11] = -1, + [DB5500_DMA_DEV5_USB_OTG_IEP_2_10] = -1, + [DB5500_DMA_DEV4_USB_OTG_IEP_1_9] = -1, +}; + +/* Mapping between destination event lines and physical device address */ +static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = { + [DB5500_DMA_DEV24_SDMMC0_TX] = -1, + [DB5500_DMA_DEV38_USB_OTG_OEP_8] = -1, + [DB5500_DMA_DEV23_USB_OTG_OEP_7_15] = -1, + [DB5500_DMA_DEV22_USB_OTG_OEP_6_14] = -1, + [DB5500_DMA_DEV21_USB_OTG_OEP_5_13] = -1, + [DB5500_DMA_DEV20_USB_OTG_OEP_4_12] = -1, + [DB5500_DMA_DEV6_USB_OTG_OEP_3_11] = -1, + [DB5500_DMA_DEV5_USB_OTG_OEP_2_10] = -1, + [DB5500_DMA_DEV4_USB_OTG_OEP_1_9] = -1, +}; + +static int dma40_memcpy_event[] = { + DB5500_DMA_MEMCPY_TX_1, + DB5500_DMA_MEMCPY_TX_2, + DB5500_DMA_MEMCPY_TX_3, + DB5500_DMA_MEMCPY_TX_4, + DB5500_DMA_MEMCPY_TX_5, +}; + +static struct stedma40_platform_data dma40_plat_data = { + .dev_len = ARRAY_SIZE(dma40_rx_map), + .dev_rx = dma40_rx_map, + .dev_tx = dma40_tx_map, + .memcpy = dma40_memcpy_event, + .memcpy_len = ARRAY_SIZE(dma40_memcpy_event), + .memcpy_conf_phy = &dma40_memcpy_conf_phy, + .memcpy_conf_log = &dma40_memcpy_conf_log, + .disabled_channels = {-1}, +}; + +static struct platform_device dma40_device = { + .dev = { + .platform_data = &dma40_plat_data, + }, + .name = "dma40", + .id = 0, + .num_resources = ARRAY_SIZE(dma40_resources), + .resource = dma40_resources +}; + +void __init db5500_dma_init(struct device *parent) +{ + int ret; + + dma40_device.dev.parent = parent; + ret = platform_device_register(&dma40_device); + if (ret) + dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); + +} diff --git a/trunk/arch/arm/mach-ux500/include/mach/db5500-regs.h b/trunk/arch/arm/mach-ux500/include/mach/db5500-regs.h new file mode 100644 index 000000000000..8e714bcb099f --- /dev/null +++ b/trunk/arch/arm/mach-ux500/include/mach/db5500-regs.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __MACH_DB5500_REGS_H +#define __MACH_DB5500_REGS_H + +#define U5500_PER1_BASE 0xA0020000 +#define U5500_PER2_BASE 0xA0010000 +#define U5500_PER3_BASE 0x80140000 +#define U5500_PER4_BASE 0x80150000 +#define U5500_PER5_BASE 0x80100000 +#define U5500_PER6_BASE 0x80120000 + +#define U5500_GIC_DIST_BASE 0xA0411000 +#define U5500_GIC_CPU_BASE 0xA0410100 +#define U5500_DMA_BASE 0x90030000 +#define U5500_STM_BASE 0x90020000 +#define U5500_STM_REG_BASE (U5500_STM_BASE + 0xF000) +#define U5500_MCDE_BASE 0xA0400000 +#define U5500_MODEM_BASE 0xB0000000 +#define U5500_L2CC_BASE 0xA0412000 +#define U5500_SCU_BASE 0xA0410000 +#define U5500_DSI1_BASE 0xA0401000 +#define U5500_DSI2_BASE 0xA0402000 +#define U5500_SIA_BASE 0xA0100000 +#define U5500_SVA_BASE 0x80200000 +#define U5500_HSEM_BASE 0xA0000000 +#define U5500_NAND0_BASE 0x60000000 +#define U5500_NAND1_BASE 0x70000000 +#define U5500_TWD_BASE 0xa0410600 +#define U5500_ICN_BASE 0xA0040000 +#define U5500_B2R2_BASE 0xa0200000 +#define U5500_BOOT_ROM_BASE 0x90000000 + +#define U5500_FSMC_BASE (U5500_PER1_BASE + 0x0000) +#define U5500_SDI0_BASE (U5500_PER1_BASE + 0x1000) +#define U5500_SDI2_BASE (U5500_PER1_BASE + 0x2000) +#define U5500_UART0_BASE (U5500_PER1_BASE + 0x3000) +#define U5500_I2C1_BASE (U5500_PER1_BASE + 0x4000) +#define U5500_MSP0_BASE (U5500_PER1_BASE + 0x5000) +#define U5500_GPIO0_BASE (U5500_PER1_BASE + 0xE000) +#define U5500_CLKRST1_BASE (U5500_PER1_BASE + 0xF000) + +#define U5500_USBOTG_BASE (U5500_PER2_BASE + 0x0000) +#define U5500_GPIO1_BASE (U5500_PER2_BASE + 0xE000) +#define U5500_CLKRST2_BASE (U5500_PER2_BASE + 0xF000) + +#define U5500_KEYPAD_BASE (U5500_PER3_BASE + 0x0000) +#define U5500_PWM_BASE (U5500_PER3_BASE + 0x1000) +#define U5500_GPIO3_BASE (U5500_PER3_BASE + 0xE000) +#define U5500_CLKRST3_BASE (U5500_PER3_BASE + 0xF000) + +#define U5500_BACKUPRAM0_BASE (U5500_PER4_BASE + 0x0000) +#define U5500_BACKUPRAM1_BASE (U5500_PER4_BASE + 0x1000) +#define U5500_RTT0_BASE (U5500_PER4_BASE + 0x2000) +#define U5500_RTT1_BASE (U5500_PER4_BASE + 0x3000) +#define U5500_RTC_BASE (U5500_PER4_BASE + 0x4000) +#define U5500_SCR_BASE (U5500_PER4_BASE + 0x5000) +#define U5500_DMC_BASE (U5500_PER4_BASE + 0x6000) +#define U5500_PRCMU_BASE (U5500_PER4_BASE + 0x7000) +#define U5500_PRCMU_TIMER_3_BASE (U5500_PER4_BASE + 0x07338) +#define U5500_PRCMU_TIMER_4_BASE (U5500_PER4_BASE + 0x07450) +#define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000) +#define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000) +#define U5500_MTIMER_BASE (U5500_PER4_BASE + 0xC000) +#define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000) +#define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000) +#define U5500_PRCMU_TCPM_BASE (U5500_PER4_BASE + 0x10000) +#define U5500_TPIU_BASE (U5500_PER4_BASE + 0x50000) + +#define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000) +#define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000) +#define U5500_SPI2_BASE (U5500_PER5_BASE + 0x2000) +#define U5500_SPI3_BASE (U5500_PER5_BASE + 0x3000) +#define U5500_UART1_BASE (U5500_PER5_BASE + 0x4000) +#define U5500_UART2_BASE (U5500_PER5_BASE + 0x5000) +#define U5500_UART3_BASE (U5500_PER5_BASE + 0x6000) +#define U5500_SDI1_BASE (U5500_PER5_BASE + 0x7000) +#define U5500_SDI3_BASE (U5500_PER5_BASE + 0x8000) +#define U5500_SDI4_BASE (U5500_PER5_BASE + 0x9000) +#define U5500_I2C2_BASE (U5500_PER5_BASE + 0xA000) +#define U5500_I2C3_BASE (U5500_PER5_BASE + 0xB000) +#define U5500_MSP2_BASE (U5500_PER5_BASE + 0xC000) +#define U5500_IRDA_BASE (U5500_PER5_BASE + 0xD000) +#define U5500_IRRC_BASE (U5500_PER5_BASE + 0x10000) +#define U5500_GPIO4_BASE (U5500_PER5_BASE + 0x1E000) +#define U5500_CLKRST5_BASE (U5500_PER5_BASE + 0x1F000) + +#define U5500_RNG_BASE (U5500_PER6_BASE + 0x0000) +#define U5500_HASH0_BASE (U5500_PER6_BASE + 0x1000) +#define U5500_HASH1_BASE (U5500_PER6_BASE + 0x2000) +#define U5500_PKA_BASE (U5500_PER6_BASE + 0x4000) +#define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5100) +#define U5500_MTU0_BASE (U5500_PER6_BASE + 0x6000) +#define U5500_MTU1_BASE (U5500_PER6_BASE + 0x7000) +#define U5500_CR_BASE (U5500_PER6_BASE + 0x8000) +#define U5500_CRYP0_BASE (U5500_PER6_BASE + 0xA000) +#define U5500_CRYP1_BASE (U5500_PER6_BASE + 0xB000) +#define U5500_CLKRST6_BASE (U5500_PER6_BASE + 0xF000) + +#define U5500_GPIOBANK0_BASE U5500_GPIO0_BASE +#define U5500_GPIOBANK1_BASE (U5500_GPIO0_BASE + 0x80) +#define U5500_GPIOBANK2_BASE U5500_GPIO1_BASE +#define U5500_GPIOBANK3_BASE U5500_GPIO2_BASE +#define U5500_GPIOBANK4_BASE U5500_GPIO3_BASE +#define U5500_GPIOBANK5_BASE U5500_GPIO4_BASE +#define U5500_GPIOBANK6_BASE (U5500_GPIO4_BASE + 0x80) +#define U5500_GPIOBANK7_BASE (U5500_GPIO4_BASE + 0x100) + +#define U5500_MBOX_BASE (U5500_MODEM_BASE + 0xFFD1000) +#define U5500_MBOX0_PEER_START (U5500_MBOX_BASE + 0x40) +#define U5500_MBOX0_PEER_END (U5500_MBOX_BASE + 0x5F) +#define U5500_MBOX0_LOCAL_START (U5500_MBOX_BASE + 0x60) +#define U5500_MBOX0_LOCAL_END (U5500_MBOX_BASE + 0x7F) +#define U5500_MBOX1_PEER_START (U5500_MBOX_BASE + 0x80) +#define U5500_MBOX1_PEER_END (U5500_MBOX_BASE + 0x9F) +#define U5500_MBOX1_LOCAL_START (U5500_MBOX_BASE + 0xA0) +#define U5500_MBOX1_LOCAL_END (U5500_MBOX_BASE + 0xBF) +#define U5500_MBOX2_PEER_START (U5500_MBOX_BASE + 0x00) +#define U5500_MBOX2_PEER_END (U5500_MBOX_BASE + 0x1F) +#define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) +#define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) + +#define U5500_ACCCON_BASE_SEC (0xBFFF0000) +#define U5500_ACCCON_BASE (0xBFFF1000) +#define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020) +#define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC) +#define U5500_INTCON_MBOX1_INT_RESET_ADDR (0xBFFD31A4) + +#define U5500_ESRAM_BASE 0x40000000 +#define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000 +#define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET) + +#define U5500_MCDE_SIZE 0x1000 +#define U5500_DSI_LINK_SIZE 0x1000 +#define U5500_DSI_LINK_COUNT 0x2 +#define U5500_DSI_LINK1_BASE (U5500_MCDE_BASE + U5500_MCDE_SIZE) +#define U5500_DSI_LINK2_BASE (U5500_DSI_LINK1_BASE + U5500_DSI_LINK_SIZE) + +#endif diff --git a/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S b/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S index 67035223334a..8d74d927d4e2 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S @@ -20,6 +20,10 @@ * built, so that there's some hint during the build that something is wrong. */ +#ifdef CONFIG_UX500_SOC_DB5500 +#define __UX500_UART(n) U5500_UART##n##_BASE +#endif + #ifdef CONFIG_UX500_SOC_DB8500 #define __UX500_UART(n) U8500_UART##n##_BASE #endif diff --git a/trunk/arch/arm/mach-ux500/include/mach/devices.h b/trunk/arch/arm/mach-ux500/include/mach/devices.h index 9b5eb69a0154..5f6cb71fc62d 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/devices.h +++ b/trunk/arch/arm/mach-ux500/include/mach/devices.h @@ -10,6 +10,7 @@ struct platform_device; struct amba_device; +extern struct platform_device u5500_gpio_devs[]; extern struct platform_device u8500_gpio_devs[]; extern struct amba_device ux500_pl031_device; diff --git a/trunk/arch/arm/mach-ux500/include/mach/hardware.h b/trunk/arch/arm/mach-ux500/include/mach/hardware.h index cf6fac3d1eeb..f84698936d36 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/hardware.h +++ b/trunk/arch/arm/mach-ux500/include/mach/hardware.h @@ -28,6 +28,7 @@ #define io_p2v(n) __io_address(n) #include +#include #define MSP_TX_RX_REG_OFFSET 0 diff --git a/trunk/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h b/trunk/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h new file mode 100644 index 000000000000..29d972c7717b --- /dev/null +++ b/trunk/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __MACH_IRQS_BOARD_U5500_H +#define __MACH_IRQS_BOARD_U5500_H + +#define AB5500_NR_IRQS 5 +#define IRQ_AB5500_BASE IRQ_BOARD_START +#define IRQ_AB5500_END (IRQ_AB5500_BASE + AB5500_NR_IRQS) + +#define U5500_IRQ_END IRQ_AB5500_END + +#if IRQ_BOARD_END < U5500_IRQ_END +#undef IRQ_BOARD_END +#define IRQ_BOARD_END U5500_IRQ_END +#endif + +#endif diff --git a/trunk/arch/arm/mach-ux500/include/mach/irqs-db5500.h b/trunk/arch/arm/mach-ux500/include/mach/irqs-db5500.h new file mode 100644 index 000000000000..77239776a6f2 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/include/mach/irqs-db5500.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __MACH_IRQS_DB5500_H +#define __MACH_IRQS_DB5500_H + +#define IRQ_DB5500_MTU0 (IRQ_SHPI_START + 4) +#define IRQ_DB5500_SPI2 (IRQ_SHPI_START + 6) +#define IRQ_DB5500_PMU0 (IRQ_SHPI_START + 7) +#define IRQ_DB5500_SPI0 (IRQ_SHPI_START + 8) +#define IRQ_DB5500_RTT (IRQ_SHPI_START + 9) +#define IRQ_DB5500_PKA (IRQ_SHPI_START + 10) +#define IRQ_DB5500_UART0 (IRQ_SHPI_START + 11) +#define IRQ_DB5500_I2C3 (IRQ_SHPI_START + 12) +#define IRQ_DB5500_L2CC (IRQ_SHPI_START + 13) +#define IRQ_DB5500_MSP0 (IRQ_SHPI_START + 14) +#define IRQ_DB5500_CRYP1 (IRQ_SHPI_START + 15) +#define IRQ_DB5500_PMU1 (IRQ_SHPI_START + 16) +#define IRQ_DB5500_MTU1 (IRQ_SHPI_START + 17) +#define IRQ_DB5500_RTC (IRQ_SHPI_START + 18) +#define IRQ_DB5500_UART1 (IRQ_SHPI_START + 19) +#define IRQ_DB5500_USB_WAKEUP (IRQ_SHPI_START + 20) +#define IRQ_DB5500_I2C0 (IRQ_SHPI_START + 21) +#define IRQ_DB5500_I2C1 (IRQ_SHPI_START + 22) +#define IRQ_DB5500_USBOTG (IRQ_SHPI_START + 23) +#define IRQ_DB5500_DMA_SECURE (IRQ_SHPI_START + 24) +#define IRQ_DB5500_DMA (IRQ_SHPI_START + 25) +#define IRQ_DB5500_UART2 (IRQ_SHPI_START + 26) +#define IRQ_DB5500_ICN_PMU1 (IRQ_SHPI_START + 27) +#define IRQ_DB5500_ICN_PMU2 (IRQ_SHPI_START + 28) +#define IRQ_DB5500_UART3 (IRQ_SHPI_START + 29) +#define IRQ_DB5500_SPI3 (IRQ_SHPI_START + 30) +#define IRQ_DB5500_SDMMC4 (IRQ_SHPI_START + 31) +#define IRQ_DB5500_IRRC (IRQ_SHPI_START + 33) +#define IRQ_DB5500_IRDA_FT (IRQ_SHPI_START + 34) +#define IRQ_DB5500_IRDA_SD (IRQ_SHPI_START + 35) +#define IRQ_DB5500_IRDA_FI (IRQ_SHPI_START + 36) +#define IRQ_DB5500_IRDA_FD (IRQ_SHPI_START + 37) +#define IRQ_DB5500_FSMC_CODEREADY (IRQ_SHPI_START + 38) +#define IRQ_DB5500_FSMC_NANDWAIT (IRQ_SHPI_START + 39) +#define IRQ_DB5500_AB5500 (IRQ_SHPI_START + 40) +#define IRQ_DB5500_SDMMC2 (IRQ_SHPI_START + 41) +#define IRQ_DB5500_SIA (IRQ_SHPI_START + 42) +#define IRQ_DB5500_SIA2 (IRQ_SHPI_START + 43) +#define IRQ_DB5500_HVA (IRQ_SHPI_START + 44) +#define IRQ_DB5500_HVA2 (IRQ_SHPI_START + 45) +#define IRQ_DB5500_PRCMU0 (IRQ_SHPI_START + 46) +#define IRQ_DB5500_PRCMU1 (IRQ_SHPI_START + 47) +#define IRQ_DB5500_DISP (IRQ_SHPI_START + 48) +#define IRQ_DB5500_SDMMC1 (IRQ_SHPI_START + 50) +#define IRQ_DB5500_MSP1 (IRQ_SHPI_START + 52) +#define IRQ_DB5500_KBD (IRQ_SHPI_START + 53) +#define IRQ_DB5500_I2C2 (IRQ_SHPI_START + 55) +#define IRQ_DB5500_B2R2 (IRQ_SHPI_START + 56) +#define IRQ_DB5500_CRYP0 (IRQ_SHPI_START + 57) +#define IRQ_DB5500_SDMMC3 (IRQ_SHPI_START + 59) +#define IRQ_DB5500_SDMMC0 (IRQ_SHPI_START + 60) +#define IRQ_DB5500_HSEM (IRQ_SHPI_START + 61) +#define IRQ_DB5500_SBAG (IRQ_SHPI_START + 63) +#define IRQ_DB5500_MODEM (IRQ_SHPI_START + 65) +#define IRQ_DB5500_SPI1 (IRQ_SHPI_START + 96) +#define IRQ_DB5500_MSP2 (IRQ_SHPI_START + 98) +#define IRQ_DB5500_SRPTIMER (IRQ_SHPI_START + 101) +#define IRQ_DB5500_CTI0 (IRQ_SHPI_START + 108) +#define IRQ_DB5500_CTI1 (IRQ_SHPI_START + 109) +#define IRQ_DB5500_ICN_ERR (IRQ_SHPI_START + 110) +#define IRQ_DB5500_MALI_PPMMU (IRQ_SHPI_START + 112) +#define IRQ_DB5500_MALI_PP (IRQ_SHPI_START + 113) +#define IRQ_DB5500_MALI_GPMMU (IRQ_SHPI_START + 114) +#define IRQ_DB5500_MALI_GP (IRQ_SHPI_START + 115) +#define IRQ_DB5500_MALI (IRQ_SHPI_START + 116) +#define IRQ_DB5500_PRCMU_SEM (IRQ_SHPI_START + 118) +#define IRQ_DB5500_GPIO0 (IRQ_SHPI_START + 119) +#define IRQ_DB5500_GPIO1 (IRQ_SHPI_START + 120) +#define IRQ_DB5500_GPIO2 (IRQ_SHPI_START + 121) +#define IRQ_DB5500_GPIO3 (IRQ_SHPI_START + 122) +#define IRQ_DB5500_GPIO4 (IRQ_SHPI_START + 123) +#define IRQ_DB5500_GPIO5 (IRQ_SHPI_START + 124) +#define IRQ_DB5500_GPIO6 (IRQ_SHPI_START + 125) +#define IRQ_DB5500_GPIO7 (IRQ_SHPI_START + 126) + +#ifdef CONFIG_UX500_SOC_DB5500 + +/* + * After the GPIO ones we reserve a range of IRQ:s in which virtual + * IRQ:s representing modem IRQ:s can be allocated + */ +#define IRQ_MODEM_EVENTS_BASE IRQ_SOC_START +#define IRQ_MODEM_EVENTS_NBR 72 +#define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR) + +/* List of virtual IRQ:s that are allocated from the range above */ +#define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43) +#define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45) +#define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41) + +/* + * We may have several SoCs, but only one will run at a + * time, so the one with most IRQs will bump this ahead, + * but the IRQ_SOC_START remains the same for either SoC. + */ +#if IRQ_SOC_END < IRQ_MODEM_EVENTS_END +#undef IRQ_SOC_END +#define IRQ_SOC_END IRQ_MODEM_EVENTS_END +#endif + +#endif /* CONFIG_UX500_SOC_DB5500 */ + +#endif diff --git a/trunk/arch/arm/mach-ux500/include/mach/irqs.h b/trunk/arch/arm/mach-ux500/include/mach/irqs.h index d06dcf6208fa..c23a6b5f0c4e 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/irqs.h +++ b/trunk/arch/arm/mach-ux500/include/mach/irqs.h @@ -36,6 +36,7 @@ /* This will be overridden by SoC-specific irq headers */ #define IRQ_SOC_END IRQ_SOC_START +#include #include #define IRQ_BOARD_START IRQ_SOC_END @@ -46,6 +47,10 @@ #include #endif +#ifdef CONFIG_MACH_U5500 +#include +#endif + #define NR_IRQS IRQ_BOARD_END #endif /* ASM_ARCH_IRQS_H */ diff --git a/trunk/arch/arm/mach-ux500/include/mach/mbox-db5500.h b/trunk/arch/arm/mach-ux500/include/mach/mbox-db5500.h new file mode 100644 index 000000000000..7f9da4d2fbda --- /dev/null +++ b/trunk/arch/arm/mach-ux500/include/mach/mbox-db5500.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Stefan Nilsson for ST-Ericsson. + * Author: Martin Persson for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef __INC_STE_MBOX_H +#define __INC_STE_MBOX_H + +#define MBOX_BUF_SIZE 16 +#define MBOX_NAME_SIZE 8 + +/** + * mbox_recv_cb_t - Definition of the mailbox callback. + * @mbox_msg: The mailbox message. + * @priv: The clients private data as specified in the call to mbox_setup. + * + * This function will be called upon reception of new mailbox messages. + */ +typedef void mbox_recv_cb_t (u32 mbox_msg, void *priv); + +/** + * struct mbox - Mailbox instance struct + * @list: Linked list head. + * @pdev: Pointer to device struct. + * @cb: Callback function. Will be called + * when new data is received. + * @client_data: Clients private data. Will be sent back + * in the callback function. + * @virtbase_peer: Virtual address for outgoing mailbox. + * @virtbase_local: Virtual address for incoming mailbox. + * @buffer: Then internal queue for outgoing messages. + * @name: Name of this mailbox. + * @buffer_available: Completion variable to achieve "blocking send". + * This variable will be signaled when there is + * internal buffer space available. + * @client_blocked: To keep track if any client is currently + * blocked. + * @lock: Spinlock to protect this mailbox instance. + * @write_index: Index in internal buffer to write to. + * @read_index: Index in internal buffer to read from. + * @allocated: Indicates whether this particular mailbox + * id has been allocated by someone. + */ +struct mbox { + struct list_head list; + struct platform_device *pdev; + mbox_recv_cb_t *cb; + void *client_data; + void __iomem *virtbase_peer; + void __iomem *virtbase_local; + u32 buffer[MBOX_BUF_SIZE]; + char name[MBOX_NAME_SIZE]; + struct completion buffer_available; + u8 client_blocked; + spinlock_t lock; + u8 write_index; + u8 read_index; + bool allocated; +}; + +/** + * mbox_setup - Set up a mailbox and return its instance. + * @mbox_id: The ID number of the mailbox. 0 or 1 for modem CPU, + * 2 for modem DSP. + * @mbox_cb: Pointer to the callback function to be called when a new message + * is received. + * @priv: Client user data which will be returned in the callback. + * + * Returns a mailbox instance to be specified in subsequent calls to mbox_send. + */ +struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv); + +/** + * mbox_send - Send a mailbox message. + * @mbox: Mailbox instance (returned by mbox_setup) + * @mbox_msg: The mailbox message to send. + * @block: Specifies whether this call will block until send is possible, + * or return an error if the mailbox buffer is full. + * + * Returns 0 on success or a negative error code on error. -ENOMEM indicates + * that the internal buffer is full and you have to try again later (or + * specify "block" in order to block until send is possible). + */ +int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block); + +#endif /*INC_STE_MBOX_H*/ diff --git a/trunk/arch/arm/mach-ux500/include/mach/setup.h b/trunk/arch/arm/mach-ux500/include/mach/setup.h index 4e369f1645ec..3dc00ffa7bfa 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/setup.h +++ b/trunk/arch/arm/mach-ux500/include/mach/setup.h @@ -15,12 +15,18 @@ #include void __init ux500_map_io(void); +extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); +extern struct device * __init u5500_init_devices(void); extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); +extern void __init u5500_sdi_init(struct device *parent); + +extern void __init db5500_dma_init(struct device *parent); + extern struct device *ux500_soc_device_init(const char *soc_id); struct amba_device; diff --git a/trunk/arch/arm/mach-ux500/include/mach/uncompress.h b/trunk/arch/arm/mach-ux500/include/mach/uncompress.h index 34775baadaea..6fb3c4b0105d 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-ux500/include/mach/uncompress.h @@ -50,8 +50,11 @@ static void flush(void) static inline void arch_decomp_setup(void) { - /* Use machine_is_foo() macro if you need to switch base someday */ - ux500_uart_base = U8500_UART2_BASE; + /* Check in run time if we run on an U8500 or U5500 */ + if (machine_is_u5500()) + ux500_uart_base = U5500_UART0_BASE; + else + ux500_uart_base = U8500_UART2_BASE; } #define arch_decomp_wdog() /* nothing to do here */ diff --git a/trunk/arch/arm/mach-ux500/mbox-db5500.c b/trunk/arch/arm/mach-ux500/mbox-db5500.c new file mode 100644 index 000000000000..2b2d51caf9d8 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/mbox-db5500.c @@ -0,0 +1,565 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Stefan Nilsson for ST-Ericsson. + * Author: Martin Persson for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2. + */ + +/* + * Mailbox nomenclature: + * + * APE MODEM + * mbox pairX + * .......................... + * . . + * . peer . + * . send ---- . + * . --> | | . + * . | | . + * . ---- . + * . . + * . local . + * . rec ---- . + * . | | <-- . + * . | | . + * . ---- . + * ......................... + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MBOX_NAME "mbox" + +#define MBOX_FIFO_DATA 0x000 +#define MBOX_FIFO_ADD 0x004 +#define MBOX_FIFO_REMOVE 0x008 +#define MBOX_FIFO_THRES_FREE 0x00C +#define MBOX_FIFO_THRES_OCCUP 0x010 +#define MBOX_FIFO_STATUS 0x014 + +#define MBOX_DISABLE_IRQ 0x4 +#define MBOX_ENABLE_IRQ 0x0 +#define MBOX_LATCH 1 + +/* Global list of all mailboxes */ +static struct list_head mboxs = LIST_HEAD_INIT(mboxs); + +static struct mbox *get_mbox_with_id(u8 id) +{ + u8 i; + struct list_head *pos = &mboxs; + for (i = 0; i <= id; i++) + pos = pos->next; + + return (struct mbox *) list_entry(pos, struct mbox, list); +} + +int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block) +{ + int res = 0; + + spin_lock(&mbox->lock); + + dev_dbg(&(mbox->pdev->dev), + "About to buffer 0x%X to mailbox 0x%X." + " ri = %d, wi = %d\n", + mbox_msg, (u32)mbox, mbox->read_index, + mbox->write_index); + + /* Check if write buffer is full */ + while (((mbox->write_index + 1) % MBOX_BUF_SIZE) == mbox->read_index) { + if (!block) { + dev_dbg(&(mbox->pdev->dev), + "Buffer full in non-blocking call! " + "Returning -ENOMEM!\n"); + res = -ENOMEM; + goto exit; + } + spin_unlock(&mbox->lock); + dev_dbg(&(mbox->pdev->dev), + "Buffer full in blocking call! Sleeping...\n"); + mbox->client_blocked = 1; + wait_for_completion(&mbox->buffer_available); + dev_dbg(&(mbox->pdev->dev), + "Blocking send was woken up! Trying again...\n"); + spin_lock(&mbox->lock); + } + + mbox->buffer[mbox->write_index] = mbox_msg; + mbox->write_index = (mbox->write_index + 1) % MBOX_BUF_SIZE; + + /* + * Indicate that we want an IRQ as soon as there is a slot + * in the FIFO + */ + writel(MBOX_ENABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); + +exit: + spin_unlock(&mbox->lock); + return res; +} +EXPORT_SYMBOL(mbox_send); + +#if defined(CONFIG_DEBUG_FS) +/* + * Expected input: + * Example: "echo 0xdeadbeef 4 > mbox-node" sends 0xdeadbeef 4 times + */ +static ssize_t mbox_write_fifo(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned long mbox_mess; + unsigned long nbr_sends; + unsigned long i; + char int_buf[16]; + char *token; + char *val; + + struct mbox *mbox = (struct mbox *) dev->platform_data; + + strncpy((char *) &int_buf, buf, sizeof(int_buf)); + token = (char *) &int_buf; + + /* Parse message */ + val = strsep(&token, " "); + if ((val == NULL) || (strict_strtoul(val, 16, &mbox_mess) != 0)) + mbox_mess = 0xDEADBEEF; + + val = strsep(&token, " "); + if ((val == NULL) || (strict_strtoul(val, 10, &nbr_sends) != 0)) + nbr_sends = 1; + + dev_dbg(dev, "Will write 0x%lX %ld times using data struct at 0x%X\n", + mbox_mess, nbr_sends, (u32) mbox); + + for (i = 0; i < nbr_sends; i++) + mbox_send(mbox, mbox_mess, true); + + return count; +} + +static ssize_t mbox_read_fifo(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int mbox_value; + struct mbox *mbox = (struct mbox *) dev->platform_data; + + if ((readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7) <= 0) + return sprintf(buf, "Mailbox is empty\n"); + + mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA); + writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE)); + + return sprintf(buf, "0x%X\n", mbox_value); +} + +static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo); + +static int mbox_show(struct seq_file *s, void *data) +{ + struct list_head *pos; + u8 mbox_index = 0; + + list_for_each(pos, &mboxs) { + struct mbox *m = + (struct mbox *) list_entry(pos, struct mbox, list); + if (m == NULL) { + seq_printf(s, + "Unable to retrieve mailbox %d\n", + mbox_index); + continue; + } + + spin_lock(&m->lock); + if ((m->virtbase_peer == NULL) || (m->virtbase_local == NULL)) { + seq_printf(s, "MAILBOX %d not setup or corrupt\n", + mbox_index); + spin_unlock(&m->lock); + continue; + } + + seq_printf(s, + "===========================\n" + " MAILBOX %d\n" + " PEER MAILBOX DUMP\n" + "---------------------------\n" + "FIFO: 0x%X (%d)\n" + "Free Threshold: 0x%.2X (%d)\n" + "Occupied Threshold: 0x%.2X (%d)\n" + "Status: 0x%.2X (%d)\n" + " Free spaces (ot): %d (%d)\n" + " Occup spaces (ot): %d (%d)\n" + "===========================\n" + " LOCAL MAILBOX DUMP\n" + "---------------------------\n" + "FIFO: 0x%.X (%d)\n" + "Free Threshold: 0x%.2X (%d)\n" + "Occupied Threshold: 0x%.2X (%d)\n" + "Status: 0x%.2X (%d)\n" + " Free spaces (ot): %d (%d)\n" + " Occup spaces (ot): %d (%d)\n" + "===========================\n" + "write_index: %d\n" + "read_index : %d\n" + "===========================\n" + "\n", + mbox_index, + readl(m->virtbase_peer + MBOX_FIFO_DATA), + readl(m->virtbase_peer + MBOX_FIFO_DATA), + readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE), + readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE), + readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP), + readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP), + readl(m->virtbase_peer + MBOX_FIFO_STATUS), + readl(m->virtbase_peer + MBOX_FIFO_STATUS), + (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 4) & 0x7, + (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 7) & 0x1, + (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 0) & 0x7, + (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 3) & 0x1, + readl(m->virtbase_local + MBOX_FIFO_DATA), + readl(m->virtbase_local + MBOX_FIFO_DATA), + readl(m->virtbase_local + MBOX_FIFO_THRES_FREE), + readl(m->virtbase_local + MBOX_FIFO_THRES_FREE), + readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP), + readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP), + readl(m->virtbase_local + MBOX_FIFO_STATUS), + readl(m->virtbase_local + MBOX_FIFO_STATUS), + (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 4) & 0x7, + (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 7) & 0x1, + (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 0) & 0x7, + (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 3) & 0x1, + m->write_index, m->read_index); + mbox_index++; + spin_unlock(&m->lock); + } + + return 0; +} + +static int mbox_open(struct inode *inode, struct file *file) +{ + return single_open(file, mbox_show, NULL); +} + +static const struct file_operations mbox_operations = { + .owner = THIS_MODULE, + .open = mbox_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +static irqreturn_t mbox_irq(int irq, void *arg) +{ + u32 mbox_value; + int nbr_occup; + int nbr_free; + struct mbox *mbox = (struct mbox *) arg; + + spin_lock(&mbox->lock); + + dev_dbg(&(mbox->pdev->dev), + "mbox IRQ [%d] received. ri = %d, wi = %d\n", + irq, mbox->read_index, mbox->write_index); + + /* + * Check if we have any outgoing messages, and if there is space for + * them in the FIFO. + */ + if (mbox->read_index != mbox->write_index) { + /* + * Check by reading FREE for LOCAL since that indicates + * OCCUP for PEER + */ + nbr_free = (readl(mbox->virtbase_local + MBOX_FIFO_STATUS) + >> 4) & 0x7; + dev_dbg(&(mbox->pdev->dev), + "Status indicates %d empty spaces in the FIFO!\n", + nbr_free); + + while ((nbr_free > 0) && + (mbox->read_index != mbox->write_index)) { + /* Write the message and latch it into the FIFO */ + writel(mbox->buffer[mbox->read_index], + (mbox->virtbase_peer + MBOX_FIFO_DATA)); + writel(MBOX_LATCH, + (mbox->virtbase_peer + MBOX_FIFO_ADD)); + dev_dbg(&(mbox->pdev->dev), + "Wrote message 0x%X to addr 0x%X\n", + mbox->buffer[mbox->read_index], + (u32) (mbox->virtbase_peer + MBOX_FIFO_DATA)); + + nbr_free--; + mbox->read_index = + (mbox->read_index + 1) % MBOX_BUF_SIZE; + } + + /* + * Check if we still want IRQ:s when there is free + * space to send + */ + if (mbox->read_index != mbox->write_index) { + dev_dbg(&(mbox->pdev->dev), + "Still have messages to send, but FIFO full. " + "Request IRQ again!\n"); + writel(MBOX_ENABLE_IRQ, + mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); + } else { + dev_dbg(&(mbox->pdev->dev), + "No more messages to send. " + "Do not request IRQ again!\n"); + writel(MBOX_DISABLE_IRQ, + mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); + } + + /* + * Check if we can signal any blocked clients that it is OK to + * start buffering again + */ + if (mbox->client_blocked && + (((mbox->write_index + 1) % MBOX_BUF_SIZE) + != mbox->read_index)) { + dev_dbg(&(mbox->pdev->dev), + "Waking up blocked client\n"); + complete(&mbox->buffer_available); + mbox->client_blocked = 0; + } + } + + /* Check if we have any incoming messages */ + nbr_occup = readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7; + if (nbr_occup == 0) + goto exit; + + if (mbox->cb == NULL) { + dev_dbg(&(mbox->pdev->dev), "No receive callback registered, " + "leaving %d incoming messages in fifo!\n", nbr_occup); + goto exit; + } + + /* Read and acknowledge the message */ + mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA); + writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE)); + + /* Notify consumer of new mailbox message */ + dev_dbg(&(mbox->pdev->dev), "Calling callback for message 0x%X!\n", + mbox_value); + mbox->cb(mbox_value, mbox->client_data); + +exit: + dev_dbg(&(mbox->pdev->dev), "Exit mbox IRQ. ri = %d, wi = %d\n", + mbox->read_index, mbox->write_index); + spin_unlock(&mbox->lock); + + return IRQ_HANDLED; +} + +/* Setup is executed once for each mbox pair */ +struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv) +{ + struct resource *resource; + int irq; + int res; + struct mbox *mbox; + + mbox = get_mbox_with_id(mbox_id); + if (mbox == NULL) { + dev_err(&(mbox->pdev->dev), "Incorrect mailbox id: %d!\n", + mbox_id); + goto exit; + } + + /* + * Check if mailbox has been allocated to someone else, + * otherwise allocate it + */ + if (mbox->allocated) { + dev_err(&(mbox->pdev->dev), "Mailbox number %d is busy!\n", + mbox_id); + mbox = NULL; + goto exit; + } + mbox->allocated = true; + + dev_dbg(&(mbox->pdev->dev), "Initiating mailbox number %d: 0x%X...\n", + mbox_id, (u32)mbox); + + mbox->client_data = priv; + mbox->cb = mbox_cb; + + /* Get addr for peer mailbox and ioremap it */ + resource = platform_get_resource_byname(mbox->pdev, + IORESOURCE_MEM, + "mbox_peer"); + if (resource == NULL) { + dev_err(&(mbox->pdev->dev), + "Unable to retrieve mbox peer resource\n"); + mbox = NULL; + goto exit; + } + dev_dbg(&(mbox->pdev->dev), + "Resource name: %s start: 0x%X, end: 0x%X\n", + resource->name, resource->start, resource->end); + mbox->virtbase_peer = ioremap(resource->start, resource_size(resource)); + if (!mbox->virtbase_peer) { + dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n"); + mbox = NULL; + goto exit; + } + dev_dbg(&(mbox->pdev->dev), + "ioremapped peer physical: (0x%X-0x%X) to virtual: 0x%X\n", + resource->start, resource->end, (u32) mbox->virtbase_peer); + + /* Get addr for local mailbox and ioremap it */ + resource = platform_get_resource_byname(mbox->pdev, + IORESOURCE_MEM, + "mbox_local"); + if (resource == NULL) { + dev_err(&(mbox->pdev->dev), + "Unable to retrieve mbox local resource\n"); + mbox = NULL; + goto exit; + } + dev_dbg(&(mbox->pdev->dev), + "Resource name: %s start: 0x%X, end: 0x%X\n", + resource->name, resource->start, resource->end); + mbox->virtbase_local = ioremap(resource->start, resource_size(resource)); + if (!mbox->virtbase_local) { + dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n"); + mbox = NULL; + goto exit; + } + dev_dbg(&(mbox->pdev->dev), + "ioremapped local physical: (0x%X-0x%X) to virtual: 0x%X\n", + resource->start, resource->end, (u32) mbox->virtbase_peer); + + init_completion(&mbox->buffer_available); + mbox->client_blocked = 0; + + /* Get IRQ for mailbox and allocate it */ + irq = platform_get_irq_byname(mbox->pdev, "mbox_irq"); + if (irq < 0) { + dev_err(&(mbox->pdev->dev), + "Unable to retrieve mbox irq resource\n"); + mbox = NULL; + goto exit; + } + + dev_dbg(&(mbox->pdev->dev), "Allocating irq %d...\n", irq); + res = request_irq(irq, mbox_irq, 0, mbox->name, (void *) mbox); + if (res < 0) { + dev_err(&(mbox->pdev->dev), + "Unable to allocate mbox irq %d\n", irq); + mbox = NULL; + goto exit; + } + + /* Set up mailbox to not launch IRQ on free space in mailbox */ + writel(MBOX_DISABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); + + /* + * Set up mailbox to launch IRQ on new message if we have + * a callback set. If not, do not raise IRQ, but keep message + * in FIFO for manual retrieval + */ + if (mbox_cb != NULL) + writel(MBOX_ENABLE_IRQ, + mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP); + else + writel(MBOX_DISABLE_IRQ, + mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP); + +#if defined(CONFIG_DEBUG_FS) + res = device_create_file(&(mbox->pdev->dev), &dev_attr_fifo); + if (res != 0) + dev_warn(&(mbox->pdev->dev), + "Unable to create mbox sysfs entry"); + + (void) debugfs_create_file("mbox", S_IFREG | S_IRUGO, NULL, + NULL, &mbox_operations); +#endif + + dev_info(&(mbox->pdev->dev), + "Mailbox driver with index %d initiated!\n", mbox_id); + +exit: + return mbox; +} +EXPORT_SYMBOL(mbox_setup); + + +int __init mbox_probe(struct platform_device *pdev) +{ + struct mbox local_mbox; + struct mbox *mbox; + int res = 0; + dev_dbg(&(pdev->dev), "Probing mailbox (pdev = 0x%X)...\n", (u32) pdev); + + memset(&local_mbox, 0x0, sizeof(struct mbox)); + + /* Associate our mbox data with the platform device */ + res = platform_device_add_data(pdev, + (void *) &local_mbox, + sizeof(struct mbox)); + if (res != 0) { + dev_err(&(pdev->dev), + "Unable to allocate driver platform data!\n"); + goto exit; + } + + mbox = (struct mbox *) pdev->dev.platform_data; + mbox->pdev = pdev; + mbox->write_index = 0; + mbox->read_index = 0; + + INIT_LIST_HEAD(&(mbox->list)); + list_add_tail(&(mbox->list), &mboxs); + + sprintf(mbox->name, "%s", MBOX_NAME); + spin_lock_init(&mbox->lock); + + dev_info(&(pdev->dev), "Mailbox driver loaded\n"); + +exit: + return res; +} + +static struct platform_driver mbox_driver = { + .driver = { + .name = MBOX_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init mbox_init(void) +{ + return platform_driver_probe(&mbox_driver, mbox_probe); +} + +module_init(mbox_init); + +void __exit mbox_exit(void) +{ + platform_driver_unregister(&mbox_driver); +} + +module_exit(mbox_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MBOX driver"); diff --git a/trunk/arch/arm/mach-ux500/modem-irq-db5500.c b/trunk/arch/arm/mach-ux500/modem-irq-db5500.c new file mode 100644 index 000000000000..6b86416c94c9 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/modem-irq-db5500.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Stefan Nilsson for ST-Ericsson. + * Author: Martin Persson for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define MODEM_INTCON_BASE_ADDR 0xBFFD3000 +#define MODEM_INTCON_SIZE 0xFFF + +#define DEST_IRQ41_OFFSET 0x2A4 +#define DEST_IRQ43_OFFSET 0x2AC +#define DEST_IRQ45_OFFSET 0x2B4 + +#define PRIO_IRQ41_OFFSET 0x6A4 +#define PRIO_IRQ43_OFFSET 0x6AC +#define PRIO_IRQ45_OFFSET 0x6B4 + +#define ALLOW_IRQ_OFFSET 0x104 + +#define MODEM_INTCON_CPU_NBR 0x1 +#define MODEM_INTCON_PRIO_HIGH 0x0 + +#define MODEM_INTCON_ALLOW_IRQ41 0x0200 +#define MODEM_INTCON_ALLOW_IRQ43 0x0800 +#define MODEM_INTCON_ALLOW_IRQ45 0x2000 + +#define MODEM_IRQ_REG_OFFSET 0x4 + +struct modem_irq { + void __iomem *modem_intcon_base; +}; + + +static void setup_modem_intcon(void __iomem *modem_intcon_base) +{ + /* IC_DESTINATION_BASE_ARRAY - Which CPU to receive the IRQ */ + writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ41_OFFSET); + writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ43_OFFSET); + writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ45_OFFSET); + + /* IC_PRIORITY_BASE_ARRAY - IRQ priority in modem IRQ controller */ + writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ41_OFFSET); + writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ43_OFFSET); + writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ45_OFFSET); + + /* IC_ALLOW_ARRAY - IRQ enable */ + writel(MODEM_INTCON_ALLOW_IRQ41 | + MODEM_INTCON_ALLOW_IRQ43 | + MODEM_INTCON_ALLOW_IRQ45, + modem_intcon_base + ALLOW_IRQ_OFFSET); +} + +static irqreturn_t modem_cpu_irq_handler(int irq, void *data) +{ + int real_irq; + int virt_irq; + struct modem_irq *mi = (struct modem_irq *)data; + + /* Read modem side IRQ number from modem IRQ controller */ + real_irq = readl(mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET) & 0xFF; + virt_irq = IRQ_MODEM_EVENTS_BASE + real_irq; + + pr_debug("modem_irq: Worker read addr 0x%X and got value 0x%X " + "which will be 0x%X (%d) which translates to " + "virtual IRQ 0x%X (%d)!\n", + (u32)mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET, + real_irq, + real_irq & 0xFF, + real_irq & 0xFF, + virt_irq, + virt_irq); + + if (virt_irq != 0) + generic_handle_irq(virt_irq); + + pr_debug("modem_irq: Done handling virtual IRQ %d!\n", virt_irq); + + return IRQ_HANDLED; +} + +static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip) +{ + irq_set_chip_and_handler(irq, modem_irq_chip, handle_simple_irq); + set_irq_flags(irq, IRQF_VALID); + + pr_debug("modem_irq: Created virtual IRQ %d\n", irq); +} + +static int modem_irq_init(void) +{ + int err; + static struct irq_chip modem_irq_chip; + struct modem_irq *mi; + + if (!cpu_is_u5500()) + return -ENODEV; + + pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n", + IRQ_DB5500_MODEM); + + mi = kmalloc(sizeof(struct modem_irq), GFP_KERNEL); + if (!mi) { + pr_err("modem_irq: Could not allocate device\n"); + return -ENOMEM; + } + + mi->modem_intcon_base = + ioremap(MODEM_INTCON_BASE_ADDR, MODEM_INTCON_SIZE); + pr_debug("modem_irq: ioremapped modem_intcon_base from " + "phy 0x%x to virt 0x%x\n", MODEM_INTCON_BASE_ADDR, + (u32)mi->modem_intcon_base); + + setup_modem_intcon(mi->modem_intcon_base); + + modem_irq_chip = dummy_irq_chip; + modem_irq_chip.name = "modem_irq"; + + /* Create the virtual IRQ:s needed */ + create_virtual_irq(MBOX_PAIR0_VIRT_IRQ, &modem_irq_chip); + create_virtual_irq(MBOX_PAIR1_VIRT_IRQ, &modem_irq_chip); + create_virtual_irq(MBOX_PAIR2_VIRT_IRQ, &modem_irq_chip); + + err = request_threaded_irq(IRQ_DB5500_MODEM, NULL, + modem_cpu_irq_handler, IRQF_ONESHOT, + "modem_irq", mi); + if (err) + pr_err("modem_irq: Could not register IRQ %d\n", + IRQ_DB5500_MODEM); + + return 0; +} + +arch_initcall(modem_irq_init); diff --git a/trunk/arch/arm/mach-ux500/pins-db5500.h b/trunk/arch/arm/mach-ux500/pins-db5500.h new file mode 100644 index 000000000000..bf50c21fe69d --- /dev/null +++ b/trunk/arch/arm/mach-ux500/pins-db5500.h @@ -0,0 +1,620 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License, version 2 + * Author: Rabin Vincent + */ + +#ifndef __MACH_DB5500_PINS_H +#define __MACH_DB5500_PINS_H + +#define GPIO0_GPIO PIN_CFG(0, GPIO) +#define GPIO0_SM_CS3n PIN_CFG(0, ALT_A) + +#define GPIO1_GPIO PIN_CFG(1, GPIO) +#define GPIO1_SM_A3 PIN_CFG(1, ALT_A) + +#define GPIO2_GPIO PIN_CFG(2, GPIO) +#define GPIO2_SM_A4 PIN_CFG(2, ALT_A) +#define GPIO2_SM_AVD PIN_CFG(2, ALT_B) + +#define GPIO3_GPIO PIN_CFG(3, GPIO) +#define GPIO3_I2C1_SCL PIN_CFG(3, ALT_A) + +#define GPIO4_GPIO PIN_CFG(4, GPIO) +#define GPIO4_I2C1_SDA PIN_CFG(4, ALT_A) + +#define GPIO5_GPIO PIN_CFG(5, GPIO) +#define GPIO5_MC0_DAT0 PIN_CFG(5, ALT_A) +#define GPIO5_SM_ADQ8 PIN_CFG(5, ALT_B) + +#define GPIO6_GPIO PIN_CFG(6, GPIO) +#define GPIO6_MC0_DAT1 PIN_CFG(6, ALT_A) +#define GPIO6_SM_ADQ0 PIN_CFG(6, ALT_B) + +#define GPIO7_GPIO PIN_CFG(7, GPIO) +#define GPIO7_MC0_DAT2 PIN_CFG(7, ALT_A) +#define GPIO7_SM_ADQ9 PIN_CFG(7, ALT_B) + +#define GPIO8_GPIO PIN_CFG(8, GPIO) +#define GPIO8_MC0_DAT3 PIN_CFG(8, ALT_A) +#define GPIO8_SM_ADQ1 PIN_CFG(8, ALT_B) + +#define GPIO9_GPIO PIN_CFG(9, GPIO) +#define GPIO9_MC0_DAT4 PIN_CFG(9, ALT_A) +#define GPIO9_SM_ADQ10 PIN_CFG(9, ALT_B) + +#define GPIO10_GPIO PIN_CFG(10, GPIO) +#define GPIO10_MC0_DAT5 PIN_CFG(10, ALT_A) +#define GPIO10_SM_ADQ2 PIN_CFG(10, ALT_B) + +#define GPIO11_GPIO PIN_CFG(11, GPIO) +#define GPIO11_MC0_DAT6 PIN_CFG(11, ALT_A) +#define GPIO11_SM_ADQ11 PIN_CFG(11, ALT_B) + +#define GPIO12_GPIO PIN_CFG(12, GPIO) +#define GPIO12_MC0_DAT7 PIN_CFG(12, ALT_A) +#define GPIO12_SM_ADQ3 PIN_CFG(12, ALT_B) + +#define GPIO13_GPIO PIN_CFG(13, GPIO) +#define GPIO13_MC0_CMD PIN_CFG(13, ALT_A) +#define GPIO13_SM_BUSY0n PIN_CFG(13, ALT_B) +#define GPIO13_SM_WAIT0n PIN_CFG(13, ALT_C) + +#define GPIO14_GPIO PIN_CFG(14, GPIO) +#define GPIO14_MC0_CLK PIN_CFG(14, ALT_A) +#define GPIO14_SM_CS1n PIN_CFG(14, ALT_B) +#define GPIO14_SM_CKO PIN_CFG(14, ALT_C) + +#define GPIO15_GPIO PIN_CFG(15, GPIO) +#define GPIO15_SM_A5 PIN_CFG(15, ALT_A) +#define GPIO15_SM_CLE PIN_CFG(15, ALT_B) + +#define GPIO16_GPIO PIN_CFG(16, GPIO) +#define GPIO16_MC2_CMD PIN_CFG(16, ALT_A) +#define GPIO16_SM_OEn PIN_CFG(16, ALT_B) + +#define GPIO17_GPIO PIN_CFG(17, GPIO) +#define GPIO17_MC2_CLK PIN_CFG(17, ALT_A) +#define GPIO17_SM_WEn PIN_CFG(17, ALT_B) + +#define GPIO18_GPIO PIN_CFG(18, GPIO) +#define GPIO18_SM_A6 PIN_CFG(18, ALT_A) +#define GPIO18_SM_ALE PIN_CFG(18, ALT_B) +#define GPIO18_SM_AVDn PIN_CFG(18, ALT_C) + +#define GPIO19_GPIO PIN_CFG(19, GPIO) +#define GPIO19_MC2_DAT1 PIN_CFG(19, ALT_A) +#define GPIO19_SM_ADQ4 PIN_CFG(19, ALT_B) + +#define GPIO20_GPIO PIN_CFG(20, GPIO) +#define GPIO20_MC2_DAT3 PIN_CFG(20, ALT_A) +#define GPIO20_SM_ADQ5 PIN_CFG(20, ALT_B) + +#define GPIO21_GPIO PIN_CFG(21, GPIO) +#define GPIO21_MC2_DAT5 PIN_CFG(21, ALT_A) +#define GPIO21_SM_ADQ6 PIN_CFG(21, ALT_B) + +#define GPIO22_GPIO PIN_CFG(22, GPIO) +#define GPIO22_MC2_DAT7 PIN_CFG(22, ALT_A) +#define GPIO22_SM_ADQ7 PIN_CFG(22, ALT_B) + +#define GPIO23_GPIO PIN_CFG(23, GPIO) +#define GPIO23_MC2_DAT0 PIN_CFG(23, ALT_A) +#define GPIO23_SM_ADQ12 PIN_CFG(23, ALT_B) +#define GPIO23_MC0_DAT1 PIN_CFG(23, ALT_C) + +#define GPIO24_GPIO PIN_CFG(24, GPIO) +#define GPIO24_MC2_DAT2 PIN_CFG(24, ALT_A) +#define GPIO24_SM_ADQ13 PIN_CFG(24, ALT_B) +#define GPIO24_MC0_DAT3 PIN_CFG(24, ALT_C) + +#define GPIO25_GPIO PIN_CFG(25, GPIO) +#define GPIO25_MC2_DAT4 PIN_CFG(25, ALT_A) +#define GPIO25_SM_ADQ14 PIN_CFG(25, ALT_B) +#define GPIO25_MC0_CMD PIN_CFG(25, ALT_C) + +#define GPIO26_GPIO PIN_CFG(26, GPIO) +#define GPIO26_MC2_DAT6 PIN_CFG(26, ALT_A) +#define GPIO26_SM_ADQ15 PIN_CFG(26, ALT_B) + +#define GPIO27_GPIO PIN_CFG(27, GPIO) +#define GPIO27_SM_CS0n PIN_CFG(27, ALT_A) +#define GPIO27_SM_PS0n PIN_CFG(27, ALT_B) + +#define GPIO28_GPIO PIN_CFG(28, GPIO) +#define GPIO28_U0_TXD PIN_CFG(28, ALT_A) +#define GPIO28_SM_A0 PIN_CFG(28, ALT_B) + +#define GPIO29_GPIO PIN_CFG(29, GPIO) +#define GPIO29_U0_RXD PIN_CFG(29, ALT_A) +#define GPIO29_SM_A1 PIN_CFG(29, ALT_B) +#define GPIO29_PWM_0 PIN_CFG(29, ALT_C) + +#define GPIO30_GPIO PIN_CFG(30, GPIO) +#define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A) +#define GPIO30_SM_A2 PIN_CFG(30, ALT_B) +#define GPIO30_PWM_1 PIN_CFG(30, ALT_C) + +#define GPIO31_GPIO PIN_CFG(31, GPIO) +#define GPIO31_MC0_DAT7 PIN_CFG(31, ALT_A) +#define GPIO31_SM_CS2n PIN_CFG(31, ALT_B) +#define GPIO31_PWM_2 PIN_CFG(31, ALT_C) + +#define GPIO32_GPIO PIN_CFG(32, GPIO) +#define GPIO32_MSP0_TCK PIN_CFG(32, ALT_A) +#define GPIO32_ACCI2S0_SCK PIN_CFG(32, ALT_B) + +#define GPIO33_GPIO PIN_CFG(33, GPIO) +#define GPIO33_MSP0_TFS PIN_CFG(33, ALT_A) +#define GPIO33_ACCI2S0_WS PIN_CFG(33, ALT_B) + +#define GPIO34_GPIO PIN_CFG(34, GPIO) +#define GPIO34_MSP0_TXD PIN_CFG(34, ALT_A) +#define GPIO34_ACCI2S0_DLD PIN_CFG(34, ALT_B) + +#define GPIO35_GPIO PIN_CFG(35, GPIO) +#define GPIO35_MSP0_RXD PIN_CFG(35, ALT_A) +#define GPIO35_ACCI2S0_ULD PIN_CFG(35, ALT_B) + +#define GPIO64_GPIO PIN_CFG(64, GPIO) +#define GPIO64_USB_DAT0 PIN_CFG(64, ALT_A) +#define GPIO64_U0_TXD PIN_CFG(64, ALT_B) + +#define GPIO65_GPIO PIN_CFG(65, GPIO) +#define GPIO65_USB_DAT1 PIN_CFG(65, ALT_A) +#define GPIO65_U0_RXD PIN_CFG(65, ALT_B) + +#define GPIO66_GPIO PIN_CFG(66, GPIO) +#define GPIO66_USB_DAT2 PIN_CFG(66, ALT_A) + +#define GPIO67_GPIO PIN_CFG(67, GPIO) +#define GPIO67_USB_DAT3 PIN_CFG(67, ALT_A) + +#define GPIO68_GPIO PIN_CFG(68, GPIO) +#define GPIO68_USB_DAT4 PIN_CFG(68, ALT_A) + +#define GPIO69_GPIO PIN_CFG(69, GPIO) +#define GPIO69_USB_DAT5 PIN_CFG(69, ALT_A) + +#define GPIO70_GPIO PIN_CFG(70, GPIO) +#define GPIO70_USB_DAT6 PIN_CFG(70, ALT_A) + +#define GPIO71_GPIO PIN_CFG(71, GPIO) +#define GPIO71_USB_DAT7 PIN_CFG(71, ALT_A) + +#define GPIO72_GPIO PIN_CFG(72, GPIO) +#define GPIO72_USB_STP PIN_CFG(72, ALT_A) + +#define GPIO73_GPIO PIN_CFG(73, GPIO) +#define GPIO73_USB_DIR PIN_CFG(73, ALT_A) + +#define GPIO74_GPIO PIN_CFG(74, GPIO) +#define GPIO74_USB_NXT PIN_CFG(74, ALT_A) + +#define GPIO75_GPIO PIN_CFG(75, GPIO) +#define GPIO75_USB_XCLK PIN_CFG(75, ALT_A) + +#define GPIO76_GPIO PIN_CFG(76, GPIO) + +#define GPIO77_GPIO PIN_CFG(77, GPIO) +#define GPIO77_ACCTX_ON PIN_CFG(77, ALT_A) + +#define GPIO78_GPIO PIN_CFG(78, GPIO) +#define GPIO78_IRQn PIN_CFG(78, ALT_A) + +#define GPIO79_GPIO PIN_CFG(79, GPIO) +#define GPIO79_ACCSIM_Clk PIN_CFG(79, ALT_A) + +#define GPIO80_GPIO PIN_CFG(80, GPIO) +#define GPIO80_ACCSIM_Da PIN_CFG(80, ALT_A) + +#define GPIO81_GPIO PIN_CFG(81, GPIO) +#define GPIO81_ACCSIM_Reset PIN_CFG(81, ALT_A) + +#define GPIO82_GPIO PIN_CFG(82, GPIO) +#define GPIO82_ACCSIM_DDir PIN_CFG(82, ALT_A) + +#define GPIO96_GPIO PIN_CFG(96, GPIO) +#define GPIO96_MSP1_TCK PIN_CFG(96, ALT_A) +#define GPIO96_PRCMU_DEBUG3 PIN_CFG(96, ALT_B) +#define GPIO96_PRCMU_DEBUG7 PIN_CFG(96, ALT_C) + +#define GPIO97_GPIO PIN_CFG(97, GPIO) +#define GPIO97_MSP1_TFS PIN_CFG(97, ALT_A) +#define GPIO97_PRCMU_DEBUG2 PIN_CFG(97, ALT_B) +#define GPIO97_PRCMU_DEBUG6 PIN_CFG(97, ALT_C) + +#define GPIO98_GPIO PIN_CFG(98, GPIO) +#define GPIO98_MSP1_TXD PIN_CFG(98, ALT_A) +#define GPIO98_PRCMU_DEBUG1 PIN_CFG(98, ALT_B) +#define GPIO98_PRCMU_DEBUG5 PIN_CFG(98, ALT_C) + +#define GPIO99_GPIO PIN_CFG(99, GPIO) +#define GPIO99_MSP1_RXD PIN_CFG(99, ALT_A) +#define GPIO99_PRCMU_DEBUG0 PIN_CFG(99, ALT_B) +#define GPIO99_PRCMU_DEBUG4 PIN_CFG(99, ALT_C) + +#define GPIO100_GPIO PIN_CFG(100, GPIO) +#define GPIO100_I2C0_SCL PIN_CFG(100, ALT_A) + +#define GPIO101_GPIO PIN_CFG(101, GPIO) +#define GPIO101_I2C0_SDA PIN_CFG(101, ALT_A) + +#define GPIO128_GPIO PIN_CFG(128, GPIO) +#define GPIO128_KP_I0 PIN_CFG(128, ALT_A) +#define GPIO128_BUSMON_D0 PIN_CFG(128, ALT_B) + +#define GPIO129_GPIO PIN_CFG(129, GPIO) +#define GPIO129_KP_O0 PIN_CFG(129, ALT_A) +#define GPIO129_BUSMON_D1 PIN_CFG(129, ALT_B) + +#define GPIO130_GPIO PIN_CFG(130, GPIO) +#define GPIO130_KP_I1 PIN_CFG(130, ALT_A) +#define GPIO130_BUSMON_D2 PIN_CFG(130, ALT_B) + +#define GPIO131_GPIO PIN_CFG(131, GPIO) +#define GPIO131_KP_O1 PIN_CFG(131, ALT_A) +#define GPIO131_BUSMON_D3 PIN_CFG(131, ALT_B) + +#define GPIO132_GPIO PIN_CFG(132, GPIO) +#define GPIO132_KP_I2 PIN_CFG(132, ALT_A) +#define GPIO132_ETM_D15 PIN_CFG(132, ALT_B) +#define GPIO132_STMAPE_CLK PIN_CFG(132, ALT_C) + +#define GPIO133_GPIO PIN_CFG(133, GPIO) +#define GPIO133_KP_O2 PIN_CFG(133, ALT_A) +#define GPIO133_ETM_D14 PIN_CFG(133, ALT_B) +#define GPIO133_U0_RXD PIN_CFG(133, ALT_C) + +#define GPIO134_GPIO PIN_CFG(134, GPIO) +#define GPIO134_KP_I3 PIN_CFG(134, ALT_A) +#define GPIO134_ETM_D13 PIN_CFG(134, ALT_B) +#define GPIO134_STMAPE_DAT0 PIN_CFG(134, ALT_C) + +#define GPIO135_GPIO PIN_CFG(135, GPIO) +#define GPIO135_KP_O3 PIN_CFG(135, ALT_A) +#define GPIO135_ETM_D12 PIN_CFG(135, ALT_B) +#define GPIO135_STMAPE_DAT1 PIN_CFG(135, ALT_C) + +#define GPIO136_GPIO PIN_CFG(136, GPIO) +#define GPIO136_KP_I4 PIN_CFG(136, ALT_A) +#define GPIO136_ETM_D11 PIN_CFG(136, ALT_B) +#define GPIO136_STMAPE_DAT2 PIN_CFG(136, ALT_C) + +#define GPIO137_GPIO PIN_CFG(137, GPIO) +#define GPIO137_KP_O4 PIN_CFG(137, ALT_A) +#define GPIO137_ETM_D10 PIN_CFG(137, ALT_B) +#define GPIO137_STMAPE_DAT3 PIN_CFG(137, ALT_C) + +#define GPIO138_GPIO PIN_CFG(138, GPIO) +#define GPIO138_KP_I5 PIN_CFG(138, ALT_A) +#define GPIO138_ETM_D9 PIN_CFG(138, ALT_B) +#define GPIO138_U0_TXD PIN_CFG(138, ALT_C) + +#define GPIO139_GPIO PIN_CFG(139, GPIO) +#define GPIO139_KP_O5 PIN_CFG(139, ALT_A) +#define GPIO139_ETM_D8 PIN_CFG(139, ALT_B) +#define GPIO139_BUSMON_D11 PIN_CFG(139, ALT_C) + +#define GPIO140_GPIO PIN_CFG(140, GPIO) +#define GPIO140_KP_I6 PIN_CFG(140, ALT_A) +#define GPIO140_ETM_D7 PIN_CFG(140, ALT_B) +#define GPIO140_STMAPE_CLK PIN_CFG(140, ALT_C) + +#define GPIO141_GPIO PIN_CFG(141, GPIO) +#define GPIO141_KP_O6 PIN_CFG(141, ALT_A) +#define GPIO141_ETM_D6 PIN_CFG(141, ALT_B) +#define GPIO141_U0_RXD PIN_CFG(141, ALT_C) + +#define GPIO142_GPIO PIN_CFG(142, GPIO) +#define GPIO142_KP_I7 PIN_CFG(142, ALT_A) +#define GPIO142_ETM_D5 PIN_CFG(142, ALT_B) +#define GPIO142_STMAPE_DAT0 PIN_CFG(142, ALT_C) + +#define GPIO143_GPIO PIN_CFG(143, GPIO) +#define GPIO143_KP_O7 PIN_CFG(143, ALT_A) +#define GPIO143_ETM_D4 PIN_CFG(143, ALT_B) +#define GPIO143_STMAPE_DAT1 PIN_CFG(143, ALT_C) + +#define GPIO144_GPIO PIN_CFG(144, GPIO) +#define GPIO144_I2C3_SCL PIN_CFG(144, ALT_A) +#define GPIO144_ETM_D3 PIN_CFG(144, ALT_B) +#define GPIO144_STMAPE_DAT2 PIN_CFG(144, ALT_C) + +#define GPIO145_GPIO PIN_CFG(145, GPIO) +#define GPIO145_I2C3_SDA PIN_CFG(145, ALT_A) +#define GPIO145_ETM_D2 PIN_CFG(145, ALT_B) +#define GPIO145_STMAPE_DAT3 PIN_CFG(145, ALT_C) + +#define GPIO146_GPIO PIN_CFG(146, GPIO) +#define GPIO146_PWM_0 PIN_CFG(146, ALT_A) +#define GPIO146_ETM_D1 PIN_CFG(146, ALT_B) + +#define GPIO147_GPIO PIN_CFG(147, GPIO) +#define GPIO147_PWM_1 PIN_CFG(147, ALT_A) +#define GPIO147_ETM_D0 PIN_CFG(147, ALT_B) + +#define GPIO148_GPIO PIN_CFG(148, GPIO) +#define GPIO148_PWM_2 PIN_CFG(148, ALT_A) +#define GPIO148_ETM_CLK PIN_CFG(148, ALT_B) + +#define GPIO160_GPIO PIN_CFG(160, GPIO) +#define GPIO160_CLKOUT_REQn PIN_CFG(160, ALT_A) + +#define GPIO161_GPIO PIN_CFG(161, GPIO) +#define GPIO161_CLKOUT_0 PIN_CFG(161, ALT_A) + +#define GPIO162_GPIO PIN_CFG(162, GPIO) +#define GPIO162_CLKOUT_1 PIN_CFG(162, ALT_A) + +#define GPIO163_GPIO PIN_CFG(163, GPIO) + +#define GPIO164_GPIO PIN_CFG(164, GPIO) +#define GPIO164_GPS_START PIN_CFG(164, ALT_A) + +#define GPIO165_GPIO PIN_CFG(165, GPIO) +#define GPIO165_SPI1_CS2n PIN_CFG(165, ALT_A) +#define GPIO165_U3_RXD PIN_CFG(165, ALT_B) +#define GPIO165_BUSMON_D20 PIN_CFG(165, ALT_C) + +#define GPIO166_GPIO PIN_CFG(166, GPIO) +#define GPIO166_SPI1_CS1n PIN_CFG(166, ALT_A) +#define GPIO166_U3_TXD PIN_CFG(166, ALT_B) +#define GPIO166_BUSMON_D21 PIN_CFG(166, ALT_C) + +#define GPIO167_GPIO PIN_CFG(167, GPIO) +#define GPIO167_SPI1_CS0n PIN_CFG(167, ALT_A) +#define GPIO167_U3_RTSn PIN_CFG(167, ALT_B) +#define GPIO167_BUSMON_D22 PIN_CFG(167, ALT_C) + +#define GPIO168_GPIO PIN_CFG(168, GPIO) +#define GPIO168_SPI1_RXD PIN_CFG(168, ALT_A) +#define GPIO168_U3_CTSn PIN_CFG(168, ALT_B) +#define GPIO168_BUSMON_D23 PIN_CFG(168, ALT_C) + +#define GPIO169_GPIO PIN_CFG(169, GPIO) +#define GPIO169_SPI1_TXD PIN_CFG(169, ALT_A) +#define GPIO169_DDR_RC PIN_CFG(169, ALT_B) +#define GPIO169_BUSMON_D24 PIN_CFG(169, ALT_C) + +#define GPIO170_GPIO PIN_CFG(170, GPIO) +#define GPIO170_SPI1_CLK PIN_CFG(170, ALT_A) + +#define GPIO171_GPIO PIN_CFG(171, GPIO) +#define GPIO171_MC3_DAT0 PIN_CFG(171, ALT_A) +#define GPIO171_SPI3_RXD PIN_CFG(171, ALT_B) +#define GPIO171_BUSMON_D25 PIN_CFG(171, ALT_C) + +#define GPIO172_GPIO PIN_CFG(172, GPIO) +#define GPIO172_MC3_DAT1 PIN_CFG(172, ALT_A) +#define GPIO172_SPI3_CS1n PIN_CFG(172, ALT_B) +#define GPIO172_BUSMON_D26 PIN_CFG(172, ALT_C) + +#define GPIO173_GPIO PIN_CFG(173, GPIO) +#define GPIO173_MC3_DAT2 PIN_CFG(173, ALT_A) +#define GPIO173_SPI3_CS2n PIN_CFG(173, ALT_B) +#define GPIO173_BUSMON_D27 PIN_CFG(173, ALT_C) + +#define GPIO174_GPIO PIN_CFG(174, GPIO) +#define GPIO174_MC3_DAT3 PIN_CFG(174, ALT_A) +#define GPIO174_SPI3_CS0n PIN_CFG(174, ALT_B) +#define GPIO174_BUSMON_D28 PIN_CFG(174, ALT_C) + +#define GPIO175_GPIO PIN_CFG(175, GPIO) +#define GPIO175_MC3_CMD PIN_CFG(175, ALT_A) +#define GPIO175_SPI3_TXD PIN_CFG(175, ALT_B) +#define GPIO175_BUSMON_D29 PIN_CFG(175, ALT_C) + +#define GPIO176_GPIO PIN_CFG(176, GPIO) +#define GPIO176_MC3_CLK PIN_CFG(176, ALT_A) +#define GPIO176_SPI3_CLK PIN_CFG(176, ALT_B) + +#define GPIO177_GPIO PIN_CFG(177, GPIO) +#define GPIO177_U2_RXD PIN_CFG(177, ALT_A) +#define GPIO177_I2C3_SCL PIN_CFG(177, ALT_B) +#define GPIO177_BUSMON_D30 PIN_CFG(177, ALT_C) + +#define GPIO178_GPIO PIN_CFG(178, GPIO) +#define GPIO178_U2_TXD PIN_CFG(178, ALT_A) +#define GPIO178_I2C3_SDA PIN_CFG(178, ALT_B) +#define GPIO178_BUSMON_D31 PIN_CFG(178, ALT_C) + +#define GPIO179_GPIO PIN_CFG(179, GPIO) +#define GPIO179_U2_CTSn PIN_CFG(179, ALT_A) +#define GPIO179_U3_RXD PIN_CFG(179, ALT_B) +#define GPIO179_BUSMON_D32 PIN_CFG(179, ALT_C) + +#define GPIO180_GPIO PIN_CFG(180, GPIO) +#define GPIO180_U2_RTSn PIN_CFG(180, ALT_A) +#define GPIO180_U3_TXD PIN_CFG(180, ALT_B) +#define GPIO180_BUSMON_D33 PIN_CFG(180, ALT_C) + +#define GPIO185_GPIO PIN_CFG(185, GPIO) +#define GPIO185_SPI3_CS2n PIN_CFG(185, ALT_A) +#define GPIO185_MC4_DAT0 PIN_CFG(185, ALT_B) + +#define GPIO186_GPIO PIN_CFG(186, GPIO) +#define GPIO186_SPI3_CS1n PIN_CFG(186, ALT_A) +#define GPIO186_MC4_DAT1 PIN_CFG(186, ALT_B) + +#define GPIO187_GPIO PIN_CFG(187, GPIO) +#define GPIO187_SPI3_CS0n PIN_CFG(187, ALT_A) +#define GPIO187_MC4_DAT2 PIN_CFG(187, ALT_B) + +#define GPIO188_GPIO PIN_CFG(188, GPIO) +#define GPIO188_SPI3_RXD PIN_CFG(188, ALT_A) +#define GPIO188_MC4_DAT3 PIN_CFG(188, ALT_B) + +#define GPIO189_GPIO PIN_CFG(189, GPIO) +#define GPIO189_SPI3_TXD PIN_CFG(189, ALT_A) +#define GPIO189_MC4_CMD PIN_CFG(189, ALT_B) + +#define GPIO190_GPIO PIN_CFG(190, GPIO) +#define GPIO190_SPI3_CLK PIN_CFG(190, ALT_A) +#define GPIO190_MC4_CLK PIN_CFG(190, ALT_B) + +#define GPIO191_GPIO PIN_CFG(191, GPIO) +#define GPIO191_MC1_DAT0 PIN_CFG(191, ALT_A) +#define GPIO191_MC4_DAT4 PIN_CFG(191, ALT_B) +#define GPIO191_STMAPE_DAT0 PIN_CFG(191, ALT_C) + +#define GPIO192_GPIO PIN_CFG(192, GPIO) +#define GPIO192_MC1_DAT1 PIN_CFG(192, ALT_A) +#define GPIO192_MC4_DAT5 PIN_CFG(192, ALT_B) +#define GPIO192_STMAPE_DAT1 PIN_CFG(192, ALT_C) + +#define GPIO193_GPIO PIN_CFG(193, GPIO) +#define GPIO193_MC1_DAT2 PIN_CFG(193, ALT_A) +#define GPIO193_MC4_DAT6 PIN_CFG(193, ALT_B) +#define GPIO193_STMAPE_DAT2 PIN_CFG(193, ALT_C) + +#define GPIO194_GPIO PIN_CFG(194, GPIO) +#define GPIO194_MC1_DAT3 PIN_CFG(194, ALT_A) +#define GPIO194_MC4_DAT7 PIN_CFG(194, ALT_B) +#define GPIO194_STMAPE_DAT3 PIN_CFG(194, ALT_C) + +#define GPIO195_GPIO PIN_CFG(195, GPIO) +#define GPIO195_MC1_CLK PIN_CFG(195, ALT_A) +#define GPIO195_STMAPE_CLK PIN_CFG(195, ALT_B) +#define GPIO195_BUSMON_CLK PIN_CFG(195, ALT_C) + +#define GPIO196_GPIO PIN_CFG(196, GPIO) +#define GPIO196_MC1_CMD PIN_CFG(196, ALT_A) +#define GPIO196_U0_RXD PIN_CFG(196, ALT_B) +#define GPIO196_BUSMON_D38 PIN_CFG(196, ALT_C) + +#define GPIO197_GPIO PIN_CFG(197, GPIO) +#define GPIO197_MC1_CMDDIR PIN_CFG(197, ALT_A) +#define GPIO197_BUSMON_D39 PIN_CFG(197, ALT_B) + +#define GPIO198_GPIO PIN_CFG(198, GPIO) +#define GPIO198_MC1_FBCLK PIN_CFG(198, ALT_A) + +#define GPIO199_GPIO PIN_CFG(199, GPIO) +#define GPIO199_MC1_DAT0DIR PIN_CFG(199, ALT_A) +#define GPIO199_BUSMON_D40 PIN_CFG(199, ALT_B) + +#define GPIO200_GPIO PIN_CFG(200, GPIO) +#define GPIO200_U1_TXD PIN_CFG(200, ALT_A) +#define GPIO200_ACCU0_RTSn PIN_CFG(200, ALT_B) + +#define GPIO201_GPIO PIN_CFG(201, GPIO) +#define GPIO201_U1_RXD PIN_CFG(201, ALT_A) +#define GPIO201_ACCU0_CTSn PIN_CFG(201, ALT_B) + +#define GPIO202_GPIO PIN_CFG(202, GPIO) +#define GPIO202_U1_CTSn PIN_CFG(202, ALT_A) +#define GPIO202_ACCU0_RXD PIN_CFG(202, ALT_B) + +#define GPIO203_GPIO PIN_CFG(203, GPIO) +#define GPIO203_U1_RTSn PIN_CFG(203, ALT_A) +#define GPIO203_ACCU0_TXD PIN_CFG(203, ALT_B) + +#define GPIO204_GPIO PIN_CFG(204, GPIO) +#define GPIO204_SPI0_CS2n PIN_CFG(204, ALT_A) +#define GPIO204_ACCGPIO_000 PIN_CFG(204, ALT_B) +#define GPIO204_LCD_VSI1 PIN_CFG(204, ALT_C) + +#define GPIO205_GPIO PIN_CFG(205, GPIO) +#define GPIO205_SPI0_CS1n PIN_CFG(205, ALT_A) +#define GPIO205_ACCGPIO_001 PIN_CFG(205, ALT_B) +#define GPIO205_LCD_D3 PIN_CFG(205, ALT_C) + +#define GPIO206_GPIO PIN_CFG(206, GPIO) +#define GPIO206_SPI0_CS0n PIN_CFG(206, ALT_A) +#define GPIO206_ACCGPIO_002 PIN_CFG(206, ALT_B) +#define GPIO206_LCD_D2 PIN_CFG(206, ALT_C) + +#define GPIO207_GPIO PIN_CFG(207, GPIO) +#define GPIO207_SPI0_RXD PIN_CFG(207, ALT_A) +#define GPIO207_ACCGPIO_003 PIN_CFG(207, ALT_B) +#define GPIO207_LCD_D1 PIN_CFG(207, ALT_C) + +#define GPIO208_GPIO PIN_CFG(208, GPIO) +#define GPIO208_SPI0_TXD PIN_CFG(208, ALT_A) +#define GPIO208_ACCGPIO_004 PIN_CFG(208, ALT_B) +#define GPIO208_LCD_D0 PIN_CFG(208, ALT_C) + +#define GPIO209_GPIO PIN_CFG(209, GPIO) +#define GPIO209_SPI0_CLK PIN_CFG(209, ALT_A) +#define GPIO209_ACCGPIO_005 PIN_CFG(209, ALT_B) +#define GPIO209_LCD_CLK PIN_CFG(209, ALT_C) + +#define GPIO210_GPIO PIN_CFG(210, GPIO) +#define GPIO210_LCD_VSO PIN_CFG(210, ALT_A) +#define GPIO210_PRCMU_PWRCTRL1 PIN_CFG(210, ALT_B) + +#define GPIO211_GPIO PIN_CFG(211, GPIO) +#define GPIO211_LCD_VSI0 PIN_CFG(211, ALT_A) +#define GPIO211_PRCMU_PWRCTRL2 PIN_CFG(211, ALT_B) + +#define GPIO212_GPIO PIN_CFG(212, GPIO) +#define GPIO212_SPI2_CS2n PIN_CFG(212, ALT_A) +#define GPIO212_LCD_HSO PIN_CFG(212, ALT_B) + +#define GPIO213_GPIO PIN_CFG(213, GPIO) +#define GPIO213_SPI2_CS1n PIN_CFG(213, ALT_A) +#define GPIO213_LCD_DE PIN_CFG(213, ALT_B) +#define GPIO213_BUSMON_D16 PIN_CFG(213, ALT_C) + +#define GPIO214_GPIO PIN_CFG(214, GPIO) +#define GPIO214_SPI2_CS0n PIN_CFG(214, ALT_A) +#define GPIO214_LCD_D7 PIN_CFG(214, ALT_B) +#define GPIO214_BUSMON_D17 PIN_CFG(214, ALT_C) + +#define GPIO215_GPIO PIN_CFG(215, GPIO) +#define GPIO215_SPI2_RXD PIN_CFG(215, ALT_A) +#define GPIO215_LCD_D6 PIN_CFG(215, ALT_B) +#define GPIO215_BUSMON_D18 PIN_CFG(215, ALT_C) + +#define GPIO216_GPIO PIN_CFG(216, GPIO) +#define GPIO216_SPI2_CLK PIN_CFG(216, ALT_A) +#define GPIO216_LCD_D5 PIN_CFG(216, ALT_B) + +#define GPIO217_GPIO PIN_CFG(217, GPIO) +#define GPIO217_SPI2_TXD PIN_CFG(217, ALT_A) +#define GPIO217_LCD_D4 PIN_CFG(217, ALT_B) +#define GPIO217_BUSMON_D19 PIN_CFG(217, ALT_C) + +#define GPIO218_GPIO PIN_CFG(218, GPIO) +#define GPIO218_I2C2_SCL PIN_CFG(218, ALT_A) +#define GPIO218_LCD_VSO PIN_CFG(218, ALT_B) + +#define GPIO219_GPIO PIN_CFG(219, GPIO) +#define GPIO219_I2C2_SDA PIN_CFG(219, ALT_A) +#define GPIO219_LCD_D3 PIN_CFG(219, ALT_B) + +#define GPIO220_GPIO PIN_CFG(220, GPIO) +#define GPIO220_MSP2_TCK PIN_CFG(220, ALT_A) +#define GPIO220_LCD_D2 PIN_CFG(220, ALT_B) + +#define GPIO221_GPIO PIN_CFG(221, GPIO) +#define GPIO221_MSP2_TFS PIN_CFG(221, ALT_A) +#define GPIO221_LCD_D1 PIN_CFG(221, ALT_B) + +#define GPIO222_GPIO PIN_CFG(222, GPIO) +#define GPIO222_MSP2_TXD PIN_CFG(222, ALT_A) +#define GPIO222_LCD_D0 PIN_CFG(222, ALT_B) + +#define GPIO223_GPIO PIN_CFG(223, GPIO) +#define GPIO223_MSP2_RXD PIN_CFG(223, ALT_A) +#define GPIO223_LCD_CLK PIN_CFG(223, ALT_B) + +#define GPIO224_GPIO PIN_CFG(224, GPIO) +#define GPIO224_PRCMU_PWRCTRL0 PIN_CFG(224, ALT_A) +#define GPIO224_LCD_VSI1 PIN_CFG(224, ALT_B) + +#define GPIO225_GPIO PIN_CFG(225, GPIO) +#define GPIO225_PRCMU_PWRCTRL1 PIN_CFG(225, ALT_A) +#define GPIO225_IRDA_RXD PIN_CFG(225, ALT_B) + +#define GPIO226_GPIO PIN_CFG(226, GPIO) +#define GPIO226_PRCMU_PWRCTRL2 PIN_CFG(226, ALT_A) +#define GPIO226_IRRC_DAT PIN_CFG(226, ALT_B) + +#define GPIO227_GPIO PIN_CFG(227, GPIO) +#define GPIO227_IRRC_DAT PIN_CFG(227, ALT_A) +#define GPIO227_IRDA_TXD PIN_CFG(227, ALT_B) + +#endif diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index e8cd51aa61e4..d2058ef8345f 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -48,7 +48,9 @@ static void write_pen_release(int val) static void __iomem *scu_base_addr(void) { - if (cpu_is_u8500()) + if (cpu_is_u5500()) + return __io_address(U5500_SCU_BASE); + else if (cpu_is_u8500()) return __io_address(U8500_SCU_BASE); else ux500_unknown_soc(); @@ -97,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ write_pen_release(cpu_logical_map(cpu)); - smp_send_reschedule(cpu); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -118,7 +120,9 @@ static void __init wakeup_secondary(void) { void __iomem *backupram; - if (cpu_is_u8500()) + if (cpu_is_u5500()) + backupram = __io_address(U5500_BACKUPRAM0_BASE); + else if (cpu_is_u8500()) backupram = __io_address(U8500_BACKUPRAM0_BASE); else ux500_unknown_soc(); diff --git a/trunk/arch/arm/mach-ux500/ste-dma40-db5500.h b/trunk/arch/arm/mach-ux500/ste-dma40-db5500.h new file mode 100644 index 000000000000..cb2110c32858 --- /dev/null +++ b/trunk/arch/arm/mach-ux500/ste-dma40-db5500.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * + * DB5500-SoC-specific configuration for DMA40 + */ + +#ifndef STE_DMA40_DB5500_H +#define STE_DMA40_DB5500_H + +#define DB5500_DMA_NR_DEV 64 + +enum dma_src_dev_type { + DB5500_DMA_DEV0_SPI0_RX = 0, + DB5500_DMA_DEV1_SPI1_RX = 1, + DB5500_DMA_DEV2_SPI2_RX = 2, + DB5500_DMA_DEV3_SPI3_RX = 3, + DB5500_DMA_DEV4_USB_OTG_IEP_1_9 = 4, + DB5500_DMA_DEV5_USB_OTG_IEP_2_10 = 5, + DB5500_DMA_DEV6_USB_OTG_IEP_3_11 = 6, + DB5500_DMA_DEV7_IRDA_RFS = 7, + DB5500_DMA_DEV8_IRDA_FIFO_RX = 8, + DB5500_DMA_DEV9_MSP0_RX = 9, + DB5500_DMA_DEV10_MSP1_RX = 10, + DB5500_DMA_DEV11_MSP2_RX = 11, + DB5500_DMA_DEV12_UART0_RX = 12, + DB5500_DMA_DEV13_UART1_RX = 13, + DB5500_DMA_DEV14_UART2_RX = 14, + DB5500_DMA_DEV15_UART3_RX = 15, + DB5500_DMA_DEV16_USB_OTG_IEP_8 = 16, + DB5500_DMA_DEV17_USB_OTG_IEP_1_9 = 17, + DB5500_DMA_DEV18_USB_OTG_IEP_2_10 = 18, + DB5500_DMA_DEV19_USB_OTG_IEP_3_11 = 19, + DB5500_DMA_DEV20_USB_OTG_IEP_4_12 = 20, + DB5500_DMA_DEV21_USB_OTG_IEP_5_13 = 21, + DB5500_DMA_DEV22_USB_OTG_IEP_6_14 = 22, + DB5500_DMA_DEV23_USB_OTG_IEP_7_15 = 23, + DB5500_DMA_DEV24_SDMMC0_RX = 24, + DB5500_DMA_DEV25_SDMMC1_RX = 25, + DB5500_DMA_DEV26_SDMMC2_RX = 26, + DB5500_DMA_DEV27_SDMMC3_RX = 27, + DB5500_DMA_DEV28_SDMMC4_RX = 28, + /* 29 - 32 not used */ + DB5500_DMA_DEV33_SDMMC0_RX = 33, + DB5500_DMA_DEV34_SDMMC1_RX = 34, + DB5500_DMA_DEV35_SDMMC2_RX = 35, + DB5500_DMA_DEV36_SDMMC3_RX = 36, + DB5500_DMA_DEV37_SDMMC4_RX = 37, + DB5500_DMA_DEV38_USB_OTG_IEP_8 = 38, + DB5500_DMA_DEV39_USB_OTG_IEP_1_9 = 39, + DB5500_DMA_DEV40_USB_OTG_IEP_2_10 = 40, + DB5500_DMA_DEV41_USB_OTG_IEP_3_11 = 41, + DB5500_DMA_DEV42_USB_OTG_IEP_4_12 = 42, + DB5500_DMA_DEV43_USB_OTG_IEP_5_13 = 43, + DB5500_DMA_DEV44_USB_OTG_IEP_6_14 = 44, + DB5500_DMA_DEV45_USB_OTG_IEP_7_15 = 45, + /* 46 not used */ + DB5500_DMA_DEV47_MCDE_RX = 47, + DB5500_DMA_DEV48_CRYPTO1_RX = 48, + /* 49, 50 not used */ + DB5500_DMA_DEV49_I2C1_RX = 51, + DB5500_DMA_DEV50_I2C3_RX = 52, + DB5500_DMA_DEV51_I2C2_RX = 53, + /* 54 - 60 not used */ + DB5500_DMA_DEV61_CRYPTO0_RX = 61, + /* 62, 63 not used */ +}; + +enum dma_dest_dev_type { + DB5500_DMA_DEV0_SPI0_TX = 0, + DB5500_DMA_DEV1_SPI1_TX = 1, + DB5500_DMA_DEV2_SPI2_TX = 2, + DB5500_DMA_DEV3_SPI3_TX = 3, + DB5500_DMA_DEV4_USB_OTG_OEP_1_9 = 4, + DB5500_DMA_DEV5_USB_OTG_OEP_2_10 = 5, + DB5500_DMA_DEV6_USB_OTG_OEP_3_11 = 6, + DB5500_DMA_DEV7_IRRC_TX = 7, + DB5500_DMA_DEV8_IRDA_FIFO_TX = 8, + DB5500_DMA_DEV9_MSP0_TX = 9, + DB5500_DMA_DEV10_MSP1_TX = 10, + DB5500_DMA_DEV11_MSP2_TX = 11, + DB5500_DMA_DEV12_UART0_TX = 12, + DB5500_DMA_DEV13_UART1_TX = 13, + DB5500_DMA_DEV14_UART2_TX = 14, + DB5500_DMA_DEV15_UART3_TX = 15, + DB5500_DMA_DEV16_USB_OTG_OEP_8 = 16, + DB5500_DMA_DEV17_USB_OTG_OEP_1_9 = 17, + DB5500_DMA_DEV18_USB_OTG_OEP_2_10 = 18, + DB5500_DMA_DEV19_USB_OTG_OEP_3_11 = 19, + DB5500_DMA_DEV20_USB_OTG_OEP_4_12 = 20, + DB5500_DMA_DEV21_USB_OTG_OEP_5_13 = 21, + DB5500_DMA_DEV22_USB_OTG_OEP_6_14 = 22, + DB5500_DMA_DEV23_USB_OTG_OEP_7_15 = 23, + DB5500_DMA_DEV24_SDMMC0_TX = 24, + DB5500_DMA_DEV25_SDMMC1_TX = 25, + DB5500_DMA_DEV26_SDMMC2_TX = 26, + DB5500_DMA_DEV27_SDMMC3_TX = 27, + DB5500_DMA_DEV28_SDMMC4_TX = 28, + /* 29 - 31 not used */ + DB5500_DMA_DEV32_FSMC_TX = 32, + DB5500_DMA_DEV33_SDMMC0_TX = 33, + DB5500_DMA_DEV34_SDMMC1_TX = 34, + DB5500_DMA_DEV35_SDMMC2_TX = 35, + DB5500_DMA_DEV36_SDMMC3_TX = 36, + DB5500_DMA_DEV37_SDMMC4_TX = 37, + DB5500_DMA_DEV38_USB_OTG_OEP_8 = 38, + DB5500_DMA_DEV39_USB_OTG_OEP_1_9 = 39, + DB5500_DMA_DEV40_USB_OTG_OEP_2_10 = 40, + DB5500_DMA_DEV41_USB_OTG_OEP_3_11 = 41, + DB5500_DMA_DEV42_USB_OTG_OEP_4_12 = 42, + DB5500_DMA_DEV43_USB_OTG_OEP_5_13 = 43, + DB5500_DMA_DEV44_USB_OTG_OEP_6_14 = 44, + DB5500_DMA_DEV45_USB_OTG_OEP_7_15 = 45, + /* 46 not used */ + DB5500_DMA_DEV47_STM_TX = 47, + DB5500_DMA_DEV48_CRYPTO1_TX = 48, + DB5500_DMA_DEV49_CRYPTO1_TX_HASH1_TX = 49, + DB5500_DMA_DEV50_HASH1_TX = 50, + DB5500_DMA_DEV51_I2C1_TX = 51, + DB5500_DMA_DEV52_I2C3_TX = 52, + DB5500_DMA_DEV53_I2C2_TX = 53, + /* 54, 55 not used */ + DB5500_DMA_MEMCPY_TX_1 = 56, + DB5500_DMA_MEMCPY_TX_2 = 57, + DB5500_DMA_MEMCPY_TX_3 = 58, + DB5500_DMA_MEMCPY_TX_4 = 59, + DB5500_DMA_MEMCPY_TX_5 = 60, + DB5500_DMA_DEV61_CRYPTO0_TX = 61, + DB5500_DMA_DEV62_CRYPTO0_TX_HASH0_TX = 62, + DB5500_DMA_DEV63_HASH0_TX = 63, +}; + +#endif diff --git a/trunk/arch/arm/mach-ux500/timer.c b/trunk/arch/arm/mach-ux500/timer.c index 52e55337aa9b..d37df98b5c32 100644 --- a/trunk/arch/arm/mach-ux500/timer.c +++ b/trunk/arch/arm/mach-ux500/timer.c @@ -18,6 +18,8 @@ #include #ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(u5500_twd_local_timer, + U5500_TWD_BASE, IRQ_LOCALTIMER); static DEFINE_TWD_LOCAL_TIMER(u8500_twd_local_timer, U8500_TWD_BASE, IRQ_LOCALTIMER); @@ -26,8 +28,8 @@ static void __init ux500_twd_init(void) struct twd_local_timer *twd_local_timer; int err; - /* Use this to switch local timer base if changed in new ASICs */ - twd_local_timer = &u8500_twd_local_timer; + twd_local_timer = cpu_is_u5500() ? &u5500_twd_local_timer : + &u8500_twd_local_timer; if (of_have_populated_dt()) twd_local_timer_of_register(); @@ -46,7 +48,10 @@ static void __init ux500_timer_init(void) void __iomem *mtu_timer_base; void __iomem *prcmu_timer_base; - if (cpu_is_u8500()) { + if (cpu_is_u5500()) { + mtu_timer_base = __io_address(U5500_MTU0_BASE); + prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE); + } else if (cpu_is_u8500()) { mtu_timer_base = __io_address(U8500_MTU0_BASE); prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); } else { @@ -65,7 +70,7 @@ static void __init ux500_timer_init(void) * depending on delay which is not yet calibrated. RTC-RTT is in the * always-on powerdomain and is used as clockevent instead of twd when * sleeping. - * The PRCMU timer 4 register a clocksource and + * The PRCMU timer 4(3 for DB5500) register a clocksource and * sched_clock with higher rating then MTU since is always-on. * */ diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 7c8a7d8467bf..7edef9121632 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -723,7 +723,7 @@ config CPU_HIGH_VECTOR bool "Select the High exception vector" help Say Y here to select high exception vector(0xFFFF0000~). - The exception vector can vary depending on the platform + The exception vector can be vary depending on the platform design in nommu mode. If your platform needs to select high exception vector, say Y. Otherwise or if you are unsure, say N, and the low exception diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index f07467533365..9055b5a84ec5 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -320,7 +320,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) */ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); - if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) { + if (flags & FAULT_FLAG_ALLOW_RETRY) { if (fault & VM_FAULT_MAJOR) { tsk->maj_flt++; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c index d51225f90ae2..6486d2f253cd 100644 --- a/trunk/arch/arm/mm/nommu.c +++ b/trunk/arch/arm/mm/nommu.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "mm.h" @@ -40,7 +39,6 @@ void __init sanity_check_meminfo(void) */ void __init paging_init(struct machine_desc *mdesc) { - early_trap_init((void *)CONFIG_VECTORS_BASE); bootmem_init(); } diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index c2e2b66f72b5..f1c8486f7501 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -254,18 +254,6 @@ __v7_setup: ldr r6, =NMRR @ NMRR mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR -#endif -#ifndef CONFIG_ARM_THUMBEE - mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE - and r0, r0, #(0xf << 12) @ ThumbEE enabled field - teq r0, #(1 << 12) @ check if ThumbEE is present - bne 1f - mov r5, #0 - mcr p14, 6, r5, c1, c0, 0 @ Initialize TEEHBR to 0 - mrc p14, 6, r0, c0, c0, 0 @ load TEECR - orr r0, r0, #1 @ set the 1st bit in order to - mcr p14, 6, r0, c0, c0, 0 @ stop userspace TEEHBR access -1: #endif adr r5, v7_crval ldmia r5, {r5, r6} diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx51.h index 36c8989d9de6..c7f5169a6a54 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -256,13 +256,13 @@ #define MX51_PAD_NANDF_RB1__GPIO3_9 IOMUX_PAD(0x4fc, 0x120, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_RB1__NANDF_RB1 IOMUX_PAD(0x4fc, 0x120, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB1__PATA_IORDY IOMUX_PAD(0x4fc, 0x120, 1, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_NANDF_RB1__SD4_CMD IOMUX_PAD(0x4fc, 0x120, 0x15, __NA_, 0, MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_NANDF_RB1__SD4_CMD IOMUX_PAD(0x4fc, 0x120, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL) #define MX51_PAD_NANDF_RB2__DISP2_WAIT IOMUX_PAD(0x500, 0x124, 5, 0x9a8, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x94c, 0, MX51_PAD_CTRL_2) #define MX51_PAD_NANDF_RB2__GPIO3_10 IOMUX_PAD(0x500, 0x124, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_RB2__NANDF_RB2 IOMUX_PAD(0x500, 0x124, 0, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_NANDF_RB2__USBH3_H3_DP IOMUX_PAD(0x500, 0x124, 0x17, __NA_, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB2__USBH3_H3_DP IOMUX_PAD(0x500, 0x124, 7, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB2__USBH3_NXT IOMUX_PAD(0x500, 0x124, 6, 0xa20, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB3__DISP1_WAIT IOMUX_PAD(0x504, 0x128, 5, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL) @@ -270,7 +270,7 @@ #define MX51_PAD_NANDF_RB3__GPIO3_11 IOMUX_PAD(0x504, 0x128, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_RB3__NANDF_RB3 IOMUX_PAD(0x504, 0x128, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB3__USBH3_CLK IOMUX_PAD(0x504, 0x128, 6, 0x9f8, 0, NO_PAD_CTRL) -#define MX51_PAD_NANDF_RB3__USBH3_H3_DM IOMUX_PAD(0x504, 0x128, 0x17, __NA_, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB3__USBH3_H3_DM IOMUX_PAD(0x504, 0x128, 7, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_NAND__GPIO_NAND IOMUX_PAD(0x514, 0x12c, 0, 0x998, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_NAND__PATA_INTRQ IOMUX_PAD(0x514, 0x12c, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS0__GPIO3_16 IOMUX_PAD(0x518, 0x130, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) @@ -283,13 +283,13 @@ #define MX51_PAD_NANDF_CS2__NANDF_CS2 IOMUX_PAD(0x520, 0x138, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS2__PATA_CS_0 IOMUX_PAD(0x520, 0x138, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS2__SD4_CLK IOMUX_PAD(0x520, 0x138, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS) -#define MX51_PAD_NANDF_CS2__USBH3_H1_DP IOMUX_PAD(0x520, 0x138, 0x17, __NA_, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS2__USBH3_H1_DP IOMUX_PAD(0x520, 0x138, 7, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13c, 2, __NA_, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS3__GPIO3_19 IOMUX_PAD(0x524, 0x13c, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_CS3__NANDF_CS3 IOMUX_PAD(0x524, 0x13c, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS3__PATA_CS_1 IOMUX_PAD(0x524, 0x13c, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS3__SD4_DAT0 IOMUX_PAD(0x524, 0x13c, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL) -#define MX51_PAD_NANDF_CS3__USBH3_H1_DM IOMUX_PAD(0x524, 0x13c, 0x17, __NA_, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS3__USBH3_H1_DM IOMUX_PAD(0x524, 0x13c, 7, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS4__FEC_TDATA1 IOMUX_PAD(0x528, 0x140, 2, __NA_, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS4__GPIO3_20 IOMUX_PAD(0x528, 0x140, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_CS4__NANDF_CS4 IOMUX_PAD(0x528, 0x140, 0, __NA_, 0, NO_PAD_CTRL) @@ -316,7 +316,7 @@ #define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x974, 0, MX51_PAD_CTRL_4) #define MX51_PAD_NANDF_RDY_INT__GPIO3_24 IOMUX_PAD(0x538, 0x150, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT IOMUX_PAD(0x538, 0x150, 0, 0x938, 0, NO_PAD_CTRL) -#define MX51_PAD_NANDF_RDY_INT__SD3_CMD IOMUX_PAD(0x538, 0x150, 0x15, __NA_, 0, MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_NANDF_RDY_INT__SD3_CMD IOMUX_PAD(0x538, 0x150, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL) #define MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53c, 0x154, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_NANDF_D15__GPIO3_25 IOMUX_PAD(0x53c, 0x154, 3, __NA_, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_NANDF_D15__NANDF_D15 IOMUX_PAD(0x53c, 0x154, 0, __NA_, 0, NO_PAD_CTRL) @@ -672,23 +672,23 @@ #define MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT6__DISP2_DAT6 IOMUX_PAD(0x774, 0x36c, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT6__FEC_TDATA1 IOMUX_PAD(0x774, 0x36c, 2, __NA_, 0, MX51_PAD_CTRL_5) -#define MX51_PAD_DISP2_DAT6__GPIO1_19 IOMUX_PAD(0x774, 0x36c, 5, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT6__GPIO1_19 IOMUX_PAD(0x774, 0x36c, 5, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT6__KEY_ROW4 IOMUX_PAD(0x774, 0x36c, 4, 0x9d0, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT6__USBH3_STP IOMUX_PAD(0x774, 0x36c, 3, 0xa24, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT7__DISP2_DAT7 IOMUX_PAD(0x778, 0x370, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT7__FEC_TDATA2 IOMUX_PAD(0x778, 0x370, 2, __NA_, 0, MX51_PAD_CTRL_5) -#define MX51_PAD_DISP2_DAT7__GPIO1_29 IOMUX_PAD(0x778, 0x370, 5, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT7__GPIO1_29 IOMUX_PAD(0x778, 0x370, 5, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT7__KEY_ROW5 IOMUX_PAD(0x778, 0x370, 4, 0x9d4, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT7__USBH3_NXT IOMUX_PAD(0x778, 0x370, 3, 0xa20, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT8__DISP2_DAT8 IOMUX_PAD(0x77c, 0x374, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT8__FEC_TDATA3 IOMUX_PAD(0x77c, 0x374, 2, __NA_, 0, MX51_PAD_CTRL_5) -#define MX51_PAD_DISP2_DAT8__GPIO1_30 IOMUX_PAD(0x77c, 0x374, 5, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT8__GPIO1_30 IOMUX_PAD(0x77c, 0x374, 5, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT8__KEY_ROW6 IOMUX_PAD(0x77c, 0x374, 4, 0x9d8, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT8__USBH3_DATA0 IOMUX_PAD(0x77c, 0x374, 3, 0x9fc, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT9__AUD6_RXC IOMUX_PAD(0x780, 0x378, 4, 0x8f4, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT9__DISP2_DAT9 IOMUX_PAD(0x780, 0x378, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT9__FEC_TX_EN IOMUX_PAD(0x780, 0x378, 2, __NA_, 0, MX51_PAD_CTRL_5) -#define MX51_PAD_DISP2_DAT9__GPIO1_31 IOMUX_PAD(0x780, 0x378, 5, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT9__GPIO1_31 IOMUX_PAD(0x780, 0x378, 5, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT9__USBH3_DATA1 IOMUX_PAD(0x780, 0x378, 3, 0xa00, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37c, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT10__DISP2_SER_CS IOMUX_PAD(0x784, 0x37c, 5, __NA_, 0, NO_PAD_CTRL) @@ -698,7 +698,7 @@ #define MX51_PAD_DISP2_DAT11__AUD6_TXD IOMUX_PAD(0x788, 0x380, 4, 0x8f0, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT11__FEC_RX_CLK IOMUX_PAD(0x788, 0x380, 2, 0x968, 1, NO_PAD_CTRL) -#define MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT11__USBH3_DATA3 IOMUX_PAD(0x788, 0x380, 3, 0xa08, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT12__AUD6_RXD IOMUX_PAD(0x78c, 0x384, 4, 0x8ec, 1, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78c, 0x384, 0, __NA_, 0, NO_PAD_CTRL) @@ -746,16 +746,16 @@ #define MX51_PAD_SD1_DATA3__CSPI_SS1 IOMUX_PAD(0x7b0, 0x3a8, 2, 0x920, 1, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7b0, 0x3a8, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL) #define MX51_PAD_GPIO1_0__CSPI_SS2 IOMUX_PAD(0x7b4, 0x3ac, 2, 0x924, 0, MX51_ECSPI_PAD_CTRL) -#define MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7b4, 0x3ac, 1, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7b4, 0x3ac, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_0__SD1_CD IOMUX_PAD(0x7b4, 0x3ac, 0, __NA_, 0, MX51_ESDHC_PAD_CTRL) #define MX51_PAD_GPIO1_1__CSPI_MISO IOMUX_PAD(0x7b8, 0x3b0, 2, 0x918, 2, MX51_ECSPI_PAD_CTRL) -#define MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7b8, 0x3b0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7b8, 0x3b0, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_1__SD1_WP IOMUX_PAD(0x7b8, 0x3b0, 0, __NA_, 0, MX51_ESDHC_PAD_CTRL) #define MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(__NA_, 0x04c, 0, 0x000, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(__NA_, 0x050, 0, 0x000, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(__NA_, 0x054, 0, 0x000, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(__NA_, 0x058, 0, 0x000, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(0x7bc, 0x3b4, 2, 0x91c, 3, MX51_ECSPI_PAD_CTRL) +#define MX51_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(__NA_, 0x3b4, 2, 0x91c, 3, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_SD2_CMD__I2C1_SCL IOMUX_PAD(0x7bc, 0x3b4, 0x11, 0x9b0, 2, MX51_I2C_PAD_CTRL) #define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7bc, 0x3b4, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL) #define MX51_PAD_SD2_CLK__CSPI_SCLK IOMUX_PAD(0x7c0, 0x3b8, 2, 0x914, 3, MX51_ECSPI_PAD_CTRL) @@ -766,19 +766,19 @@ #define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7c4, 0x3bc, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL) #define MX51_PAD_SD2_DATA1__SD1_DAT5 IOMUX_PAD(0x7c8, 0x3c0, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7c8, 0x3c0, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL) -#define MX51_PAD_SD2_DATA1__USBH3_H2_DP IOMUX_PAD(0x7c8, 0x3c0, 0x12, __NA_, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_DATA1__USBH3_H2_DP IOMUX_PAD(0x7c8, 0x3c0, 2, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_SD2_DATA2__SD1_DAT6 IOMUX_PAD(0x7cc, 0x3c4, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7cc, 0x3c4, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL) -#define MX51_PAD_SD2_DATA2__USBH3_H2_DM IOMUX_PAD(0x7cc, 0x3c4, 0x12, __NA_, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_DATA2__USBH3_H2_DM IOMUX_PAD(0x7cc, 0x3c4, 2, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_SD2_DATA3__CSPI_SS2 IOMUX_PAD(0x7d0, 0x3c8, 2, 0x924, 1, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_SD2_DATA3__SD1_DAT7 IOMUX_PAD(0x7d0, 0x3c8, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7d0, 0x3c8, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL) #define MX51_PAD_GPIO1_2__CCM_OUT_2 IOMUX_PAD(0x7d4, 0x3cc, 5, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_2__I2C2_SCL IOMUX_PAD(0x7d4, 0x3cc, 0x12, 0x9b8, 3, MX51_I2C_PAD_CTRL) #define MX51_PAD_GPIO1_2__PLL1_BYP IOMUX_PAD(0x7d4, 0x3cc, 7, 0x90c, 1, NO_PAD_CTRL) #define MX51_PAD_GPIO1_2__PWM1_PWMO IOMUX_PAD(0x7d4, 0x3cc, 1, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_3__I2C2_SDA IOMUX_PAD(0x7d8, 0x3d0, 0x12, 0x9bc, 3, MX51_I2C_PAD_CTRL) #define MX51_PAD_GPIO1_3__PLL2_BYP IOMUX_PAD(0x7d8, 0x3d0, 7, 0x910, 1, NO_PAD_CTRL) #define MX51_PAD_GPIO1_3__PWM2_PWMO IOMUX_PAD(0x7d8, 0x3d0, 1, __NA_, 0, NO_PAD_CTRL) @@ -786,27 +786,27 @@ #define MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B IOMUX_PAD(0x7fc, 0x3d4, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_4__DISP2_EXT_CLK IOMUX_PAD(0x804, 0x3d8, 4, 0x908, 1, NO_PAD_CTRL) #define MX51_PAD_GPIO1_4__EIM_RDY IOMUX_PAD(0x804, 0x3d8, 3, 0x938, 1, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3d8, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3d8, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_4__WDOG1_WDOG_B IOMUX_PAD(0x804, 0x3d8, 2, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_5__CSI2_MCLK IOMUX_PAD(0x808, 0x3dc, 6, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_5__DISP2_PIN16 IOMUX_PAD(0x808, 0x3dc, 3, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_5__WDOG2_WDOG_B IOMUX_PAD(0x808, 0x3dc, 2, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_6__DISP2_PIN17 IOMUX_PAD(0x80c, 0x3e0, 4, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_6__REF_EN_B IOMUX_PAD(0x80c, 0x3e0, 3, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_7__CCM_OUT_0 IOMUX_PAD(0x810, 0x3e4, 3, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_7__SD2_WP IOMUX_PAD(0x810, 0x3e4, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL) #define MX51_PAD_GPIO1_7__SPDIF_OUT1 IOMUX_PAD(0x810, 0x3e4, 2, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_8__CSI2_DATA_EN IOMUX_PAD(0x814, 0x3e8, 2, 0x99c, 2, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3e8, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3e8, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_8__SD2_CD IOMUX_PAD(0x814, 0x3e8, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL) #define MX51_PAD_GPIO1_8__USBH3_PWR IOMUX_PAD(0x814, 0x3e8, 1, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_9__CCM_OUT_1 IOMUX_PAD(0x818, 0x3ec, 3, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_9__DISP2_D1_CS IOMUX_PAD(0x818, 0x3ec, 2, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_9__DISP2_SER_CS IOMUX_PAD(0x818, 0x3ec, 7, __NA_, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3ec, 0, __NA_, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3ec, 0, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_9__SD2_LCTL IOMUX_PAD(0x818, 0x3ec, 6, __NA_, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO1_9__USBH3_OC IOMUX_PAD(0x818, 0x3ec, 1, __NA_, 0, NO_PAD_CTRL) diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h index 9761e003bde2..527f8fe3e31b 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h +++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h @@ -573,7 +573,7 @@ #define MX53_PAD_EIM_D28__UART2_CTS IOMUX_PAD(0x494, 0x14C, 2, __NA_, 0, MX53_UART_PAD_CTRL) #define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO IOMUX_PAD(0x494, 0x14C, 3, 0x82C, 1, NO_PAD_CTRL) #define MX53_PAD_EIM_D28__CSPI_MOSI IOMUX_PAD(0x494, 0x14C, 4, 0x788, 1, NO_PAD_CTRL) -#define MX53_PAD_EIM_D28__I2C1_SDA IOMUX_PAD(0x494, 0x14C, 5 | IOMUX_CONFIG_SION, 0x818, 1, NO_PAD_CTRL) +#define MX53_PAD_EIM_D28__I2C1_SDA IOMUX_PAD(0x494, 0x14C, 5 | IOMUX_CONFIG_SION, 0x818, 1, PAD_CTRL_I2C) #define MX53_PAD_EIM_D28__IPU_EXT_TRIG IOMUX_PAD(0x494, 0x14C, 6, __NA_, 0, NO_PAD_CTRL) #define MX53_PAD_EIM_D28__IPU_DI0_PIN13 IOMUX_PAD(0x494, 0x14C, 7, __NA_, 0, NO_PAD_CTRL) #define MX53_PAD_EIM_D29__EMI_WEIM_D_29 IOMUX_PAD(0x498, 0x150, 0, __NA_, 0, NO_PAD_CTRL) @@ -1187,7 +1187,7 @@ #define MX53_PAD_GPIO_8__ESAI1_TX5_RX0 IOMUX_PAD(0x6C8, 0x338, 0, 0x7F8, 1, NO_PAD_CTRL) #define MX53_PAD_GPIO_8__GPIO1_8 IOMUX_PAD(0x6C8, 0x338, 1, __NA_, 0, NO_PAD_CTRL) #define MX53_PAD_GPIO_8__EPIT2_EPITO IOMUX_PAD(0x6C8, 0x338, 2, __NA_, 0, NO_PAD_CTRL) -#define MX53_PAD_GPIO_8__CAN1_RXCAN IOMUX_PAD(0x6C8, 0x338, 3, 0x760, 2, NO_PAD_CTRL) +#define MX53_PAD_GPIO_8__CAN1_RXCAN IOMUX_PAD(0x6C8, 0x338, 3, 0x760, 3, NO_PAD_CTRL) #define MX53_PAD_GPIO_8__UART2_RXD_MUX IOMUX_PAD(0x6C8, 0x338, 4, 0x880, 5, MX53_UART_PAD_CTRL) #define MX53_PAD_GPIO_8__FIRI_TXD IOMUX_PAD(0x6C8, 0x338, 5, __NA_, 0, NO_PAD_CTRL) #define MX53_PAD_GPIO_8__SPDIF_SRCLK IOMUX_PAD(0x6C8, 0x338, 6, __NA_, 0, NO_PAD_CTRL) diff --git a/trunk/arch/arm/plat-omap/clock.c b/trunk/arch/arm/plat-omap/clock.c index 62ec5c452792..8506cbb7fea4 100644 --- a/trunk/arch/arm/plat-omap/clock.c +++ b/trunk/arch/arm/plat-omap/clock.c @@ -398,6 +398,32 @@ struct clk dummy_ck = { .ops = &clkops_null, }; +#ifdef CONFIG_CPU_FREQ +void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) +{ + unsigned long flags; + + if (!arch_clock || !arch_clock->clk_init_cpufreq_table) + return; + + spin_lock_irqsave(&clockfw_lock, flags); + arch_clock->clk_init_cpufreq_table(table); + spin_unlock_irqrestore(&clockfw_lock, flags); +} + +void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + unsigned long flags; + + if (!arch_clock || !arch_clock->clk_exit_cpufreq_table) + return; + + spin_lock_irqsave(&clockfw_lock, flags); + arch_clock->clk_exit_cpufreq_table(table); + spin_unlock_irqrestore(&clockfw_lock, flags); +} +#endif + /* * */ diff --git a/trunk/arch/arm/plat-omap/include/plat/clock.h b/trunk/arch/arm/plat-omap/include/plat/clock.h index d0ef57c1d71b..240a7b9fd946 100644 --- a/trunk/arch/arm/plat-omap/include/plat/clock.h +++ b/trunk/arch/arm/plat-omap/include/plat/clock.h @@ -272,6 +272,8 @@ struct clk { #endif }; +struct cpufreq_frequency_table; + struct clk_functions { int (*clk_enable)(struct clk *clk); void (*clk_disable)(struct clk *clk); @@ -281,6 +283,10 @@ struct clk_functions { void (*clk_allow_idle)(struct clk *clk); void (*clk_deny_idle)(struct clk *clk); void (*clk_disable_unused)(struct clk *clk); +#ifdef CONFIG_CPU_FREQ + void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); + void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **); +#endif }; extern int mpurate; @@ -295,6 +301,10 @@ extern void recalculate_root_clocks(void); extern unsigned long followparent_recalc(struct clk *clk); extern void clk_enable_init_clocks(void); unsigned long omap_fixed_divisor_recalc(struct clk *clk); +#ifdef CONFIG_CPU_FREQ +extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); +#endif extern struct clk *omap_clk_get_by_name(const char *name); extern int omap_clk_enable_autoidle_all(void); extern int omap_clk_disable_autoidle_all(void); diff --git a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h index 3f26db4ee8e6..8070145ccb98 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -305,7 +305,6 @@ struct omap_hwmod_sysc_fields { * @rev_offs: IP block revision register offset (from module base addr) * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr) * @syss_offs: OCP_SYSSTATUS register offset (from module base addr) - * @srst_udelay: Delay needed after doing a softreset in usecs * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART} * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported * @clockact: the default value of the module CLOCKACTIVITY bits @@ -331,10 +330,9 @@ struct omap_hwmod_class_sysconfig { u16 sysc_offs; u16 syss_offs; u16 sysc_flags; - struct omap_hwmod_sysc_fields *sysc_fields; - u8 srst_udelay; u8 idlemodes; u8 clockact; + struct omap_hwmod_sysc_fields *sysc_fields; }; /** diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index f9a8c5341ee9..eec98afa0f83 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -348,6 +348,7 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, sdrc_actim_ctrl_b_1, sdrc_mr_1); } +#ifdef CONFIG_PM void omap3_sram_restore_context(void) { omap_sram_ceil = omap_sram_base + omap_sram_size; @@ -357,18 +358,17 @@ void omap3_sram_restore_context(void) omap3_sram_configure_core_dpll_sz); omap_push_sram_idle(); } +#endif /* CONFIG_PM */ + +#endif /* CONFIG_ARCH_OMAP3 */ static inline int omap34xx_sram_init(void) { +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) omap3_sram_restore_context(); +#endif return 0; } -#else -static inline int omap34xx_sram_init(void) -{ - return 0; -} -#endif /* CONFIG_ARCH_OMAP3 */ static inline int am33xx_sram_init(void) { diff --git a/trunk/arch/arm/plat-samsung/Kconfig b/trunk/arch/arm/plat-samsung/Kconfig index a0ffc77da809..71553f410016 100644 --- a/trunk/arch/arm/plat-samsung/Kconfig +++ b/trunk/arch/arm/plat-samsung/Kconfig @@ -302,7 +302,6 @@ comment "Power management" config SAMSUNG_PM_DEBUG bool "S3C2410 PM Suspend debug" depends on PM - select DEBUG_LL help Say Y here if you want verbose debugging from the PM Suspend and Resume code. See diff --git a/trunk/arch/c6x/include/asm/irq.h b/trunk/arch/c6x/include/asm/irq.h index ab4577f93d96..f13b78d5e1ca 100644 --- a/trunk/arch/c6x/include/asm/irq.h +++ b/trunk/arch/c6x/include/asm/irq.h @@ -42,6 +42,10 @@ /* This number is used when no interrupt has been assigned */ #define NO_IRQ 0 +struct irq_data; +extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); +extern irq_hw_number_t virq_to_hw(unsigned int virq); + extern void __init init_pic_c64xplus(void); extern void init_IRQ(void); diff --git a/trunk/arch/c6x/kernel/irq.c b/trunk/arch/c6x/kernel/irq.c index c90fb5e82ad7..65b8ddf54b44 100644 --- a/trunk/arch/c6x/kernel/irq.c +++ b/trunk/arch/c6x/kernel/irq.c @@ -130,3 +130,16 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); return 0; } + +irq_hw_number_t irqd_to_hwirq(struct irq_data *d) +{ + return d->hwirq; +} +EXPORT_SYMBOL_GPL(irqd_to_hwirq); + +irq_hw_number_t virq_to_hw(unsigned int virq) +{ + struct irq_data *irq_data = irq_get_irq_data(virq); + return WARN_ON(!irq_data) ? 0 : irq_data->hwirq; +} +EXPORT_SYMBOL_GPL(virq_to_hw); diff --git a/trunk/arch/ia64/include/asm/cmpxchg.h b/trunk/arch/ia64/include/asm/cmpxchg.h index 4f37dbbb8640..4c96187e2049 100644 --- a/trunk/arch/ia64/include/asm/cmpxchg.h +++ b/trunk/arch/ia64/include/asm/cmpxchg.h @@ -1,147 +1 @@ -#ifndef _ASM_IA64_CMPXCHG_H -#define _ASM_IA64_CMPXCHG_H - -/* - * Compare/Exchange, forked from asm/intrinsics.h - * which was: - * - * Copyright (C) 2002-2003 Hewlett-Packard Co - * David Mosberger-Tang - */ - -#ifndef __ASSEMBLY__ - -#include -/* include compiler specific intrinsics */ -#include -#ifdef __INTEL_COMPILER -# include -#else -# include -#endif - -/* - * This function doesn't exist, so you'll get a linker error if - * something tries to do an invalid xchg(). - */ -extern void ia64_xchg_called_with_bad_pointer(void); - -#define __xchg(x, ptr, size) \ -({ \ - unsigned long __xchg_result; \ - \ - switch (size) { \ - case 1: \ - __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ - break; \ - \ - case 2: \ - __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ - break; \ - \ - case 4: \ - __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ - break; \ - \ - case 8: \ - __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ - break; \ - default: \ - ia64_xchg_called_with_bad_pointer(); \ - } \ - __xchg_result; \ -}) - -#define xchg(ptr, x) \ -((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) - -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - */ - -#define __HAVE_ARCH_CMPXCHG 1 - -/* - * This function doesn't exist, so you'll get a linker error - * if something tries to do an invalid cmpxchg(). - */ -extern long ia64_cmpxchg_called_with_bad_pointer(void); - -#define ia64_cmpxchg(sem, ptr, old, new, size) \ -({ \ - __u64 _o_, _r_; \ - \ - switch (size) { \ - case 1: \ - _o_ = (__u8) (long) (old); \ - break; \ - case 2: \ - _o_ = (__u16) (long) (old); \ - break; \ - case 4: \ - _o_ = (__u32) (long) (old); \ - break; \ - case 8: \ - _o_ = (__u64) (long) (old); \ - break; \ - default: \ - break; \ - } \ - switch (size) { \ - case 1: \ - _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ - break; \ - \ - case 2: \ - _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ - break; \ - \ - case 4: \ - _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ - break; \ - \ - case 8: \ - _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ - break; \ - \ - default: \ - _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ - break; \ - } \ - (__typeof__(old)) _r_; \ -}) - -#define cmpxchg_acq(ptr, o, n) \ - ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) -#define cmpxchg_rel(ptr, o, n) \ - ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) - -/* for compatibility with other platforms: */ -#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) -#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) - -#define cmpxchg_local cmpxchg -#define cmpxchg64_local cmpxchg64 - -#ifdef CONFIG_IA64_DEBUG_CMPXCHG -# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; -# define CMPXCHG_BUGCHECK(v) \ -do { \ - if (_cmpxchg_bugcheck_count-- <= 0) { \ - void *ip; \ - extern int printk(const char *fmt, ...); \ - ip = (void *) ia64_getreg(_IA64_REG_IP); \ - printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));\ - break; \ - } \ -} while (0) -#else /* !CONFIG_IA64_DEBUG_CMPXCHG */ -# define CMPXCHG_BUGCHECK_DECL -# define CMPXCHG_BUGCHECK(v) -#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ - -#endif /* !__ASSEMBLY__ */ - -#endif /* _ASM_IA64_CMPXCHG_H */ +#include diff --git a/trunk/arch/ia64/include/asm/futex.h b/trunk/arch/ia64/include/asm/futex.h index d2bf1fd5e44f..0ab82cc2dc8f 100644 --- a/trunk/arch/ia64/include/asm/futex.h +++ b/trunk/arch/ia64/include/asm/futex.h @@ -106,16 +106,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8"); + register unsigned long r8 __asm ("r8") = 0; unsigned long prev; __asm__ __volatile__( " mf;; \n" - " mov %0=r0 \n" - " mov ar.ccv=%4;; \n" - "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " mov ar.ccv=%3;; \n" + "[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "=r" (r8), "=r" (prev) + : "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); diff --git a/trunk/arch/ia64/include/asm/intrinsics.h b/trunk/arch/ia64/include/asm/intrinsics.h index d129e367e764..e4076b511829 100644 --- a/trunk/arch/ia64/include/asm/intrinsics.h +++ b/trunk/arch/ia64/include/asm/intrinsics.h @@ -18,7 +18,6 @@ #else # include #endif -#include #define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I) @@ -82,6 +81,119 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); #define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ +/* + * This function doesn't exist, so you'll get a linker error if + * something tries to do an invalid xchg(). + */ +extern void ia64_xchg_called_with_bad_pointer (void); + +#define __xchg(x,ptr,size) \ +({ \ + unsigned long __xchg_result; \ + \ + switch (size) { \ + case 1: \ + __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ + break; \ + \ + case 2: \ + __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ + break; \ + \ + case 4: \ + __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ + break; \ + \ + case 8: \ + __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ + break; \ + default: \ + ia64_xchg_called_with_bad_pointer(); \ + } \ + __xchg_result; \ +}) + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr)))) + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ + +#define __HAVE_ARCH_CMPXCHG 1 + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid cmpxchg(). + */ +extern long ia64_cmpxchg_called_with_bad_pointer (void); + +#define ia64_cmpxchg(sem,ptr,old,new,size) \ +({ \ + __u64 _o_, _r_; \ + \ + switch (size) { \ + case 1: _o_ = (__u8 ) (long) (old); break; \ + case 2: _o_ = (__u16) (long) (old); break; \ + case 4: _o_ = (__u32) (long) (old); break; \ + case 8: _o_ = (__u64) (long) (old); break; \ + default: break; \ + } \ + switch (size) { \ + case 1: \ + _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ + break; \ + \ + case 2: \ + _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ + break; \ + \ + case 4: \ + _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ + break; \ + \ + case 8: \ + _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ + break; \ + \ + default: \ + _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ + break; \ + } \ + (__typeof__(old)) _r_; \ +}) + +#define cmpxchg_acq(ptr, o, n) \ + ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) +#define cmpxchg_rel(ptr, o, n) \ + ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) + +/* for compatibility with other platforms: */ +#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) +#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) + +#define cmpxchg_local cmpxchg +#define cmpxchg64_local cmpxchg64 + +#ifdef CONFIG_IA64_DEBUG_CMPXCHG +# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; +# define CMPXCHG_BUGCHECK(v) \ + do { \ + if (_cmpxchg_bugcheck_count-- <= 0) { \ + void *ip; \ + extern int printk(const char *fmt, ...); \ + ip = (void *) ia64_getreg(_IA64_REG_IP); \ + printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v)); \ + break; \ + } \ + } while (0) +#else /* !CONFIG_IA64_DEBUG_CMPXCHG */ +# define CMPXCHG_BUGCHECK_DECL +# define CMPXCHG_BUGCHECK(v) +#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ + #endif #ifdef __KERNEL__ diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index f00ba025375d..9d0fd7d5bb82 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -604,6 +604,12 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) spin_unlock(&(x)->ctx_lock); } +static inline unsigned int +pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) +{ + return do_munmap(mm, addr, len); +} + static inline unsigned long pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec) { @@ -1452,9 +1458,8 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) * a PROTECT_CTX() section. */ static int -pfm_remove_smpl_mapping(void *vaddr, unsigned long size) +pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size) { - struct task_struct *task = current; int r; /* sanity checks */ @@ -1468,8 +1473,13 @@ pfm_remove_smpl_mapping(void *vaddr, unsigned long size) /* * does the actual unmapping */ - r = vm_munmap((unsigned long)vaddr, size); + down_write(&task->mm->mmap_sem); + DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size)); + + r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0); + + up_write(&task->mm->mmap_sem); if (r !=0) { printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); } @@ -1935,7 +1945,7 @@ pfm_flush(struct file *filp, fl_owner_t id) * because some VM function reenables interrupts. * */ - if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size); + if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size); return 0; } diff --git a/trunk/arch/m68k/configs/m5275evb_defconfig b/trunk/arch/m68k/configs/m5275evb_defconfig index a1230e82bb1e..33c32aeca12b 100644 --- a/trunk/arch/m68k/configs/m5275evb_defconfig +++ b/trunk/arch/m68k/configs/m5275evb_defconfig @@ -49,6 +49,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_FEC=y +CONFIG_FEC2=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_PPP=y diff --git a/trunk/arch/m68k/platform/527x/config.c b/trunk/arch/m68k/platform/527x/config.c index f91a53294c35..7ed848c3b848 100644 --- a/trunk/arch/m68k/platform/527x/config.c +++ b/trunk/arch/m68k/platform/527x/config.c @@ -74,7 +74,9 @@ static void __init m527x_fec_init(void) writew(par | 0xf00, MCF_IPSBAR + 0x100082); v = readb(MCF_IPSBAR + 0x100078); writeb(v | 0xc0, MCF_IPSBAR + 0x100078); +#endif +#ifdef CONFIG_FEC2 /* Set multi-function pins to ethernet mode for fec1 */ par = readw(MCF_IPSBAR + 0x100082); writew(par | 0xa0, MCF_IPSBAR + 0x100082); diff --git a/trunk/arch/m68k/platform/68EZ328/Makefile b/trunk/arch/m68k/platform/68EZ328/Makefile index b44d799b1115..ee97735a242c 100644 --- a/trunk/arch/m68k/platform/68EZ328/Makefile +++ b/trunk/arch/m68k/platform/68EZ328/Makefile @@ -3,3 +3,9 @@ # obj-y := config.o + +extra-y := bootlogo.rh + +$(obj)/bootlogo.rh: $(src)/bootlogo.h + perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \ + > $(obj)/bootlogo.rh diff --git a/trunk/arch/m68k/platform/68VZ328/bootlogo.h b/trunk/arch/m68k/platform/68EZ328/bootlogo.h similarity index 99% rename from trunk/arch/m68k/platform/68VZ328/bootlogo.h rename to trunk/arch/m68k/platform/68EZ328/bootlogo.h index b38e2b255142..e842bdae5839 100644 --- a/trunk/arch/m68k/platform/68VZ328/bootlogo.h +++ b/trunk/arch/m68k/platform/68EZ328/bootlogo.h @@ -1,6 +1,6 @@ #define splash_width 640 #define splash_height 480 -unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = { +static unsigned char splash_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/trunk/arch/m68k/platform/68VZ328/Makefile b/trunk/arch/m68k/platform/68VZ328/Makefile index a49d75e65489..447ffa0fd7c7 100644 --- a/trunk/arch/m68k/platform/68VZ328/Makefile +++ b/trunk/arch/m68k/platform/68VZ328/Makefile @@ -3,9 +3,14 @@ # obj-y := config.o -extra-$(DRAGEN2):= screen.h +logo-$(UCDIMM) := bootlogo.rh +logo-$(DRAGEN2) := screen.h +extra-y := $(logo-y) + +$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h + perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h -clean-files := $(obj)/screen.h +clean-files := $(obj)/screen.h $(obj)/bootlogo.rh diff --git a/trunk/arch/m68k/platform/coldfire/device.c b/trunk/arch/m68k/platform/coldfire/device.c index 7af97362b95c..fa50c48292ff 100644 --- a/trunk/arch/m68k/platform/coldfire/device.c +++ b/trunk/arch/m68k/platform/coldfire/device.c @@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = { static struct platform_device mcf_fec1 = { .name = "fec", - .id = 1, + .id = 0, .num_resources = ARRAY_SIZE(mcf_fec1_resources), .resource = mcf_fec1_resources, }; diff --git a/trunk/arch/powerpc/include/asm/irq.h b/trunk/arch/powerpc/include/asm/irq.h index e648af92ced1..cf417e510736 100644 --- a/trunk/arch/powerpc/include/asm/irq.h +++ b/trunk/arch/powerpc/include/asm/irq.h @@ -33,6 +33,8 @@ extern atomic_t ppc_n_lost_interrupts; /* Same thing, used by the generic IRQ code */ #define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS +struct irq_data; +extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); extern irq_hw_number_t virq_to_hw(unsigned int virq); /** diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index ba3aeb4bc06a..3e57a00b8cba 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -206,43 +206,40 @@ reenable_mmu: /* re-enable mmu so we can */ andi. r10,r10,MSR_EE /* Did EE change? */ beq 1f + /* Save handler and return address into the 2 unused words + * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything + * else can be recovered from the pt_regs except r3 which for + * normal interrupts has been set to pt_regs and for syscalls + * is an argument, so we temporarily use ORIG_GPR3 to save it + */ + stw r9,8(r1) + stw r11,12(r1) + stw r3,ORIG_GPR3(r1) /* * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1. * If from user mode there is only one stack frame on the stack, and * accessing CALLER_ADDR1 will cause oops. So we need create a dummy * stack frame to make trace_hardirqs_off happy. - * - * This is handy because we also need to save a bunch of GPRs, - * r3 can be different from GPR3(r1) at this point, r9 and r11 - * contains the old MSR and handler address respectively, - * r4 & r5 can contain page fault arguments that need to be passed - * along as well. r12, CCR, CTR, XER etc... are left clobbered as - * they aren't useful past this point (aren't syscall arguments), - * the rest is restored from the exception frame. */ - stwu r1,-32(r1) - stw r9,8(r1) - stw r11,12(r1) - stw r3,16(r1) - stw r4,20(r1) - stw r5,24(r1) andi. r12,r12,MSR_PR - b 11f + beq 11f + stwu r1,-16(r1) bl trace_hardirqs_off + addi r1,r1,16 b 12f + 11: bl trace_hardirqs_off 12: - lwz r5,24(r1) - lwz r4,20(r1) - lwz r3,16(r1) - lwz r11,12(r1) - lwz r9,8(r1) - addi r1,r1,32 lwz r0,GPR0(r1) + lwz r3,ORIG_GPR3(r1) + lwz r4,GPR4(r1) + lwz r5,GPR5(r1) lwz r6,GPR6(r1) lwz r7,GPR7(r1) lwz r8,GPR8(r1) + lwz r9,8(r1) + lwz r11,12(r1) 1: mtctr r11 mtlr r9 bctr /* jump to handler */ diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 5ec1b2354ca6..243dbabfe74d 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -560,6 +560,12 @@ void do_softirq(void) local_irq_restore(flags); } +irq_hw_number_t irqd_to_hwirq(struct irq_data *d) +{ + return d->hwirq; +} +EXPORT_SYMBOL_GPL(irqd_to_hwirq); + irq_hw_number_t virq_to_hw(unsigned int virq) { struct irq_data *irq_data = irq_get_irq_data(virq); diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 4937c9690090..f88698c0f332 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -1235,7 +1235,7 @@ void __ppc64_runlatch_on(void) ctrl |= CTRL_RUNLATCH; mtspr(SPRN_CTRLT, ctrl); - ti->local_flags |= _TLF_RUNLATCH; + ti->local_flags |= TLF_RUNLATCH; } /* Called with hard IRQs off */ @@ -1244,7 +1244,7 @@ void __ppc64_runlatch_off(void) struct thread_info *ti = current_thread_info(); unsigned long ctrl; - ti->local_flags &= ~_TLF_RUNLATCH; + ti->local_flags &= ~TLF_RUNLATCH; ctrl = mfspr(SPRN_CTRLF); ctrl &= ~CTRL_RUNLATCH; diff --git a/trunk/arch/powerpc/platforms/cell/axon_msi.c b/trunk/arch/powerpc/platforms/cell/axon_msi.c index d09f3e8e6867..db360fc4cf0e 100644 --- a/trunk/arch/powerpc/platforms/cell/axon_msi.c +++ b/trunk/arch/powerpc/platforms/cell/axon_msi.c @@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device) } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); - msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); + msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic); if (!msic->irq_domain) { printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", dn->full_name); diff --git a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c index f9a48af335cb..e5c3a2c6090d 100644 --- a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c @@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void) ppc_md.get_irq = beatic_get_irq; /* Allocate an irq host */ - beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL); + beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL); BUG_ON(beatic_host == NULL); irq_set_default_host(beatic_host); } diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index b4ddaa3fbb29..a81e5a88fbdf 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void) { int rc = -ENOMEM; - psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL); + psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL); if (psurge_host) psurge_secondary_virq = irq_create_direct_mapping(psurge_host); diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index 5f3b23220b8e..2a4ff86cc21f 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -753,8 +753,9 @@ void __init ps3_init_IRQ(void) unsigned cpu; struct irq_domain *host; - host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL); + host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL); irq_set_default_host(host); + irq_set_virq_count(PS3_PLUG_MAX + 1); for_each_possible_cpu(cpu) { struct ps3_private *pd = &per_cpu(ps3_private, cpu); diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 9015060919a0..2b7c0fbe578e 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -90,6 +90,7 @@ config S390 select HAVE_KERNEL_XZ select HAVE_ARCH_MUTEX_CPU_RELAX select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 + select HAVE_RCU_TABLE_FREE if SMP select ARCH_SAVE_PAGE_KEYS if HIBERNATION select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 1957a9dd256d..6cf8e26b3137 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -1,12 +1,8 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y +CONFIG_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y @@ -18,22 +14,16 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y -CONFIG_NAMESPACES=y CONFIG_BLK_DEV_INITRD=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_EXPERT=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_IBM_PARTITION=y CONFIG_DEFAULT_DEADLINE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -44,15 +34,18 @@ CONFIG_KSM=y CONFIG_BINFMT_MISC=m CONFIG_CMM=m CONFIG_HZ_100=y -CONFIG_CRASH_DUMP=y +CONFIG_KEXEC=y +CONFIG_PM=y CONFIG_HIBERNATION=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_NET_KEY=y +CONFIG_AFIUCV=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_INET_LRO is not set CONFIG_IPV6=y +CONFIG_NET_SCTPPROBE=m CONFIG_L2TP=m CONFIG_L2TP_DEBUGFS=m CONFIG_VLAN_8021Q=y @@ -91,14 +84,15 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ZFCP=y +CONFIG_ZFCP_DIF=y CONFIG_NETDEVICES=y -CONFIG_BONDING=m CONFIG_DUMMY=m +CONFIG_BONDING=m CONFIG_EQUALIZER=m CONFIG_TUN=m +CONFIG_NET_ETHERNET=y CONFIG_VIRTIO_NET=y CONFIG_RAW_DRIVER=m -CONFIG_VIRTIO_BALLOON=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -109,21 +103,27 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y CONFIG_PROVE_RCU=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y -CONFIG_RCU_TRACE=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_KPROBES_SANITY_TEST=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_LATENCYTOP=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_PAGEALLOC=y -CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE is not set # CONFIG_STRICT_DEVMEM is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m @@ -173,3 +173,4 @@ CONFIG_CRYPTO_SHA512_S390=m CONFIG_CRYPTO_DES_S390=m CONFIG_CRYPTO_AES_S390=m CONFIG_CRC7=m +CONFIG_VIRTIO_BALLOON=y diff --git a/trunk/arch/s390/include/asm/facility.h b/trunk/arch/s390/include/asm/facility.h index 2ee66a65f2d4..1e5b27edc0c9 100644 --- a/trunk/arch/s390/include/asm/facility.h +++ b/trunk/arch/s390/include/asm/facility.h @@ -38,11 +38,12 @@ static inline void stfle(u64 *stfle_fac_list, int size) unsigned long nr; preempt_disable(); + S390_lowcore.stfl_fac_list = 0; asm volatile( " .insn s,0xb2b10000,0(0)\n" /* stfl */ "0:\n" EX_TABLE(0b, 0b) - : "+m" (S390_lowcore.stfl_fac_list)); + : "=m" (S390_lowcore.stfl_fac_list)); nr = 4; /* bytes stored by stfl */ memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); if (S390_lowcore.stfl_fac_list & 0x01000000) { diff --git a/trunk/arch/s390/include/asm/pgalloc.h b/trunk/arch/s390/include/asm/pgalloc.h index 78e3041919de..8eef9b5b3cf4 100644 --- a/trunk/arch/s390/include/asm/pgalloc.h +++ b/trunk/arch/s390/include/asm/pgalloc.h @@ -22,7 +22,10 @@ void crst_table_free(struct mm_struct *, unsigned long *); unsigned long *page_table_alloc(struct mm_struct *, unsigned long); void page_table_free(struct mm_struct *, unsigned long *); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE void page_table_free_rcu(struct mmu_gather *, unsigned long *); +void __tlb_remove_table(void *_table); +#endif static inline void clear_table(unsigned long *s, unsigned long val, size_t n) { diff --git a/trunk/arch/s390/include/asm/swab.h b/trunk/arch/s390/include/asm/swab.h index a3e4ebb32090..6bdee21c077e 100644 --- a/trunk/arch/s390/include/asm/swab.h +++ b/trunk/arch/s390/include/asm/swab.h @@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x) asm volatile( #ifndef __s390x__ - " icm %0,2,%O1+1(%R1)\n" + " icm %0,2,%O+1(%R1)\n" " ic %0,%1\n" : "=&d" (result) : "Q" (*x) : "cc"); #else /* __s390x__ */ diff --git a/trunk/arch/s390/include/asm/tlb.h b/trunk/arch/s390/include/asm/tlb.h index 775a5eea8f9e..c687a2c83462 100644 --- a/trunk/arch/s390/include/asm/tlb.h +++ b/trunk/arch/s390/include/asm/tlb.h @@ -30,10 +30,14 @@ struct mmu_gather { struct mm_struct *mm; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch *batch; +#endif unsigned int fullmm; + unsigned int need_flush; }; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch { struct rcu_head rcu; unsigned int nr; @@ -45,6 +49,7 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); +#endif static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, @@ -52,20 +57,29 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, { tlb->mm = mm; tlb->fullmm = full_mm_flush; + tlb->need_flush = 0; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb->batch = NULL; +#endif if (tlb->fullmm) __tlb_flush_mm(mm); } static inline void tlb_flush_mmu(struct mmu_gather *tlb) { + if (!tlb->need_flush) + return; + tlb->need_flush = 0; + __tlb_flush_mm(tlb->mm); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); +#endif } static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - tlb_table_flush(tlb); + tlb_flush_mmu(tlb); } /* @@ -91,8 +105,10 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long address) { +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return page_table_free_rcu(tlb, (unsigned long *) pte); +#endif page_table_free(tlb->mm, (unsigned long *) pte); } @@ -109,8 +125,10 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pmd); +#endif crst_table_free(tlb->mm, (unsigned long *) pmd); #endif } @@ -128,8 +146,10 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pud); +#endif crst_table_free(tlb->mm, (unsigned long *) pud); #endif } diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index adccd908ebc7..c27a0727f930 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -474,9 +474,9 @@ ENTRY(startup_kdump) stck __LC_LAST_UPDATE_CLOCK spt 5f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13) - xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST #ifndef CONFIG_MARCH_G5 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} + xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list tm __LC_STFL_FAC_LIST,0x01 # stfle available ? jz 0f diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index 8a22c27219dd..1c2cdd59ccd0 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -118,10 +118,9 @@ asmlinkage void do_softirq(void) "a" (__do_softirq) : "0", "1", "2", "3", "4", "5", "14", "cc", "memory" ); - } else { + } else /* We are already on the async stack. */ __do_softirq(); - } } local_irq_restore(flags); @@ -193,12 +192,11 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) int index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + list_for_each_entry_rcu(p, &ext_int_hash[index], entry) if (p->code == code && p->handler == handler) { list_del_rcu(&p->entry); kfree_rcu(p, rcu); } - } spin_unlock_irqrestore(&ext_int_hash_lock, flags); return 0; } @@ -213,10 +211,9 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, old_regs = set_irq_regs(regs); irq_enter(); - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) { + if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) /* Serve timer interrupts first. */ clock_comparator_work(); - } kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; if (ext_code.code != 0x1004) __get_cpu_var(s390_idle).nohz_delay = 1; diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index cb019f429e88..46405086479c 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu) err = lcctl(cpuhw->state); if (err) { pr_err("Enabling the performance measuring unit " - "failed with rc=%x\n", err); + "failed with rc=%lx\n", err); return; } @@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu) err = lcctl(inactive); if (err) { pr_err("Disabling the performance measuring unit " - "failed with rc=%x\n", err); + "failed with rc=%lx\n", err); return; } diff --git a/trunk/arch/s390/mm/maccess.c b/trunk/arch/s390/mm/maccess.c index e1335dc2b1b7..7bb15fcca75e 100644 --- a/trunk/arch/s390/mm/maccess.c +++ b/trunk/arch/s390/mm/maccess.c @@ -61,14 +61,21 @@ long probe_kernel_write(void *dst, const void *src, size_t size) return copied < 0 ? -EFAULT : 0; } -static int __memcpy_real(void *dest, void *src, size_t count) +/* + * Copy memory in real mode (kernel to kernel) + */ +int memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; register unsigned long _len1 asm("3") = (unsigned long) count; register unsigned long _src asm("4") = (unsigned long) src; register unsigned long _len2 asm("5") = (unsigned long) count; + unsigned long flags; int rc = -EFAULT; + if (!count) + return 0; + flags = __arch_local_irq_stnsm(0xf8UL); asm volatile ( "0: mvcle %1,%2,0x0\n" "1: jo 0b\n" @@ -79,23 +86,7 @@ static int __memcpy_real(void *dest, void *src, size_t count) "+d" (_len2), "=m" (*((long *) dest)) : "m" (*((long *) src)) : "cc", "memory"); - return rc; -} - -/* - * Copy memory in real mode (kernel to kernel) - */ -int memcpy_real(void *dest, void *src, size_t count) -{ - unsigned long flags; - int rc; - - if (!count) - return 0; - local_irq_save(flags); - __arch_local_irq_stnsm(0xfbUL); - rc = __memcpy_real(dest, src, count); - local_irq_restore(flags); + arch_local_irq_restore(flags); return rc; } diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 6e765bf00670..373adf69b01c 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -678,6 +678,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) } } +#ifdef CONFIG_HAVE_RCU_TABLE_FREE + static void __page_table_free_rcu(void *table, unsigned bit) { struct page *page; @@ -731,66 +733,7 @@ void __tlb_remove_table(void *_table) free_pages((unsigned long) table, ALLOC_ORDER); } -static void tlb_remove_table_smp_sync(void *arg) -{ - /* Simply deliver the interrupt */ -} - -static void tlb_remove_table_one(void *table) -{ - /* - * This isn't an RCU grace period and hence the page-tables cannot be - * assumed to be actually RCU-freed. - * - * It is however sufficient for software page-table walkers that rely - * on IRQ disabling. See the comment near struct mmu_table_batch. - */ - smp_call_function(tlb_remove_table_smp_sync, NULL, 1); - __tlb_remove_table(table); -} - -static void tlb_remove_table_rcu(struct rcu_head *head) -{ - struct mmu_table_batch *batch; - int i; - - batch = container_of(head, struct mmu_table_batch, rcu); - - for (i = 0; i < batch->nr; i++) - __tlb_remove_table(batch->tables[i]); - - free_page((unsigned long)batch); -} - -void tlb_table_flush(struct mmu_gather *tlb) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch) { - __tlb_flush_mm(tlb->mm); - call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); - *batch = NULL; - } -} - -void tlb_remove_table(struct mmu_gather *tlb, void *table) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch == NULL) { - *batch = (struct mmu_table_batch *) - __get_free_page(GFP_NOWAIT | __GFP_NOWARN); - if (*batch == NULL) { - __tlb_flush_mm(tlb->mm); - tlb_remove_table_one(table); - return; - } - (*batch)->nr = 0; - } - (*batch)->tables[(*batch)->nr++] = table; - if ((*batch)->nr == MAX_TABLE_BATCH) - tlb_table_flush(tlb); -} +#endif /* * switch on pgstes for its userspace process (for kvm) diff --git a/trunk/arch/sparc/kernel/ds.c b/trunk/arch/sparc/kernel/ds.c index b93c2c9ccb1d..fea13c7b1aee 100644 --- a/trunk/arch/sparc/kernel/ds.c +++ b/trunk/arch/sparc/kernel/ds.c @@ -1264,4 +1264,4 @@ static int __init ds_init(void) return vio_register_driver(&ds_driver); } -fs_initcall(ds_init); +subsys_initcall(ds_init); diff --git a/trunk/arch/sparc/kernel/leon_pci.c b/trunk/arch/sparc/kernel/leon_pci.c index 19f56058742b..aba6b958b2a5 100644 --- a/trunk/arch/sparc/kernel/leon_pci.c +++ b/trunk/arch/sparc/kernel/leon_pci.c @@ -45,6 +45,7 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) void __devinit pcibios_fixup_bus(struct pci_bus *pbus) { + struct leon_pci_info *info = pbus->sysdata; struct pci_dev *dev; int i, has_io, has_mem; u16 cmd; @@ -110,6 +111,18 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pci_enable_resources(dev, mask); } +struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) +{ + /* + * Currently the OpenBoot nodes are not connected with the PCI device, + * this is because the LEON PROM does not create PCI nodes. Eventually + * this will change and the same approach as pcic.c can be used to + * match PROM nodes with pci devices. + */ + return NULL; +} +EXPORT_SYMBOL(pci_device_to_OF_node); + void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) { #ifdef CONFIG_PCI_DEBUG diff --git a/trunk/arch/sparc/kernel/leon_smp.c b/trunk/arch/sparc/kernel/leon_smp.c index 160cac9c4036..1210fde18740 100644 --- a/trunk/arch/sparc/kernel/leon_smp.c +++ b/trunk/arch/sparc/kernel/leon_smp.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -79,8 +78,6 @@ void __cpuinit leon_callin(void) local_flush_tlb_all(); leon_configure_cache_smp(); - notify_cpu_starting(cpuid); - /* Get our local ticker going. */ smp_setup_percpu_timer(); diff --git a/trunk/arch/sparc/kernel/rtrap_64.S b/trunk/arch/sparc/kernel/rtrap_64.S index 9171fc238def..77f1b95e0806 100644 --- a/trunk/arch/sparc/kernel/rtrap_64.S +++ b/trunk/arch/sparc/kernel/rtrap_64.S @@ -20,6 +20,11 @@ .text .align 32 +__handle_softirq: + call do_softirq + nop + ba,a,pt %xcc, __handle_softirq_continue + nop __handle_preemption: call schedule wrpr %g0, RTRAP_PSTATE, %pstate @@ -84,7 +89,9 @@ rtrap: cmp %l1, 0 /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ + bne,pn %icc, __handle_softirq ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 +__handle_softirq_continue: rtrap_xcall: sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 3ee51f189a55..232df9949530 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -566,10 +566,15 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) { + long ret; + if (invalid_64bit_range(addr, len)) return -EINVAL; - return vm_munmap(addr, len); + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, addr, len); + up_write(¤t->mm->mmap_sem); + return ret; } extern unsigned long do_mremap(unsigned long addr, diff --git a/trunk/arch/sparc/mm/fault_32.c b/trunk/arch/sparc/mm/fault_32.c index df3155a17991..7705c6731e28 100644 --- a/trunk/arch/sparc/mm/fault_32.c +++ b/trunk/arch/sparc/mm/fault_32.c @@ -225,8 +225,6 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long g2; int from_user = !(regs->psr & PSR_PS); int fault, code; - unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - (write ? FAULT_FLAG_WRITE : 0)); if(text_fault) address = regs->pc; @@ -253,7 +251,6 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); -retry: down_read(&mm->mmap_sem); /* @@ -292,11 +289,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, * make sure we exit gracefully rather than endlessly redo * the fault. */ - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -304,29 +297,13 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, goto do_sigbus; BUG(); } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) { - current->maj_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, - 1, regs, address); - } else { - current->min_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, - 1, regs, address); - } - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } + if (fault & VM_FAULT_MAJOR) { + current->maj_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); + } else { + current->min_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } - up_read(&mm->mmap_sem); return; diff --git a/trunk/arch/sparc/mm/fault_64.c b/trunk/arch/sparc/mm/fault_64.c index 1fe0429b6314..504c0622f729 100644 --- a/trunk/arch/sparc/mm/fault_64.c +++ b/trunk/arch/sparc/mm/fault_64.c @@ -279,7 +279,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) unsigned int insn = 0; int si_code, fault_code, fault; unsigned long address, mm_rss; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; fault_code = get_thread_fault_code(); @@ -334,8 +333,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) insn = get_fault_insn(regs, insn); goto handle_kernel_fault; } - -retry: down_read(&mm->mmap_sem); } @@ -426,12 +423,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) goto bad_area; } - flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0); - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -439,27 +431,12 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) goto do_sigbus; BUG(); } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) { - current->maj_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, - 1, regs, address); - } else { - current->min_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, - 1, regs, address); - } - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } + if (fault & VM_FAULT_MAJOR) { + current->maj_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); + } else { + current->min_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } up_read(&mm->mmap_sem); diff --git a/trunk/arch/tile/kernel/proc.c b/trunk/arch/tile/kernel/proc.c index 446a7f52cc11..7a9327046404 100644 --- a/trunk/arch/tile/kernel/proc.c +++ b/trunk/arch/tile/kernel/proc.c @@ -146,6 +146,7 @@ static ctl_table unaligned_table[] = { }, {} }; +#endif static struct ctl_path tile_path[] = { { .procname = "tile" }, @@ -154,9 +155,10 @@ static struct ctl_path tile_path[] = { static int __init proc_sys_tile_init(void) { +#ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ register_sysctl_paths(tile_path, unaligned_table); +#endif return 0; } arch_initcall(proc_sys_tile_init); -#endif diff --git a/trunk/arch/tile/kernel/single_step.c b/trunk/arch/tile/kernel/single_step.c index 89529c9f0605..9efbc1391b3c 100644 --- a/trunk/arch/tile/kernel/single_step.c +++ b/trunk/arch/tile/kernel/single_step.c @@ -346,10 +346,12 @@ void single_step_once(struct pt_regs *regs) } /* allocate a cache line of writable, executable memory */ - buffer = (void __user *) vm_mmap(NULL, 0, 64, + down_write(¤t->mm->mmap_sem); + buffer = (void __user *) do_mmap(NULL, 0, 64, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void __force *)buffer)) { kfree(state); diff --git a/trunk/arch/tile/kernel/smpboot.c b/trunk/arch/tile/kernel/smpboot.c index 172aef7d3159..b949edcec200 100644 --- a/trunk/arch/tile/kernel/smpboot.c +++ b/trunk/arch/tile/kernel/smpboot.c @@ -196,8 +196,6 @@ void __cpuinit online_secondary(void) /* This must be done before setting cpu_online_mask */ wmb(); - notify_cpu_starting(smp_processor_id()); - /* * We need to hold call_lock, so there is no inconsistency * between the time smp_call_function() determines number of diff --git a/trunk/arch/um/drivers/cow.h b/trunk/arch/um/drivers/cow.h index 6673508f3426..dc36b222100b 100644 --- a/trunk/arch/um/drivers/cow.h +++ b/trunk/arch/um/drivers/cow.h @@ -3,6 +3,41 @@ #include +#if defined(__KERNEL__) + +# include + +# if defined(__BIG_ENDIAN) +# define ntohll(x) (x) +# define htonll(x) (x) +# elif defined(__LITTLE_ENDIAN) +# define ntohll(x) be64_to_cpu(x) +# define htonll(x) cpu_to_be64(x) +# else +# error "Could not determine byte order" +# endif + +#else +/* For the definition of ntohl, htonl and __BYTE_ORDER */ +#include +#include +#if defined(__BYTE_ORDER) + +# if __BYTE_ORDER == __BIG_ENDIAN +# define ntohll(x) (x) +# define htonll(x) (x) +# elif __BYTE_ORDER == __LITTLE_ENDIAN +# define ntohll(x) bswap_64(x) +# define htonll(x) bswap_64(x) +# else +# error "Could not determine byte order: __BYTE_ORDER uncorrectly defined" +# endif + +#else /* ! defined(__BYTE_ORDER) */ +# error "Could not determine byte order: __BYTE_ORDER not defined" +#endif +#endif /* ! defined(__KERNEL__) */ + extern int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, int alignment, int *bitmap_offset_out, unsigned long *bitmap_len_out, int *data_offset_out); diff --git a/trunk/arch/um/drivers/cow_user.c b/trunk/arch/um/drivers/cow_user.c index 0ee9cc6cc4c7..9cbb426c0b91 100644 --- a/trunk/arch/um/drivers/cow_user.c +++ b/trunk/arch/um/drivers/cow_user.c @@ -8,10 +8,11 @@ * that. */ #include +#include #include #include #include -#include +#include #include "cow.h" #include "cow_sys.h" @@ -213,8 +214,8 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, "header\n"); goto out; } - header->magic = htobe32(COW_MAGIC); - header->version = htobe32(COW_VERSION); + header->magic = htonl(COW_MAGIC); + header->version = htonl(COW_VERSION); err = -EINVAL; if (strlen(backing_file) > sizeof(header->backing_file) - 1) { @@ -245,10 +246,10 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, goto out_free; } - header->mtime = htobe32(modtime); - header->size = htobe64(*size); - header->sectorsize = htobe32(sectorsize); - header->alignment = htobe32(alignment); + header->mtime = htonl(modtime); + header->size = htonll(*size); + header->sectorsize = htonl(sectorsize); + header->alignment = htonl(alignment); header->cow_format = COW_BITMAP; err = cow_write_file(fd, header, sizeof(*header)); @@ -300,8 +301,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, magic = header->v1.magic; if (magic == COW_MAGIC) version = header->v1.version; - else if (magic == be32toh(COW_MAGIC)) - version = be32toh(header->v1.version); + else if (magic == ntohl(COW_MAGIC)) + version = ntohl(header->v1.version); /* No error printed because the non-COW case comes through here */ else goto out; @@ -326,9 +327,9 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, "header\n"); goto out; } - *mtime_out = be32toh(header->v2.mtime); - *size_out = be64toh(header->v2.size); - *sectorsize_out = be32toh(header->v2.sectorsize); + *mtime_out = ntohl(header->v2.mtime); + *size_out = ntohll(header->v2.size); + *sectorsize_out = ntohl(header->v2.sectorsize); *bitmap_offset_out = sizeof(header->v2); *align_out = *sectorsize_out; file = header->v2.backing_file; @@ -340,10 +341,10 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, "header\n"); goto out; } - *mtime_out = be32toh(header->v3.mtime); - *size_out = be64toh(header->v3.size); - *sectorsize_out = be32toh(header->v3.sectorsize); - *align_out = be32toh(header->v3.alignment); + *mtime_out = ntohl(header->v3.mtime); + *size_out = ntohll(header->v3.size); + *sectorsize_out = ntohl(header->v3.sectorsize); + *align_out = ntohl(header->v3.alignment); if (*align_out == 0) { cow_printf("read_cow_header - invalid COW header, " "align == 0\n"); @@ -365,16 +366,16 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, * this was used until Dec2005 - 64bits are needed to represent * 2038+. I.e. we can safely do this truncating cast. * - * Additionally, we must use be32toh() instead of be64toh(), since + * Additionally, we must use ntohl() instead of ntohll(), since * the program used to use the former (tested - I got mtime * mismatch "0 vs whatever"). * * Ever heard about bug-to-bug-compatibility ? ;-) */ - *mtime_out = (time32_t) be32toh(header->v3_b.mtime); + *mtime_out = (time32_t) ntohl(header->v3_b.mtime); - *size_out = be64toh(header->v3_b.size); - *sectorsize_out = be32toh(header->v3_b.sectorsize); - *align_out = be32toh(header->v3_b.alignment); + *size_out = ntohll(header->v3_b.size); + *sectorsize_out = ntohl(header->v3_b.sectorsize); + *align_out = ntohl(header->v3_b.alignment); if (*align_out == 0) { cow_printf("read_cow_header - invalid COW header, " "align == 0\n"); diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 43b39d61b538..e672bd6d43e3 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "init.h" #include "irq_kern.h" diff --git a/trunk/arch/um/include/asm/Kbuild b/trunk/arch/um/include/asm/Kbuild index fff24352255d..8419f5cf2ac7 100644 --- a/trunk/arch/um/include/asm/Kbuild +++ b/trunk/arch/um/include/asm/Kbuild @@ -1,4 +1,3 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h -generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h -generic-y += switch_to.h +generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index 65a1c3d690ea..492bc4c1b62b 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -3,10 +3,9 @@ # Licensed under the GPL # -CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ - -DELF_ARCH=$(LDS_ELF_ARCH) \ - -DELF_FORMAT=$(LDS_ELF_FORMAT) \ - $(LDS_EXTRA) +CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ + -DELF_ARCH=$(LDS_ELF_ARCH) \ + -DELF_FORMAT=$(LDS_ELF_FORMAT) extra-y := vmlinux.lds clean-files := diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 2b73dedb44ca..f386d04a84a5 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -88,8 +88,11 @@ static inline void set_current(struct task_struct *task) extern void arch_switch_to(struct task_struct *to); -void *__switch_to(struct task_struct *from, struct task_struct *to) +void *_switch_to(void *prev, void *next, void *last) { + struct task_struct *from = prev; + struct task_struct *to = next; + to->thread.prev_sched = from; set_current(to); @@ -108,6 +111,7 @@ void *__switch_to(struct task_struct *from, struct task_struct *to) } while (current->thread.saved_task); return current->thread.prev_sched; + } void interrupt_end(void) diff --git a/trunk/arch/um/kernel/skas/mmu.c b/trunk/arch/um/kernel/skas/mmu.c index 0a49ef0c2bf4..4947b319f53a 100644 --- a/trunk/arch/um/kernel/skas/mmu.c +++ b/trunk/arch/um/kernel/skas/mmu.c @@ -103,6 +103,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) void uml_setup_stubs(struct mm_struct *mm) { + struct page **pages; int err, ret; if (!skas_needs_stub) diff --git a/trunk/arch/x86/Makefile.um b/trunk/arch/x86/Makefile.um index 36b62bc52638..4be406abeefd 100644 --- a/trunk/arch/x86/Makefile.um +++ b/trunk/arch/x86/Makefile.um @@ -14,9 +14,6 @@ LINK-y += $(call cc-option,-m32) export LDFLAGS -LDS_EXTRA := -Ui386 -export LDS_EXTRA - # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. include $(srctree)/arch/x86/Makefile_32.cpu diff --git a/trunk/arch/x86/ia32/ia32_aout.c b/trunk/arch/x86/ia32/ia32_aout.c index 4824fb45560f..d511d951a052 100644 --- a/trunk/arch/x86/ia32/ia32_aout.c +++ b/trunk/arch/x86/ia32/ia32_aout.c @@ -119,7 +119,9 @@ static void set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end <= start) return; - vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); } #ifdef CORE_DUMP @@ -330,7 +332,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) pos = 32; map_size = ex.a_text+ex.a_data; - error = vm_brk(text_addr & PAGE_MASK, map_size); + down_write(¤t->mm->mmap_sem); + error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); @@ -369,7 +373,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { loff_t pos = fd_offset; - vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + down_write(¤t->mm->mmap_sem); + do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -379,22 +385,26 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto beyond_if; } - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -466,7 +476,9 @@ static int load_aout_library(struct file *file) error_time = jiffies; } #endif - vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + down_write(¤t->mm->mmap_sem); + do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -478,10 +490,12 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, N_TXTOFF(ex)); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; @@ -489,7 +503,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = vm_brk(start_addr + len, bss - len); + down_write(¤t->mm->mmap_sem); + error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out; diff --git a/trunk/arch/x86/include/asm/cmpxchg.h b/trunk/arch/x86/include/asm/cmpxchg.h index 99480e55973d..b3b733262909 100644 --- a/trunk/arch/x86/include/asm/cmpxchg.h +++ b/trunk/arch/x86/include/asm/cmpxchg.h @@ -43,7 +43,7 @@ extern void __add_wrong_size(void) switch (sizeof(*(ptr))) { \ case __X86_CASE_B: \ asm volatile (lock #op "b %b0, %1\n" \ - : "+q" (__ret), "+m" (*(ptr)) \ + : "+r" (__ret), "+m" (*(ptr)) \ : : "memory", "cc"); \ break; \ case __X86_CASE_W: \ @@ -173,7 +173,7 @@ extern void __add_wrong_size(void) switch (sizeof(*(ptr))) { \ case __X86_CASE_B: \ asm volatile (lock "addb %b1, %0\n" \ - : "+m" (*(ptr)) : "qi" (inc) \ + : "+m" (*(ptr)) : "ri" (inc) \ : "memory", "cc"); \ break; \ case __X86_CASE_W: \ diff --git a/trunk/arch/x86/include/asm/uaccess.h b/trunk/arch/x86/include/asm/uaccess.h index e0544597cfe7..8be5f54d9360 100644 --- a/trunk/arch/x86/include/asm/uaccess.h +++ b/trunk/arch/x86/include/asm/uaccess.h @@ -557,8 +557,6 @@ struct __large_struct { unsigned long buf[100]; }; extern unsigned long copy_from_user_nmi(void *to, const void __user *from, unsigned long n); -extern __must_check long -strncpy_from_user(char *dst, const char __user *src, long count); /* * movsl can be slow when source and dest are not both 8-byte aligned diff --git a/trunk/arch/x86/include/asm/uaccess_32.h b/trunk/arch/x86/include/asm/uaccess_32.h index 8084bc73b18c..566e803cc602 100644 --- a/trunk/arch/x86/include/asm/uaccess_32.h +++ b/trunk/arch/x86/include/asm/uaccess_32.h @@ -213,6 +213,11 @@ static inline unsigned long __must_check copy_from_user(void *to, return n; } +long __must_check strncpy_from_user(char *dst, const char __user *src, + long count); +long __must_check __strncpy_from_user(char *dst, + const char __user *src, long count); + /** * strlen_user: - Get the size of a string in user space. * @str: The string to measure. diff --git a/trunk/arch/x86/include/asm/uaccess_64.h b/trunk/arch/x86/include/asm/uaccess_64.h index fcd4b6f3ef02..1c66d30971ad 100644 --- a/trunk/arch/x86/include/asm/uaccess_64.h +++ b/trunk/arch/x86/include/asm/uaccess_64.h @@ -208,6 +208,10 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) } } +__must_check long +strncpy_from_user(char *dst, const char __user *src, long count); +__must_check long +__strncpy_from_user(char *dst, const char __user *src, long count); __must_check long strnlen_user(const char __user *str, long n); __must_check long __strnlen_user(const char __user *str, long n); __must_check long strlen_user(const char __user *str); diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c index 7515cf0e1805..f386dc49f988 100644 --- a/trunk/arch/x86/kernel/vsyscall_64.c +++ b/trunk/arch/x86/kernel/vsyscall_64.c @@ -216,9 +216,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) current_thread_info()->sig_on_uaccess_error = 1; /* - * NULL is a valid user pointer (in the access_ok sense) on 32-bit and + * 0 is a valid user pointer (in the access_ok sense) on 32-bit and * 64-bit, so we don't need to special-case it here. For all the - * vsyscalls, NULL means "don't write anything" not "write it at + * vsyscalls, 0 means "don't write anything" not "write it at * address 0". */ ret = -EFAULT; @@ -247,7 +247,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) ret = sys_getcpu((unsigned __user *)regs->di, (unsigned __user *)regs->si, - NULL); + 0); break; } diff --git a/trunk/arch/x86/kvm/pmu.c b/trunk/arch/x86/kvm/pmu.c index 2e88438ffd83..173df38dbda5 100644 --- a/trunk/arch/x86/kvm/pmu.c +++ b/trunk/arch/x86/kvm/pmu.c @@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1); if (pmu->version == 1) { - pmu->nr_arch_fixed_counters = 0; - } else { - pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), - X86_PMC_MAX_FIXED); - pmu->counter_bitmask[KVM_PMC_FIXED] = - ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1; + return; } - pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | - (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); - pmu->global_ctrl_mask = ~pmu->global_ctrl; + pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), + X86_PMC_MAX_FIXED); + pmu->counter_bitmask[KVM_PMC_FIXED] = + ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1) + | (((1ull << pmu->nr_arch_fixed_counters) - 1) + << X86_PMC_IDX_FIXED)); } void kvm_pmu_init(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 4ff0ab9bc3c8..ad85adfef843 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -2210,12 +2210,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) msr = find_msr_entry(vmx, msr_index); if (msr) { msr->data = data; - if (msr - vmx->guest_msrs < vmx->save_nmsrs) { - preempt_disable(); + if (msr - vmx->guest_msrs < vmx->save_nmsrs) kvm_set_shared_msr(msr->index, msr->data, msr->mask); - preempt_enable(); - } break; } ret = kvm_set_msr_common(vcpu, msr_index, data); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 91a5e989abcf..4044ce0bf7c1 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -6336,11 +6336,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, if (npages && !old.rmap) { unsigned long userspace_addr; - userspace_addr = vm_mmap(NULL, 0, + down_write(¤t->mm->mmap_sem); + userspace_addr = do_mmap(NULL, 0, npages * PAGE_SIZE, PROT_READ | PROT_WRITE, map_flags, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void *)userspace_addr)) return PTR_ERR((void *)userspace_addr); @@ -6364,8 +6366,10 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (!user_alloc && !old.user_alloc && old.rmap && !npages) { int ret; - ret = vm_munmap(old.userspace_addr, + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, old.userspace_addr, old.npages * PAGE_SIZE); + up_write(¤t->mm->mmap_sem); if (ret < 0) printk(KERN_WARNING "kvm_vm_ioctl_set_memory_region: " diff --git a/trunk/arch/x86/lib/insn.c b/trunk/arch/x86/lib/insn.c index b1e6c4b2e8eb..25feb1ae71c5 100644 --- a/trunk/arch/x86/lib/insn.c +++ b/trunk/arch/x86/lib/insn.c @@ -379,8 +379,8 @@ void insn_get_displacement(struct insn *insn) return; } -/* Decode moffset16/32/64. Return 0 if failed */ -static int __get_moffset(struct insn *insn) +/* Decode moffset16/32/64 */ +static void __get_moffset(struct insn *insn) { switch (insn->addr_bytes) { case 2: @@ -397,19 +397,15 @@ static int __get_moffset(struct insn *insn) insn->moffset2.value = get_next(int, insn); insn->moffset2.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } insn->moffset1.got = insn->moffset2.got = 1; - return 1; - err_out: - return 0; + return; } -/* Decode imm v32(Iz). Return 0 if failed */ -static int __get_immv32(struct insn *insn) +/* Decode imm v32(Iz) */ +static void __get_immv32(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -421,18 +417,14 @@ static int __get_immv32(struct insn *insn) insn->immediate.value = get_next(int, insn); insn->immediate.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } - return 1; - err_out: - return 0; + return; } -/* Decode imm v64(Iv/Ov), Return 0 if failed */ -static int __get_immv(struct insn *insn) +/* Decode imm v64(Iv/Ov) */ +static void __get_immv(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -449,18 +441,15 @@ static int __get_immv(struct insn *insn) insn->immediate2.value = get_next(int, insn); insn->immediate2.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } insn->immediate1.got = insn->immediate2.got = 1; - return 1; err_out: - return 0; + return; } /* Decode ptr16:16/32(Ap) */ -static int __get_immptr(struct insn *insn) +static void __get_immptr(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -473,17 +462,14 @@ static int __get_immptr(struct insn *insn) break; case 8: /* ptr16:64 is not exist (no segment) */ - return 0; - default: /* opnd_bytes must be modified manually */ - goto err_out; + return; } insn->immediate2.value = get_next(unsigned short, insn); insn->immediate2.nbytes = 2; insn->immediate1.got = insn->immediate2.got = 1; - return 1; err_out: - return 0; + return; } /** @@ -503,8 +489,7 @@ void insn_get_immediate(struct insn *insn) insn_get_displacement(insn); if (inat_has_moffset(insn->attr)) { - if (!__get_moffset(insn)) - goto err_out; + __get_moffset(insn); goto done; } @@ -532,20 +517,16 @@ void insn_get_immediate(struct insn *insn) insn->immediate2.nbytes = 4; break; case INAT_IMM_PTR: - if (!__get_immptr(insn)) - goto err_out; + __get_immptr(insn); break; case INAT_IMM_VWORD32: - if (!__get_immv32(insn)) - goto err_out; + __get_immv32(insn); break; case INAT_IMM_VWORD: - if (!__get_immv(insn)) - goto err_out; + __get_immv(insn); break; default: - /* Here, insn must have an immediate, but failed */ - goto err_out; + break; } if (inat_has_second_immediate(insn->attr)) { insn->immediate2.value = get_next(char, insn); diff --git a/trunk/arch/x86/lib/usercopy.c b/trunk/arch/x86/lib/usercopy.c index d6ae30bbd7bb..97be9cb54483 100644 --- a/trunk/arch/x86/lib/usercopy.c +++ b/trunk/arch/x86/lib/usercopy.c @@ -7,8 +7,6 @@ #include #include -#include - /* * best effort, GUP based copy_from_user() that is NMI-safe */ @@ -43,104 +41,3 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) return len; } EXPORT_SYMBOL_GPL(copy_from_user_nmi); - -static inline unsigned long count_bytes(unsigned long mask) -{ - mask = (mask - 1) & ~mask; - mask >>= 7; - return count_masked_bytes(mask); -} - -/* - * Do a strncpy, return length of string without final '\0'. - * 'count' is the user-supplied count (return 'count' if we - * hit it), 'max' is the address space maximum (and we return - * -EFAULT if we hit it). - */ -static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) -{ - long res = 0; - - /* - * Truncate 'max' to the user-specified limit, so that - * we only have one limit we need to check in the loop - */ - if (max > count) - max = count; - - while (max >= sizeof(unsigned long)) { - unsigned long c; - - /* Fall back to byte-at-a-time if we get a page fault */ - if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) - break; - /* This can write a few bytes past the NUL character, but that's ok */ - *(unsigned long *)(dst+res) = c; - c = has_zero(c); - if (c) - return res + count_bytes(c); - res += sizeof(unsigned long); - max -= sizeof(unsigned long); - } - - while (max) { - char c; - - if (unlikely(__get_user(c,src+res))) - return -EFAULT; - dst[res] = c; - if (!c) - return res; - res++; - max--; - } - - /* - * Uhhuh. We hit 'max'. But was that the user-specified maximum - * too? If so, that's ok - we got as much as the user asked for. - */ - if (res >= count) - return res; - - /* - * Nope: we hit the address space limit, and we still had more - * characters the caller would have wanted. That's an EFAULT. - */ - return -EFAULT; -} - -/** - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ -long -strncpy_from_user(char *dst, const char __user *src, long count) -{ - unsigned long max_addr, src_addr; - - if (unlikely(count <= 0)) - return 0; - - max_addr = current_thread_info()->addr_limit.seg; - src_addr = (unsigned long)src; - if (likely(src_addr < max_addr)) { - unsigned long max = max_addr - src_addr; - return do_strncpy_from_user(dst, src, count, max); - } - return -EFAULT; -} -EXPORT_SYMBOL(strncpy_from_user); diff --git a/trunk/arch/x86/lib/usercopy_32.c b/trunk/arch/x86/lib/usercopy_32.c index ef2a6a5d78e3..d9b094ca7aaa 100644 --- a/trunk/arch/x86/lib/usercopy_32.c +++ b/trunk/arch/x86/lib/usercopy_32.c @@ -32,6 +32,93 @@ static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned lon #define movsl_is_ok(a1, a2, n) \ __movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n)) +/* + * Copy a null terminated string from userspace. + */ + +#define __do_strncpy_from_user(dst, src, count, res) \ +do { \ + int __d0, __d1, __d2; \ + might_fault(); \ + __asm__ __volatile__( \ + " testl %1,%1\n" \ + " jz 2f\n" \ + "0: lodsb\n" \ + " stosb\n" \ + " testb %%al,%%al\n" \ + " jz 1f\n" \ + " decl %1\n" \ + " jnz 0b\n" \ + "1: subl %1,%0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %5,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(0b,3b) \ + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ + "=&D" (__d2) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "memory"); \ +} while (0) + +/** + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * Caller must check the specified block with access_ok() before calling + * this function. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ +long +__strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res; + __do_strncpy_from_user(dst, src, count, res); + return res; +} +EXPORT_SYMBOL(__strncpy_from_user); + +/** + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ +long +strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + __do_strncpy_from_user(dst, src, count, res); + return res; +} +EXPORT_SYMBOL(strncpy_from_user); + /* * Zero Userspace */ diff --git a/trunk/arch/x86/lib/usercopy_64.c b/trunk/arch/x86/lib/usercopy_64.c index 0d0326f388c0..b7c2849ffb66 100644 --- a/trunk/arch/x86/lib/usercopy_64.c +++ b/trunk/arch/x86/lib/usercopy_64.c @@ -8,6 +8,55 @@ #include #include +/* + * Copy a null terminated string from userspace. + */ + +#define __do_strncpy_from_user(dst,src,count,res) \ +do { \ + long __d0, __d1, __d2; \ + might_fault(); \ + __asm__ __volatile__( \ + " testq %1,%1\n" \ + " jz 2f\n" \ + "0: lodsb\n" \ + " stosb\n" \ + " testb %%al,%%al\n" \ + " jz 1f\n" \ + " decq %1\n" \ + " jnz 0b\n" \ + "1: subq %1,%0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movq %5,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(0b,3b) \ + : "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ + "=&D" (__d2) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "memory"); \ +} while (0) + +long +__strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res; + __do_strncpy_from_user(dst, src, count, res); + return res; +} +EXPORT_SYMBOL(__strncpy_from_user); + +long +strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + return __strncpy_from_user(dst, src, count); + return res; +} +EXPORT_SYMBOL(strncpy_from_user); + /* * Zero Userspace */ diff --git a/trunk/arch/x86/um/asm/barrier.h b/trunk/arch/x86/um/asm/barrier.h deleted file mode 100644 index 7d01b8c56c00..000000000000 --- a/trunk/arch/x86/um/asm/barrier.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _ASM_UM_BARRIER_H_ -#define _ASM_UM_BARRIER_H_ - -#include -#include -#include -#include -#include - -#include -#include - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 - -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) - -#else /* CONFIG_X86_32 */ - -#define mb() asm volatile("mfence" : : : "memory") -#define rmb() asm volatile("lfence" : : : "memory") -#define wmb() asm volatile("sfence" : : : "memory") - -#endif /* CONFIG_X86_32 */ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP - -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -#define smp_rmb() rmb() -#else /* CONFIG_X86_PPRO_FENCE */ -#define smp_rmb() barrier() -#endif /* CONFIG_X86_PPRO_FENCE */ - -#ifdef CONFIG_X86_OOSTORE -#define smp_wmb() wmb() -#else /* CONFIG_X86_OOSTORE */ -#define smp_wmb() barrier() -#endif /* CONFIG_X86_OOSTORE */ - -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) - -#else /* CONFIG_SMP */ - -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) - -#endif /* CONFIG_SMP */ - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/trunk/arch/x86/um/asm/system.h b/trunk/arch/x86/um/asm/system.h new file mode 100644 index 000000000000..a459fd9b7598 --- /dev/null +++ b/trunk/arch/x86/um/asm/system.h @@ -0,0 +1,135 @@ +#ifndef _ASM_X86_SYSTEM_H_ +#define _ASM_X86_SYSTEM_H_ + +#include +#include +#include +#include +#include + +#include +#include + +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + +extern unsigned long arch_align_stack(unsigned long sp); + +void default_idle(void); + +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + */ +#ifdef CONFIG_X86_32 +/* + * Some non-Intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ +#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) +#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) +#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) +#else +#define mb() asm volatile("mfence":::"memory") +#define rmb() asm volatile("lfence":::"memory") +#define wmb() asm volatile("sfence" ::: "memory") +#endif + +/** + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like this where there are no data dependencies. + **/ + +#define read_barrier_depends() do { } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#ifdef CONFIG_X86_PPRO_FENCE +# define smp_rmb() rmb() +#else +# define smp_rmb() barrier() +#endif +#ifdef CONFIG_X86_OOSTORE +# define smp_wmb() wmb() +#else +# define smp_wmb() barrier() +#endif +#define smp_read_barrier_depends() read_barrier_depends() +#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) +#define set_mb(var, value) do { var = value; barrier(); } while (0) +#endif + +/* + * Stop RDTSC speculation. This is needed when you need to use RDTSC + * (or get_cycles or vread that possibly accesses the TSC) in a defined + * code region. + * + * (Could use an alternative three way for this if there was one.) + */ +static inline void rdtsc_barrier(void) +{ + alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); + alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); +} + +extern void *_switch_to(void *prev, void *next, void *last); +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) + +#endif diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 1f61b74867e4..3a78b00edd71 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -483,7 +483,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) if (!q) return NULL; - q->id = ida_simple_get(&blk_queue_ida, 0, 0, gfp_mask); + q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL); if (q->id < 0) goto fail_q; @@ -1277,8 +1277,7 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio, list_for_each_entry_reverse(rq, &plug->list, queuelist) { int el_ret; - if (rq->q == q) - (*request_count)++; + (*request_count)++; if (rq->q != q || !blk_rq_merge_ok(rq, bio)) continue; diff --git a/trunk/block/blk-throttle.c b/trunk/block/blk-throttle.c index f2ddb94626bd..5eed6a76721d 100644 --- a/trunk/block/blk-throttle.c +++ b/trunk/block/blk-throttle.c @@ -1218,7 +1218,7 @@ void blk_throtl_drain(struct request_queue *q) struct bio_list bl; struct bio *bio; - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); bio_list_init(&bl); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 3c38536bd52c..457295253566 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -295,7 +295,6 @@ struct cfq_data { unsigned int cfq_slice_idle; unsigned int cfq_group_idle; unsigned int cfq_latency; - unsigned int cfq_target_latency; /* * Fallback dummy cfqq for extreme OOM conditions @@ -605,7 +604,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg) { struct cfq_rb_root *st = &cfqd->grp_service_tree; - return cfqd->cfq_target_latency * cfqg->weight / st->total_weight; + return cfq_target_latency * cfqg->weight / st->total_weight; } static inline unsigned @@ -2272,8 +2271,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) * to have higher weight. A more accurate thing would be to * calculate system wide asnc/sync ratio. */ - tmp = cfqd->cfq_target_latency * - cfqg_busy_async_queues(cfqd, cfqg); + tmp = cfq_target_latency * cfqg_busy_async_queues(cfqd, cfqg); tmp = tmp/cfqd->busy_queues; slice = min_t(unsigned, slice, tmp); @@ -3739,7 +3737,6 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->cfq_back_penalty = cfq_back_penalty; cfqd->cfq_slice[0] = cfq_slice_async; cfqd->cfq_slice[1] = cfq_slice_sync; - cfqd->cfq_target_latency = cfq_target_latency; cfqd->cfq_slice_async_rq = cfq_slice_async_rq; cfqd->cfq_slice_idle = cfq_slice_idle; cfqd->cfq_group_idle = cfq_group_idle; @@ -3791,7 +3788,6 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); -SHOW_FUNCTION(cfq_target_latency_show, cfqd->cfq_target_latency, 1); #undef SHOW_FUNCTION #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ @@ -3825,7 +3821,6 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, 0); STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); -STORE_FUNCTION(cfq_target_latency_store, &cfqd->cfq_target_latency, 1, UINT_MAX, 1); #undef STORE_FUNCTION #define CFQ_ATTR(name) \ @@ -3843,7 +3838,6 @@ static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(slice_idle), CFQ_ATTR(group_idle), CFQ_ATTR(low_latency), - CFQ_ATTR(target_latency), __ATTR_NULL }; diff --git a/trunk/crypto/Kconfig b/trunk/crypto/Kconfig index 8e84225c096b..21ff9d015432 100644 --- a/trunk/crypto/Kconfig +++ b/trunk/crypto/Kconfig @@ -627,7 +627,7 @@ config CRYPTO_BLOWFISH_COMMON config CRYPTO_BLOWFISH_X86_64 tristate "Blowfish cipher algorithm (x86_64)" - depends on X86 && 64BIT + depends on (X86 || UML_X86) && 64BIT select CRYPTO_ALGAPI select CRYPTO_BLOWFISH_COMMON help @@ -657,7 +657,7 @@ config CRYPTO_CAMELLIA config CRYPTO_CAMELLIA_X86_64 tristate "Camellia cipher algorithm (x86_64)" - depends on X86 && 64BIT + depends on (X86 || UML_X86) && 64BIT depends on CRYPTO select CRYPTO_ALGAPI select CRYPTO_LRW @@ -893,7 +893,7 @@ config CRYPTO_TWOFISH_X86_64 config CRYPTO_TWOFISH_X86_64_3WAY tristate "Twofish cipher algorithm (x86_64, 3-way parallel)" - depends on X86 && 64BIT + depends on (X86 || UML_X86) && 64BIT select CRYPTO_ALGAPI select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 diff --git a/trunk/crypto/sha512_generic.c b/trunk/crypto/sha512_generic.c index dd30f40af9f5..107f6f7be5e1 100644 --- a/trunk/crypto/sha512_generic.c +++ b/trunk/crypto/sha512_generic.c @@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) index = sctx->count[0] & 0x7f; /* Update number of bytes */ - if ((sctx->count[0] += len) < len) + if (!(sctx->count[0] += len)) sctx->count[1]++; part_len = 128 - index; diff --git a/trunk/drivers/acpi/acpica/hwxface.c b/trunk/drivers/acpi/acpica/hwxface.c index a716fede4f25..ab513a972c95 100644 --- a/trunk/drivers/acpi/acpica/hwxface.c +++ b/trunk/drivers/acpi/acpica/hwxface.c @@ -74,8 +74,7 @@ acpi_status acpi_reset(void) /* Check if the reset register is supported */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || - !reset_reg->address) { + if (!reset_reg->address) { return_ACPI_STATUS(AE_NOT_EXIST); } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index c3881b2eb8b2..ba14fb93c929 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -607,7 +607,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, acpi_irq_handler = handler; acpi_irq_context = context; - if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { + if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", + acpi_irq)) { printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); acpi_irq_handler = NULL; return AE_NOT_ACQUIRED; diff --git a/trunk/drivers/acpi/reboot.c b/trunk/drivers/acpi/reboot.c index a6c77e8b37bd..c1d612435939 100644 --- a/trunk/drivers/acpi/reboot.c +++ b/trunk/drivers/acpi/reboot.c @@ -23,8 +23,7 @@ void acpi_reboot(void) /* Is the reset register supported? The spec says we should be * checking the bit width and bit offset, but Windows ignores * these fields */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) - return; + /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */ reset_value = acpi_gbl_FADT.reset_value; diff --git a/trunk/drivers/amba/bus.c b/trunk/drivers/amba/bus.c index cc273226dbd0..01c2cf4efcdd 100644 --- a/trunk/drivers/amba/bus.c +++ b/trunk/drivers/amba/bus.c @@ -247,7 +247,8 @@ static int amba_pm_restore(struct device *dev) /* * Hooks to provide runtime PM of the pclk (bus clock). It is safe to * enable/disable the bus clock at runtime PM suspend/resume as this - * does not result in loss of context. + * does not result in loss of context. However, disabling vcore power + * would do, so we leave that to the driver. */ static int amba_pm_runtime_suspend(struct device *dev) { @@ -353,6 +354,39 @@ static void amba_put_disable_pclk(struct amba_device *pcdev) clk_put(pclk); } +static int amba_get_enable_vcore(struct amba_device *pcdev) +{ + struct regulator *vcore = regulator_get(&pcdev->dev, "vcore"); + int ret; + + pcdev->vcore = vcore; + + if (IS_ERR(vcore)) { + /* It is OK not to supply a vcore regulator */ + if (PTR_ERR(vcore) == -ENODEV) + return 0; + return PTR_ERR(vcore); + } + + ret = regulator_enable(vcore); + if (ret) { + regulator_put(vcore); + pcdev->vcore = ERR_PTR(-ENODEV); + } + + return ret; +} + +static void amba_put_disable_vcore(struct amba_device *pcdev) +{ + struct regulator *vcore = pcdev->vcore; + + if (!IS_ERR(vcore)) { + regulator_disable(vcore); + regulator_put(vcore); + } +} + /* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. @@ -365,6 +399,10 @@ static int amba_probe(struct device *dev) int ret; do { + ret = amba_get_enable_vcore(pcdev); + if (ret) + break; + ret = amba_get_enable_pclk(pcdev); if (ret) break; @@ -382,6 +420,7 @@ static int amba_probe(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); + amba_put_disable_vcore(pcdev); } while (0); return ret; @@ -403,6 +442,7 @@ static int amba_remove(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); + amba_put_disable_vcore(pcdev); return ret; } diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 7857e8fd0a3e..68013f96729f 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -329,8 +329,6 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, - /* SATA Controller IDE (DH89xxCC) */ - { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 28db50b57b91..e0bda9ff89cd 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); static unsigned long ata_dev_blacklisted(const struct ata_device *dev); -atomic_t ata_print_id = ATOMIC_INIT(1); +unsigned int ata_print_id = 1; struct ata_force_param { const char *name; @@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) /* give ports names and add SCSI hosts */ for (i = 0; i < host->n_ports; i++) - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); + host->ports[i]->print_id = ata_print_id++; /* Create associated sysfs transport objects */ diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 93dabdcd2cbe..1ee00c8b5b04 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -3843,7 +3843,7 @@ int ata_sas_async_port_init(struct ata_port *ap) int rc = ap->ops->port_start(ap); if (!rc) { - ap->print_id = atomic_inc_return(&ata_print_id); + ap->print_id = ata_print_id++; __ata_port_probe(ap); } @@ -3867,7 +3867,7 @@ int ata_sas_port_init(struct ata_port *ap) int rc = ap->ops->port_start(ap); if (!rc) { - ap->print_id = atomic_inc_return(&ata_print_id); + ap->print_id = ata_print_id++; rc = ata_port_probe(ap); } diff --git a/trunk/drivers/ata/libata-transport.c b/trunk/drivers/ata/libata-transport.c index c34190485377..74aaee30e264 100644 --- a/trunk/drivers/ata/libata-transport.c +++ b/trunk/drivers/ata/libata-transport.c @@ -294,7 +294,6 @@ int ata_tport_add(struct device *parent, device_enable_async_suspend(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - pm_runtime_forbid(dev); transport_add_device(dev); transport_configure_device(dev); diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 9d0fd0b71852..2e26fcaf635b 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -53,7 +53,7 @@ enum { ATA_DNXFER_QUIET = (1 << 31), }; -extern atomic_t ata_print_id; +extern unsigned int ata_print_id; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 7336d4a7ab31..38950ea8398a 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -4025,8 +4025,7 @@ static int mv_platform_probe(struct platform_device *pdev) struct ata_host *host; struct mv_host_priv *hpriv; struct resource *res; - int n_ports = 0; - int rc; + int n_ports, rc; ata_print_version_once(&pdev->dev, DRV_VERSION); diff --git a/trunk/drivers/base/soc.c b/trunk/drivers/base/soc.c index ba29b2e73d48..05f150382da8 100644 --- a/trunk/drivers/base/soc.c +++ b/trunk/drivers/base/soc.c @@ -15,7 +15,7 @@ #include #include -static DEFINE_IDA(soc_ida); +static DEFINE_IDR(soc_ida); static DEFINE_SPINLOCK(soc_lock); static ssize_t soc_info_get(struct device *dev, @@ -168,6 +168,8 @@ void soc_device_unregister(struct soc_device *soc_dev) static int __init soc_bus_register(void) { + spin_lock_init(&soc_lock); + return bus_register(&soc_bus_type); } core_initcall(soc_bus_register); diff --git a/trunk/drivers/bcma/Kconfig b/trunk/drivers/bcma/Kconfig index fb7c80fb721e..c1172dafdffa 100644 --- a/trunk/drivers/bcma/Kconfig +++ b/trunk/drivers/bcma/Kconfig @@ -29,7 +29,7 @@ config BCMA_HOST_PCI config BCMA_DRIVER_PCI_HOSTMODE bool "Driver for PCI core working in hostmode" - depends on BCMA && MIPS && BCMA_HOST_PCI + depends on BCMA && MIPS help PCI core hostmode operation (external PCI bus). diff --git a/trunk/drivers/bcma/driver_pci_host.c b/trunk/drivers/bcma/driver_pci_host.c index d2097a11c3c7..4e20bcfa7ec5 100644 --- a/trunk/drivers/bcma/driver_pci_host.c +++ b/trunk/drivers/bcma/driver_pci_host.c @@ -10,7 +10,6 @@ */ #include "bcma_private.h" -#include #include #include #include diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index acda773b3720..e820b68d2f6c 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -866,7 +866,6 @@ cciss_scsi_detect(ctlr_info_t *h) sh->can_queue = cciss_tape_cmds; sh->sg_tablesize = h->maxsgentries; sh->max_cmd_len = MAX_COMMAND_SIZE; - sh->max_sectors = h->cciss_max_sectors; ((struct cciss_scsi_adapter_data_t *) h->scsi_ctlr)->scsi_host = sh; @@ -1411,7 +1410,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c, /* track how many SG entries we are using */ if (request_nsgs > h->maxSG) h->maxSG = request_nsgs; - c->Header.SGTotal = (u16) request_nsgs + chained; + c->Header.SGTotal = (__u8) request_nsgs + chained; if (request_nsgs > h->max_cmd_sgentries) c->Header.SGList = h->max_cmd_sgentries; else diff --git a/trunk/drivers/block/mtip32xx/Kconfig b/trunk/drivers/block/mtip32xx/Kconfig index 0ba837fc62a8..b5dd14e072f2 100644 --- a/trunk/drivers/block/mtip32xx/Kconfig +++ b/trunk/drivers/block/mtip32xx/Kconfig @@ -4,6 +4,6 @@ config BLK_DEV_PCIESSD_MTIP32XX tristate "Block Device Driver for Micron PCIe SSDs" - depends on PCI + depends on HOTPLUG_PCI_PCIE help This enables the block driver for Micron PCIe SSDs. diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 00f9fc992090..8eb81c96608f 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -36,7 +36,6 @@ #include #include #include <../drivers/ata/ahci.h> -#include #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -45,7 +44,6 @@ #define HW_PORT_PRIV_DMA_SZ \ (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) -#define HOST_CAP_NZDMA (1 << 19) #define HOST_HSORG 0xFC #define HSORG_DISABLE_SLOTGRP_INTR (1<<24) #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16) @@ -141,12 +139,6 @@ static void mtip_command_cleanup(struct driver_data *dd) int group = 0, commandslot = 0, commandindex = 0; struct mtip_cmd *command; struct mtip_port *port = dd->port; - static int in_progress; - - if (in_progress) - return; - - in_progress = 1; for (group = 0; group < 4; group++) { for (commandslot = 0; commandslot < 32; commandslot++) { @@ -173,8 +165,7 @@ static void mtip_command_cleanup(struct driver_data *dd) up(&port->cmd_slot); - set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag); - in_progress = 0; + atomic_set(&dd->drv_cleanup_done, true); } /* @@ -271,9 +262,6 @@ static int hba_reset_nosleep(struct driver_data *dd) && time_before(jiffies, timeout)) mdelay(1); - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) - return -1; - if (readl(dd->mmio + HOST_CTL) & HOST_RESET) return -1; @@ -306,10 +294,6 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) port->cmd_issue[MTIP_TAG_INDEX(tag)]); spin_unlock_irqrestore(&port->cmd_issue_lock, flags); - - /* Set the command's timeout value.*/ - port->commands[tag].comp_time = jiffies + msecs_to_jiffies( - MTIP_NCQ_COMMAND_TIMEOUT_MS); } /* @@ -436,12 +420,7 @@ static void mtip_init_port(struct mtip_port *port) writel(0xFFFFFFFF, port->completed[i]); /* Clear any pending interrupts for this port */ - writel(readl(port->dd->mmio + PORT_IRQ_STAT), - port->dd->mmio + PORT_IRQ_STAT); - - /* Clear any pending interrupts on the HBA. */ - writel(readl(port->dd->mmio + HOST_IRQ_STAT), - port->dd->mmio + HOST_IRQ_STAT); + writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); /* Enable port interrupts */ writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK); @@ -468,9 +447,6 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return; - /* * Chip quirk: escalate to hba reset if * PxCMD.CR not clear after 500 ms @@ -499,9 +475,6 @@ static void mtip_restart_port(struct mtip_port *port) while (time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return; - /* Clear PxSCTL.DET */ writel(readl(port->mmio + PORT_SCR_CTL) & ~1, port->mmio + PORT_SCR_CTL); @@ -513,35 +486,15 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return; - if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) dev_warn(&port->dd->pdev->dev, "COM reset failed\n"); - mtip_init_port(port); - mtip_start_port(port); - -} - -/* - * Helper function for tag logging - */ -static void print_tags(struct driver_data *dd, - char *msg, - unsigned long *tagbits, - int cnt) -{ - unsigned char tagmap[128]; - int group, tagmap_len = 0; + /* Clear SError, the PxSERR.DIAG.x should be set so clear it */ + writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); - memset(tagmap, 0, sizeof(tagmap)); - for (group = SLOTBITS_IN_LONGS; group > 0; group--) - tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ", - tagbits[group-1]); - dev_warn(&dd->pdev->dev, - "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap); + /* Enable the DMA engine */ + mtip_enable_engine(port, 1); } /* @@ -561,18 +514,15 @@ static void mtip_timeout_function(unsigned long int data) int tag, cmdto_cnt = 0; unsigned int bit, group; unsigned int num_command_slots = port->dd->slot_groups * 32; - unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; if (unlikely(!port)) return; - if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) { + if (atomic_read(&port->dd->resumeflag) == true) { mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(30000)); return; } - /* clear the tag accumulator */ - memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); for (tag = 0; tag < num_command_slots; tag++) { /* @@ -590,10 +540,12 @@ static void mtip_timeout_function(unsigned long int data) command = &port->commands[tag]; fis = (struct host_to_dev_fis *) command->command; - set_bit(tag, tagaccum); + dev_warn(&port->dd->pdev->dev, + "Timeout for command tag %d\n", tag); + cmdto_cnt++; if (cmdto_cnt == 1) - set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); /* * Clear the completed bit. This should prevent @@ -626,29 +578,15 @@ static void mtip_timeout_function(unsigned long int data) } } - if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); - + if (cmdto_cnt) { + dev_warn(&port->dd->pdev->dev, + "%d commands timed out: restarting port", + cmdto_cnt); mtip_restart_port(port); - clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); } - if (port->ic_pause_timer) { - to = port->ic_pause_timer + msecs_to_jiffies(1000); - if (time_after(jiffies, to)) { - if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - port->ic_pause_timer = 0; - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); - wake_up_interruptible(&port->svc_wait); - } - - - } - } - /* Restart the timer */ mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); @@ -743,18 +681,23 @@ static void mtip_completion(struct mtip_port *port, complete(waiting); } -static void mtip_null_completion(struct mtip_port *port, - int tag, - void *data, - int status) +/* + * Helper function for tag logging + */ +static void print_tags(struct driver_data *dd, + char *msg, + unsigned long *tagbits) { - return; + unsigned int tag, count = 0; + + for (tag = 0; tag < (dd->slot_groups) * 32; tag++) { + if (test_bit(tag, tagbits)) + count++; + } + if (count) + dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count); } -static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, - dma_addr_t buffer_dma, unsigned int sectors); -static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, - struct smart_attr *attrib); /* * Handle an error. * @@ -765,16 +708,12 @@ static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, */ static void mtip_handle_tfe(struct driver_data *dd) { - int group, tag, bit, reissue, rv; + int group, tag, bit, reissue; struct mtip_port *port; - struct mtip_cmd *cmd; + struct mtip_cmd *command; u32 completed; struct host_to_dev_fis *fis; unsigned long tagaccum[SLOTBITS_IN_LONGS]; - unsigned int cmd_cnt = 0; - unsigned char *buf; - char *fail_reason = NULL; - int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0; dev_warn(&dd->pdev->dev, "Taskfile error\n"); @@ -783,11 +722,8 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Stop the timer to prevent command timeouts. */ del_timer(&port->cmd_timer); - /* clear the tag accumulator */ - memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); - /* Set eh_active */ - set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); /* Loop through all the groups */ for (group = 0; group < dd->slot_groups; group++) { @@ -796,6 +732,9 @@ static void mtip_handle_tfe(struct driver_data *dd) /* clear completed status register in the hardware.*/ writel(completed, port->completed[group]); + /* clear the tag accumulator */ + memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + /* Process successfully completed commands */ for (bit = 0; bit < 32 && completed; bit++) { if (!(completed & (1<commands[tag]; - if (likely(cmd->comp_func)) { + command = &port->commands[tag]; + if (likely(command->comp_func)) { set_bit(tag, tagaccum); - cmd_cnt++; - atomic_set(&cmd->active, 0); - cmd->comp_func(port, + atomic_set(&port->commands[tag].active, 0); + command->comp_func(port, tag, - cmd->comp_data, + command->comp_data, 0); } else { dev_err(&port->dd->pdev->dev, @@ -827,45 +765,12 @@ static void mtip_handle_tfe(struct driver_data *dd) } } } - - print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt); + print_tags(dd, "TFE tags completed:", tagaccum); /* Restart the port */ mdelay(20); mtip_restart_port(port); - /* Trying to determine the cause of the error */ - rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, - dd->port->log_buf, - dd->port->log_buf_dma, 1); - if (rv) { - dev_warn(&dd->pdev->dev, - "Error in READ LOG EXT (10h) command\n"); - /* non-critical error, don't fail the load */ - } else { - buf = (unsigned char *)dd->port->log_buf; - if (buf[259] & 0x1) { - dev_info(&dd->pdev->dev, - "Write protect bit is set.\n"); - set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); - fail_all_ncq_write = 1; - fail_reason = "write protect"; - } - if (buf[288] == 0xF7) { - dev_info(&dd->pdev->dev, - "Exceeded Tmax, drive in thermal shutdown.\n"); - set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); - fail_all_ncq_cmds = 1; - fail_reason = "thermal shutdown"; - } - if (buf[288] == 0xBF) { - dev_info(&dd->pdev->dev, - "Drive indicates rebuild has failed.\n"); - fail_all_ncq_cmds = 1; - fail_reason = "rebuild failed"; - } - } - /* clear the tag accumulator */ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); @@ -874,47 +779,32 @@ static void mtip_handle_tfe(struct driver_data *dd) for (bit = 0; bit < 32; bit++) { reissue = 1; tag = (group << 5) + bit; - cmd = &port->commands[tag]; /* If the active bit is set re-issue the command */ - if (atomic_read(&cmd->active) == 0) + if (atomic_read(&port->commands[tag].active) == 0) continue; - fis = (struct host_to_dev_fis *)cmd->command; + fis = (struct host_to_dev_fis *) + port->commands[tag].command; /* Should re-issue? */ if (tag == MTIP_TAG_INTERNAL || fis->command == ATA_CMD_SET_FEATURES) reissue = 0; - else { - if (fail_all_ncq_cmds || - (fail_all_ncq_write && - fis->command == ATA_CMD_FPDMA_WRITE)) { - dev_warn(&dd->pdev->dev, - " Fail: %s w/tag %d [%s].\n", - fis->command == ATA_CMD_FPDMA_WRITE ? - "write" : "read", - tag, - fail_reason != NULL ? - fail_reason : "unknown"); - atomic_set(&cmd->active, 0); - if (cmd->comp_func) { - cmd->comp_func(port, tag, - cmd->comp_data, - -ENODATA); - } - continue; - } - } /* * First check if this command has * exceeded its retries. */ - if (reissue && (cmd->retries-- > 0)) { + if (reissue && + (port->commands[tag].retries-- > 0)) { set_bit(tag, tagaccum); + /* Update the timeout value. */ + port->commands[tag].comp_time = + jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); /* Re-issue the command. */ mtip_issue_ncq_command(port, tag); @@ -924,13 +814,13 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Retire a command that will not be reissued */ dev_warn(&port->dd->pdev->dev, "retiring tag %d\n", tag); - atomic_set(&cmd->active, 0); + atomic_set(&port->commands[tag].active, 0); - if (cmd->comp_func) - cmd->comp_func( + if (port->commands[tag].comp_func) + port->commands[tag].comp_func( port, tag, - cmd->comp_data, + port->commands[tag].comp_data, PORT_IRQ_TF_ERR); else dev_warn(&port->dd->pdev->dev, @@ -938,10 +828,10 @@ static void mtip_handle_tfe(struct driver_data *dd) tag); } } - print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); + print_tags(dd, "TFE tags reissued:", tagaccum); /* clear eh_active */ - clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); mod_timer(&port->cmd_timer, @@ -1009,7 +899,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) struct mtip_port *port = dd->port; struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; - if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && + if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL))) { if (cmd->comp_func) { @@ -1021,6 +911,8 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) } } + dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat); + return; } @@ -1076,9 +968,6 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) /* don't proceed further */ return IRQ_HANDLED; } - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag)) - return rv; mtip_process_errors(dd, port_stat & PORT_IRQ_ERR); } @@ -1126,39 +1015,6 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) port->cmd_issue[MTIP_TAG_INDEX(tag)]); } -static bool mtip_pause_ncq(struct mtip_port *port, - struct host_to_dev_fis *fis) -{ - struct host_to_dev_fis *reply; - unsigned long task_file_data; - - reply = port->rxfis + RX_FIS_D2H_REG; - task_file_data = readl(port->mmio+PORT_TFDATA); - - if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT)) - return false; - - if (fis->command == ATA_CMD_SEC_ERASE_PREP) { - set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - port->ic_pause_timer = jiffies; - return true; - } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) && - (fis->features == 0x03)) { - set_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); - port->ic_pause_timer = jiffies; - return true; - } else if ((fis->command == ATA_CMD_SEC_ERASE_UNIT) || - ((fis->command == 0xFC) && - (fis->features == 0x27 || fis->features == 0x72 || - fis->features == 0x62 || fis->features == 0x26))) { - /* Com reset after secure erase or lowlevel format */ - mtip_restart_port(port); - return false; - } - - return false; -} - /* * Wait for port to quiesce * @@ -1177,13 +1033,11 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) to = jiffies + msecs_to_jiffies(timeout); do { - if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) && - test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { + if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) && + test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { msleep(20); continue; /* svc thd is actively issuing commands */ } - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return -EFAULT; /* * Ignore s_active bit 0 of array element 0. * This bit will always be set @@ -1220,7 +1074,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) * -EAGAIN Time out waiting for command to complete. */ static int mtip_exec_internal_command(struct mtip_port *port, - struct host_to_dev_fis *fis, + void *fis, int fis_len, dma_addr_t buffer, int buf_len, @@ -1230,9 +1084,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, { struct mtip_cmd_sg *command_sg; DECLARE_COMPLETION_ONSTACK(wait); - int rv = 0, ready2go = 1; + int rv = 0; struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; - unsigned long to; /* Make sure the buffer is 8 byte aligned. This is asic specific. */ if (buffer & 0x00000007) { @@ -1241,38 +1094,23 @@ static int mtip_exec_internal_command(struct mtip_port *port, return -EFAULT; } - to = jiffies + msecs_to_jiffies(timeout); - do { - ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL, - port->allocated); - if (ready2go) - break; - mdelay(100); - } while (time_before(jiffies, to)); - if (!ready2go) { + /* Only one internal command should be running at a time */ + if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) { dev_warn(&port->dd->pdev->dev, - "Internal cmd active. new cmd [%02X]\n", fis->command); + "Internal command already active\n"); return -EBUSY; } - set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); - port->ic_pause_timer = 0; - - if (fis->command == ATA_CMD_SEC_ERASE_UNIT) - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - else if (fis->command == ATA_CMD_DOWNLOAD_MICRO) - clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); + set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { - if (fis->command != ATA_CMD_STANDBYNOW1) { - /* wait for io to complete if non atomic */ - if (mtip_quiesce_io(port, 5000) < 0) { - dev_warn(&port->dd->pdev->dev, - "Failed to quiesce IO\n"); - release_slot(port, MTIP_TAG_INTERNAL); - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); - wake_up_interruptible(&port->svc_wait); - return -EBUSY; - } + /* wait for io to complete if non atomic */ + if (mtip_quiesce_io(port, 5000) < 0) { + dev_warn(&port->dd->pdev->dev, + "Failed to quiesce IO\n"); + release_slot(port, MTIP_TAG_INTERNAL); + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); + return -EBUSY; } /* Set the completion function and data for the command. */ @@ -1282,7 +1120,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, } else { /* Clear completion - we're going to poll */ int_cmd->comp_data = NULL; - int_cmd->comp_func = mtip_null_completion; + int_cmd->comp_func = NULL; } /* Copy the command to the command table */ @@ -1321,12 +1159,6 @@ static int mtip_exec_internal_command(struct mtip_port *port, "Internal command did not complete [%d] " "within timeout of %lu ms\n", atomic, timeout); - if (mtip_check_surprise_removal(port->dd->pdev) || - test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - rv = -ENXIO; - goto exec_ic_exit; - } rv = -EAGAIN; } @@ -1334,59 +1166,31 @@ static int mtip_exec_internal_command(struct mtip_port *port, & (1 << MTIP_TAG_INTERNAL)) { dev_warn(&port->dd->pdev->dev, "Retiring internal command but CI is 1.\n"); - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - hba_reset_nosleep(port->dd); - rv = -ENXIO; - } else { - mtip_restart_port(port); - rv = -EAGAIN; - } - goto exec_ic_exit; } } else { /* Spin for checking if command still outstanding */ timeout = jiffies + msecs_to_jiffies(timeout); - while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL]) - & (1 << MTIP_TAG_INTERNAL)) - && time_before(jiffies, timeout)) { - if (mtip_check_surprise_removal(port->dd->pdev)) { - rv = -ENXIO; - goto exec_ic_exit; - } - if ((fis->command != ATA_CMD_STANDBYNOW1) && - test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - rv = -ENXIO; - goto exec_ic_exit; - } - } + + while ((readl( + port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) + && time_before(jiffies, timeout)) + ; if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { dev_err(&port->dd->pdev->dev, - "Internal command did not complete [atomic]\n"); + "Internal command did not complete [%d]\n", + atomic); rv = -EAGAIN; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - hba_reset_nosleep(port->dd); - rv = -ENXIO; - } else { - mtip_restart_port(port); - rv = -EAGAIN; - } } } -exec_ic_exit: + /* Clear the allocated and active bits for the internal command. */ atomic_set(&int_cmd->active, 0); release_slot(port, MTIP_TAG_INTERNAL); - if (rv >= 0 && mtip_pause_ncq(port, fis)) { - /* NCQ paused */ - return rv; - } - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); return rv; @@ -1436,9 +1240,6 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) int rv = 0; struct host_to_dev_fis fis; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return -EFAULT; - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1512,7 +1313,6 @@ static int mtip_standby_immediate(struct mtip_port *port) { int rv; struct host_to_dev_fis fis; - unsigned long start; /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); @@ -1520,150 +1320,15 @@ static int mtip_standby_immediate(struct mtip_port *port) fis.opts = 1 << 7; fis.command = ATA_CMD_STANDBYNOW1; - start = jiffies; + /* Execute the command. Use a 15-second timeout for large drives. */ rv = mtip_exec_internal_command(port, &fis, 5, 0, 0, 0, - GFP_ATOMIC, + GFP_KERNEL, 15000); - dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n", - jiffies_to_msecs(jiffies - start)); - if (rv) - dev_warn(&port->dd->pdev->dev, - "STANDBY IMMEDIATE command failed.\n"); - - return rv; -} - -/* - * Issue a READ LOG EXT command to the device. - * - * @port pointer to the port structure. - * @page page number to fetch - * @buffer pointer to buffer - * @buffer_dma dma address corresponding to @buffer - * @sectors page length to fetch, in sectors - * - * return value - * @rv return value from mtip_exec_internal_command() - */ -static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, - dma_addr_t buffer_dma, unsigned int sectors) -{ - struct host_to_dev_fis fis; - - memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.type = 0x27; - fis.opts = 1 << 7; - fis.command = ATA_CMD_READ_LOG_EXT; - fis.sect_count = sectors & 0xFF; - fis.sect_cnt_ex = (sectors >> 8) & 0xFF; - fis.lba_low = page; - fis.lba_mid = 0; - fis.device = ATA_DEVICE_OBS; - - memset(buffer, 0, sectors * ATA_SECT_SIZE); - - return mtip_exec_internal_command(port, - &fis, - 5, - buffer_dma, - sectors * ATA_SECT_SIZE, - 0, - GFP_ATOMIC, - MTIP_INTERNAL_COMMAND_TIMEOUT_MS); -} - -/* - * Issue a SMART READ DATA command to the device. - * - * @port pointer to the port structure. - * @buffer pointer to buffer - * @buffer_dma dma address corresponding to @buffer - * - * return value - * @rv return value from mtip_exec_internal_command() - */ -static int mtip_get_smart_data(struct mtip_port *port, u8 *buffer, - dma_addr_t buffer_dma) -{ - struct host_to_dev_fis fis; - - memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.type = 0x27; - fis.opts = 1 << 7; - fis.command = ATA_CMD_SMART; - fis.features = 0xD0; - fis.sect_count = 1; - fis.lba_mid = 0x4F; - fis.lba_hi = 0xC2; - fis.device = ATA_DEVICE_OBS; - - return mtip_exec_internal_command(port, - &fis, - 5, - buffer_dma, - ATA_SECT_SIZE, - 0, - GFP_ATOMIC, - 15000); -} - -/* - * Get the value of a smart attribute - * - * @port pointer to the port structure - * @id attribute number - * @attrib pointer to return attrib information corresponding to @id - * - * return value - * -EINVAL NULL buffer passed or unsupported attribute @id. - * -EPERM Identify data not valid, SMART not supported or not enabled - */ -static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, - struct smart_attr *attrib) -{ - int rv, i; - struct smart_attr *pattr; - - if (!attrib) - return -EINVAL; - - if (!port->identify_valid) { - dev_warn(&port->dd->pdev->dev, "IDENTIFY DATA not valid\n"); - return -EPERM; - } - if (!(port->identify[82] & 0x1)) { - dev_warn(&port->dd->pdev->dev, "SMART not supported\n"); - return -EPERM; - } - if (!(port->identify[85] & 0x1)) { - dev_warn(&port->dd->pdev->dev, "SMART not enabled\n"); - return -EPERM; - } - - memset(port->smart_buf, 0, ATA_SECT_SIZE); - rv = mtip_get_smart_data(port, port->smart_buf, port->smart_buf_dma); - if (rv) { - dev_warn(&port->dd->pdev->dev, "Failed to ge SMART data\n"); - return rv; - } - - pattr = (struct smart_attr *)(port->smart_buf + 2); - for (i = 0; i < 29; i++, pattr++) - if (pattr->attr_id == id) { - memcpy(attrib, pattr, sizeof(struct smart_attr)); - break; - } - - if (i == 29) { - dev_warn(&port->dd->pdev->dev, - "Query for invalid SMART attribute ID\n"); - rv = -EINVAL; - } return rv; } @@ -1839,7 +1504,10 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) fis.cyl_hi = command[5]; fis.device = command[6] & ~0x10; /* Clear the dev bit*/ - dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", + + dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, " + "nsect %x, sect %x, lcyl %x, " + "hcyl %x, sel %x\n", __func__, command[0], command[1], @@ -1866,7 +1534,8 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) command[4] = reply->cyl_low; command[5] = reply->cyl_hi; - dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n", + dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, " + "err %x , cyl_lo %x cyl_hi %x\n", __func__, command[0], command[1], @@ -1909,7 +1578,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, } dbg_printk(MTIP_DRV_NAME - " %s: User Command: cmd %x, sect %x, " + "%s: User Command: cmd %x, sect %x, " "feat %x, sectcnt %x\n", __func__, command[0], @@ -1938,7 +1607,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, command[2] = command[3]; dbg_printk(MTIP_DRV_NAME - " %s: Completion Status: stat %x, " + "%s: Completion Status: stat %x, " "err %x, cmd %x\n", __func__, command[0], @@ -2141,10 +1810,9 @@ static int exec_drive_taskfile(struct driver_data *dd, } dbg_printk(MTIP_DRV_NAME - " %s: cmd %x, feat %x, nsect %x," + "taskfile: cmd %x, feat %x, nsect %x," " sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x," " head/dev %x\n", - __func__, fis.command, fis.features, fis.sect_count, @@ -2155,8 +1823,8 @@ static int exec_drive_taskfile(struct driver_data *dd, switch (fis.command) { case ATA_CMD_DOWNLOAD_MICRO: - /* Change timeout for Download Microcode to 2 minutes */ - timeout = 120000; + /* Change timeout for Download Microcode to 60 seconds.*/ + timeout = 60000; break; case ATA_CMD_SEC_ERASE_UNIT: /* Change timeout for Security Erase Unit to 4 minutes.*/ @@ -2172,8 +1840,8 @@ static int exec_drive_taskfile(struct driver_data *dd, timeout = 10000; break; case ATA_CMD_SMART: - /* Change timeout for vendor unique command to 15 secs */ - timeout = 15000; + /* Change timeout for vendor unique command to 10 secs */ + timeout = 10000; break; default: timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; @@ -2235,8 +1903,18 @@ static int exec_drive_taskfile(struct driver_data *dd, req_task->hob_ports[1] = reply->features_ex; req_task->hob_ports[2] = reply->sect_cnt_ex; } + + /* Com rest after secure erase or lowlevel format */ + if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) || + ((fis.command == 0xFC) && + (fis.features == 0x27 || fis.features == 0x72 || + fis.features == 0x62 || fis.features == 0x26))) && + !(reply->command & 1)) { + mtip_restart_port(dd->port); + } + dbg_printk(MTIP_DRV_NAME - " %s: Completion: stat %x," + "%s: Completion: stat %x," "err %x, sect_cnt %x, lbalo %x," "lbamid %x, lbahi %x, dev %x\n", __func__, @@ -2402,10 +2080,14 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, struct host_to_dev_fis *fis; struct mtip_port *port = dd->port; struct mtip_cmd *command = &port->commands[tag]; - int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; /* Map the scatter list for DMA access */ - nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); + if (dir == READ) + nents = dma_map_sg(&dd->pdev->dev, command->sg, + nents, DMA_FROM_DEVICE); + else + nents = dma_map_sg(&dd->pdev->dev, command->sg, + nents, DMA_TO_DEVICE); command->scatter_ents = nents; @@ -2445,7 +2127,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, */ command->comp_data = dd; command->comp_func = mtip_async_complete; - command->direction = dma_dir; + command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE); /* * Set the completion function and data for the command passed @@ -2458,16 +2140,19 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, * To prevent this command from being issued * if an internal command is in progress or error handling is active. */ - if (port->flags & MTIP_PF_PAUSE_IO) { + if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) || + test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) { set_bit(tag, port->cmds_to_issue); - set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); + set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); return; } /* Issue the command to the hardware */ mtip_issue_ncq_command(port, tag); - return; + /* Set the command's timeout value.*/ + port->commands[tag].comp_time = jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); } /* @@ -2506,10 +2191,6 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, down(&dd->port->cmd_slot); *tag = get_slot(dd->port); - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { - up(&dd->port->cmd_slot); - return NULL; - } if (unlikely(*tag < 0)) return NULL; @@ -2526,7 +2207,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t mtip_hw_show_registers(struct device *dev, +static ssize_t hw_show_registers(struct device *dev, struct device_attribute *attr, char *buf) { @@ -2535,7 +2216,7 @@ static ssize_t mtip_hw_show_registers(struct device *dev, int size = 0; int n; - size += sprintf(&buf[size], "S ACTive:\n"); + size += sprintf(&buf[size], "%s:\ns_active:\n", __func__); for (n = 0; n < dd->slot_groups; n++) size += sprintf(&buf[size], "0x%08x\n", @@ -2559,39 +2240,20 @@ static ssize_t mtip_hw_show_registers(struct device *dev, group_allocated); } - size += sprintf(&buf[size], "Completed:\n"); + size += sprintf(&buf[size], "completed:\n"); for (n = 0; n < dd->slot_groups; n++) size += sprintf(&buf[size], "0x%08x\n", readl(dd->port->completed[n])); - size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n", + size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n", readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n", + size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n", readl(dd->mmio + HOST_IRQ_STAT)); return size; } - -static ssize_t mtip_hw_show_status(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; - - if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "thermal_shutdown\n"); - else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "write_protect\n"); - else - size += sprintf(buf, "%s", "online\n"); - - return size; -} - -static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); -static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); +static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL); /* * Create the sysfs related attributes. @@ -2610,10 +2272,7 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (sysfs_create_file(kobj, &dev_attr_registers.attr)) dev_warn(&dd->pdev->dev, - "Error creating 'registers' sysfs entry\n"); - if (sysfs_create_file(kobj, &dev_attr_status.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'status' sysfs entry\n"); + "Error creating registers sysfs entry\n"); return 0; } @@ -2633,7 +2292,6 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) return -EINVAL; sysfs_remove_file(kobj, &dev_attr_registers.attr); - sysfs_remove_file(kobj, &dev_attr_status.attr); return 0; } @@ -2726,12 +2384,10 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) "FTL rebuild in progress. Polling for completion.\n"); start = jiffies; + dd->ftlrebuildflag = 1; timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); do { - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag))) - return -EFAULT; if (mtip_check_surprise_removal(dd->pdev)) return -EFAULT; @@ -2752,17 +2408,22 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) dev_warn(&dd->pdev->dev, "FTL rebuild complete (%d secs).\n", jiffies_to_msecs(jiffies - start) / 1000); + dd->ftlrebuildflag = 0; mtip_block_initialize(dd); - return 0; + break; } ssleep(10); } while (time_before(jiffies, timeout)); /* Check for timeout */ - dev_err(&dd->pdev->dev, + if (dd->ftlrebuildflag) { + dev_err(&dd->pdev->dev, "Timed out waiting for FTL rebuild to complete (%d secs).\n", jiffies_to_msecs(jiffies - start) / 1000); - return -EFAULT; + return -EFAULT; + } + + return 0; } /* @@ -2787,17 +2448,14 @@ static int mtip_service_thread(void *data) * is in progress nor error handling is active */ wait_event_interruptible(port->svc_wait, (port->flags) && - !(port->flags & MTIP_PF_PAUSE_IO)); + !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && + !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags)); if (kthread_should_stop()) break; - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag))) - break; - - set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { + set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); + if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { slot = 1; /* used to restrict the loop to one iteration */ slot_start = num_cmd_slots; @@ -2822,19 +2480,21 @@ static int mtip_service_thread(void *data) /* Issue the command to the hardware */ mtip_issue_ncq_command(port, slot); + /* Set the command's timeout value.*/ + port->commands[slot].comp_time = jiffies + + msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS); + clear_bit(slot, port->cmds_to_issue); } - clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); - } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { - if (!mtip_ftl_rebuild_poll(dd)) - set_bit(MTIP_DDF_REBUILD_FAILED_BIT, - &dd->dd_flag); - clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); + clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); + } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) { + mtip_ftl_rebuild_poll(dd); + clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags); } - clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) + if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags)) break; } return 0; @@ -2853,9 +2513,6 @@ static int mtip_hw_init(struct driver_data *dd) int i; int rv; unsigned int num_command_slots; - unsigned long timeout, timetaken; - unsigned char *buf; - struct smart_attr attr242; dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; @@ -2890,7 +2547,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Allocate memory for the command list. */ dd->port->command_list = dmam_alloc_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), &dd->port->command_list_dma, GFP_KERNEL); if (!dd->port->command_list) { @@ -2903,7 +2560,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Clear the memory we have allocated. */ memset(dd->port->command_list, 0, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4)); + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2)); /* Setup the addresse of the RX FIS. */ dd->port->rxfis = dd->port->command_list + HW_CMD_SLOT_SZ; @@ -2919,19 +2576,10 @@ static int mtip_hw_init(struct driver_data *dd) dd->port->identify_dma = dd->port->command_tbl_dma + HW_CMD_TBL_AR_SZ; - /* Setup the address of the sector buffer - for some non-ncq cmds */ + /* Setup the address of the sector buffer. */ dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE; dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE; - /* Setup the address of the log buf - for read log command */ - dd->port->log_buf = (void *)dd->port->sector_buffer + ATA_SECT_SIZE; - dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE; - - /* Setup the address of the smart buf - for smart read data command */ - dd->port->smart_buf = (void *)dd->port->log_buf + ATA_SECT_SIZE; - dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE; - - /* Point the command headers at the command tables. */ for (i = 0; i < num_command_slots; i++) { dd->port->commands[i].command_header = @@ -2975,43 +2623,14 @@ static int mtip_hw_init(struct driver_data *dd) dd->port->mmio + i*0x80 + PORT_SDBV; } - timetaken = jiffies; - timeout = jiffies + msecs_to_jiffies(30000); - while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) && - time_before(jiffies, timeout)) { - mdelay(100); - } - if (unlikely(mtip_check_surprise_removal(dd->pdev))) { - timetaken = jiffies - timetaken; - dev_warn(&dd->pdev->dev, - "Surprise removal detected at %u ms\n", - jiffies_to_msecs(timetaken)); - rv = -ENODEV; - goto out2 ; - } - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { - timetaken = jiffies - timetaken; - dev_warn(&dd->pdev->dev, - "Removal detected at %u ms\n", - jiffies_to_msecs(timetaken)); - rv = -EFAULT; + /* Reset the HBA. */ + if (mtip_hba_reset(dd) < 0) { + dev_err(&dd->pdev->dev, + "Card did not reset within timeout\n"); + rv = -EIO; goto out2; } - /* Conditionally reset the HBA. */ - if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) { - if (mtip_hba_reset(dd) < 0) { - dev_err(&dd->pdev->dev, - "Card did not reset within timeout\n"); - rv = -EIO; - goto out2; - } - } else { - /* Clear any pending interrupts on the HBA */ - writel(readl(dd->mmio + HOST_IRQ_STAT), - dd->mmio + HOST_IRQ_STAT); - } - mtip_init_port(dd->port); mtip_start_port(dd->port); @@ -3041,12 +2660,6 @@ static int mtip_hw_init(struct driver_data *dd) mod_timer(&dd->port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); - - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { - rv = -EFAULT; - goto out3; - } - if (mtip_get_identify(dd->port, NULL) < 0) { rv = -EFAULT; goto out3; @@ -3054,47 +2667,10 @@ static int mtip_hw_init(struct driver_data *dd) if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == MTIP_FTL_REBUILD_MAGIC) { - set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); + set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags); return MTIP_FTL_REBUILD_MAGIC; } mtip_dump_identify(dd->port); - - /* check write protect, over temp and rebuild statuses */ - rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, - dd->port->log_buf, - dd->port->log_buf_dma, 1); - if (rv) { - dev_warn(&dd->pdev->dev, - "Error in READ LOG EXT (10h) command\n"); - /* non-critical error, don't fail the load */ - } else { - buf = (unsigned char *)dd->port->log_buf; - if (buf[259] & 0x1) { - dev_info(&dd->pdev->dev, - "Write protect bit is set.\n"); - set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); - } - if (buf[288] == 0xF7) { - dev_info(&dd->pdev->dev, - "Exceeded Tmax, drive in thermal shutdown.\n"); - set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); - } - if (buf[288] == 0xBF) { - dev_info(&dd->pdev->dev, - "Drive indicates rebuild has failed.\n"); - /* TODO */ - } - } - - /* get write protect progess */ - memset(&attr242, 0, sizeof(struct smart_attr)); - if (mtip_get_smart_attr(dd->port, 242, &attr242)) - dev_warn(&dd->pdev->dev, - "Unable to check write protect progress\n"); - else - dev_info(&dd->pdev->dev, - "Write protect progress: %d%% (%d blocks)\n", - attr242.cur, attr242.data); return rv; out3: @@ -3112,7 +2688,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), dd->port->command_list, dd->port->command_list_dma); out1: @@ -3136,12 +2712,9 @@ static int mtip_hw_exit(struct driver_data *dd) * Send standby immediate (E0h) to the drive so that it * saves its state. */ - if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { + if (atomic_read(&dd->drv_cleanup_done) != true) { - if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) - if (mtip_standby_immediate(dd->port)) - dev_warn(&dd->pdev->dev, - "STANDBY IMMEDIATE failed\n"); + mtip_standby_immediate(dd->port); /* de-initialize the port. */ mtip_deinit_port(dd->port); @@ -3161,7 +2734,7 @@ static int mtip_hw_exit(struct driver_data *dd) /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), dd->port->command_list, dd->port->command_list_dma); /* Free the memory allocated for the for structure. */ @@ -3319,9 +2892,6 @@ static int mtip_block_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) - return -ENOTTY; - switch (cmd) { case BLKFLSBUF: return -ENOTTY; @@ -3357,9 +2927,6 @@ static int mtip_block_compat_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) - return -ENOTTY; - switch (cmd) { case BLKFLSBUF: return -ENOTTY; @@ -3482,24 +3049,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) int nents = 0; int tag = 0; - if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag))) { - bio_endio(bio, -ENXIO); - return; - } - if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) { - bio_endio(bio, -ENODATA); - return; - } - if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT, - &dd->dd_flag) && - bio_data_dir(bio))) { - bio_endio(bio, -ENODATA); - return; - } - } - if (unlikely(!bio_has_data(bio))) { blk_queue_flush(queue, 0); bio_endio(bio, 0); @@ -3512,7 +3061,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { dev_warn(&dd->pdev->dev, - "Maximum number of SGL entries exceeded\n"); + "Maximum number of SGL entries exceeded"); bio_io_error(bio); mtip_hw_release_scatterlist(dd, tag); return; @@ -3661,10 +3210,8 @@ static int mtip_block_initialize(struct driver_data *dd) kobject_put(kobj); } - if (dd->mtip_svc_handler) { - set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); + if (dd->mtip_svc_handler) return rv; /* service thread created for handling rebuild */ - } start_service_thread: sprintf(thd_name, "mtip_svc_thd_%02d", index); @@ -3673,15 +3220,12 @@ static int mtip_block_initialize(struct driver_data *dd) dd, thd_name); if (IS_ERR(dd->mtip_svc_handler)) { - dev_err(&dd->pdev->dev, "service thread failed to start\n"); + printk(KERN_ERR "mtip32xx: service thread failed to start\n"); dd->mtip_svc_handler = NULL; rv = -EFAULT; goto kthread_run_error; } - if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) - rv = wait_for_rebuild; - return rv; kthread_run_error: @@ -3722,18 +3266,16 @@ static int mtip_block_remove(struct driver_data *dd) struct kobject *kobj; if (dd->mtip_svc_handler) { - set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); + set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); wake_up_interruptible(&dd->port->svc_wait); kthread_stop(dd->mtip_svc_handler); } - /* Clean up the sysfs attributes, if created */ - if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) { - kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); - if (kobj) { - mtip_hw_sysfs_exit(dd, kobj); - kobject_put(kobj); - } + /* Clean up the sysfs attributes managed by the protocol layer. */ + kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); + if (kobj) { + mtip_hw_sysfs_exit(dd, kobj); + kobject_put(kobj); } /* @@ -3741,11 +3283,6 @@ static int mtip_block_remove(struct driver_data *dd) * from /dev */ del_gendisk(dd->disk); - - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, dd->index); - spin_unlock(&rssd_index_lock); - blk_cleanup_queue(dd->queue); dd->disk = NULL; dd->queue = NULL; @@ -3775,11 +3312,6 @@ static int mtip_block_shutdown(struct driver_data *dd) /* Delete our gendisk structure, and cleanup the blk queue. */ del_gendisk(dd->disk); - - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, dd->index); - spin_unlock(&rssd_index_lock); - blk_cleanup_queue(dd->queue); dd->disk = NULL; dd->queue = NULL; @@ -3827,6 +3359,11 @@ static int mtip_pci_probe(struct pci_dev *pdev, return -ENOMEM; } + /* Set the atomic variable as 1 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + + atomic_set(&dd->resumeflag, false); + /* Attach the private data to this PCI device. */ pci_set_drvdata(pdev, dd); @@ -3883,8 +3420,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, * instance number. */ instance++; - if (rv != MTIP_FTL_REBUILD_MAGIC) - set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); + goto done; block_initialize_err: @@ -3898,6 +3434,9 @@ static int mtip_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, NULL); return rv; done: + /* Set the atomic variable as 0 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + return rv; } @@ -3913,10 +3452,8 @@ static void mtip_pci_remove(struct pci_dev *pdev) struct driver_data *dd = pci_get_drvdata(pdev); int counter = 0; - set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); - if (mtip_check_surprise_removal(pdev)) { - while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { + while (atomic_read(&dd->drv_cleanup_done) == false) { counter++; msleep(20); if (counter == 10) { @@ -3926,6 +3463,8 @@ static void mtip_pci_remove(struct pci_dev *pdev) } } } + /* Set the atomic variable as 1 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); /* Clean up the block layer. */ mtip_block_remove(dd); @@ -3954,7 +3493,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) return -EFAULT; } - set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); + atomic_set(&dd->resumeflag, true); /* Disable ports & interrupts then send standby immediate */ rv = mtip_block_suspend(dd); @@ -4020,7 +3559,7 @@ static int mtip_pci_resume(struct pci_dev *pdev) dev_err(&pdev->dev, "Unable to resume\n"); err: - clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); + atomic_set(&dd->resumeflag, false); return rv; } @@ -4069,25 +3608,18 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl); */ static int __init mtip_init(void) { - int error; - printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); /* Allocate a major block device number to use with this driver. */ - error = register_blkdev(0, MTIP_DRV_NAME); - if (error <= 0) { + mtip_major = register_blkdev(0, MTIP_DRV_NAME); + if (mtip_major < 0) { printk(KERN_ERR "Unable to register block device (%d)\n", - error); + mtip_major); return -EBUSY; } - mtip_major = error; /* Register our PCI operations. */ - error = pci_register_driver(&mtip_pci_driver); - if (error) - unregister_blkdev(mtip_major, MTIP_DRV_NAME); - - return error; + return pci_register_driver(&mtip_pci_driver); } /* diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index 4ef58336310a..e0554a8f2233 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -34,8 +34,8 @@ /* offset of Device Control register in PCIe extended capabilites space */ #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 -/* # of times to retry timed out/failed IOs */ -#define MTIP_MAX_RETRIES 2 +/* # of times to retry timed out IOs */ +#define MTIP_MAX_RETRIES 5 /* Various timeout values in ms */ #define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000 @@ -114,41 +114,12 @@ #define __force_bit2int (unsigned int __force) /* below are bit numbers in 'flags' defined in mtip_port */ -#define MTIP_PF_IC_ACTIVE_BIT 0 /* pio/ioctl */ -#define MTIP_PF_EH_ACTIVE_BIT 1 /* error handling */ -#define MTIP_PF_SE_ACTIVE_BIT 2 /* secure erase */ -#define MTIP_PF_DM_ACTIVE_BIT 3 /* download microcde */ -#define MTIP_PF_PAUSE_IO ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ - (1 << MTIP_PF_EH_ACTIVE_BIT) | \ - (1 << MTIP_PF_SE_ACTIVE_BIT) | \ - (1 << MTIP_PF_DM_ACTIVE_BIT)) - -#define MTIP_PF_SVC_THD_ACTIVE_BIT 4 -#define MTIP_PF_ISSUE_CMDS_BIT 5 -#define MTIP_PF_REBUILD_BIT 6 -#define MTIP_PF_SVC_THD_STOP_BIT 8 - -/* below are bit numbers in 'dd_flag' defined in driver_data */ -#define MTIP_DDF_REMOVE_PENDING_BIT 1 -#define MTIP_DDF_OVER_TEMP_BIT 2 -#define MTIP_DDF_WRITE_PROTECT_BIT 3 -#define MTIP_DDF_STOP_IO ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ - (1 << MTIP_DDF_OVER_TEMP_BIT) | \ - (1 << MTIP_DDF_WRITE_PROTECT_BIT)) - -#define MTIP_DDF_CLEANUP_BIT 5 -#define MTIP_DDF_RESUME_BIT 6 -#define MTIP_DDF_INIT_DONE_BIT 7 -#define MTIP_DDF_REBUILD_FAILED_BIT 8 - -__packed struct smart_attr{ - u8 attr_id; - u16 flags; - u8 cur; - u8 worst; - u32 data; - u8 res[3]; -}; +#define MTIP_FLAG_IC_ACTIVE_BIT 0 +#define MTIP_FLAG_EH_ACTIVE_BIT 1 +#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 +#define MTIP_FLAG_ISSUE_CMDS_BIT 4 +#define MTIP_FLAG_REBUILD_BIT 5 +#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { @@ -374,12 +345,6 @@ struct mtip_port { * when the command slot and all associated data structures * are no longer needed. */ - u16 *log_buf; - dma_addr_t log_buf_dma; - - u8 *smart_buf; - dma_addr_t smart_buf_dma; - unsigned long allocated[SLOTBITS_IN_LONGS]; /* * used to queue commands when an internal command is in progress @@ -403,7 +368,6 @@ struct mtip_port { * Timer used to complete commands that have been active for too long. */ struct timer_list cmd_timer; - unsigned long ic_pause_timer; /* * Semaphore used to block threads if there are no * command slots available. @@ -440,9 +404,13 @@ struct driver_data { unsigned slot_groups; /* number of slot groups the product supports */ + atomic_t drv_cleanup_done; /* Atomic variable for SRSI */ + unsigned long index; /* Index to determine the disk name */ - unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ + unsigned int ftlrebuildflag; /* FTL rebuild flag */ + + atomic_t resumeflag; /* Atomic variable to track suspend/resume */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ }; diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 0d39f2f4294a..c4a60badf252 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -351,7 +351,6 @@ static void virtblk_config_changed_work(struct work_struct *work) cap_str_10, cap_str_2); set_capacity(vblk->disk, capacity); - revalidate_disk(vblk->disk); done: mutex_unlock(&vblk->config_lock); } @@ -375,34 +374,6 @@ static int init_vq(struct virtio_blk *vblk) return err; } -/* - * Legacy naming scheme used for virtio devices. We are stuck with it for - * virtio blk but don't ever use it for any new driver. - */ -static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) -{ - const int base = 'z' - 'a' + 1; - char *begin = buf + strlen(prefix); - char *end = buf + buflen; - char *p; - int unit; - - p = end - 1; - *p = '\0'; - unit = base; - do { - if (p == begin) - return -EINVAL; - *--p = 'a' + (index % unit); - index = (index / unit) - 1; - } while (index >= 0); - - memmove(begin, p, end - p); - memcpy(buf, prefix, strlen(prefix)); - - return 0; -} - static int __devinit virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -471,7 +442,18 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) q->queuedata = vblk; - virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN); + if (index < 26) { + sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); + } else if (index < (26 + 1) * 26) { + sprintf(vblk->disk->disk_name, "vd%c%c", + 'a' + index / 26 - 1, 'a' + index % 26); + } else { + const unsigned int m1 = (index / 26 - 1) / 26 - 1; + const unsigned int m2 = (index / 26 - 1) % 26; + const unsigned int m3 = index % 26; + sprintf(vblk->disk->disk_name, "vd%c%c%c", + 'a' + m1, 'a' + m2, 'a' + m3); + } vblk->disk->major = major; vblk->disk->first_minor = index_to_minor(index); diff --git a/trunk/drivers/block/xen-blkback/blkback.c b/trunk/drivers/block/xen-blkback/blkback.c index 73f196ca713f..0088bf60f368 100644 --- a/trunk/drivers/block/xen-blkback/blkback.c +++ b/trunk/drivers/block/xen-blkback/blkback.c @@ -321,7 +321,6 @@ struct seg_buf { static void xen_blkbk_unmap(struct pending_req *req) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; grant_handle_t handle; int ret; @@ -333,12 +332,25 @@ static void xen_blkbk_unmap(struct pending_req *req) gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), GNTMAP_host_map, handle); pending_handle(req, i) = BLKBACK_INVALID_HANDLE; - pages[invcount] = virt_to_page(vaddr(req, i)); invcount++; } - ret = gnttab_unmap_refs(unmap, pages, invcount, false); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); BUG_ON(ret); + /* + * Note, we use invcount, so nr->pages, so we can't index + * using vaddr(req, i). + */ + for (i = 0; i < invcount; i++) { + ret = m2p_remove_override( + virt_to_page(unmap[i].host_addr), false); + if (ret) { + pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n", + (unsigned long)unmap[i].host_addr); + continue; + } + } } static int xen_blkbk_map(struct blkif_request *req, @@ -366,7 +378,7 @@ static int xen_blkbk_map(struct blkif_request *req, pending_req->blkif->domid); } - ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), nseg); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); BUG_ON(ret); /* @@ -386,6 +398,15 @@ static int xen_blkbk_map(struct blkif_request *req, if (ret) continue; + ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), + blkbk->pending_page(pending_req, i), NULL); + if (ret) { + pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n", + (unsigned long)map[i].dev_bus_addr, ret); + /* We could switch over to GNTTABOP_copy */ + continue; + } + seg[i].buf = map[i].dev_bus_addr | (req->u.rw.seg[i].first_sect << 9); } @@ -398,18 +419,21 @@ static int dispatch_discard_io(struct xen_blkif *blkif, int err = 0; int status = BLKIF_RSP_OKAY; struct block_device *bdev = blkif->vbd.bdev; - unsigned long secure; blkif->st_ds_req++; xen_blkif_get(blkif); - secure = (blkif->vbd.discard_secure && - (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? - BLKDEV_DISCARD_SECURE : 0; - - err = blkdev_issue_discard(bdev, req->u.discard.sector_number, - req->u.discard.nr_sectors, - GFP_KERNEL, secure); + if (blkif->blk_backend_type == BLKIF_BACKEND_PHY || + blkif->blk_backend_type == BLKIF_BACKEND_FILE) { + unsigned long secure = (blkif->vbd.discard_secure && + (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? + BLKDEV_DISCARD_SECURE : 0; + err = blkdev_issue_discard(bdev, + req->u.discard.sector_number, + req->u.discard.nr_sectors, + GFP_KERNEL, secure); + } else + err = -EOPNOTSUPP; if (err == -EOPNOTSUPP) { pr_debug(DRV_PFX "discard op failed, not supported\n"); @@ -806,7 +830,7 @@ static int __init xen_blkif_init(void) int i, mmap_pages; int rc = 0; - if (!xen_domain()) + if (!xen_pv_domain()) return -ENODEV; blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL); diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 773cf27dc23f..d0ee7edc9be8 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -146,6 +146,11 @@ enum blkif_protocol { BLKIF_PROTOCOL_X86_64 = 3, }; +enum blkif_backend_type { + BLKIF_BACKEND_PHY = 1, + BLKIF_BACKEND_FILE = 2, +}; + struct xen_vbd { /* What the domain refers to this vbd as. */ blkif_vdev_t handle; @@ -172,6 +177,7 @@ struct xen_blkif { unsigned int irq; /* Comms information. */ enum blkif_protocol blk_protocol; + enum blkif_backend_type blk_backend_type; union blkif_back_rings blk_rings; void *blk_ring; /* The VBD attached to this interface. */ diff --git a/trunk/drivers/block/xen-blkback/xenbus.c b/trunk/drivers/block/xen-blkback/xenbus.c index 4f66171c6683..24a2fb57e5d0 100644 --- a/trunk/drivers/block/xen-blkback/xenbus.c +++ b/trunk/drivers/block/xen-blkback/xenbus.c @@ -381,49 +381,72 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache", "%d", state); if (err) - dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err); + xenbus_dev_fatal(dev, err, "writing feature-flush-cache"); return err; } -static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) +int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) { struct xenbus_device *dev = be->dev; struct xen_blkif *blkif = be->blkif; + char *type; int err; int state = 0; - struct block_device *bdev = be->blkif->vbd.bdev; - struct request_queue *q = bdev_get_queue(bdev); - if (blk_queue_discard(q)) { - err = xenbus_printf(xbt, dev->nodename, - "discard-granularity", "%u", - q->limits.discard_granularity); - if (err) { - dev_warn(&dev->dev, "writing discard-granularity (%d)", err); - return; + type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL); + if (!IS_ERR(type)) { + if (strncmp(type, "file", 4) == 0) { + state = 1; + blkif->blk_backend_type = BLKIF_BACKEND_FILE; } - err = xenbus_printf(xbt, dev->nodename, - "discard-alignment", "%u", - q->limits.discard_alignment); - if (err) { - dev_warn(&dev->dev, "writing discard-alignment (%d)", err); - return; - } - state = 1; - /* Optional. */ - err = xenbus_printf(xbt, dev->nodename, - "discard-secure", "%d", - blkif->vbd.discard_secure); - if (err) { - dev_warn(&dev->dev, "writing discard-secure (%d)", err); - return; + if (strncmp(type, "phy", 3) == 0) { + struct block_device *bdev = be->blkif->vbd.bdev; + struct request_queue *q = bdev_get_queue(bdev); + if (blk_queue_discard(q)) { + err = xenbus_printf(xbt, dev->nodename, + "discard-granularity", "%u", + q->limits.discard_granularity); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard-granularity"); + goto kfree; + } + err = xenbus_printf(xbt, dev->nodename, + "discard-alignment", "%u", + q->limits.discard_alignment); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard-alignment"); + goto kfree; + } + state = 1; + blkif->blk_backend_type = BLKIF_BACKEND_PHY; + } + /* Optional. */ + err = xenbus_printf(xbt, dev->nodename, + "discard-secure", "%d", + blkif->vbd.discard_secure); + if (err) { + xenbus_dev_fatal(dev, err, + "writting discard-secure"); + goto kfree; + } } + } else { + err = PTR_ERR(type); + xenbus_dev_fatal(dev, err, "reading type"); + goto out; } + err = xenbus_printf(xbt, dev->nodename, "feature-discard", "%d", state); if (err) - dev_warn(&dev->dev, "writing feature-discard (%d)", err); + xenbus_dev_fatal(dev, err, "writing feature-discard"); +kfree: + kfree(type); +out: + return err; } int xen_blkbk_barrier(struct xenbus_transaction xbt, struct backend_info *be, int state) @@ -434,7 +457,7 @@ int xen_blkbk_barrier(struct xenbus_transaction xbt, err = xenbus_printf(xbt, dev->nodename, "feature-barrier", "%d", state); if (err) - dev_warn(&dev->dev, "writing feature-barrier (%d)", err); + xenbus_dev_fatal(dev, err, "writing feature-barrier"); return err; } @@ -666,12 +689,14 @@ static void connect(struct backend_info *be) return; } - /* If we can't advertise it is OK. */ - xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); + err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); + if (err) + goto abort; - xen_blkbk_discard(xbt, be); + err = xen_blkbk_discard(xbt, be); - xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); + /* If we can't advertise it is OK. */ + err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", (unsigned long long)vbd_sz(&be->blkif->vbd)); diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index 4e86393a09cf..98cbeba8cd53 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -82,7 +81,6 @@ static const struct block_device_operations xlvbd_block_fops; */ struct blkfront_info { - spinlock_t io_lock; struct mutex mutex; struct xenbus_device *xbdev; struct gendisk *gd; @@ -107,6 +105,8 @@ struct blkfront_info int is_ready; }; +static DEFINE_SPINLOCK(blkif_io_lock); + static unsigned int nr_minors; static unsigned long *minors; static DEFINE_SPINLOCK(minor_lock); @@ -177,7 +177,8 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) spin_lock(&minor_lock); if (find_next_bit(minors, end, minor) >= end) { - bitmap_set(minors, minor, nr); + for (; minor < end; ++minor) + __set_bit(minor, minors); rc = 0; } else rc = -EBUSY; @@ -192,7 +193,8 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr) BUG_ON(end > nr_minors); spin_lock(&minor_lock); - bitmap_clear(minors, minor, nr); + for (; minor < end; ++minor) + __clear_bit(minor, minors); spin_unlock(&minor_lock); } @@ -417,7 +419,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) struct request_queue *rq; struct blkfront_info *info = gd->private_data; - rq = blk_init_queue(do_blkif_request, &info->io_lock); + rq = blk_init_queue(do_blkif_request, &blkif_io_lock); if (rq == NULL) return -1; @@ -634,14 +636,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) if (info->rq == NULL) return; - spin_lock_irqsave(&info->io_lock, flags); + spin_lock_irqsave(&blkif_io_lock, flags); /* No more blkif_request(). */ blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); - spin_unlock_irqrestore(&info->io_lock, flags); + spin_unlock_irqrestore(&blkif_io_lock, flags); /* Flush gnttab callback work. Must be done with no locks held. */ flush_work_sync(&info->work); @@ -673,16 +675,16 @@ static void blkif_restart_queue(struct work_struct *work) { struct blkfront_info *info = container_of(work, struct blkfront_info, work); - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); if (info->connected == BLKIF_STATE_CONNECTED) kick_pending_request_queues(info); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); } static void blkif_free(struct blkfront_info *info, int suspend) { /* Prevent new requests being issued until we fix things up. */ - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); info->connected = suspend ? BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; /* No more blkif_request(). */ @@ -690,7 +692,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); /* Flush gnttab callback work. Must be done with no locks held. */ flush_work_sync(&info->work); @@ -726,10 +728,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) struct blkfront_info *info = (struct blkfront_info *)dev_id; int error; - spin_lock_irqsave(&info->io_lock, flags); + spin_lock_irqsave(&blkif_io_lock, flags); if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { - spin_unlock_irqrestore(&info->io_lock, flags); + spin_unlock_irqrestore(&blkif_io_lock, flags); return IRQ_HANDLED; } @@ -814,7 +816,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) kick_pending_request_queues(info); - spin_unlock_irqrestore(&info->io_lock, flags); + spin_unlock_irqrestore(&blkif_io_lock, flags); return IRQ_HANDLED; } @@ -989,7 +991,6 @@ static int blkfront_probe(struct xenbus_device *dev, } mutex_init(&info->mutex); - spin_lock_init(&info->io_lock); info->xbdev = dev; info->vdevice = vdevice; info->connected = BLKIF_STATE_DISCONNECTED; @@ -1067,7 +1068,7 @@ static int blkif_recover(struct blkfront_info *info) xenbus_switch_state(info->xbdev, XenbusStateConnected); - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); /* Now safe for us to use the shared ring */ info->connected = BLKIF_STATE_CONNECTED; @@ -1078,7 +1079,7 @@ static int blkif_recover(struct blkfront_info *info) /* Kick any other new requests queued since we resumed */ kick_pending_request_queues(info); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); return 0; } @@ -1276,10 +1277,10 @@ static void blkfront_connect(struct blkfront_info *info) xenbus_switch_state(info->xbdev, XenbusStateConnected); /* Kick pending requests. */ - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); info->connected = BLKIF_STATE_CONNECTED; kick_pending_request_queues(info); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); add_disk(info->gd); @@ -1409,6 +1410,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) mutex_lock(&blkfront_mutex); bdev = bdget_disk(disk, 0); + bdput(bdev); if (bdev->bd_openers) goto out; @@ -1439,7 +1441,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) } out: - bdput(bdev); mutex_unlock(&blkfront_mutex); return 0; } diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index ae9edca7b56d..48442476ec00 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -72,9 +72,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3004) }, - { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, - { USB_DEVICE(0x04CA, 0x3005) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -91,9 +89,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index 3311b812a0c6..480cad920048 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, /* Broadcom SoftSailing reporting vendor specific */ - { USB_DEVICE(0x0a5c, 0x21e1) }, + { USB_DEVICE(0x05ac, 0x21e1) }, /* Apple MacBookPro 7,1 */ { USB_DEVICE(0x05ac, 0x8213) }, @@ -103,7 +103,6 @@ static struct usb_device_id btusb_table[] = { /* Broadcom BCM20702A0 */ { USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x0a5c, 0x21e6) }, - { USB_DEVICE(0x0a5c, 0x21e8) }, { USB_DEVICE(0x0a5c, 0x21f3) }, { USB_DEVICE(0x413c, 0x8197) }, @@ -130,9 +129,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3012 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 98a8c05d4f23..fd5adb408f44 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -299,11 +299,11 @@ static void hci_uart_tty_close(struct tty_struct *tty) hci_uart_close(hdev); if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { + hu->proto->close(hu); if (hdev) { hci_unregister_dev(hdev); hci_free_dev(hdev); } - hu->proto->close(hu); } kfree(hu); diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index dfd7876f127c..3845ab44c330 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -906,8 +906,8 @@ int hpet_alloc(struct hpet_data *hdp) hpetp->hp_which, hdp->hd_phys_address, hpetp->hp_ntimer > 1 ? "s" : ""); for (i = 0; i < hpetp->hp_ntimer; i++) - printk(KERN_CONT "%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); - printk(KERN_CONT "\n"); + printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); + printk("\n"); temp = hpetp->hp_tick_freq; remainder = do_div(temp, 1000000); diff --git a/trunk/drivers/char/hw_random/Kconfig b/trunk/drivers/char/hw_random/Kconfig index b2402eb076c7..0689bf6b0183 100644 --- a/trunk/drivers/char/hw_random/Kconfig +++ b/trunk/drivers/char/hw_random/Kconfig @@ -62,7 +62,7 @@ config HW_RANDOM_AMD config HW_RANDOM_ATMEL tristate "Atmel Random Number Generator support" - depends on HW_RANDOM && HAVE_CLK + depends on HW_RANDOM && ARCH_AT91SAM9G45 default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 4ec04a754733..54ca8b23cde3 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1260,15 +1260,10 @@ static int proc_do_uuid(ctl_table *table, int write, uuid = table->data; if (!uuid) { uuid = tmp_uuid; - generate_random_uuid(uuid); - } else { - static DEFINE_SPINLOCK(bootid_spinlock); - - spin_lock(&bootid_spinlock); - if (!uuid[8]) - generate_random_uuid(uuid); - spin_unlock(&bootid_spinlock); + uuid[8] = 0; } + if (uuid[8] == 0) + generate_random_uuid(uuid); sprintf(buf, "%pU", uuid); diff --git a/trunk/drivers/clocksource/Kconfig b/trunk/drivers/clocksource/Kconfig index 99c6b203e6cd..5138927a416c 100644 --- a/trunk/drivers/clocksource/Kconfig +++ b/trunk/drivers/clocksource/Kconfig @@ -18,7 +18,7 @@ config DW_APB_TIMER config CLKSRC_DBX500_PRCMU bool "Clocksource PRCMU Timer" - depends on UX500_SOC_DB8500 + depends on UX500_SOC_DB5500 || UX500_SOC_DB8500 default y help Use the always on PRCMU Timer as clocksource diff --git a/trunk/drivers/clocksource/acpi_pm.c b/trunk/drivers/clocksource/acpi_pm.c index 6b5cf02c35c8..82e882028fcf 100644 --- a/trunk/drivers/clocksource/acpi_pm.c +++ b/trunk/drivers/clocksource/acpi_pm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* @@ -179,17 +180,15 @@ static int verify_pmtmr_rate(void) /* Number of reads we try to get two different values */ #define ACPI_PM_READ_CHECKS 10000 -static int __init init_acpi_pm_clocksource(void) +static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie) { cycle_t value1, value2; unsigned int i, j = 0; - if (!pmtmr_ioport) - return -ENODEV; /* "verify" this timing source: */ for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { - udelay(100 * j); + usleep_range(100 * j, 100 * j + 100); value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); @@ -203,25 +202,34 @@ static int __init init_acpi_pm_clocksource(void) " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); pmtmr_ioport = 0; - return -EINVAL; + return; } if (i == ACPI_PM_READ_CHECKS) { printk(KERN_INFO "PM-Timer failed consistency check " " (0x%#llx) - aborting.\n", value1); pmtmr_ioport = 0; - return -ENODEV; + return; } } if (verify_pmtmr_rate() != 0){ pmtmr_ioport = 0; - return -ENODEV; + return; } - return clocksource_register_hz(&clocksource_acpi_pm, + clocksource_register_hz(&clocksource_acpi_pm, PMTMR_TICKS_PER_SEC); } +static int __init init_acpi_pm_clocksource(void) +{ + if (!pmtmr_ioport) + return -ENODEV; + + async_schedule(acpi_pm_clocksource_async, NULL); + return 0; +} + /* We use fs_initcall because we want the PCI fixups to have run * but we still need to load before device_initcall */ diff --git a/trunk/drivers/cpufreq/Kconfig.arm b/trunk/drivers/cpufreq/Kconfig.arm index 5961e6415f08..ffbb44685915 100644 --- a/trunk/drivers/cpufreq/Kconfig.arm +++ b/trunk/drivers/cpufreq/Kconfig.arm @@ -4,7 +4,6 @@ config ARM_OMAP2PLUS_CPUFREQ bool "TI OMAP2+" - depends on ARCH_OMAP2PLUS default ARCH_OMAP2PLUS select CPU_FREQ_TABLE diff --git a/trunk/drivers/crypto/ixp4xx_crypto.c b/trunk/drivers/crypto/ixp4xx_crypto.c index 8f3f74ce8c7f..0053d7ebb5ca 100644 --- a/trunk/drivers/crypto/ixp4xx_crypto.c +++ b/trunk/drivers/crypto/ixp4xx_crypto.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/crypto/talitos.c b/trunk/drivers/crypto/talitos.c index 921039e56f87..dc641c796526 100644 --- a/trunk/drivers/crypto/talitos.c +++ b/trunk/drivers/crypto/talitos.c @@ -124,9 +124,6 @@ struct talitos_private { void __iomem *reg; int irq[2]; - /* SEC global registers lock */ - spinlock_t reg_lock ____cacheline_aligned; - /* SEC version geometry (from device tree node) */ unsigned int num_channels; unsigned int chfifo_len; @@ -415,7 +412,6 @@ static void talitos_done_##name(unsigned long data) \ { \ struct device *dev = (struct device *)data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ - unsigned long flags; \ \ if (ch_done_mask & 1) \ flush_channel(dev, 0, 0, 0); \ @@ -431,10 +427,8 @@ static void talitos_done_##name(unsigned long data) \ out: \ /* At this point, all completed channels have been processed */ \ /* Unmask done interrupts for channels completed later on. */ \ - spin_lock_irqsave(&priv->reg_lock, flags); \ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ } DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) @@ -625,28 +619,22 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ struct device *dev = data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ u32 isr, isr_lo; \ - unsigned long flags; \ \ - spin_lock_irqsave(&priv->reg_lock, flags); \ isr = in_be32(priv->reg + TALITOS_ISR); \ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ /* Acknowledge interrupt */ \ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ \ - if (unlikely(isr & ch_err_mask || isr_lo)) { \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ - } \ - else { \ + if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \ + talitos_error(dev, isr, isr_lo); \ + else \ if (likely(isr & ch_done_mask)) { \ /* mask further done interrupts. */ \ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ /* done_task will unmask done interrupts at exit */ \ tasklet_schedule(&priv->done_task[tlet]); \ } \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ - } \ \ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ IRQ_NONE; \ @@ -2731,8 +2719,6 @@ static int talitos_probe(struct platform_device *ofdev) priv->ofdev = ofdev; - spin_lock_init(&priv->reg_lock); - err = talitos_probe_irq(ofdev); if (err) goto err_out; diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index ef378b5b17e4..cf9da362d64f 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -91,10 +91,11 @@ config DW_DMAC config AT_HDMAC tristate "Atmel AHB DMA support" - depends on ARCH_AT91 + depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 select DMA_ENGINE help - Support the Atmel AHB DMA controller. + Support the Atmel AHB DMA controller. This can be integrated in + chips such as the Atmel AT91SAM9RL. config FSL_DMA tristate "Freescale Elo and Elo Plus DMA support" diff --git a/trunk/drivers/dma/dmaengine.c b/trunk/drivers/dma/dmaengine.c index 2397f6f451b1..767bcc31b365 100644 --- a/trunk/drivers/dma/dmaengine.c +++ b/trunk/drivers/dma/dmaengine.c @@ -332,20 +332,6 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) } EXPORT_SYMBOL(dma_find_channel); -/* - * net_dma_find_channel - find a channel for net_dma - * net_dma has alignment requirements - */ -struct dma_chan *net_dma_find_channel(void) -{ - struct dma_chan *chan = dma_find_channel(DMA_MEMCPY); - if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1)) - return NULL; - - return chan; -} -EXPORT_SYMBOL(net_dma_find_channel); - /** * dma_issue_pending_all - flush all pending operations across all channels */ diff --git a/trunk/drivers/dma/ioat/dma.c b/trunk/drivers/dma/ioat/dma.c index 73b2b65cb1de..31493d80e0e9 100644 --- a/trunk/drivers/dma/ioat/dma.c +++ b/trunk/drivers/dma/ioat/dma.c @@ -546,9 +546,9 @@ void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, PCI_DMA_TODEVICE, flags, 0); } -dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan) +unsigned long ioat_get_current_completion(struct ioat_chan_common *chan) { - dma_addr_t phys_complete; + unsigned long phys_complete; u64 completion; completion = *chan->completion; @@ -569,7 +569,7 @@ dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan) } bool ioat_cleanup_preamble(struct ioat_chan_common *chan, - dma_addr_t *phys_complete) + unsigned long *phys_complete) { *phys_complete = ioat_get_current_completion(chan); if (*phys_complete == chan->last_completion) @@ -580,14 +580,14 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, return true; } -static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete) +static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete) { struct ioat_chan_common *chan = &ioat->base; struct list_head *_desc, *n; struct dma_async_tx_descriptor *tx; - dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n", - __func__, (unsigned long long) phys_complete); + dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n", + __func__, phys_complete); list_for_each_safe(_desc, n, &ioat->used_desc) { struct ioat_desc_sw *desc; @@ -652,7 +652,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete) static void ioat1_cleanup(struct ioat_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; prefetch(chan->completion); @@ -698,7 +698,7 @@ static void ioat1_timer_event(unsigned long data) mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); spin_unlock_bh(&ioat->desc_lock); } else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { - dma_addr_t phys_complete; + unsigned long phys_complete; spin_lock_bh(&ioat->desc_lock); /* if we haven't made progress and we have already diff --git a/trunk/drivers/dma/ioat/dma.h b/trunk/drivers/dma/ioat/dma.h index 5e8fe01ba69d..c7888bccd974 100644 --- a/trunk/drivers/dma/ioat/dma.h +++ b/trunk/drivers/dma/ioat/dma.h @@ -88,7 +88,7 @@ struct ioatdma_device { struct ioat_chan_common { struct dma_chan common; void __iomem *reg_base; - dma_addr_t last_completion; + unsigned long last_completion; spinlock_t cleanup_lock; unsigned long state; #define IOAT_COMPLETION_PENDING 0 @@ -310,7 +310,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device); void __devexit ioat_dma_remove(struct ioatdma_device *device); struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase); -dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan); +unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx); enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, @@ -318,7 +318,7 @@ enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, size_t len, struct ioat_dma_descriptor *hw); bool ioat_cleanup_preamble(struct ioat_chan_common *chan, - dma_addr_t *phys_complete); + unsigned long *phys_complete); void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); void ioat_kobject_del(struct ioatdma_device *device); extern const struct sysfs_ops ioat_sysfs_ops; diff --git a/trunk/drivers/dma/ioat/dma_v2.c b/trunk/drivers/dma/ioat/dma_v2.c index 86895760b598..e8e110ff3d96 100644 --- a/trunk/drivers/dma/ioat/dma_v2.c +++ b/trunk/drivers/dma/ioat/dma_v2.c @@ -128,7 +128,7 @@ static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat) spin_unlock_bh(&ioat->prep_lock); } -static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) +static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) { struct ioat_chan_common *chan = &ioat->base; struct dma_async_tx_descriptor *tx; @@ -179,7 +179,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) static void ioat2_cleanup(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; spin_lock_bh(&chan->cleanup_lock); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -260,7 +260,7 @@ int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo) static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; ioat2_quiesce(chan, 0); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -275,7 +275,7 @@ void ioat2_timer_event(unsigned long data) struct ioat_chan_common *chan = &ioat->base; if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { - dma_addr_t phys_complete; + unsigned long phys_complete; u64 status; status = ioat_chansts(chan); @@ -572,9 +572,9 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order) */ struct ioat_chan_common *chan = &ioat->base; struct dma_chan *c = &chan->common; - const u32 curr_size = ioat2_ring_size(ioat); + const u16 curr_size = ioat2_ring_size(ioat); const u16 active = ioat2_ring_active(ioat); - const u32 new_size = 1 << order; + const u16 new_size = 1 << order; struct ioat_ring_ent **ring; u16 i; diff --git a/trunk/drivers/dma/ioat/dma_v2.h b/trunk/drivers/dma/ioat/dma_v2.h index be2a55b95c23..a2c413b2b8d8 100644 --- a/trunk/drivers/dma/ioat/dma_v2.h +++ b/trunk/drivers/dma/ioat/dma_v2.h @@ -74,7 +74,7 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) return container_of(chan, struct ioat2_dma_chan, base); } -static inline u32 ioat2_ring_size(struct ioat2_dma_chan *ioat) +static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat) { return 1 << ioat->alloc_order; } @@ -91,7 +91,7 @@ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat) return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat)); } -static inline u32 ioat2_ring_space(struct ioat2_dma_chan *ioat) +static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) { return ioat2_ring_size(ioat) - ioat2_ring_active(ioat); } diff --git a/trunk/drivers/dma/ioat/dma_v3.c b/trunk/drivers/dma/ioat/dma_v3.c index f7f1dc62c15c..2c4476c0e405 100644 --- a/trunk/drivers/dma/ioat/dma_v3.c +++ b/trunk/drivers/dma/ioat/dma_v3.c @@ -257,7 +257,7 @@ static bool desc_has_ext(struct ioat_ring_ent *desc) * The difference from the dma_v2.c __cleanup() is that this routine * handles extended descriptors and dma-unmapping raid operations. */ -static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) +static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) { struct ioat_chan_common *chan = &ioat->base; struct ioat_ring_ent *desc; @@ -314,7 +314,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) static void ioat3_cleanup(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; spin_lock_bh(&chan->cleanup_lock); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -333,7 +333,7 @@ static void ioat3_cleanup_event(unsigned long data) static void ioat3_restart_channel(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; ioat2_quiesce(chan, 0); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -348,7 +348,7 @@ static void ioat3_timer_event(unsigned long data) struct ioat_chan_common *chan = &ioat->base; if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { - dma_addr_t phys_complete; + unsigned long phys_complete; u64 status; status = ioat_chansts(chan); @@ -1149,44 +1149,6 @@ static int ioat3_reset_hw(struct ioat_chan_common *chan) return ioat2_reset_sync(chan, msecs_to_jiffies(200)); } -static bool is_jf_ioat(struct pci_dev *pdev) -{ - switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_IOAT_JSF0: - case PCI_DEVICE_ID_INTEL_IOAT_JSF1: - case PCI_DEVICE_ID_INTEL_IOAT_JSF2: - case PCI_DEVICE_ID_INTEL_IOAT_JSF3: - case PCI_DEVICE_ID_INTEL_IOAT_JSF4: - case PCI_DEVICE_ID_INTEL_IOAT_JSF5: - case PCI_DEVICE_ID_INTEL_IOAT_JSF6: - case PCI_DEVICE_ID_INTEL_IOAT_JSF7: - case PCI_DEVICE_ID_INTEL_IOAT_JSF8: - case PCI_DEVICE_ID_INTEL_IOAT_JSF9: - return true; - default: - return false; - } -} - -static bool is_snb_ioat(struct pci_dev *pdev) -{ - switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_IOAT_SNB0: - case PCI_DEVICE_ID_INTEL_IOAT_SNB1: - case PCI_DEVICE_ID_INTEL_IOAT_SNB2: - case PCI_DEVICE_ID_INTEL_IOAT_SNB3: - case PCI_DEVICE_ID_INTEL_IOAT_SNB4: - case PCI_DEVICE_ID_INTEL_IOAT_SNB5: - case PCI_DEVICE_ID_INTEL_IOAT_SNB6: - case PCI_DEVICE_ID_INTEL_IOAT_SNB7: - case PCI_DEVICE_ID_INTEL_IOAT_SNB8: - case PCI_DEVICE_ID_INTEL_IOAT_SNB9: - return true; - default: - return false; - } -} - int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) { struct pci_dev *pdev = device->pdev; @@ -1207,9 +1169,6 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; dma->device_free_chan_resources = ioat2_free_chan_resources; - if (is_jf_ioat(pdev) || is_snb_ioat(pdev)) - dma->copy_align = 6; - dma_cap_set(DMA_INTERRUPT, dma->cap_mask); dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock; diff --git a/trunk/drivers/dma/iop-adma.c b/trunk/drivers/dma/iop-adma.c index 79e3eba29702..da6c4c2c066a 100644 --- a/trunk/drivers/dma/iop-adma.c +++ b/trunk/drivers/dma/iop-adma.c @@ -1252,8 +1252,8 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) struct page **pq_hw = &pq[IOP_ADMA_NUM_SRC_TEST+2]; /* address conversion buffers (dma_map / page_address) */ void *pq_sw[IOP_ADMA_NUM_SRC_TEST+2]; - dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST+2]; - dma_addr_t *pq_dest = &pq_src[IOP_ADMA_NUM_SRC_TEST]; + dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST]; + dma_addr_t pq_dest[2]; int i; struct dma_async_tx_descriptor *tx; diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index e03653d69357..edadbdad31d0 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -430,7 +430,7 @@ config GPIO_ML_IOH config GPIO_SODAVILLE bool "Intel Sodaville GPIO support" - depends on X86 && PCI && OF + depends on X86 && PCI && OF && BROKEN select GPIO_GENERIC select GENERIC_IRQ_CHIP help diff --git a/trunk/drivers/gpio/gpio-adp5588.c b/trunk/drivers/gpio/gpio-adp5588.c index ae5d7f12ce66..9ad1703d1408 100644 --- a/trunk/drivers/gpio/gpio-adp5588.c +++ b/trunk/drivers/gpio/gpio-adp5588.c @@ -252,7 +252,7 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid) if (ret < 0) memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat)); - for (bank = 0, bit = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); + for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); bank++, bit = 0) { pending = dev->irq_stat[bank] & dev->irq_mask[bank]; diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index 19d6fc0229c3..46277877b7ec 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -2382,8 +2382,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { #endif }; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_1[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPA0(0), @@ -2541,11 +2541,11 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { .to_irq = samsung_gpiolib_to_irq, }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_2[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPE0(0), @@ -2602,11 +2602,11 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = { }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_3[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPV0(0), @@ -2638,11 +2638,11 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = { .label = "GPV4", }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_4[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPZ(0), @@ -2650,8 +2650,8 @@ static struct samsung_gpio_chip exynos5_gpios_4[] = { .label = "GPZ", }, }, -}; #endif +}; #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) diff --git a/trunk/drivers/gpio/gpio-sodaville.c b/trunk/drivers/gpio/gpio-sodaville.c index 031e5d24837d..9ba15d31d242 100644 --- a/trunk/drivers/gpio/gpio-sodaville.c +++ b/trunk/drivers/gpio/gpio-sodaville.c @@ -41,7 +41,7 @@ struct sdv_gpio_chip_data { int irq_base; void __iomem *gpio_pub_base; - struct irq_domain *id; + struct irq_domain id; struct irq_chip_generic *gc; struct bgpio_chip bgpio; }; @@ -51,9 +51,10 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct sdv_gpio_chip_data *sd = gc->private; void __iomem *type_reg; + u32 irq_offs = d->irq - sd->irq_base; u32 reg; - if (d->hwirq < 8) + if (irq_offs < 8) type_reg = sd->gpio_pub_base + GPIT1R0; else type_reg = sd->gpio_pub_base + GPIT1R1; @@ -62,11 +63,11 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) switch (type) { case IRQ_TYPE_LEVEL_HIGH: - reg &= ~BIT(4 * (d->hwirq % 8)); + reg &= ~BIT(4 * (irq_offs % 8)); break; case IRQ_TYPE_LEVEL_LOW: - reg |= BIT(4 * (d->hwirq % 8)); + reg |= BIT(4 * (irq_offs % 8)); break; default: @@ -90,7 +91,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) u32 irq_bit = __fls(irq_stat); irq_stat &= ~BIT(irq_bit); - generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); + generic_handle_irq(sd->irq_base + irq_bit); } return IRQ_HANDLED; @@ -126,7 +127,7 @@ static int sdv_xlate(struct irq_domain *h, struct device_node *node, } static struct irq_domain_ops irq_domain_sdv_ops = { - .xlate = sdv_xlate, + .dt_translate = sdv_xlate, }; static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, @@ -148,6 +149,10 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, if (ret) goto out_free_desc; + sd->id.irq_base = sd->irq_base; + sd->id.of_node = of_node_get(pdev->dev.of_node); + sd->id.ops = &irq_domain_sdv_ops; + /* * This gpio irq controller latches level irqs. Testing shows that if * we unmask & ACK the IRQ before the source of the interrupt is gone @@ -174,10 +179,7 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); - sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS, - sd->irq_base, 0, &irq_domain_sdv_ops, sd); - if (!sd->id) - goto out_free_irq; + irq_domain_add(&sd->id); return 0; out_free_irq: free_irq(pdev->irq, sd); @@ -258,6 +260,7 @@ static void sdv_gpio_remove(struct pci_dev *pdev) { struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev); + irq_domain_del(&sd->id); free_irq(pdev->irq, sd); irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); diff --git a/trunk/drivers/gpu/drm/drm_bufs.c b/trunk/drivers/gpu/drm/drm_bufs.c index 348b367debeb..30372f7b2d45 100644 --- a/trunk/drivers/gpu/drm/drm_bufs.c +++ b/trunk/drivers/gpu/drm/drm_bufs.c @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, * \param arg pointer to a drm_buf_map structure. * \return zero on success or a negative number on failure. * - * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls vm_mmap() with + * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls do_mmap() with * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ @@ -1553,14 +1553,18 @@ int drm_mapbufs(struct drm_device *dev, void *data, retcode = -EINVAL; goto done; } - virtual = vm_mmap(file_priv->filp, 0, map->size, + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(file_priv->filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, token); + up_write(¤t->mm->mmap_sem); } else { - virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(file_priv->filp, 0, dma->byte_count, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); } if (virtual > -1024UL) { /* Real error */ diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index c79870a75c2f..d3aaeb6ae236 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -3335,12 +3335,10 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ret = crtc->funcs->page_flip(crtc, fb, e); if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); - } + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); } out: diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 123de28f94ef..cdfbf27b2b3c 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp) drm_events_release(file_priv); - if (dev->driver->driver_features & DRIVER_MODESET) - drm_fb_release(file_priv); - if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); + if (dev->driver->driver_features & DRIVER_MODESET) + drm_fb_release(file_priv); + mutex_lock(&dev->ctxlist_mutex); if (!list_empty(&dev->ctxlist)) { struct drm_ctx_list *pos, *n; diff --git a/trunk/drivers/gpu/drm/drm_usb.c b/trunk/drivers/gpu/drm/drm_usb.c index 37c9a523dd1c..c8c83dad2ce1 100644 --- a/trunk/drivers/gpu/drm/drm_usb.c +++ b/trunk/drivers/gpu/drm/drm_usb.c @@ -1,6 +1,6 @@ #include "drmP.h" #include -#include +#include int drm_get_usb_dev(struct usb_interface *interface, const struct usb_device_id *id, @@ -114,7 +114,3 @@ void drm_usb_exit(struct drm_driver *driver, usb_deregister(udriver); } EXPORT_SYMBOL(drm_usb_exit); - -MODULE_AUTHOR("David Airlie"); -MODULE_DESCRIPTION("USB DRM support"); -MODULE_LICENSE("GPL and additional rights"); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c index de8d2090bce3..4a3a5f72ed4a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -34,14 +34,14 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, unsigned int flags, struct exynos_drm_gem_buf *buf) { - dma_addr_t start_addr; + dma_addr_t start_addr, end_addr; unsigned int npages, page_size, i = 0; struct scatterlist *sgl; int ret = 0; DRM_DEBUG_KMS("%s\n", __FILE__); - if (IS_NONCONTIG_BUFFER(flags)) { + if (flags & EXYNOS_BO_NONCONTIG) { DRM_DEBUG_KMS("not support allocation type.\n"); return -EINVAL; } @@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, } if (buf->size >= SZ_1M) { - npages = buf->size >> SECTION_SHIFT; + npages = (buf->size >> SECTION_SHIFT) + 1; page_size = SECTION_SIZE; } else if (buf->size >= SZ_64K) { - npages = buf->size >> 16; + npages = (buf->size >> 16) + 1; page_size = SZ_64K; } else { - npages = buf->size >> PAGE_SHIFT; + npages = (buf->size >> PAGE_SHIFT) + 1; page_size = PAGE_SIZE; } @@ -76,13 +76,26 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, return -ENOMEM; } - buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL); - if (!buf->kvaddr) { - DRM_ERROR("failed to allocate buffer.\n"); - ret = -ENOMEM; - goto err1; - } + buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, + &buf->dma_addr, GFP_KERNEL); + if (!buf->kvaddr) { + DRM_ERROR("failed to allocate buffer.\n"); + ret = -ENOMEM; + goto err1; + } + + start_addr = buf->dma_addr; + end_addr = buf->dma_addr + buf->size; + + buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); + if (!buf->pages) { + DRM_ERROR("failed to allocate pages.\n"); + ret = -ENOMEM; + goto err2; + } + + start_addr = buf->dma_addr; + end_addr = buf->dma_addr + buf->size; buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); if (!buf->pages) { @@ -92,17 +105,23 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, } sgl = buf->sgt->sgl; - start_addr = buf->dma_addr; while (i < npages) { buf->pages[i] = phys_to_page(start_addr); sg_set_page(sgl, buf->pages[i], page_size, 0); sg_dma_address(sgl) = start_addr; start_addr += page_size; + if (end_addr - start_addr < page_size) + break; sgl = sg_next(sgl); i++; } + buf->pages[i] = phys_to_page(start_addr); + + sgl = sg_next(sgl); + sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0); + DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->kvaddr, (unsigned long)buf->dma_addr, @@ -131,7 +150,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, * non-continuous memory would be released by exynos * gem framework. */ - if (IS_NONCONTIG_BUFFER(flags)) { + if (flags & EXYNOS_BO_NONCONTIG) { DRM_DEBUG_KMS("not support allocation type.\n"); return; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c index eaf630dc5dba..411832e8e17a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -54,18 +54,16 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev, * * P.S. note that this driver is considered for modularization. */ - ret = subdrv->probe(dev, subdrv->dev); + ret = subdrv->probe(dev, subdrv->manager.dev); if (ret) return ret; } - if (!subdrv->manager) + if (subdrv->is_local) return 0; - subdrv->manager->dev = subdrv->dev; - /* create and initialize a encoder for this sub driver. */ - encoder = exynos_drm_encoder_create(dev, subdrv->manager, + encoder = exynos_drm_encoder_create(dev, &subdrv->manager, (1 << MAX_CRTC) - 1); if (!encoder) { DRM_ERROR("failed to create encoder\n"); @@ -188,7 +186,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { if (subdrv->open) { - ret = subdrv->open(dev, subdrv->dev, file); + ret = subdrv->open(dev, subdrv->manager.dev, file); if (ret) goto err; } @@ -199,7 +197,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) err: list_for_each_entry_reverse(subdrv, &subdrv->list, list) { if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); + subdrv->close(dev, subdrv->manager.dev, file); } return ret; } @@ -211,7 +209,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); + subdrv->close(dev, subdrv->manager.dev, file); } } EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h index 1d814175cd49..fbd0a232c93d 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -225,25 +225,24 @@ struct exynos_drm_private { * Exynos drm sub driver structure. * * @list: sub driver has its own list object to register to exynos drm driver. - * @dev: pointer to device object for subdrv device driver. * @drm_dev: pointer to drm_device and this pointer would be set * when sub driver calls exynos_drm_subdrv_register(). - * @manager: subdrv has its own manager to control a hardware appropriately - * and we can access a hardware drawing on this manager. + * @is_local: appear encoder and connector disrelated device. * @probe: this callback would be called by exynos drm driver after * subdrv is registered to it. * @remove: this callback is used to release resources created * by probe callback. * @open: this would be called with drm device file open. * @close: this would be called with drm device file close. + * @manager: subdrv has its own manager to control a hardware appropriately + * and we can access a hardware drawing on this manager. * @encoder: encoder object owned by this sub driver. * @connector: connector object owned by this sub driver. */ struct exynos_drm_subdrv { struct list_head list; - struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_manager *manager; + bool is_local; int (*probe)(struct drm_device *drm_dev, struct device *dev); void (*remove)(struct drm_device *dev); @@ -252,6 +251,7 @@ struct exynos_drm_subdrv { void (*close)(struct drm_device *drm_dev, struct device *dev, struct drm_file *file); + struct exynos_drm_manager manager; struct drm_encoder *encoder; struct drm_connector *connector; }; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 29fdbfeb43cb..ecb6db229700 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) static void fimd_apply(struct device *subdrv_dev) { struct fimd_context *ctx = get_fimd_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; + struct exynos_drm_manager *mgr = &ctx->subdrv.manager; struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; struct fimd_win_data *win_data; @@ -577,13 +577,6 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = { .disable = fimd_win_disable, }; -static struct exynos_drm_manager fimd_manager = { - .pipe = -1, - .ops = &fimd_manager_ops, - .overlay_ops = &fimd_overlay_ops, - .display_ops = &fimd_display_ops, -}; - static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) { struct exynos_drm_private *dev_priv = drm_dev->dev_private; @@ -635,7 +628,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) struct fimd_context *ctx = (struct fimd_context *)dev_id; struct exynos_drm_subdrv *subdrv = &ctx->subdrv; struct drm_device *drm_dev = subdrv->drm_dev; - struct exynos_drm_manager *manager = subdrv->manager; + struct exynos_drm_manager *manager = &subdrv->manager; u32 val; val = readl(ctx->regs + VIDINTCON1); @@ -751,7 +744,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) static int fimd_power_on(struct fimd_context *ctx, bool enable) { struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; + struct device *dev = subdrv->manager.dev; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -874,10 +867,13 @@ static int __devinit fimd_probe(struct platform_device *pdev) subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &fimd_manager; subdrv->probe = fimd_subdrv_probe; subdrv->remove = fimd_subdrv_remove; + subdrv->manager.pipe = -1; + subdrv->manager.ops = &fimd_manager_ops; + subdrv->manager.overlay_ops = &fimd_overlay_ops; + subdrv->manager.display_ops = &fimd_display_ops; + subdrv->manager.dev = dev; mutex_init(&ctx->lock); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c index 392ce71ed6a1..fa1aa94a3d8e 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -56,28 +56,9 @@ static unsigned int convert_to_vm_err_msg(int msg) return out_msg; } -static int check_gem_flags(unsigned int flags) +static unsigned int mask_gem_flags(unsigned int flags) { - if (flags & ~(EXYNOS_BO_MASK)) { - DRM_ERROR("invalid flags.\n"); - return -EINVAL; - } - - return 0; -} - -static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) -{ - if (!IS_NONCONTIG_BUFFER(flags)) { - if (size >= SZ_1M) - return roundup(size, SECTION_SIZE); - else if (size >= SZ_64K) - return roundup(size, SZ_64K); - else - goto out; - } -out: - return roundup(size, PAGE_SIZE); + return flags &= EXYNOS_BO_NONCONTIG; } static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, @@ -338,17 +319,10 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, struct exynos_drm_gem_buf *buf; int ret; - if (!size) { - DRM_ERROR("invalid size.\n"); - return ERR_PTR(-EINVAL); - } + size = roundup(size, PAGE_SIZE); + DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); - size = roundup_gem_size(size, flags); - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = check_gem_flags(flags); - if (ret) - return ERR_PTR(ret); + flags = mask_gem_flags(flags); buf = exynos_drm_init_buf(dev, size); if (!buf) @@ -357,7 +331,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, exynos_gem_obj = exynos_drm_gem_init(dev, size); if (!exynos_gem_obj) { ret = -ENOMEM; - goto err_fini_buf; + goto err; } exynos_gem_obj->buffer = buf; @@ -373,19 +347,18 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); if (ret < 0) { drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; + goto err; } } else { ret = exynos_drm_alloc_buf(dev, buf, flags); if (ret < 0) { drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; + goto err; } } return exynos_gem_obj; - -err_fini_buf: +err: exynos_drm_fini_buf(dev, buf); return ERR_PTR(ret); } @@ -581,8 +554,10 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, obj->filp->f_op = &exynos_drm_gem_fops; obj->filp->private_data = obj; - addr = vm_mmap(obj->filp, 0, args->size, + down_write(¤t->mm->mmap_sem); + addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h index 4ed842039505..e40fbad8b705 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -29,8 +29,6 @@ #define to_exynos_gem_obj(x) container_of(x,\ struct exynos_drm_gem_obj, base) -#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) - /* * exynos drm gem buffer structure. * diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 3424463676e0..14eb26b0ba1c 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -30,8 +30,9 @@ struct drm_hdmi_context, subdrv); /* these callback points shoud be set by specific drivers. */ -static struct exynos_hdmi_ops *hdmi_ops; -static struct exynos_mixer_ops *mixer_ops; +static struct exynos_hdmi_display_ops *hdmi_display_ops; +static struct exynos_hdmi_manager_ops *hdmi_manager_ops; +static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops; struct drm_hdmi_context { struct exynos_drm_subdrv subdrv; @@ -39,20 +40,31 @@ struct drm_hdmi_context { struct exynos_drm_hdmi_context *mixer_ctx; }; -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) +void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops + *display_ops) { DRM_DEBUG_KMS("%s\n", __FILE__); - if (ops) - hdmi_ops = ops; + if (display_ops) + hdmi_display_ops = display_ops; } -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops) +void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops + *manager_ops) { DRM_DEBUG_KMS("%s\n", __FILE__); - if (ops) - mixer_ops = ops; + if (manager_ops) + hdmi_manager_ops = manager_ops; +} + +void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops + *overlay_ops) +{ + DRM_DEBUG_KMS("%s\n", __FILE__); + + if (overlay_ops) + hdmi_overlay_ops = overlay_ops; } static bool drm_hdmi_is_connected(struct device *dev) @@ -61,8 +73,8 @@ static bool drm_hdmi_is_connected(struct device *dev) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->is_connected) - return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); + if (hdmi_display_ops && hdmi_display_ops->is_connected) + return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx); return false; } @@ -74,9 +86,9 @@ static int drm_hdmi_get_edid(struct device *dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->get_edid) - return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, - len); + if (hdmi_display_ops && hdmi_display_ops->get_edid) + return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx, + connector, edid, len); return 0; } @@ -87,8 +99,9 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->check_timing) - return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); + if (hdmi_display_ops && hdmi_display_ops->check_timing) + return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx, + timing); return 0; } @@ -99,8 +112,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->power_on) - return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); + if (hdmi_display_ops && hdmi_display_ops->power_on) + return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode); return 0; } @@ -117,13 +130,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev) { struct drm_hdmi_context *ctx = to_context(subdrv_dev); struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; + struct exynos_drm_manager *manager = &subdrv->manager; DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->enable_vblank) - return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, - manager->pipe); + if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank) + return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx, + manager->pipe); return 0; } @@ -134,8 +147,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev) DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->disable_vblank) - return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); + if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank) + return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx); } static void drm_hdmi_mode_fixup(struct device *subdrv_dev, @@ -147,9 +160,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->mode_fixup) - hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, - adjusted_mode); + if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup) + hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, + mode, adjusted_mode); } static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) @@ -158,8 +171,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->mode_set) - hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); + if (hdmi_manager_ops && hdmi_manager_ops->mode_set) + hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode); } static void drm_hdmi_get_max_resol(struct device *subdrv_dev, @@ -169,8 +182,9 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->get_max_resol) - hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); + if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol) + hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, + height); } static void drm_hdmi_commit(struct device *subdrv_dev) @@ -179,8 +193,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->commit) - hdmi_ops->commit(ctx->hdmi_ctx->ctx); + if (hdmi_manager_ops && hdmi_manager_ops->commit) + hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx); } static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) @@ -195,8 +209,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (hdmi_ops && hdmi_ops->disable) - hdmi_ops->disable(ctx->hdmi_ctx->ctx); + if (hdmi_manager_ops && hdmi_manager_ops->disable) + hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx); break; default: DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); @@ -221,8 +235,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->win_mode_set) - mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); + if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set) + hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); } static void drm_mixer_commit(struct device *subdrv_dev, int zpos) @@ -231,8 +245,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos) DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->win_commit) - mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); + if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit) + hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos); } static void drm_mixer_disable(struct device *subdrv_dev, int zpos) @@ -241,8 +255,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos) DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->win_disable) - mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); + if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable) + hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos); } static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { @@ -251,12 +265,6 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { .disable = drm_mixer_disable, }; -static struct exynos_drm_manager hdmi_manager = { - .pipe = -1, - .ops = &drm_hdmi_manager_ops, - .overlay_ops = &drm_hdmi_overlay_ops, - .display_ops = &drm_hdmi_display_ops, -}; static int hdmi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) @@ -324,9 +332,12 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &hdmi_manager; subdrv->probe = hdmi_subdrv_probe; + subdrv->manager.pipe = -1; + subdrv->manager.ops = &drm_hdmi_manager_ops; + subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops; + subdrv->manager.display_ops = &drm_hdmi_display_ops; + subdrv->manager.dev = dev; platform_set_drvdata(pdev, subdrv); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index f3ae192c8dcf..44497cfb6c74 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context { void *ctx; }; -struct exynos_hdmi_ops { - /* display */ +struct exynos_hdmi_display_ops { bool (*is_connected)(void *ctx); int (*get_edid)(void *ctx, struct drm_connector *connector, u8 *edid, int len); int (*check_timing)(void *ctx, void *timing); int (*power_on)(void *ctx, int mode); +}; - /* manager */ +struct exynos_hdmi_manager_ops { void (*mode_fixup)(void *ctx, struct drm_connector *connector, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); @@ -57,17 +57,22 @@ struct exynos_hdmi_ops { void (*disable)(void *ctx); }; -struct exynos_mixer_ops { - /* manager */ +struct exynos_hdmi_overlay_ops { int (*enable_vblank)(void *ctx, int pipe); void (*disable_vblank)(void *ctx); - - /* overlay */ void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); void (*win_commit)(void *ctx, int zpos); void (*win_disable)(void *ctx, int zpos); }; -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); +extern struct platform_driver hdmi_driver; +extern struct platform_driver mixer_driver; + +void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops + *display_ops); +void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops + *manager_ops); +void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops + *overlay_ops); + #endif diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c index f92fe4c6174a..c277a3a445f5 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -24,10 +24,6 @@ struct exynos_plane { static const uint32_t formats[] = { DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV12M, - DRM_FORMAT_NV12MT, }; static int diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 7b9c153dceb6..8e1339f9fe1f 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode) static void vidi_apply(struct device *subdrv_dev) { struct vidi_context *ctx = get_vidi_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; + struct exynos_drm_manager *mgr = &ctx->subdrv.manager; struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; struct vidi_win_data *win_data; @@ -374,13 +374,6 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = { .disable = vidi_win_disable, }; -static struct exynos_drm_manager vidi_manager = { - .pipe = -1, - .ops = &vidi_manager_ops, - .overlay_ops = &vidi_overlay_ops, - .display_ops = &vidi_display_ops, -}; - static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) { struct exynos_drm_private *dev_priv = drm_dev->dev_private; @@ -432,7 +425,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) struct vidi_context *ctx = container_of(work, struct vidi_context, work); struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; + struct exynos_drm_manager *manager = &subdrv->manager; if (manager->pipe < 0) return; @@ -478,7 +471,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev) static int vidi_power_on(struct vidi_context *ctx, bool enable) { struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; + struct device *dev = subdrv->manager.dev; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -618,10 +611,13 @@ static int __devinit vidi_probe(struct platform_device *pdev) ctx->raw_edid = (struct edid *)fake_edid_info; subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &vidi_manager; subdrv->probe = vidi_subdrv_probe; subdrv->remove = vidi_subdrv_remove; + subdrv->manager.pipe = -1; + subdrv->manager.ops = &vidi_manager_ops; + subdrv->manager.overlay_ops = &vidi_overlay_ops; + subdrv->manager.display_ops = &vidi_display_ops; + subdrv->manager.dev = dev; mutex_init(&ctx->lock); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c index b00353876458..575a8cbd3533 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -40,6 +40,7 @@ #include "exynos_hdmi.h" +#define HDMI_OVERLAY_NUMBER 3 #define MAX_WIDTH 1920 #define MAX_HEIGHT 1080 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) @@ -1193,7 +1194,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata, static bool hdmi_is_connected(void *ctx) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); if (val) @@ -1206,7 +1207,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector, u8 *edid, int len) { struct edid *raw_edid; - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1274,7 +1275,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing) static int hdmi_check_timing(void *ctx, void *timing) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; struct fb_videomode *check_timing = timing; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1311,6 +1312,13 @@ static int hdmi_display_power_on(void *ctx, int mode) return 0; } +static struct exynos_hdmi_display_ops display_ops = { + .is_connected = hdmi_is_connected, + .get_edid = hdmi_get_edid, + .check_timing = hdmi_check_timing, + .power_on = hdmi_display_power_on, +}; + static void hdmi_set_acr(u32 freq, u8 *acr) { u32 n, cts; @@ -1906,7 +1914,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, struct drm_display_mode *adjusted_mode) { struct drm_display_mode *m; - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; int index; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1943,7 +1951,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, static void hdmi_mode_set(void *ctx, void *mode) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; int conf_idx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1966,7 +1974,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width, static void hdmi_commit(void *ctx) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1977,7 +1985,7 @@ static void hdmi_commit(void *ctx) static void hdmi_disable(void *ctx) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1988,14 +1996,7 @@ static void hdmi_disable(void *ctx) } } -static struct exynos_hdmi_ops hdmi_ops = { - /* display */ - .is_connected = hdmi_is_connected, - .get_edid = hdmi_get_edid, - .check_timing = hdmi_check_timing, - .power_on = hdmi_display_power_on, - - /* manager */ +static struct exynos_hdmi_manager_ops manager_ops = { .mode_fixup = hdmi_mode_fixup, .mode_set = hdmi_mode_set, .get_max_resol = hdmi_get_max_resol, @@ -2019,7 +2020,7 @@ static void hdmi_hotplug_func(struct work_struct *work) static irqreturn_t hdmi_irq_handler(int irq, void *arg) { struct exynos_drm_hdmi_context *ctx = arg; - struct hdmi_context *hdata = ctx->ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; u32 intc_flag; intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); @@ -2172,7 +2173,7 @@ static int hdmi_runtime_suspend(struct device *dev) DRM_DEBUG_KMS("%s\n", __func__); - hdmi_resource_poweroff(ctx->ctx); + hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx); return 0; } @@ -2183,7 +2184,7 @@ static int hdmi_runtime_resume(struct device *dev) DRM_DEBUG_KMS("%s\n", __func__); - hdmi_resource_poweron(ctx->ctx); + hdmi_resource_poweron((struct hdmi_context *)ctx->ctx); return 0; } @@ -2321,7 +2322,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev) hdata->irq = res->start; /* register specific callbacks to common hdmi. */ - exynos_hdmi_ops_register(&hdmi_ops); + exynos_drm_display_ops_register(&display_ops); + exynos_drm_manager_ops_register(&manager_ops); hdmi_resource_poweron(hdata); @@ -2349,7 +2351,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) static int __devexit hdmi_remove(struct platform_device *pdev) { struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); - struct hdmi_context *hdata = ctx->ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index e15438c01129..4d5f41e19527 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -37,8 +37,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_hdmi.h" -#define MIXER_WIN_NR 3 -#define MIXER_DEFAULT_WIN 0 +#define HDMI_OVERLAY_NUMBER 3 #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) @@ -76,12 +75,16 @@ struct mixer_resources { }; struct mixer_context { + struct fb_videomode *default_timing; + unsigned int default_win; + unsigned int default_bpp; unsigned int irq; int pipe; bool interlace; + bool vp_enabled; struct mixer_resources mixer_res; - struct hdmi_win_data win_data[MIXER_WIN_NR]; + struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER]; }; static const u8 filter_y_horiz_tap8[] = { @@ -640,9 +643,9 @@ static void mixer_win_mode_set(void *ctx, win = overlay->zpos; if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; + win = mixer_ctx->default_win; - if (win < 0 || win > MIXER_WIN_NR) { + if (win < 0 || win > HDMI_OVERLAY_NUMBER) { DRM_ERROR("overlay plane[%d] is wrong\n", win); return; } @@ -680,9 +683,9 @@ static void mixer_win_commit(void *ctx, int zpos) DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; + win = mixer_ctx->default_win; - if (win < 0 || win > MIXER_WIN_NR) { + if (win < 0 || win > HDMI_OVERLAY_NUMBER) { DRM_ERROR("overlay plane[%d] is wrong\n", win); return; } @@ -703,9 +706,9 @@ static void mixer_win_disable(void *ctx, int zpos) DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; + win = mixer_ctx->default_win; - if (win < 0 || win > MIXER_WIN_NR) { + if (win < 0 || win > HDMI_OVERLAY_NUMBER) { DRM_ERROR("overlay plane[%d] is wrong\n", win); return; } @@ -719,12 +722,9 @@ static void mixer_win_disable(void *ctx, int zpos) spin_unlock_irqrestore(&res->reg_slock, flags); } -static struct exynos_mixer_ops mixer_ops = { - /* manager */ +static struct exynos_hdmi_overlay_ops overlay_ops = { .enable_vblank = mixer_enable_vblank, .disable_vblank = mixer_disable_vblank, - - /* overlay */ .win_mode_set = mixer_win_mode_set, .win_commit = mixer_win_commit, .win_disable = mixer_win_disable, @@ -771,7 +771,8 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) static irqreturn_t mixer_irq_handler(int irq, void *arg) { struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; - struct mixer_context *ctx = drm_hdmi_ctx->ctx; + struct mixer_context *ctx = + (struct mixer_context *)drm_hdmi_ctx->ctx; struct mixer_resources *res = &ctx->mixer_res; u32 val, val_base; @@ -901,7 +902,7 @@ static int mixer_runtime_resume(struct device *dev) DRM_DEBUG_KMS("resume - start\n"); - mixer_resource_poweron(ctx->ctx); + mixer_resource_poweron((struct mixer_context *)ctx->ctx); return 0; } @@ -912,7 +913,7 @@ static int mixer_runtime_suspend(struct device *dev) DRM_DEBUG_KMS("suspend - start\n"); - mixer_resource_poweroff(ctx->ctx); + mixer_resource_poweroff((struct mixer_context *)ctx->ctx); return 0; } @@ -925,7 +926,8 @@ static const struct dev_pm_ops mixer_pm_ops = { static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, struct platform_device *pdev) { - struct mixer_context *mixer_ctx = ctx->ctx; + struct mixer_context *mixer_ctx = + (struct mixer_context *)ctx->ctx; struct device *dev = &pdev->dev; struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; struct resource *res; @@ -1074,7 +1076,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) goto fail; /* register specific callback point to common hdmi. */ - exynos_mixer_ops_register(&mixer_ops); + exynos_drm_overlay_ops_register(&overlay_ops); mixer_resource_poweron(ctx); @@ -1091,7 +1093,7 @@ static int mixer_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; struct exynos_drm_hdmi_context *drm_hdmi_ctx = platform_get_drvdata(pdev); - struct mixer_context *ctx = drm_hdmi_ctx->ctx; + struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; dev_info(dev, "remove successful\n"); diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 36eb0744841c..21071cef92a4 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h @@ -29,6 +29,7 @@ #define __MDFLD_DSI_OUTPUT_H__ #include +#include #include #include #include diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c index f920fb5e42b6..2c8a60c3b98e 100644 --- a/trunk/drivers/gpu/drm/i810/i810_dma.c +++ b/trunk/drivers/gpu/drm/i810/i810_dma.c @@ -129,7 +129,6 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) if (buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; - /* This is all entirely broken */ down_write(¤t->mm->mmap_sem); old_fops = file_priv->filp->f_op; file_priv->filp->f_op = &i810_buffer_fops; @@ -158,8 +157,11 @@ static int i810_unmap_buffer(struct drm_buf *buf) if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; - retcode = vm_munmap((unsigned long)buf_priv->virtual, + down_write(¤t->mm->mmap_sem); + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, (size_t) buf->total); + up_write(¤t->mm->mmap_sem); buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = NULL; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index ae8a64f9f845..dfa55e7478fb 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores, "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); int i915_enable_rc6 __read_mostly = -1; -module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); +module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); MODULE_PARM_DESC(i915_enable_rc6, "Enable power-saving render C-state 6. " "Different stages can be selected via bitmask values " diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 0d1e4b7b4b99..4c65c639f772 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1087,9 +1087,11 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - addr = vm_mmap(obj->filp, 0, args->size, + down_write(¤t->mm->mmap_sem); + addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, args->offset); + up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); if (IS_ERR((void *)addr)) return addr; @@ -1491,7 +1493,6 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) { list_del_init(&obj->ring_list); obj->last_rendering_seqno = 0; - obj->last_fenced_seqno = 0; } static void @@ -1520,7 +1521,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) BUG_ON(!list_empty(&obj->gpu_write_list)); BUG_ON(!obj->active); obj->ring = NULL; - obj->last_fenced_ring = NULL; i915_gem_object_move_off_active(obj); obj->fenced_gpu_access = false; diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index b4bb1ef77ddc..2abf4eb94039 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -3728,9 +3728,6 @@ #define GT_FIFO_FREE_ENTRIES 0x120008 #define GT_FIFO_NUM_RESERVED_ENTRIES 20 -#define GEN6_UCGCTL1 0x9400 -# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5) - #define GEN6_UCGCTL2 0x9404 # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 5908cd563400..91b35fd1db8c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -2244,33 +2244,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, return 0; } -static int -intel_finish_fb(struct drm_framebuffer *old_fb) -{ - struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - bool was_interruptible = dev_priv->mm.interruptible; - int ret; - - wait_event(dev_priv->pending_flip_queue, - atomic_read(&dev_priv->mm.wedged) || - atomic_read(&obj->pending_flip) == 0); - - /* Big Hammer, we also need to ensure that any pending - * MI_WAIT_FOR_EVENT inside a user batch buffer on the - * current scanout is retired before unpinning the old - * framebuffer. - * - * This should only fail upon a hung GPU, in which case we - * can safely continue. - */ - dev_priv->mm.interruptible = false; - ret = i915_gem_object_finish_gpu(obj); - dev_priv->mm.interruptible = was_interruptible; - - return ret; -} - static int intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) @@ -2309,8 +2282,25 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - if (old_fb) - intel_finish_fb(old_fb); + if (old_fb) { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; + + wait_event(dev_priv->pending_flip_queue, + atomic_read(&dev_priv->mm.wedged) || + atomic_read(&obj->pending_flip) == 0); + + /* Big Hammer, we also need to ensure that any pending + * MI_WAIT_FOR_EVENT inside a user batch buffer on the + * current scanout is retired before unpinning the old + * framebuffer. + * + * This should only fail upon a hung GPU, in which case we + * can safely continue. + */ + ret = i915_gem_object_finish_gpu(obj); + (void) ret; + } ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, LEAVE_ATOMIC_MODE_SET); @@ -3381,23 +3371,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc) struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; struct drm_device *dev = crtc->dev; - /* Flush any pending WAITs before we disable the pipe. Note that - * we need to drop the struct_mutex in order to acquire it again - * during the lowlevel dpms routines around a couple of the - * operations. It does not look trivial nor desirable to move - * that locking higher. So instead we leave a window for the - * submission of further commands on the fb before we can actually - * disable it. This race with userspace exists anyway, and we can - * only rely on the pipe being disabled by userspace after it - * receives the hotplug notification and has flushed any pending - * batches. - */ - if (crtc->fb) { - mutex_lock(&dev->struct_mutex); - intel_finish_fb(crtc->fb); - mutex_unlock(&dev->struct_mutex); - } - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); @@ -3478,11 +3451,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, return false; } - /* All interlaced capable intel hw wants timings in frames. Note though - * that intel_lvds_mode_fixup does some funny tricks with the crtc - * timings, so we need to be careful not to clobber these.*/ - if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) - drm_mode_set_crtcinfo(adjusted_mode, 0); + /* All interlaced capable intel hw wants timings in frames. */ + drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } @@ -7468,13 +7438,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, OUT_RING(fb->pitches[0] | obj->tiling_mode); OUT_RING(obj->gtt_offset); - /* Contrary to the suggestions in the documentation, - * "Enable Panel Fitter" does not seem to be required when page - * flipping with a non-native mode, and worse causes a normal - * modeset to fail. - * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; - */ - pf = 0; + pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; OUT_RING(pf | pipesrc); ADVANCE_LP_RING(); @@ -8565,10 +8529,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - I915_WRITE(GEN6_UCGCTL1, - I915_READ(GEN6_UCGCTL1) | - GEN6_BLBUNIT_CLOCK_GATE_DISABLE); - /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock * gating disable must be set. Failure to set it results in * flickering pixels due to Z write ordering failures after diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 4b637919f74f..110552ff302c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -219,38 +219,14 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) return (max_link_clock * max_lanes * 8) / 10; } -static bool -intel_dp_adjust_dithering(struct intel_dp *intel_dp, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); - int max_lanes = intel_dp_max_lane_count(intel_dp); - int max_rate, mode_rate; - - mode_rate = intel_dp_link_required(mode->clock, 24); - max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); - - if (mode_rate > max_rate) { - mode_rate = intel_dp_link_required(mode->clock, 18); - if (mode_rate > max_rate) - return false; - - if (adjusted_mode) - adjusted_mode->private_flags - |= INTEL_MODE_DP_FORCE_6BPC; - - return true; - } - - return true; -} - static int intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct intel_dp *intel_dp = intel_attached_dp(connector); + int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); + int max_lanes = intel_dp_max_lane_count(intel_dp); + int max_rate, mode_rate; if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) @@ -260,8 +236,16 @@ intel_dp_mode_valid(struct drm_connector *connector, return MODE_PANEL; } - if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) - return MODE_CLOCK_HIGH; + mode_rate = intel_dp_link_required(mode->clock, 24); + max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); + + if (mode_rate > max_rate) { + mode_rate = intel_dp_link_required(mode->clock, 18); + if (mode_rate > max_rate) + return MODE_CLOCK_HIGH; + else + mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC; + } if (mode->clock < 10000) return MODE_CLOCK_LOW; @@ -688,7 +672,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, int lane_count, clock; int max_lane_count = intel_dp_max_lane_count(intel_dp); int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; - int bpp; + int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { @@ -702,11 +686,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, mode->clock = intel_dp->panel_fixed_mode->clock; } - if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) - return false; - - bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 715afa153025..5a14149b3794 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -105,10 +105,6 @@ #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) #define INTEL_MODE_DP_FORCE_6BPC (0x10) -/* This flag must be set by the encoder's mode_fixup if it changes the crtc - * timings in the mode to prevent the crtc fixup from overwriting them. - * Currently only lvds needs that. */ -#define INTEL_MODE_CRTC_TIMINGS_SET (0x20) static inline void intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index 6e9ee33fd412..19ecd78b8a2c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -279,8 +279,6 @@ void intel_fb_restore_mode(struct drm_device *dev) struct drm_mode_config *config = &dev->mode_config; struct drm_plane *plane; - mutex_lock(&dev->mode_config.mutex); - ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); if (ret) DRM_DEBUG("failed to restore crtc mode\n"); @@ -288,6 +286,4 @@ void intel_fb_restore_mode(struct drm_device *dev) /* Be sure to shut off any planes that may be active */ list_for_each_entry(plane, &config->plane_list, head) plane->funcs->disable_plane(plane); - - mutex_unlock(&dev->mode_config.mutex); } diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index 8fdc95700218..601c86e664af 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev) bus->has_gpio = intel_gpio_setup(bus, i); /* XXX force bit banging until GMBUS is fully debugged */ - if (bus->has_gpio) + if (bus->has_gpio && IS_GEN2(dev)) bus->force_bit = true; } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 30e2c82101de..95db2e988227 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -187,8 +187,6 @@ centre_horizontally(struct drm_display_mode *mode, mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static void @@ -210,8 +208,6 @@ centre_vertically(struct drm_display_mode *mode, mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static inline u32 panel_fitter_scaling(u32 source, u32 target) @@ -287,8 +283,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, for_each_pipe(pipe) I915_WRITE(BCLRPAT(pipe), 0); - drm_mode_set_crtcinfo(adjusted_mode, 0); - switch (intel_lvds->fitting_mode) { case DRM_MODE_SCALE_CENTER: /* diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index 48177ec4720e..230a141dbea3 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -47,6 +47,8 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, adjusted_mode->vtotal = fixed_mode->vtotal; adjusted_mode->clock = fixed_mode->clock; + + drm_mode_set_crtcinfo(adjusted_mode, 0); } /* adjusted_mode has been preset to be the panel's fixed mode */ diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index f75806e5bff5..e25581a9f60f 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1038,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev, * of the buffer. */ ring->effective_size = ring->size; - if (IS_I830(ring->dev) || IS_845G(ring->dev)) + if (IS_I830(ring->dev)) ring->effective_size -= 128; return 0; diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index e90dfb625c42..a464771a7240 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -95,6 +95,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, /* must disable */ sprctl |= SPRITE_TRICKLE_FEED_DISABLE; sprctl |= SPRITE_ENABLE; + sprctl |= SPRITE_DEST_KEY; /* Sizes are 0 based */ src_w--; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index da3e7c3abab7..34d591b7d4ef 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -235,7 +235,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) return -EPERM; strncpy(string, profile, sizeof(string)); - string[sizeof(string) - 1] = 0; if ((ptr = strchr(string, '\n'))) *ptr = '\0'; diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_sor.c b/trunk/drivers/gpu/drm/nouveau/nv50_sor.c index 274640212475..a7844ab6a50c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_sor.c @@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) struct drm_nouveau_private *dev_priv = dev->dev_private; static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ static const u8 nv50[] = { 16, 8, 0, 24 }; - if (dev_priv->chipset == 0xaf) + if (dev_priv->card_type == 0xaf) return nvaf[lane]; return nv50[lane]; } diff --git a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c index 2d39f9977e00..e607c4d7dd98 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c @@ -230,10 +230,6 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) return; - /* some R4xx chips have the wrong frev */ - if (rdev->family <= CHIP_RV410) - frev = 1; - switch (frev) { case 1: switch (crev) { diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index fe33d35dae8c..81801c176aa5 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev) * or the chip could hang on a subsequent access */ if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { - mdelay(5); + udelay(5000); } /* This function is required to workaround a hardware bug in some (all?) diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index c8187c4b6ae8..391bd2636a80 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end + 1; + mc->vram_start = mc->gtt_end; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", @@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev) /* r7xx asics need to soft reset RLC before halting */ WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); RREG32(SRBM_SOFT_RESET); - mdelay(15); + udelay(15000); WREG32(SRBM_SOFT_RESET, 0); RREG32(SRBM_SOFT_RESET); } diff --git a/trunk/drivers/gpu/drm/radeon/r600_cp.c b/trunk/drivers/gpu/drm/radeon/r600_cp.c index 75ed17c96115..84c546250955 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cp.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cp.c @@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); + DRM_UDELAY(15000); RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); fw_data = (const __be32 *)dev_priv->me_fw->data; @@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); + DRM_UDELAY(15000); RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); fw_data = (const __be32 *)dev_priv->pfp_fw->data; @@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); + DRM_UDELAY(15000); RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_clocks.c b/trunk/drivers/gpu/drm/radeon/radeon_clocks.c index 9c6b29a41927..6ae0c75f016a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_clocks.c @@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp &= ~(R300_SCLK_FORCE_VAP); tmp |= RADEON_SCLK_FORCE_CP; WREG32_PLL(RADEON_SCLK_CNTL, tmp); - mdelay(15); + udelay(15000); tmp = RREG32_PLL(R300_SCLK_CNTL2); tmp &= ~(R300_SCLK_FORCE_TCL | @@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp |= (RADEON_ENGIN_DYNCLK_MODE | (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); - mdelay(15); + udelay(15000); tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); tmp |= RADEON_SCLK_DYN_START_CNTL; WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); - mdelay(15); + udelay(15000); /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 to lockup randomly, leave them as set by BIOS. @@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp |= RADEON_SCLK_MORE_FORCEON; } WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - mdelay(15); + udelay(15000); } /* RV200::A11 A12, RV250::A11 A12 */ @@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp |= RADEON_TCL_BYPASS_DISABLE; WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); } - mdelay(15); + udelay(15000); /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); @@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) RADEON_PIXCLK_TMDS_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - mdelay(15); + udelay(15000); tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); tmp |= (RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb); WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - mdelay(15); + udelay(15000); } } else { /* Turn everything OFF (ForceON to everything) */ @@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) } WREG32_PLL(RADEON_SCLK_CNTL, tmp); - mdelay(16); + udelay(16000); if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) { @@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA); WREG32_PLL(R300_SCLK_CNTL2, tmp); - mdelay(16); + udelay(16000); } if (rdev->flags & RADEON_IS_IGP) { @@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp &= ~(RADEON_FORCEON_MCLKA | RADEON_FORCEON_YCLKA); WREG32_PLL(RADEON_MCLK_CNTL, tmp); - mdelay(16); + udelay(16000); } if ((rdev->family == CHIP_RV200) || @@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); tmp |= RADEON_SCLK_MORE_FORCEON; WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - mdelay(16); + udelay(16000); } tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); @@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) RADEON_PIXCLK_TMDS_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - mdelay(16); + udelay(16000); tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index 2cad9fde92fc..81fc100be7e1 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) case 4: val = RBIOS16(index); index += 2; - mdelay(val); + udelay(val * 1000); break; case 6: slave_addr = id & 0xff; @@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) udelay(150); break; case 2: - mdelay(1); + udelay(1000); break; case 3: while (tmp--) { @@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) /*mclk_cntl |= 0x00001111;*//* ??? */ WREG32_PLL(RADEON_MCLK_CNTL, mclk_cntl); - mdelay(10); + udelay(10000); #endif WREG32_PLL (RADEON_CLK_PWRMGT_CNTL, tmp & ~RADEON_CG_NO1_DEBUG_0); - mdelay(10); + udelay(10000); } break; default: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index 3c2e7a000a2a..bd05156edbdb 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder = obj_to_encoder(obj); - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && + if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) continue; @@ -1000,7 +1000,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) * cases the DVI port is actually a virtual KVM port connected to the service * processor. */ -out: if ((!rdev->is_atom_bios) && (ret == connector_status_disconnected) && rdev->mode_info.bios_hardcoded_edid_size) { @@ -1008,6 +1007,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_connected; } +out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); return ret; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c index 3edec1c198e3..85bcfc8923a7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c @@ -900,10 +900,6 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_chan *i2c; int ret; - /* don't add the mm_i2c bus unless hw_i2c is enabled */ - if (rec->mm_i2c && (radeon_hw_i2c == 0)) - return NULL; - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); if (i2c == NULL) return NULL; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c index 65060b77c805..66d5fe1c8174 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -147,12 +147,6 @@ static bool radeon_msi_ok(struct radeon_device *rdev) (rdev->pdev->subsystem_device == 0x01fd)) return true; - /* RV515 seems to have MSI issues where it loses - * MSI rearms occasionally. This leads to lockups and freezes. - * disable it by default. - */ - if (rdev->family == CHIP_RV515) - return false; if (rdev->flags & RADEON_IS_IGP) { /* APUs work fine with MSIs */ if (rdev->family >= CHIP_PALM) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 42db254f6bb0..2f46e0c8df53 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); lvds_pll_cntl |= RADEON_LVDS_PLL_EN; WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - mdelay(1); + udelay(1000); lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; @@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); if (is_mac) lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; - mdelay(panel_pwr_delay); + udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); break; case DRM_MODE_DPMS_STANDBY: @@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); } - mdelay(panel_pwr_delay); + udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - mdelay(panel_pwr_delay); + udelay(panel_pwr_delay * 1000); break; } @@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc WREG32(RADEON_DAC_MACRO_CNTL, tmp); - mdelay(2); + udelay(2000); if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) found = connector_status_connected; @@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; WREG32(RADEON_DAC_CNTL2, tmp); - mdelay(10); + udelay(10000); if (ASIC_IS_R300(rdev)) { if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index cdab1aeaed6e..c62ae4be3845 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end + 1; + mc->vram_start = mc->gtt_end; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 27bda986fc2b..ac7a199ffece 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_gpu_addr); - radeon_bo_unreserve(rdev->rlc.save_restore_obj); if (r) { + radeon_bo_unreserve(rdev->rlc.save_restore_obj); dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); si_rlc_fini(rdev); return r; @@ -3023,8 +3023,9 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_gpu_addr); - radeon_bo_unreserve(rdev->rlc.clear_state_obj); if (r) { + + radeon_bo_unreserve(rdev->rlc.clear_state_obj); dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); si_rlc_fini(rdev); return r; diff --git a/trunk/drivers/gpu/drm/savage/savage_state.c b/trunk/drivers/gpu/drm/savage/savage_state.c index b6d8608375cd..031aaaf79ac2 100644 --- a/trunk/drivers/gpu/drm/savage/savage_state.c +++ b/trunk/drivers/gpu/drm/savage/savage_state.c @@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ * for locking on FreeBSD. */ if (cmdbuf->size) { - kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL); + kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL); if (kcmd_addr == NULL) return -ENOMEM; @@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ cmdbuf->vb_addr = kvb_addr; } if (cmdbuf->nbox) { - kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect), - GFP_KERNEL); + kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), + GFP_KERNEL); if (kbox_addr == NULL) { ret = -ENOMEM; goto done; diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index ffddcba32af6..a3d033252995 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -34,7 +34,7 @@ config HID config HID_BATTERY_STRENGTH bool depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY - default n + default y config HIDRAW bool "/dev/hidraw raw HID device support" diff --git a/trunk/drivers/hid/hid-tivo.c b/trunk/drivers/hid/hid-tivo.c index 9f85f827607f..de47039c708c 100644 --- a/trunk/drivers/hid/hid-tivo.c +++ b/trunk/drivers/hid/hid-tivo.c @@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id tivo_devices[] = { /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, { } }; diff --git a/trunk/drivers/hwmon/acpi_power_meter.c b/trunk/drivers/hwmon/acpi_power_meter.c index 9140236a0182..145f13580ff0 100644 --- a/trunk/drivers/hwmon/acpi_power_meter.c +++ b/trunk/drivers/hwmon/acpi_power_meter.c @@ -391,7 +391,6 @@ static ssize_t show_str(struct device *dev, break; default: BUG(); - val = ""; } return sprintf(buf, "%s\n", val); diff --git a/trunk/drivers/hwmon/ads1015.c b/trunk/drivers/hwmon/ads1015.c index 1958f03efd7a..7765e4f74ec5 100644 --- a/trunk/drivers/hwmon/ads1015.c +++ b/trunk/drivers/hwmon/ads1015.c @@ -59,11 +59,14 @@ struct ads1015_data { struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; }; -static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) +static int ads1015_read_value(struct i2c_client *client, unsigned int channel, + int *value) { u16 config; + s16 conversion; struct ads1015_data *data = i2c_get_clientdata(client); unsigned int pga = data->channel_data[channel].pga; + int fullscale; unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int conversion_time_ms; int res; @@ -75,6 +78,7 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) if (res < 0) goto err_unlock; config = res; + fullscale = fullscale_table[pga]; conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); /* setup and start single conversion */ @@ -101,20 +105,19 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) } res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); + if (res < 0) + goto err_unlock; + conversion = res; -err_unlock: mutex_unlock(&data->update_lock); - return res; -} -static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, - s16 reg) -{ - struct ads1015_data *data = i2c_get_clientdata(client); - unsigned int pga = data->channel_data[channel].pga; - int fullscale = fullscale_table[pga]; + *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); + + return 0; - return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +err_unlock: + mutex_unlock(&data->update_lock); + return res; } /* sysfs callback function */ @@ -123,14 +126,12 @@ static ssize_t show_in(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); + int in; int res; - int index = attr->index; - res = ads1015_read_adc(client, index); - if (res < 0) - return res; + res = ads1015_read_value(client, attr->index, &in); - return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res)); + return (res < 0) ? res : sprintf(buf, "%d\n", in); } static const struct sensor_device_attribute ads1015_in[] = { diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index 37a8fc92b44a..b7494af1e4a9 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -122,38 +122,6 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) return true; } -/* - * Newer BKDG versions have an updated recommendation on how to properly - * initialize the running average range (was: 0xE, now: 0x9). This avoids - * counter saturations resulting in bogus power readings. - * We correct this value ourselves to cope with older BIOSes. - */ -static void __devinit tweak_runavg_range(struct pci_dev *pdev) -{ - u32 val; - const struct pci_device_id affected_device = { - PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }; - - /* - * let this quirk apply only to the current version of the - * northbridge, since future versions may change the behavior - */ - if (!pci_match_id(&affected_device, pdev)) - return; - - pci_bus_read_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, &val); - if ((val & 0xf) != 0xe) - return; - - val &= ~0xf; - val |= 0x9; - pci_bus_write_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, val); -} - static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -187,13 +155,6 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; int err; - /* - * though we ignore every other northbridge, we still have to - * do the tweaking on _each_ node in MCM processors as the counters - * are working hand-in-hand - */ - tweak_runavg_range(pdev); - if (!fam15h_power_is_internal_node0(pdev)) { err = -ENODEV; goto exit; diff --git a/trunk/drivers/hwmon/pmbus/pmbus_core.c b/trunk/drivers/hwmon/pmbus/pmbus_core.c index 29b319db573e..be51037363c8 100644 --- a/trunk/drivers/hwmon/pmbus/pmbus_core.c +++ b/trunk/drivers/hwmon/pmbus/pmbus_core.c @@ -710,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data, * If a negative value is stored in any of the referenced registers, this value * reflects an error code which will be returned. */ -static int pmbus_get_boolean(struct pmbus_data *data, int index) +static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) { u8 s1 = (index >> 24) & 0xff; u8 s2 = (index >> 16) & 0xff; u8 reg = (index >> 8) & 0xff; u8 mask = index & 0xff; - int ret, status; + int status; u8 regval; status = data->status[reg]; @@ -725,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index) regval = status & mask; if (!s1 && !s2) - ret = !!regval; + *val = !!regval; else { long v1, v2; struct pmbus_sensor *sensor1, *sensor2; @@ -739,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index) v1 = pmbus_reg2data(data, sensor1); v2 = pmbus_reg2data(data, sensor2); - ret = !!(regval && v1 >= v2); + *val = !!(regval && v1 >= v2); } - return ret; + return 0; } static ssize_t pmbus_show_boolean(struct device *dev, @@ -750,10 +750,11 @@ static ssize_t pmbus_show_boolean(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct pmbus_data *data = pmbus_update_device(dev); int val; + int err; - val = pmbus_get_boolean(data, attr->index); - if (val < 0) - return val; + err = pmbus_get_boolean(data, attr->index, &val); + if (err) + return err; return snprintf(buf, PAGE_SIZE, "%d\n", val); } diff --git a/trunk/drivers/hwmon/smsc47b397.c b/trunk/drivers/hwmon/smsc47b397.c index c5f6be478bad..d3b778da3f86 100644 --- a/trunk/drivers/hwmon/smsc47b397.c +++ b/trunk/drivers/hwmon/smsc47b397.c @@ -343,11 +343,10 @@ static int __init smsc47b397_device_add(unsigned short address) return err; } -static int __init smsc47b397_find(void) +static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; char *name; - unsigned short addr; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -371,14 +370,14 @@ static int __init smsc47b397_find(void) rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); - addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) + *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); pr_info("found SMSC %s (base address 0x%04x, revision %u)\n", - name, addr, rev); + name, *addr, rev); superio_exit(); - return addr; + return 0; } static int __init smsc47b397_init(void) @@ -386,10 +385,9 @@ static int __init smsc47b397_init(void) unsigned short address; int ret; - ret = smsc47b397_find(); - if (ret < 0) + ret = smsc47b397_find(&address); + if (ret) return ret; - address = ret; ret = platform_driver_register(&smsc47b397_driver); if (ret) diff --git a/trunk/drivers/hwmon/smsc47m1.c b/trunk/drivers/hwmon/smsc47m1.c index b5aa38dd7ab9..c590c1469793 100644 --- a/trunk/drivers/hwmon/smsc47m1.c +++ b/trunk/drivers/hwmon/smsc47m1.c @@ -491,10 +491,10 @@ static const struct attribute_group smsc47m1_group = { .attrs = smsc47m1_attributes, }; -static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) +static int __init smsc47m1_find(unsigned short *addr, + struct smsc47m1_sio_data *sio_data) { u8 val; - unsigned short addr; superio_enter(); val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -546,9 +546,9 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) } superio_select(); - addr = (superio_inb(SUPERIO_REG_BASE) << 8) + *addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); - if (addr == 0) { + if (*addr == 0) { pr_info("Device address not set, will not use\n"); superio_exit(); return -ENODEV; @@ -565,7 +565,7 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) } superio_exit(); - return addr; + return 0; } /* Restore device to its initial state */ @@ -938,15 +938,13 @@ static int __init sm_smsc47m1_init(void) unsigned short address; struct smsc47m1_sio_data sio_data; - err = smsc47m1_find(&sio_data); - if (err < 0) - return err; - address = err; + if (smsc47m1_find(&address, &sio_data)) + return -ENODEV; /* Sets global pdev as a side effect */ err = smsc47m1_device_add(address, &sio_data); if (err) - return err; + goto exit; err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe); if (err) @@ -957,6 +955,7 @@ static int __init sm_smsc47m1_init(void) exit_device: platform_device_unregister(pdev); smsc47m1_restore(&sio_data); +exit: return err; } diff --git a/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c b/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c index 00e8f213f56e..37f42113af31 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -182,6 +182,7 @@ static int i2c_dw_pci_resume(struct device *dev) pci_restore_state(pdev); i2c_dw_init(i2c); + i2c_dw_enable(i2c); return 0; } diff --git a/trunk/drivers/infiniband/core/sysfs.c b/trunk/drivers/infiniband/core/sysfs.c index 246fdc151652..83b720ef6c34 100644 --- a/trunk/drivers/infiniband/core/sysfs.c +++ b/trunk/drivers/infiniband/core/sysfs.c @@ -179,7 +179,7 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, { struct ib_port_attr attr; char *speed = ""; - int rate; /* in deci-Gb/sec */ + int rate = -1; /* in deci-Gb/sec */ ssize_t ret; ret = ib_query_port(p->ibdev, p->port_num, &attr); @@ -187,6 +187,9 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, return ret; switch (attr.active_speed) { + case IB_SPEED_SDR: + rate = 25; + break; case IB_SPEED_DDR: speed = " DDR"; rate = 50; @@ -207,10 +210,6 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, speed = " EDR"; rate = 250; break; - case IB_SPEED_SDR: - default: /* default to SDR for invalid rates */ - rate = 25; - break; } rate *= ib_width_enum_to_int(attr.active_width); diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index 669673e81439..75d305629300 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -253,11 +253,6 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port, if (out_mad->data[15] & 0x1) props->active_speed = IB_SPEED_FDR10; } - - /* Avoid wrong speed value returned by FW if the IB link is down. */ - if (props->state == IB_PORT_DOWN) - props->active_speed = IB_SPEED_SDR; - out: kfree(in_mad); kfree(out_mad); diff --git a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c index daf21b899999..69e2ad06e515 100644 --- a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3232,7 +3232,6 @@ static void srpt_add_one(struct ib_device *device) srq_attr.attr.max_wr = sdev->srq_size; srq_attr.attr.max_sge = 1; srq_attr.attr.srq_limit = 0; - srq_attr.srq_type = IB_SRQT_BASIC; sdev->srq = ib_create_srq(sdev->pd, &srq_attr); if (IS_ERR(sdev->srq)) diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 7faf4a7fcaa9..2d787796bf50 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -380,7 +380,8 @@ config INPUT_TWL4030_VIBRA config INPUT_TWL6040_VIBRA tristate "Support for TWL6040 Vibrator" - depends on TWL6040_CORE + depends on TWL4030_CORE + select TWL6040_CORE select INPUT_FF_MEMLESS help This option enables support for TWL6040 Vibrator Driver. diff --git a/trunk/drivers/input/misc/da9052_onkey.c b/trunk/drivers/input/misc/da9052_onkey.c index 3c843cd725fa..34aebb8cd080 100644 --- a/trunk/drivers/input/misc/da9052_onkey.c +++ b/trunk/drivers/input/misc/da9052_onkey.c @@ -95,8 +95,7 @@ static int __devinit da9052_onkey_probe(struct platform_device *pdev) input_dev = input_allocate_device(); if (!onkey || !input_dev) { dev_err(&pdev->dev, "Failed to allocate memory\n"); - error = -ENOMEM; - goto err_free_mem; + return -ENOMEM; } onkey->input = input_dev; diff --git a/trunk/drivers/input/misc/twl6040-vibra.c b/trunk/drivers/input/misc/twl6040-vibra.c index 14e94f56cb7d..45874fed523a 100644 --- a/trunk/drivers/input/misc/twl6040-vibra.c +++ b/trunk/drivers/input/misc/twl6040-vibra.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int __devinit twl6040_vibra_probe(struct platform_device *pdev) { - struct twl6040_vibra_data *pdata = pdev->dev.platform_data; + struct twl4030_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; diff --git a/trunk/drivers/input/mouse/elantech.c b/trunk/drivers/input/mouse/elantech.c index 479011004a11..d2c0db159b18 100644 --- a/trunk/drivers/input/mouse/elantech.c +++ b/trunk/drivers/input/mouse/elantech.c @@ -486,6 +486,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) unsigned char *packet = psmouse->packet; input_report_key(dev, BTN_LEFT, packet[0] & 0x01); + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); input_mt_report_pointer_emulation(dev, true); input_sync(dev); } @@ -966,7 +967,6 @@ static int elantech_set_input_params(struct psmouse *psmouse) if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) return -1; - __set_bit(INPUT_PROP_POINTER, dev->propbit); __set_bit(EV_KEY, dev->evbit); __set_bit(EV_ABS, dev->evbit); __clear_bit(EV_REL, dev->evbit); @@ -1017,9 +1017,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) */ psmouse_warn(psmouse, "couldn't query resolution data.\n"); } - /* v4 is clickpad, with only one button. */ - __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); - __clear_bit(BTN_RIGHT, dev->keybit); + __set_bit(BTN_TOOL_QUADTAP, dev->keybit); /* For X to recognize me as touchpad. */ input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); @@ -1247,8 +1245,6 @@ static void elantech_disconnect(struct psmouse *psmouse) */ static int elantech_reconnect(struct psmouse *psmouse) { - psmouse_reset(psmouse); - if (elantech_detect(psmouse, 0)) return -1; @@ -1328,8 +1324,6 @@ int elantech_init(struct psmouse *psmouse) if (!etd) return -ENOMEM; - psmouse_reset(psmouse); - etd->parity[0] = 1; for (i = 1; i < 256; i++) etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; diff --git a/trunk/drivers/input/mouse/gpio_mouse.c b/trunk/drivers/input/mouse/gpio_mouse.c index 39fe9b737cae..a9ad8e1402be 100644 --- a/trunk/drivers/input/mouse/gpio_mouse.c +++ b/trunk/drivers/input/mouse/gpio_mouse.c @@ -12,9 +12,9 @@ #include #include #include -#include #include +#include /* * Timer function which is run every scan_ms ms when the device is opened. diff --git a/trunk/drivers/input/mouse/sentelic.c b/trunk/drivers/input/mouse/sentelic.c index 661a0ca3b3d6..a977bfaa6821 100644 --- a/trunk/drivers/input/mouse/sentelic.c +++ b/trunk/drivers/input/mouse/sentelic.c @@ -741,14 +741,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) } } else { /* SFAC packet */ - if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) == - FSP_PB0_LBTN) { - /* On-pad click in SFAC mode should be handled - * by userspace. On-pad clicks in MFMC mode - * are real clickpad clicks, and not ignored. - */ - packet[0] &= ~FSP_PB0_LBTN; - } /* no multi-finger information */ ad->last_mt_fgr = 0; diff --git a/trunk/drivers/input/mouse/trackpoint.c b/trunk/drivers/input/mouse/trackpoint.c index f3102494237d..22b218018137 100644 --- a/trunk/drivers/input/mouse/trackpoint.c +++ b/trunk/drivers/input/mouse/trackpoint.c @@ -304,7 +304,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) return 0; if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { - psmouse_warn(psmouse, "failed to get extended button data\n"); + printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); button_info = 0; } @@ -326,18 +326,16 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); if (error) { - psmouse_err(psmouse, - "failed to create sysfs attributes, error: %d\n", - error); + printk(KERN_ERR + "trackpoint.c: failed to create sysfs attributes, error: %d\n", + error); kfree(psmouse->private); psmouse->private = NULL; return -1; } - psmouse_info(psmouse, - "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", - firmware_id, - (button_info & 0xf0) >> 4, button_info & 0x0f); + printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", + firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); return 0; } diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index 75838d7710ce..2a2141915aa0 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -489,10 +489,10 @@ config TOUCHSCREEN_TI_TSCADC config TOUCHSCREEN_ATMEL_TSADCC tristate "Atmel Touchscreen Interface" - depends on ARCH_AT91 + depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help Say Y here if you have a 4-wire touchscreen connected to the - ADC Controller on your Atmel SoC. + ADC Controller on your Atmel SoC (such as the AT91SAM9RL). If unsure, say N. diff --git a/trunk/drivers/input/touchscreen/tps6507x-ts.c b/trunk/drivers/input/touchscreen/tps6507x-ts.c index f7eda3d00fad..6c6f6d8ea9b4 100644 --- a/trunk/drivers/input/touchscreen/tps6507x-ts.c +++ b/trunk/drivers/input/touchscreen/tps6507x-ts.c @@ -1,4 +1,6 @@ /* + * drivers/input/touchscreen/tps6507x_ts.c + * * Touchscreen driver for the tps6507x chip. * * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) @@ -374,4 +376,4 @@ module_platform_driver(tps6507x_ts_driver); MODULE_AUTHOR("Todd Fischer "); MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:tps6507x-ts"); +MODULE_ALIAS("platform:tps6507x-tsc"); diff --git a/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c index a6d9fd2858f7..b3d6ac17272d 100644 --- a/trunk/drivers/isdn/gigaset/interface.c +++ b/trunk/drivers/isdn/gigaset/interface.c @@ -176,7 +176,7 @@ static void if_close(struct tty_struct *tty, struct file *filp) struct cardstate *cs = tty->driver_data; if (!cs) { /* happens if we didn't find cs in open */ - gig_dbg(DEBUG_IF, "%s: no cardstate", __func__); + printk(KERN_DEBUG "%s: no cardstate\n", __func__); return; } diff --git a/trunk/drivers/leds/leds-atmel-pwm.c b/trunk/drivers/leds/leds-atmel-pwm.c index 64ad702a2ecc..800243b6037e 100644 --- a/trunk/drivers/leds/leds-atmel-pwm.c +++ b/trunk/drivers/leds/leds-atmel-pwm.c @@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b) * NOTE: we reuse the platform_data structure of GPIO leds, * but repurpose its "gpio" number as a PWM channel number. */ -static int __devinit pwmled_probe(struct platform_device *pdev) +static int __init pwmled_probe(struct platform_device *pdev) { const struct gpio_led_platform_data *pdata; struct pwmled *leds; diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 97e73e555d11..3d0dfa7a89a2 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -539,6 +539,9 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap) bitmap->events_cleared = bitmap->mddev->events; sb->events_cleared = cpu_to_le64(bitmap->mddev->events); + bitmap->flags |= BITMAP_HOSTENDIAN; + sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN); + kunmap_atomic(sb); return 0; @@ -1785,9 +1788,7 @@ int bitmap_load(struct mddev *mddev) * re-add of a missing device */ start = mddev->recovery_cp; - mutex_lock(&mddev->bitmap_info.mutex); err = bitmap_init_from_disk(bitmap, start); - mutex_unlock(&mddev->bitmap_info.mutex); if (err) goto out; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 15dd59b84e94..d35e4c991e38 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1712,7 +1712,6 @@ static int process_checks(struct r1bio *r1_bio) struct r1conf *conf = mddev->private; int primary; int i; - int vcnt; for (primary = 0; primary < conf->raid_disks * 2; primary++) if (r1_bio->bios[primary]->bi_end_io == end_sync_read && @@ -1722,9 +1721,9 @@ static int process_checks(struct r1bio *r1_bio) break; } r1_bio->read_disk = primary; - vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9); for (i = 0; i < conf->raid_disks * 2; i++) { int j; + int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9); struct bio *pbio = r1_bio->bios[primary]; struct bio *sbio = r1_bio->bios[i]; int size; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index c8dbb84d5357..fff782189e48 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1788,7 +1788,6 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) struct r10conf *conf = mddev->private; int i, first; struct bio *tbio, *fbio; - int vcnt; atomic_set(&r10_bio->remaining, 1); @@ -1803,10 +1802,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) first = i; fbio = r10_bio->devs[i].bio; - vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9); /* now find blocks with errors */ for (i=0 ; i < conf->copies ; i++) { int j, d; + int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9); tbio = r10_bio->devs[i].bio; @@ -1872,6 +1871,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) */ for (i = 0; i < conf->copies; i++) { int j, d; + int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9); tbio = r10_bio->devs[i].repl_bio; if (!tbio || !tbio->bi_end_io) diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index eab2ea424200..7f98984e4fad 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -54,7 +54,6 @@ struct xc5000_priv { struct list_head hybrid_tuner_instance_list; u32 if_khz; - u32 xtal_khz; u32 freq_hz; u32 bandwidth; u8 video_standard; @@ -215,9 +214,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = { .size = 12401, }; -static const struct xc5000_fw_cfg xc5000c_41_024_5 = { - .name = "dvb-fe-xc5000c-41.024.5.fw", - .size = 16497, +static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { + .name = "dvb-fe-xc5000c-41.024.5-31875.fw", + .size = 16503, }; static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) @@ -227,7 +226,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) case XC5000A: return &xc5000a_1_6_114; case XC5000C: - return &xc5000c_41_024_5; + return &xc5000c_41_024_5_31875; } } @@ -573,31 +572,6 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) return found; } -static int xc_set_xtal(struct dvb_frontend *fe) -{ - struct xc5000_priv *priv = fe->tuner_priv; - int ret = XC_RESULT_SUCCESS; - - switch (priv->chip_id) { - default: - case XC5000A: - /* 32.000 MHz xtal is default */ - break; - case XC5000C: - switch (priv->xtal_khz) { - default: - case 32000: - /* 32.000 MHz xtal is default */ - break; - case 31875: - /* 31.875 MHz xtal configuration */ - ret = xc_write_reg(priv, 0x000f, 0x8081); - break; - } - break; - } - return ret; -} static int xc5000_fwupload(struct dvb_frontend *fe) { @@ -629,8 +603,6 @@ static int xc5000_fwupload(struct dvb_frontend *fe) } else { printk(KERN_INFO "xc5000: firmware uploading...\n"); ret = xc_load_i2c_sequence(fe, fw->data); - if (XC_RESULT_SUCCESS == ret) - ret = xc_set_xtal(fe); printk(KERN_INFO "xc5000: firmware upload complete...\n"); } @@ -1192,9 +1164,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, priv->if_khz = cfg->if_khz; } - if (priv->xtal_khz == 0) - priv->xtal_khz = cfg->xtal_khz; - if (priv->radio_input == 0) priv->radio_input = cfg->radio_input; diff --git a/trunk/drivers/media/common/tuners/xc5000.h b/trunk/drivers/media/common/tuners/xc5000.h index 39a73bf01406..3396f8e02b40 100644 --- a/trunk/drivers/media/common/tuners/xc5000.h +++ b/trunk/drivers/media/common/tuners/xc5000.h @@ -34,7 +34,6 @@ struct xc5000_config { u8 i2c_address; u32 if_khz; u8 radio_input; - u32 xtal_khz; int chip_id; }; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 0f64d7182657..4555baa383b2 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -143,12 +143,10 @@ struct dvb_frontend_private { static void dvb_frontend_wakeup(struct dvb_frontend *fe); static int dtv_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p_out); -static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p); static bool has_get_frontend(struct dvb_frontend *fe) { - return fe->ops.get_frontend != NULL; + return fe->ops.get_frontend; } /* @@ -699,7 +697,6 @@ static int dvb_frontend_thread(void *data) fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; fepriv->delay = HZ / 2; } - dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); /* update event list */ @@ -1446,28 +1443,6 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } - /* - * Get a delivery system that is compatible with DVBv3 - * NOTE: in order for this to work with softwares like Kaffeine that - * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to - * DVB-S, drivers that support both should put the SYS_DVBS entry - * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. - * The real fix is that userspace applications should not use DVBv3 - * and not trust on calling FE_SET_FRONTEND to switch the delivery - * system. - */ - ncaps = 0; - while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if (fe->ops.delsys[ncaps] == desired_system) { - delsys = desired_system; - break; - } - ncaps++; - } - if (delsys == SYS_UNDEFINED) { - dprintk("%s() Couldn't find a delivery system that matches %d\n", - __func__, desired_system); - } } else { /* * This is a DVBv5 call. So, it likely knows the supported @@ -1516,10 +1491,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } + c->delivery_system = delsys; } - c->delivery_system = delsys; - /* * The DVBv3 or DVBv5 call is requesting a different system. So, * emulation is needed. @@ -1858,13 +1832,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe) if (dvb_frontend_check_parameters(fe) < 0) return -EINVAL; - /* - * Initialize output parameters to match the values given by - * the user. FE_SET_FRONTEND triggers an initial frontend event - * with status = 0, which copies output parameters to userspace. - */ - dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); - /* * Be sure that the bandwidth will be filled for all * non-satellite systems, as tuners need to know what diff --git a/trunk/drivers/media/dvb/dvb-usb/it913x.c b/trunk/drivers/media/dvb/dvb-usb/it913x.c index 482d249ca7f3..3b7b102f20ae 100644 --- a/trunk/drivers/media/dvb/dvb-usb/it913x.c +++ b/trunk/drivers/media/dvb/dvb-usb/it913x.c @@ -238,27 +238,12 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) static u32 it913x_query(struct usb_device *udev, u8 pro) { - int ret, i; + int ret; u8 data[4]; - u8 ver; - - for (i = 0; i < 5; i++) { - ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, - 0x1222, 0, &data[0], 3); - ver = data[0]; - if (ver > 0 && ver < 3) - break; - msleep(100); - } + ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, + 0x1222, 0, &data[0], 3); - if (ver < 1 || ver > 2) { - info("Failed to identify chip version applying 1"); - it913x_config.chip_ver = 0x1; - it913x_config.chip_type = 0x9135; - return 0; - } - - it913x_config.chip_ver = ver; + it913x_config.chip_ver = data[0]; it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, @@ -675,41 +660,30 @@ static int it913x_download_firmware(struct usb_device *udev, if ((packet_size > min_pkt) || (i == fw->size)) { fw_data = (u8 *)(fw->data + pos); pos += packet_size; - if (packet_size > 0) { - ret = it913x_io(udev, WRITE_DATA, + if (packet_size > 0) + ret |= it913x_io(udev, WRITE_DATA, DEV_0, CMD_SCATTER_WRITE, 0, 0, fw_data, packet_size); - if (ret < 0) - break; - } udelay(1000); } } i++; } - if (ret < 0) - info("FRM Firmware Download Failed (%d)" , ret); - else - info("FRM Firmware Download Completed - Resetting Device"); + ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); - msleep(30); + msleep(100); - ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); if (ret < 0) - info("FRM Device not responding to reboot"); + info("FRM Firmware Download Failed (%04x)" , ret); + else + info("FRM Firmware Download Completed - Resetting Device"); - ret = it913x_return_status(udev); - if (ret == 0) { - info("FRM Failed to reboot device"); - return -ENODEV; - } + ret |= it913x_return_status(udev); msleep(30); - ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); - - msleep(30); + ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); /* Tuner function */ if (it913x_config.dual_mode) @@ -927,5 +901,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.28"); +MODULE_VERSION("1.27"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/drxk_hard.c b/trunk/drivers/media/dvb/frontends/drxk_hard.c index a414b1f2b6a5..36d11756492f 100644 --- a/trunk/drivers/media/dvb/frontends/drxk_hard.c +++ b/trunk/drivers/media/dvb/frontends/drxk_hard.c @@ -1520,10 +1520,8 @@ static int scu_command(struct drxk_state *state, dprintk(1, "\n"); if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || - ((resultLen > 0) && (result == NULL))) { - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - return status; - } + ((resultLen > 0) && (result == NULL))) + goto error; mutex_lock(&state->mutex); diff --git a/trunk/drivers/media/rc/winbond-cir.c b/trunk/drivers/media/rc/winbond-cir.c index af526586fa26..b09c5fae489b 100644 --- a/trunk/drivers/media/rc/winbond-cir.c +++ b/trunk/drivers/media/rc/winbond-cir.c @@ -1046,7 +1046,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_unregister_led; } - data->dev->driver_type = RC_DRIVER_IR_RAW; data->dev->driver_name = WBCIR_NAME; data->dev->input_name = WBCIR_NAME; data->dev->input_phys = "wbcir/cir0"; diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index ce1e7ba940f6..f2479c5c0eb2 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -492,7 +492,7 @@ config VIDEO_VS6624 config VIDEO_MT9M032 tristate "MT9M032 camera sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on I2C && VIDEO_V4L2 select VIDEO_APTINA_PLL ---help--- This driver supports MT9M032 camera sensors from Aptina, monochrome diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index 989e556913ed..5452beef8e11 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg); case AUDIO_BILINGUAL_CHANNEL_SELECT: IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg); default: return -EINVAL; diff --git a/trunk/drivers/media/video/mt9m032.c b/trunk/drivers/media/video/mt9m032.c index 645973c5feb0..7636672c3548 100644 --- a/trunk/drivers/media/video/mt9m032.c +++ b/trunk/drivers/media/video/mt9m032.c @@ -392,11 +392,10 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, } /* Scaling is not supported, the format is thus fixed. */ - fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); - ret = 0; + ret = mt9m032_get_pad_format(subdev, fh, fmt); done: - mutex_unlock(&sensor->lock); + mutex_lock(&sensor->lock); return ret; } diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c index b76b0ac0958f..4a44f9a1bae0 100644 --- a/trunk/drivers/media/video/uvc/uvc_video.c +++ b/trunk/drivers/media/video/uvc/uvc_video.c @@ -468,30 +468,22 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, spin_unlock_irqrestore(&stream->clock.lock, flags); } -static void uvc_video_clock_reset(struct uvc_streaming *stream) +static int uvc_video_clock_init(struct uvc_streaming *stream) { struct uvc_clock *clock = &stream->clock; + spin_lock_init(&clock->lock); clock->head = 0; clock->count = 0; + clock->size = 32; clock->last_sof = -1; clock->sof_offset = -1; -} - -static int uvc_video_clock_init(struct uvc_streaming *stream) -{ - struct uvc_clock *clock = &stream->clock; - - spin_lock_init(&clock->lock); - clock->size = 32; clock->samples = kmalloc(clock->size * sizeof(*clock->samples), GFP_KERNEL); if (clock->samples == NULL) return -ENOMEM; - uvc_video_clock_reset(stream); - return 0; } @@ -1432,6 +1424,8 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) if (free_buffers) uvc_free_urb_buffers(stream); + + uvc_video_clock_cleanup(stream); } /* @@ -1561,6 +1555,10 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) uvc_video_stats_start(stream); + ret = uvc_video_clock_init(stream); + if (ret < 0) + return ret; + if (intf->num_altsetting > 1) { struct usb_host_endpoint *best_ep = NULL; unsigned int best_psize = 3 * 1024; @@ -1685,8 +1683,6 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) stream->frozen = 0; - uvc_video_clock_reset(stream); - ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) { uvc_queue_enable(&stream->queue, 0); @@ -1823,35 +1819,25 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) uvc_uninit_video(stream, 1); usb_set_interface(stream->dev->udev, stream->intfnum, 0); uvc_queue_enable(&stream->queue, 0); - uvc_video_clock_cleanup(stream); return 0; } - ret = uvc_video_clock_init(stream); - if (ret < 0) - return ret; - ret = uvc_queue_enable(&stream->queue, 1); if (ret < 0) - goto error_queue; + return ret; /* Commit the streaming parameters. */ ret = uvc_commit_video(stream, &stream->ctrl); - if (ret < 0) - goto error_commit; + if (ret < 0) { + uvc_queue_enable(&stream->queue, 0); + return ret; + } ret = uvc_init_video(stream, GFP_KERNEL); - if (ret < 0) - goto error_video; - - return 0; - -error_video: - usb_set_interface(stream->dev->udev, stream->intfnum, 0); -error_commit: - uvc_queue_enable(&stream->queue, 0); -error_queue: - uvc_video_clock_cleanup(stream); + if (ret < 0) { + usb_set_interface(stream->dev->udev, stream->intfnum, 0); + uvc_queue_enable(&stream->queue, 0); + } return ret; } diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index d875bfa56ad5..29f463cc09cb 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -268,17 +268,10 @@ config TWL6030_PWM This is used to control charging LED brightness. config TWL6040_CORE - bool "Support for TWL6040 audio codec" - depends on I2C=y && GENERIC_HARDIRQS + bool + depends on TWL4030_CORE && GENERIC_HARDIRQS select MFD_CORE - select REGMAP_I2C default n - help - Say yes here if you want support for Texas Instruments TWL6040 audio - codec. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device (audio, vibra). config MFD_STMPE bool "Support STMicroelectronics STMPE" @@ -648,6 +641,23 @@ config EZX_PCAP This enables the PCAP ASIC present on EZX Phones. This is needed for MMC, TouchScreen, Sound, USB, etc.. +config AB5500_CORE + bool "ST-Ericsson AB5500 Mixed Signal Power Management chip" + depends on ABX500_CORE && MFD_DB5500_PRCMU + select MFD_CORE + help + Select this option to enable access to AB5500 power management + chip. This connects to the db5500 chip via the I2C bus via PRCMU. + This chip embeds various other multimedia funtionalities as well. + +config AB5500_DEBUG + bool "Enable debug info via debugfs" + depends on AB5500_CORE && DEBUG_FS + default y if DEBUG_FS + help + Select this option if you want debug information from the AB5500 + using the debug filesystem, debugfs. + config AB8500_CORE bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" depends on GENERIC_HARDIRQS && ABX500_CORE @@ -694,6 +704,16 @@ config MFD_DB8500_PRCMU system controller running an XP70 microprocessor, which is accessed through a register map. +config MFD_DB5500_PRCMU + bool "ST-Ericsson DB5500 Power Reset Control Management Unit" + depends on UX500_SOC_DB5500 + select MFD_CORE + help + Select this option to enable support for the DB5500 Power Reset + and Control Management Unit. This is basically an autonomous + system controller running an XP70 microprocessor, which is accessed + through a register map. + config MFD_CS5535 tristate "Support for CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/trunk/drivers/mfd/Makefile b/trunk/drivers/mfd/Makefile index 669ba7d85a36..05fa538c5efe 100644 --- a/trunk/drivers/mfd/Makefile +++ b/trunk/drivers/mfd/Makefile @@ -87,12 +87,15 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o obj-$(CONFIG_ABX500_CORE) += abx500-core.o obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o +obj-$(CONFIG_AB5500_CORE) += ab5500-core.o +obj-$(CONFIG_AB5500_DEBUG) += ab5500-debugfs.o obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o # ab8500-i2c need to come after db8500-prcmu (which provides the channel) obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o +obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o diff --git a/trunk/drivers/mfd/ab5500-core.c b/trunk/drivers/mfd/ab5500-core.c new file mode 100644 index 000000000000..54d0fe40845f --- /dev/null +++ b/trunk/drivers/mfd/ab5500-core.c @@ -0,0 +1,1439 @@ +/* + * Copyright (C) 2007-2011 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Low-level core for exclusive access to the AB5500 IC on the I2C bus + * and some basic chip-configuration. + * Author: Bengt Jonsson + * Author: Mattias Nilsson + * Author: Mattias Wallin + * Author: Rickard Andersson + * Author: Karl Komierowski + * Author: Bibek Basu + * + * TODO: Event handling with irq_chip. Waiting for PRCMU fw support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ab5500-core.h" +#include "ab5500-debugfs.h" + +#define AB5500_NUM_EVENT_REG 23 +#define AB5500_IT_LATCH0_REG 0x40 +#define AB5500_IT_MASK0_REG 0x60 + +/* + * Permissible register ranges for reading and writing per device and bank. + * + * The ranges must be listed in increasing address order, and no overlaps are + * allowed. It is assumed that write permission implies read permission + * (i.e. only RO and RW permissions should be used). Ranges with write + * permission must not be split up. + */ + +#define NO_RANGE {.count = 0, .range = NULL,} +static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = { + [AB5500_DEVID_USB] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_USB, + .nranges = 12, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x01, + .last = 0x01, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x80, + .last = 0x83, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x87, + .last = 0x8A, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x8B, + .last = 0x8B, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x91, + .last = 0x92, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x93, + .last = 0x93, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x94, + .last = 0x94, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xA8, + .last = 0xB0, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xB2, + .last = 0xB2, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xB4, + .last = 0xBC, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xBF, + .last = 0xBF, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xC1, + .last = 0xC5, + .perm = AB5500_PERM_RO, + }, + }, + }, + }, + }, + [AB5500_DEVID_ADC] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_ADC, + .nranges = 6, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x1F, + .last = 0x22, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x23, + .last = 0x24, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x26, + .last = 0x2D, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x2F, + .last = 0x34, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x37, + .last = 0x57, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x58, + .last = 0x58, + .perm = AB5500_PERM_RO, + }, + }, + }, + }, + }, + [AB5500_DEVID_LEDS] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_LED, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x0C, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_VIDEO] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_VDENC, + .nranges = 12, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x08, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x09, + .last = 0x09, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x0A, + .last = 0x12, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x15, + .last = 0x19, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x1B, + .last = 0x21, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x27, + .last = 0x2C, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x41, + .last = 0x41, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x45, + .last = 0x5B, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x5D, + .last = 0x5D, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x69, + .last = 0x69, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x6C, + .last = 0x6D, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x80, + .last = 0x81, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_REGULATORS] = { + .nbanks = 2, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_STARTUP, + .nranges = 12, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x01, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x1F, + .last = 0x1F, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x2E, + .last = 0x2E, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x2F, + .last = 0x30, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x50, + .last = 0x51, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x60, + .last = 0x61, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x66, + .last = 0x8A, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x8C, + .last = 0x96, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xAA, + .last = 0xB4, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xB7, + .last = 0xBF, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xC1, + .last = 0xCA, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xD3, + .last = 0xE0, + .perm = AB5500_PERM_RW, + }, + }, + }, + { + .bankid = AB5500_BANK_SIM_USBSIM, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x13, + .last = 0x19, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_SIM] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_SIM_USBSIM, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x13, + .last = 0x19, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_RTC] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_RTC, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x04, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x06, + .last = 0x0C, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_CHARGER] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_CHG, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x11, + .last = 0x11, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x12, + .last = 0x1B, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_FUELGAUGE] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_FG_BATTCOM_ACC, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x0B, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x0C, + .last = 0x10, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_VIBRATOR] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_VIBRA, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x10, + .last = 0x13, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xFE, + .last = 0xFE, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_CODEC] = { + .nbanks = 1, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_AUDIO_HEADSETUSB, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x48, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xEB, + .last = 0xFB, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, + [AB5500_DEVID_POWER] = { + .nbanks = 2, + .bank = (struct ab5500_i2c_ranges []) { + { + .bankid = AB5500_BANK_STARTUP, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x30, + .last = 0x30, + .perm = AB5500_PERM_RW, + }, + }, + }, + { + .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x01, + .last = 0x01, + .perm = AB5500_PERM_RW, + }, + }, + }, + }, + }, +}; + +#define AB5500_IRQ(bank, bit) ((bank) * 8 + (bit)) + +/* I appologize for the resource names beeing a mix of upper case + * and lower case but I want them to be exact as the documentation */ +static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = { + [AB5500_DEVID_LEDS] = { + .name = "ab5500-leds", + .id = AB5500_DEVID_LEDS, + }, + [AB5500_DEVID_POWER] = { + .name = "ab5500-power", + .id = AB5500_DEVID_POWER, + }, + [AB5500_DEVID_REGULATORS] = { + .name = "ab5500-regulator", + .id = AB5500_DEVID_REGULATORS, + }, + [AB5500_DEVID_SIM] = { + .name = "ab5500-sim", + .id = AB5500_DEVID_SIM, + .num_resources = 1, + .resources = (struct resource[]) { + { + .name = "SIMOFF", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(2, 0), /*rising*/ + .end = AB5500_IRQ(2, 1), /*falling*/ + }, + }, + }, + [AB5500_DEVID_RTC] = { + .name = "ab5500-rtc", + .id = AB5500_DEVID_RTC, + .num_resources = 1, + .resources = (struct resource[]) { + { + .name = "RTC_Alarm", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(1, 7), + .end = AB5500_IRQ(1, 7), + } + }, + }, + [AB5500_DEVID_CHARGER] = { + .name = "ab5500-charger", + .id = AB5500_DEVID_CHARGER, + }, + [AB5500_DEVID_ADC] = { + .name = "ab5500-adc", + .id = AB5500_DEVID_ADC, + .num_resources = 10, + .resources = (struct resource[]) { + { + .name = "TRIGGER-0", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 0), + .end = AB5500_IRQ(0, 0), + }, + { + .name = "TRIGGER-1", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 1), + .end = AB5500_IRQ(0, 1), + }, + { + .name = "TRIGGER-2", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 2), + .end = AB5500_IRQ(0, 2), + }, + { + .name = "TRIGGER-3", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 3), + .end = AB5500_IRQ(0, 3), + }, + { + .name = "TRIGGER-4", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 4), + .end = AB5500_IRQ(0, 4), + }, + { + .name = "TRIGGER-5", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 5), + .end = AB5500_IRQ(0, 5), + }, + { + .name = "TRIGGER-6", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 6), + .end = AB5500_IRQ(0, 6), + }, + { + .name = "TRIGGER-7", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 7), + .end = AB5500_IRQ(0, 7), + }, + { + .name = "TRIGGER-VBAT", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 8), + .end = AB5500_IRQ(0, 8), + }, + { + .name = "TRIGGER-VBAT-TXON", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(0, 9), + .end = AB5500_IRQ(0, 9), + }, + }, + }, + [AB5500_DEVID_FUELGAUGE] = { + .name = "ab5500-fuelgauge", + .id = AB5500_DEVID_FUELGAUGE, + .num_resources = 6, + .resources = (struct resource[]) { + { + .name = "Batt_attach", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(7, 5), + .end = AB5500_IRQ(7, 5), + }, + { + .name = "Batt_removal", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(7, 6), + .end = AB5500_IRQ(7, 6), + }, + { + .name = "UART_framing", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(7, 7), + .end = AB5500_IRQ(7, 7), + }, + { + .name = "UART_overrun", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 0), + .end = AB5500_IRQ(8, 0), + }, + { + .name = "UART_Rdy_RX", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 1), + .end = AB5500_IRQ(8, 1), + }, + { + .name = "UART_Rdy_TX", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 2), + .end = AB5500_IRQ(8, 2), + }, + }, + }, + [AB5500_DEVID_VIBRATOR] = { + .name = "ab5500-vibrator", + .id = AB5500_DEVID_VIBRATOR, + }, + [AB5500_DEVID_CODEC] = { + .name = "ab5500-codec", + .id = AB5500_DEVID_CODEC, + .num_resources = 3, + .resources = (struct resource[]) { + { + .name = "audio_spkr1_ovc", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 5), + .end = AB5500_IRQ(9, 5), + }, + { + .name = "audio_plllocked", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 6), + .end = AB5500_IRQ(9, 6), + }, + { + .name = "audio_spkr2_ovc", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(17, 4), + .end = AB5500_IRQ(17, 4), + }, + }, + }, + [AB5500_DEVID_USB] = { + .name = "ab5500-usb", + .id = AB5500_DEVID_USB, + .num_resources = 36, + .resources = (struct resource[]) { + { + .name = "Link_Update", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(22, 1), + .end = AB5500_IRQ(22, 1), + }, + { + .name = "DCIO", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 3), + .end = AB5500_IRQ(8, 4), + }, + { + .name = "VBUS_R", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 5), + .end = AB5500_IRQ(8, 5), + }, + { + .name = "VBUS_F", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 6), + .end = AB5500_IRQ(8, 6), + }, + { + .name = "CHGstate_10_PCVBUSchg", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(8, 7), + .end = AB5500_IRQ(8, 7), + }, + { + .name = "DCIOreverse_ovc", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 0), + .end = AB5500_IRQ(9, 0), + }, + { + .name = "USBCharDetDone", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 1), + .end = AB5500_IRQ(9, 1), + }, + { + .name = "DCIO_no_limit", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 2), + .end = AB5500_IRQ(9, 2), + }, + { + .name = "USB_suspend", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 3), + .end = AB5500_IRQ(9, 3), + }, + { + .name = "DCIOreverse_fwdcurrent", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 4), + .end = AB5500_IRQ(9, 4), + }, + { + .name = "Vbus_Imeasmax_change", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(9, 5), + .end = AB5500_IRQ(9, 6), + }, + { + .name = "OVV", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 5), + .end = AB5500_IRQ(14, 5), + }, + { + .name = "USBcharging_NOTok", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(15, 3), + .end = AB5500_IRQ(15, 3), + }, + { + .name = "usb_adp_sensoroff", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(15, 6), + .end = AB5500_IRQ(15, 6), + }, + { + .name = "usb_adp_probeplug", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(15, 7), + .end = AB5500_IRQ(15, 7), + }, + { + .name = "usb_adp_sinkerror", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(16, 0), + .end = AB5500_IRQ(16, 6), + }, + { + .name = "usb_adp_sourceerror", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(16, 1), + .end = AB5500_IRQ(16, 1), + }, + { + .name = "usb_idgnd_r", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(16, 2), + .end = AB5500_IRQ(16, 2), + }, + { + .name = "usb_idgnd_f", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(16, 3), + .end = AB5500_IRQ(16, 3), + }, + { + .name = "usb_iddetR1", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(16, 4), + .end = AB5500_IRQ(16, 5), + }, + { + .name = "usb_iddetR2", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(16, 6), + .end = AB5500_IRQ(16, 7), + }, + { + .name = "usb_iddetR3", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(17, 0), + .end = AB5500_IRQ(17, 1), + }, + { + .name = "usb_iddetR4", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(17, 2), + .end = AB5500_IRQ(17, 3), + }, + { + .name = "CharTempWindowOk", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(17, 7), + .end = AB5500_IRQ(18, 0), + }, + { + .name = "USB_SprDetect", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(18, 1), + .end = AB5500_IRQ(18, 1), + }, + { + .name = "usb_adp_probe_unplug", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(18, 2), + .end = AB5500_IRQ(18, 2), + }, + { + .name = "VBUSChDrop", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(18, 3), + .end = AB5500_IRQ(18, 4), + }, + { + .name = "dcio_char_rec_done", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(18, 5), + .end = AB5500_IRQ(18, 5), + }, + { + .name = "Charging_stopped_by_temp", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(18, 6), + .end = AB5500_IRQ(18, 6), + }, + { + .name = "CHGstate_11_SafeModeVBUS", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 1), + .end = AB5500_IRQ(21, 2), + }, + { + .name = "CHGstate_12_comletedVBUS", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 2), + .end = AB5500_IRQ(21, 2), + }, + { + .name = "CHGstate_13_completedVBUS", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 3), + .end = AB5500_IRQ(21, 3), + }, + { + .name = "CHGstate_14_FullChgDCIO", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 4), + .end = AB5500_IRQ(21, 4), + }, + { + .name = "CHGstate_15_SafeModeDCIO", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 5), + .end = AB5500_IRQ(21, 5), + }, + { + .name = "CHGstate_16_OFFsuspendDCIO", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 6), + .end = AB5500_IRQ(21, 6), + }, + { + .name = "CHGstate_17_completedDCIO", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(21, 7), + .end = AB5500_IRQ(21, 7), + }, + }, + }, + [AB5500_DEVID_OTP] = { + .name = "ab5500-otp", + .id = AB5500_DEVID_OTP, + }, + [AB5500_DEVID_VIDEO] = { + .name = "ab5500-video", + .id = AB5500_DEVID_VIDEO, + .num_resources = 1, + .resources = (struct resource[]) { + { + .name = "plugTVdet", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(22, 2), + .end = AB5500_IRQ(22, 2), + }, + }, + }, + [AB5500_DEVID_DBIECI] = { + .name = "ab5500-dbieci", + .id = AB5500_DEVID_DBIECI, + .num_resources = 10, + .resources = (struct resource[]) { + { + .name = "COLL", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 0), + .end = AB5500_IRQ(14, 0), + }, + { + .name = "RESERR", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 1), + .end = AB5500_IRQ(14, 1), + }, + { + .name = "FRAERR", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 2), + .end = AB5500_IRQ(14, 2), + }, + { + .name = "COMERR", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 3), + .end = AB5500_IRQ(14, 3), + }, + { + .name = "BSI_indicator", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 4), + .end = AB5500_IRQ(14, 4), + }, + { + .name = "SPDSET", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 6), + .end = AB5500_IRQ(14, 6), + }, + { + .name = "DSENT", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(14, 7), + .end = AB5500_IRQ(14, 7), + }, + { + .name = "DREC", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(15, 0), + .end = AB5500_IRQ(15, 0), + }, + { + .name = "ACCINT", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(15, 1), + .end = AB5500_IRQ(15, 1), + }, + { + .name = "NOPINT", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(15, 2), + .end = AB5500_IRQ(15, 2), + }, + }, + }, + [AB5500_DEVID_ONSWA] = { + .name = "ab5500-onswa", + .id = AB5500_DEVID_ONSWA, + .num_resources = 2, + .resources = (struct resource[]) { + { + .name = "ONSWAn_rising", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(1, 3), + .end = AB5500_IRQ(1, 3), + }, + { + .name = "ONSWAn_falling", + .flags = IORESOURCE_IRQ, + .start = AB5500_IRQ(1, 4), + .end = AB5500_IRQ(1, 4), + }, + }, + }, +}; + +/* + * Functionality for getting/setting register values. + */ +int ab5500_get_register_interruptible_raw(struct ab5500 *ab, + u8 bank, u8 reg, + u8 *value) +{ + int err; + + if (bank >= AB5500_NUM_BANKS) + return -EINVAL; + + err = mutex_lock_interruptible(&ab->access_mutex); + if (err) + return err; + err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1); + + mutex_unlock(&ab->access_mutex); + return err; +} + +static int get_register_page_interruptible(struct ab5500 *ab, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs) +{ + int err; + + if (bank >= AB5500_NUM_BANKS) + return -EINVAL; + + err = mutex_lock_interruptible(&ab->access_mutex); + if (err) + return err; + + while (numregs) { + /* The hardware limit for get page is 4 */ + u8 curnum = min_t(u8, numregs, 4u); + + err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, + first_reg, regvals, curnum); + if (err) + goto out; + + numregs -= curnum; + first_reg += curnum; + regvals += curnum; + } + +out: + mutex_unlock(&ab->access_mutex); + return err; +} + +int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues) +{ + int err = 0; + + if (bank >= AB5500_NUM_BANKS) + return -EINVAL; + + if (bitmask) { + u8 buf; + + err = mutex_lock_interruptible(&ab->access_mutex); + if (err) + return err; + + if (bitmask == 0xFF) /* No need to read in this case. */ + buf = bitvalues; + else { /* Read and modify the register value. */ + err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, + reg, &buf, 1); + if (err) + return err; + + buf = ((~bitmask & buf) | (bitmask & bitvalues)); + } + /* Write the new value. */ + err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg, + &buf, 1); + + mutex_unlock(&ab->access_mutex); + } + return err; +} + +static int +set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value) +{ + return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, + 0xff, value); +} + +/* + * Read/write permission checking functions. + */ +static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank) +{ + u8 i; + + if (devid < AB5500_NUM_DEVICES) { + for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) { + if (ab5500_bank_ranges[devid].bank[i].bankid == bank) + return &ab5500_bank_ranges[devid].bank[i]; + } + } + return NULL; +} + +static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) +{ + u8 i; /* range loop index */ + const struct ab5500_i2c_ranges *bankref; + + bankref = get_bankref(devid, bank); + if (bankref == NULL || last_reg < first_reg) + return false; + + for (i = 0; i < bankref->nranges; i++) { + if (first_reg < bankref->range[i].first) + break; + if ((last_reg <= bankref->range[i].last) && + (bankref->range[i].perm & AB5500_PERM_WR)) + return true; + } + return false; +} + +static bool reg_write_allowed(u8 devid, u8 bank, u8 reg) +{ + return page_write_allowed(devid, bank, reg, reg); +} + +static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) +{ + u8 i; + const struct ab5500_i2c_ranges *bankref; + + bankref = get_bankref(devid, bank); + if (bankref == NULL || last_reg < first_reg) + return false; + + + /* Find the range (if it exists in the list) that includes first_reg. */ + for (i = 0; i < bankref->nranges; i++) { + if (first_reg < bankref->range[i].first) + return false; + if (first_reg <= bankref->range[i].last) + break; + } + /* Make sure that the entire range up to and including last_reg is + * readable. This may span several of the ranges in the list. + */ + while ((i < bankref->nranges) && + (bankref->range[i].perm & AB5500_PERM_RD)) { + if (last_reg <= bankref->range[i].last) + return true; + if ((++i >= bankref->nranges) || + (bankref->range[i].first != + (bankref->range[i - 1].last + 1))) { + break; + } + } + return false; +} + +static bool reg_read_allowed(u8 devid, u8 bank, u8 reg) +{ + return page_read_allowed(devid, bank, reg, reg); +} + + +/* + * The exported register access functionality. + */ +static int ab5500_get_chip_id(struct device *dev) +{ + struct ab5500 *ab = dev_get_drvdata(dev->parent); + + return (int)ab->chip_id; +} + +static int ab5500_mask_and_set_register_interruptible(struct device *dev, + u8 bank, u8 reg, u8 bitmask, u8 bitvalues) +{ + struct ab5500 *ab; + struct platform_device *pdev = to_platform_device(dev); + + if ((AB5500_NUM_BANKS <= bank) || + !reg_write_allowed(pdev->id, bank, reg)) + return -EINVAL; + + ab = dev_get_drvdata(dev->parent); + return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, + bitmask, bitvalues); +} + +static int ab5500_set_register_interruptible(struct device *dev, u8 bank, + u8 reg, u8 value) +{ + return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF, + value); +} + +static int ab5500_get_register_interruptible(struct device *dev, u8 bank, + u8 reg, u8 *value) +{ + struct ab5500 *ab; + struct platform_device *pdev = to_platform_device(dev); + + if ((AB5500_NUM_BANKS <= bank) || + !reg_read_allowed(pdev->id, bank, reg)) + return -EINVAL; + + ab = dev_get_drvdata(dev->parent); + return ab5500_get_register_interruptible_raw(ab, bank, reg, value); +} + +static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs) +{ + struct ab5500 *ab; + struct platform_device *pdev = to_platform_device(dev); + + if ((AB5500_NUM_BANKS <= bank) || + !page_read_allowed(pdev->id, bank, + first_reg, (first_reg + numregs - 1))) + return -EINVAL; + + ab = dev_get_drvdata(dev->parent); + return get_register_page_interruptible(ab, bank, first_reg, regvals, + numregs); +} + +static int +ab5500_event_registers_startup_state_get(struct device *dev, u8 *event) +{ + struct ab5500 *ab; + + ab = dev_get_drvdata(dev->parent); + if (!ab->startup_events_read) + return -EAGAIN; /* Try again later */ + + memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG); + return 0; +} + +static struct abx500_ops ab5500_ops = { + .get_chip_id = ab5500_get_chip_id, + .get_register = ab5500_get_register_interruptible, + .set_register = ab5500_set_register_interruptible, + .get_register_page = ab5500_get_register_page_interruptible, + .set_register_page = NULL, + .mask_and_set_register = ab5500_mask_and_set_register_interruptible, + .event_registers_startup_state_get = + ab5500_event_registers_startup_state_get, + .startup_irq_enabled = NULL, +}; + +/* + * ab5500_setup : Basic set-up, datastructure creation/destruction + * and I2C interface.This sets up a default config + * in the AB5500 chip so that it will work as expected. + * @ab : Pointer to ab5500 structure + * @settings : Pointer to struct abx500_init_settings + * @size : Size of init data + */ +static int __init ab5500_setup(struct ab5500 *ab, + struct abx500_init_settings *settings, unsigned int size) +{ + int err = 0; + int i; + + for (i = 0; i < size; i++) { + err = ab5500_mask_and_set_register_interruptible_raw(ab, + settings[i].bank, + settings[i].reg, + 0xFF, settings[i].setting); + if (err) + goto exit_no_setup; + + /* If event mask register update the event mask in ab5500 */ + if ((settings[i].bank == AB5500_BANK_IT) && + (AB5500_MASK_BASE <= settings[i].reg) && + (settings[i].reg <= AB5500_MASK_END)) { + ab->mask[settings[i].reg - AB5500_MASK_BASE] = + settings[i].setting; + } + } +exit_no_setup: + return err; +} + +struct ab_family_id { + u8 id; + char *name; +}; + +static const struct ab_family_id ids[] __initdata = { + /* AB5500 */ + { + .id = AB5500_1_0, + .name = "1.0" + }, + { + .id = AB5500_1_1, + .name = "1.1" + }, + /* Terminator */ + { + .id = 0x00, + } +}; + +static int __init ab5500_probe(struct platform_device *pdev) +{ + struct ab5500 *ab; + struct ab5500_platform_data *ab5500_plf_data = + pdev->dev.platform_data; + int err; + int i; + + ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL); + if (!ab) { + dev_err(&pdev->dev, + "could not allocate ab5500 device\n"); + return -ENOMEM; + } + + /* Initialize data structure */ + mutex_init(&ab->access_mutex); + mutex_init(&ab->irq_lock); + ab->dev = &pdev->dev; + + platform_set_drvdata(pdev, ab); + + /* Read chip ID register */ + err = ab5500_get_register_interruptible_raw(ab, + AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, + AB5500_CHIP_ID, &ab->chip_id); + if (err) { + dev_err(&pdev->dev, "could not communicate with the analog " + "baseband chip\n"); + goto exit_no_detect; + } + + for (i = 0; ids[i].id != 0x0; i++) { + if (ids[i].id == ab->chip_id) { + snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1, + "AB5500 %s", ids[i].name); + break; + } + } + if (ids[i].id == 0x0) { + dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n", + ab->chip_id); + dev_err(&pdev->dev, "driver not started!\n"); + goto exit_no_detect; + } + + /* Clear and mask all interrupts */ + for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) { + u8 latchreg = AB5500_IT_LATCH0_REG + i; + u8 maskreg = AB5500_IT_MASK0_REG + i; + u8 val; + + ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT, + latchreg, &val); + set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff); + ab->mask[i] = ab->oldmask[i] = 0xff; + } + + err = abx500_register_ops(&pdev->dev, &ab5500_ops); + if (err) { + dev_err(&pdev->dev, "ab5500_register ops error\n"); + goto exit_no_detect; + } + + /* Set up and register the platform devices. */ + for (i = 0; i < AB5500_NUM_DEVICES; i++) { + ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i]; + ab5500_devs[i].pdata_size = + sizeof(ab5500_plf_data->dev_data[i]); + } + + err = mfd_add_devices(&pdev->dev, 0, ab5500_devs, + ARRAY_SIZE(ab5500_devs), NULL, + ab5500_plf_data->irq.base); + if (err) { + dev_err(&pdev->dev, "ab5500_mfd_add_device error\n"); + goto exit_no_detect; + } + + err = ab5500_setup(ab, ab5500_plf_data->init_settings, + ab5500_plf_data->init_settings_sz); + if (err) { + dev_err(&pdev->dev, "ab5500_setup error\n"); + goto exit_no_detect; + } + + ab5500_setup_debugfs(ab); + + dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]); + return 0; + +exit_no_detect: + kfree(ab); + return err; +} + +static int __exit ab5500_remove(struct platform_device *pdev) +{ + struct ab5500 *ab = platform_get_drvdata(pdev); + + ab5500_remove_debugfs(); + mfd_remove_devices(&pdev->dev); + kfree(ab); + return 0; +} + +static struct platform_driver ab5500_driver = { + .driver = { + .name = "ab5500-core", + .owner = THIS_MODULE, + }, + .remove = __exit_p(ab5500_remove), +}; + +static int __init ab5500_core_init(void) +{ + return platform_driver_probe(&ab5500_driver, ab5500_probe); +} + +static void __exit ab5500_core_exit(void) +{ + platform_driver_unregister(&ab5500_driver); +} + +subsys_initcall(ab5500_core_init); +module_exit(ab5500_core_exit); + +MODULE_AUTHOR("Mattias Wallin "); +MODULE_DESCRIPTION("AB5500 core driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mfd/ab5500-debugfs.c b/trunk/drivers/mfd/ab5500-debugfs.c new file mode 100644 index 000000000000..72006940937a --- /dev/null +++ b/trunk/drivers/mfd/ab5500-debugfs.c @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2011 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Debugfs support for the AB5500 MFD driver + */ + +#include +#include +#include +#include +#include +#include + +#include "ab5500-core.h" +#include "ab5500-debugfs.h" + +static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = { + [AB5500_BANK_LED] = { + .bankid = AB5500_BANK_LED, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x0C, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_ADC] = { + .bankid = AB5500_BANK_ADC, + .nranges = 6, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x1F, + .last = 0x22, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x23, + .last = 0x24, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x26, + .last = 0x2D, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x2F, + .last = 0x34, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x37, + .last = 0x57, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x58, + .last = 0x58, + .perm = AB5500_PERM_RO, + }, + }, + }, + [AB5500_BANK_RTC] = { + .bankid = AB5500_BANK_RTC, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x04, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x06, + .last = 0x0C, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_STARTUP] = { + .bankid = AB5500_BANK_STARTUP, + .nranges = 12, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x01, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x1F, + .last = 0x1F, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x2E, + .last = 0x2E, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x2F, + .last = 0x30, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x50, + .last = 0x51, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x60, + .last = 0x61, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x66, + .last = 0x8A, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x8C, + .last = 0x96, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xAA, + .last = 0xB4, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xB7, + .last = 0xBF, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xC1, + .last = 0xCA, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xD3, + .last = 0xE0, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_DBI_ECI] = { + .bankid = AB5500_BANK_DBI_ECI, + .nranges = 3, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x07, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x10, + .last = 0x10, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x13, + .last = 0x13, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_CHG] = { + .bankid = AB5500_BANK_CHG, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x11, + .last = 0x11, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x12, + .last = 0x1B, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_FG_BATTCOM_ACC] = { + .bankid = AB5500_BANK_FG_BATTCOM_ACC, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x0B, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x0C, + .last = 0x10, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_USB] = { + .bankid = AB5500_BANK_USB, + .nranges = 12, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x01, + .last = 0x01, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x80, + .last = 0x83, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x87, + .last = 0x8A, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x8B, + .last = 0x8B, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x91, + .last = 0x92, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x93, + .last = 0x93, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x94, + .last = 0x94, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xA8, + .last = 0xB0, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xB2, + .last = 0xB2, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xB4, + .last = 0xBC, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xBF, + .last = 0xBF, + .perm = AB5500_PERM_RO, + }, + { + .first = 0xC1, + .last = 0xC5, + .perm = AB5500_PERM_RO, + }, + }, + }, + [AB5500_BANK_IT] = { + .bankid = AB5500_BANK_IT, + .nranges = 4, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x02, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x20, + .last = 0x36, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x40, + .last = 0x56, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x60, + .last = 0x76, + .perm = AB5500_PERM_RO, + }, + }, + }, + [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { + .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST, + .nranges = 7, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x02, + .last = 0x02, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x12, + .last = 0x12, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x30, + .last = 0x34, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x40, + .last = 0x44, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x50, + .last = 0x54, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x60, + .last = 0x64, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x70, + .last = 0x74, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { + .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, + .nranges = 13, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x01, + .last = 0x01, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x02, + .last = 0x02, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x0D, + .last = 0x0F, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x1C, + .last = 0x1C, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x1E, + .last = 0x1E, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x20, + .last = 0x21, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x25, + .last = 0x25, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x28, + .last = 0x2A, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x30, + .last = 0x33, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x40, + .last = 0x43, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x50, + .last = 0x53, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x60, + .last = 0x63, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x70, + .last = 0x73, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_VIBRA] = { + .bankid = AB5500_BANK_VIBRA, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x10, + .last = 0x13, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xFE, + .last = 0xFE, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_AUDIO_HEADSETUSB] = { + .bankid = AB5500_BANK_AUDIO_HEADSETUSB, + .nranges = 2, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x48, + .perm = AB5500_PERM_RW, + }, + { + .first = 0xEB, + .last = 0xFB, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_SIM_USBSIM] = { + .bankid = AB5500_BANK_SIM_USBSIM, + .nranges = 1, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x13, + .last = 0x19, + .perm = AB5500_PERM_RW, + }, + }, + }, + [AB5500_BANK_VDENC] = { + .bankid = AB5500_BANK_VDENC, + .nranges = 12, + .range = (struct ab5500_reg_range[]) { + { + .first = 0x00, + .last = 0x08, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x09, + .last = 0x09, + .perm = AB5500_PERM_RO, + }, + { + .first = 0x0A, + .last = 0x12, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x15, + .last = 0x19, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x1B, + .last = 0x21, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x27, + .last = 0x2C, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x41, + .last = 0x41, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x45, + .last = 0x5B, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x5D, + .last = 0x5D, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x69, + .last = 0x69, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x6C, + .last = 0x6D, + .perm = AB5500_PERM_RW, + }, + { + .first = 0x80, + .last = 0x81, + .perm = AB5500_PERM_RW, + }, + }, + }, +}; + +static int ab5500_registers_print(struct seq_file *s, void *p) +{ + struct ab5500 *ab = s->private; + unsigned int i; + u8 bank = (u8)ab->debug_bank; + + seq_printf(s, "ab5500 register values:\n"); + for (bank = 0; bank < AB5500_NUM_BANKS; bank++) { + seq_printf(s, " bank %u, %s (0x%x):\n", bank, + bankinfo[bank].name, + bankinfo[bank].slave_addr); + for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) { + u8 reg; + int err; + + for (reg = ab5500_reg_ranges[bank].range[i].first; + reg <= ab5500_reg_ranges[bank].range[i].last; + reg++) { + u8 value; + + err = ab5500_get_register_interruptible_raw(ab, + bank, reg, + &value); + if (err < 0) { + dev_err(ab->dev, "get_reg failed %d" + "bank 0x%x reg 0x%x\n", + err, bank, reg); + return err; + } + + err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n", + bank, reg, value); + if (err < 0) { + dev_err(ab->dev, + "seq_printf overflow\n"); + /* + * Error is not returned here since + * the output is wanted in any case + */ + return 0; + } + } + } + } + return 0; +} + +static int ab5500_registers_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab5500_registers_print, inode->i_private); +} + +static const struct file_operations ab5500_registers_fops = { + .open = ab5500_registers_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab5500_bank_print(struct seq_file *s, void *p) +{ + struct ab5500 *ab = s->private; + + seq_printf(s, "%d\n", ab->debug_bank); + return 0; +} + +static int ab5500_bank_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab5500_bank_print, inode->i_private); +} + +static ssize_t ab5500_bank_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_bank; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_bank); + if (err) + return -EINVAL; + + if (user_bank >= AB5500_NUM_BANKS) { + dev_err(ab->dev, + "debugfs error input > number of banks\n"); + return -EINVAL; + } + + ab->debug_bank = user_bank; + + return buf_size; +} + +static int ab5500_address_print(struct seq_file *s, void *p) +{ + struct ab5500 *ab = s->private; + + seq_printf(s, "0x%02X\n", ab->debug_address); + return 0; +} + +static int ab5500_address_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab5500_address_print, inode->i_private); +} + +static ssize_t ab5500_address_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_address; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_address); + if (err) + return -EINVAL; + if (user_address > 0xff) { + dev_err(ab->dev, + "debugfs error input > 0xff\n"); + return -EINVAL; + } + ab->debug_address = user_address; + return buf_size; +} + +static int ab5500_val_print(struct seq_file *s, void *p) +{ + struct ab5500 *ab = s->private; + int err; + u8 regvalue; + + err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, + (u8)ab->debug_address, ®value); + if (err) { + dev_err(ab->dev, "get_reg failed %d, bank 0x%x" + ", reg 0x%x\n", err, ab->debug_bank, + ab->debug_address); + return -EINVAL; + } + seq_printf(s, "0x%02X\n", regvalue); + + return 0; +} + +static int ab5500_val_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab5500_val_print, inode->i_private); +} + +static ssize_t ab5500_val_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_val; + int err; + u8 regvalue; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_val); + if (err) + return -EINVAL; + if (user_val > 0xff) { + dev_err(ab->dev, + "debugfs error input > 0xff\n"); + return -EINVAL; + } + err = ab5500_mask_and_set_register_interruptible_raw( + ab, (u8)ab->debug_bank, + (u8)ab->debug_address, 0xFF, (u8)user_val); + if (err) + return -EINVAL; + + ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, + (u8)ab->debug_address, ®value); + if (err) + return -EINVAL; + + return buf_size; +} + +static const struct file_operations ab5500_bank_fops = { + .open = ab5500_bank_open, + .write = ab5500_bank_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ab5500_address_fops = { + .open = ab5500_address_open, + .write = ab5500_address_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ab5500_val_fops = { + .open = ab5500_val_open, + .write = ab5500_val_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static struct dentry *ab5500_dir; +static struct dentry *ab5500_reg_file; +static struct dentry *ab5500_bank_file; +static struct dentry *ab5500_address_file; +static struct dentry *ab5500_val_file; + +void __init ab5500_setup_debugfs(struct ab5500 *ab) +{ + ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP; + ab->debug_address = AB5500_CHIP_ID; + + ab5500_dir = debugfs_create_dir("ab5500", NULL); + if (!ab5500_dir) + goto exit_no_debugfs; + + ab5500_reg_file = debugfs_create_file("all-bank-registers", + S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops); + if (!ab5500_reg_file) + goto exit_destroy_dir; + + ab5500_bank_file = debugfs_create_file("register-bank", + (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops); + if (!ab5500_bank_file) + goto exit_destroy_reg; + + ab5500_address_file = debugfs_create_file("register-address", + (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops); + if (!ab5500_address_file) + goto exit_destroy_bank; + + ab5500_val_file = debugfs_create_file("register-value", + (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops); + if (!ab5500_val_file) + goto exit_destroy_address; + + return; + +exit_destroy_address: + debugfs_remove(ab5500_address_file); +exit_destroy_bank: + debugfs_remove(ab5500_bank_file); +exit_destroy_reg: + debugfs_remove(ab5500_reg_file); +exit_destroy_dir: + debugfs_remove(ab5500_dir); +exit_no_debugfs: + dev_err(ab->dev, "failed to create debugfs entries.\n"); + return; +} + +void __exit ab5500_remove_debugfs(void) +{ + debugfs_remove(ab5500_val_file); + debugfs_remove(ab5500_address_file); + debugfs_remove(ab5500_bank_file); + debugfs_remove(ab5500_reg_file); + debugfs_remove(ab5500_dir); +} diff --git a/trunk/drivers/mfd/ab5500-debugfs.h b/trunk/drivers/mfd/ab5500-debugfs.h new file mode 100644 index 000000000000..7330a9b6afa6 --- /dev/null +++ b/trunk/drivers/mfd/ab5500-debugfs.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2011 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Debugfs interface to the AB5500 core driver + */ + +#ifdef CONFIG_DEBUG_FS + +void ab5500_setup_debugfs(struct ab5500 *ab); +void ab5500_remove_debugfs(void); + +#else /* !CONFIG_DEBUG_FS */ + +static inline void ab5500_setup_debugfs(struct ab5500 *ab) +{ +} + +static inline void ab5500_remove_debugfs(void) +{ +} + +#endif diff --git a/trunk/drivers/mfd/asic3.c b/trunk/drivers/mfd/asic3.c index 1582c3d95257..1895cf9fab8c 100644 --- a/trunk/drivers/mfd/asic3.c +++ b/trunk/drivers/mfd/asic3.c @@ -527,9 +527,7 @@ static void asic3_gpio_set(struct gpio_chip *chip, static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - struct asic3 *asic = container_of(chip, struct asic3, gpio); - - return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; + return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO; } static __init int asic3_gpio_probe(struct platform_device *pdev, diff --git a/trunk/drivers/mfd/db5500-prcmu.c b/trunk/drivers/mfd/db5500-prcmu.c new file mode 100644 index 000000000000..bb115b2f04e9 --- /dev/null +++ b/trunk/drivers/mfd/db5500-prcmu.c @@ -0,0 +1,451 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Mattias Nilsson + * + * U5500 PRCM Unit interface driver + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dbx500-prcmu-regs.h" + +#define _PRCM_MB_HEADER (tcdm_base + 0xFE8) +#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) +#define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1) +#define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2) +#define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3) +#define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4) +#define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5) +#define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6) +#define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7) +#define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8) +#define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9) +#define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa) +#define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb) +#define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc) +#define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd) +#define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe) +#define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf) + +/* Req Mailboxes */ +#define PRCM_REQ_MB0 (tcdm_base + 0xFD8) +#define PRCM_REQ_MB1 (tcdm_base + 0xFCC) +#define PRCM_REQ_MB2 (tcdm_base + 0xFC4) +#define PRCM_REQ_MB3 (tcdm_base + 0xFC0) +#define PRCM_REQ_MB4 (tcdm_base + 0xF98) +#define PRCM_REQ_MB5 (tcdm_base + 0xF90) +#define PRCM_REQ_MB6 (tcdm_base + 0xF8C) +#define PRCM_REQ_MB7 (tcdm_base + 0xF84) + +/* Ack Mailboxes */ +#define PRCM_ACK_MB0 (tcdm_base + 0xF38) +#define PRCM_ACK_MB1 (tcdm_base + 0xF30) +#define PRCM_ACK_MB2 (tcdm_base + 0xF24) +#define PRCM_ACK_MB3 (tcdm_base + 0xF20) +#define PRCM_ACK_MB4 (tcdm_base + 0xF1C) +#define PRCM_ACK_MB5 (tcdm_base + 0xF14) +#define PRCM_ACK_MB6 (tcdm_base + 0xF0C) +#define PRCM_ACK_MB7 (tcdm_base + 0xF08) + +enum mb_return_code { + RC_SUCCESS, + RC_FAIL, +}; + +/* Mailbox 0 headers. */ +enum mb0_header { + /* request */ + RMB0H_PWR_STATE_TRANS = 1, + RMB0H_WAKE_UP_CFG, + RMB0H_RD_WAKE_UP_ACK, + /* acknowledge */ + AMB0H_WAKE_UP = 1, +}; + +/* Mailbox 5 headers. */ +enum mb5_header { + MB5H_I2C_WRITE = 1, + MB5H_I2C_READ, +}; + +/* Request mailbox 5 fields. */ +#define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0) +#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1) +#define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2) +#define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4) + +/* Acknowledge mailbox 5 fields. */ +#define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0) +#define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4) + +#define NUM_MB 8 +#define MBOX_BIT BIT +#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) + +/* +* Used by MCDE to setup all necessary PRCMU registers +*/ +#define PRCMU_RESET_DSIPLL 0x00004000 +#define PRCMU_UNCLAMP_DSIPLL 0x00400800 + +/* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/ +#define PRCMU_DSI_CLOCK_SETTING 0x00000128 +/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ +#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 +#define PRCMU_PLLDSI_FREQ_SETTING 0x00020121 +#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 +#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000201 +#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 + +#define PRCMU_ENABLE_PLLDSI 0x00000001 +#define PRCMU_DISABLE_PLLDSI 0x00000000 + +#define PRCMU_DSI_RESET_SW 0x00000003 +#define PRCMU_RESOUTN0_PIN 0x00000001 +#define PRCMU_RESOUTN1_PIN 0x00000002 +#define PRCMU_RESOUTN2_PIN 0x00000004 + +#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 + +/* + * mb0_transfer - state needed for mailbox 0 communication. + * @lock: The transaction lock. + */ +static struct { + spinlock_t lock; +} mb0_transfer; + +/* + * mb5_transfer - state needed for mailbox 5 communication. + * @lock: The transaction lock. + * @work: The transaction completion structure. + * @ack: Reply ("acknowledge") data. + */ +static struct { + struct mutex lock; + struct completion work; + struct { + u8 header; + u8 status; + u8 value[4]; + } ack; +} mb5_transfer; + +/* PRCMU TCDM base IO address. */ +static __iomem void *tcdm_base; + +/** + * db5500_prcmu_abb_read() - Read register value(s) from the ABB. + * @slave: The I2C slave address. + * @reg: The (start) register address. + * @value: The read out value(s). + * @size: The number of registers to read. + * + * Reads register value(s) from the ABB. + * @size has to be <= 4. + */ +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + int r; + + if ((size < 1) || (4 < size)) + return -EINVAL; + + mutex_lock(&mb5_transfer.lock); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + cpu_relax(); + writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); + writeb(reg, PRCM_REQ_MB5_I2C_REG); + writeb(size, PRCM_REQ_MB5_I2C_SIZE); + writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER); + + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); + wait_for_completion(&mb5_transfer.work); + + r = 0; + if ((mb5_transfer.ack.header == MB5H_I2C_READ) && + (mb5_transfer.ack.status == RC_SUCCESS)) + memcpy(value, mb5_transfer.ack.value, (size_t)size); + else + r = -EIO; + + mutex_unlock(&mb5_transfer.lock); + + return r; +} + +/** + * db5500_prcmu_abb_write() - Write register value(s) to the ABB. + * @slave: The I2C slave address. + * @reg: The (start) register address. + * @value: The value(s) to write. + * @size: The number of registers to write. + * + * Writes register value(s) to the ABB. + * @size has to be <= 4. + */ +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + int r; + + if ((size < 1) || (4 < size)) + return -EINVAL; + + mutex_lock(&mb5_transfer.lock); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + cpu_relax(); + writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); + writeb(reg, PRCM_REQ_MB5_I2C_REG); + writeb(size, PRCM_REQ_MB5_I2C_SIZE); + memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size); + writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER); + + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); + wait_for_completion(&mb5_transfer.work); + + if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) && + (mb5_transfer.ack.status == RC_SUCCESS)) + r = 0; + else + r = -EIO; + + mutex_unlock(&mb5_transfer.lock); + + return r; +} + +int db5500_prcmu_enable_dsipll(void) +{ + int i; + + /* Enable DSIPLL_RESETN resets */ + writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); + /* Unclamp DSIPLL in/out */ + writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); + /* Set DSI PLL FREQ */ + writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ); + writel(PRCMU_DSI_PLLOUT_SEL_SETTING, + PRCM_DSI_PLLOUT_SEL); + /* Enable Escape clocks */ + writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); + + /* Start DSI PLL */ + writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); + /* Reset DSI PLL */ + writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); + for (i = 0; i < 10; i++) { + if ((readl(PRCM_PLLDSI_LOCKP) & + PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED) + break; + udelay(100); + } + /* Release DSIPLL_RESETN */ + writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); + return 0; +} + +int db5500_prcmu_disable_dsipll(void) +{ + /* Disable dsi pll */ + writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); + /* Disable escapeclock */ + writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); + return 0; +} + +int db5500_prcmu_set_display_clocks(void) +{ + /* HDMI and TVCLK Should be handled somewhere else */ + /* PLLDIV=8, PLLSW=2, CLKEN=1 */ + writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); + /* PLLDIV=14, PLLSW=2, CLKEN=1 */ + writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); + return 0; +} + +static void ack_dbb_wakeup(void) +{ + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) + cpu_relax(); + + writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER); + writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); +} + +static inline void print_unknown_header_warning(u8 n, u8 header) +{ + pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", + header, n); +} + +static bool read_mailbox_0(void) +{ + bool r; + u8 header; + + header = readb(PRCM_ACK_MB0_HEADER); + switch (header) { + case AMB0H_WAKE_UP: + r = true; + break; + default: + print_unknown_header_warning(0, header); + r = false; + break; + } + writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR); + return r; +} + +static bool read_mailbox_1(void) +{ + writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR); + return false; +} + +static bool read_mailbox_2(void) +{ + writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR); + return false; +} + +static bool read_mailbox_3(void) +{ + writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR); + return false; +} + +static bool read_mailbox_4(void) +{ + writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR); + return false; +} + +static bool read_mailbox_5(void) +{ + u8 header; + + header = readb(PRCM_ACK_MB5_HEADER); + switch (header) { + case MB5H_I2C_READ: + memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4); + case MB5H_I2C_WRITE: + mb5_transfer.ack.header = header; + mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE); + complete(&mb5_transfer.work); + break; + default: + print_unknown_header_warning(5, header); + break; + } + writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR); + return false; +} + +static bool read_mailbox_6(void) +{ + writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR); + return false; +} + +static bool read_mailbox_7(void) +{ + writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR); + return false; +} + +static bool (* const read_mailbox[NUM_MB])(void) = { + read_mailbox_0, + read_mailbox_1, + read_mailbox_2, + read_mailbox_3, + read_mailbox_4, + read_mailbox_5, + read_mailbox_6, + read_mailbox_7 +}; + +static irqreturn_t prcmu_irq_handler(int irq, void *data) +{ + u32 bits; + u8 n; + irqreturn_t r; + + bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); + if (unlikely(!bits)) + return IRQ_NONE; + + r = IRQ_HANDLED; + for (n = 0; bits; n++) { + if (bits & MBOX_BIT(n)) { + bits -= MBOX_BIT(n); + if (read_mailbox[n]()) + r = IRQ_WAKE_THREAD; + } + } + return r; +} + +static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) +{ + ack_dbb_wakeup(); + return IRQ_HANDLED; +} + +void __init db5500_prcmu_early_init(void) +{ + tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE); + spin_lock_init(&mb0_transfer.lock); + mutex_init(&mb5_transfer.lock); + init_completion(&mb5_transfer.work); +} + +/** + * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic + * + */ +int __init db5500_prcmu_init(void) +{ + int r = 0; + + if (ux500_is_svp() || !cpu_is_u5500()) + return -ENODEV; + + /* Clean up the mailbox interrupts after pre-kernel code. */ + writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); + + r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, + prcmu_irq_thread_fn, 0, "prcmu", NULL); + if (r < 0) { + pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n"); + return -EBUSY; + } + return 0; +} + +arch_initcall(db5500_prcmu_init); diff --git a/trunk/drivers/mfd/db8500-prcmu.c b/trunk/drivers/mfd/db8500-prcmu.c index 5be32489714f..ebc1e8658226 100644 --- a/trunk/drivers/mfd/db8500-prcmu.c +++ b/trunk/drivers/mfd/db8500-prcmu.c @@ -2788,7 +2788,6 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { .constraints = { .name = "db8500-vape", .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .always_on = true, }, .consumer_supplies = db8500_vape_consumers, .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), diff --git a/trunk/drivers/mfd/omap-usb-host.c b/trunk/drivers/mfd/omap-usb-host.c index c8aae6640e64..95a2e546a489 100644 --- a/trunk/drivers/mfd/omap-usb-host.c +++ b/trunk/drivers/mfd/omap-usb-host.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -501,6 +502,19 @@ static void omap_usbhs_init(struct device *dev) pm_runtime_get_sync(dev); spin_lock_irqsave(&omap->lock, flags); + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[0], + GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[1], + GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(10); + } + omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -579,10 +593,39 @@ static void omap_usbhs_init(struct device *dev) usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } + if (pdata->ehci_data->phy_reset) { + /* Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[0], 1); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[1], 1); + } + spin_unlock_irqrestore(&omap->lock, flags); pm_runtime_put_sync(dev); } +static void omap_usbhs_deinit(struct device *dev) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = &omap->platdata; + + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_free(pdata->ehci_data->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_free(pdata->ehci_data->reset_gpio_port[1]); + } +} + /** * usbhs_omap_probe - initialize TI-based HCDs @@ -817,6 +860,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) { struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); + omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); iounmap(omap->uhh_base); clk_put(omap->init_60m_fclk); diff --git a/trunk/drivers/mfd/rc5t583.c b/trunk/drivers/mfd/rc5t583.c index 44afae0a69ce..99ef944c621d 100644 --- a/trunk/drivers/mfd/rc5t583.c +++ b/trunk/drivers/mfd/rc5t583.c @@ -80,6 +80,44 @@ static struct mfd_cell rc5t583_subdevs[] = { {.name = "rc5t583-key", } }; +int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_write(rc5t583->regmap, reg, val); +} + +int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + unsigned int ival; + int ret; + ret = regmap_read(rc5t583->regmap, reg, &ival); + if (!ret) + *val = (uint8_t)ival; + return ret; +} + +int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); +} + +int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); +} + +int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, mask, val); +} + static int __rc5t583_set_ext_pwrreq1_control(struct device *dev, int id, int ext_pwr, int slots) { @@ -159,7 +197,6 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id, ds_id, ext_pwr_req); return 0; } -EXPORT_SYMBOL(rc5t583_ext_power_req_config); static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583, struct rc5t583_platform_data *pdata) diff --git a/trunk/drivers/mfd/twl6040-core.c b/trunk/drivers/mfd/twl6040-core.c index 2d6bedadca09..b2d8e512d3cb 100644 --- a/trunk/drivers/mfd/twl6040-core.c +++ b/trunk/drivers/mfd/twl6040-core.c @@ -30,9 +30,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -41,7 +39,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) { int ret; - unsigned int val; + u8 val = 0; mutex_lock(&twl6040->io_mutex); /* Vibra control registers from cache */ @@ -49,7 +47,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) reg == TWL6040_REG_VIBCTLR)) { val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)]; } else { - ret = regmap_read(twl6040->regmap, reg, &val); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); if (ret < 0) { mutex_unlock(&twl6040->io_mutex); return ret; @@ -66,7 +64,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val) int ret; mutex_lock(&twl6040->io_mutex); - ret = regmap_write(twl6040->regmap, reg, val); + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); /* Cache the vibra control registers */ if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR) twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; @@ -79,9 +77,16 @@ EXPORT_SYMBOL(twl6040_reg_write); int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; + u8 val; mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, mask); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + if (ret) + goto out; + + val |= mask; + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +out: mutex_unlock(&twl6040->io_mutex); return ret; } @@ -90,9 +95,16 @@ EXPORT_SYMBOL(twl6040_set_bits); int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; + u8 val; mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, 0); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + if (ret) + goto out; + + val &= ~mask; + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +out: mutex_unlock(&twl6040->io_mutex); return ret; } @@ -482,58 +494,32 @@ static struct resource twl6040_codec_rsrc[] = { }, }; -static bool twl6040_readable_reg(struct device *dev, unsigned int reg) +static int __devinit twl6040_probe(struct platform_device *pdev) { - /* Register 0 is not readable */ - if (!reg) - return false; - return true; -} - -static struct regmap_config twl6040_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = TWL6040_REG_STATUS, /* 0x2e */ - - .readable_reg = twl6040_readable_reg, -}; - -static int __devinit twl6040_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct twl6040_platform_data *pdata = client->dev.platform_data; + struct twl4030_audio_data *pdata = pdev->dev.platform_data; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int ret, children = 0; if (!pdata) { - dev_err(&client->dev, "Platform data is missing\n"); + dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ - if (!client->irq || !pdata->irq_base) { - dev_err(&client->dev, "Invalid IRQ configuration\n"); + if (!pdata->naudint_irq || !pdata->irq_base) { + dev_err(&pdev->dev, "Invalid IRQ configuration\n"); return -EINVAL; } - twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), - GFP_KERNEL); - if (!twl6040) { - ret = -ENOMEM; - goto err; - } - - twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); - if (IS_ERR(twl6040->regmap)) { - ret = PTR_ERR(twl6040->regmap); - goto err; - } + twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); + if (!twl6040) + return -ENOMEM; - i2c_set_clientdata(client, twl6040); + platform_set_drvdata(pdev, twl6040); - twl6040->dev = &client->dev; - twl6040->irq = client->irq; + twl6040->dev = &pdev->dev; + twl6040->irq = pdata->naudint_irq; twl6040->irq_base = pdata->irq_base; mutex_init(&twl6040->mutex); @@ -602,12 +588,12 @@ static int __devinit twl6040_probe(struct i2c_client *client, } if (children) { - ret = mfd_add_devices(&client->dev, -1, twl6040->cells, + ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, children, NULL, 0); if (ret) goto mfd_err; } else { - dev_err(&client->dev, "No platform data found for children\n"); + dev_err(&pdev->dev, "No platform data found for children\n"); ret = -ENODEV; goto mfd_err; } @@ -622,15 +608,14 @@ static int __devinit twl6040_probe(struct i2c_client *client, if (gpio_is_valid(twl6040->audpwron)) gpio_free(twl6040->audpwron); gpio1_err: - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); -err: + platform_set_drvdata(pdev, NULL); + kfree(twl6040); return ret; } -static int __devexit twl6040_remove(struct i2c_client *client) +static int __devexit twl6040_remove(struct platform_device *pdev) { - struct twl6040 *twl6040 = i2c_get_clientdata(client); + struct twl6040 *twl6040 = platform_get_drvdata(pdev); if (twl6040->power_count) twl6040_power(twl6040, 0); @@ -641,30 +626,23 @@ static int __devexit twl6040_remove(struct i2c_client *client) free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); twl6040_irq_exit(twl6040); - mfd_remove_devices(&client->dev); - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); + mfd_remove_devices(&pdev->dev); + platform_set_drvdata(pdev, NULL); + kfree(twl6040); return 0; } -static const struct i2c_device_id twl6040_i2c_id[] = { - { "twl6040", 0, }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); - -static struct i2c_driver twl6040_driver = { - .driver = { - .name = "twl6040", - .owner = THIS_MODULE, - }, +static struct platform_driver twl6040_driver = { .probe = twl6040_probe, .remove = __devexit_p(twl6040_remove), - .id_table = twl6040_i2c_id, + .driver = { + .owner = THIS_MODULE, + .name = "twl6040", + }, }; -module_i2c_driver(twl6040_driver); +module_platform_driver(twl6040_driver); MODULE_DESCRIPTION("TWL6040 MFD"); MODULE_AUTHOR("Misael Lopez Cruz "); diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index dabec556ebb8..b1809650b7aa 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg, trim_arg, erase_arg; + unsigned int from, nr, arg; int err = 0, type = MMC_BLK_SECDISCARD; if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { @@ -881,26 +881,20 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, goto out; } - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); - /* The sanitize operation is supported at v4.5 only */ if (mmc_can_sanitize(card)) { - erase_arg = MMC_ERASE_ARG; - trim_arg = MMC_TRIM_ARG; - } else { - erase_arg = MMC_SECURE_ERASE_ARG; - trim_arg = MMC_SECURE_TRIM1_ARG; - } - - if (mmc_erase_group_aligned(card, from, nr)) - arg = erase_arg; - else if (mmc_can_trim(card)) - arg = trim_arg; - else { - err = -EINVAL; + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1, 0); goto out; } + + from = blk_rq_pos(req); + nr = blk_rq_sectors(req); + + if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) + arg = MMC_SECURE_TRIM1_ARG; + else + arg = MMC_SECURE_ERASE_ARG; retry: if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -910,41 +904,25 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, INAND_CMD38_ARG_SECERASE, 0); if (err) - goto out_retry; + goto out; } - err = mmc_erase(card, from, nr, arg); - if (err == -EIO) - goto out_retry; - if (err) - goto out; - - if (arg == MMC_SECURE_TRIM1_ARG) { + if (!err && arg == MMC_SECURE_TRIM1_ARG) { if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, INAND_CMD38_ARG_EXT_CSD, INAND_CMD38_ARG_SECTRIM2, 0); if (err) - goto out_retry; + goto out; } - err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); - if (err == -EIO) - goto out_retry; - if (err) - goto out; } - - if (mmc_can_sanitize(card)) - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, 0); -out_retry: - if (err && !mmc_blk_reset(md, card->host, type)) +out: + if (err == -EIO && !mmc_blk_reset(md, card->host, type)) goto retry; if (!err) mmc_blk_reset_success(md, type); -out: spin_lock_irq(&md->lock); __blk_end_request(req, err, blk_rq_bytes(req)); spin_unlock_irq(&md->lock); @@ -1824,7 +1802,7 @@ static void mmc_blk_remove(struct mmc_card *card) } #ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card) +static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) { struct mmc_blk_data *part_md; struct mmc_blk_data *md = mmc_get_drvdata(card); diff --git a/trunk/drivers/mmc/card/queue.c b/trunk/drivers/mmc/card/queue.c index 996f8e36e23d..2517547b4366 100644 --- a/trunk/drivers/mmc/card/queue.c +++ b/trunk/drivers/mmc/card/queue.c @@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); q->limits.max_discard_sectors = max_discard; - if (card->erased_byte == 0 && !mmc_can_discard(card)) + if (card->erased_byte == 0) q->limits.discard_zeroes_data = 1; q->limits.discard_granularity = card->pref_erase << 9; /* granularity must not be greater than max. discard */ diff --git a/trunk/drivers/mmc/core/bus.c b/trunk/drivers/mmc/core/bus.c index c60cee92a2b2..3f606068d552 100644 --- a/trunk/drivers/mmc/core/bus.c +++ b/trunk/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev) return 0; } -static int mmc_bus_suspend(struct device *dev) +static int mmc_bus_suspend(struct device *dev, pm_message_t state) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; if (dev->driver && drv->suspend) - ret = drv->suspend(card); + ret = drv->suspend(card, state); return ret; } @@ -165,14 +165,20 @@ static int mmc_runtime_idle(struct device *dev) return pm_runtime_suspend(dev); } -#endif /* !CONFIG_PM_RUNTIME */ - static const struct dev_pm_ops mmc_bus_pm_ops = { - SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, - mmc_runtime_idle) - SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume) + .runtime_suspend = mmc_runtime_suspend, + .runtime_resume = mmc_runtime_resume, + .runtime_idle = mmc_runtime_idle, }; +#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) + +#else /* !CONFIG_PM_RUNTIME */ + +#define MMC_PM_OPS_PTR NULL + +#endif /* !CONFIG_PM_RUNTIME */ + static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -180,7 +186,9 @@ static struct bus_type mmc_bus_type = { .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, - .pm = &mmc_bus_pm_ops, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, + .pm = MMC_PM_OPS_PTR, }; int mmc_register_bus(void) diff --git a/trunk/drivers/mmc/core/cd-gpio.c b/trunk/drivers/mmc/core/cd-gpio.c index 2c14be73254c..29de31e260dd 100644 --- a/trunk/drivers/mmc/core/cd-gpio.c +++ b/trunk/drivers/mmc/core/cd-gpio.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index ba821fe70bca..7474c47b9c08 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -1409,10 +1409,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, { unsigned int erase_timeout; - if (arg == MMC_DISCARD_ARG || - (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { - erase_timeout = card->ext_csd.trim_timeout; - } else if (card->ext_csd.erase_group_def & 1) { + if (card->ext_csd.erase_group_def & 1) { /* High Capacity Erase Group Size uses HC timeouts */ if (arg == MMC_TRIM_ARG) erase_timeout = card->ext_csd.trim_timeout; @@ -1684,6 +1681,8 @@ int mmc_can_trim(struct mmc_card *card) { if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) return 1; + if (mmc_can_discard(card)) + return 1; return 0; } EXPORT_SYMBOL(mmc_can_trim); @@ -1702,8 +1701,6 @@ EXPORT_SYMBOL(mmc_can_discard); int mmc_can_sanitize(struct mmc_card *card) { - if (!mmc_can_trim(card) && !mmc_can_erase(card)) - return 0; if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) return 1; return 0; @@ -2238,7 +2235,6 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) mmc_card_is_removable(host)) return err; - mmc_claim_host(host); if (card && mmc_card_mmc(card) && (card->ext_csd.cache_size > 0)) { enable = !!enable; @@ -2256,7 +2252,6 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) card->ext_csd.cache_ctrl = enable; } } - mmc_release_host(host); return err; } @@ -2274,32 +2269,49 @@ int mmc_suspend_host(struct mmc_host *host) cancel_delayed_work(&host->detect); mmc_flush_scheduled_work(); + if (mmc_try_claim_host(host)) { + err = mmc_cache_ctrl(host, 0); + mmc_release_host(host); + } else { + err = -EBUSY; + } - err = mmc_cache_ctrl(host, 0); if (err) goto out; mmc_bus_get(host); if (host->bus_ops && !host->bus_dead) { - if (host->bus_ops->suspend) - err = host->bus_ops->suspend(host); - - if (err == -ENOSYS || !host->bus_ops->resume) { - /* - * We simply "remove" the card in this case. - * It will be redetected on resume. (Calling - * bus_ops->remove() with a claimed host can - * deadlock.) - */ - if (host->bus_ops->remove) - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_power_off(host); + /* + * A long response time is not acceptable for device drivers + * when doing suspend. Prevent mmc_claim_host in the suspend + * sequence, to potentially wait "forever" by trying to + * pre-claim the host. + */ + if (mmc_try_claim_host(host)) { + if (host->bus_ops->suspend) { + err = host->bus_ops->suspend(host); + } mmc_release_host(host); - host->pm_flags = 0; - err = 0; + + if (err == -ENOSYS || !host->bus_ops->resume) { + /* + * We simply "remove" the card in this case. + * It will be redetected on resume. (Calling + * bus_ops->remove() with a claimed host can + * deadlock.) + */ + if (host->bus_ops->remove) + host->bus_ops->remove(host); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_power_off(host); + mmc_release_host(host); + host->pm_flags = 0; + err = 0; + } + } else { + err = -EBUSY; } } mmc_bus_put(host); diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index ab3fc4617107..bf3c9b456aaf 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -526,10 +526,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) return -ENODEV; sg_len = dw_mci_pre_dma_transfer(host, data, 0); - if (sg_len < 0) { - host->dma_ops->stop(host); + if (sg_len < 0) return sg_len; - } host->using_dma = 1; @@ -1881,8 +1879,7 @@ static void dw_mci_init_dma(struct dw_mci *host) if (!host->dma_ops) goto no_dma; - if (host->dma_ops->init && host->dma_ops->start && - host->dma_ops->stop && host->dma_ops->cleanup) { + if (host->dma_ops->init) { if (host->dma_ops->init(host)) { dev_err(&host->dev, "%s: Unable to initialize " "DMA Controller.\n", __func__); diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index 56d4499d4388..5c2b1c10af9c 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, * the pbias cell programming support is still missing when * booting with Device tree */ - if (dev->of_node && !vdd) + if (of_have_populated_dt() && !vdd) return 0; if (mmc_slot(host).before_set_reg) @@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * can't be allowed when booting with device * tree. */ - !host->dev->of_node) { + (!of_have_populated_dt())) { /* * The mmc_select_voltage fn of the core does * not seem to set the power_mode to @@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = { .data = &omap4_reg_offset, }, {}, -}; +} MODULE_DEVICE_TABLE(of, omap_mmc_of_match); static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) diff --git a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c index 8abdaf6697a8..6193a0d7bde5 100644 --- a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c @@ -467,7 +467,8 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) clk_prepare_enable(clk); pltfm_host->clk = clk; - host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + if (!is_imx25_esdhc(imx_data)) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index ccefdebeff14..9aa77f3f04a8 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) u32 present, irqs; if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || - (host->mmc->caps & MMC_CAP_NONREMOVABLE)) + !mmc_card_is_removable(host->mmc)) return; present = sdhci_readl(host, SDHCI_PRESENT_STATE) & diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index 58fc65f5c817..94eb05b1afdf 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -106,14 +106,16 @@ static int mtdchar_open(struct inode *inode, struct file *file) } if (mtd->type == MTD_ABSENT) { + put_mtd_device(mtd); ret = -ENODEV; - goto out1; + goto out; } mtd_ino = iget_locked(mnt->mnt_sb, devnum); if (!mtd_ino) { + put_mtd_device(mtd); ret = -ENOMEM; - goto out1; + goto out; } if (mtd_ino->i_state & I_NEW) { mtd_ino->i_private = mtd; @@ -125,25 +127,23 @@ static int mtdchar_open(struct inode *inode, struct file *file) /* You can't open it RW if it's not a writeable device */ if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { + iput(mtd_ino); + put_mtd_device(mtd); ret = -EACCES; - goto out2; + goto out; } mfi = kzalloc(sizeof(*mfi), GFP_KERNEL); if (!mfi) { + iput(mtd_ino); + put_mtd_device(mtd); ret = -ENOMEM; - goto out2; + goto out; } mfi->ino = mtd_ino; mfi->mtd = mtd; file->private_data = mfi; - mutex_unlock(&mtd_mutex); - return 0; -out2: - iput(mtd_ino); -out1: - put_mtd_device(mtd); out: mutex_unlock(&mtd_mutex); simple_release_fs(&mnt, &count); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 2504ab005589..215eb2536b1e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc) if (--sc->ps_usecount != 0) goto unlock; - if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) + if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) + goto unlock; + + if (sc->ps_idle) mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK))) + PS_WAIT_FOR_PSPOLL_DATA))) mode = ATH9K_PM_NETWORK_SLEEP; else goto unlock; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 90cc5e772650..fc9901e027c1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1062,6 +1062,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags); + /* + * Register the extra components. + */ + rt2x00rfkill_register(rt2x00dev); + return 0; } @@ -1205,7 +1210,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) rt2x00link_register(rt2x00dev); rt2x00leds_register(rt2x00dev); rt2x00debug_register(rt2x00dev); - rt2x00rfkill_register(rt2x00dev); return 0; diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index e54488db0e10..510023554e5f 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -838,10 +838,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, __le16 fc = hdr->frame_control; txrate = ieee80211_get_tx_rate(hw, info); - if (txrate) - tcb_desc->hw_rate = txrate->hw_value; - else - tcb_desc->hw_rate = 0; + tcb_desc->hw_rate = txrate->hw_value; if (ieee80211_is_data(fc)) { /* diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index 288b035a3579..07dd38efe62a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -912,13 +912,8 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); ring = &rtlpci->tx_ring[BEACON_QUEUE]; pskb = __skb_dequeue(&ring->queue); - if (pskb) { - struct rtl_tx_desc *entry = &ring->desc[ring->idx]; - pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops->get_desc( - (u8 *) entry, true, HW_DESC_TXBUFF_ADDR), - pskb->len, PCI_DMA_TODEVICE); + if (pskb) kfree_skb(pskb); - } /*NB: the beacon data buffer must be 32-bit aligned. */ pskb = ieee80211_beacon_get(hw, mac->vif); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 480862c07f92..4898c502974d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -91,6 +91,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) u8 tid; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + static int header_print; rtlpriv->dm.dm_initialgain_enable = true; rtlpriv->dm.dm_flag = 0; @@ -170,6 +171,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) for (tid = 0; tid < 8; tid++) skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + /* Only load firmware for first MAC */ + if (header_print) + return 0; + /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { @@ -181,6 +186,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->max_fw_size = 0x8000; pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); + header_print++; /* request fw */ err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index d04dbda13f5a..2e1e352864bb 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -124,38 +124,46 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, return status; } -static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len) +static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len) { - struct device *dev = rtlpriv->io.dev; - struct usb_device *udev = to_usb_device(dev); u8 request; u16 wvalue; u16 index; - __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; + u32 *data; + u32 ret; + data = kmalloc(sizeof(u32), GFP_KERNEL); + if (!data) + return -ENOMEM; request = REALTEK_USB_VENQT_CMD_REQ; index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ wvalue = (u16)addr; _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); - if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) - rtlpriv->usb_data_index = 0; - return le32_to_cpu(*data); + ret = le32_to_cpu(*data); + kfree(data); + return ret; } static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { - return (u8)_usb_read_sync(rtlpriv, addr, 1); + struct device *dev = rtlpriv->io.dev; + + return (u8)_usb_read_sync(to_usb_device(dev), addr, 1); } static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr) { - return (u16)_usb_read_sync(rtlpriv, addr, 2); + struct device *dev = rtlpriv->io.dev; + + return (u16)_usb_read_sync(to_usb_device(dev), addr, 2); } static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr) { - return _usb_read_sync(rtlpriv, addr, 4); + struct device *dev = rtlpriv->io.dev; + + return _usb_read_sync(to_usb_device(dev), addr, 4); } static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val, @@ -947,11 +955,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, return -ENOMEM; } rtlpriv = hw->priv; - rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32), - GFP_KERNEL); - if (!rtlpriv->usb_data) - return -ENOMEM; - rtlpriv->usb_data_index = 0; init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); udev = interface_to_usbdev(intf); @@ -1022,7 +1025,6 @@ void rtl_usb_disconnect(struct usb_interface *intf) /* rtl_deinit_rfkill(hw); */ rtl_usb_deinit(hw); rtl_deinit_core(hw); - kfree(rtlpriv->usb_data); rtlpriv->cfg->ops->deinit_sw_leds(hw); rtlpriv->cfg->ops->deinit_sw_vars(hw); _rtl_usb_io_handler_release(hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index 28ebc69218a3..b591614c3b9b 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -67,7 +67,7 @@ #define QOS_QUEUE_NUM 4 #define RTL_MAC80211_NUM_QUEUE 5 #define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 -#define RTL_USB_MAX_RX_COUNT 100 + #define QBSS_LOAD_SIZE 5 #define MAX_WMMELE_LENGTH 64 @@ -1629,10 +1629,6 @@ struct rtl_priv { interface or hardware */ unsigned long status; - /* data buffer pointer for USB reads */ - __le32 *usb_data; - int usb_data_index; - /*This must be the last item so that it points to the data allocated beyond this structure like: diff --git a/trunk/drivers/of/gpio.c b/trunk/drivers/of/gpio.c index bf984b6dc477..bba81216b4db 100644 --- a/trunk/drivers/of/gpio.c +++ b/trunk/drivers/of/gpio.c @@ -140,7 +140,7 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) return -EINVAL; - if (gpiospec->args[0] >= gc->ngpio) + if (gpiospec->args[0] > gc->ngpio) return -EINVAL; if (flags) diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 111569ccab43..815674415267 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -967,59 +967,16 @@ pci_save_state(struct pci_dev *dev) return 0; } -static void pci_restore_config_dword(struct pci_dev *pdev, int offset, - u32 saved_val, int retry) -{ - u32 val; - - pci_read_config_dword(pdev, offset, &val); - if (val == saved_val) - return; - - for (;;) { - dev_dbg(&pdev->dev, "restoring config space at offset " - "%#x (was %#x, writing %#x)\n", offset, val, saved_val); - pci_write_config_dword(pdev, offset, saved_val); - if (retry-- <= 0) - return; - - pci_read_config_dword(pdev, offset, &val); - if (val == saved_val) - return; - - mdelay(1); - } -} - -static void pci_restore_config_space_range(struct pci_dev *pdev, - int start, int end, int retry) -{ - int index; - - for (index = end; index >= start; index--) - pci_restore_config_dword(pdev, 4 * index, - pdev->saved_config_space[index], - retry); -} - -static void pci_restore_config_space(struct pci_dev *pdev) -{ - if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { - pci_restore_config_space_range(pdev, 10, 15, 0); - /* Restore BARs before the command register. */ - pci_restore_config_space_range(pdev, 4, 9, 10); - pci_restore_config_space_range(pdev, 0, 3, 0); - } else { - pci_restore_config_space_range(pdev, 0, 15, 0); - } -} - /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with */ void pci_restore_state(struct pci_dev *dev) { + int i; + u32 val; + int tries; + if (!dev->state_saved) return; @@ -1027,8 +984,24 @@ void pci_restore_state(struct pci_dev *dev) pci_restore_pcie_state(dev); pci_restore_ats_state(dev); - pci_restore_config_space(dev); - + /* + * The Base Address register should be programmed before the command + * register(s) + */ + for (i = 15; i >= 0; i--) { + pci_read_config_dword(dev, i * 4, &val); + tries = 10; + while (tries && val != dev->saved_config_space[i]) { + dev_dbg(&dev->dev, "restoring config " + "space at offset %#x (was %#x, writing %#x)\n", + i, val, (int)dev->saved_config_space[i]); + pci_write_config_dword(dev,i * 4, + dev->saved_config_space[i]); + pci_read_config_dword(dev, i * 4, &val); + mdelay(10); + tries--; + } + } pci_restore_pcix_state(dev); pci_restore_msi_state(dev); pci_restore_iov_state(dev); diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index df6296c5f47b..ec3b8cc188af 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -908,6 +908,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) const struct pinctrl_ops *ops = pctldev->desc->pctlops; unsigned selector = 0; + /* No grouping */ + if (!ops) + return 0; + mutex_lock(&pinctrl_mutex); seq_puts(s, "registered pin groups:\n"); @@ -1221,19 +1225,6 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) #endif -static int pinctrl_check_ops(struct pinctrl_dev *pctldev) -{ - const struct pinctrl_ops *ops = pctldev->desc->pctlops; - - if (!ops || - !ops->list_groups || - !ops->get_group_name || - !ops->get_group_pins) - return -EINVAL; - - return 0; -} - /** * pinctrl_register() - register a pin controller device * @pctldesc: descriptor for this pin controller @@ -1265,14 +1256,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, INIT_LIST_HEAD(&pctldev->gpio_ranges); pctldev->dev = dev; - /* check core ops for sanity */ - ret = pinctrl_check_ops(pctldev); - if (ret) { - pr_err("%s pinctrl ops lacks necessary functions\n", - pctldesc->name); - goto out_err; - } - /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { ret = pinmux_check_ops(pctldev); diff --git a/trunk/drivers/regulator/anatop-regulator.c b/trunk/drivers/regulator/anatop-regulator.c index 81fd606e47bc..53969af17558 100644 --- a/trunk/drivers/regulator/anatop-regulator.c +++ b/trunk/drivers/regulator/anatop-regulator.c @@ -214,7 +214,7 @@ static struct of_device_id __devinitdata of_anatop_regulator_match_tbl[] = { { /* end */ } }; -static struct platform_driver anatop_regulator_driver = { +static struct platform_driver anatop_regulator = { .driver = { .name = "anatop_regulator", .owner = THIS_MODULE, @@ -226,13 +226,13 @@ static struct platform_driver anatop_regulator_driver = { static int __init anatop_regulator_init(void) { - return platform_driver_register(&anatop_regulator_driver); + return platform_driver_register(&anatop_regulator); } postcore_initcall(anatop_regulator_init); static void __exit anatop_regulator_exit(void) { - platform_driver_unregister(&anatop_regulator_driver); + platform_driver_unregister(&anatop_regulator); } module_exit(anatop_regulator_exit); diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 4161bfe462cd..8c8377d50c4c 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -838,7 +838,7 @@ config RTC_DRV_AT32AP700X config RTC_DRV_AT91RM9200 tristate "AT91RM9200 or some AT91SAM9 RTC" - depends on ARCH_AT91 + depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help Driver for the internal RTC (Realtime Clock) module found on Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips diff --git a/trunk/drivers/rtc/rtc-efi.c b/trunk/drivers/rtc/rtc-efi.c index c9f890b088da..550292304b0f 100644 --- a/trunk/drivers/rtc/rtc-efi.c +++ b/trunk/drivers/rtc/rtc-efi.c @@ -213,6 +213,7 @@ static struct platform_driver efi_rtc_driver = { .name = "rtc-efi", .owner = THIS_MODULE, }, + .probe = efi_rtc_probe, .remove = __exit_p(efi_rtc_remove), }; diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index 684ef4bbfce4..692de7360e94 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -339,7 +339,8 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); /* Enable the clockwatch on ST Variants */ - if (ldata->hw_designer == AMBA_VENDOR_ST) + if ((ldata->hw_designer == AMBA_VENDOR_ST) && + (ldata->hw_revision > 1)) writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, ldata->base + RTC_CR); diff --git a/trunk/drivers/rtc/rtc-r9701.c b/trunk/drivers/rtc/rtc-r9701.c index 33b6ba0afa0d..7f8e6c247935 100644 --- a/trunk/drivers/rtc/rtc-r9701.c +++ b/trunk/drivers/rtc/rtc-r9701.c @@ -122,7 +122,6 @@ static const struct rtc_class_ops r9701_rtc_ops = { static int __devinit r9701_probe(struct spi_device *spi) { struct rtc_device *rtc; - struct rtc_time dt; unsigned char tmp; int res; @@ -133,27 +132,6 @@ static int __devinit r9701_probe(struct spi_device *spi) return -ENODEV; } - /* - * The device seems to be present. Now check if the registers - * contain invalid values. If so, try to write a default date: - * 2000/1/1 00:00:00 - */ - r9701_get_datetime(&spi->dev, &dt); - if (rtc_valid_tm(&dt)) { - dev_info(&spi->dev, "trying to repair invalid date/time\n"); - dt.tm_sec = 0; - dt.tm_min = 0; - dt.tm_hour = 0; - dt.tm_mday = 1; - dt.tm_mon = 0; - dt.tm_year = 100; - - if (r9701_set_datetime(&spi->dev, &dt)) { - dev_err(&spi->dev, "cannot repair RTC register\n"); - return -ENODEV; - } - } - rtc = rtc_device_register("r9701", &spi->dev, &r9701_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 3f3a29752369..9ccea134a996 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -40,10 +40,6 @@ enum s3c_cpu_type { TYPE_S3C64XX, }; -struct s3c_rtc_drv_data { - int cpu_type; -}; - /* I have yet to find an S3C implementation with more than one * of these rtc blocks in */ @@ -450,12 +446,10 @@ static const struct of_device_id s3c_rtc_dt_match[]; static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) { #ifdef CONFIG_OF - struct s3c_rtc_drv_data *data; if (pdev->dev.of_node) { const struct of_device_id *match; match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); - data = (struct s3c_rtc_drv_data *) match->data; - return data->cpu_type; + return match->data; } #endif return platform_get_device_id(pdev)->driver_data; @@ -670,27 +664,20 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif -static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { - [TYPE_S3C2410] = { TYPE_S3C2410 }, - [TYPE_S3C2416] = { TYPE_S3C2416 }, - [TYPE_S3C2443] = { TYPE_S3C2443 }, - [TYPE_S3C64XX] = { TYPE_S3C64XX }, -}; - #ifdef CONFIG_OF static const struct of_device_id s3c_rtc_dt_match[] = { { - .compatible = "samsung,s3c2410-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], + .compatible = "samsung,s3c2410-rtc" + .data = TYPE_S3C2410, }, { - .compatible = "samsung,s3c2416-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], + .compatible = "samsung,s3c2416-rtc" + .data = TYPE_S3C2416, }, { - .compatible = "samsung,s3c2443-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], + .compatible = "samsung,s3c2443-rtc" + .data = TYPE_S3C2443, }, { - .compatible = "samsung,s3c6410-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], + .compatible = "samsung,s3c6410-rtc" + .data = TYPE_S3C64XX, }, {}, }; diff --git a/trunk/drivers/rtc/rtc-twl.c b/trunk/drivers/rtc/rtc-twl.c index 258abeabf624..4c2c6df2a9ef 100644 --- a/trunk/drivers/rtc/rtc-twl.c +++ b/trunk/drivers/rtc/rtc-twl.c @@ -112,7 +112,6 @@ static const u8 twl6030_rtc_reg_map[] = { #define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10 #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20 #define BIT_RTC_CTRL_REG_GET_TIME_M 0x40 -#define BIT_RTC_CTRL_REG_RTC_V_OPT 0x80 /* RTC_STATUS_REG bitfields */ #define BIT_RTC_STATUS_REG_RUN_M 0x02 @@ -236,57 +235,25 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned char rtc_data[ALL_TIME_REGS + 1]; int ret; u8 save_control; - u8 rtc_control; ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret); + if (ret < 0) return ret; - } - /* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */ - if (twl_class_is_6030()) { - if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) { - save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M; - ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s clr GET_TIME, error %d\n", - __func__, ret); - return ret; - } - } - } - - /* Copy RTC counting registers to static registers or latches */ - rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M; - /* for twl6030/32 enable read access to static shadowed registers */ - if (twl_class_is_6030()) - rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT; + save_control |= BIT_RTC_CTRL_REG_GET_TIME_M; - ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret); + ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); + if (ret < 0) return ret; - } ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); if (ret < 0) { - dev_err(dev, "%s: reading data, error %d\n", __func__, ret); + dev_err(dev, "rtc_read_time error %d\n", ret); return ret; } - /* for twl6030 restore original state of rtc control register */ - if (twl_class_is_6030()) { - ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s: restore CTRL_REG, error %d\n", - __func__, ret); - return ret; - } - } - tm->tm_sec = bcd2bin(rtc_data[0]); tm->tm_min = bcd2bin(rtc_data[1]); tm->tm_hour = bcd2bin(rtc_data[2]); diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index bc2e8a7c265b..c21871a4e73d 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -2844,7 +2844,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( sector_t recid, trkid; unsigned int offs; unsigned int count, count_to_trk_end; - int ret; basedev = block->base; if (rq_data_dir(req) == READ) { @@ -2885,8 +2884,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0); if (IS_ERR(itcw)) { - ret = -EINVAL; - goto out_error; + dasd_sfree_request(cqr, startdev); + return ERR_PTR(-EINVAL); } cqr->cpaddr = itcw_get_tcw(itcw); if (prepare_itcw(itcw, first_trk, last_trk, @@ -2898,8 +2897,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( /* Clock not in sync and XRC is enabled. * Try again later. */ - ret = -EAGAIN; - goto out_error; + dasd_sfree_request(cqr, startdev); + return ERR_PTR(-EAGAIN); } len_to_track_end = 0; /* @@ -2938,10 +2937,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( tidaw_flags = 0; last_tidaw = itcw_add_tidaw(itcw, tidaw_flags, dst, part_len); - if (IS_ERR(last_tidaw)) { - ret = -EINVAL; - goto out_error; - } + if (IS_ERR(last_tidaw)) + return ERR_PTR(-EINVAL); dst += part_len; } } @@ -2950,10 +2947,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( dst = page_address(bv->bv_page) + bv->bv_offset; last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len); - if (IS_ERR(last_tidaw)) { - ret = -EINVAL; - goto out_error; - } + if (IS_ERR(last_tidaw)) + return ERR_PTR(-EINVAL); } } last_tidaw->flags |= TIDAW_FLAGS_LAST; @@ -2973,9 +2968,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( cqr->buildclk = get_clock(); cqr->status = DASD_CQR_FILLED; return cqr; -out_error: - dasd_sfree_request(cqr, startdev); - return ERR_PTR(ret); } static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index 73bef0bd394c..85f4a9a5d12e 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev) goto fail_urdev_put; } - urd->char_device->ops = &ur_fops; + cdev_init(urd->char_device, &ur_fops); urd->char_device->dev = MKDEV(major, minor); urd->char_device->owner = ur_fops.owner; diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 386f0c53bea7..2cfcbffa41fd 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -835,7 +835,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, scsi_eh_restore_cmnd(scmd, &ses); - if (sdrv && sdrv->eh_action) + if (sdrv->eh_action) rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn); return rtn; diff --git a/trunk/drivers/spi/spi-davinci.c b/trunk/drivers/spi/spi-davinci.c index 9b2901feaf78..31bfba805cf4 100644 --- a/trunk/drivers/spi/spi-davinci.c +++ b/trunk/drivers/spi/spi-davinci.c @@ -653,7 +653,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n", rx_buf_count); if (t->tx_buf) - dma_unmap_single(&spi->dev, t->tx_dma, t->len, + dma_unmap_single(NULL, t->tx_dma, t->len, DMA_TO_DEVICE); return -ENOMEM; } @@ -692,10 +692,10 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) if (spicfg->io_type == SPI_IO_TYPE_DMA) { if (t->tx_buf) - dma_unmap_single(&spi->dev, t->tx_dma, t->len, + dma_unmap_single(NULL, t->tx_dma, t->len, DMA_TO_DEVICE); - dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count, + dma_unmap_single(NULL, t->rx_dma, rx_buf_count, DMA_FROM_DEVICE); clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN); diff --git a/trunk/drivers/spi/spi-fsl-spi.c b/trunk/drivers/spi/spi-fsl-spi.c index 5f748c0d96bd..24cacff57786 100644 --- a/trunk/drivers/spi/spi-fsl-spi.c +++ b/trunk/drivers/spi/spi-fsl-spi.c @@ -139,12 +139,10 @@ static void fsl_spi_change_mode(struct spi_device *spi) static void fsl_spi_chipselect(struct spi_device *spi, int value) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_platform_data *pdata; + struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; bool pol = spi->mode & SPI_CS_HIGH; struct spi_mpc8xxx_cs *cs = spi->controller_state; - pdata = spi->dev.parent->parent->platform_data; - if (value == BITBANG_CS_INACTIVE) { if (pdata->cs_control) pdata->cs_control(spi, !pol); diff --git a/trunk/drivers/spi/spi-imx.c b/trunk/drivers/spi/spi-imx.c index 570f22053be8..31054e3de4c1 100644 --- a/trunk/drivers/spi/spi-imx.c +++ b/trunk/drivers/spi/spi-imx.c @@ -83,7 +83,7 @@ struct spi_imx_data { struct spi_bitbang bitbang; struct completion xfer_done; - void __iomem *base; + void *base; int irq; struct clk *clk; unsigned long spi_clk; @@ -766,12 +766,8 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) } ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs); - if (ret < 0) { - if (mxc_platform_info) - num_cs = mxc_platform_info->num_chipselect; - else - return ret; - } + if (ret < 0) + num_cs = mxc_platform_info->num_chipselect; master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data) + sizeof(int) * num_cs); @@ -788,7 +784,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) for (i = 0; i < master->num_chipselect; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); - if (cs_gpio < 0 && mxc_platform_info) + if (cs_gpio < 0) cs_gpio = mxc_platform_info->chipselect[i]; spi_imx->chipselect[i] = cs_gpio; diff --git a/trunk/drivers/spi/spi-pl022.c b/trunk/drivers/spi/spi-pl022.c index 09c925aaf320..96f0da66b185 100644 --- a/trunk/drivers/spi/spi-pl022.c +++ b/trunk/drivers/spi/spi-pl022.c @@ -2195,6 +2195,7 @@ static int pl022_runtime_suspend(struct device *dev) struct pl022 *pl022 = dev_get_drvdata(dev); clk_disable(pl022->clk); + amba_vcore_disable(pl022->adev); return 0; } @@ -2203,6 +2204,7 @@ static int pl022_runtime_resume(struct device *dev) { struct pl022 *pl022 = dev_get_drvdata(dev); + amba_vcore_enable(pl022->adev); clk_enable(pl022->clk); return 0; diff --git a/trunk/drivers/staging/android/Kconfig b/trunk/drivers/staging/android/Kconfig index eb1dee26bda3..08a3b1133d29 100644 --- a/trunk/drivers/staging/android/Kconfig +++ b/trunk/drivers/staging/android/Kconfig @@ -27,14 +27,13 @@ config ANDROID_LOGGER config ANDROID_PERSISTENT_RAM bool - depends on HAVE_MEMBLOCK select REED_SOLOMON select REED_SOLOMON_ENC8 select REED_SOLOMON_DEC8 config ANDROID_RAM_CONSOLE bool "Android RAM buffer console" - depends on !S390 && !UML && HAVE_MEMBLOCK + depends on !S390 && !UML select ANDROID_PERSISTENT_RAM default n diff --git a/trunk/drivers/staging/android/lowmemorykiller.c b/trunk/drivers/staging/android/lowmemorykiller.c index b91e4bc332a7..052b43e4e505 100644 --- a/trunk/drivers/staging/android/lowmemorykiller.c +++ b/trunk/drivers/staging/android/lowmemorykiller.c @@ -55,6 +55,7 @@ static int lowmem_minfree[6] = { }; static int lowmem_minfree_size = 4; +static struct task_struct *lowmem_deathpending; static unsigned long lowmem_deathpending_timeout; #define lowmem_print(level, x...) \ @@ -63,6 +64,24 @@ static unsigned long lowmem_deathpending_timeout; printk(x); \ } while (0) +static int +task_notify_func(struct notifier_block *self, unsigned long val, void *data); + +static struct notifier_block task_nb = { + .notifier_call = task_notify_func, +}; + +static int +task_notify_func(struct notifier_block *self, unsigned long val, void *data) +{ + struct task_struct *task = data; + + if (task == lowmem_deathpending) + lowmem_deathpending = NULL; + + return NOTIFY_OK; +} + static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; @@ -78,6 +97,19 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); + /* + * If we already have a death outstanding, then + * bail out right away; indicating to vmscan + * that we have nothing further to offer on + * this pass. + * + * Note: Currently you need CONFIG_PROFILING + * for this to work correctly. + */ + if (lowmem_deathpending && + time_before_eq(jiffies, lowmem_deathpending_timeout)) + return 0; + if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) @@ -116,12 +148,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) if (!p) continue; - if (test_tsk_thread_flag(p, TIF_MEMDIE) && - time_before_eq(jiffies, lowmem_deathpending_timeout)) { - task_unlock(p); - rcu_read_unlock(); - return 0; - } oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); @@ -148,9 +174,15 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize); + /* + * If CONFIG_PROFILING is off, then we don't want to stall + * the killer by setting lowmem_deathpending. + */ +#ifdef CONFIG_PROFILING + lowmem_deathpending = selected; lowmem_deathpending_timeout = jiffies + HZ; +#endif send_sig(SIGKILL, selected, 0); - set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; } lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", @@ -166,6 +198,7 @@ static struct shrinker lowmem_shrinker = { static int __init lowmem_init(void) { + task_handoff_register(&task_nb); register_shrinker(&lowmem_shrinker); return 0; } @@ -173,6 +206,7 @@ static int __init lowmem_init(void) static void __exit lowmem_exit(void) { unregister_shrinker(&lowmem_shrinker); + task_handoff_unregister(&task_nb); } module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); diff --git a/trunk/drivers/staging/android/persistent_ram.c b/trunk/drivers/staging/android/persistent_ram.c index 8d8c1e33e0ff..e08f2574e30a 100644 --- a/trunk/drivers/staging/android/persistent_ram.c +++ b/trunk/drivers/staging/android/persistent_ram.c @@ -399,12 +399,12 @@ static __init struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) { struct persistent_ram_zone *prz; - int ret = -ENOMEM; + int ret; prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); if (!prz) { pr_err("persistent_ram: failed to allocate persistent ram zone\n"); - goto err; + return ERR_PTR(-ENOMEM); } INIT_LIST_HEAD(&prz->node); @@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) ret = persistent_ram_buffer_init(dev_name(dev), prz); if (ret) { pr_err("persistent_ram: failed to initialize buffer\n"); - goto err; + return ERR_PTR(ret); } prz->ecc = ecc; ret = persistent_ram_init_ecc(prz, prz->buffer_size); if (ret) - goto err; + return ERR_PTR(ret); if (prz->buffer->sig == PERSISTENT_RAM_SIG) { if (buffer_size(prz) > prz->buffer_size || @@ -442,9 +442,6 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) atomic_set(&prz->buffer->size, 0); return prz; -err: - kfree(prz); - return ERR_PTR(ret); } struct persistent_ram_zone * __init diff --git a/trunk/drivers/staging/android/timed_gpio.c b/trunk/drivers/staging/android/timed_gpio.c index 45c522cbe784..bc723eff11af 100644 --- a/trunk/drivers/staging/android/timed_gpio.c +++ b/trunk/drivers/staging/android/timed_gpio.c @@ -85,7 +85,7 @@ static int timed_gpio_probe(struct platform_device *pdev) struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; struct timed_gpio *cur_gpio; struct timed_gpio_data *gpio_data, *gpio_dat; - int i, ret; + int i, j, ret = 0; if (!pdata) return -EBUSY; @@ -108,12 +108,18 @@ static int timed_gpio_probe(struct platform_device *pdev) gpio_dat->dev.get_time = gpio_get_time; gpio_dat->dev.enable = gpio_enable; ret = gpio_request(cur_gpio->gpio, cur_gpio->name); - if (ret < 0) - goto err_out; - ret = timed_output_dev_register(&gpio_dat->dev); + if (ret >= 0) { + ret = timed_output_dev_register(&gpio_dat->dev); + if (ret < 0) + gpio_free(cur_gpio->gpio); + } if (ret < 0) { - gpio_free(cur_gpio->gpio); - goto err_out; + for (j = 0; j < i; j++) { + timed_output_dev_unregister(&gpio_data[i].dev); + gpio_free(gpio_data[i].gpio); + } + kfree(gpio_data); + return ret; } gpio_dat->gpio = cur_gpio->gpio; @@ -125,15 +131,6 @@ static int timed_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpio_data); return 0; - -err_out: - while (--i >= 0) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - kfree(gpio_data); - - return ret; } static int timed_gpio_remove(struct platform_device *pdev) diff --git a/trunk/drivers/staging/iio/inkern.c b/trunk/drivers/staging/iio/inkern.c index ef07a02bf542..de2c8ea64965 100644 --- a/trunk/drivers/staging/iio/inkern.c +++ b/trunk/drivers/staging/iio/inkern.c @@ -82,7 +82,6 @@ int iio_map_array_unregister(struct iio_dev *indio_dev, ret = -ENODEV; goto error_ret; } - i++; } error_ret: mutex_unlock(&iio_map_list_lock); diff --git a/trunk/drivers/staging/iio/magnetometer/ak8975.c b/trunk/drivers/staging/iio/magnetometer/ak8975.c index ebc2d0840caf..d5ddac3d8831 100644 --- a/trunk/drivers/staging/iio/magnetometer/ak8975.c +++ b/trunk/drivers/staging/iio/magnetometer/ak8975.c @@ -108,8 +108,7 @@ static const int ak8975_index_to_reg[] = { static int ak8975_write_data(struct i2c_client *client, u8 reg, u8 val, u8 mask, u8 shift) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct ak8975_data *data = iio_priv(indio_dev); + struct ak8975_data *data = i2c_get_clientdata(client); u8 regval; int ret; @@ -160,8 +159,7 @@ static int ak8975_read_data(struct i2c_client *client, */ static int ak8975_setup(struct i2c_client *client) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct ak8975_data *data = iio_priv(indio_dev); + struct ak8975_data *data = i2c_get_clientdata(client); u8 device_id; int ret; @@ -511,7 +509,6 @@ static int ak8975_probe(struct i2c_client *client, goto exit_gpio; } data = iio_priv(indio_dev); - i2c_set_clientdata(client, indio_dev); /* Perform some basic start-of-day setup of the device. */ err = ak8975_setup(client); if (err < 0) { @@ -519,6 +516,7 @@ static int ak8975_probe(struct i2c_client *client, goto exit_free_iio; } + i2c_set_clientdata(client, indio_dev); data->client = client; mutex_init(&data->lock); data->eoc_irq = client->irq; diff --git a/trunk/drivers/staging/iio/magnetometer/hmc5843.c b/trunk/drivers/staging/iio/magnetometer/hmc5843.c index e00b416c4d33..91dd3da70cb4 100644 --- a/trunk/drivers/staging/iio/magnetometer/hmc5843.c +++ b/trunk/drivers/staging/iio/magnetometer/hmc5843.c @@ -521,9 +521,7 @@ static int hmc5843_detect(struct i2c_client *client, /* Called when we have found a new HMC5843. */ static void hmc5843_init_client(struct i2c_client *client) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct hmc5843_data *data = iio_priv(indio_dev); - + struct hmc5843_data *data = i2c_get_clientdata(client); hmc5843_set_meas_conf(client, data->meas_conf); hmc5843_set_rate(client, data->rate); hmc5843_configure(client, data->operating_mode); diff --git a/trunk/drivers/staging/media/as102/as102_fw.c b/trunk/drivers/staging/media/as102/as102_fw.c index 1075fb1df0d9..43ebc43e6b9a 100644 --- a/trunk/drivers/staging/media/as102/as102_fw.c +++ b/trunk/drivers/staging/media/as102/as102_fw.c @@ -165,7 +165,7 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) { int errno = -EFAULT; - const struct firmware *firmware = NULL; + const struct firmware *firmware; unsigned char *cmd_buf = NULL; char *fw1, *fw2; struct usb_device *dev = bus_adap->usb_dev; diff --git a/trunk/drivers/staging/omapdrm/omap_drv.c b/trunk/drivers/staging/omapdrm/omap_drv.c index 620b8d54223d..3df5b4c58ecd 100644 --- a/trunk/drivers/staging/omapdrm/omap_drv.c +++ b/trunk/drivers/staging/omapdrm/omap_drv.c @@ -803,6 +803,9 @@ static void pdev_shutdown(struct platform_device *device) static int pdev_probe(struct platform_device *device) { DBG("%s", device->name); + if (platform_driver_register(&omap_dmm_driver)) + dev_err(&device->dev, "DMM registration failed\n"); + return drm_platform_init(&omap_drm_driver, device); } @@ -830,10 +833,6 @@ struct platform_driver pdev = { static int __init omap_drm_init(void) { DBG("init"); - if (platform_driver_register(&omap_dmm_driver)) { - /* we can continue on without DMM.. so not fatal */ - dev_err(NULL, "DMM registration failed\n"); - } return platform_driver_register(&pdev); } diff --git a/trunk/drivers/staging/ozwpan/TODO b/trunk/drivers/staging/ozwpan/TODO index c2d30a7112f3..f7a9c122f596 100644 --- a/trunk/drivers/staging/ozwpan/TODO +++ b/trunk/drivers/staging/ozwpan/TODO @@ -8,7 +8,5 @@ TODO: - code review by USB developer community. - testing with as many devices as possible. -Please send any patches for this driver to -Rupesh Gujare -Chris Kelly +Please send any patches for this driver to Chris Kelly and Greg Kroah-Hartman . diff --git a/trunk/drivers/staging/ramster/Kconfig b/trunk/drivers/staging/ramster/Kconfig index 4af1f8d4b953..8b57b87edda4 100644 --- a/trunk/drivers/staging/ramster/Kconfig +++ b/trunk/drivers/staging/ramster/Kconfig @@ -1,6 +1,10 @@ +# Dependency on CONFIG_BROKEN is because there is a commit dependency +# on a cleancache naming change to be submitted by Konrad Wilk +# a39c00ded70339603ffe1b0ffdf3ade85bcf009a "Merge branch 'stable/cleancache.v13' +# into linux-next. Once this commit is present, BROKEN can be removed config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && BROKEN select LZO_COMPRESS select LZO_DECOMPRESS default n diff --git a/trunk/drivers/staging/rts_pstor/ms.c b/trunk/drivers/staging/rts_pstor/ms.c index f9a4498984cc..66341dff8c99 100644 --- a/trunk/drivers/staging/rts_pstor/ms.c +++ b/trunk/drivers/staging/rts_pstor/ms.c @@ -3498,8 +3498,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 log_blk++; - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; - seg_no++) { + for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) { if (log_blk < ms_start_idx[seg_no+1]) break; } diff --git a/trunk/drivers/staging/rts_pstor/rtsx.c b/trunk/drivers/staging/rts_pstor/rtsx.c index 1dccd933a7e4..a7feb3e328a0 100644 --- a/trunk/drivers/staging/rts_pstor/rtsx.c +++ b/trunk/drivers/staging/rts_pstor/rtsx.c @@ -1000,11 +1000,6 @@ static int __devinit rtsx_probe(struct pci_dev *pci, rtsx_init_chip(dev->chip); - /* set the supported max_lun and max_id for the scsi host - * NOTE: the minimal value of max_id is 1 */ - host->max_id = 1; - host->max_lun = dev->chip->max_lun; - /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { diff --git a/trunk/drivers/staging/rts_pstor/rtsx_transport.c b/trunk/drivers/staging/rts_pstor/rtsx_transport.c index 9b2e5c99870f..4e3d2c106af0 100644 --- a/trunk/drivers/staging/rts_pstor/rtsx_transport.c +++ b/trunk/drivers/staging/rts_pstor/rtsx_transport.c @@ -335,7 +335,6 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, int sg_cnt, i, resid; int err = 0; long timeleft; - struct scatterlist *sg_ptr; u32 val = TRIG_DMA; if ((sg == NULL) || (num_sg <= 0) || !offset || !index) @@ -372,7 +371,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); resid = size; - sg_ptr = sg; + chip->sgi = 0; /* Usually the next entry will be @sg@ + 1, but if this sg element * is part of a chained scatterlist, it could jump to the start of @@ -380,14 +379,14 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, * the proper sg */ for (i = 0; i < *index; i++) - sg_ptr = sg_next(sg_ptr); + sg = sg_next(sg); for (i = *index; i < sg_cnt; i++) { dma_addr_t addr; unsigned int len; u8 option; - addr = sg_dma_address(sg_ptr); - len = sg_dma_len(sg_ptr); + addr = sg_dma_address(sg); + len = sg_dma_len(sg); RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len); @@ -416,7 +415,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, if (!resid) break; - sg_ptr = sg_next(sg_ptr); + sg = sg_next(sg); } RTSX_DEBUGP("SG table count = %d\n", chip->sgi); diff --git a/trunk/drivers/staging/sep/sep_main.c b/trunk/drivers/staging/sep/sep_main.c index f1701bc6e312..ad54c2e5c932 100644 --- a/trunk/drivers/staging/sep/sep_main.c +++ b/trunk/drivers/staging/sep/sep_main.c @@ -3114,7 +3114,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) current->pid); if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &call_status->status)) { - dev_dbg(&sep->pdev->dev, + dev_warn(&sep->pdev->dev, "[PID%d] dcb prep needed before send msg\n", current->pid); error = -EPROTO; @@ -3122,9 +3122,9 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (!arg) { - dev_dbg(&sep->pdev->dev, + dev_warn(&sep->pdev->dev, "[PID%d] dcb null arg\n", current->pid); - error = -EINVAL; + error = EINVAL; goto end_function; } diff --git a/trunk/drivers/staging/vme/devices/vme_pio2_core.c b/trunk/drivers/staging/vme/devices/vme_pio2_core.c index 573c80003f0c..9fedc442a779 100644 --- a/trunk/drivers/staging/vme/devices/vme_pio2_core.c +++ b/trunk/drivers/staging/vme/devices/vme_pio2_core.c @@ -35,10 +35,10 @@ static int vector[PIO2_CARDS_MAX]; static int vector_num; static int level[PIO2_CARDS_MAX]; static int level_num; -static char *variant[PIO2_CARDS_MAX]; +static const char *variant[PIO2_CARDS_MAX]; static int variant_num; -static bool loopback; +static int loopback; static int pio2_match(struct vme_dev *); static int __devinit pio2_probe(struct vme_dev *); diff --git a/trunk/drivers/staging/vt6655/key.c b/trunk/drivers/staging/vt6655/key.c index 774b0d4a7e06..0ff8d7bbf2a7 100644 --- a/trunk/drivers/staging/vt6655/key.c +++ b/trunk/drivers/staging/vt6655/key.c @@ -655,9 +655,6 @@ bool KeybSetDefaultKey ( return (false); } - if (uKeyLength > MAX_KEY_LEN) - return false; - pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true; for(ii=0;iiKeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; diff --git a/trunk/drivers/staging/vt6656/ioctl.c b/trunk/drivers/staging/vt6656/ioctl.c index d59456c29df1..1463d76895f0 100644 --- a/trunk/drivers/staging/vt6656/ioctl.c +++ b/trunk/drivers/staging/vt6656/ioctl.c @@ -565,7 +565,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -ENOMEM; break; } - pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); + pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); if (pNodeList == NULL) { result = -ENOMEM; break; @@ -601,7 +601,6 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } } if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { - kfree(pNodeList); result = -EFAULT; break; } diff --git a/trunk/drivers/staging/vt6656/key.c b/trunk/drivers/staging/vt6656/key.c index ee62a06a75f4..27bb523c8a97 100644 --- a/trunk/drivers/staging/vt6656/key.c +++ b/trunk/drivers/staging/vt6656/key.c @@ -684,9 +684,6 @@ BOOL KeybSetDefaultKey( return (FALSE); } - if (uKeyLength > MAX_KEY_LEN) - return false; - pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE; for (ii = 0; ii < ETH_ALEN; ii++) pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; diff --git a/trunk/drivers/staging/xgifb/vb_init.c b/trunk/drivers/staging/xgifb/vb_init.c index 3650bbff7686..94d5c35e22fb 100644 --- a/trunk/drivers/staging/xgifb/vb_init.c +++ b/trunk/drivers/staging/xgifb/vb_init.c @@ -61,7 +61,7 @@ XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, } temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) + if ((temp & 0x88) == 0x80) data = 0; /* DDR */ else data = 1; /* DDRII */ diff --git a/trunk/drivers/staging/xgifb/vb_setmode.c b/trunk/drivers/staging/xgifb/vb_setmode.c index 60d4adf99923..2919924213c4 100644 --- a/trunk/drivers/staging/xgifb/vb_setmode.c +++ b/trunk/drivers/staging/xgifb/vb_setmode.c @@ -152,7 +152,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->pXGINew_CR97 = &XG20_CR97; if (ChipType == XG27) { - unsigned char temp; pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI27New_MCLKData; pVBInfo->CR40 = XGI27_cr41; @@ -163,13 +162,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->pCRDE = XG27_CRDE; pVBInfo->pSR40 = &XG27_SR40; pVBInfo->pSR41 = &XG27_SR41; - pVBInfo->SR15 = XG27_SR13; - /*Z11m DDR*/ - temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); - /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - pVBInfo->pXGINew_CR97 = &Z11m_CR97; } if (ChipType >= XG20) { diff --git a/trunk/drivers/staging/xgifb/vb_table.h b/trunk/drivers/staging/xgifb/vb_table.h index e8d6f674b274..dddf261ed53d 100644 --- a/trunk/drivers/staging/xgifb/vb_table.h +++ b/trunk/drivers/staging/xgifb/vb_table.h @@ -33,13 +33,6 @@ static struct XGI_ECLKDataStruct XGI340_ECLKData[] = { {0x5c, 0x23, 0x01, 166} }; -static unsigned char XG27_SR13[4][8] = { - {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ - {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ - {0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */ - {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */ -}; - static unsigned char XGI340_SR13[4][8] = { {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ @@ -78,7 +71,7 @@ static unsigned char XGI27_cr41[24][8] = { {0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */ - {0xB3, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7], + {0xB5, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7], CR99[2:0], CR45[3:0]*/ {0xf0, 0xf5, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4 CR59 */ @@ -2810,8 +2803,6 @@ static unsigned char XG27_CRDE[2]; static unsigned char XG27_SR40 = 0x04 ; static unsigned char XG27_SR41 = 0x00 ; -static unsigned char Z11m_CR97 = 0x80 ; - static struct XGI330_VCLKDataStruct XGI_VCLKData[] = { /* SR2B,SR2C,SR2D */ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ diff --git a/trunk/drivers/staging/zsmalloc/zsmalloc-main.c b/trunk/drivers/staging/zsmalloc/zsmalloc-main.c index 917461c66014..09caa4f2687e 100644 --- a/trunk/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/trunk/drivers/staging/zsmalloc/zsmalloc-main.c @@ -267,39 +267,33 @@ static unsigned long obj_idx_to_offset(struct page *page, return off + obj_idx * class_size; } -static void reset_page(struct page *page) -{ - clear_bit(PG_private, &page->flags); - clear_bit(PG_private_2, &page->flags); - set_page_private(page, 0); - page->mapping = NULL; - page->freelist = NULL; - reset_page_mapcount(page); -} - static void free_zspage(struct page *first_page) { - struct page *nextp, *tmp, *head_extra; + struct page *nextp, *tmp; BUG_ON(!is_first_page(first_page)); BUG_ON(first_page->inuse); - head_extra = (struct page *)page_private(first_page); + nextp = (struct page *)page_private(first_page); - reset_page(first_page); + clear_bit(PG_private, &first_page->flags); + clear_bit(PG_private_2, &first_page->flags); + set_page_private(first_page, 0); + first_page->mapping = NULL; + first_page->freelist = NULL; + reset_page_mapcount(first_page); __free_page(first_page); /* zspage with only 1 system page */ - if (!head_extra) + if (!nextp) return; - list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) { + list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) { list_del(&nextp->lru); - reset_page(nextp); + clear_bit(PG_private_2, &nextp->flags); + nextp->index = 0; __free_page(nextp); } - reset_page(head_extra); - __free_page(head_extra); } /* Initialize a newly allocated zspage */ diff --git a/trunk/drivers/tty/amiserial.c b/trunk/drivers/tty/amiserial.c index 6cc4358f68c1..24145c30c9b0 100644 --- a/trunk/drivers/tty/amiserial.c +++ b/trunk/drivers/tty/amiserial.c @@ -1073,10 +1073,8 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, (new_serial.close_delay != port->close_delay) || (new_serial.xmit_fifo_size != state->xmit_fifo_size) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (port->flags & ~ASYNC_USR_MASK))) { - tty_unlock(); + (port->flags & ~ASYNC_USR_MASK))) return -EPERM; - } port->flags = ((port->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); state->custom_divisor = new_serial.custom_divisor; diff --git a/trunk/drivers/tty/serial/8250/8250.c b/trunk/drivers/tty/serial/8250/8250.c index 5c27f7e6c9f1..5b149b466ec8 100644 --- a/trunk/drivers/tty/serial/8250/8250.c +++ b/trunk/drivers/tty/serial/8250/8250.c @@ -1572,11 +1572,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) do { struct uart_8250_port *up; struct uart_port *port; + bool skip; up = list_entry(l, struct uart_8250_port, list); port = &up->port; + skip = pass_counter && up->port.flags & UPF_IIR_ONCE; - if (port->handle_irq(port)) { + if (!skip && port->handle_irq(port)) { handled = 1; end = NULL; } else if (end == NULL) @@ -2035,12 +2037,10 @@ static int serial8250_startup(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); /* - * If the interrupt is not reasserted, or we otherwise - * don't trust the iir, setup a timer to kick the UART - * on a regular basis. + * If the interrupt is not reasserted, setup a timer to + * kick the UART on a regular basis. */ - if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || - up->port.flags & UPF_BUG_THRE) { + if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { up->bugs |= UART_BUG_THRE; pr_debug("ttyS%d - using backup timer\n", serial_index(port)); diff --git a/trunk/drivers/tty/serial/8250/8250_pci.c b/trunk/drivers/tty/serial/8250/8250_pci.c index 858dca865d6a..da2b0b0a183f 100644 --- a/trunk/drivers/tty/serial/8250/8250_pci.c +++ b/trunk/drivers/tty/serial/8250/8250_pci.c @@ -1096,7 +1096,7 @@ static int kt_serial_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_port *port, int idx) { - port->flags |= UPF_BUG_THRE; + port->flags |= UPF_IIR_ONCE; return skip_tx_en_setup(priv, board, port, idx); } @@ -1118,6 +1118,18 @@ pci_xr17c154_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int try_enable_msi(struct pci_dev *dev) +{ + /* use msi if available, but fallback to legacy otherwise */ + pci_enable_msi(dev); + return 0; +} + +static void disable_msi(struct pci_dev *dev) +{ + pci_disable_msi(dev); +} + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1237,7 +1249,9 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, + .init = try_enable_msi, .setup = kt_serial_setup, + .exit = disable_msi, }, /* * ITE diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 070b442c1f81..665beb68f670 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -1041,7 +1041,7 @@ config SERIAL_OMAP config SERIAL_OMAP_CONSOLE bool "Console on OMAP serial port" - depends on SERIAL_OMAP=y + depends on SERIAL_OMAP select SERIAL_CORE_CONSOLE help Select this option if you would like to use omap serial port as diff --git a/trunk/drivers/tty/serial/altera_uart.c b/trunk/drivers/tty/serial/altera_uart.c index 1f0330915d5a..e7903751e058 100644 --- a/trunk/drivers/tty/serial/altera_uart.c +++ b/trunk/drivers/tty/serial/altera_uart.c @@ -556,7 +556,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; - else if (platp) + else if (platp->mapbase) port->mapbase = platp->mapbase; else return -EINVAL; @@ -564,7 +564,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) port->irq = res_irq->start; - else if (platp) + else if (platp->irq) port->irq = platp->irq; /* Check platform data first so we can override device node data */ diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index 3d569cd68f58..0c65c9e66986 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -1946,6 +1946,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto unmap; } + /* Ensure interrupts from this UART are masked and cleared */ + writew(0, uap->port.membase + UART011_IMSC); + writew(0xffff, uap->port.membase + UART011_ICR); + uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; @@ -1963,10 +1967,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.line = i; pl011_dma_probe(uap); - /* Ensure interrupts from this UART are masked and cleared */ - writew(0, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); - snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); amba_ports[i] = uap; diff --git a/trunk/drivers/tty/serial/atmel_serial.c b/trunk/drivers/tty/serial/atmel_serial.c index 3d7e1ee2fa57..f9a6be7a9bed 100644 --- a/trunk/drivers/tty/serial/atmel_serial.c +++ b/trunk/drivers/tty/serial/atmel_serial.c @@ -389,8 +389,6 @@ static void atmel_start_rx(struct uart_port *port) { UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ - UART_PUT_CR(port, ATMEL_US_RXEN); - if (atmel_use_dma_rx(port)) { /* enable PDC controller */ UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | @@ -406,8 +404,6 @@ static void atmel_start_rx(struct uart_port *port) */ static void atmel_stop_rx(struct uart_port *port) { - UART_PUT_CR(port, ATMEL_US_RXDIS); - if (atmel_use_dma_rx(port)) { /* disable PDC receive */ UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); diff --git a/trunk/drivers/tty/serial/clps711x.c b/trunk/drivers/tty/serial/clps711x.c index 836fe2731234..e6c3dbd781d6 100644 --- a/trunk/drivers/tty/serial/clps711x.c +++ b/trunk/drivers/tty/serial/clps711x.c @@ -154,9 +154,10 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) port->x_char = 0; return IRQ_HANDLED; } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto disable_tx_irq; + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + clps711xuart_stop_tx(port); + return IRQ_HANDLED; + } count = port->fifosize >> 1; do { @@ -170,11 +171,8 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) { - disable_tx_irq: - disable_irq_nosync(TX_IRQ(port)); - tx_enabled(port) = 0; - } + if (uart_circ_empty(xmit)) + clps711xuart_stop_tx(port); return IRQ_HANDLED; } diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index d00b38eb268e..0121486ac4fa 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -1381,24 +1381,29 @@ static int serial_omap_probe(struct platform_device *pdev) return -ENODEV; } - if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), + if (!request_mem_region(mem->start, resource_size(mem), pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); - if (!dma_rx) - return -ENXIO; + if (!dma_rx) { + ret = -EINVAL; + goto err; + } dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); - if (!dma_tx) - return -ENXIO; - - up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); - if (!up) - return -ENOMEM; + if (!dma_tx) { + ret = -EINVAL; + goto err; + } + up = kzalloc(sizeof(*up), GFP_KERNEL); + if (up == NULL) { + ret = -ENOMEM; + goto do_release_region; + } up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; @@ -1418,17 +1423,16 @@ static int serial_omap_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", up->port.line); ret = -ENODEV; - goto err_port_line; + goto err; } sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; - up->port.membase = devm_ioremap(&pdev->dev, mem->start, - resource_size(mem)); + up->port.membase = ioremap(mem->start, resource_size(mem)); if (!up->port.membase) { dev_err(&pdev->dev, "can't ioremap UART\n"); ret = -ENOMEM; - goto err_ioremap; + goto err; } up->port.flags = omap_up_info->flags; @@ -1474,19 +1478,16 @@ static int serial_omap_probe(struct platform_device *pdev) ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) - goto err_add_port; + goto do_release_region; pm_runtime_put(&pdev->dev); platform_set_drvdata(pdev, up); return 0; - -err_add_port: - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); -err_ioremap: -err_port_line: +err: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); +do_release_region: + release_mem_region(mem->start, resource_size(mem)); return ret; } @@ -1498,6 +1499,8 @@ static int serial_omap_remove(struct platform_device *dev) pm_runtime_disable(&up->pdev->dev); uart_remove_one_port(&serial_omap_reg, &up->port); pm_qos_remove_request(&up->pm_qos_request); + + kfree(up); } platform_set_drvdata(dev, NULL); diff --git a/trunk/drivers/tty/serial/pch_uart.c b/trunk/drivers/tty/serial/pch_uart.c index c2816f494807..08b9962b8fda 100644 --- a/trunk/drivers/tty/serial/pch_uart.c +++ b/trunk/drivers/tty/serial/pch_uart.c @@ -210,7 +210,6 @@ enum { #define CMITC_UARTCLK 192000000 /* 192.0000 MHz */ #define FRI2_64_UARTCLK 64000000 /* 64.0000 MHz */ #define FRI2_48_UARTCLK 48000000 /* 48.0000 MHz */ -#define NTC1_UARTCLK 64000000 /* 64.0000 MHz */ struct pch_uart_buffer { unsigned char *buf; @@ -385,12 +384,6 @@ static int pch_uart_get_uartclk(void) if (cmp && strstr(cmp, "Fish River Island II")) return FRI2_48_UARTCLK; - /* Kontron COMe-mTT10 (nanoETXexpress-TT) */ - cmp = dmi_get_system_info(DMI_BOARD_NAME); - if (cmp && (strstr(cmp, "COMe-mTT") || - strstr(cmp, "nanoETXexpress-TT"))) - return NTC1_UARTCLK; - return DEFAULT_UARTCLK; } @@ -1447,11 +1440,9 @@ static int pch_uart_verify_port(struct uart_port *port, __func__); return -EOPNOTSUPP; #endif + priv->use_dma = 1; priv->use_dma_flag = 1; dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); - if (!priv->use_dma) - pch_request_dma(port); - priv->use_dma = 1; } return 0; @@ -1660,7 +1651,6 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, } pci_enable_msi(pdev); - pci_set_master(pdev); iobase = pci_resource_start(pdev, 0); mapbase = pci_resource_start(pdev, 1); diff --git a/trunk/drivers/tty/serial/samsung.c b/trunk/drivers/tty/serial/samsung.c index d8b0aee35632..de249d265bec 100644 --- a/trunk/drivers/tty/serial/samsung.c +++ b/trunk/drivers/tty/serial/samsung.c @@ -982,7 +982,6 @@ static void s3c24xx_serial_resetport(struct uart_port *port, ucon &= ucon_mask; wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); /* reset both fifos */ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/tty/vt/vt.c index 2156188db4a6..3bdd4b19dd06 100644 --- a/trunk/drivers/tty/vt/vt.c +++ b/trunk/drivers/tty/vt/vt.c @@ -2932,10 +2932,11 @@ static int __init con_init(void) gotoxy(vc, vc->vc_x, vc->vc_y); csi_J(vc, 0); update_screen(vc); - pr_info("Console: %s %s %dx%d\n", + pr_info("Console: %s %s %dx%d", vc->vc_can_do_color ? "colour" : "mono", display_desc, vc->vc_cols, vc->vc_rows); printable = 1; + printk("\n"); console_unlock(); diff --git a/trunk/drivers/usb/Kconfig b/trunk/drivers/usb/Kconfig index 76316a33061b..cbd8f5f80596 100644 --- a/trunk/drivers/usb/Kconfig +++ b/trunk/drivers/usb/Kconfig @@ -2,6 +2,14 @@ # USB device configuration # +menuconfig USB_SUPPORT + bool "USB support" + depends on HAS_IOMEM + default y + ---help--- + This option adds core support for Universal Serial Bus (USB). + You will also need drivers from the following menu to make use of it. + # many non-PCI SOC chips embed OHCI config USB_ARCH_HAS_OHCI boolean @@ -55,14 +63,6 @@ config USB_ARCH_HAS_XHCI boolean default PCI -menuconfig USB_SUPPORT - bool "USB support" - depends on HAS_IOMEM - default y - ---help--- - This option adds core support for Universal Serial Bus (USB). - You will also need drivers from the following menu to make use of it. - if USB_SUPPORT config USB_COMMON diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index 9a56635dc19c..f8e2d6d52e5c 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -1189,13 +1189,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) if (status == 0) { status = usb_suspend_device(udev, msg); - /* - * Ignore errors from non-root-hub devices during - * system sleep transitions. For the most part, - * these devices should go to low power anyway when - * the entire bus is suspended. - */ - if (udev->parent && !PMSG_IS_AUTO(msg)) + /* Again, ignore errors during system sleep transitions */ + if (!PMSG_IS_AUTO(msg)) status = 0; } diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index 140d3e11f212..9d7fc9a39933 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -1978,18 +1978,6 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) if (status == 0) { usb_set_device_state(rhdev, USB_STATE_SUSPENDED); hcd->state = HC_STATE_SUSPENDED; - - /* Did we race with a root-hub wakeup event? */ - if (rhdev->do_remote_wakeup) { - char buffer[6]; - - status = hcd->driver->hub_status_data(hcd, buffer); - if (status != 0) { - dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n"); - hcd_bus_resume(rhdev, PMSG_AUTO_RESUME); - status = -EBUSY; - } - } } else { spin_lock_irq(&hcd_root_hub_lock); if (!HCD_DEAD(hcd)) { diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index ec6c97dadbe4..28664eb7f555 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -1667,6 +1667,7 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. @@ -1689,7 +1690,9 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); + mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); + mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); @@ -3160,22 +3163,6 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; - /* - * Some superspeed devices have finished the link training process - * and attached to a superspeed hub port, but the device descriptor - * got from those devices show they aren't superspeed devices. Warm - * reset the port attached by the devices can fix them. - */ - if ((udev->speed == USB_SPEED_SUPER) && - (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { - dev_err(&udev->dev, "got a wrong device descriptor, " - "warm reset device\n"); - hub_port_reset(hub, port1, udev, - HUB_BH_RESET_TIME, true); - retval = -EINVAL; - goto fail; - } - if (udev->descriptor.bMaxPacketSize0 == 0xff || udev->speed == USB_SPEED_SUPER) i = 512; diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index ca717da3be95..b3bdfede45e6 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -308,8 +308,7 @@ static void sg_complete(struct urb *urb) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -ENODEV && - retval != -EBUSY && - retval != -EIDRM) + retval != -EBUSY) dev_err(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); @@ -318,6 +317,7 @@ static void sg_complete(struct urb *urb) } spin_lock(&io->lock); } + urb->dev = NULL; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; @@ -524,6 +524,7 @@ void usb_sg_wait(struct usb_sg_request *io) case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: + io->urbs[i]->dev = NULL; retval = 0; yield(); break; @@ -541,6 +542,7 @@ void usb_sg_wait(struct usb_sg_request *io) /* fail any uncompleted urbs */ default: + io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", __func__, retval); @@ -591,10 +593,7 @@ void usb_sg_cancel(struct usb_sg_request *io) if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb(io->urbs [i]); - if (retval != -EINPROGRESS - && retval != -ENODEV - && retval != -EBUSY - && retval != -EIDRM) + if (retval != -EINPROGRESS && retval != -EBUSY) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } @@ -1136,6 +1135,8 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. + * + * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { @@ -1188,9 +1189,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) usb_disable_endpoint(dev, i + USB_DIR_IN, false); } /* Remove endpoints from the host controller internal state */ - mutex_lock(hcd->bandwidth_mutex); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - mutex_unlock(hcd->bandwidth_mutex); /* Second pass: remove endpoint pointers */ } for (i = skip_ep0; i < 16; ++i) { @@ -1750,6 +1749,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ + mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1762,7 +1762,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); diff --git a/trunk/drivers/usb/core/urb.c b/trunk/drivers/usb/core/urb.c index cd9b3a2cd8a7..7239a73c1b8c 100644 --- a/trunk/drivers/usb/core/urb.c +++ b/trunk/drivers/usb/core/urb.c @@ -539,10 +539,6 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * never submitted, or it was unlinked before, or the hardware is already * finished with it), even if the completion handler has not yet run. * - * The URB must not be deallocated while this routine is running. In - * particular, when a driver calls this routine, it must insure that the - * completion handler cannot deallocate the URB. - * * Unlinking and Endpoint Queues: * * [The behaviors and guarantees described below do not apply to virtual @@ -607,10 +603,6 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * - * The URB must not be deallocated while this routine is running. In - * particular, when a driver calls this routine, it must insure that the - * completion handler cannot deallocate the URB. - * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). @@ -648,10 +640,6 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * - * The URB must not be deallocated while this routine is running. In - * particular, when a driver calls this routine, it must insure that the - * completion handler cannot deallocate the URB. - * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). diff --git a/trunk/drivers/usb/dwc3/core.c b/trunk/drivers/usb/dwc3/core.c index 99b58d84553a..7bd815a507e8 100644 --- a/trunk/drivers/usb/dwc3/core.c +++ b/trunk/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) for (i = 0; i < dwc->num_event_buffers; i++) { evt = dwc->ev_buffs[i]; - if (evt) + if (evt) { dwc3_free_one_event_buffer(dwc, evt); + dwc->ev_buffs[i] = NULL; + } } - - kfree(dwc->ev_buffs); } /** diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index 3584a169886f..25910e251c04 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/drivers/usb/dwc3/ep0.c @@ -353,9 +353,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, dwc->test_mode_nr = wIndex >> 8; dwc->test_mode = true; - break; - default: - return -EINVAL; } break; @@ -562,20 +559,15 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, length = trb->size & DWC3_TRB_SIZE_MASK; if (dwc->ep0_bounced) { - unsigned transfer_size = ur->length; - unsigned maxp = ep0->endpoint.maxpacket; - - transfer_size += (maxp - (transfer_size % maxp)); transferred = min_t(u32, ur->length, - transfer_size - length); + ep0->endpoint.maxpacket - length); memcpy(ur->buf, dwc->ep0_bounce, transferred); dwc->ep0_bounced = false; } else { transferred = ur->length - length; + ur->actual += transferred; } - ur->actual += transferred; - if ((epnum & 1) && ur->actual < ur->length) { /* for some reason we did not get everything out */ diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index 9d7bcd910074..0c935d7c65bd 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev) mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT); } else { - if (request_irq(gpio_to_irq(udc->board.vbus_pin), - at91_vbus_irq, 0, driver_name, udc)) { + if (request_irq(udc->board.vbus_pin, at91_vbus_irq, + 0, driver_name, udc)) { DBG("request vbus irq %d failed\n", udc->board.vbus_pin); retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) return 0; fail4: if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) - free_irq(gpio_to_irq(udc->board.vbus_pin), udc); + free_irq(udc->board.vbus_pin, udc); fail3: if (gpio_is_valid(udc->board.vbus_pin)) gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); if (gpio_is_valid(udc->board.vbus_pin)) { - free_irq(gpio_to_irq(udc->board.vbus_pin), udc); + free_irq(udc->board.vbus_pin, udc); gpio_free(udc->board.vbus_pin); } free_irq(udc->udp_irq, udc); diff --git a/trunk/drivers/usb/gadget/f_fs.c b/trunk/drivers/usb/gadget/f_fs.c index f52cb1ae45d9..1cbba70836bc 100644 --- a/trunk/drivers/usb/gadget/f_fs.c +++ b/trunk/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) if (code == FUNCTIONFS_INTERFACE_REVMAP) { struct ffs_function *func = ffs->func; ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget && gadget->ops->ioctl) { + } else if (gadget->ops->ioctl) { ret = gadget->ops->ioctl(gadget, code, value); } else { ret = -ENOTTY; @@ -1382,7 +1382,6 @@ static void functionfs_unbind(struct ffs_data *ffs) ffs->ep0req = NULL; ffs->gadget = NULL; ffs_data_put(ffs); - clear_bit(FFS_FL_BOUND, &ffs->flags); } } diff --git a/trunk/drivers/usb/gadget/f_rndis.c b/trunk/drivers/usb/gadget/f_rndis.c index 52343654f5df..7b1cf18df5e3 100644 --- a/trunk/drivers/usb/gadget/f_rndis.c +++ b/trunk/drivers/usb/gadget/f_rndis.c @@ -500,7 +500,6 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) if (buf) { memcpy(req->buf, buf, n); req->complete = rndis_response_complete; - req->context = rndis; rndis_free_response(rndis->config, buf); value = n; } diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index 55abfb6bd612..5f94e79cd6b9 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) : (1 << (ep_index(ep))); /* check if the pipe is empty */ - if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) { + if (!(list_empty(&ep->queue))) { /* Add td to the end */ struct fsl_req *lastreq; lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,6 +918,10 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return -ENOMEM; } + /* Update ep0 state */ + if ((ep_index(ep) == 0)) + udc->ep0_state = DATA_STATE_XMIT; + /* irq handler advances the queue */ if (req != NULL) list_add_tail(&req->queue, &ep->queue); @@ -1275,8 +1279,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) udc->ep0_dir = USB_DIR_OUT; ep = &udc->eps[0]; - if (udc->ep0_state != DATA_STATE_XMIT) - udc->ep0_state = WAIT_FOR_OUT_STATUS; + udc->ep0_state = WAIT_FOR_OUT_STATUS; req->ep = ep; req->req.length = 0; @@ -1381,9 +1384,6 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, list_add_tail(&req->queue, &ep->queue); udc->ep0_state = DATA_STATE_XMIT; - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); - return; stall: ep0stall(udc); @@ -1492,14 +1492,6 @@ static void setup_received_irq(struct fsl_udc *udc, spin_lock(&udc->lock); udc->ep0_state = (setup->bRequestType & USB_DIR_IN) ? DATA_STATE_XMIT : DATA_STATE_RECV; - /* - * If the data stage is IN, send status prime immediately. - * See 2.0 Spec chapter 8.5.3.3 for detail. - */ - if (udc->ep0_state == DATA_STATE_XMIT) - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); - } else { /* No data phase, IN status from gadget */ udc->ep0_dir = USB_DIR_IN; @@ -1528,8 +1520,9 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, switch (udc->ep0_state) { case DATA_STATE_XMIT: - /* already primed at setup_received_irq */ - udc->ep0_state = WAIT_FOR_OUT_STATUS; + /* receive status phase */ + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); break; case DATA_STATE_RECV: /* send status phase */ diff --git a/trunk/drivers/usb/gadget/g_ffs.c b/trunk/drivers/usb/gadget/g_ffs.c index a85eaf40b948..331cd6729d3c 100644 --- a/trunk/drivers/usb/gadget/g_ffs.c +++ b/trunk/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = { static struct ffs_data *gfs_ffs_data; static unsigned long gfs_registered; -static int __init gfs_init(void) +static int gfs_init(void) { ENTER(); @@ -169,7 +169,7 @@ static int __init gfs_init(void) } module_init(gfs_init); -static void __exit gfs_exit(void) +static void gfs_exit(void) { ENTER(); diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index e58b16442971..8793f32bab11 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -1574,6 +1574,7 @@ static void destroy_ep_files (struct dev_data *dev) DBG (dev, "%s %d\n", __func__, dev->state); /* dev->state must prevent interference */ +restart: spin_lock_irq (&dev->lock); while (!list_empty(&dev->epfiles)) { struct ep_data *ep; diff --git a/trunk/drivers/usb/gadget/s3c-hsotg.c b/trunk/drivers/usb/gadget/s3c-hsotg.c index 105b206cd844..69295ba9d99a 100644 --- a/trunk/drivers/usb/gadget/s3c-hsotg.c +++ b/trunk/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) /* currently we allocate TX FIFOs for all possible endpoints, * and assume that they are all the same size. */ - for (ep = 1; ep <= 15; ep++) { + for (ep = 0; ep <= 15; ep++) { val = addr; val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; addr += size; @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, /* write size / packets */ writel(epsize, hsotg->regs + epsize_reg); - if (using_dma(hsotg) && !continuing) { + if (using_dma(hsotg)) { unsigned int dma_reg; /* write DMA address to control register, buffer already @@ -1696,12 +1696,10 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, reg |= mpsval; writel(reg, regs + S3C_DIEPCTL(ep)); - if (ep) { - reg = readl(regs + S3C_DOEPCTL(ep)); - reg &= ~S3C_DxEPCTL_MPS_MASK; - reg |= mpsval; - writel(reg, regs + S3C_DOEPCTL(ep)); - } + reg = readl(regs + S3C_DOEPCTL(ep)); + reg &= ~S3C_DxEPCTL_MPS_MASK; + reg |= mpsval; + writel(reg, regs + S3C_DOEPCTL(ep)); return; @@ -1921,8 +1919,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, ints & S3C_DIEPMSK_TxFIFOEmpty) { dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); - if (!using_dma(hsotg)) - s3c_hsotg_trytx(hsotg, hs_ep); + s3c_hsotg_trytx(hsotg, hs_ep); } } } diff --git a/trunk/drivers/usb/gadget/udc-core.c b/trunk/drivers/usb/gadget/udc-core.c index 2fa9865babed..56da49f31d6c 100644 --- a/trunk/drivers/usb/gadget/udc-core.c +++ b/trunk/drivers/usb/gadget/udc-core.c @@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) if (udc_is_newstyle(udc)) { udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); - usb_gadget_disconnect(udc->gadget); usb_gadget_udc_stop(udc->gadget, udc->driver); + usb_gadget_disconnect(udc->gadget); } else { usb_gadget_stop(udc->gadget, udc->driver); } @@ -411,12 +411,8 @@ static ssize_t usb_udc_softconn_store(struct device *dev, struct usb_udc *udc = container_of(dev, struct usb_udc, dev); if (sysfs_streq(buf, "connect")) { - if (udc_is_newstyle(udc)) - usb_gadget_udc_start(udc->gadget, udc->driver); usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { - if (udc_is_newstyle(udc)) - usb_gadget_udc_stop(udc->gadget, udc->driver); usb_gadget_disconnect(udc->gadget); } else { dev_err(dev, "unsupported command '%s'\n", buf); diff --git a/trunk/drivers/usb/gadget/uvc_queue.c b/trunk/drivers/usb/gadget/uvc_queue.c index 0cdf89d32a15..d776adb2da67 100644 --- a/trunk/drivers/usb/gadget/uvc_queue.c +++ b/trunk/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ static int uvc_queue_enable(struct uvc_video_queue *queue, int enable) return ret; } -/* called with queue->irqlock held.. */ static struct uvc_buffer * uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { struct uvc_buffer *nextbuf; + unsigned long flags; if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->buf.length != buf->buf.bytesused) { @@ -556,12 +556,14 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) return buf; } + spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); if (!list_empty(&queue->irqqueue)) nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); else nextbuf = NULL; + spin_unlock_irqrestore(&queue->irqlock, flags); buf->buf.sequence = queue->sequence++; do_gettimeofday(&buf->buf.timestamp); diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index d0a84bd3f3eb..3e7345172e03 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -218,9 +218,6 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, u32 portsc; struct usb_hcd *hcd = ehci_to_hcd(ehci); void __iomem *non_ehci = hcd->regs; - struct fsl_usb2_platform_data *pdata; - - pdata = hcd->self.controller->platform_data; portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -237,9 +234,7 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, /* fall through */ case FSL_USB2_PHY_UTMI: /* enable UTMI PHY */ - if (pdata->have_sysif_regs) - setbits32(non_ehci + FSL_SOC_USB_CTRL, - CTRL_UTMI_PHY_EN); + setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 4a3bc5b7a06f..057cdda7a489 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -347,8 +347,6 @@ static int ehci_reset (struct ehci_hcd *ehci) if (ehci->debug) dbgp_external_startup(); - ehci->port_c_suspend = ehci->suspended_ports = - ehci->resuming_ports = 0; return retval; } @@ -858,13 +856,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) goto dead; } - /* - * We don't use STS_FLR, but some controllers don't like it to - * remain on, so mask it out along with the other status bits. - */ - masked_status = status & (INTR_MASK | STS_FLR); - /* Shared IRQ? */ + masked_status = status & INTR_MASK; if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { spin_unlock(&ehci->lock); return IRQ_NONE; @@ -915,7 +908,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (ehci->rh_state == EHCI_RH_SUSPENDED) + if (!(cmd & CMD_RUN)) usb_hcd_resume_root_hub(hcd); /* get per-port change detect bits */ @@ -946,7 +939,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) * like usb_port_resume() does. */ ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); - set_bit(i, &ehci->resuming_ports); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); mod_timer(&hcd->rh_timer, ehci->reset_done[i]); } diff --git a/trunk/drivers/usb/host/ehci-hub.c b/trunk/drivers/usb/host/ehci-hub.c index 38fe07623152..256fbd42e48c 100644 --- a/trunk/drivers/usb/host/ehci-hub.c +++ b/trunk/drivers/usb/host/ehci-hub.c @@ -223,10 +223,15 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) * remote wakeup, we must fail the suspend. */ if (hcd->self.root_hub->do_remote_wakeup) { - if (ehci->resuming_ports) { - spin_unlock_irq(&ehci->lock); - ehci_dbg(ehci, "suspend failed because a port is resuming\n"); - return -EBUSY; + port = HCS_N_PORTS(ehci->hcs_params); + while (port--) { + if (ehci->reset_done[port] != 0) { + spin_unlock_irq(&ehci->lock); + ehci_dbg(ehci, "suspend failed because " + "port %d is resuming\n", + port + 1); + return -EBUSY; + } } } @@ -549,12 +554,16 @@ static int ehci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 temp, status; + u32 temp, status = 0; u32 mask; int ports, i, retval = 1; unsigned long flags; u32 ppcd = 0; + /* if !USB_SUSPEND, root hub timers won't get shut down ... */ + if (ehci->rh_state != EHCI_RH_RUNNING) + return 0; + /* init status to no-changes */ buf [0] = 0; ports = HCS_N_PORTS (ehci->hcs_params); @@ -563,11 +572,6 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) retval++; } - /* Inform the core about resumes-in-progress by returning - * a non-zero value even if there are no status changes. - */ - status = ehci->resuming_ports; - /* Some boards (mostly VIA?) report bogus overcurrent indications, * causing massive log spam unless we completely ignore them. It * may be relevant that VIA VT8235 controllers, where PORT_POWER is @@ -842,7 +846,6 @@ static int ehci_hub_control ( ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESUME), status_reg); - clear_bit(wIndex, &ehci->resuming_ports); retval = handshake(ehci, status_reg, PORT_RESUME, 0, 2000 /* 2msec */); if (retval != 0) { @@ -861,7 +864,6 @@ static int ehci_hub_control ( ehci->reset_done[wIndex])) { status |= USB_PORT_STAT_C_RESET << 16; ehci->reset_done [wIndex] = 0; - clear_bit(wIndex, &ehci->resuming_ports); /* force reset to complete */ ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), @@ -882,10 +884,8 @@ static int ehci_hub_control ( ehci_readl(ehci, status_reg)); } - if (!(temp & (PORT_RESUME|PORT_RESET))) { + if (!(temp & (PORT_RESUME|PORT_RESET))) ehci->reset_done[wIndex] = 0; - clear_bit(wIndex, &ehci->resuming_ports); - } /* transfer dedicated ports to the companion hc */ if ((temp & PORT_CONNECT) && @@ -920,7 +920,6 @@ static int ehci_hub_control ( status |= USB_PORT_STAT_SUSPEND; } else if (test_bit(wIndex, &ehci->suspended_ports)) { clear_bit(wIndex, &ehci->suspended_ports); - clear_bit(wIndex, &ehci->resuming_ports); ehci->reset_done[wIndex] = 0; if (temp & PORT_PE) set_bit(wIndex, &ehci->port_c_suspend); diff --git a/trunk/drivers/usb/host/ehci-omap.c b/trunk/drivers/usb/host/ehci-omap.c index 5c78f9e71466..bba9850f32f0 100644 --- a/trunk/drivers/usb/host/ehci-omap.c +++ b/trunk/drivers/usb/host/ehci-omap.c @@ -42,7 +42,6 @@ #include #include #include -#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -192,19 +191,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } } - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_request_one(pdata->reset_gpio_port[0], - GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_request_one(pdata->reset_gpio_port[1], - GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); - } - pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -251,19 +237,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); - if (pdata->phy_reset) { - /* Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_set_value(pdata->reset_gpio_port[0], 1); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_set_value(pdata->reset_gpio_port[1], 1); - } - return 0; err_add_hcd: @@ -286,9 +259,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); usb_remove_hcd(hcd); disable_put_regulator(dev->platform_data); @@ -297,13 +269,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) pm_runtime_put_sync(dev); pm_runtime_disable(dev); - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_free(pdata->reset_gpio_port[0]); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_free(pdata->reset_gpio_port[1]); - } return 0; } diff --git a/trunk/drivers/usb/host/ehci-tegra.c b/trunk/drivers/usb/host/ehci-tegra.c index 86183366647f..3de48a2d7955 100644 --- a/trunk/drivers/usb/host/ehci-tegra.c +++ b/trunk/drivers/usb/host/ehci-tegra.c @@ -224,7 +224,6 @@ static int tegra_ehci_hub_control( temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); /* start resume signalling */ ehci_writel(ehci, temp | PORT_RESUME, status_reg); - set_bit(wIndex-1, &ehci->resuming_ports); spin_unlock_irqrestore(&ehci->lock, flags); msleep(20); @@ -237,7 +236,6 @@ static int tegra_ehci_hub_control( pr_err("%s: timeout waiting for SUSPEND\n", __func__); ehci->reset_done[wIndex-1] = 0; - clear_bit(wIndex-1, &ehci->resuming_ports); tegra->port_resuming = 1; goto done; @@ -731,6 +729,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) err = -ENODEV; goto fail; } + set_irq_flags(irq, IRQF_VALID); #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 2694ed6558d2..8f9acbc96fde 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -117,8 +117,6 @@ struct ehci_hcd { /* one per controller */ the change-suspend feature turned on */ unsigned long suspended_ports; /* which ports are suspended */ - unsigned long resuming_ports; /* which ports have - started to resume */ /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 13ebeca8e73e..09f597ad6e00 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -108,7 +108,7 @@ static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_dev * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, +static int usb_hcd_at91_probe(const struct hc_driver *driver, struct platform_device *pdev) { int retval; @@ -203,7 +203,7 @@ static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, * context, "rmmod" or something similar. * */ -static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd, +static void usb_hcd_at91_remove(struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); @@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) { struct at91_usbh_data *pdata; int i; @@ -620,7 +620,7 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); } -static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) { struct at91_usbh_data *pdata = pdev->dev.platform_data; int i; @@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci"); static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, - .remove = __devexit_p(ohci_hcd_at91_drv_remove), + .remove = ohci_hcd_at91_drv_remove, .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_hcd_at91_drv_suspend, .resume = ohci_hcd_at91_drv_resume, diff --git a/trunk/drivers/usb/host/pci-quirks.c b/trunk/drivers/usb/host/pci-quirks.c index 32dada8c8b4f..11de5f1be981 100644 --- a/trunk/drivers/usb/host/pci-quirks.c +++ b/trunk/drivers/usb/host/pci-quirks.c @@ -825,13 +825,9 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) } } - val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); - /* Mask off (turn off) any enabled SMIs */ - val &= XHCI_LEGACY_DISABLE_SMI; - /* Mask all SMI events bits, RW1C */ - val |= XHCI_LEGACY_SMI_EVENTS; - /* Disable any BIOS SMIs and clear all SMI events*/ - writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); + /* Disable any BIOS SMIs */ + writel(XHCI_LEGACY_DISABLE_SMI, + base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); if (usb_is_intel_switchable_xhci(pdev)) usb_enable_xhci_ports(pdev); diff --git a/trunk/drivers/usb/host/uhci-hub.c b/trunk/drivers/usb/host/uhci-hub.c index 768d54295a20..045cde4cbc3d 100644 --- a/trunk/drivers/usb/host/uhci-hub.c +++ b/trunk/drivers/usb/host/uhci-hub.c @@ -196,12 +196,11 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) status = get_hub_status_data(uhci, buf); switch (uhci->rh_state) { + case UHCI_RH_SUSPENDING: case UHCI_RH_SUSPENDED: /* if port change, ask to be resumed */ - if (status || uhci->resuming_ports) { - status = 1; + if (status || uhci->resuming_ports) usb_hcd_resume_root_hub(hcd); - } break; case UHCI_RH_AUTO_STOPPED: diff --git a/trunk/drivers/usb/host/xhci-dbg.c b/trunk/drivers/usb/host/xhci-dbg.c index 4b436f5a4171..e9b0f043455d 100644 --- a/trunk/drivers/usb/host/xhci-dbg.c +++ b/trunk/drivers/usb/host/xhci-dbg.c @@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci) xhci_dbg(xhci, " Event Interrupts %s\n", (temp & CMD_EIE) ? "enabled " : "disabled"); xhci_dbg(xhci, " Host System Error Interrupts %s\n", - (temp & CMD_HSEIE) ? "enabled " : "disabled"); + (temp & CMD_EIE) ? "enabled " : "disabled"); xhci_dbg(xhci, " HC has %sfinished light reset\n", (temp & CMD_LRESET) ? "not " : ""); } diff --git a/trunk/drivers/usb/host/xhci-ext-caps.h b/trunk/drivers/usb/host/xhci-ext-caps.h index 377f4242dabb..c7f33123d4c0 100644 --- a/trunk/drivers/usb/host/xhci-ext-caps.h +++ b/trunk/drivers/usb/host/xhci-ext-caps.h @@ -62,9 +62,8 @@ /* USB Legacy Support Control and Status Register - section 7.1.2 */ /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */ #define XHCI_LEGACY_CONTROL_OFFSET (0x04) -/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ -#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17)) -#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29) +/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ +#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */ #define XHCI_L1C (1 << 16) diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 68eaa908ac8e..cae4c6f2845a 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -1796,6 +1796,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) int i; /* Free the Event Ring Segment Table and the actual Event Ring */ + if (xhci->ir_set) { + xhci_writel(xhci, 0, &xhci->ir_set->erst_size); + xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); + xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); + } size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); if (xhci->erst.entries) dma_free_coherent(&pdev->dev, size, @@ -1807,6 +1812,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->event_ring = NULL; xhci_dbg(xhci, "Freed event ring\n"); + xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); if (xhci->cmd_ring) xhci_ring_free(xhci, xhci->cmd_ring); xhci->cmd_ring = NULL; @@ -1835,6 +1841,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->medium_streams_pool = NULL; xhci_dbg(xhci, "Freed medium stream array pool\n"); + xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); if (xhci->dcbaa) dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa), xhci->dcbaa, xhci->dcbaa->dma); @@ -2452,8 +2459,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) fail: xhci_warn(xhci, "Couldn't initialize memory\n"); - xhci_halt(xhci); - xhci_reset(xhci); xhci_mem_cleanup(xhci); return -ENOMEM; } diff --git a/trunk/drivers/usb/host/xhci-pci.c b/trunk/drivers/usb/host/xhci-pci.c index 7a856a767e77..ef98b38626fb 100644 --- a/trunk/drivers/usb/host/xhci-pci.c +++ b/trunk/drivers/usb/host/xhci-pci.c @@ -95,8 +95,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_RESET_ON_RESUME; xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); } - if (pdev->vendor == PCI_VENDOR_ID_VIA) - xhci->quirks |= XHCI_RESET_ON_RESUME; } /* called during probe() after chip reset completes */ @@ -328,7 +326,7 @@ int __init xhci_register_pci(void) return pci_register_driver(&xhci_pci_driver); } -void xhci_unregister_pci(void) +void __exit xhci_unregister_pci(void) { pci_unregister_driver(&xhci_pci_driver); } diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 3d9422f16a20..6bd9d53062eb 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -2417,7 +2417,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) u32 irq_pending; /* Acknowledge the PCI interrupt */ irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - irq_pending |= IMAN_IP; + irq_pending |= 0x3; xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); } @@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, urb->dev->speed == USB_SPEED_FULL) urb->interval /= 8; } - return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index); + return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } /* @@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, } ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free; - return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index); + return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } /**** Command Ring Operations ****/ diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index 36641a7f2371..e1963d4a430f 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -106,9 +106,6 @@ int xhci_halt(struct xhci_hcd *xhci) STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (!ret) xhci->xhc_state |= XHCI_STATE_HALTED; - else - xhci_warn(xhci, "Host not halted after %u microseconds.\n", - XHCI_MAX_HALT_USEC); return ret; } @@ -667,11 +664,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); + xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); } static void xhci_restore_registers(struct xhci_hcd *xhci) @@ -680,11 +677,10 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); - xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); - xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); - xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); + xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); } static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) diff --git a/trunk/drivers/usb/host/xhci.h b/trunk/drivers/usb/host/xhci.h index 3d69c4b2b542..91074fdab3eb 100644 --- a/trunk/drivers/usb/host/xhci.h +++ b/trunk/drivers/usb/host/xhci.h @@ -205,10 +205,6 @@ struct xhci_op_regs { #define CMD_PM_INDEX (1 << 11) /* bits 12:31 are reserved (and should be preserved on writes). */ -/* IMAN - Interrupt Management Register */ -#define IMAN_IP (1 << 1) -#define IMAN_IE (1 << 0) - /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ #define STS_HALT XHCI_STS_HALT diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 9dcb68f04f03..959145baf3cf 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary) unsigned i; unsigned size = max; - sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL); + sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); if (!sg) return NULL; sg_init_table(sg, nents); @@ -904,9 +904,6 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) struct ctrl_ctx context; int i; - if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) - return -EOPNOTSUPP; - spin_lock_init(&context.lock); context.dev = dev; init_completion(&context.complete); @@ -1984,6 +1981,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) /* queued control messaging */ case 10: + if (param->sglen == 0) + break; retval = 0; dev_info(&intf->dev, "TEST 10: queue %d control calls, %d times\n", @@ -2277,8 +2276,6 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) if (status < 0) { WARNING(dev, "couldn't get endpoints, %d\n", status); - kfree(dev->buf); - kfree(dev); return status; } /* may find bulk or ISO pipes */ diff --git a/trunk/drivers/usb/misc/yurex.c b/trunk/drivers/usb/misc/yurex.c index 70201462e19c..897edda42270 100644 --- a/trunk/drivers/usb/misc/yurex.c +++ b/trunk/drivers/usb/misc/yurex.c @@ -99,7 +99,9 @@ static void yurex_delete(struct kref *kref) usb_put_dev(dev->udev); if (dev->cntl_urb) { usb_kill_urb(dev->cntl_urb); - kfree(dev->cntl_req); + if (dev->cntl_req) + usb_free_coherent(dev->udev, YUREX_BUF_SIZE, + dev->cntl_req, dev->cntl_urb->setup_dma); if (dev->cntl_buffer) usb_free_coherent(dev->udev, YUREX_BUF_SIZE, dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -232,7 +234,9 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ } /* allocate buffer for control req */ - dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); + dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, + GFP_KERNEL, + &dev->cntl_urb->setup_dma); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; @@ -282,7 +286,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); - dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index 66aaccf04490..0f8b82918a40 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -137,9 +137,6 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) int i = 0; u8 r; u8 power; - int ret; - - pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -157,22 +154,15 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) { - ret = -ETIMEDOUT; - goto out; - } + if (i == 10000) + return -ETIMEDOUT; } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - ret = musb_readb(addr, MUSB_ULPI_REG_DATA); - -out: - pm_runtime_put(phy->io_dev); - - return ret; + return musb_readb(addr, MUSB_ULPI_REG_DATA); } static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -181,9 +171,6 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) int i = 0; u8 r = 0; u8 power; - int ret = 0; - - pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -197,20 +184,15 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) { - ret = -ETIMEDOUT; - goto out; - } + if (i == 10000) + return -ETIMEDOUT; } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -out: - pm_runtime_put(phy->io_dev); - - return ret; + return 0; } #else #define musb_ulpi_read NULL @@ -1922,17 +1904,14 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (!musb->isr) { status = -ENODEV; - goto fail2; + goto fail3; } if (!musb->xceiv->io_ops) { - musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; musb->xceiv->io_ops = &musb_ulpi_access; } - pm_runtime_get_sync(musb->controller); - #ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) { struct dma_controller *c; @@ -2044,8 +2023,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail5; #endif - pm_runtime_put(musb->controller); - dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; switch (musb->board_mode) { @@ -2070,9 +2047,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb_gadget_cleanup(musb); fail3: - pm_runtime_put_sync(musb->controller); - -fail2: if (musb->irq_wake) device_init_wakeup(dev, 0); musb_platform_exit(musb); diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index ef8d744800ac..79cb0af779fa 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) } /* turn off DMA requests, discard state, stop polling ... */ - if (ep->epnum && is_in) { + if (is_in) { /* giveback saves bulk toggle */ csr = musb_h_flush_rxfifo(ep, 0); diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index c7785e81254c..2ae0bb309994 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -282,8 +282,7 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work) static int omap2430_musb_init(struct musb *musb) { - u32 l; - int status = 0; + u32 l, status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -302,7 +301,7 @@ static int omap2430_musb_init(struct musb *musb) status = pm_runtime_get_sync(dev); if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); + dev_err(dev, "pm_runtime_get_sync FAILED"); goto err1; } @@ -334,7 +333,6 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - pm_runtime_put_noidle(musb->controller); return 0; err1: @@ -454,14 +452,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev) goto err2; } - pm_runtime_enable(&pdev->dev); - ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } + pm_runtime_enable(&pdev->dev); + return 0; err2: @@ -480,6 +478,7 @@ static int __devexit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + pm_runtime_put(&pdev->dev); kfree(glue); return 0; @@ -492,13 +491,11 @@ static int omap2430_runtime_suspend(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - musb->context.otg_interfsel = musb_readl(musb->mregs, - OTG_INTERFSEL); + musb->context.otg_interfsel = musb_readl(musb->mregs, + OTG_INTERFSEL); - omap2430_low_level_exit(musb); - usb_phy_set_suspend(musb->xceiv, 1); - } + omap2430_low_level_exit(musb); + usb_phy_set_suspend(musb->xceiv, 1); return 0; } @@ -508,13 +505,11 @@ static int omap2430_runtime_resume(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - omap2430_low_level_init(musb); - musb_writel(musb->mregs, OTG_INTERFSEL, - musb->context.otg_interfsel); + omap2430_low_level_init(musb); + musb_writel(musb->mregs, OTG_INTERFSEL, + musb->context.otg_interfsel); - usb_phy_set_suspend(musb->xceiv, 0); - } + usb_phy_set_suspend(musb->xceiv, 0); return 0; } diff --git a/trunk/drivers/usb/serial/bus.c b/trunk/drivers/usb/serial/bus.c index ed8adb052ca7..7f547dc3a590 100644 --- a/trunk/drivers/usb/serial/bus.c +++ b/trunk/drivers/usb/serial/bus.c @@ -60,6 +60,8 @@ static int usb_serial_device_probe(struct device *dev) retval = -ENODEV; goto exit; } + if (port->dev_state != PORT_REGISTERING) + goto exit; driver = port->serial->type; if (driver->port_probe) { @@ -96,6 +98,9 @@ static int usb_serial_device_remove(struct device *dev) if (!port) return -ENODEV; + if (port->dev_state != PORT_UNREGISTERING) + return retval; + device_remove_file(&port->dev, &dev_attr_port_number); driver = port->serial->type; diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index ec30f95ef399..0310e2df59f5 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -287,8 +287,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_GET_TIMEOUT); + port_priv->bInterfaceNumber, buf, size, 300); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -341,14 +340,12 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_SET_TIMEOUT); + port_priv->bInterfaceNumber, buf, size, 300); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, - USB_CTRL_SET_TIMEOUT); + port_priv->bInterfaceNumber, NULL, 0, 300); } kfree(buf); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 02e7f2d32d52..ff8605b4b4be 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -75,8 +75,7 @@ struct ftdi_private { unsigned long last_dtr_rts; /* saved modem control outputs */ struct async_icount icount; wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - char prev_status; /* Used for TIOCMIWAIT */ - bool dev_gone; /* Used to abort TIOCMIWAIT */ + char prev_status, diff_status; /* Used for TIOCMIWAIT */ char transmit_empty; /* If transmitter is empty or not */ struct usb_serial_port *port; __u16 interface; /* FT2232C, FT2232H or FT4232H port interface @@ -1682,7 +1681,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) init_waitqueue_head(&priv->delta_msr_wait); priv->flags = ASYNC_LOW_LATENCY; - priv->dev_gone = false; if (quirk && quirk->port_probe) quirk->port_probe(priv); @@ -1841,9 +1839,6 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) dbg("%s", __func__); - priv->dev_gone = true; - wake_up_interruptible_all(&priv->delta_msr_wait); - remove_sysfs_attrs(port); kref_put(&priv->kref, ftdi_sio_priv_release); @@ -1987,19 +1982,17 @@ static int ftdi_process_packet(struct tty_struct *tty, N.B. packet may be processed more than once, but differences are only processed once. */ status = packet[0] & FTDI_STATUS_B0_MASK; + if (status & FTDI_RS0_CTS) + priv->icount.cts++; + if (status & FTDI_RS0_DSR) + priv->icount.dsr++; + if (status & FTDI_RS0_RI) + priv->icount.rng++; + if (status & FTDI_RS0_RLSD) + priv->icount.dcd++; if (status != priv->prev_status) { - char diff_status = status ^ priv->prev_status; - - if (diff_status & FTDI_RS0_CTS) - priv->icount.cts++; - if (diff_status & FTDI_RS0_DSR) - priv->icount.dsr++; - if (diff_status & FTDI_RS0_RI) - priv->icount.rng++; - if (diff_status & FTDI_RS0_RLSD) - priv->icount.dcd++; - - wake_up_interruptible_all(&priv->delta_msr_wait); + priv->diff_status |= status ^ priv->prev_status; + wake_up_interruptible(&priv->delta_msr_wait); priv->prev_status = status; } @@ -2402,12 +2395,15 @@ static int ftdi_ioctl(struct tty_struct *tty, */ case TIOCMIWAIT: cprev = priv->icount; - while (!priv->dev_gone) { + while (1) { interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; cnow = priv->icount; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || @@ -2416,7 +2412,7 @@ static int ftdi_ioctl(struct tty_struct *tty, } cprev = cnow; } - return -EIO; + /* not reached */ break; case TIOCSERGETLSR: return get_lsr_info(port, (struct serial_struct __user *)arg); diff --git a/trunk/drivers/usb/serial/metro-usb.c b/trunk/drivers/usb/serial/metro-usb.c index 08d16e8c002d..6e1622f2a297 100644 --- a/trunk/drivers/usb/serial/metro-usb.c +++ b/trunk/drivers/usb/serial/metro-usb.c @@ -27,8 +27,8 @@ /* Product information. */ #define FOCUS_VENDOR_ID 0x0C2E -#define FOCUS_PRODUCT_ID_BI 0x0720 -#define FOCUS_PRODUCT_ID_UNI 0x0700 +#define FOCUS_PRODUCT_ID 0x0720 +#define FOCUS_PRODUCT_ID_UNI 0x0710 #define METROUSB_SET_REQUEST_TYPE 0x40 #define METROUSB_SET_MODEM_CTRL_REQUEST 10 @@ -47,7 +47,7 @@ struct metrousb_private { /* Device table list. */ static struct usb_device_id id_table[] = { - { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) }, { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, { }, /* Terminating entry. */ }; diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index f4465ccddc35..836cfa9a515f 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -708,7 +708,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index a1a9062954c4..ff4a174fa5de 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty, control = priv->line_control; if ((cflag & CBAUD) == B0) priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else if ((old_termios->c_cflag & CBAUD) == B0) + else priv->line_control |= (CONTROL_DTR | CONTROL_RTS); if (control != priv->line_control) { control = priv->line_control; diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 8c8bf806f6fa..f14465a83dd1 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = { }; /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; static const struct sierra_iface_info direct_ip_interface_blacklist = { .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), .ifaceinfo = direct_ip_non_serial_ifaces, @@ -298,9 +298,6 @@ static const struct usb_device_id id_table[] = { /* Sierra Wireless HSPA Non-Composite Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ - { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 97355a15bbea..69230f01056a 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -1059,12 +1059,6 @@ int usb_serial_probe(struct usb_interface *interface, serial->attached = 1; } - /* Avoid race with tty_open and serial_install by setting the - * disconnected flag and not clearing it until all ports have been - * registered. - */ - serial->disconnected = 1; - if (get_free_serial(serial, num_ports, &minor) == NULL) { dev_err(&interface->dev, "No more free serial devices\n"); goto probe_error; @@ -1076,16 +1070,19 @@ int usb_serial_probe(struct usb_interface *interface, port = serial->port[i]; dev_set_name(&port->dev, "ttyUSB%d", port->number); dbg ("%s - registering %s", __func__, dev_name(&port->dev)); + port->dev_state = PORT_REGISTERING; device_enable_async_suspend(&port->dev); retval = device_add(&port->dev); - if (retval) + if (retval) { dev_err(&port->dev, "Error registering port device, " "continuing\n"); + port->dev_state = PORT_UNREGISTERED; + } else { + port->dev_state = PORT_REGISTERED; + } } - serial->disconnected = 0; - usb_serial_console_init(debug, minor); exit: @@ -1127,8 +1124,22 @@ void usb_serial_disconnect(struct usb_interface *interface) } kill_traffic(port); cancel_work_sync(&port->work); - if (device_is_registered(&port->dev)) + if (port->dev_state == PORT_REGISTERED) { + + /* Make sure the port is bound so that the + * driver's port_remove method is called. + */ + if (!port->dev.driver) { + int rc; + + port->dev.driver = + &serial->type->driver; + rc = device_bind_driver(&port->dev); + } + port->dev_state = PORT_UNREGISTERING; device_del(&port->dev); + port->dev_state = PORT_UNREGISTERED; + } } } serial->type->disconnect(serial); diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index 2653e73db623..c18538e4a6db 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -132,35 +132,6 @@ static struct us_unusual_dev for_dynamic_ids = #undef COMPLIANT_DEV #undef USUAL_DEV -#ifdef CONFIG_LOCKDEP - -static struct lock_class_key us_interface_key[USB_MAXINTERFACES]; - -static void us_set_lock_class(struct mutex *mutex, - struct usb_interface *intf) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_config *config = udev->actconfig; - int i; - - for (i = 0; i < config->desc.bNumInterfaces; i++) { - if (config->interface[i] == intf) - break; - } - - BUG_ON(i == config->desc.bNumInterfaces); - - lockdep_set_class(mutex, &us_interface_key[i]); -} - -#else - -static void us_set_lock_class(struct mutex *mutex, - struct usb_interface *intf) -{ -} - -#endif #ifdef CONFIG_PM /* Minimal support for suspend and resume */ @@ -924,7 +895,6 @@ int usb_stor_probe1(struct us_data **pus, *pus = us = host_to_us(host); memset(us, 0, sizeof(struct us_data)); mutex_init(&(us->dev_mutex)); - us_set_lock_class(&us->dev_mutex, intf); init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); diff --git a/trunk/drivers/uwb/hwa-rc.c b/trunk/drivers/uwb/hwa-rc.c index 810c90ae2c55..66797e9c5010 100644 --- a/trunk/drivers/uwb/hwa-rc.c +++ b/trunk/drivers/uwb/hwa-rc.c @@ -645,8 +645,7 @@ void hwarc_neep_cb(struct urb *urb) dev_err(dev, "NEEP: URB error %d\n", urb->status); } result = usb_submit_urb(urb, GFP_ATOMIC); - if (result < 0 && result != -ENODEV && result != -EPERM) { - /* ignoring unrecoverable errors */ + if (result < 0) { dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", result); goto error; diff --git a/trunk/drivers/uwb/neh.c b/trunk/drivers/uwb/neh.c index 8cb71bb333c2..a269937be1b8 100644 --- a/trunk/drivers/uwb/neh.c +++ b/trunk/drivers/uwb/neh.c @@ -107,7 +107,6 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; - u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -410,7 +409,6 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size struct device *dev = &rc->uwb_dev.dev; struct uwb_rc_neh *neh; struct uwb_rceb *notif; - unsigned long flags; if (rceb->bEventContext == 0) { notif = kmalloc(size, GFP_ATOMIC); @@ -424,11 +422,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size } else { neh = uwb_rc_neh_lookup(rc, rceb); if (neh) { - spin_lock_irqsave(&rc->neh_lock, flags); - /* to guard against a timeout */ - neh->completed = 1; - del_timer(&neh->timer); - spin_unlock_irqrestore(&rc->neh_lock, flags); + del_timer_sync(&neh->timer); uwb_rc_neh_cb(neh, rceb, size); } else dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -574,10 +568,6 @@ static void uwb_rc_neh_timer(unsigned long arg) unsigned long flags; spin_lock_irqsave(&rc->neh_lock, flags); - if (neh->completed) { - spin_unlock_irqrestore(&rc->neh_lock, flags); - return; - } if (neh->context) __uwb_rc_neh_rm(rc, neh); else diff --git a/trunk/drivers/vhost/test.c b/trunk/drivers/vhost/test.c index 3de00d9fae2e..fc9a1d75281f 100644 --- a/trunk/drivers/vhost/test.c +++ b/trunk/drivers/vhost/test.c @@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) vhost_test_stop(n, &private); vhost_test_flush(n); - vhost_dev_cleanup(&n->dev, false); + vhost_dev_cleanup(&n->dev); /* We do an extra flush before freeing memory, * since jobs can re-queue themselves. */ vhost_test_flush(n); diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index ffbce4525468..befcbd8ef019 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -499,8 +499,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) au1100fb_fix.mmio_start = regs_res->start; au1100fb_fix.mmio_len = resource_size(regs_res); - if (!devm_request_mem_region(&dev->dev, - au1100fb_fix.mmio_start, + if (!devm_request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len, DRIVER_NAME)) { print_err("fail to lock memory region at 0x%08lx", @@ -517,7 +516,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; - fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, + fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { diff --git a/trunk/drivers/video/au1200fb.c b/trunk/drivers/video/au1200fb.c index 7ca79f02056e..3e9a773db09f 100644 --- a/trunk/drivers/video/au1200fb.c +++ b/trunk/drivers/video/au1200fb.c @@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) /* Allocate the framebuffer to the maximum screen size */ fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, + fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { diff --git a/trunk/drivers/video/kyro/STG4000Reg.h b/trunk/drivers/video/kyro/STG4000Reg.h index 50f4670e9252..5d6269882589 100644 --- a/trunk/drivers/video/kyro/STG4000Reg.h +++ b/trunk/drivers/video/kyro/STG4000Reg.h @@ -73,210 +73,210 @@ typedef enum _OVRL_PIX_FORMAT { /* Register Table */ typedef struct { /* 0h */ - volatile u32 Thread0Enable; /* 0x0000 */ - volatile u32 Thread1Enable; /* 0x0004 */ - volatile u32 Thread0Recover; /* 0x0008 */ - volatile u32 Thread1Recover; /* 0x000C */ - volatile u32 Thread0Step; /* 0x0010 */ - volatile u32 Thread1Step; /* 0x0014 */ - volatile u32 VideoInStatus; /* 0x0018 */ - volatile u32 Core2InSignStart; /* 0x001C */ - volatile u32 Core1ResetVector; /* 0x0020 */ - volatile u32 Core1ROMOffset; /* 0x0024 */ - volatile u32 Core1ArbiterPriority; /* 0x0028 */ - volatile u32 VideoInControl; /* 0x002C */ - volatile u32 VideoInReg0CtrlA; /* 0x0030 */ - volatile u32 VideoInReg0CtrlB; /* 0x0034 */ - volatile u32 VideoInReg1CtrlA; /* 0x0038 */ - volatile u32 VideoInReg1CtrlB; /* 0x003C */ - volatile u32 Thread0Kicker; /* 0x0040 */ - volatile u32 Core2InputSign; /* 0x0044 */ - volatile u32 Thread0ProgCtr; /* 0x0048 */ - volatile u32 Thread1ProgCtr; /* 0x004C */ - volatile u32 Thread1Kicker; /* 0x0050 */ - volatile u32 GPRegister1; /* 0x0054 */ - volatile u32 GPRegister2; /* 0x0058 */ - volatile u32 GPRegister3; /* 0x005C */ - volatile u32 GPRegister4; /* 0x0060 */ - volatile u32 SerialIntA; /* 0x0064 */ - - volatile u32 Fill0[6]; /* GAP 0x0068 - 0x007C */ - - volatile u32 SoftwareReset; /* 0x0080 */ - volatile u32 SerialIntB; /* 0x0084 */ - - volatile u32 Fill1[37]; /* GAP 0x0088 - 0x011C */ - - volatile u32 ROMELQV; /* 0x011C */ - volatile u32 WLWH; /* 0x0120 */ - volatile u32 ROMELWL; /* 0x0124 */ - - volatile u32 dwFill_1; /* GAP 0x0128 */ - - volatile u32 IntStatus; /* 0x012C */ - volatile u32 IntMask; /* 0x0130 */ - volatile u32 IntClear; /* 0x0134 */ - - volatile u32 Fill2[6]; /* GAP 0x0138 - 0x014C */ - - volatile u32 ROMGPIOA; /* 0x0150 */ - volatile u32 ROMGPIOB; /* 0x0154 */ - volatile u32 ROMGPIOC; /* 0x0158 */ - volatile u32 ROMGPIOD; /* 0x015C */ - - volatile u32 Fill3[2]; /* GAP 0x0160 - 0x0168 */ - - volatile u32 AGPIntID; /* 0x0168 */ - volatile u32 AGPIntClassCode; /* 0x016C */ - volatile u32 AGPIntBIST; /* 0x0170 */ - volatile u32 AGPIntSSID; /* 0x0174 */ - volatile u32 AGPIntPMCSR; /* 0x0178 */ - volatile u32 VGAFrameBufBase; /* 0x017C */ - volatile u32 VGANotify; /* 0x0180 */ - volatile u32 DACPLLMode; /* 0x0184 */ - volatile u32 Core1VideoClockDiv; /* 0x0188 */ - volatile u32 AGPIntStat; /* 0x018C */ + volatile unsigned long Thread0Enable; /* 0x0000 */ + volatile unsigned long Thread1Enable; /* 0x0004 */ + volatile unsigned long Thread0Recover; /* 0x0008 */ + volatile unsigned long Thread1Recover; /* 0x000C */ + volatile unsigned long Thread0Step; /* 0x0010 */ + volatile unsigned long Thread1Step; /* 0x0014 */ + volatile unsigned long VideoInStatus; /* 0x0018 */ + volatile unsigned long Core2InSignStart; /* 0x001C */ + volatile unsigned long Core1ResetVector; /* 0x0020 */ + volatile unsigned long Core1ROMOffset; /* 0x0024 */ + volatile unsigned long Core1ArbiterPriority; /* 0x0028 */ + volatile unsigned long VideoInControl; /* 0x002C */ + volatile unsigned long VideoInReg0CtrlA; /* 0x0030 */ + volatile unsigned long VideoInReg0CtrlB; /* 0x0034 */ + volatile unsigned long VideoInReg1CtrlA; /* 0x0038 */ + volatile unsigned long VideoInReg1CtrlB; /* 0x003C */ + volatile unsigned long Thread0Kicker; /* 0x0040 */ + volatile unsigned long Core2InputSign; /* 0x0044 */ + volatile unsigned long Thread0ProgCtr; /* 0x0048 */ + volatile unsigned long Thread1ProgCtr; /* 0x004C */ + volatile unsigned long Thread1Kicker; /* 0x0050 */ + volatile unsigned long GPRegister1; /* 0x0054 */ + volatile unsigned long GPRegister2; /* 0x0058 */ + volatile unsigned long GPRegister3; /* 0x005C */ + volatile unsigned long GPRegister4; /* 0x0060 */ + volatile unsigned long SerialIntA; /* 0x0064 */ + + volatile unsigned long Fill0[6]; /* GAP 0x0068 - 0x007C */ + + volatile unsigned long SoftwareReset; /* 0x0080 */ + volatile unsigned long SerialIntB; /* 0x0084 */ + + volatile unsigned long Fill1[37]; /* GAP 0x0088 - 0x011C */ + + volatile unsigned long ROMELQV; /* 0x011C */ + volatile unsigned long WLWH; /* 0x0120 */ + volatile unsigned long ROMELWL; /* 0x0124 */ + + volatile unsigned long dwFill_1; /* GAP 0x0128 */ + + volatile unsigned long IntStatus; /* 0x012C */ + volatile unsigned long IntMask; /* 0x0130 */ + volatile unsigned long IntClear; /* 0x0134 */ + + volatile unsigned long Fill2[6]; /* GAP 0x0138 - 0x014C */ + + volatile unsigned long ROMGPIOA; /* 0x0150 */ + volatile unsigned long ROMGPIOB; /* 0x0154 */ + volatile unsigned long ROMGPIOC; /* 0x0158 */ + volatile unsigned long ROMGPIOD; /* 0x015C */ + + volatile unsigned long Fill3[2]; /* GAP 0x0160 - 0x0168 */ + + volatile unsigned long AGPIntID; /* 0x0168 */ + volatile unsigned long AGPIntClassCode; /* 0x016C */ + volatile unsigned long AGPIntBIST; /* 0x0170 */ + volatile unsigned long AGPIntSSID; /* 0x0174 */ + volatile unsigned long AGPIntPMCSR; /* 0x0178 */ + volatile unsigned long VGAFrameBufBase; /* 0x017C */ + volatile unsigned long VGANotify; /* 0x0180 */ + volatile unsigned long DACPLLMode; /* 0x0184 */ + volatile unsigned long Core1VideoClockDiv; /* 0x0188 */ + volatile unsigned long AGPIntStat; /* 0x018C */ /* - volatile u32 Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400 - volatile u32 Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table - volatile u32 Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604 - volatile u32 Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680 - volatile u32 Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC + volatile unsigned long Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400 + volatile unsigned long Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table + volatile unsigned long Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604 + volatile unsigned long Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680 + volatile unsigned long Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC */ - volatile u32 Fill4[412]; /* 0x0190 - 0x07FC */ - - volatile u32 TACtrlStreamBase; /* 0x0800 */ - volatile u32 TAObjDataBase; /* 0x0804 */ - volatile u32 TAPtrDataBase; /* 0x0808 */ - volatile u32 TARegionDataBase; /* 0x080C */ - volatile u32 TATailPtrBase; /* 0x0810 */ - volatile u32 TAPtrRegionSize; /* 0x0814 */ - volatile u32 TAConfiguration; /* 0x0818 */ - volatile u32 TAObjDataStartAddr; /* 0x081C */ - volatile u32 TAObjDataEndAddr; /* 0x0820 */ - volatile u32 TAXScreenClip; /* 0x0824 */ - volatile u32 TAYScreenClip; /* 0x0828 */ - volatile u32 TARHWClamp; /* 0x082C */ - volatile u32 TARHWCompare; /* 0x0830 */ - volatile u32 TAStart; /* 0x0834 */ - volatile u32 TAObjReStart; /* 0x0838 */ - volatile u32 TAPtrReStart; /* 0x083C */ - volatile u32 TAStatus1; /* 0x0840 */ - volatile u32 TAStatus2; /* 0x0844 */ - volatile u32 TAIntStatus; /* 0x0848 */ - volatile u32 TAIntMask; /* 0x084C */ - - volatile u32 Fill5[235]; /* GAP 0x0850 - 0x0BF8 */ - - volatile u32 TextureAddrThresh; /* 0x0BFC */ - volatile u32 Core1Translation; /* 0x0C00 */ - volatile u32 TextureAddrReMap; /* 0x0C04 */ - volatile u32 RenderOutAGPRemap; /* 0x0C08 */ - volatile u32 _3DRegionReadTrans; /* 0x0C0C */ - volatile u32 _3DPtrReadTrans; /* 0x0C10 */ - volatile u32 _3DParamReadTrans; /* 0x0C14 */ - volatile u32 _3DRegionReadThresh; /* 0x0C18 */ - volatile u32 _3DPtrReadThresh; /* 0x0C1C */ - volatile u32 _3DParamReadThresh; /* 0x0C20 */ - volatile u32 _3DRegionReadAGPRemap; /* 0x0C24 */ - volatile u32 _3DPtrReadAGPRemap; /* 0x0C28 */ - volatile u32 _3DParamReadAGPRemap; /* 0x0C2C */ - volatile u32 ZBufferAGPRemap; /* 0x0C30 */ - volatile u32 TAIndexAGPRemap; /* 0x0C34 */ - volatile u32 TAVertexAGPRemap; /* 0x0C38 */ - volatile u32 TAUVAddrTrans; /* 0x0C3C */ - volatile u32 TATailPtrCacheTrans; /* 0x0C40 */ - volatile u32 TAParamWriteTrans; /* 0x0C44 */ - volatile u32 TAPtrWriteTrans; /* 0x0C48 */ - volatile u32 TAParamWriteThresh; /* 0x0C4C */ - volatile u32 TAPtrWriteThresh; /* 0x0C50 */ - volatile u32 TATailPtrCacheAGPRe; /* 0x0C54 */ - volatile u32 TAParamWriteAGPRe; /* 0x0C58 */ - volatile u32 TAPtrWriteAGPRe; /* 0x0C5C */ - volatile u32 SDRAMArbiterConf; /* 0x0C60 */ - volatile u32 SDRAMConf0; /* 0x0C64 */ - volatile u32 SDRAMConf1; /* 0x0C68 */ - volatile u32 SDRAMConf2; /* 0x0C6C */ - volatile u32 SDRAMRefresh; /* 0x0C70 */ - volatile u32 SDRAMPowerStat; /* 0x0C74 */ - - volatile u32 Fill6[2]; /* GAP 0x0C78 - 0x0C7C */ - - volatile u32 RAMBistData; /* 0x0C80 */ - volatile u32 RAMBistCtrl; /* 0x0C84 */ - volatile u32 FIFOBistKey; /* 0x0C88 */ - volatile u32 RAMBistResult; /* 0x0C8C */ - volatile u32 FIFOBistResult; /* 0x0C90 */ + volatile unsigned long Fill4[412]; /* 0x0190 - 0x07FC */ + + volatile unsigned long TACtrlStreamBase; /* 0x0800 */ + volatile unsigned long TAObjDataBase; /* 0x0804 */ + volatile unsigned long TAPtrDataBase; /* 0x0808 */ + volatile unsigned long TARegionDataBase; /* 0x080C */ + volatile unsigned long TATailPtrBase; /* 0x0810 */ + volatile unsigned long TAPtrRegionSize; /* 0x0814 */ + volatile unsigned long TAConfiguration; /* 0x0818 */ + volatile unsigned long TAObjDataStartAddr; /* 0x081C */ + volatile unsigned long TAObjDataEndAddr; /* 0x0820 */ + volatile unsigned long TAXScreenClip; /* 0x0824 */ + volatile unsigned long TAYScreenClip; /* 0x0828 */ + volatile unsigned long TARHWClamp; /* 0x082C */ + volatile unsigned long TARHWCompare; /* 0x0830 */ + volatile unsigned long TAStart; /* 0x0834 */ + volatile unsigned long TAObjReStart; /* 0x0838 */ + volatile unsigned long TAPtrReStart; /* 0x083C */ + volatile unsigned long TAStatus1; /* 0x0840 */ + volatile unsigned long TAStatus2; /* 0x0844 */ + volatile unsigned long TAIntStatus; /* 0x0848 */ + volatile unsigned long TAIntMask; /* 0x084C */ + + volatile unsigned long Fill5[235]; /* GAP 0x0850 - 0x0BF8 */ + + volatile unsigned long TextureAddrThresh; /* 0x0BFC */ + volatile unsigned long Core1Translation; /* 0x0C00 */ + volatile unsigned long TextureAddrReMap; /* 0x0C04 */ + volatile unsigned long RenderOutAGPRemap; /* 0x0C08 */ + volatile unsigned long _3DRegionReadTrans; /* 0x0C0C */ + volatile unsigned long _3DPtrReadTrans; /* 0x0C10 */ + volatile unsigned long _3DParamReadTrans; /* 0x0C14 */ + volatile unsigned long _3DRegionReadThresh; /* 0x0C18 */ + volatile unsigned long _3DPtrReadThresh; /* 0x0C1C */ + volatile unsigned long _3DParamReadThresh; /* 0x0C20 */ + volatile unsigned long _3DRegionReadAGPRemap; /* 0x0C24 */ + volatile unsigned long _3DPtrReadAGPRemap; /* 0x0C28 */ + volatile unsigned long _3DParamReadAGPRemap; /* 0x0C2C */ + volatile unsigned long ZBufferAGPRemap; /* 0x0C30 */ + volatile unsigned long TAIndexAGPRemap; /* 0x0C34 */ + volatile unsigned long TAVertexAGPRemap; /* 0x0C38 */ + volatile unsigned long TAUVAddrTrans; /* 0x0C3C */ + volatile unsigned long TATailPtrCacheTrans; /* 0x0C40 */ + volatile unsigned long TAParamWriteTrans; /* 0x0C44 */ + volatile unsigned long TAPtrWriteTrans; /* 0x0C48 */ + volatile unsigned long TAParamWriteThresh; /* 0x0C4C */ + volatile unsigned long TAPtrWriteThresh; /* 0x0C50 */ + volatile unsigned long TATailPtrCacheAGPRe; /* 0x0C54 */ + volatile unsigned long TAParamWriteAGPRe; /* 0x0C58 */ + volatile unsigned long TAPtrWriteAGPRe; /* 0x0C5C */ + volatile unsigned long SDRAMArbiterConf; /* 0x0C60 */ + volatile unsigned long SDRAMConf0; /* 0x0C64 */ + volatile unsigned long SDRAMConf1; /* 0x0C68 */ + volatile unsigned long SDRAMConf2; /* 0x0C6C */ + volatile unsigned long SDRAMRefresh; /* 0x0C70 */ + volatile unsigned long SDRAMPowerStat; /* 0x0C74 */ + + volatile unsigned long Fill6[2]; /* GAP 0x0C78 - 0x0C7C */ + + volatile unsigned long RAMBistData; /* 0x0C80 */ + volatile unsigned long RAMBistCtrl; /* 0x0C84 */ + volatile unsigned long FIFOBistKey; /* 0x0C88 */ + volatile unsigned long RAMBistResult; /* 0x0C8C */ + volatile unsigned long FIFOBistResult; /* 0x0C90 */ /* - volatile u32 Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC - volatile u32 Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters + volatile unsigned long Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC + volatile unsigned long Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters */ - volatile u32 Fill7[16]; /* 0x0c94 - 0x0cd0 */ + volatile unsigned long Fill7[16]; /* 0x0c94 - 0x0cd0 */ - volatile u32 SDRAMAddrSign; /* 0x0CD4 */ - volatile u32 SDRAMDataSign; /* 0x0CD8 */ - volatile u32 SDRAMSignConf; /* 0x0CDC */ + volatile unsigned long SDRAMAddrSign; /* 0x0CD4 */ + volatile unsigned long SDRAMDataSign; /* 0x0CD8 */ + volatile unsigned long SDRAMSignConf; /* 0x0CDC */ /* DWFILL; //GAP 0x0CE0 */ - volatile u32 dwFill_2; - - volatile u32 ISPSignature; /* 0x0CE4 */ - - volatile u32 Fill8[454]; /*GAP 0x0CE8 - 0x13FC */ - - volatile u32 DACPrimAddress; /* 0x1400 */ - volatile u32 DACPrimSize; /* 0x1404 */ - volatile u32 DACCursorAddr; /* 0x1408 */ - volatile u32 DACCursorCtrl; /* 0x140C */ - volatile u32 DACOverlayAddr; /* 0x1410 */ - volatile u32 DACOverlayUAddr; /* 0x1414 */ - volatile u32 DACOverlayVAddr; /* 0x1418 */ - volatile u32 DACOverlaySize; /* 0x141C */ - volatile u32 DACOverlayVtDec; /* 0x1420 */ - - volatile u32 Fill9[9]; /* GAP 0x1424 - 0x1444 */ - - volatile u32 DACVerticalScal; /* 0x1448 */ - volatile u32 DACPixelFormat; /* 0x144C */ - volatile u32 DACHorizontalScal; /* 0x1450 */ - volatile u32 DACVidWinStart; /* 0x1454 */ - volatile u32 DACVidWinEnd; /* 0x1458 */ - volatile u32 DACBlendCtrl; /* 0x145C */ - volatile u32 DACHorTim1; /* 0x1460 */ - volatile u32 DACHorTim2; /* 0x1464 */ - volatile u32 DACHorTim3; /* 0x1468 */ - volatile u32 DACVerTim1; /* 0x146C */ - volatile u32 DACVerTim2; /* 0x1470 */ - volatile u32 DACVerTim3; /* 0x1474 */ - volatile u32 DACBorderColor; /* 0x1478 */ - volatile u32 DACSyncCtrl; /* 0x147C */ - volatile u32 DACStreamCtrl; /* 0x1480 */ - volatile u32 DACLUTAddress; /* 0x1484 */ - volatile u32 DACLUTData; /* 0x1488 */ - volatile u32 DACBurstCtrl; /* 0x148C */ - volatile u32 DACCrcTrigger; /* 0x1490 */ - volatile u32 DACCrcDone; /* 0x1494 */ - volatile u32 DACCrcResult1; /* 0x1498 */ - volatile u32 DACCrcResult2; /* 0x149C */ - volatile u32 DACLinecount; /* 0x14A0 */ - - volatile u32 Fill10[151]; /*GAP 0x14A4 - 0x16FC */ - - volatile u32 DigVidPortCtrl; /* 0x1700 */ - volatile u32 DigVidPortStat; /* 0x1704 */ + volatile unsigned long dwFill_2; + + volatile unsigned long ISPSignature; /* 0x0CE4 */ + + volatile unsigned long Fill8[454]; /*GAP 0x0CE8 - 0x13FC */ + + volatile unsigned long DACPrimAddress; /* 0x1400 */ + volatile unsigned long DACPrimSize; /* 0x1404 */ + volatile unsigned long DACCursorAddr; /* 0x1408 */ + volatile unsigned long DACCursorCtrl; /* 0x140C */ + volatile unsigned long DACOverlayAddr; /* 0x1410 */ + volatile unsigned long DACOverlayUAddr; /* 0x1414 */ + volatile unsigned long DACOverlayVAddr; /* 0x1418 */ + volatile unsigned long DACOverlaySize; /* 0x141C */ + volatile unsigned long DACOverlayVtDec; /* 0x1420 */ + + volatile unsigned long Fill9[9]; /* GAP 0x1424 - 0x1444 */ + + volatile unsigned long DACVerticalScal; /* 0x1448 */ + volatile unsigned long DACPixelFormat; /* 0x144C */ + volatile unsigned long DACHorizontalScal; /* 0x1450 */ + volatile unsigned long DACVidWinStart; /* 0x1454 */ + volatile unsigned long DACVidWinEnd; /* 0x1458 */ + volatile unsigned long DACBlendCtrl; /* 0x145C */ + volatile unsigned long DACHorTim1; /* 0x1460 */ + volatile unsigned long DACHorTim2; /* 0x1464 */ + volatile unsigned long DACHorTim3; /* 0x1468 */ + volatile unsigned long DACVerTim1; /* 0x146C */ + volatile unsigned long DACVerTim2; /* 0x1470 */ + volatile unsigned long DACVerTim3; /* 0x1474 */ + volatile unsigned long DACBorderColor; /* 0x1478 */ + volatile unsigned long DACSyncCtrl; /* 0x147C */ + volatile unsigned long DACStreamCtrl; /* 0x1480 */ + volatile unsigned long DACLUTAddress; /* 0x1484 */ + volatile unsigned long DACLUTData; /* 0x1488 */ + volatile unsigned long DACBurstCtrl; /* 0x148C */ + volatile unsigned long DACCrcTrigger; /* 0x1490 */ + volatile unsigned long DACCrcDone; /* 0x1494 */ + volatile unsigned long DACCrcResult1; /* 0x1498 */ + volatile unsigned long DACCrcResult2; /* 0x149C */ + volatile unsigned long DACLinecount; /* 0x14A0 */ + + volatile unsigned long Fill10[151]; /*GAP 0x14A4 - 0x16FC */ + + volatile unsigned long DigVidPortCtrl; /* 0x1700 */ + volatile unsigned long DigVidPortStat; /* 0x1704 */ /* - volatile u32 Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC - volatile u32 Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT + volatile unsigned long Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC + volatile unsigned long Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT */ - volatile u32 Fill11[1598]; + volatile unsigned long Fill11[1598]; /* DWFILL; //GAP 0x3000 ALUT 256MB offset */ - volatile u32 Fill_3; + volatile unsigned long Fill_3; } STG4000REG; diff --git a/trunk/drivers/video/msm/mddi.c b/trunk/drivers/video/msm/mddi.c index b061d709bc44..4527cbf0a4ec 100644 --- a/trunk/drivers/video/msm/mddi.c +++ b/trunk/drivers/video/msm/mddi.c @@ -420,7 +420,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata) mddi_set_auto_hibernate(&mddi->client_data, 1); } -static int __devinit mddi_get_client_caps(struct mddi_info *mddi) +static int __init mddi_get_client_caps(struct mddi_info *mddi) { int i, j; @@ -622,9 +622,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) static struct mddi_info mddi_info[2]; -static int __devinit mddi_clk_setup(struct platform_device *pdev, - struct mddi_info *mddi, - unsigned long clk_rate) +static int __init mddi_clk_setup(struct platform_device *pdev, + struct mddi_info *mddi, + unsigned long clk_rate) { int ret; diff --git a/trunk/drivers/video/uvesafb.c b/trunk/drivers/video/uvesafb.c index 26e83d7fdd6f..260cca7ddb41 100644 --- a/trunk/drivers/video/uvesafb.c +++ b/trunk/drivers/video/uvesafb.c @@ -815,15 +815,8 @@ static int __devinit uvesafb_vbe_init(struct fb_info *info) par->pmi_setpal = pmi_setpal; par->ypan = ypan; - if (par->pmi_setpal || par->ypan) { - if (__supported_pte_mask & _PAGE_NX) { - par->pmi_setpal = par->ypan = 0; - printk(KERN_WARNING "uvesafb: NX protection is actively." - "We have better not to use the PMI.\n"); - } else { - uvesafb_vbe_getpmi(task, par); - } - } + if (par->pmi_setpal || par->ypan) + uvesafb_vbe_getpmi(task, par); #else /* The protected mode interface is not available on non-x86. */ par->pmi_setpal = par->ypan = 0; diff --git a/trunk/drivers/virtio/virtio_balloon.c b/trunk/drivers/virtio/virtio_balloon.c index c2d05a8279fd..05f0a80818a2 100644 --- a/trunk/drivers/virtio/virtio_balloon.c +++ b/trunk/drivers/virtio/virtio_balloon.c @@ -28,13 +28,6 @@ #include #include -/* - * Balloon device works in 4K page units. So each page is pointed to by - * multiple balloon pages. All memory counters in this driver are in balloon - * page units. - */ -#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) - struct virtio_balloon { struct virtio_device *vdev; @@ -49,13 +42,8 @@ struct virtio_balloon /* Waiting for host to ack the pages we released. */ struct completion acked; - /* Number of balloon pages we've told the Host we're not using. */ + /* The pages we've told the Host we're not using. */ unsigned int num_pages; - /* - * The pages we've told the Host we're not using. - * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE - * to num_pages above. - */ struct list_head pages; /* The array of pfns we tell the Host about. */ @@ -78,13 +66,7 @@ static u32 page_to_balloon_pfn(struct page *page) BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT); /* Convert pfn from Linux page size to balloon page size. */ - return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; -} - -static struct page *balloon_pfn_to_page(u32 pfn) -{ - BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE); - return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE); + return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); } static void balloon_ack(struct virtqueue *vq) @@ -114,23 +96,12 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) wait_for_completion(&vb->acked); } -static void set_page_pfns(u32 pfns[], struct page *page) -{ - unsigned int i; - - /* Set balloon pfns pointing at this page. - * Note that the first pfn points at start of the page. */ - for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++) - pfns[i] = page_to_balloon_pfn(page) + i; -} - static void fill_balloon(struct virtio_balloon *vb, size_t num) { /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; - vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); if (!page) { @@ -142,9 +113,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) msleep(200); break; } - set_page_pfns(vb->pfns + vb->num_pfns, page); - vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; + vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); totalram_pages--; + vb->num_pages++; list_add(&page->lru, &vb->pages); } @@ -159,9 +130,8 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) { unsigned int i; - /* Find pfns pointing at start of each page, get pages and free them. */ - for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { - __free_page(balloon_pfn_to_page(pfns[i])); + for (i = 0; i < num; i++) { + __free_page(pfn_to_page(pfns[i])); totalram_pages++; } } @@ -173,12 +143,11 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; - vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { page = list_first_entry(&vb->pages, struct page, lru); list_del(&page->lru); - set_page_pfns(vb->pfns + vb->num_pfns, page); - vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; + vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); + vb->num_pages--; } /* @@ -265,14 +234,11 @@ static void virtballoon_changed(struct virtio_device *vdev) static inline s64 towards_target(struct virtio_balloon *vb) { - __le32 v; - s64 target; - + u32 v; vb->vdev->config->get(vb->vdev, offsetof(struct virtio_balloon_config, num_pages), &v, sizeof(v)); - target = le32_to_cpu(v); - return target - vb->num_pages; + return (s64)v - vb->num_pages; } static void update_balloon_size(struct virtio_balloon *vb) diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index 1ffd03bf8e10..99d8151c824a 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; if (use_ptemod) - vma->vm_flags |= VM_DONTCOPY; + vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; vma->vm_private_data = map; diff --git a/trunk/drivers/xen/grant-table.c b/trunk/drivers/xen/grant-table.c index f100ce20b16b..b4d4eac761db 100644 --- a/trunk/drivers/xen/grant-table.c +++ b/trunk/drivers/xen/grant-table.c @@ -1029,7 +1029,6 @@ int gnttab_init(void) int i; unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int nr_init_grefs; - int ret; nr_grant_frames = 1; boot_max_nr_grant_frames = __max_nr_grant_frames(); @@ -1048,16 +1047,12 @@ int gnttab_init(void) nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; for (i = 0; i < nr_glist_frames; i++) { gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); - if (gnttab_list[i] == NULL) { - ret = -ENOMEM; + if (gnttab_list[i] == NULL) goto ini_nomem; - } } - if (gnttab_resume() < 0) { - ret = -ENODEV; - goto ini_nomem; - } + if (gnttab_resume() < 0) + return -ENODEV; nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; @@ -1075,7 +1070,7 @@ int gnttab_init(void) for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); - return ret; + return -ENOMEM; } EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/trunk/drivers/xen/manage.c b/trunk/drivers/xen/manage.c index 412b96cc5305..9e14ae6cd49c 100644 --- a/trunk/drivers/xen/manage.c +++ b/trunk/drivers/xen/manage.c @@ -132,7 +132,6 @@ static void do_suspend(void) err = dpm_suspend_end(PMSG_FREEZE); if (err) { printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); - si.cancelled = 0; goto out_resume; } diff --git a/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c b/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c index a31b54d48839..f20c5f178b40 100644 --- a/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev) return xenbus_read_otherend_details(xendev, "backend-id", "backend"); } -static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential) +static int is_device_connecting(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); struct device_driver *drv = data; @@ -152,41 +152,16 @@ static int is_device_connecting(struct device *dev, void *data, bool ignore_none if (drv && (dev->driver != drv)) return 0; - if (ignore_nonessential) { - /* With older QEMU, for PVonHVM guests the guest config files - * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] - * which is nonsensical as there is no PV FB (there can be - * a PVKB) running as HVM guest. */ - - if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) - return 0; - - if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) - return 0; - } xendrv = to_xenbus_driver(dev->driver); return (xendev->state < XenbusStateConnected || (xendev->state == XenbusStateConnected && xendrv->is_ready && !xendrv->is_ready(xendev))); } -static int essential_device_connecting(struct device *dev, void *data) -{ - return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); -} -static int non_essential_device_connecting(struct device *dev, void *data) -{ - return is_device_connecting(dev, data, false); -} -static int exists_essential_connecting_device(struct device_driver *drv) +static int exists_connecting_device(struct device_driver *drv) { return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - essential_device_connecting); -} -static int exists_non_essential_connecting_device(struct device_driver *drv) -{ - return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - non_essential_device_connecting); + is_device_connecting); } static int print_device_status(struct device *dev, void *data) @@ -217,23 +192,6 @@ static int print_device_status(struct device *dev, void *data) /* We only wait for device setup after most initcalls have run. */ static int ready_to_wait_for_devices; -static bool wait_loop(unsigned long start, unsigned int max_delay, - unsigned int *seconds_waited) -{ - if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { - if (!*seconds_waited) - printk(KERN_WARNING "XENBUS: Waiting for " - "devices to initialise: "); - *seconds_waited += 5; - printk("%us...", max_delay - *seconds_waited); - if (*seconds_waited == max_delay) - return true; - } - - schedule_timeout_interruptible(HZ/10); - - return false; -} /* * On a 5-minute timeout, wait for all devices currently configured. We need * to do this to guarantee that the filesystems and / or network devices @@ -257,14 +215,19 @@ static void wait_for_devices(struct xenbus_driver *xendrv) if (!ready_to_wait_for_devices || !xen_domain()) return; - while (exists_non_essential_connecting_device(drv)) - if (wait_loop(start, 30, &seconds_waited)) - break; - - /* Skips PVKB and PVFB check.*/ - while (exists_essential_connecting_device(drv)) - if (wait_loop(start, 270, &seconds_waited)) - break; + while (exists_connecting_device(drv)) { + if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { + if (!seconds_waited) + printk(KERN_WARNING "XENBUS: Waiting for " + "devices to initialise: "); + seconds_waited += 5; + printk("%us...", 300 - seconds_waited); + if (seconds_waited == 300) + break; + } + + schedule_timeout_interruptible(HZ/10); + } if (seconds_waited) printk("\n"); diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 67a6db3e1b6f..da887604dfc5 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -93,8 +93,9 @@ static void aio_free_ring(struct kioctx *ctx) put_page(info->ring_pages[i]); if (info->mmap_size) { - BUG_ON(ctx->mm != current->mm); - vm_munmap(info->mmap_base, info->mmap_size); + down_write(&ctx->mm->mmap_sem); + do_munmap(ctx->mm, info->mmap_base, info->mmap_size); + up_write(&ctx->mm->mmap_sem); } if (info->ring_pages && info->ring_pages != info->internal_pages) @@ -388,17 +389,6 @@ void exit_aio(struct mm_struct *mm) "exit_aio:ioctx still alive: %d %d %d\n", atomic_read(&ctx->users), ctx->dead, ctx->reqs_active); - /* - * We don't need to bother with munmap() here - - * exit_mmap(mm) is coming and it'll unmap everything. - * Since aio_free_ring() uses non-zero ->mmap_size - * as indicator that it needs to unmap the area, - * just set it to 0; aio_free_ring() is the only - * place that uses ->mmap_size, so it's safe. - * That way we get all munmap done to current->mm - - * all other callers have ctx->mm == current->mm. - */ - ctx->ring_info.mmap_size = 0; put_ioctx(ctx); } } diff --git a/trunk/fs/binfmt_aout.c b/trunk/fs/binfmt_aout.c index d146e181d10d..2eb12f13593d 100644 --- a/trunk/fs/binfmt_aout.c +++ b/trunk/fs/binfmt_aout.c @@ -50,7 +50,9 @@ static int set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end > start) { unsigned long addr; - addr = vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(addr)) return addr; } @@ -278,7 +280,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) pos = 32; map_size = ex.a_text+ex.a_data; #endif - error = vm_brk(text_addr & PAGE_MASK, map_size); + down_write(¤t->mm->mmap_sem); + error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -309,7 +313,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { loff_t pos = fd_offset; - vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + down_write(¤t->mm->mmap_sem); + do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -319,20 +325,24 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto beyond_if; } - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -402,7 +412,9 @@ static int load_aout_library(struct file *file) "N_TXTOFF is not page aligned. Please convert library: %s\n", file->f_path.dentry->d_name.name); } - vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + down_write(¤t->mm->mmap_sem); + do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -413,10 +425,12 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, N_TXTOFF(ex)); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; @@ -424,7 +438,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = vm_brk(start_addr + len, bss - len); + down_write(¤t->mm->mmap_sem); + error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out; diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 16f735417072..48ffb3dc610a 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -82,7 +82,9 @@ static int set_brk(unsigned long start, unsigned long end) end = ELF_PAGEALIGN(end); if (end > start) { unsigned long addr; - addr = vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(addr)) return addr; } @@ -512,7 +514,9 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* Map the last of the bss segment */ - error = vm_brk(elf_bss, last_bss - elf_bss); + down_write(¤t->mm->mmap_sem); + error = do_brk(elf_bss, last_bss - elf_bss); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(error)) goto out_close; } @@ -958,8 +962,10 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ - error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, + down_write(¤t->mm->mmap_sem); + error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); } #ifdef ELF_PLAT_INIT @@ -1044,7 +1050,8 @@ static int load_elf_library(struct file *file) eppnt++; /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, ELF_PAGESTART(eppnt->p_vaddr), (eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr)), @@ -1052,6 +1059,7 @@ static int load_elf_library(struct file *file) MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, (eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr))); + up_write(¤t->mm->mmap_sem); if (error != ELF_PAGESTART(eppnt->p_vaddr)) goto out_free_ph; @@ -1064,8 +1072,11 @@ static int load_elf_library(struct file *file) len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss = eppnt->p_memsz + eppnt->p_vaddr; - if (bss > len) - vm_brk(len, bss - len); + if (bss > len) { + down_write(¤t->mm->mmap_sem); + do_brk(len, bss - len); + up_write(¤t->mm->mmap_sem); + } error = 0; out_free_ph: diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index d390a0fffc65..9bd5612a8224 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -390,17 +390,21 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) stack_prot |= PROT_EXEC; - current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot, + down_write(¤t->mm->mmap_sem); + current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED | MAP_GROWSDOWN, 0); if (IS_ERR_VALUE(current->mm->start_brk)) { + up_write(¤t->mm->mmap_sem); retval = current->mm->start_brk; current->mm->start_brk = 0; goto error_kill; } + up_write(¤t->mm->mmap_sem); + current->mm->brk = current->mm->start_brk; current->mm->context.end_brk = current->mm->start_brk; current->mm->context.end_brk += @@ -951,8 +955,10 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE) mflags |= MAP_EXECUTABLE; - maddr = vm_mmap(NULL, load_addr, top - base, + down_write(&mm->mmap_sem); + maddr = do_mmap(NULL, load_addr, top - base, PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); + up_write(&mm->mmap_sem); if (IS_ERR_VALUE(maddr)) return (int) maddr; @@ -1090,8 +1096,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, /* create the mapping */ disp = phdr->p_vaddr & ~PAGE_MASK; - maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, + down_write(&mm->mmap_sem); + maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp); + up_write(&mm->mmap_sem); kdebug("mmap[%d] sz=%lx pr=%x fl=%x of=%lx --> %08lx", loop, phdr->p_memsz + disp, prot, flags, @@ -1135,8 +1143,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, unsigned long xmaddr; flags |= MAP_FIXED | MAP_ANONYMOUS; - xmaddr = vm_mmap(NULL, xaddr, excess - excess1, + down_write(&mm->mmap_sem); + xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0); + up_write(&mm->mmap_sem); kdebug("mmap[%d] " " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 6b2daf99fab8..024d20ee3ca3 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -542,8 +542,10 @@ static int load_flat_file(struct linux_binprm * bprm, */ DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); - textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, + down_write(¤t->mm->mmap_sem); + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_EXECUTABLE, 0); + up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) textpos = (unsigned long) -ENOMEM; @@ -554,8 +556,10 @@ static int load_flat_file(struct linux_binprm * bprm, len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - realdatastart = vm_mmap(0, 0, len, + down_write(¤t->mm->mmap_sem); + realdatastart = do_mmap(0, 0, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { if (!realdatastart) @@ -599,8 +603,10 @@ static int load_flat_file(struct linux_binprm * bprm, len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - textpos = vm_mmap(0, 0, len, + down_write(¤t->mm->mmap_sem); + textpos = do_mmap(0, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) diff --git a/trunk/fs/binfmt_som.c b/trunk/fs/binfmt_som.c index 4517aaff61b4..e4fc746629a7 100644 --- a/trunk/fs/binfmt_som.c +++ b/trunk/fs/binfmt_som.c @@ -147,8 +147,10 @@ static int map_som_binary(struct file *file, code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize); current->mm->start_code = code_start; current->mm->end_code = code_start + code_size; - retval = vm_mmap(file, code_start, code_size, prot, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(file, code_start, code_size, prot, flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); + up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; @@ -156,16 +158,20 @@ static int map_som_binary(struct file *file, data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize); current->mm->start_data = data_start; current->mm->end_data = bss_start = data_start + data_size; - retval = vm_mmap(file, data_start, data_size, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(file, data_start, data_size, prot | PROT_WRITE, flags, SOM_PAGESTART(hpuxhdr->exec_dfile)); + up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize); current->mm->start_brk = current->mm->brk = som_brk; - retval = vm_mmap(NULL, bss_start, som_brk - bss_start, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(NULL, bss_start, som_brk - bss_start, prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (retval > 0 || retval < -1024) retval = 0; out: diff --git a/trunk/fs/btrfs/compression.c b/trunk/fs/btrfs/compression.c index 86eff48dab78..d286b40a5671 100644 --- a/trunk/fs/btrfs/compression.c +++ b/trunk/fs/btrfs/compression.c @@ -405,7 +405,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, bio_put(bio); bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); - BUG_ON(!bio); bio->bi_private = cb; bio->bi_end_io = end_compressed_bio_write; bio_add_page(bio, page, PAGE_CACHE_SIZE, 0); @@ -688,7 +687,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); - BUG_ON(!comp_bio); comp_bio->bi_private = cb; comp_bio->bi_end_io = end_compressed_bio_read; diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 3f65a812e282..5b8ef8eb3521 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -2166,7 +2166,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, static inline bool btrfs_root_readonly(struct btrfs_root *root) { - return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; + return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY; } /* struct btrfs_root_backup */ diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 2b35f8d14bb9..a84420491c11 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -529,7 +529,9 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, * allocate blocks for the tree root we can't do the fast caching since * we likely hold important locks. */ - if (fs_info->mount_opt & BTRFS_MOUNT_SPACE_CACHE) { + if (trans && (!trans->transaction->in_commit) && + (root && root != root->fs_info->tree_root) && + btrfs_test_opt(root, SPACE_CACHE)) { ret = load_free_space_cache(fs_info, cache); spin_lock(&cache->lock); @@ -3150,14 +3152,15 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) /* * returns target flags in extended format or 0 if restripe for this * chunk_type is not in progress - * - * should be called with either volume_mutex or balance_lock held */ static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags) { struct btrfs_balance_control *bctl = fs_info->balance_ctl; u64 target = 0; + BUG_ON(!mutex_is_locked(&fs_info->volume_mutex) && + !spin_is_locked(&fs_info->balance_lock)); + if (!bctl) return 0; @@ -4202,7 +4205,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info) num_bytes += div64_u64(data_used + meta_used, 50); if (num_bytes * 3 > meta_used) - num_bytes = div64_u64(meta_used, 3); + num_bytes = div64_u64(meta_used, 3) * 2; return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10); } diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index cd4b5e400221..8d904dd7ea9f 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -1937,7 +1937,7 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; u64 start = eb->start; unsigned long i, num_pages = num_extent_pages(eb->start, eb->len); - int ret = 0; + int ret; for (i = 0; i < num_pages; i++) { struct page *p = extent_buffer_page(eb, i); @@ -2180,10 +2180,6 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page, } bio = bio_alloc(GFP_NOFS, 1); - if (!bio) { - free_io_failure(inode, failrec, 0); - return -EIO; - } bio->bi_private = state; bio->bi_end_io = failed_bio->bi_end_io; bio->bi_sector = failrec->logical >> 9; diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index 202008ec367d..e88330d3df52 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -747,6 +747,13 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, bool matched; u64 used = btrfs_block_group_used(&block_group->item); + /* + * If we're unmounting then just return, since this does a search on the + * normal root and not the commit root and we could deadlock. + */ + if (btrfs_fs_closing(fs_info)) + return 0; + /* * If this block group has been marked to be cleared for one reason or * another then we can't trust the on disk cache, so just return. @@ -761,8 +768,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, path = btrfs_alloc_path(); if (!path) return 0; - path->search_commit_root = 1; - path->skip_locking = 1; inode = lookup_free_space_inode(root, block_group, path); if (IS_ERR(inode)) { diff --git a/trunk/fs/btrfs/scrub.c b/trunk/fs/btrfs/scrub.c index bc015f77f3ea..90acc82046c3 100644 --- a/trunk/fs/btrfs/scrub.c +++ b/trunk/fs/btrfs/scrub.c @@ -1044,8 +1044,6 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, BUG_ON(!page->page); bio = bio_alloc(GFP_NOFS, 1); - if (!bio) - return -EIO; bio->bi_bdev = page->bdev; bio->bi_sector = page->physical >> 9; bio->bi_end_io = scrub_complete_bio_end_io; @@ -1173,8 +1171,6 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, DECLARE_COMPLETION_ONSTACK(complete); bio = bio_alloc(GFP_NOFS, 1); - if (!bio) - return -EIO; bio->bi_bdev = page_bad->bdev; bio->bi_sector = page_bad->physical >> 9; bio->bi_end_io = scrub_complete_bio_end_io; diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 11b77a59db62..8da29e8e4de1 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -480,7 +480,6 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_fs_info *info = root->fs_info; int count = 0; - int err = 0; if (--trans->use_count) { trans->block_rsv = trans->orig_rsv; @@ -533,18 +532,18 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, if (current->journal_info == trans) current->journal_info = NULL; + memset(trans, 0, sizeof(*trans)); + kmem_cache_free(btrfs_trans_handle_cachep, trans); if (throttle) btrfs_run_delayed_iputs(root); if (trans->aborted || root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { - err = -EIO; + return -EIO; } - memset(trans, 0, sizeof(*trans)); - kmem_cache_free(btrfs_trans_handle_cachep, trans); - return err; + return 0; } int btrfs_end_transaction(struct btrfs_trans_handle *trans, diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 759d02486d7c..a872b48be0ae 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -3833,7 +3833,6 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, int sub_stripes = 0; u64 stripes_per_dev = 0; u32 remaining_stripes = 0; - u32 last_stripe = 0; if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) { @@ -3847,8 +3846,6 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, stripe_nr_orig, factor, &remaining_stripes); - div_u64_rem(stripe_nr_end - 1, factor, &last_stripe); - last_stripe *= sub_stripes; } for (i = 0; i < num_stripes; i++) { @@ -3861,29 +3858,16 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, BTRFS_BLOCK_GROUP_RAID10)) { bbio->stripes[i].length = stripes_per_dev * map->stripe_len; - if (i / sub_stripes < remaining_stripes) bbio->stripes[i].length += map->stripe_len; - - /* - * Special for the first stripe and - * the last stripe: - * - * |-------|...|-------| - * |----------| - * off end_off - */ if (i < sub_stripes) bbio->stripes[i].length -= stripe_offset; - - if (stripe_index >= last_stripe && - stripe_index <= (last_stripe + - sub_stripes - 1)) + if ((i / sub_stripes + 1) % + sub_stripes == remaining_stripes) bbio->stripes[i].length -= stripe_end_offset; - if (i == sub_stripes - 1) stripe_offset = 0; } else diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index f31dc9ac37b7..d81e933a796b 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -109,8 +109,6 @@ enum { /* Options which could be blank */ Opt_blank_pass, - Opt_blank_user, - Opt_blank_ip, Opt_err }; @@ -185,15 +183,11 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_wsize, "wsize=%s" }, { Opt_actimeo, "actimeo=%s" }, - { Opt_blank_user, "user=" }, - { Opt_blank_user, "username=" }, { Opt_user, "user=%s" }, { Opt_user, "username=%s" }, { Opt_blank_pass, "pass=" }, { Opt_pass, "pass=%s" }, { Opt_pass, "password=%s" }, - { Opt_blank_ip, "ip=" }, - { Opt_blank_ip, "addr=" }, { Opt_ip, "ip=%s" }, { Opt_ip, "addr=%s" }, { Opt_unc, "unc=%s" }, @@ -1123,7 +1117,7 @@ static int get_option_ul(substring_t args[], unsigned long *option) string = match_strdup(args); if (string == NULL) return -ENOMEM; - rc = kstrtoul(string, 0, option); + rc = kstrtoul(string, 10, option); kfree(string); return rc; @@ -1540,17 +1534,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* String Arguments */ - case Opt_blank_user: - /* null user, ie. anonymous authentication */ - vol->nullauth = 1; - vol->username = NULL; - break; case Opt_user: string = match_strdup(args); if (string == NULL) goto out_nomem; - if (strnlen(string, MAX_USERNAME_SIZE) > + if (!*string) { + /* null user, ie. anonymous authentication */ + vol->nullauth = 1; + } else if (strnlen(string, MAX_USERNAME_SIZE) > MAX_USERNAME_SIZE) { printk(KERN_WARNING "CIFS: username too long\n"); goto cifs_parse_mount_err; @@ -1619,15 +1611,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } vol->password[j] = '\0'; break; - case Opt_blank_ip: - vol->UNCip = NULL; - break; case Opt_ip: string = match_strdup(args); if (string == NULL) goto out_nomem; - if (strnlen(string, INET6_ADDRSTRLEN) > + if (!*string) { + vol->UNCip = NULL; + } else if (strnlen(string, INET6_ADDRSTRLEN) > INET6_ADDRSTRLEN) { printk(KERN_WARNING "CIFS: ip address " "too long\n"); @@ -1645,6 +1636,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: invalid path to " + "network resource\n"); + goto cifs_parse_mount_err; + } + temp_len = strnlen(string, 300); if (temp_len == 300) { printk(KERN_WARNING "CIFS: UNC name too long\n"); @@ -1673,7 +1670,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (strnlen(string, 256) == 256) { + if (!*string) { + printk(KERN_WARNING "CIFS: invalid domain" + " name\n"); + goto cifs_parse_mount_err; + } else if (strnlen(string, 256) == 256) { printk(KERN_WARNING "CIFS: domain name too" " long\n"); goto cifs_parse_mount_err; @@ -1692,7 +1693,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!cifs_convert_address( + if (!*string) { + printk(KERN_WARNING "CIFS: srcaddr value not" + " specified\n"); + goto cifs_parse_mount_err; + } else if (!cifs_convert_address( (struct sockaddr *)&vol->srcaddr, string, strlen(string))) { printk(KERN_WARNING "CIFS: Could not parse" @@ -1705,6 +1710,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: Invalid path" + " prefix\n"); + goto cifs_parse_mount_err; + } temp_len = strnlen(string, 1024); if (string[0] != '/') temp_len++; /* missing leading slash */ @@ -1732,7 +1742,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (strnlen(string, 1024) >= 65) { + if (!*string) { + printk(KERN_WARNING "CIFS: Invalid iocharset" + " specified\n"); + goto cifs_parse_mount_err; + } else if (strnlen(string, 1024) >= 65) { printk(KERN_WARNING "CIFS: iocharset name " "too long.\n"); goto cifs_parse_mount_err; @@ -1757,6 +1771,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: No socket option" + " specified\n"); + goto cifs_parse_mount_err; + } if (strnicmp(string, "TCP_NODELAY", 11) == 0) vol->sockopt_tcp_nodelay = 1; break; @@ -1765,6 +1784,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: Invalid (empty)" + " netbiosname\n"); + break; + } + memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); /* @@ -1792,6 +1817,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: Empty server" + " netbiosname specified\n"); + break; + } /* last byte, type, is 0x20 for servr type */ memset(vol->target_rfc1001_name, 0x20, RFC1001_NAME_LEN_WITH_NULL); @@ -1818,6 +1848,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + cERROR(1, "no protocol version specified" + " after vers= mount option"); + goto cifs_parse_mount_err; + } + if (strnicmp(string, "cifs", 4) == 0 || strnicmp(string, "1", 1) == 0) { /* This is the default */ @@ -1832,6 +1868,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: no security flavor" + " specified\n"); + break; + } + if (cifs_parse_security_flavors(string, vol) != 0) goto cifs_parse_mount_err; break; diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 0e01e90add8b..ab2594a30f86 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -1203,6 +1203,9 @@ struct ext4_sb_info { unsigned long s_ext_blocks; unsigned long s_ext_extents; #endif + /* ext4 extent cache stats */ + unsigned long extent_cache_hits; + unsigned long extent_cache_misses; /* for buddy allocator */ struct ext4_group_info ***s_group_info; diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index abcdeab67f52..1421938e6792 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -2066,6 +2066,10 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block, ret = 1; } errout: + if (!ret) + sbi->extent_cache_misses++; + else + sbi->extent_cache_hits++; trace_ext4_ext_in_cache(inode, block, ret); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); return ret; @@ -2878,7 +2882,7 @@ static int ext4_split_extent_at(handle_t *handle, if (err) goto fix_extent_len; /* update the extent length and mark as initialized */ - ex->ee_len = cpu_to_le16(ee_len); + ex->ee_len = cpu_to_le32(ee_len); ext4_ext_try_to_merge(inode, path, ex); err = ext4_ext_dirty(handle, inode, path + depth); goto out; diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 6da193564e43..ceebaf853beb 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) ext4_msg(sb, KERN_ERR, "Cannot change journaled " "quota options when quota turned on"); - return -1; + return 0; } qname = match_strdup(args); if (!qname) { ext4_msg(sb, KERN_ERR, "Not enough memory for storing quotafile name"); - return -1; + return 0; } if (sbi->s_qf_names[qtype] && strcmp(sbi->s_qf_names[qtype], qname)) { ext4_msg(sb, KERN_ERR, "%s quota file already specified", QTYPE2NAME(qtype)); kfree(qname); - return -1; + return 0; } sbi->s_qf_names[qtype] = qname; if (strchr(sbi->s_qf_names[qtype], '/')) { @@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) "quotafile must be on filesystem root"); kfree(sbi->s_qf_names[qtype]); sbi->s_qf_names[qtype] = NULL; - return -1; + return 0; } set_opt(sb, QUOTA); return 1; @@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype) sbi->s_qf_names[qtype]) { ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" " when quota turned on"); - return -1; + return 0; } /* * The space will be released later when all options are confirmed @@ -1450,16 +1450,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, const struct mount_opts *m; int arg = 0; -#ifdef CONFIG_QUOTA - if (token == Opt_usrjquota) - return set_qf_name(sb, USRQUOTA, &args[0]); - else if (token == Opt_grpjquota) - return set_qf_name(sb, GRPQUOTA, &args[0]); - else if (token == Opt_offusrjquota) - return clear_qf_name(sb, USRQUOTA); - else if (token == Opt_offgrpjquota) - return clear_qf_name(sb, GRPQUOTA); -#endif if (args->from && match_int(args, &arg)) return -1; switch (token) { @@ -1559,6 +1549,18 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, sbi->s_mount_opt |= m->mount_opt; } #ifdef CONFIG_QUOTA + } else if (token == Opt_usrjquota) { + if (!set_qf_name(sb, USRQUOTA, &args[0])) + return -1; + } else if (token == Opt_grpjquota) { + if (!set_qf_name(sb, GRPQUOTA, &args[0])) + return -1; + } else if (token == Opt_offusrjquota) { + if (!clear_qf_name(sb, USRQUOTA)) + return -1; + } else if (token == Opt_offgrpjquota) { + if (!clear_qf_name(sb, GRPQUOTA)) + return -1; } else if (m->flags & MOPT_QFMT) { if (sb_any_quota_loaded(sb) && sbi->s_jquota_fmt != m->mount_opt) { @@ -2364,6 +2366,18 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, EXT4_SB(sb)->s_sectors_written_start) >> 1))); } +static ssize_t extent_cache_hits_show(struct ext4_attr *a, + struct ext4_sb_info *sbi, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits); +} + +static ssize_t extent_cache_misses_show(struct ext4_attr *a, + struct ext4_sb_info *sbi, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses); +} + static ssize_t inode_readahead_blks_store(struct ext4_attr *a, struct ext4_sb_info *sbi, const char *buf, size_t count) @@ -2421,6 +2435,8 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) EXT4_RO_ATTR(delayed_allocation_blocks); EXT4_RO_ATTR(session_write_kbytes); EXT4_RO_ATTR(lifetime_write_kbytes); +EXT4_RO_ATTR(extent_cache_hits); +EXT4_RO_ATTR(extent_cache_misses); EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show, inode_readahead_blks_store, s_inode_readahead_blks); EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); @@ -2436,6 +2452,8 @@ static struct attribute *ext4_attrs[] = { ATTR_LIST(delayed_allocation_blocks), ATTR_LIST(session_write_kbytes), ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(extent_cache_hits), + ATTR_LIST(extent_cache_misses), ATTR_LIST(inode_readahead_blks), ATTR_LIST(inode_goal), ATTR_LIST(mb_stats), diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index df5ac048dc74..206632887bb4 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -387,6 +387,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (fc->no_create) return -ENOSYS; + if (flags & O_DIRECT) + return -EINVAL; + forget = fuse_alloc_forget(); if (!forget) return -ENOMEM; @@ -641,12 +644,13 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) fuse_put_request(fc, req); if (!err) { struct inode *inode = entry->d_inode; - struct fuse_inode *fi = get_fuse_inode(inode); - spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; - drop_nlink(inode); - spin_unlock(&fc->lock); + /* + * Set nlink to zero so the inode can be cleared, if the inode + * does have more links this will be discovered at the next + * lookup/getattr. + */ + clear_nlink(inode); fuse_invalidate_attr(inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); @@ -758,17 +762,8 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, will reflect changes in the backing inode (link count, etc.) */ - if (!err) { - struct fuse_inode *fi = get_fuse_inode(inode); - - spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; - inc_nlink(inode); - spin_unlock(&fc->lock); - fuse_invalidate_attr(inode); - } else if (err == -EINTR) { + if (!err || err == -EINTR) fuse_invalidate_attr(inode); - } return err; } diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 504e61b7fd75..a841868bf9ce 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -194,6 +194,10 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) struct fuse_conn *fc = get_fuse_conn(inode); int err; + /* VFS checks this, but only _after_ ->open() */ + if (file->f_flags & O_DIRECT) + return -EINVAL; + err = generic_file_open(inode, file); if (err) return err; @@ -928,23 +932,17 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; size_t count = 0; - size_t ocount = 0; ssize_t written = 0; - ssize_t written_buffered = 0; struct inode *inode = mapping->host; ssize_t err; struct iov_iter i; - loff_t endbyte = 0; WARN_ON(iocb->ki_pos != pos); - ocount = 0; - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); + err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); if (err) return err; - count = ocount; - mutex_lock(&inode->i_mutex); vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); @@ -964,41 +962,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, file_update_time(file); - if (file->f_flags & O_DIRECT) { - written = generic_file_direct_write(iocb, iov, &nr_segs, - pos, &iocb->ki_pos, - count, ocount); - if (written < 0 || written == count) - goto out; - - pos += written; - count -= written; + iov_iter_init(&i, iov, nr_segs, count, 0); + written = fuse_perform_write(file, mapping, &i, pos); + if (written >= 0) + iocb->ki_pos = pos + written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = fuse_perform_write(file, mapping, &i, pos); - if (written_buffered < 0) { - err = written_buffered; - goto out; - } - endbyte = pos + written_buffered - 1; - - err = filemap_write_and_wait_range(file->f_mapping, pos, - endbyte); - if (err) - goto out; - - invalidate_mapping_pages(file->f_mapping, - pos >> PAGE_CACHE_SHIFT, - endbyte >> PAGE_CACHE_SHIFT); - - written += written_buffered; - iocb->ki_pos = pos + written_buffered; - } else { - iov_iter_init(&i, iov, nr_segs, count, 0); - written = fuse_perform_write(file, mapping, &i, pos); - if (written >= 0) - iocb->ki_pos = pos + written; - } out: current->backing_dev_info = NULL; mutex_unlock(&inode->i_mutex); @@ -1133,24 +1101,6 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, return res; } -static ssize_t __fuse_direct_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct inode *inode = file->f_path.dentry->d_inode; - ssize_t res; - - res = generic_write_checks(file, ppos, &count, 0); - if (!res) { - res = fuse_direct_io(file, buf, count, ppos, 1); - if (res > 0) - fuse_write_update_size(inode, *ppos); - } - - fuse_invalidate_attr(inode); - - return res; -} - static ssize_t fuse_direct_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -1162,9 +1112,16 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = __fuse_direct_write(file, buf, count, ppos); + res = generic_write_checks(file, ppos, &count, 0); + if (!res) { + res = fuse_direct_io(file, buf, count, ppos, 1); + if (res > 0) + fuse_write_update_size(inode, *ppos); + } mutex_unlock(&inode->i_mutex); + fuse_invalidate_attr(inode); + return res; } @@ -2120,57 +2077,6 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc, return 0; } -static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov, - unsigned long nr_segs, loff_t *ppos, int rw) -{ - const struct iovec *vector = iov; - ssize_t ret = 0; - - while (nr_segs > 0) { - void __user *base; - size_t len; - ssize_t nr; - - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - if (rw == WRITE) - nr = __fuse_direct_write(filp, base, len, ppos); - else - nr = fuse_direct_read(filp, base, len, ppos); - - if (nr < 0) { - if (!ret) - ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } - - return ret; -} - - -static ssize_t -fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t offset, unsigned long nr_segs) -{ - ssize_t ret = 0; - struct file *file = NULL; - loff_t pos = 0; - - file = iocb->ki_filp; - pos = offset; - - ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw); - - return ret; -} - static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -2214,7 +2120,6 @@ static const struct address_space_operations fuse_file_aops = { .readpages = fuse_readpages, .set_page_dirty = __set_page_dirty_nobuffers, .bmap = fuse_bmap, - .direct_IO = fuse_direct_IO, }; void fuse_init_file_inode(struct inode *inode) diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index 26783eb2b1fc..4aec5995867e 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -947,7 +947,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_time_gran = 1; sb->s_export_op = &fuse_export_operations; file = fget(d.fd); diff --git a/trunk/fs/gfs2/Kconfig b/trunk/fs/gfs2/Kconfig index eb08c9e43c2a..c465ae066c62 100644 --- a/trunk/fs/gfs2/Kconfig +++ b/trunk/fs/gfs2/Kconfig @@ -1,6 +1,10 @@ config GFS2_FS tristate "GFS2 file system support" depends on (64BIT || LBDAF) + select DLM if GFS2_FS_LOCKING_DLM + select CONFIGFS_FS if GFS2_FS_LOCKING_DLM + select SYSFS if GFS2_FS_LOCKING_DLM + select IP_SCTP if DLM_SCTP select FS_POSIX_ACL select CRC32 select QUOTACTL @@ -25,8 +29,7 @@ config GFS2_FS config GFS2_FS_LOCKING_DLM bool "GFS2 DLM locking" - depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \ - HOTPLUG && DLM && CONFIGFS_FS && SYSFS + depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && HOTPLUG help Multiple node locking module for GFS2 diff --git a/trunk/fs/gfs2/aops.c b/trunk/fs/gfs2/aops.c index 9b2ff0e851b1..38b7a74a0f91 100644 --- a/trunk/fs/gfs2/aops.c +++ b/trunk/fs/gfs2/aops.c @@ -807,7 +807,7 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, if (inode == sdp->sd_rindex) { adjust_fs_space(inode); - sdp->sd_rindex_uptodate = 0; + ip->i_gh.gh_flags |= GL_NOCACHE; } brelse(dibh); @@ -873,7 +873,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, if (inode == sdp->sd_rindex) { adjust_fs_space(inode); - sdp->sd_rindex_uptodate = 0; + ip->i_gh.gh_flags |= GL_NOCACHE; } brelse(dibh); diff --git a/trunk/fs/gfs2/bmap.c b/trunk/fs/gfs2/bmap.c index 03c04febe26f..197c5c47e577 100644 --- a/trunk/fs/gfs2/bmap.c +++ b/trunk/fs/gfs2/bmap.c @@ -724,11 +724,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, int metadata; unsigned int revokes = 0; int x; - int error; - - error = gfs2_rindex_update(sdp); - if (error) - return error; + int error = 0; if (!*top) sm->sm_first = 0; diff --git a/trunk/fs/gfs2/dir.c b/trunk/fs/gfs2/dir.c index a836056343f0..c35573abd371 100644 --- a/trunk/fs/gfs2/dir.c +++ b/trunk/fs/gfs2/dir.c @@ -1844,10 +1844,6 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, unsigned int x, size = len * sizeof(u64); int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); ht = kzalloc(size, GFP_NOFS); diff --git a/trunk/fs/gfs2/inode.c b/trunk/fs/gfs2/inode.c index a9ba2444e077..c98a60ee6dfd 100644 --- a/trunk/fs/gfs2/inode.c +++ b/trunk/fs/gfs2/inode.c @@ -1031,13 +1031,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) struct buffer_head *bh; struct gfs2_holder ghs[3]; struct gfs2_rgrpd *rgd; - int error; - - error = gfs2_rindex_update(sdp); - if (error) - return error; - - error = -EROFS; + int error = -EROFS; gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); @@ -1230,10 +1224,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, return 0; } - error = gfs2_rindex_update(sdp); - if (error) - return error; - if (odip != ndip) { error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0, &r_gh); @@ -1355,6 +1345,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, error = alloc_required; if (error < 0) goto out_gunlock; + error = 0; if (alloc_required) { struct gfs2_qadata *qa = gfs2_qadata_get(ndip); diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 3df65c9ab73b..19bde40b4864 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -332,6 +332,9 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact) struct rb_node *n, *next; struct gfs2_rgrpd *cur; + if (gfs2_rindex_update(sdp)) + return NULL; + spin_lock(&sdp->sd_rindex_spin); n = sdp->sd_rindex_tree.rb_node; while (n) { @@ -637,7 +640,6 @@ static int read_rindex_entry(struct gfs2_inode *ip, return 0; error = 0; /* someone else read in the rgrp; free it and ignore it */ - gfs2_glock_put(rgd->rd_gl); fail: kfree(rgd->rd_bits); @@ -925,10 +927,6 @@ int gfs2_fitrim(struct file *filp, void __user *argp) } else if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; - ret = gfs2_rindex_update(sdp); - if (ret) - return ret; - rgd = gfs2_blk2rgrpd(sdp, r.start, 0); rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); diff --git a/trunk/fs/gfs2/xattr.c b/trunk/fs/gfs2/xattr.c index 927f4df874ae..2e5ba425cae7 100644 --- a/trunk/fs/gfs2/xattr.c +++ b/trunk/fs/gfs2/xattr.c @@ -238,10 +238,6 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, unsigned int x; int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - if (GFS2_EA_IS_STUFFED(ea)) return 0; @@ -1334,10 +1330,6 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) unsigned int x; int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh); @@ -1447,10 +1439,6 @@ static int ea_dealloc_block(struct gfs2_inode *ip) struct gfs2_holder gh; int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1); if (!rgd) { gfs2_consist_inode(ip); diff --git a/trunk/fs/libfs.c b/trunk/fs/libfs.c index 18d08f5db53a..358094f0433d 100644 --- a/trunk/fs/libfs.c +++ b/trunk/fs/libfs.c @@ -529,7 +529,6 @@ int simple_fill_super(struct super_block *s, unsigned long magic, return 0; out: d_genocide(root); - shrink_dcache_parent(root); dput(root); return -ENOMEM; } diff --git a/trunk/fs/lockd/clnt4xdr.c b/trunk/fs/lockd/clnt4xdr.c index 13ad1539fbf2..3ddcbb1c0a43 100644 --- a/trunk/fs/lockd/clnt4xdr.c +++ b/trunk/fs/lockd/clnt4xdr.c @@ -241,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(ntohl(*p) > ntohl(nlm4_failed))) + if (unlikely(*p > nlm4_failed)) goto out_bad_xdr; *stat = *p; return 0; diff --git a/trunk/fs/lockd/clntxdr.c b/trunk/fs/lockd/clntxdr.c index d269ada7670e..3d35e3e80c1c 100644 --- a/trunk/fs/lockd/clntxdr.c +++ b/trunk/fs/lockd/clntxdr.c @@ -236,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr, p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period))) + if (unlikely(*p > nlm_lck_denied_grace_period)) goto out_enum; *stat = *p; return 0; diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index 43f46cd9edea..08c6e36ab2eb 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -803,13 +803,13 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, return p; } -static __be32 +static int compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, const char *name, int namlen) { struct svc_export *exp; struct dentry *dparent, *dchild; - __be32 rv = nfserr_noent; + int rv = 0; dparent = cd->fh.fh_dentry; exp = cd->fh.fh_export; @@ -817,20 +817,26 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, if (isdotent(name, namlen)) { if (namlen == 2) { dchild = dget_parent(dparent); - /* filesystem root - cannot return filehandle for ".." */ - if (dchild == dparent) - goto out; + if (dchild == dparent) { + /* filesystem root - cannot return filehandle for ".." */ + dput(dchild); + return -ENOENT; + } } else dchild = dget(dparent); } else dchild = lookup_one_len(name, dparent, namlen); if (IS_ERR(dchild)) - return rv; + return -ENOENT; + rv = -ENOENT; if (d_mountpoint(dchild)) goto out; + rv = fh_compose(fhp, exp, dchild, &cd->fh); + if (rv) + goto out; if (!dchild->d_inode) goto out; - rv = fh_compose(fhp, exp, dchild, &cd->fh); + rv = 0; out: dput(dchild); return rv; @@ -839,7 +845,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) { struct svc_fh fh; - __be32 err; + int err; fh_init(&fh, NFS3_FHSIZE); err = compose_entry_fh(cd, &fh, name, namlen); diff --git a/trunk/fs/nfsd/nfs4proc.c b/trunk/fs/nfsd/nfs4proc.c index 987e719fbae8..2ed14dfd00a2 100644 --- a/trunk/fs/nfsd/nfs4proc.c +++ b/trunk/fs/nfsd/nfs4proc.c @@ -235,15 +235,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o */ if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_MODIFY); + FATTR4_WORD1_TIME_MODIFY); } else { status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, resfh); fh_unlock(current_fh); + if (status) + goto out; + status = nfsd_check_obj_isreg(resfh); } - if (status) - goto out; - status = nfsd_check_obj_isreg(resfh); if (status) goto out; @@ -841,7 +841,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) { __be32 status = nfs_ok; - int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { nfs4_lock_state(); @@ -853,9 +852,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } } - err = fh_want_write(&cstate->current_fh); - if (err) - return nfserrno(err); + status = fh_want_write(&cstate->current_fh); + if (status) + return status; status = nfs_ok; status = check_attr_support(rqstp, cstate, setattr->sa_bmval, diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 7f71c69cdcdf..1841f8bf845e 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -4211,14 +4211,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * vfs_test_lock. (Arguably perhaps test_lock should be done with an * inode operation.) */ -static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) +static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) { struct file *file; - __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); - if (!err) { - err = nfserrno(vfs_test_lock(file, lock)); - nfsd_close(file); - } + int err; + + err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); + if (err) + return err; + err = vfs_test_lock(file, lock); + nfsd_close(file); return err; } @@ -4232,6 +4234,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct inode *inode; struct file_lock file_lock; struct nfs4_lockowner *lo; + int error; __be32 status; if (locks_in_grace()) @@ -4277,10 +4280,12 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfs4_transform_lock_offset(&file_lock); - status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); - if (status) + status = nfs_ok; + error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); + if (error) { + status = nfserrno(error); goto out; - + } if (file_lock.fl_type != F_UNLCK) { status = nfserr_denied; nfs4_set_lock_denied(&file_lock, &lockt->lt_denied); diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 74c00bc92b9a..bcd8904ab1e3 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -1392,7 +1392,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta for (i = 0; i < test_stateid->ts_num_ids; i++) { stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL); if (!stateid) { - status = nfserrno(-ENOMEM); + status = PTR_ERR(stateid); goto out; } @@ -3410,7 +3410,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, *p++ = htonl(test_stateid->ts_num_ids); list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) { - *p++ = stateid->ts_id_status; + *p++ = htonl(stateid->ts_id_status); } ADJUST_ARGS(); diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 568666156ea4..296d671654d6 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, switch (createmode) { case NFS3_CREATE_UNCHECKED: if (! S_ISREG(dchild->d_inode->i_mode)) - goto out; + err = nfserr_exist; else if (truncp) { /* in nfsv4, we need to treat this case a little * differently. we don't want to truncate the diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index 31b9463fba1f..3165aebb43c8 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -1134,7 +1134,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle, } el = path_leaf_el(path); - rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1]; + rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1]; ocfs2_adjust_rightmost_records(handle, et, path, rec); diff --git a/trunk/fs/ocfs2/refcounttree.c b/trunk/fs/ocfs2/refcounttree.c index 9f32d7cbb7a3..cf7823382664 100644 --- a/trunk/fs/ocfs2/refcounttree.c +++ b/trunk/fs/ocfs2/refcounttree.c @@ -1036,14 +1036,14 @@ static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, tmp_el = left_path->p_node[subtree_root].el; blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; - for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) { + for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); break; } } - BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec)); + BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); out: ocfs2_free_path(left_path); @@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, trace_ocfs2_divide_leaf_refcount_block( (unsigned long long)ref_leaf_bh->b_blocknr, - le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used)); + le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used)); /* * XXX: Improvement later. @@ -2411,7 +2411,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, rb = (struct ocfs2_refcount_block *) prev_bh->b_data; - if (le16_to_cpu(rb->rf_records.rl_used) + + if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -2476,7 +2476,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, if (prev_bh) { rb = (struct ocfs2_refcount_block *)prev_bh->b_data; - if (le16_to_cpu(rb->rf_records.rl_used) + recs_add > + if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -3629,7 +3629,7 @@ int ocfs2_refcounted_xattr_delete_need(struct inode *inode, * one will split a refcount rec, so totally we need * clusters * 2 new refcount rec. */ - if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 > + if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; diff --git a/trunk/fs/ocfs2/suballoc.c b/trunk/fs/ocfs2/suballoc.c index f169da4624fd..ba5d97e4a73e 100644 --- a/trunk/fs/ocfs2/suballoc.c +++ b/trunk/fs/ocfs2/suballoc.c @@ -600,7 +600,7 @@ static void ocfs2_bg_alloc_cleanup(handle_t *handle, ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode, cluster_ac->ac_bh, le64_to_cpu(rec->e_blkno), - le16_to_cpu(rec->e_leaf_clusters)); + le32_to_cpu(rec->e_leaf_clusters)); if (ret) mlog_errno(ret); /* Try all the clusters to free */ @@ -1628,7 +1628,7 @@ static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res, { unsigned int bpc = le16_to_cpu(cl->cl_bpc); unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc; - unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc; + unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc; if (res->sr_bit_offset < bitoff) return 0; diff --git a/trunk/fs/proc/stat.c b/trunk/fs/proc/stat.c index 64c3b3172367..6a0c62d6e442 100644 --- a/trunk/fs/proc/stat.c +++ b/trunk/fs/proc/stat.c @@ -18,39 +18,19 @@ #ifndef arch_irq_stat #define arch_irq_stat() 0 #endif - -#ifdef arch_idle_time - -static cputime64_t get_idle_time(int cpu) -{ - cputime64_t idle; - - idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; - if (cpu_online(cpu) && !nr_iowait_cpu(cpu)) - idle += arch_idle_time(cpu); - return idle; -} - -static cputime64_t get_iowait_time(int cpu) -{ - cputime64_t iowait; - - iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; - if (cpu_online(cpu) && nr_iowait_cpu(cpu)) - iowait += arch_idle_time(cpu); - return iowait; -} - -#else +#ifndef arch_idle_time +#define arch_idle_time(cpu) 0 +#endif static u64 get_idle_time(int cpu) { u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); - if (idle_time == -1ULL) + if (idle_time == -1ULL) { /* !NO_HZ so we can rely on cpustat.idle */ idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; - else + idle += arch_idle_time(cpu); + } else idle = usecs_to_cputime64(idle_time); return idle; @@ -69,8 +49,6 @@ static u64 get_iowait_time(int cpu) return iowait; } -#endif - static int show_stat(struct seq_file *p, void *v) { int i, j; diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index 35a36d39fa2c..2a7a3f5d1ca6 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -729,9 +729,6 @@ int sysfs_create_dir(struct kobject * kobj) else parent_sd = &sysfs_root; - if (!parent_sd) - return -ENOENT; - if (sysfs_ns_type(parent_sd)) ns = kobj->ktype->namespace(kobj); type = sysfs_read_ns_type(kobj); @@ -881,6 +878,7 @@ int sysfs_rename(struct sysfs_dirent *sd, dup_name = sd->s_name; sd->s_name = new_name; + sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); } /* Move to the appropriate place in the appropriate directories rbtree. */ @@ -888,7 +886,6 @@ int sysfs_rename(struct sysfs_dirent *sd, sysfs_get(new_parent_sd); sysfs_put(sd->s_parent); sd->s_ns = new_ns; - sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); sd->s_parent = new_parent_sd; sysfs_link_sibling(sd); diff --git a/trunk/fs/sysfs/group.c b/trunk/fs/sysfs/group.c index 2df555c66d57..dd1701caecc9 100644 --- a/trunk/fs/sysfs/group.c +++ b/trunk/fs/sysfs/group.c @@ -67,11 +67,7 @@ static int internal_create_group(struct kobject *kobj, int update, /* Updates may happen before the object has been instantiated */ if (unlikely(update && !kobj->sd)) return -EINVAL; - if (!grp->attrs) { - WARN(1, "sysfs: attrs not set by subsystem for group: %s/%s\n", - kobj->name, grp->name ? "" : grp->name); - return -EINVAL; - } + if (grp->name) { error = sysfs_create_subdir(kobj, grp->name, &sd); if (error) diff --git a/trunk/include/drm/exynos_drm.h b/trunk/include/drm/exynos_drm.h index e478de4e5d56..3963116083ae 100644 --- a/trunk/include/drm/exynos_drm.h +++ b/trunk/include/drm/exynos_drm.h @@ -85,7 +85,7 @@ struct drm_exynos_gem_mmap { struct drm_exynos_vidi_connection { unsigned int connection; unsigned int extensions; - uint64_t edid; + uint64_t *edid; }; struct drm_exynos_plane_set_zpos { @@ -96,8 +96,7 @@ struct drm_exynos_plane_set_zpos { /* memory type definitions. */ enum e_drm_exynos_gem_mem_type { /* Physically Non-Continuous memory. */ - EXYNOS_BO_NONCONTIG = 1 << 0, - EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG + EXYNOS_BO_NONCONTIG = 1 << 0 }; #define DRM_EXYNOS_GEM_CREATE 0x00 diff --git a/trunk/include/linux/amba/bus.h b/trunk/include/linux/amba/bus.h index 8d54f79457ba..7847e197730a 100644 --- a/trunk/include/linux/amba/bus.h +++ b/trunk/include/linux/amba/bus.h @@ -30,6 +30,7 @@ struct amba_device { struct device dev; struct resource res; struct clk *pclk; + struct regulator *vcore; u64 dma_mask; unsigned int periphid; unsigned int irq[AMBA_NR_IRQS]; @@ -74,6 +75,12 @@ void amba_release_regions(struct amba_device *); #define amba_pclk_disable(d) \ do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0) +#define amba_vcore_enable(d) \ + (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore)) + +#define amba_vcore_disable(d) \ + do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0) + /* Some drivers don't use the struct amba_device */ #define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff) #define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f) diff --git a/trunk/include/linux/amba/pl022.h b/trunk/include/linux/amba/pl022.h index 76dd1b199a1b..b8c51124ed19 100644 --- a/trunk/include/linux/amba/pl022.h +++ b/trunk/include/linux/amba/pl022.h @@ -25,8 +25,6 @@ #ifndef _SSP_PL022_H #define _SSP_PL022_H -#include - /** * whether SSP is in loopback mode or not */ diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 2aa24664a5b5..606cf339bb56 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -426,10 +426,14 @@ struct request_queue { (1 << QUEUE_FLAG_SAME_COMP) | \ (1 << QUEUE_FLAG_ADD_RANDOM)) -static inline void queue_lockdep_assert_held(struct request_queue *q) +static inline int queue_is_locked(struct request_queue *q) { - if (q->queue_lock) - lockdep_assert_held(q->queue_lock); +#ifdef CONFIG_SMP + spinlock_t *lock = q->queue_lock; + return lock && spin_is_locked(lock); +#else + return 1; +#endif } static inline void queue_flag_set_unlocked(unsigned int flag, @@ -441,7 +445,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag, static inline int queue_flag_test_and_clear(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); if (test_bit(flag, &q->queue_flags)) { __clear_bit(flag, &q->queue_flags); @@ -454,7 +458,7 @@ static inline int queue_flag_test_and_clear(unsigned int flag, static inline int queue_flag_test_and_set(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); if (!test_bit(flag, &q->queue_flags)) { __set_bit(flag, &q->queue_flags); @@ -466,7 +470,7 @@ static inline int queue_flag_test_and_set(unsigned int flag, static inline void queue_flag_set(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); __set_bit(flag, &q->queue_flags); } @@ -483,7 +487,7 @@ static inline int queue_in_flight(struct request_queue *q) static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); __clear_bit(flag, &q->queue_flags); } diff --git a/trunk/include/linux/dmaengine.h b/trunk/include/linux/dmaengine.h index f9a2e5e67a54..676f967390ae 100644 --- a/trunk/include/linux/dmaengine.h +++ b/trunk/include/linux/dmaengine.h @@ -974,7 +974,6 @@ int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); -struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) /* --- Helper iov-locking functions --- */ diff --git a/trunk/include/linux/fuse.h b/trunk/include/linux/fuse.h index 8f2ab8fef929..8ba2c9460b28 100644 --- a/trunk/include/linux/fuse.h +++ b/trunk/include/linux/fuse.h @@ -593,7 +593,7 @@ struct fuse_dirent { __u64 off; __u32 namelen; __u32 type; - char name[]; + char name[0]; }; #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) diff --git a/trunk/include/linux/i2c/twl.h b/trunk/include/linux/i2c/twl.h index 1f90de0cfdbe..2463b6100333 100644 --- a/trunk/include/linux/i2c/twl.h +++ b/trunk/include/linux/i2c/twl.h @@ -666,11 +666,23 @@ struct twl4030_codec_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; + u16 hs_left_step; + u16 hs_right_step; + u16 hf_left_step; + u16 hf_right_step; void (*set_hs_extmute)(int mute); }; struct twl4030_vibra_data { unsigned int coexist; + + /* twl6040 */ + unsigned int vibldrv_res; /* left driver resistance */ + unsigned int vibrdrv_res; /* right driver resistance */ + unsigned int viblmotor_res; /* left motor resistance */ + unsigned int vibrmotor_res; /* right motor resistance */ + int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ + int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ }; struct twl4030_audio_data { diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 7810406f3d80..bff29c58da23 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -263,11 +263,6 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; } -static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) -{ - return d->hwirq; -} - /** * struct irq_chip - hardware interrupt chip descriptor * diff --git a/trunk/include/linux/irqdomain.h b/trunk/include/linux/irqdomain.h index c65740d76e66..ead4a4215797 100644 --- a/trunk/include/linux/irqdomain.h +++ b/trunk/include/linux/irqdomain.h @@ -42,6 +42,12 @@ struct of_device_id; /* Number of irqs reserved for a legacy isa controller */ #define NUM_ISA_INTERRUPTS 16 +/* This type is the placeholder for a hardware interrupt number. It has to + * be big enough to enclose whatever representation is used by a given + * platform. + */ +typedef unsigned long irq_hw_number_t; + /** * struct irq_domain_ops - Methods for irq_domain objects * @match: Match an interrupt controller device node to a host, returns @@ -98,9 +104,6 @@ struct irq_domain { unsigned int size; unsigned int *revmap; } linear; - struct { - unsigned int max_irq; - } nomap; struct radix_tree_root tree; } revmap_data; const struct irq_domain_ops *ops; @@ -123,7 +126,6 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, const struct irq_domain_ops *ops, void *host_data); struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, - unsigned int max_irq, const struct irq_domain_ops *ops, void *host_data); struct irq_domain *irq_domain_add_tree(struct device_node *of_node, @@ -132,6 +134,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node, extern struct irq_domain *irq_find_host(struct device_node *node); extern void irq_set_default_host(struct irq_domain *host); +extern void irq_set_virq_count(unsigned int count); static inline struct irq_domain *irq_domain_add_legacy_isa( struct device_node *of_node, @@ -143,6 +146,7 @@ static inline struct irq_domain *irq_domain_add_legacy_isa( } extern struct irq_domain *irq_find_host(struct device_node *node); extern void irq_set_default_host(struct irq_domain *host); +extern void irq_set_virq_count(unsigned int count); extern unsigned int irq_create_mapping(struct irq_domain *host, diff --git a/trunk/include/linux/kconfig.h b/trunk/include/linux/kconfig.h index be342b94c640..067eda0e4b32 100644 --- a/trunk/include/linux/kconfig.h +++ b/trunk/include/linux/kconfig.h @@ -4,43 +4,29 @@ #include /* - * Helper macros to use CONFIG_ options in C/CPP expressions. Note that + * Helper macros to use CONFIG_ options in C expressions. Note that * these only work with boolean and tristate options. */ -/* - * Getting something that works in C and CPP for an arg that may or may - * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" - * we match on the placeholder define, insert the "0," for arg1 and generate - * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). - * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when - * the last step cherry picks the 2nd arg, we get a zero. - */ -#define __ARG_PLACEHOLDER_1 0, -#define config_enabled(cfg) _config_enabled(cfg) -#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) -#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) -#define ___config_enabled(__ignored, val, ...) val - /* * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', * 0 otherwise. * */ #define IS_ENABLED(option) \ - (config_enabled(option) || config_enabled(option##_MODULE)) + (__enabled_ ## option || __enabled_ ## option ## _MODULE) /* * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 * otherwise. For boolean options, this is equivalent to * IS_ENABLED(CONFIG_FOO). */ -#define IS_BUILTIN(option) config_enabled(option) +#define IS_BUILTIN(option) __enabled_ ## option /* * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 * otherwise. */ -#define IS_MODULE(option) config_enabled(option##_MODULE) +#define IS_MODULE(option) __enabled_ ## option ## _MODULE #endif /* __LINUX_KCONFIG_H */ diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 72cbf08d45fb..665a260c7e09 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -596,7 +596,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_IOMMU_API int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); -void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); int kvm_iommu_map_guest(struct kvm *kvm); int kvm_iommu_unmap_guest(struct kvm *kvm); int kvm_assign_device(struct kvm *kvm, @@ -610,11 +609,6 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm, return 0; } -static inline void kvm_iommu_unmap_pages(struct kvm *kvm, - struct kvm_memory_slot *slot) -{ -} - static inline int kvm_iommu_map_guest(struct kvm *kvm) { return -ENODEV; diff --git a/trunk/include/linux/mfd/abx500.h b/trunk/include/linux/mfd/abx500.h index 1318ca622633..ee96cd51d8b2 100644 --- a/trunk/include/linux/mfd/abx500.h +++ b/trunk/include/linux/mfd/abx500.h @@ -6,7 +6,7 @@ * * ABX500 core access functions. * The abx500 interface is used for the Analog Baseband chip - * ab3100 and ab8500. + * ab3100, ab5500, and ab8500. * * Author: Mattias Wallin * Author: Mattias Nilsson @@ -30,6 +30,9 @@ struct device; #define AB3100_P1G 0xc6 #define AB3100_R2A 0xc7 #define AB3100_R2B 0xc8 +#define AB5500_1_0 0x20 +#define AB5500_1_1 0x21 +#define AB5500_2_0 0x24 /* * AB3100, EVENTA1, A2 and A3 event register flags diff --git a/trunk/include/linux/mfd/abx500/ab5500.h b/trunk/include/linux/mfd/abx500/ab5500.h new file mode 100644 index 000000000000..54f820ed73bb --- /dev/null +++ b/trunk/include/linux/mfd/abx500/ab5500.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) ST-Ericsson 2011 + * + * License Terms: GNU General Public License v2 + */ +#ifndef MFD_AB5500_H +#define MFD_AB5500_H + +struct device; + +enum ab5500_devid { + AB5500_DEVID_ADC, + AB5500_DEVID_LEDS, + AB5500_DEVID_POWER, + AB5500_DEVID_REGULATORS, + AB5500_DEVID_SIM, + AB5500_DEVID_RTC, + AB5500_DEVID_CHARGER, + AB5500_DEVID_FUELGAUGE, + AB5500_DEVID_VIBRATOR, + AB5500_DEVID_CODEC, + AB5500_DEVID_USB, + AB5500_DEVID_OTP, + AB5500_DEVID_VIDEO, + AB5500_DEVID_DBIECI, + AB5500_DEVID_ONSWA, + AB5500_NUM_DEVICES, +}; + +enum ab5500_banks { + AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP = 0, + AB5500_BANK_VDDDIG_IO_I2C_CLK_TST = 1, + AB5500_BANK_VDENC = 2, + AB5500_BANK_SIM_USBSIM = 3, + AB5500_BANK_LED = 4, + AB5500_BANK_ADC = 5, + AB5500_BANK_RTC = 6, + AB5500_BANK_STARTUP = 7, + AB5500_BANK_DBI_ECI = 8, + AB5500_BANK_CHG = 9, + AB5500_BANK_FG_BATTCOM_ACC = 10, + AB5500_BANK_USB = 11, + AB5500_BANK_IT = 12, + AB5500_BANK_VIBRA = 13, + AB5500_BANK_AUDIO_HEADSETUSB = 14, + AB5500_NUM_BANKS = 15, +}; + +enum ab5500_banks_addr { + AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP = 0x4A, + AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST = 0x4B, + AB5500_ADDR_VDENC = 0x06, + AB5500_ADDR_SIM_USBSIM = 0x04, + AB5500_ADDR_LED = 0x10, + AB5500_ADDR_ADC = 0x0A, + AB5500_ADDR_RTC = 0x0F, + AB5500_ADDR_STARTUP = 0x03, + AB5500_ADDR_DBI_ECI = 0x07, + AB5500_ADDR_CHG = 0x0B, + AB5500_ADDR_FG_BATTCOM_ACC = 0x0C, + AB5500_ADDR_USB = 0x05, + AB5500_ADDR_IT = 0x0E, + AB5500_ADDR_VIBRA = 0x02, + AB5500_ADDR_AUDIO_HEADSETUSB = 0x0D, +}; + +/* + * Interrupt register offsets + * Bank : 0x0E + */ +#define AB5500_IT_SOURCE0_REG 0x20 +#define AB5500_IT_SOURCE1_REG 0x21 +#define AB5500_IT_SOURCE2_REG 0x22 +#define AB5500_IT_SOURCE3_REG 0x23 +#define AB5500_IT_SOURCE4_REG 0x24 +#define AB5500_IT_SOURCE5_REG 0x25 +#define AB5500_IT_SOURCE6_REG 0x26 +#define AB5500_IT_SOURCE7_REG 0x27 +#define AB5500_IT_SOURCE8_REG 0x28 +#define AB5500_IT_SOURCE9_REG 0x29 +#define AB5500_IT_SOURCE10_REG 0x2A +#define AB5500_IT_SOURCE11_REG 0x2B +#define AB5500_IT_SOURCE12_REG 0x2C +#define AB5500_IT_SOURCE13_REG 0x2D +#define AB5500_IT_SOURCE14_REG 0x2E +#define AB5500_IT_SOURCE15_REG 0x2F +#define AB5500_IT_SOURCE16_REG 0x30 +#define AB5500_IT_SOURCE17_REG 0x31 +#define AB5500_IT_SOURCE18_REG 0x32 +#define AB5500_IT_SOURCE19_REG 0x33 +#define AB5500_IT_SOURCE20_REG 0x34 +#define AB5500_IT_SOURCE21_REG 0x35 +#define AB5500_IT_SOURCE22_REG 0x36 +#define AB5500_IT_SOURCE23_REG 0x37 + +#define AB5500_NUM_IRQ_REGS 23 + +/** + * struct ab5500 + * @access_mutex: lock out concurrent accesses to the AB registers + * @dev: a pointer to the device struct for this chip driver + * @ab5500_irq: the analog baseband irq + * @irq_base: the platform configuration irq base for subdevices + * @chip_name: name of this chip variant + * @chip_id: 8 bit chip ID for this chip variant + * @irq_lock: a lock to protect the mask + * @abb_events: a local bit mask of the prcmu wakeup events + * @event_mask: a local copy of the mask event registers + * @last_event_mask: a copy of the last event_mask written to hardware + * @startup_events: a copy of the first reading of the event registers + * @startup_events_read: whether the first events have been read + */ +struct ab5500 { + struct mutex access_mutex; + struct device *dev; + unsigned int ab5500_irq; + unsigned int irq_base; + char chip_name[32]; + u8 chip_id; + struct mutex irq_lock; + u32 abb_events; + u8 mask[AB5500_NUM_IRQ_REGS]; + u8 oldmask[AB5500_NUM_IRQ_REGS]; + u8 startup_events[AB5500_NUM_IRQ_REGS]; + bool startup_events_read; +#ifdef CONFIG_DEBUG_FS + unsigned int debug_bank; + unsigned int debug_address; +#endif +}; + +struct ab5500_platform_data { + struct {unsigned int base; unsigned int count; } irq; + void *dev_data[AB5500_NUM_DEVICES]; + struct abx500_init_settings *init_settings; + unsigned int init_settings_sz; + bool pm_power_off; +}; + +#endif /* MFD_AB5500_H */ diff --git a/trunk/include/linux/mfd/db5500-prcmu.h b/trunk/include/linux/mfd/db5500-prcmu.h new file mode 100644 index 000000000000..9890687f582d --- /dev/null +++ b/trunk/include/linux/mfd/db5500-prcmu.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * + * U5500 PRCMU API. + */ +#ifndef __MFD_DB5500_PRCMU_H +#define __MFD_DB5500_PRCMU_H + +#ifdef CONFIG_MFD_DB5500_PRCMU + +void db5500_prcmu_early_init(void); +int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state); +int db5500_prcmu_set_display_clocks(void); +int db5500_prcmu_disable_dsipll(void); +int db5500_prcmu_enable_dsipll(void); +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); +void db5500_prcmu_enable_wakeups(u32 wakeups); +int db5500_prcmu_request_clock(u8 clock, bool enable); +void db5500_prcmu_config_abb_event_readout(u32 abb_events); +void db5500_prcmu_get_abb_event_buffer(void __iomem **buf); +int prcmu_resetout(u8 resoutn, u8 state); +int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll); +int db5500_prcmu_config_esram0_deep_sleep(u8 state); +void db5500_prcmu_system_reset(u16 reset_code); +u16 db5500_prcmu_get_reset_code(void); +bool db5500_prcmu_is_ac_wake_requested(void); +int db5500_prcmu_set_arm_opp(u8 opp); +int db5500_prcmu_get_arm_opp(void); + +#else /* !CONFIG_UX500_SOC_DB5500 */ + +static inline void db5500_prcmu_early_init(void) {} + +static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline int db5500_prcmu_request_clock(u8 clock, bool enable) +{ + return 0; +} + +static inline int db5500_prcmu_set_display_clocks(void) +{ + return 0; +} + +static inline int db5500_prcmu_disable_dsipll(void) +{ + return 0; +} + +static inline int db5500_prcmu_enable_dsipll(void) +{ + return 0; +} + +static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) +{ + return 0; +} + +static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} + +static inline int prcmu_resetout(u8 resoutn, u8 state) +{ + return 0; +} + +static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) +{ + return 0; +} + +static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {} +static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} + +static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll) +{ + return 0; +} + +static inline void db5500_prcmu_system_reset(u16 reset_code) {} + +static inline u16 db5500_prcmu_get_reset_code(void) +{ + return 0; +} + +static inline bool db5500_prcmu_is_ac_wake_requested(void) +{ + return 0; +} + +static inline int db5500_prcmu_set_arm_opp(u8 opp) +{ + return 0; +} + +static inline int db5500_prcmu_get_arm_opp(void) +{ + return 0; +} + + +#endif /* CONFIG_MFD_DB5500_PRCMU */ + +#endif /* __MFD_DB5500_PRCMU_H */ diff --git a/trunk/include/linux/mfd/dbx500-prcmu.h b/trunk/include/linux/mfd/dbx500-prcmu.h index 5a13f93d8f1c..d7674eb7305f 100644 --- a/trunk/include/linux/mfd/dbx500-prcmu.h +++ b/trunk/include/linux/mfd/dbx500-prcmu.h @@ -54,6 +54,17 @@ enum prcmu_wakeup_index { #define EPOD_ID_ESRAM34 7 #define NUM_EPOD_ID 8 +/* + * DB5500 EPODs + */ +#define DB5500_EPOD_ID_BASE 0x0100 +#define DB5500_EPOD_ID_SGA (DB5500_EPOD_ID_BASE + 0) +#define DB5500_EPOD_ID_HVA (DB5500_EPOD_ID_BASE + 1) +#define DB5500_EPOD_ID_SIA (DB5500_EPOD_ID_BASE + 2) +#define DB5500_EPOD_ID_DISP (DB5500_EPOD_ID_BASE + 3) +#define DB5500_EPOD_ID_ESRAM12 (DB5500_EPOD_ID_BASE + 6) +#define DB5500_NUM_EPOD_ID 7 + /* * state definition for EPOD (power domain) * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged @@ -69,6 +80,29 @@ enum prcmu_wakeup_index { #define EPOD_STATE_ON_CLK_OFF 0x03 #define EPOD_STATE_ON 0x04 +/* DB5500 CLKOUT IDs */ +enum { + DB5500_CLKOUT0 = 0, + DB5500_CLKOUT1, +}; + +/* DB5500 CLKOUTx sources */ +enum { + DB5500_CLKOUT_REF_CLK_SEL0, + DB5500_CLKOUT_RTC_CLK0_SEL0, + DB5500_CLKOUT_ULP_CLK_SEL0, + DB5500_CLKOUT_STATIC0, + DB5500_CLKOUT_REFCLK, + DB5500_CLKOUT_ULPCLK, + DB5500_CLKOUT_ARMCLK, + DB5500_CLKOUT_SYSACC0CLK, + DB5500_CLKOUT_SOC0PLLCLK, + DB5500_CLKOUT_SOC1PLLCLK, + DB5500_CLKOUT_DDRPLLCLK, + DB5500_CLKOUT_TVCLK, + DB5500_CLKOUT_IRDACLK, +}; + /* * CLKOUT sources */ @@ -214,66 +248,101 @@ enum ddr_pwrst { }; #include +#include -#if defined(CONFIG_UX500_SOC_DB8500) +#if defined(CONFIG_UX500_SOC_DB8500) || defined(CONFIG_UX500_SOC_DB5500) #include static inline void __init prcmu_early_init(void) { - return db8500_prcmu_early_init(); + if (cpu_is_u5500()) + return db5500_prcmu_early_init(); + else + return db8500_prcmu_early_init(); } static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) { - return db8500_prcmu_set_power_state(state, keep_ulp_clk, - keep_ap_pll); + if (cpu_is_u5500()) + return db5500_prcmu_set_power_state(state, keep_ulp_clk, + keep_ap_pll); + else + return db8500_prcmu_set_power_state(state, keep_ulp_clk, + keep_ap_pll); } static inline u8 prcmu_get_power_state_result(void) { - return db8500_prcmu_get_power_state_result(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_get_power_state_result(); } static inline int prcmu_gic_decouple(void) { - return db8500_prcmu_gic_decouple(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_gic_decouple(); } static inline int prcmu_gic_recouple(void) { - return db8500_prcmu_gic_recouple(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_gic_recouple(); } static inline bool prcmu_gic_pending_irq(void) { - return db8500_prcmu_gic_pending_irq(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_gic_pending_irq(); } static inline bool prcmu_is_cpu_in_wfi(int cpu) { - return db8500_prcmu_is_cpu_in_wfi(cpu); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_is_cpu_in_wfi(cpu); } static inline int prcmu_copy_gic_settings(void) { - return db8500_prcmu_copy_gic_settings(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_copy_gic_settings(); } static inline bool prcmu_pending_irq(void) { - return db8500_prcmu_pending_irq(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_pending_irq(); } static inline int prcmu_set_epod(u16 epod_id, u8 epod_state) { - return db8500_prcmu_set_epod(epod_id, epod_state); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_set_epod(epod_id, epod_state); } static inline void prcmu_enable_wakeups(u32 wakeups) { - db8500_prcmu_enable_wakeups(wakeups); + if (cpu_is_u5500()) + db5500_prcmu_enable_wakeups(wakeups); + else + db8500_prcmu_enable_wakeups(wakeups); } static inline void prcmu_disable_wakeups(void) @@ -283,12 +352,18 @@ static inline void prcmu_disable_wakeups(void) static inline void prcmu_config_abb_event_readout(u32 abb_events) { - db8500_prcmu_config_abb_event_readout(abb_events); + if (cpu_is_u5500()) + db5500_prcmu_config_abb_event_readout(abb_events); + else + db8500_prcmu_config_abb_event_readout(abb_events); } static inline void prcmu_get_abb_event_buffer(void __iomem **buf) { - db8500_prcmu_get_abb_event_buffer(buf); + if (cpu_is_u5500()) + db5500_prcmu_get_abb_event_buffer(buf); + else + db8500_prcmu_get_abb_event_buffer(buf); } int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); @@ -299,7 +374,10 @@ int prcmu_config_clkout(u8 clkout, u8 source, u8 div); static inline int prcmu_request_clock(u8 clock, bool enable) { - return db8500_prcmu_request_clock(clock, enable); + if (cpu_is_u5500()) + return db5500_prcmu_request_clock(clock, enable); + else + return db8500_prcmu_request_clock(clock, enable); } unsigned long prcmu_clock_rate(u8 clock); @@ -308,133 +386,211 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate); static inline int prcmu_set_ddr_opp(u8 opp) { - return db8500_prcmu_set_ddr_opp(opp); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_set_ddr_opp(opp); } static inline int prcmu_get_ddr_opp(void) { - return db8500_prcmu_get_ddr_opp(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_get_ddr_opp(); } static inline int prcmu_set_arm_opp(u8 opp) { - return db8500_prcmu_set_arm_opp(opp); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_set_arm_opp(opp); } static inline int prcmu_get_arm_opp(void) { - return db8500_prcmu_get_arm_opp(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_get_arm_opp(); } static inline int prcmu_set_ape_opp(u8 opp) { - return db8500_prcmu_set_ape_opp(opp); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_set_ape_opp(opp); } static inline int prcmu_get_ape_opp(void) { - return db8500_prcmu_get_ape_opp(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_get_ape_opp(); } static inline void prcmu_system_reset(u16 reset_code) { - return db8500_prcmu_system_reset(reset_code); + if (cpu_is_u5500()) + return db5500_prcmu_system_reset(reset_code); + else + return db8500_prcmu_system_reset(reset_code); } static inline u16 prcmu_get_reset_code(void) { - return db8500_prcmu_get_reset_code(); + if (cpu_is_u5500()) + return db5500_prcmu_get_reset_code(); + else + return db8500_prcmu_get_reset_code(); } void prcmu_ac_wake_req(void); void prcmu_ac_sleep_req(void); static inline void prcmu_modem_reset(void) { - return db8500_prcmu_modem_reset(); + if (cpu_is_u5500()) + return; + else + return db8500_prcmu_modem_reset(); } static inline bool prcmu_is_ac_wake_requested(void) { - return db8500_prcmu_is_ac_wake_requested(); + if (cpu_is_u5500()) + return db5500_prcmu_is_ac_wake_requested(); + else + return db8500_prcmu_is_ac_wake_requested(); } static inline int prcmu_set_display_clocks(void) { - return db8500_prcmu_set_display_clocks(); + if (cpu_is_u5500()) + return db5500_prcmu_set_display_clocks(); + else + return db8500_prcmu_set_display_clocks(); } static inline int prcmu_disable_dsipll(void) { - return db8500_prcmu_disable_dsipll(); + if (cpu_is_u5500()) + return db5500_prcmu_disable_dsipll(); + else + return db8500_prcmu_disable_dsipll(); } static inline int prcmu_enable_dsipll(void) { - return db8500_prcmu_enable_dsipll(); + if (cpu_is_u5500()) + return db5500_prcmu_enable_dsipll(); + else + return db8500_prcmu_enable_dsipll(); } static inline int prcmu_config_esram0_deep_sleep(u8 state) { - return db8500_prcmu_config_esram0_deep_sleep(state); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_config_esram0_deep_sleep(state); } static inline int prcmu_config_hotdog(u8 threshold) { - return db8500_prcmu_config_hotdog(threshold); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_config_hotdog(threshold); } static inline int prcmu_config_hotmon(u8 low, u8 high) { - return db8500_prcmu_config_hotmon(low, high); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_config_hotmon(low, high); } static inline int prcmu_start_temp_sense(u16 cycles32k) { - return db8500_prcmu_start_temp_sense(cycles32k); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_start_temp_sense(cycles32k); } static inline int prcmu_stop_temp_sense(void) { - return db8500_prcmu_stop_temp_sense(); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_stop_temp_sense(); } static inline u32 prcmu_read(unsigned int reg) { - return db8500_prcmu_read(reg); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_read(reg); } static inline void prcmu_write(unsigned int reg, u32 value) { - db8500_prcmu_write(reg, value); + if (cpu_is_u5500()) + return; + else + db8500_prcmu_write(reg, value); } static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) { - db8500_prcmu_write_masked(reg, mask, value); + if (cpu_is_u5500()) + return; + else + db8500_prcmu_write_masked(reg, mask, value); } static inline int prcmu_enable_a9wdog(u8 id) { - return db8500_prcmu_enable_a9wdog(id); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_enable_a9wdog(id); } static inline int prcmu_disable_a9wdog(u8 id) { - return db8500_prcmu_disable_a9wdog(id); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_disable_a9wdog(id); } static inline int prcmu_kick_a9wdog(u8 id) { - return db8500_prcmu_kick_a9wdog(id); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_kick_a9wdog(id); } static inline int prcmu_load_a9wdog(u8 id, u32 timeout) { - return db8500_prcmu_load_a9wdog(id, timeout); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_load_a9wdog(id, timeout); } static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off) { - return db8500_prcmu_config_a9wdog(num, sleep_auto_off); + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_config_a9wdog(num, sleep_auto_off); } #else @@ -612,7 +768,7 @@ static inline void prcmu_clear(unsigned int reg, u32 bits) prcmu_write_masked(reg, bits, 0); } -#if defined(CONFIG_UX500_SOC_DB8500) +#if defined(CONFIG_UX500_SOC_DB8500) || defined(CONFIG_UX500_SOC_DB5500) /** * prcmu_enable_spi2 - Enables pin muxing for SPI2 on OtherAlternateC1. diff --git a/trunk/include/linux/mfd/rc5t583.h b/trunk/include/linux/mfd/rc5t583.h index 0b64b19d81ab..a2c61609d21d 100644 --- a/trunk/include/linux/mfd/rc5t583.h +++ b/trunk/include/linux/mfd/rc5t583.h @@ -26,7 +26,6 @@ #include #include -#include #define RC5T583_MAX_REGS 0xF8 @@ -280,44 +279,14 @@ struct rc5t583_platform_data { bool enable_shutdown; }; -static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_write(rc5t583->regmap, reg, val); -} - -static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - unsigned int ival; - int ret; - ret = regmap_read(rc5t583->regmap, reg, &ival); - if (!ret) - *val = (uint8_t)ival; - return ret; -} - -static inline int rc5t583_set_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); -} - -static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); -} - -static inline int rc5t583_update(struct device *dev, unsigned int reg, - unsigned int val, unsigned int mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, mask, val); -} - +int rc5t583_write(struct device *dev, u8 reg, uint8_t val); +int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val); +int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask); +int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask); +int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask); int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id, int ext_pwr_req, int deepsleep_slot_nr); int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base); diff --git a/trunk/include/linux/mfd/twl6040.h b/trunk/include/linux/mfd/twl6040.h index b15b5f03f5c4..9bc9ac651dad 100644 --- a/trunk/include/linux/mfd/twl6040.h +++ b/trunk/include/linux/mfd/twl6040.h @@ -174,35 +174,8 @@ #define TWL6040_SYSCLK_SEL_LPPLL 0 #define TWL6040_SYSCLK_SEL_HPPLL 1 -struct twl6040_codec_data { - u16 hs_left_step; - u16 hs_right_step; - u16 hf_left_step; - u16 hf_right_step; -}; - -struct twl6040_vibra_data { - unsigned int vibldrv_res; /* left driver resistance */ - unsigned int vibrdrv_res; /* right driver resistance */ - unsigned int viblmotor_res; /* left motor resistance */ - unsigned int vibrmotor_res; /* right motor resistance */ - int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ - int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ -}; - -struct twl6040_platform_data { - int audpwron_gpio; /* audio power-on gpio */ - unsigned int irq_base; - - struct twl6040_codec_data *codec; - struct twl6040_vibra_data *vibra; -}; - -struct regmap; - struct twl6040 { struct device *dev; - struct regmap *regmap; struct mutex mutex; struct mutex io_mutex; struct mutex irq_mutex; diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 74aa71bea1e4..d8738a464b94 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -1393,20 +1393,29 @@ extern int install_special_mapping(struct mm_struct *mm, extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long pgoff); extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, vm_flags_t vm_flags, unsigned long pgoff); -extern unsigned long do_mmap(struct file *, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); + +static inline unsigned long do_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + unsigned long ret = -EINVAL; + if ((offset + PAGE_ALIGN(len)) < offset) + goto out; + if (!(offset & ~PAGE_MASK)) + ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +out: + return ret; +} + extern int do_munmap(struct mm_struct *, unsigned long, size_t); -/* These take the mm semaphore themselves */ -extern unsigned long vm_brk(unsigned long, unsigned long); -extern int vm_munmap(unsigned long, size_t); -extern unsigned long vm_mmap(struct file *, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); +extern unsigned long do_brk(unsigned long, unsigned long); /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/trunk/include/linux/mmc/card.h b/trunk/include/linux/mmc/card.h index 629b823f8836..01beae78f079 100644 --- a/trunk/include/linux/mmc/card.h +++ b/trunk/include/linux/mmc/card.h @@ -481,7 +481,7 @@ struct mmc_driver { struct device_driver drv; int (*probe)(struct mmc_card *); void (*remove)(struct mmc_card *); - int (*suspend)(struct mmc_card *); + int (*suspend)(struct mmc_card *, pm_message_t); int (*resume)(struct mmc_card *); }; diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 1bc898b14a80..f549adccc94c 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -287,17 +287,7 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb, struct xt_table *table); /* Check for an extension */ -static inline int -ip6t_ext_hdr(u8 nexthdr) -{ return (nexthdr == IPPROTO_HOPOPTS) || - (nexthdr == IPPROTO_ROUTING) || - (nexthdr == IPPROTO_FRAGMENT) || - (nexthdr == IPPROTO_ESP) || - (nexthdr == IPPROTO_AH) || - (nexthdr == IPPROTO_NONE) || - (nexthdr == IPPROTO_DSTOPTS); -} - +extern int ip6t_ext_hdr(u8 nexthdr); /* find specified header and get offset to it */ extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target, unsigned short *fragoff); diff --git a/trunk/include/linux/nfsd/Kbuild b/trunk/include/linux/nfsd/Kbuild index 5b7d84ac954a..b8d4001212b3 100644 --- a/trunk/include/linux/nfsd/Kbuild +++ b/trunk/include/linux/nfsd/Kbuild @@ -1,4 +1,3 @@ -header-y += cld.h header-y += debug.h header-y += export.h header-y += nfsfh.h diff --git a/trunk/include/linux/pinctrl/machine.h b/trunk/include/linux/pinctrl/machine.h index e4d1de742502..fee4349364f7 100644 --- a/trunk/include/linux/pinctrl/machine.h +++ b/trunk/include/linux/pinctrl/machine.h @@ -12,8 +12,6 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H -#include - #include "pinctrl-state.h" enum pinctrl_map_type { @@ -150,7 +148,7 @@ struct pinctrl_map { #define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \ PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs) -#ifdef CONFIG_PINCTRL +#ifdef CONFIG_PINMUX extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index 2db407a40051..f51bf2e70c69 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -357,7 +357,7 @@ struct uart_port { #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) -#define UPF_BUG_THRE ((__force upf_t) (1 << 26)) +#define UPF_IIR_ONCE ((__force upf_t) (1 << 26)) /* The exact UART type is known and should not be probed. */ #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 70a3f8d49118..33370271b8b2 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -481,7 +481,6 @@ struct sk_buff { union { __u32 mark; __u32 dropcount; - __u32 avail_size; }; sk_buff_data_t transport_header; @@ -1366,18 +1365,6 @@ static inline int skb_tailroom(const struct sk_buff *skb) return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail; } -/** - * skb_availroom - bytes at buffer end - * @skb: buffer to check - * - * Return the number of bytes of free space at the tail of an sk_buff - * allocated by sk_stream_alloc() - */ -static inline int skb_availroom(const struct sk_buff *skb) -{ - return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len; -} - /** * skb_reserve - adjust headroom * @skb: buffer to alter diff --git a/trunk/include/linux/stddef.h b/trunk/include/linux/stddef.h index 1747b6787b9e..6a40c76bdcf1 100644 --- a/trunk/include/linux/stddef.h +++ b/trunk/include/linux/stddef.h @@ -3,10 +3,14 @@ #include -#ifdef __KERNEL__ - #undef NULL +#if defined(__cplusplus) +#define NULL 0 +#else #define NULL ((void *)0) +#endif + +#ifdef __KERNEL__ enum { false = 0, diff --git a/trunk/include/linux/types.h b/trunk/include/linux/types.h index 7f480db60231..e5fa50345516 100644 --- a/trunk/include/linux/types.h +++ b/trunk/include/linux/types.h @@ -210,12 +210,6 @@ typedef u32 phys_addr_t; typedef phys_addr_t resource_size_t; -/* - * This type is the placeholder for a hardware interrupt number. It has to be - * big enough to enclose whatever representation is used by a given platform. - */ -typedef unsigned long irq_hw_number_t; - typedef struct { int counter; } atomic_t; diff --git a/trunk/include/linux/usb/otg.h b/trunk/include/linux/usb/otg.h index 38ab3f46346f..f67810f8f21b 100644 --- a/trunk/include/linux/usb/otg.h +++ b/trunk/include/linux/usb/otg.h @@ -94,7 +94,6 @@ struct usb_phy { struct usb_otg *otg; - struct device *io_dev; struct usb_phy_io_ops *io_ops; void __iomem *io_priv; diff --git a/trunk/include/linux/usb/serial.h b/trunk/include/linux/usb/serial.h index 474283888233..fbb666b1b670 100644 --- a/trunk/include/linux/usb/serial.h +++ b/trunk/include/linux/usb/serial.h @@ -28,6 +28,13 @@ /* parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) +enum port_dev_state { + PORT_UNREGISTERED, + PORT_REGISTERING, + PORT_REGISTERED, + PORT_UNREGISTERING, +}; + /* USB serial flags */ #define USB_SERIAL_WRITE_BUSY 0 @@ -117,6 +124,7 @@ struct usb_serial_port { char throttle_req; unsigned long sysrq; /* sysrq timeout */ struct device dev; + enum port_dev_state dev_state; }; #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) diff --git a/trunk/include/linux/vgaarb.h b/trunk/include/linux/vgaarb.h index b572f80bdfd5..9c3120dca294 100644 --- a/trunk/include/linux/vgaarb.h +++ b/trunk/include/linux/vgaarb.h @@ -47,8 +47,6 @@ */ #define VGA_DEFAULT_DEVICE (NULL) -struct pci_dev; - /* For use by clients */ /** diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index d47e523c9d83..344b0f972828 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -92,7 +92,6 @@ enum { HCI_SERVICE_CACHE, HCI_LINK_KEYS, HCI_DEBUG_KEYS, - HCI_UNREGISTER, HCI_LE_SCAN, HCI_SSP_ENABLED, @@ -1328,8 +1327,8 @@ struct sockaddr_hci { #define HCI_DEV_NONE 0xffff #define HCI_CHANNEL_RAW 0 +#define HCI_CHANNEL_CONTROL 1 #define HCI_CHANNEL_MONITOR 2 -#define HCI_CHANNEL_CONTROL 3 struct hci_filter { unsigned long type_mask; diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index 6822d2595aff..daefaac51131 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -427,7 +427,7 @@ enum { static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - return (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && + return (test_bit(HCI_SSP_ENABLED, &hdev->flags) && test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)); } @@ -907,13 +907,11 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) { - size_t parsed = 0; + u8 field_len; + size_t parsed; - if (data_len < 2) - return false; - - while (parsed < data_len - 1) { - u8 field_len = data[0]; + for (parsed = 0; parsed < data_len - 1; parsed += field_len) { + field_len = data[0]; if (field_len == 0) break; diff --git a/trunk/include/net/bluetooth/mgmt.h b/trunk/include/net/bluetooth/mgmt.h index ebfd91fc20f8..ffc1377e092e 100644 --- a/trunk/include/net/bluetooth/mgmt.h +++ b/trunk/include/net/bluetooth/mgmt.h @@ -117,7 +117,7 @@ struct mgmt_mode { #define MGMT_OP_SET_DISCOVERABLE 0x0006 struct mgmt_cp_set_discoverable { __u8 val; - __le16 timeout; + __u16 timeout; } __packed; #define MGMT_SET_DISCOVERABLE_SIZE 3 diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 9210bdc7bd8d..87d203ff7a8a 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -1327,7 +1327,7 @@ static inline struct ieee80211_rate * ieee80211_get_tx_rate(const struct ieee80211_hw *hw, const struct ieee80211_tx_info *c) { - if (WARN_ON_ONCE(c->control.rates[0].idx < 0)) + if (WARN_ON(c->control.rates[0].idx < 0)) return NULL; return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[0].idx]; } diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index 1e1198546c72..377df4a28512 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -134,9 +134,6 @@ struct scsi_cmnd { static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) { - if (!cmd->request->rq_disk) - return NULL; - return *(struct scsi_driver **)cmd->request->rq_disk->private_data; } diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index bc056687f647..b6e0f57d451d 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -325,13 +325,6 @@ void release_and_free_resource(struct resource *res); /* --- */ -/* sound printk debug levels */ -enum { - SND_PR_ALWAYS, - SND_PR_DEBUG, - SND_PR_VERBOSE, -}; - #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK) __printf(4, 5) void __snd_printk(unsigned int level, const char *file, int line, @@ -361,8 +354,6 @@ void __snd_printk(unsigned int level, const char *file, int line, */ #define snd_printd(fmt, args...) \ __snd_printk(1, __FILE__, __LINE__, fmt, ##args) -#define _snd_printd(level, fmt, args...) \ - __snd_printk(level, __FILE__, __LINE__, fmt, ##args) /** * snd_BUG - give a BUG warning message and stack trace @@ -392,7 +383,6 @@ void __snd_printk(unsigned int level, const char *file, int line, #else /* !CONFIG_SND_DEBUG */ #define snd_printd(fmt, args...) do { } while (0) -#define _snd_printd(level, fmt, args...) do { } while (0) #define snd_BUG() do { } while (0) static inline int __snd_bug_on(int cond) { diff --git a/trunk/kernel/cred.c b/trunk/kernel/cred.c index e70683d9ec32..97b36eeca4c9 100644 --- a/trunk/kernel/cred.c +++ b/trunk/kernel/cred.c @@ -386,8 +386,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) struct cred *new; int ret; - p->replacement_session_keyring = NULL; - if ( #ifdef CONFIG_KEYS !p->cred->thread_keyring && diff --git a/trunk/kernel/irq/Kconfig b/trunk/kernel/irq/Kconfig index d1a758bc972a..cf1a4a68ce44 100644 --- a/trunk/kernel/irq/Kconfig +++ b/trunk/kernel/irq/Kconfig @@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG help This option will show the mapping relationship between hardware irq numbers and Linux irq numbers. The mapping is exposed via debugfs - in the file "irq_domain_mapping". + in the file "virq_mapping". If you don't know what this means you don't need it. diff --git a/trunk/kernel/irq/irqdomain.c b/trunk/kernel/irq/irqdomain.c index 0e0ba5f840b2..3601f3fbf67c 100644 --- a/trunk/kernel/irq/irqdomain.c +++ b/trunk/kernel/irq/irqdomain.c @@ -23,6 +23,7 @@ static LIST_HEAD(irq_domain_list); static DEFINE_MUTEX(irq_domain_mutex); static DEFINE_MUTEX(revmap_trees_mutex); +static unsigned int irq_virq_count = NR_IRQS; static struct irq_domain *irq_default_domain; /** @@ -183,16 +184,13 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, } struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, - unsigned int max_irq, const struct irq_domain_ops *ops, void *host_data) { struct irq_domain *domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_NOMAP, ops, host_data); - if (domain) { - domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0; + if (domain) irq_domain_add(domain); - } return domain; } @@ -264,6 +262,22 @@ void irq_set_default_host(struct irq_domain *domain) irq_default_domain = domain; } +/** + * irq_set_virq_count() - Set the maximum number of linux irqs + * @count: number of linux irqs, capped with NR_IRQS + * + * This is mainly for use by platforms like iSeries who want to program + * the virtual irq number in the controller to avoid the reverse mapping + */ +void irq_set_virq_count(unsigned int count) +{ + pr_debug("irq: Trying to set virq count to %d\n", count); + + BUG_ON(count < NUM_ISA_INTERRUPTS); + if (count < NR_IRQS) + irq_virq_count = count; +} + static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq) { @@ -306,12 +320,13 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) pr_debug("irq: create_direct virq allocation failed\n"); return 0; } - if (virq >= domain->revmap_data.nomap.max_irq) { + if (virq >= irq_virq_count) { pr_err("ERROR: no free irqs available below %i maximum\n", - domain->revmap_data.nomap.max_irq); + irq_virq_count); irq_free_desc(virq); return 0; } + pr_debug("irq: create_direct obtained virq %d\n", virq); if (irq_setup_virq(domain, virq, virq)) { @@ -335,8 +350,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) unsigned int irq_create_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) { - unsigned int hint; - int virq; + unsigned int virq, hint; pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); @@ -363,13 +377,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain, return irq_domain_legacy_revmap(domain, hwirq); /* Allocate a virtual interrupt number */ - hint = hwirq % nr_irqs; + hint = hwirq % irq_virq_count; if (hint == 0) hint++; virq = irq_alloc_desc_from(hint, 0); - if (virq <= 0) + if (!virq) virq = irq_alloc_desc_from(1, 0); - if (virq <= 0) { + if (!virq) { pr_debug("irq: -> virq allocation failed\n"); return 0; } @@ -501,7 +515,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) { unsigned int i; - unsigned int hint = hwirq % nr_irqs; + unsigned int hint = hwirq % irq_virq_count; /* Look for default domain if nececssary */ if (domain == NULL) @@ -522,7 +536,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, if (data && (data->domain == domain) && (data->hwirq == hwirq)) return i; i++; - if (i >= nr_irqs) + if (i >= irq_virq_count) i = 1; } while(i != hint); return 0; @@ -628,9 +642,8 @@ static int virq_debug_show(struct seq_file *m, void *private) void *data; int i; - seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq", - "chip name", (int)(2 * sizeof(void *) + 2), "chip data", - "domain name"); + seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", + "chip name", "chip data", "domain name"); for (i = 1; i < nr_irqs; i++) { desc = irq_to_desc(i); @@ -653,7 +666,7 @@ static int virq_debug_show(struct seq_file *m, void *private) seq_printf(m, "%-15s ", p); data = irq_desc_get_chip_data(desc); - seq_printf(m, data ? "0x%p " : " %p ", data); + seq_printf(m, "0x%16p ", data); if (desc->irq_data.domain && desc->irq_data.domain->of_node) p = desc->irq_data.domain->of_node->full_name; diff --git a/trunk/kernel/irq_work.c b/trunk/kernel/irq_work.c index 1588e3b2871b..0c56d44b9fd5 100644 --- a/trunk/kernel/irq_work.c +++ b/trunk/kernel/irq_work.c @@ -11,7 +11,6 @@ #include #include #include -#include #include /* diff --git a/trunk/kernel/itimer.c b/trunk/kernel/itimer.c index 8d262b467573..22000c3db0dd 100644 --- a/trunk/kernel/itimer.c +++ b/trunk/kernel/itimer.c @@ -284,12 +284,8 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, if (value) { if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) return -EFAULT; - } else { - memset(&set_buffer, 0, sizeof(set_buffer)); - printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer." - " Misfeature support will be removed\n", - current->comm); - } + } else + memset((char *) &set_buffer, 0, sizeof(set_buffer)); error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); if (error || !ovalue) diff --git a/trunk/kernel/panic.c b/trunk/kernel/panic.c index 8ed89a175d79..80aed44e345a 100644 --- a/trunk/kernel/panic.c +++ b/trunk/kernel/panic.c @@ -97,7 +97,7 @@ void panic(const char *fmt, ...) /* * Avoid nested stack-dumping if a panic occurs during oops processing */ - if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) + if (!oops_in_progress) dump_stack(); #endif diff --git a/trunk/kernel/time/Kconfig b/trunk/kernel/time/Kconfig index a20dc8a3c949..2cf9cc7aa103 100644 --- a/trunk/kernel/time/Kconfig +++ b/trunk/kernel/time/Kconfig @@ -1,10 +1,6 @@ # # Timer subsystem related configuration options # - -# Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is -# only related to the tick functionality. Oneshot clockevent devices -# are supported independ of this. config TICK_ONESHOT bool diff --git a/trunk/kernel/time/tick-broadcast.c b/trunk/kernel/time/tick-broadcast.c index bf57abdc7bd0..e883f57a3cd3 100644 --- a/trunk/kernel/time/tick-broadcast.c +++ b/trunk/kernel/time/tick-broadcast.c @@ -575,12 +575,10 @@ void tick_broadcast_switch_to_oneshot(void) unsigned long flags; raw_spin_lock_irqsave(&tick_broadcast_lock, flags); - - tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; - if (cpumask_empty(tick_get_broadcast_mask())) goto end; + tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; bc = tick_broadcast_device.evtdev; if (bc) tick_broadcast_setup_oneshot(bc); diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index 6a3a5b9ff561..3526038f2836 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -534,9 +534,9 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) hrtimer_get_expires(&ts->sched_timer), 0)) break; } - /* Reread time and update jiffies */ - now = ktime_get(); + /* Update jiffies and reread time */ tick_do_update_jiffies64(now); + now = ktime_get(); } } diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index aeefa8bc8b1c..21dee7c19afd 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -192,14 +192,14 @@ static int kobject_add_internal(struct kobject *kobj) /* be noisy on error issues */ if (error == -EEXIST) - WARN(1, "%s failed for %s with " - "-EEXIST, don't try to register things with " - "the same name in the same directory.\n", - __func__, kobject_name(kobj)); + printk(KERN_ERR "%s failed for %s with " + "-EEXIST, don't try to register things with " + "the same name in the same directory.\n", + __func__, kobject_name(kobj)); else - WARN(1, "%s failed for %s (error: %d parent: %s)\n", - __func__, kobject_name(kobj), error, - parent ? kobject_name(parent) : "'none'"); + printk(KERN_ERR "%s failed for %s (%d)\n", + __func__, kobject_name(kobj), error); + dump_stack(); } else kobj->state_in_sysfs = 1; diff --git a/trunk/lib/mpi/mpi-bit.c b/trunk/lib/mpi/mpi-bit.c index 0c505361da19..2f526627e4f5 100644 --- a/trunk/lib/mpi/mpi-bit.c +++ b/trunk/lib/mpi/mpi-bit.c @@ -177,8 +177,8 @@ int mpi_rshift(MPI x, MPI a, unsigned n) */ int mpi_lshift_limbs(MPI a, unsigned int count) { - const int n = a->nlimbs; - mpi_ptr_t ap; + mpi_ptr_t ap = a->d; + int n = a->nlimbs; int i; if (!count || !n) @@ -187,7 +187,6 @@ int mpi_lshift_limbs(MPI a, unsigned int count) if (RESIZE_IF_NEEDED(a, n + count) < 0) return -ENOMEM; - ap = a->d; for (i = n - 1; i >= 0; i--) ap[i + count] = ap[i]; for (i = 0; i < count; i++) diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index cd65cb19c941..b8ce6f450956 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -2791,7 +2791,6 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, * so no worry about deadlock. */ page = pte_page(entry); - get_page(page); if (page != pagecache_page) lock_page(page); @@ -2823,7 +2822,6 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, } if (page != pagecache_page) unlock_page(page); - put_page(page); out_mutex: mutex_unlock(&hugetlb_instantiation_mutex); diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index a44eab3157f8..99f285599501 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -330,9 +330,6 @@ static int __init_memblock memblock_add_region(struct memblock_type *type, phys_addr_t end = base + memblock_cap_size(base, &size); int i, nr_new; - if (!size) - return 0; - /* special case for empty array */ if (type->regions[0].size == 0) { WARN_ON(type->cnt != 1 || type->total_size); @@ -433,9 +430,6 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, *start_rgn = *end_rgn = 0; - if (!size) - return 0; - /* we'll create at most two more regions */ while (type->cnt + 2 > type->max) if (memblock_double_array(type) < 0) @@ -520,6 +514,7 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) (unsigned long long)base, (unsigned long long)base + size, (void *)_RET_IP_); + BUG_ON(0 == size); return memblock_add_region(_rgn, base, size, MAX_NUMNODES); } diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index b868def9bcc1..7d698df4a067 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -2165,7 +2165,7 @@ static int __cpuinit memcg_cpu_hotplug_callback(struct notifier_block *nb, if (action == CPU_ONLINE) return NOTIFY_OK; - if (action != CPU_DEAD && action != CPU_DEAD_FROZEN) + if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN) return NOTIFY_OK; for_each_mem_cgroup(iter) @@ -3392,7 +3392,6 @@ void mem_cgroup_replace_page_cache(struct page *oldpage, * the newpage may be on LRU(or pagevec for LRU) already. We lock * LRU while we overwrite pc->mem_cgroup. */ - pc = lookup_page_cgroup(newpage); __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true); } @@ -3764,7 +3763,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg, bool free_all) goto try_to_free; cond_resched(); /* "ret" should also be checked to ensure all lists are empty. */ - } while (res_counter_read_u64(&memcg->res, RES_USAGE) > 0 || ret); + } while (memcg->res.usage > 0 || ret); out: css_put(&memcg->css); return ret; @@ -3779,7 +3778,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg, bool free_all) lru_add_drain_all(); /* try to free all pages in this cgroup */ shrink = 1; - while (nr_retries && res_counter_read_u64(&memcg->res, RES_USAGE) > 0) { + while (nr_retries && memcg->res.usage > 0) { int progress; if (signal_pending(current)) { diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 848ef52d9603..a7bf6a31c9f6 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -240,8 +240,6 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) return next; } -static unsigned long do_brk(unsigned long addr, unsigned long len); - SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; @@ -953,7 +951,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) * The caller must hold down_write(¤t->mm->mmap_sem). */ -static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long pgoff) { @@ -1089,32 +1087,7 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, return mmap_region(file, addr, len, flags, vm_flags, pgoff); } - -unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - if (unlikely(offset + PAGE_ALIGN(len) < offset)) - return -EINVAL; - if (unlikely(offset & ~PAGE_MASK)) - return -EINVAL; - return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -} -EXPORT_SYMBOL(do_mmap); - -unsigned long vm_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret; - struct mm_struct *mm = current->mm; - - down_write(&mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flag, offset); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_mmap); +EXPORT_SYMBOL(do_mmap_pgoff); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, @@ -2132,25 +2105,21 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) return 0; } + EXPORT_SYMBOL(do_munmap); -int vm_munmap(unsigned long start, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; + profile_munmap(addr); + down_write(&mm->mmap_sem); - ret = do_munmap(mm, start, len); + ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL(vm_munmap); - -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) -{ - profile_munmap(addr); - return vm_munmap(addr, len); -} static inline void verify_mm_writelocked(struct mm_struct *mm) { @@ -2167,7 +2136,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm) * anonymous maps. eventually we may be able to do some * brk-specific accounting here. */ -static unsigned long do_brk(unsigned long addr, unsigned long len) +unsigned long do_brk(unsigned long addr, unsigned long len) { struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; @@ -2263,17 +2232,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) return addr; } -unsigned long vm_brk(unsigned long addr, unsigned long len) -{ - struct mm_struct *mm = current->mm; - unsigned long ret; - - down_write(&mm->mmap_sem); - ret = do_brk(addr, len); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_brk); +EXPORT_SYMBOL(do_brk); /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index bb8f4f004a82..f59e170fceb4 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -1233,7 +1233,7 @@ static int do_mmap_private(struct vm_area_struct *vma, /* * handle mapping creation for uClinux */ -static unsigned long do_mmap_pgoff(struct file *file, +unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -1470,32 +1470,7 @@ static unsigned long do_mmap_pgoff(struct file *file, show_free_areas(0); return -ENOMEM; } - -unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - if (unlikely(offset + PAGE_ALIGN(len) < offset)) - return -EINVAL; - if (unlikely(offset & ~PAGE_MASK)) - return -EINVAL; - return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -} -EXPORT_SYMBOL(do_mmap); - -unsigned long vm_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret; - struct mm_struct *mm = current->mm; - - down_write(&mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flag, offset); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_mmap); +EXPORT_SYMBOL(do_mmap_pgoff); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, @@ -1734,22 +1709,16 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) } EXPORT_SYMBOL(do_munmap); -int vm_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { - struct mm_struct *mm = current->mm; int ret; + struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL(vm_munmap); - -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) -{ - return vm_munmap(addr, len); -} /* * release all the mappings made in a process's VM space @@ -1775,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm) kleave(""); } -unsigned long vm_brk(unsigned long addr, unsigned long len) +unsigned long do_brk(unsigned long addr, unsigned long len) { return -ENOMEM; } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 1a518684a32f..33c332bbab73 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -2107,7 +2107,12 @@ static void shrink_mem_cgroup_zone(int priority, struct mem_cgroup_zone *mz, * with multiple processes reclaiming pages, the total * freeing target can get unreasonably large. */ - if (nr_reclaimed >= nr_to_reclaim && priority < DEF_PRIORITY) + if (nr_reclaimed >= nr_to_reclaim) + nr_to_reclaim = 0; + else + nr_to_reclaim -= nr_reclaimed; + + if (!nr_to_reclaim && priority < DEF_PRIORITY) break; } blk_finish_plug(&plug); diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 92a857e3786d..e33af63a884a 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -665,11 +665,6 @@ int hci_dev_open(__u16 dev) hci_req_lock(hdev); - if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { - ret = -ENODEV; - goto done; - } - if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { ret = -ERFKILL; goto done; @@ -1854,8 +1849,6 @@ void hci_unregister_dev(struct hci_dev *hdev) BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); - set_bit(HCI_UNREGISTER, &hdev->dev_flags); - write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 94552b33d528..b8e17e4dac8b 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -1308,7 +1308,6 @@ static void l2cap_monitor_timeout(struct work_struct *work) if (chan->retry_count >= chan->remote_max_tx) { l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); l2cap_chan_unlock(chan); - l2cap_chan_put(chan); return; } @@ -1317,7 +1316,6 @@ static void l2cap_monitor_timeout(struct work_struct *work) l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); l2cap_chan_unlock(chan); - l2cap_chan_put(chan); } static void l2cap_retrans_timeout(struct work_struct *work) @@ -1337,7 +1335,6 @@ static void l2cap_retrans_timeout(struct work_struct *work) l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); l2cap_chan_unlock(chan); - l2cap_chan_put(chan); } static void l2cap_drop_acked_frames(struct l2cap_chan *chan) diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index 29122ed28ea9..c4fe583b0af6 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -82,7 +82,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) } if (la.l2_cid) - err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid)); + err = l2cap_add_scid(chan, la.l2_cid); else err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm); @@ -123,8 +123,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al if (la.l2_cid && la.l2_psm) return -EINVAL; - err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), - &la.l2_bdaddr); + err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr); if (err) return err; diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index 4ef275c69675..7fcff8887131 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -2523,18 +2523,13 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, if (cp->val) { type = PAGE_SCAN_TYPE_INTERLACED; - - /* 22.5 msec page scan interval */ - acp.interval = __constant_cpu_to_le16(0x0024); + acp.interval = 0x0024; /* 22.5 msec page scan interval */ } else { type = PAGE_SCAN_TYPE_STANDARD; /* default */ - - /* default 1.28 sec page scan */ - acp.interval = __constant_cpu_to_le16(0x0800); + acp.interval = 0x0800; /* default 1.28 sec page scan */ } - /* default 11.25 msec page scan window */ - acp.window = __constant_cpu_to_le16(0x0012); + acp.window = 0x0012; /* default 11.25 msec page scan window */ err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, sizeof(acp), &acp); @@ -2941,7 +2936,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, name, name_len); if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0) - eir_len = eir_append_data(ev->eir, eir_len, + eir_len = eir_append_data(&ev->eir[eir_len], eir_len, EIR_CLASS_OF_DEV, dev_class, 3); put_unaligned_le16(eir_len, &ev->eir_len); diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index 27ca25ed7021..702a1ae9220b 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -241,6 +241,7 @@ static void br_multicast_group_expired(unsigned long data) hlist_del_rcu(&mp->hlist[mdb->ver]); mdb->size--; + del_timer(&mp->query_timer); call_rcu_bh(&mp->rcu, br_multicast_free_group); out: @@ -270,6 +271,7 @@ static void br_multicast_del_pg(struct net_bridge *br, rcu_assign_pointer(*pp, p->next); hlist_del_init(&p->mglist); del_timer(&p->timer); + del_timer(&p->query_timer); call_rcu_bh(&p->rcu, br_multicast_free_pg); if (!mp->ports && !mp->mglist && @@ -505,6 +507,74 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, return NULL; } +static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp) +{ + struct net_bridge *br = mp->br; + struct sk_buff *skb; + + skb = br_multicast_alloc_query(br, &mp->addr); + if (!skb) + goto timer; + + netif_rx(skb); + +timer: + if (++mp->queries_sent < br->multicast_last_member_count) + mod_timer(&mp->query_timer, + jiffies + br->multicast_last_member_interval); +} + +static void br_multicast_group_query_expired(unsigned long data) +{ + struct net_bridge_mdb_entry *mp = (void *)data; + struct net_bridge *br = mp->br; + + spin_lock(&br->multicast_lock); + if (!netif_running(br->dev) || !mp->mglist || + mp->queries_sent >= br->multicast_last_member_count) + goto out; + + br_multicast_send_group_query(mp); + +out: + spin_unlock(&br->multicast_lock); +} + +static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg) +{ + struct net_bridge_port *port = pg->port; + struct net_bridge *br = port->br; + struct sk_buff *skb; + + skb = br_multicast_alloc_query(br, &pg->addr); + if (!skb) + goto timer; + + br_deliver(port, skb); + +timer: + if (++pg->queries_sent < br->multicast_last_member_count) + mod_timer(&pg->query_timer, + jiffies + br->multicast_last_member_interval); +} + +static void br_multicast_port_group_query_expired(unsigned long data) +{ + struct net_bridge_port_group *pg = (void *)data; + struct net_bridge_port *port = pg->port; + struct net_bridge *br = port->br; + + spin_lock(&br->multicast_lock); + if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) || + pg->queries_sent >= br->multicast_last_member_count) + goto out; + + br_multicast_send_port_group_query(pg); + +out: + spin_unlock(&br->multicast_lock); +} + static struct net_bridge_mdb_entry *br_multicast_get_group( struct net_bridge *br, struct net_bridge_port *port, struct br_ip *group, int hash) @@ -620,6 +690,8 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( mp->addr = *group; setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp); + setup_timer(&mp->query_timer, br_multicast_group_query_expired, + (unsigned long)mp); hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]); mdb->size++; @@ -674,6 +746,8 @@ static int br_multicast_add_group(struct net_bridge *br, hlist_add_head(&p->mglist, &port->mglist); setup_timer(&p->timer, br_multicast_port_group_expired, (unsigned long)p); + setup_timer(&p->query_timer, br_multicast_port_group_query_expired, + (unsigned long)p); rcu_assign_pointer(*pp, p); @@ -1217,6 +1291,9 @@ static void br_multicast_leave_group(struct net_bridge *br, time_after(mp->timer.expires, time) : try_to_del_timer_sync(&mp->timer) >= 0)) { mod_timer(&mp->timer, time); + + mp->queries_sent = 0; + mod_timer(&mp->query_timer, now); } goto out; @@ -1233,6 +1310,9 @@ static void br_multicast_leave_group(struct net_bridge *br, time_after(p->timer.expires, time) : try_to_del_timer_sync(&p->timer) >= 0)) { mod_timer(&p->timer, time); + + p->queries_sent = 0; + mod_timer(&p->query_timer, now); } break; @@ -1601,6 +1681,7 @@ void br_multicast_stop(struct net_bridge *br) hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i], hlist[ver]) { del_timer(&mp->timer); + del_timer(&mp->query_timer); call_rcu_bh(&mp->rcu, br_multicast_free_group); } } diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index e1d882257877..0b67a63ad7a8 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -82,7 +82,9 @@ struct net_bridge_port_group { struct hlist_node mglist; struct rcu_head rcu; struct timer_list timer; + struct timer_list query_timer; struct br_ip addr; + u32 queries_sent; }; struct net_bridge_mdb_entry @@ -92,8 +94,10 @@ struct net_bridge_mdb_entry struct net_bridge_port_group __rcu *ports; struct rcu_head rcu; struct timer_list timer; + struct timer_list query_timer; struct br_ip addr; bool mglist; + u32 queries_sent; }; struct net_bridge_mdb_htable diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index e59840010d45..baf8d281152c 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -952,11 +952,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, goto adjust_others; } - data = kmalloc(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), - gfp_mask); + data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); if (!data) goto nodata; - size = SKB_WITH_OVERHEAD(ksize(data)); /* Copy only real data... and, alas, header. This should be * optimized for the cases when header is void. diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index cf73cc70ed2d..de9da21113a1 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -74,24 +74,16 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); if (iph == NULL) - return -NF_ACCEPT; + return -NF_DROP; /* Conntrack defragments packets, we might still see fragments * inside ICMP packets though. */ if (iph->frag_off & htons(IP_OFFSET)) - return -NF_ACCEPT; + return -NF_DROP; *dataoff = nhoff + (iph->ihl << 2); *protonum = iph->protocol; - /* Check bogus IP headers */ - if (*dataoff > skb->len) { - pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: " - "nhoff %u, ihl %u, skblen %u\n", - nhoff, iph->ihl << 2, skb->len); - return -NF_ACCEPT; - } - return NF_ACCEPT; } diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 8bb6adeb62c0..5d54ed30e821 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -701,12 +701,11 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp) skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp); if (skb) { if (sk_wmem_schedule(sk, skb->truesize)) { - skb_reserve(skb, sk->sk_prot->max_header); /* * Make sure that we have exactly size bytes * available to the caller, no more, no less. */ - skb->avail_size = size; + skb_reserve(skb, skb_tailroom(skb) - size); return skb; } __kfree_skb(skb); @@ -996,9 +995,10 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, copy = seglen; /* Where to copy to? */ - if (skb_availroom(skb) > 0) { + if (skb_tailroom(skb) > 0) { /* We have some space in skb head. Superb! */ - copy = min_t(int, copy, skb_availroom(skb)); + if (copy > skb_tailroom(skb)) + copy = skb_tailroom(skb); err = skb_add_data_nocache(sk, skb, from, copy); if (err) goto do_fault; @@ -1452,7 +1452,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if ((available < target) && (len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) && !sysctl_tcp_low_latency && - net_dma_find_channel()) { + dma_find_channel(DMA_MEMCPY)) { preempt_enable_no_resched(); tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len); @@ -1667,7 +1667,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (!(flags & MSG_TRUNC)) { #ifdef CONFIG_NET_DMA if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan) { tp->ucopy.dma_cookie = dma_skb_copy_datagram_iovec( @@ -3302,7 +3302,8 @@ void __init tcp_init(void) tcp_init_mem(&init_net); /* Set per-socket limits to no more than 1/128 the pressure threshold */ - limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7); + limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10); + limit = max(limit, 128UL); max_share = min(4UL*1024*1024, limit); sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 9944c1d9a218..e886e2f7fa8d 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -474,11 +474,8 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) if (!win_dep) { m -= (new_sample >> 3); new_sample += m; - } else { - m <<= 3; - if (m < new_sample) - new_sample = m; - } + } else if (m < new_sample) + new_sample = m << 3; } else { /* No previous measure. */ new_sample = m << 3; @@ -5228,7 +5225,7 @@ static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, return 0; if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) { diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 0cb86ceb652f..3a25cf743f8b 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -1730,7 +1730,7 @@ int tcp_v4_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_DMA struct tcp_sock *tp = tcp_sk(sk); if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan) ret = tcp_v4_do_rcv(sk, skb); else diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 376b2cfbb685..364784a91939 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -2060,7 +2060,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, /* Punt if not enough space exists in the first SKB for * the data in the second */ - if (skb->len > skb_availroom(to)) + if (skb->len > skb_tailroom(to)) break; if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp))) diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 9d4e15559319..94874b0bdcdc 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -78,6 +78,19 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table); Hence the start of any table is given by get_table() below. */ +/* Check for an extension */ +int +ip6t_ext_hdr(u8 nexthdr) +{ + return (nexthdr == IPPROTO_HOPOPTS) || + (nexthdr == IPPROTO_ROUTING) || + (nexthdr == IPPROTO_FRAGMENT) || + (nexthdr == IPPROTO_ESP) || + (nexthdr == IPPROTO_AH) || + (nexthdr == IPPROTO_NONE) || + (nexthdr == IPPROTO_DSTOPTS); +} + /* Returns whether matches rule or not. */ /* Performance critical - called for every packet */ static inline bool @@ -2353,6 +2366,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, EXPORT_SYMBOL(ip6t_register_table); EXPORT_SYMBOL(ip6t_unregister_table); EXPORT_SYMBOL(ip6t_do_table); +EXPORT_SYMBOL(ip6t_ext_hdr); EXPORT_SYMBOL(ipv6_find_hdr); module_init(ip6_tables_init); diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 86cfe6005f40..12c6ece67f39 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -1645,7 +1645,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_DMA struct tcp_sock *tp = tcp_sk(sk); if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan) ret = tcp_v6_do_rcv(sk, skb); else diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index f76da5b3f5c5..576fb25456dd 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -3387,7 +3387,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, */ printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", sdata->name, ifmgd->bssid); - assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); + assoc_data->timeout = jiffies + + TU_TO_EXP_TIME(req->bss->beacon_interval); } else { assoc_data->have_beacon = true; assoc_data->sent_assoc = false; diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index 729f157a0efa..3cc4487ac349 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -1592,7 +1592,7 @@ static int nf_conntrack_init_net(struct net *net) return 0; err_timeout: - nf_conntrack_ecache_fini(net); + nf_conntrack_timeout_fini(net); err_ecache: nf_conntrack_tstamp_fini(net); err_tstamp: diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 0d07a1dcf605..361eade62a09 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -584,8 +584,8 @@ static bool tcp_in_window(const struct nf_conn *ct, * Let's try to use the data from the packet. */ sender->td_end = end; - swin = win << sender->td_scale; - sender->td_maxwin = (swin == 0 ? 1 : swin); + win <<= sender->td_scale; + sender->td_maxwin = (win == 0 ? 1 : win); sender->td_maxend = end + sender->td_maxwin; /* * We haven't seen traffic in the other direction yet diff --git a/trunk/net/nfc/llcp/commands.c b/trunk/net/nfc/llcp/commands.c index ef10ffcb4b6f..7b76eb7192f3 100644 --- a/trunk/net/nfc/llcp/commands.c +++ b/trunk/net/nfc/llcp/commands.c @@ -474,7 +474,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, while (remaining_len > 0) { - frag_len = min_t(size_t, local->remote_miu, remaining_len); + frag_len = min_t(u16, local->remote_miu, remaining_len); pr_debug("Fragment %zd bytes remaining %zd", frag_len, remaining_len); @@ -497,7 +497,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, release_sock(sk); remaining_len -= frag_len; - msg_ptr += frag_len; + msg_ptr += len; } kfree(msg_data); diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index f432c57af05d..e49da2797022 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1294,11 +1294,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) goto bad_res; } - if (!netif_running(netdev)) { - result = -ENETDOWN; - goto bad_res; - } - nla_for_each_nested(nl_txq_params, info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], rem_txq_params) { @@ -6389,7 +6384,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_get_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6421,7 +6416,7 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_set_beacon, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6429,7 +6424,7 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_start_ap, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6437,7 +6432,7 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_stop_ap, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6453,7 +6448,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6469,7 +6464,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_del_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6502,7 +6497,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_del_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6510,7 +6505,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_bss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6536,7 +6531,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_get_mesh_config, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6669,7 +6664,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6677,7 +6672,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6685,7 +6680,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_flush_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6845,7 +6840,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_probe_client, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { diff --git a/trunk/net/wireless/wext-core.c b/trunk/net/wireless/wext-core.c index af648e08e61b..0af7f54e4f61 100644 --- a/trunk/net/wireless/wext-core.c +++ b/trunk/net/wireless/wext-core.c @@ -780,10 +780,8 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, if (cmd == SIOCSIWENCODEEXT) { struct iw_encode_ext *ee = (void *) extra; - if (iwp->length < sizeof(*ee) + ee->key_len) { - err = -EFAULT; - goto out; - } + if (iwp->length < sizeof(*ee) + ee->key_len) + return -EFAULT; } } diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index faea0ec612bf..de639eeeed50 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1869,6 +1869,12 @@ sub process { "No space is necessary after a cast\n" . $hereprev); } + if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $prevrawline =~ /^\+[ \t]*$/) { + CHK("BLOCK_COMMENT_STYLE", + "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev); + } + # check for spaces at the beginning of a line. # Exceptions: # 1) within comments diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index 52577f052bc1..0586085136d1 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -539,6 +539,35 @@ static struct conf_printer header_printer_cb = .print_comment = header_print_comment, }; +/* + * Generate the __enabled_CONFIG_* and __enabled_CONFIG_*_MODULE macros for + * use by the IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is + * generated even for booleans so that the IS_ENABLED() macro works. + */ +static void +header_print__enabled_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +{ + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: { + fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", + sym->name, (*value == 'y')); + fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", + sym->name, (*value == 'm')); + break; + } + default: + break; + } +} + +static struct conf_printer header__enabled_printer_cb = +{ + .print_symbol = header_print__enabled_symbol, + .print_comment = header_print_comment, +}; + /* * Tristate printer * @@ -920,11 +949,16 @@ int conf_write_autoconf(void) conf_write_heading(out_h, &header_printer_cb, NULL); for_all_symbols(i, sym) { + if (!sym->name) + continue; + sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE) || !sym->name) + + conf_write_symbol(out_h, sym, &header__enabled_printer_cb, NULL); + + if (!(sym->flags & SYMBOL_WRITE)) continue; - /* write symbol to auto.conf, tristate and header files */ conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index c4e7d1510f9d..3f01fd908730 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -132,10 +132,8 @@ static struct module *new_module(char *modname) /* strip trailing .o */ s = strrchr(p, '.'); if (s != NULL) - if (strcmp(s, ".o") == 0) { + if (strcmp(s, ".o") == 0) *s = '\0'; - mod->is_dot_o = 1; - } /* add to list */ mod->name = p; @@ -589,8 +587,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, unsigned int crc; enum export export; - if ((!is_vmlinux(mod->name) || mod->is_dot_o) && - strncmp(symname, "__ksymtab", 9) == 0) + if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0) export = export_from_secname(info, get_secindex(info, sym)); else export = export_from_sec(info, get_secindex(info, sym)); diff --git a/trunk/scripts/mod/modpost.h b/trunk/scripts/mod/modpost.h index 51207e4d5f8b..2031119080dc 100644 --- a/trunk/scripts/mod/modpost.h +++ b/trunk/scripts/mod/modpost.h @@ -113,7 +113,6 @@ struct module { int has_cleanup; struct buffer dev_table_buf; char srcversion[25]; - int is_dot_o; }; struct elf_info { diff --git a/trunk/scripts/xz_wrap.sh b/trunk/scripts/xz_wrap.sh index 7a2d372f4885..17a5798c29da 100644 --- a/trunk/scripts/xz_wrap.sh +++ b/trunk/scripts/xz_wrap.sh @@ -12,8 +12,8 @@ BCJ= LZMA2OPTS= -case $SRCARCH in - x86) BCJ=--x86 ;; +case $ARCH in + x86|x86_64) BCJ=--x86 ;; powerpc) BCJ=--powerpc ;; ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; arm) BCJ=--arm ;; diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 71a166a05975..0cf4b53480a7 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -29,7 +29,6 @@ #include #include #include -#include /* * If a non-root user executes a setuid-root binary in @@ -506,11 +505,6 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) } skip: - /* if we have fs caps, clear dangerous personality flags */ - if (!cap_issubset(new->cap_permitted, old->cap_permitted)) - bprm->per_clear |= PER_CLEAR_ON_SETID; - - /* Don't let someone trace a set[ug]id/setpcap binary with the revised * credentials unless they have the appropriate permit */ diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 45c32f074166..81c03a597112 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -1939,19 +1939,18 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) char *hostsp; struct socket_smack *ssp = sk->sk_security; struct smk_audit_info ad; + struct lsm_network_audit net; rcu_read_lock(); hostsp = smack_host_label(sap); if (hostsp != NULL) { + sk_lbl = SMACK_UNLABELED_SOCKET; #ifdef CONFIG_AUDIT - struct lsm_network_audit net; - smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = sap->sin_family; ad.a.u.net->dport = sap->sin_port; ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; #endif - sk_lbl = SMACK_UNLABELED_SOCKET; rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); } else { sk_lbl = SMACK_CIPSO_SOCKET; @@ -2810,14 +2809,11 @@ static int smack_unix_stream_connect(struct sock *sock, struct socket_smack *osp = other->sk_security; struct socket_smack *nsp = newsk->sk_security; struct smk_audit_info ad; - int rc = 0; - -#ifdef CONFIG_AUDIT struct lsm_network_audit net; + int rc = 0; smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_setfield_u_net_sk(&ad, other); -#endif if (!capable(CAP_MAC_OVERRIDE)) rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); @@ -2846,14 +2842,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) struct socket_smack *ssp = sock->sk->sk_security; struct socket_smack *osp = other->sk->sk_security; struct smk_audit_info ad; - int rc = 0; - -#ifdef CONFIG_AUDIT struct lsm_network_audit net; + int rc = 0; smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_setfield_u_net_sk(&ad, other->sk); -#endif if (!capable(CAP_MAC_OVERRIDE)) rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); @@ -3000,9 +2993,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) char *csp; int rc; struct smk_audit_info ad; -#ifdef CONFIG_AUDIT struct lsm_network_audit net; -#endif if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) return 0; @@ -3165,9 +3156,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, char *sp; int rc; struct smk_audit_info ad; -#ifdef CONFIG_AUDIT struct lsm_network_audit net; -#endif /* handle mapped IPv4 packets arriving via IPv6 sockets */ if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) @@ -3640,38 +3629,8 @@ struct security_operations smack_ops = { }; -static __init void init_smack_known_list(void) +static __init void init_smack_know_list(void) { - /* - * Initialize CIPSO locks - */ - spin_lock_init(&smack_known_huh.smk_cipsolock); - spin_lock_init(&smack_known_hat.smk_cipsolock); - spin_lock_init(&smack_known_star.smk_cipsolock); - spin_lock_init(&smack_known_floor.smk_cipsolock); - spin_lock_init(&smack_known_invalid.smk_cipsolock); - spin_lock_init(&smack_known_web.smk_cipsolock); - /* - * Initialize rule list locks - */ - mutex_init(&smack_known_huh.smk_rules_lock); - mutex_init(&smack_known_hat.smk_rules_lock); - mutex_init(&smack_known_floor.smk_rules_lock); - mutex_init(&smack_known_star.smk_rules_lock); - mutex_init(&smack_known_invalid.smk_rules_lock); - mutex_init(&smack_known_web.smk_rules_lock); - /* - * Initialize rule lists - */ - INIT_LIST_HEAD(&smack_known_huh.smk_rules); - INIT_LIST_HEAD(&smack_known_hat.smk_rules); - INIT_LIST_HEAD(&smack_known_star.smk_rules); - INIT_LIST_HEAD(&smack_known_floor.smk_rules); - INIT_LIST_HEAD(&smack_known_invalid.smk_rules); - INIT_LIST_HEAD(&smack_known_web.smk_rules); - /* - * Create the known labels list - */ list_add(&smack_known_huh.list, &smack_known_list); list_add(&smack_known_hat.list, &smack_known_list); list_add(&smack_known_star.list, &smack_known_list); @@ -3706,8 +3665,16 @@ static __init int smack_init(void) cred = (struct cred *) current->cred; cred->security = tsp; - /* initialize the smack_known_list */ - init_smack_known_list(); + /* initialize the smack_know_list */ + init_smack_know_list(); + /* + * Initialize locks + */ + spin_lock_init(&smack_known_huh.smk_cipsolock); + spin_lock_init(&smack_known_hat.smk_cipsolock); + spin_lock_init(&smack_known_star.smk_cipsolock); + spin_lock_init(&smack_known_floor.smk_cipsolock); + spin_lock_init(&smack_known_invalid.smk_cipsolock); /* * Register with LSM diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index 038811cb7e62..5c32f36ff706 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -1614,6 +1614,20 @@ static int __init init_smk_fs(void) smk_cipso_doi(); smk_unlbl_ambient(NULL); + mutex_init(&smack_known_floor.smk_rules_lock); + mutex_init(&smack_known_hat.smk_rules_lock); + mutex_init(&smack_known_huh.smk_rules_lock); + mutex_init(&smack_known_invalid.smk_rules_lock); + mutex_init(&smack_known_star.smk_rules_lock); + mutex_init(&smack_known_web.smk_rules_lock); + + INIT_LIST_HEAD(&smack_known_floor.smk_rules); + INIT_LIST_HEAD(&smack_known_hat.smk_rules); + INIT_LIST_HEAD(&smack_known_huh.smk_rules); + INIT_LIST_HEAD(&smack_known_invalid.smk_rules); + INIT_LIST_HEAD(&smack_known_star.smk_rules); + INIT_LIST_HEAD(&smack_known_web.smk_rules); + return err; } diff --git a/trunk/sound/core/vmaster.c b/trunk/sound/core/vmaster.c index 857586135d18..14a286a7bf2b 100644 --- a/trunk/sound/core/vmaster.c +++ b/trunk/sound/core/vmaster.c @@ -419,7 +419,6 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master); * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control * @kcontrol: vmaster kctl element * @hook: the hook function - * @private_data: the private_data pointer to be saved * * Adds the given hook to the vmaster control element so that it's called * at each time when the value is changed. diff --git a/trunk/sound/isa/sscape.c b/trunk/sound/isa/sscape.c index 8490f59709bb..b4a6aa960f4b 100644 --- a/trunk/sound/isa/sscape.c +++ b/trunk/sound/isa/sscape.c @@ -1019,15 +1019,13 @@ static int __devinit create_sscape(int dev, struct snd_card *card) irq_cfg = get_irq_config(sscape->type, irq[dev]); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); - err = -ENXIO; - goto _release_dma; + return -ENXIO; } mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]); if (mpu_irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); - err = -ENXIO; - goto _release_dma; + return -ENXIO; } /* diff --git a/trunk/sound/last.c b/trunk/sound/last.c index 7ffc182e0844..bdd0857b8871 100644 --- a/trunk/sound/last.c +++ b/trunk/sound/last.c @@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void) return 0; } -late_initcall_sync(alsa_sound_last_init); +__initcall(alsa_sound_last_init); diff --git a/trunk/sound/oss/msnd_pinnacle.c b/trunk/sound/oss/msnd_pinnacle.c index 536c4c0514d3..2c79d60a725f 100644 --- a/trunk/sound/oss/msnd_pinnacle.c +++ b/trunk/sound/oss/msnd_pinnacle.c @@ -1294,8 +1294,6 @@ static int __init calibrate_adc(WORD srate) static int upload_dsp_code(void) { - int ret = 0; - msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); #ifndef HAVE_DSPCODEH INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE); @@ -1314,8 +1312,7 @@ static int upload_dsp_code(void) memcpy_toio(dev.base, PERMCODE, PERMCODESIZE); if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) { printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } #ifdef HAVE_DSPCODEH printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n"); @@ -1323,13 +1320,12 @@ static int upload_dsp_code(void) printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n"); #endif -out: #ifndef HAVE_DSPCODEH vfree(INITCODE); vfree(PERMCODE); #endif - return ret; + return 0; } #ifdef MSND_CLASSIC diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 5ca0939e4223..88168044375f 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -2,8 +2,8 @@ config SND_TEA575X tristate - depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO - default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO + depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 + default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 menuconfig SND_PCI bool "PCI sound devices" diff --git a/trunk/sound/pci/asihpi/hpi_internal.h b/trunk/sound/pci/asihpi/hpi_internal.h index bc86cb726d79..8c63200cf339 100644 --- a/trunk/sound/pci/asihpi/hpi_internal.h +++ b/trunk/sound/pci/asihpi/hpi_internal.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2012 AudioScience Inc. + Copyright (C) 1997-2011 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -42,7 +42,7 @@ On error *pLockedMemHandle marked invalid, non-zero returned. If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle. */ -u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle, +int hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle, /**< memory handle */ u32 size, /**< Size in bytes to allocate */ struct pci_dev *p_os_reference diff --git a/trunk/sound/pci/asihpi/hpios.c b/trunk/sound/pci/asihpi/hpios.c index 5ef4fe964366..87f4385fe8c7 100644 --- a/trunk/sound/pci/asihpi/hpios.c +++ b/trunk/sound/pci/asihpi/hpios.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2012 AudioScience Inc. + Copyright (C) 1997-2011 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -39,11 +39,11 @@ void hpios_delay_micro_seconds(u32 num_micro_sec) } -/** Allocate an area of locked memory for bus master DMA operations. +/** Allocated an area of locked memory for bus master DMA operations. -If allocation fails, return 1, and *pMemArea.size = 0 +On error, return -ENOMEM, and *pMemArea.size = 0 */ -u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, +int hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, struct pci_dev *pdev) { /*?? any benefit in using managed dmam_alloc_coherent? */ @@ -62,7 +62,7 @@ u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, HPI_DEBUG_LOG(WARNING, "failed to allocate %d bytes locked memory\n", size); p_mem_area->size = 0; - return 1; + return -ENOMEM; } } diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 56b4f74c0b13..9a9f372e1be4 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -851,9 +851,6 @@ struct hda_codec { unsigned int pin_amp_workaround:1; /* pin out-amp takes index * (e.g. Conexant codecs) */ - unsigned int single_adc_amp:1; /* adc in-amp takes no index - * (e.g. CX20549 codec) - */ unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ diff --git a/trunk/sound/pci/hda/hda_eld.c b/trunk/sound/pci/hda/hda_eld.c index 4c054f4486b9..b58b4b1687fa 100644 --- a/trunk/sound/pci/hda/hda_eld.c +++ b/trunk/sound/pci/hda/hda_eld.c @@ -418,7 +418,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a) else buf2[0] = '\0'; - _snd_printd(SND_PR_VERBOSE, "HDMI: supports coding type %s:" + printk(KERN_INFO "HDMI: supports coding type %s:" " channels = %d, rates =%s%s\n", cea_audio_coding_type_names[a->format], a->channels, @@ -442,14 +442,14 @@ void snd_hdmi_show_eld(struct hdmi_eld *e) { int i; - _snd_printd(SND_PR_VERBOSE, "HDMI: detected monitor %s at connection type %s\n", + printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n", e->monitor_name, eld_connection_type_names[e->conn_type]); if (e->spk_alloc) { char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); - _snd_printd(SND_PR_VERBOSE, "HDMI: available speakers:%s\n", buf); + printk(KERN_INFO "HDMI: available speakers:%s\n", buf); } for (i = 0; i < e->sad_count; i++) diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index e59e2f059b6e..254ab5204603 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -651,16 +651,9 @@ static void print_codec_info(struct snd_info_entry *entry, snd_iprintf(buffer, " Amp-In caps: "); print_amp_caps(buffer, codec, nid, HDA_INPUT); snd_iprintf(buffer, " Amp-In vals: "); - if (wid_type == AC_WID_PIN || - (codec->single_adc_amp && - wid_type == AC_WID_AUD_IN)) - print_amp_vals(buffer, codec, nid, HDA_INPUT, - wid_caps & AC_WCAP_STEREO, - 1); - else - print_amp_vals(buffer, codec, nid, HDA_INPUT, - wid_caps & AC_WCAP_STEREO, - conn_len); + print_amp_vals(buffer, codec, nid, HDA_INPUT, + wid_caps & AC_WCAP_STEREO, + wid_type == AC_WID_PIN ? 1 : conn_len); } if (wid_caps & AC_WCAP_OUT_AMP) { snd_iprintf(buffer, " Amp-Out caps: "); diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index d906c5b74cf0..8c6523bbc797 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -141,6 +141,7 @@ struct conexant_spec { unsigned int hp_laptop:1; unsigned int asus:1; unsigned int pin_eapd_ctrls:1; + unsigned int single_adc_amp:1; unsigned int adc_switching:1; @@ -686,26 +687,27 @@ static const struct hda_channel_mode cxt5045_modes[1] = { static const struct hda_input_mux cxt5045_capture_source = { .num_items = 2, .items = { - { "Internal Mic", 0x1 }, - { "Mic", 0x2 }, + { "IntMic", 0x1 }, + { "ExtMic", 0x2 }, } }; static const struct hda_input_mux cxt5045_capture_source_benq = { - .num_items = 4, + .num_items = 5, .items = { - { "Internal Mic", 0x1 }, - { "Mic", 0x2 }, - { "Line", 0x3 }, - { "Mixer", 0x0 }, + { "IntMic", 0x1 }, + { "ExtMic", 0x2 }, + { "LineIn", 0x3 }, + { "CD", 0x4 }, + { "Mixer", 0x0 }, } }; static const struct hda_input_mux cxt5045_capture_source_hp530 = { .num_items = 2, .items = { - { "Mic", 0x1 }, - { "Internal Mic", 0x2 }, + { "ExtMic", 0x1 }, + { "IntMic", 0x2 }, } }; @@ -796,8 +798,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, } static const struct snd_kcontrol_new cxt5045_mixers[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), @@ -818,15 +822,27 @@ static const struct snd_kcontrol_new cxt5045_mixers[] = { }; static const struct snd_kcontrol_new cxt5045_benq_mixers[] = { - HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), + HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), + + HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT), {} }; static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), @@ -930,10 +946,10 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Output controls */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("HP-OUT Playback Volume", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("HP-OUT Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LINE1 Playback Switch", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), /* Modes for retasking pin widgets */ CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), @@ -944,16 +960,16 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Loopback mixer controls */ - HDA_CODEC_VOLUME("PCM Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("PCM Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("MIC1 pin Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 pin Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("LINE1 pin Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("LINE1 pin Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("HP-OUT pin Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("HP-OUT pin Switch", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("CD pin Volume", 0x17, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD pin Switch", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -962,8 +978,16 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = { .put = conexant_mux_enum_put, }, /* Audio input controls */ - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT), { } /* end */ }; @@ -985,6 +1009,10 @@ static const struct hda_verb cxt5045_test_init_verbs[] = { {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0}, + /* Start with output sum widgets muted and their output gains at min */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + /* Unmute retasking pin widget output buffers since the default * state appears to be output. As the pin mode is changed by the * user the pin mode control will take care of enabling the pin's @@ -999,11 +1027,11 @@ static const struct hda_verb cxt5045_test_init_verbs[] = { /* Set ADC connection select to match default mixer setting (mic1 * pin) */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Mute all inputs to mixer widget (even unconnected ones) */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */ @@ -1082,7 +1110,7 @@ static int patch_cxt5045(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; - codec->single_adc_amp = 1; + codec->pin_amp_workaround = 1; spec->multiout.max_channels = 2; spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids); @@ -3971,14 +3999,9 @@ static void cx_auto_init_output(struct hda_codec *codec) int i; mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); - for (i = 0; i < cfg->hp_outs; i++) { - unsigned int val = PIN_OUT; - if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & - AC_PINCAP_HP_DRV) - val |= AC_PINCTL_HP_EN; + for (i = 0; i < cfg->hp_outs; i++) snd_hda_codec_write(codec, cfg->hp_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, val); - } + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); @@ -4197,7 +4220,7 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, int idx = get_input_connection(codec, adc_nid, nid); if (idx < 0) continue; - if (codec->single_adc_amp) + if (spec->single_adc_amp) idx = 0; return cx_auto_add_volume_idx(codec, label, pfx, cidx, adc_nid, HDA_INPUT, idx); @@ -4252,7 +4275,7 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) if (cidx < 0) continue; input_conn[i] = spec->imux_info[i].adc; - if (!codec->single_adc_amp) + if (!spec->single_adc_amp) input_conn[i] |= cidx << 8; if (i > 0 && input_conn[i] != input_conn[0]) multi_connection = 1; @@ -4396,10 +4419,8 @@ static void apply_pin_fixup(struct hda_codec *codec, enum { CXT_PINCFG_LENOVO_X200, - CXT_PINCFG_LENOVO_TP410, }; -/* ThinkPad X200 & co with cxt5051 */ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ { 0x17, 0x21a11000 }, /* dock-mic */ @@ -4408,33 +4429,15 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { {} }; -/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */ -static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = { - { 0x19, 0x042110ff }, /* HP (seq# overridden) */ - { 0x1a, 0x21a190f0 }, /* dock-mic */ - { 0x1c, 0x212140ff }, /* dock-HP */ - {} -}; - static const struct cxt_pincfg *cxt_pincfg_tbl[] = { [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, - [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410, }; -static const struct snd_pci_quirk cxt5051_fixups[] = { +static const struct snd_pci_quirk cxt_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), {} }; -static const struct snd_pci_quirk cxt5066_fixups[] = { - SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), - {} -}; - /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches * can be created (bko#42825) */ @@ -4463,21 +4466,19 @@ static int patch_conexant_auto(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; + codec->pin_amp_workaround = 1; switch (codec->vendor_id) { case 0x14f15045: - codec->single_adc_amp = 1; + spec->single_adc_amp = 1; break; case 0x14f15051: add_cx5051_fake_mutes(codec); - codec->pin_amp_workaround = 1; - apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl); break; - default: - codec->pin_amp_workaround = 1; - apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl); } + apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); + /* Show mute-led control only on HP laptops * This is a sort of white-list: on HP laptops, EAPD corresponds * only to the mute-LED without actualy amp function. Meanwhile, diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c index 83f345f3c961..540cd13f7f15 100644 --- a/trunk/sound/pci/hda/patch_hdmi.c +++ b/trunk/sound/pci/hda/patch_hdmi.c @@ -757,6 +757,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) struct hdmi_spec *spec = codec->spec; int tag = res >> AC_UNSOL_RES_TAG_SHIFT; int pin_nid; + int pd = !!(res & AC_UNSOL_RES_PD); + int eldv = !!(res & AC_UNSOL_RES_ELDV); int pin_idx; struct hda_jack_tbl *jack; @@ -766,10 +768,9 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) pin_nid = jack->nid; jack->jack_dirty = 1; - _snd_printd(SND_PR_VERBOSE, + printk(KERN_INFO "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, - !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); + codec->addr, pin_nid, pd, eldv); pin_idx = pin_nid_to_pin_index(spec, pin_nid); if (pin_idx < 0) @@ -991,7 +992,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) if (eld->monitor_present) eld_valid = !!(present & AC_PINSENSE_ELDV); - _snd_printd(SND_PR_VERBOSE, + printk(KERN_INFO "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", codec->addr, pin_nid, eld->monitor_present, eld_valid); diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index e65e35433055..9917e55d6f11 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1445,13 +1445,6 @@ enum { ALC_FIXUP_ACT_BUILD, }; -static void alc_apply_pincfgs(struct hda_codec *codec, - const struct alc_pincfg *cfg) -{ - for (; cfg->nid; cfg++) - snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); -} - static void alc_apply_fixup(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; @@ -1485,7 +1478,9 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) snd_printdd(KERN_INFO "hda_codec: %s: " "Apply pincfg for %s\n", codec->chip_name, modelname); - alc_apply_pincfgs(codec, cfg); + for (; cfg->nid; cfg++) + snd_hda_codec_set_pincfg(codec, cfg->nid, + cfg->val); break; case ALC_FIXUP_VERBS: if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) @@ -3403,10 +3398,8 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (;;) { badness = fill_and_eval_dacs(codec, fill_hardwired, fill_mio_first); - if (badness < 0) { - kfree(best_cfg); + if (badness < 0) return badness; - } debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", cfg->line_out_type, fill_hardwired, fill_mio_first, badness); @@ -3441,7 +3434,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; fill_hardwired = true; continue; - } + } if (cfg->hp_outs > 0 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { cfg->speaker_outs = cfg->line_outs; @@ -3455,7 +3448,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) cfg->line_out_type = AUTO_PIN_HP_OUT; fill_hardwired = true; continue; - } + } break; } @@ -4430,7 +4423,7 @@ static int alc_parse_auto_config(struct hda_codec *codec, static int alc880_parse_auto_config(struct hda_codec *codec) { static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; - static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; + static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); } @@ -4866,7 +4859,6 @@ enum { ALC260_FIXUP_GPIO1_TOGGLE, ALC260_FIXUP_REPLACER, ALC260_FIXUP_HP_B1900, - ALC260_FIXUP_KN1, }; static void alc260_gpio1_automute(struct hda_codec *codec) @@ -4894,36 +4886,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, } } -static void alc260_fixup_kn1(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - struct alc_spec *spec = codec->spec; - static const struct alc_pincfg pincfgs[] = { - { 0x0f, 0x02214000 }, /* HP/speaker */ - { 0x12, 0x90a60160 }, /* int mic */ - { 0x13, 0x02a19000 }, /* ext mic */ - { 0x18, 0x01446000 }, /* SPDIF out */ - /* disable bogus I/O pins */ - { 0x10, 0x411111f0 }, - { 0x11, 0x411111f0 }, - { 0x14, 0x411111f0 }, - { 0x15, 0x411111f0 }, - { 0x16, 0x411111f0 }, - { 0x17, 0x411111f0 }, - { 0x19, 0x411111f0 }, - { } - }; - - switch (action) { - case ALC_FIXUP_ACT_PRE_PROBE: - alc_apply_pincfgs(codec, pincfgs); - break; - case ALC_FIXUP_ACT_PROBE: - spec->init_amp = ALC_INIT_NONE; - break; - } -} - static const struct alc_fixup alc260_fixups[] = { [ALC260_FIXUP_HP_DC5750] = { .type = ALC_FIXUP_PINS, @@ -4974,11 +4936,7 @@ static const struct alc_fixup alc260_fixups[] = { .v.func = alc260_fixup_gpio1_toggle, .chained = true, .chain_id = ALC260_FIXUP_COEF, - }, - [ALC260_FIXUP_KN1] = { - .type = ALC_FIXUP_FUNC, - .v.func = alc260_fixup_kn1, - }, + } }; static const struct snd_pci_quirk alc260_fixup_tbl[] = { @@ -4988,7 +4946,6 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), - SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), {} @@ -5312,9 +5269,7 @@ static const struct alc_fixup alc882_fixups[] = { { 0x16, 0x99130111 }, /* CLFE speaker */ { 0x17, 0x99130112 }, /* surround speaker */ { } - }, - .chained = true, - .chain_id = ALC882_FIXUP_GPIO1, + } }, [ALC882_FIXUP_ACER_ASPIRE_8930G] = { .type = ALC_FIXUP_PINS, @@ -5357,9 +5312,7 @@ static const struct alc_fixup alc882_fixups[] = { { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, { } - }, - .chained = true, - .chain_id = ALC882_FIXUP_GPIO1, + } }, [ALC885_FIXUP_MACPRO_GPIO] = { .type = ALC_FIXUP_FUNC, @@ -5406,7 +5359,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), - SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), @@ -5432,7 +5384,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), - SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), @@ -5448,13 +5399,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { {} }; -static const struct alc_model_fixup alc882_fixup_models[] = { - {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, - {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, - {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, - {} -}; - /* * BIOS auto configuration */ @@ -5495,8 +5439,7 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) goto error; - alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, - alc882_fixups); + alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); @@ -6136,7 +6079,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. - */ + */ SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), @@ -6353,7 +6296,7 @@ static void alc_fixup_no_jack_detect(struct hda_codec *codec, { if (action == ALC_FIXUP_ACT_PRE_PROBE) codec->no_jack_detect = 1; -} +} static const struct alc_fixup alc861_fixups[] = { [ALC861_FIXUP_FSC_AMILO_PI1505] = { @@ -6771,7 +6714,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. - */ + */ SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 4742cac26aa9..33a9946b492c 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -5063,11 +5063,12 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled) if (spec->gpio_led_polarity) muted = !muted; + /*polarity defines *not* muted state level*/ if (!spec->vref_mute_led_nid) { if (muted) - spec->gpio_data |= spec->gpio_led; + spec->gpio_data &= ~spec->gpio_led; /* orange */ else - spec->gpio_data &= ~spec->gpio_led; + spec->gpio_data |= spec->gpio_led; /* white */ stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); } else { diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index 59d8efaa17e9..6508e8b790bb 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C select SND_SOC_TWL4030 if TWL4030_CORE - select SND_SOC_TWL6040 if TWL6040_CORE + select SND_SOC_TWL6040 if TWL4030_CORE select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WL1273 if MFD_WL1273_CORE @@ -276,6 +276,7 @@ config SND_SOC_TWL4030 tristate config SND_SOC_TWL6040 + select TWL6040_CORE tristate config SND_SOC_UDA134X diff --git a/trunk/sound/soc/codecs/ak4642.c b/trunk/sound/soc/codecs/ak4642.c index b3e24f289421..f8e10ced244a 100644 --- a/trunk/sound/soc/codecs/ak4642.c +++ b/trunk/sound/soc/codecs/ak4642.c @@ -140,7 +140,7 @@ * min : 0xFE : -115.0 dB * mute: 0xFF */ -static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1); +static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1); static const struct snd_kcontrol_new ak4642_snd_controls[] = { diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index 8e92fb88ed09..d1926266fe00 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -143,11 +143,11 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, } /* - * As manual described, ADC/DAC only works when VAG powerup, - * So enabled VAG before ADC/DAC up. - * In power down case, we need wait 400ms when vag fully ramped down. + * using codec assist to small pop, hp_powerup or lineout_powerup + * should stay setting until vag_powerup is fully ramped down, + * vag fully ramped down require 400ms. */ -static int power_vag_event(struct snd_soc_dapm_widget *w, +static int small_pop_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { switch (event) { @@ -156,7 +156,7 @@ static int power_vag_event(struct snd_soc_dapm_widget *w, SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); break; - case SND_SOC_DAPM_POST_PMD: + case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, SGTL5000_VAG_POWERUP, 0); msleep(400); @@ -201,8 +201,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { mic_bias_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0), - SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0, + small_pop_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0, + small_pop_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux), SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux), @@ -217,11 +221,8 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { 0, SGTL5000_CHIP_DIG_POWER, 1, 0), - SND_SOC_DAPM_SUPPLY("VAG_POWER", SGTL5000_CHIP_ANA_POWER, 7, 0, - power_vag_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0), + SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0), }; @@ -230,11 +231,9 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ - {"ADC", NULL, "VAG_POWER"}, {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */ {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */ - {"DAC", NULL, "VAG_POWER"}, {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */ {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ {"LO", NULL, "DAC"}, /* dac --> line_out */ diff --git a/trunk/sound/soc/codecs/twl6040.c b/trunk/sound/soc/codecs/twl6040.c index dc7509b9d53a..2d8c6b825e57 100644 --- a/trunk/sound/soc/codecs/twl6040.c +++ b/trunk/sound/soc/codecs/twl6040.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -1527,7 +1528,7 @@ static int twl6040_resume(struct snd_soc_codec *codec) static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; - struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev); + struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); struct platform_device *pdev = container_of(codec->dev, struct platform_device, dev); int ret = 0; diff --git a/trunk/sound/soc/imx/imx-audmux.c b/trunk/sound/soc/imx/imx-audmux.c index f23700359c67..1765a197acb0 100644 --- a/trunk/sound/soc/imx/imx-audmux.c +++ b/trunk/sound/soc/imx/imx-audmux.c @@ -73,9 +73,6 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; - if (!audmux_base) - return -ENOSYS; - if (audmux_clk) clk_prepare_enable(audmux_clk); @@ -155,7 +152,7 @@ static void __init audmux_debugfs_init(void) return; } - for (i = 0; i < MX31_AUDMUX_PORT6_SSI_PINS_6 + 1; i++) { + for (i = 1; i < 8; i++) { snprintf(buf, sizeof(buf), "ssi%d", i); if (!debugfs_create_file(buf, 0444, audmux_debugfs_root, (void *)i, &audmux_debugfs_fops)) diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index deafbfaacdbf..e00dd0b1139c 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 + depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4 select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.c b/trunk/sound/soc/pxa/pxa2xx-i2s.c index d08583790d23..609abd51e55f 100644 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.c +++ b/trunk/sound/soc/pxa/pxa2xx-i2s.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index accdcb7d4d9d..e19c24ade414 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -1081,8 +1081,6 @@ static int soc_probe_platform(struct snd_soc_card *card, snd_soc_dapm_new_controls(&platform->dapm, driver->dapm_widgets, driver->num_dapm_widgets); - platform->dapm.idle_bias_off = 1; - if (driver->probe) { ret = driver->probe(platform); if (ret < 0) { diff --git a/trunk/sound/soc/tegra/tegra_i2s.c b/trunk/sound/soc/tegra/tegra_i2s.c index e53349912b2e..33509de52540 100644 --- a/trunk/sound/soc/tegra/tegra_i2s.c +++ b/trunk/sound/soc/tegra/tegra_i2s.c @@ -79,15 +79,11 @@ static int tegra_i2s_show(struct seq_file *s, void *unused) struct tegra_i2s *i2s = s->private; int i; - clk_enable(i2s->clk_i2s); - for (i = 0; i < ARRAY_SIZE(regs); i++) { u32 val = tegra_i2s_read(i2s, regs[i].offset); seq_printf(s, "%s = %08x\n", regs[i].name, val); } - clk_disable(i2s->clk_i2s); - return 0; } @@ -116,7 +112,7 @@ static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) debugfs_remove(i2s->debug); } #else -static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s) +static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) { } diff --git a/trunk/sound/soc/tegra/tegra_spdif.c b/trunk/sound/soc/tegra/tegra_spdif.c index 9ff2c601445f..475428cf270e 100644 --- a/trunk/sound/soc/tegra/tegra_spdif.c +++ b/trunk/sound/soc/tegra/tegra_spdif.c @@ -79,15 +79,11 @@ static int tegra_spdif_show(struct seq_file *s, void *unused) struct tegra_spdif *spdif = s->private; int i; - clk_enable(spdif->clk_spdif_out); - for (i = 0; i < ARRAY_SIZE(regs); i++) { u32 val = tegra_spdif_read(spdif, regs[i].offset); seq_printf(s, "%s = %08x\n", regs[i].name, val); } - clk_disable(spdif->clk_spdif_out); - return 0; } diff --git a/trunk/tools/perf/.gitignore b/trunk/tools/perf/.gitignore index 26b823b61aa1..416684be0ad3 100644 --- a/trunk/tools/perf/.gitignore +++ b/trunk/tools/perf/.gitignore @@ -19,5 +19,3 @@ TAGS cscope* config.mak config.mak.autogen -*-bison.* -*-flex.* diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 03059e75665a..820371f10d1b 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -237,20 +237,21 @@ export PERL_PATH FLEX = $(CROSS_COMPILE)flex BISON= $(CROSS_COMPILE)bison -$(OUTPUT)util/parse-events-flex.c: util/parse-events.l +event-parser: + $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c -$(OUTPUT)util/parse-events-bison.c: util/parse-events.y - $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c +$(OUTPUT)util/parse-events-flex.c: event-parser +$(OUTPUT)util/parse-events-bison.c: event-parser -$(OUTPUT)util/pmu-flex.c: util/pmu.l +pmu-parser: + $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c -$(OUTPUT)util/pmu-bison.c: util/pmu.y - $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c +$(OUTPUT)util/pmu-flex.c: pmu-parser +$(OUTPUT)util/pmu-bison.c: pmu-parser -$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c -$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c +$(OUTPUT)util/parse-events.o: event-parser pmu-parser LIB_FILE=$(OUTPUT)libperf.a @@ -526,7 +527,7 @@ else endif ifdef NO_GTK2 - BASIC_CFLAGS += -DNO_GTK2_SUPPORT + BASIC_CFLAGS += -DNO_GTK2 else FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0) ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) @@ -851,6 +852,8 @@ help: @echo ' html - make html documentation' @echo ' info - make GNU info documentation (access with info )' @echo ' pdf - make pdf documentation' + @echo ' event-parser - make event parser code' + @echo ' pmu-parser - make pmu format parser code' @echo ' TAGS - use etags to make tag information for source browsing' @echo ' tags - use ctags to make tag information for source browsing' @echo ' cscope - use cscope to make interactive browsing database' diff --git a/trunk/tools/perf/builtin-sched.c b/trunk/tools/perf/builtin-sched.c index 1cad3af4bf4c..fb8b5f83b4a0 100644 --- a/trunk/tools/perf/builtin-sched.c +++ b/trunk/tools/perf/builtin-sched.c @@ -17,7 +17,6 @@ #include "util/debug.h" #include -#include #include #include diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 8ef59f8262bb..e3c63aef8efc 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -42,7 +42,6 @@ #include "util/debug.h" #include -#include #include #include @@ -60,7 +59,6 @@ #include #include #include -#include #include #include @@ -164,40 +162,12 @@ static void __zero_source_counters(struct hist_entry *he) symbol__annotate_zero_histograms(sym); } -static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) -{ - struct utsname uts; - int err = uname(&uts); - - ui__warning("Out of bounds address found:\n\n" - "Addr: %" PRIx64 "\n" - "DSO: %s %c\n" - "Map: %" PRIx64 "-%" PRIx64 "\n" - "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n" - "Arch: %s\n" - "Kernel: %s\n" - "Tools: %s\n\n" - "Not all samples will be on the annotation output.\n\n" - "Please report to linux-kernel@vger.kernel.org\n", - ip, map->dso->long_name, dso__symtab_origin(map->dso), - map->start, map->end, sym->start, sym->end, - sym->binding == STB_GLOBAL ? 'g' : - sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, - err ? "[unknown]" : uts.machine, - err ? "[unknown]" : uts.release, perf_version_string); - if (use_browser <= 0) - sleep(5); - - map->erange_warned = true; -} - static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, int counter, u64 ip) { struct annotation *notes; struct symbol *sym; - int err; if (he == NULL || he->ms.sym == NULL || ((top->sym_filter_entry == NULL || @@ -219,12 +189,9 @@ static void perf_top__record_precise_ip(struct perf_top *top, } ip = he->ms.map->map_ip(he->ms.map, ip); - err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); + symbol__inc_addr_samples(sym, he->ms.map, counter, ip); pthread_mutex_unlock(¬es->lock); - - if (err == -ERANGE && !he->ms.map->erange_warned) - ui__warn_map_erange(he->ms.map, sym, ip); } static void perf_top__show_details(struct perf_top *top) @@ -648,7 +615,6 @@ static void *display_thread(void *arg) /* Tag samples to be skipped. */ static const char *skip_symbols[] = { - "intel_idle", "default_idle", "native_safe_halt", "cpu_idle", diff --git a/trunk/tools/perf/perf-archive.sh b/trunk/tools/perf/perf-archive.sh index 95b6f8b6177a..677e59d62a8d 100644 --- a/trunk/tools/perf/perf-archive.sh +++ b/trunk/tools/perf/perf-archive.sh @@ -29,14 +29,13 @@ if [ ! -s $BUILDIDS ] ; then fi MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX) -PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/ cut -d ' ' -f 1 $BUILDIDS | \ while read build_id ; do linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2} filename=$(readlink -f $linkname) echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST - echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST + echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST done tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST diff --git a/trunk/tools/perf/util/annotate.c b/trunk/tools/perf/util/annotate.c index 08c6d138a655..199f69ec656f 100644 --- a/trunk/tools/perf/util/annotate.c +++ b/trunk/tools/perf/util/annotate.c @@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); - if (addr < sym->start || addr > sym->end) - return -ERANGE; + if (addr > sym->end) + return 0; offset = addr - sym->start; h = annotation__histogram(notes, evidx); @@ -561,12 +561,16 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); - int len = sym->end - sym->start, offset; + struct objdump_line *pos; + int len = sym->end - sym->start; h->sum = 0; - for (offset = 0; offset < len; ++offset) { - h->addr[offset] = h->addr[offset] * 7 / 8; - h->sum += h->addr[offset]; + + list_for_each_entry(pos, ¬es->src->source, node) { + if (pos->offset != -1 && pos->offset < len) { + h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; + h->sum += h->addr[pos->offset]; + } } } diff --git a/trunk/tools/perf/util/hist.c b/trunk/tools/perf/util/hist.c index 9f6d630d5316..2ec4b60aff6c 100644 --- a/trunk/tools/perf/util/hist.c +++ b/trunk/tools/perf/util/hist.c @@ -256,18 +256,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists, if (!cmp) { he->period += period; ++he->nr_events; - - /* If the map of an existing hist_entry has - * become out-of-date due to an exec() or - * similar, update it. Otherwise we will - * mis-adjust symbol addresses when computing - * the history counter to increment. - */ - if (he->ms.map != entry->ms.map) { - he->ms.map = entry->ms.map; - if (he->ms.map) - he->ms.map->referenced = true; - } goto out; } diff --git a/trunk/tools/perf/util/map.c b/trunk/tools/perf/util/map.c index 35ae56864e4f..dea6d1c1a954 100644 --- a/trunk/tools/perf/util/map.c +++ b/trunk/tools/perf/util/map.c @@ -38,7 +38,6 @@ void map__init(struct map *self, enum map_type type, RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; - self->erange_warned = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, diff --git a/trunk/tools/perf/util/map.h b/trunk/tools/perf/util/map.h index 81371bad4ef0..b100c20b7f94 100644 --- a/trunk/tools/perf/util/map.h +++ b/trunk/tools/perf/util/map.h @@ -33,7 +33,6 @@ struct map { u64 end; u8 /* enum map_type */ type; bool referenced; - bool erange_warned; u32 priv; u64 pgoff; diff --git a/trunk/tools/perf/util/session.c b/trunk/tools/perf/util/session.c index 1efd3bee6336..9412e3b05f68 100644 --- a/trunk/tools/perf/util/session.c +++ b/trunk/tools/perf/util/session.c @@ -826,16 +826,8 @@ static struct machine * { const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { - u32 pid; - - if (event->header.type == PERF_RECORD_MMAP) - pid = event->mmap.pid; - else - pid = event->ip.pid; - - return perf_session__find_machine(session, pid); - } + if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) + return perf_session__find_machine(session, event->ip.pid); return perf_session__find_host_machine(session); } @@ -876,11 +868,11 @@ static int perf_session_deliver_event(struct perf_session *session, dump_sample(session, event, sample); if (evsel == NULL) { ++session->hists.stats.nr_unknown_id; - return 0; + return -1; } if (machine == NULL) { ++session->hists.stats.nr_unprocessable_samples; - return 0; + return -1; } return tool->sample(tool, event, sample, evsel, machine); case PERF_RECORD_MMAP: diff --git a/trunk/tools/perf/util/ui/browsers/hists.c b/trunk/tools/perf/util/ui/browsers/hists.c index 2f83e5dc9967..d7a1c4afe28b 100644 --- a/trunk/tools/perf/util/ui/browsers/hists.c +++ b/trunk/tools/perf/util/ui/browsers/hists.c @@ -125,9 +125,6 @@ static int callchain__count_rows(struct rb_root *chain) static bool map_symbol__toggle_fold(struct map_symbol *self) { - if (!self) - return false; - if (!self->has_children) return false; diff --git a/trunk/virt/kvm/iommu.c b/trunk/virt/kvm/iommu.c index e9fff9830bf0..a457d2138f49 100644 --- a/trunk/virt/kvm/iommu.c +++ b/trunk/virt/kvm/iommu.c @@ -240,13 +240,9 @@ int kvm_iommu_map_guest(struct kvm *kvm) return -ENODEV; } - mutex_lock(&kvm->slots_lock); - kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type); - if (!kvm->arch.iommu_domain) { - r = -ENOMEM; - goto out_unlock; - } + if (!kvm->arch.iommu_domain) + return -ENOMEM; if (!allow_unsafe_assigned_interrupts && !iommu_domain_has_cap(kvm->arch.iommu_domain, @@ -257,16 +253,17 @@ int kvm_iommu_map_guest(struct kvm *kvm) " module option.\n", __func__); iommu_domain_free(kvm->arch.iommu_domain); kvm->arch.iommu_domain = NULL; - r = -EPERM; - goto out_unlock; + return -EPERM; } r = kvm_iommu_map_memslots(kvm); if (r) - kvm_iommu_unmap_memslots(kvm); + goto out_unmap; -out_unlock: - mutex_unlock(&kvm->slots_lock); + return 0; + +out_unmap: + kvm_iommu_unmap_memslots(kvm); return r; } @@ -313,11 +310,6 @@ static void kvm_iommu_put_pages(struct kvm *kvm, } } -void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot) -{ - kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages); -} - static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int idx; @@ -328,7 +320,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) - kvm_iommu_unmap_pages(kvm, memslot); + kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages); srcu_read_unlock(&kvm->srcu, idx); @@ -343,11 +335,7 @@ int kvm_iommu_unmap_guest(struct kvm *kvm) if (!domain) return 0; - mutex_lock(&kvm->slots_lock); kvm_iommu_unmap_memslots(kvm); - kvm->arch.iommu_domain = NULL; - mutex_unlock(&kvm->slots_lock); - iommu_domain_free(domain); return 0; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 9739b533ca2e..42b73930a6de 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -808,13 +808,12 @@ int __kvm_set_memory_region(struct kvm *kvm, if (r) goto out_free; - /* map/unmap the pages in iommu page table */ + /* map the pages in iommu page table */ if (npages) { r = kvm_iommu_map_pages(kvm, &new); if (r) goto out_free; - } else - kvm_iommu_unmap_pages(kvm, &old); + } r = -ENOMEM; slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),