aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/uio-howto.tmpl90
-rw-r--r--Documentation/namespaces/compatibility-list.txt39
-rw-r--r--Documentation/tty.txt8
-rw-r--r--Documentation/usb/power-management.txt8
-rw-r--r--Documentation/x86_64/uefi.txt29
-rw-r--r--MAINTAINERS111
-rw-r--r--arch/arm/common/uengine.c6
-rw-r--r--arch/arm/kernel/entry-armv.S96
-rw-r--r--arch/arm/kernel/traps.c5
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c41
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c42
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c42
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c42
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c43
-rw-r--r--arch/arm/mach-at91/board-carmeva.c2
-rw-r--r--arch/arm/mach-at91/board-csb337.c11
-rw-r--r--arch/arm/mach-at91/board-csb637.c2
-rw-r--r--arch/arm/mach-at91/board-dk.c15
-rw-r--r--arch/arm/mach-at91/board-eb9200.c10
-rw-r--r--arch/arm/mach-at91/board-ek.c2
-rw-r--r--arch/arm/mach-at91/board-kafa.c2
-rw-r--r--arch/arm/mach-at91/board-kb9202.c2
-rw-r--r--arch/arm/mach-at91/board-picotux200.c2
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c2
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c18
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c2
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c2
-rw-r--r--arch/arm/mach-at91/clock.c9
-rw-r--r--arch/arm/mach-imx/irq.c51
-rw-r--r--arch/arm/mach-pxa/pxa27x.c2
-rw-r--r--arch/arm/mach-pxa/pxa320.c7
-rw-r--r--arch/arm/mach-pxa/ssp.c1
-rw-r--r--arch/frv/kernel/break.S2
-rw-r--r--arch/frv/kernel/entry.S2
-rw-r--r--arch/frv/kernel/vmlinux.lds.S27
-rw-r--r--arch/frv/mm/tlb-miss.S2
-rw-r--r--arch/m32r/kernel/signal.c17
-rw-r--r--arch/m32r/kernel/syscall_table.S40
-rw-r--r--arch/mips/kernel/csrc-r4k.c6
-rw-r--r--arch/mips/sgi-ip22/ip22-setup.c19
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/drivers/ubd_kern.c1
-rw-r--r--arch/um/os-Linux/time.c54
-rw-r--r--arch/x86/boot/header.S41
-rw-r--r--arch/x86/kernel/paravirt_32.c4
-rw-r--r--arch/x86/lguest/Kconfig1
-rw-r--r--arch/x86/mm/init_64.c2
-rw-r--r--arch/x86/xen/mmu.c4
-rw-r--r--drivers/acpi/processor_core.c14
-rw-r--r--drivers/base/core.c4
-rw-r--r--drivers/base/power/Makefile3
-rw-r--r--drivers/base/power/main.c8
-rw-r--r--drivers/base/power/power.h28
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/tpm/tpm_tis.c10
-rw-r--r--drivers/dma/Kconfig8
-rw-r--r--drivers/isdn/hisax/hfcscard.c3
-rw-r--r--drivers/mfd/sm501.c2
-rw-r--r--drivers/mmc/card/sdio_uart.c2
-rw-r--r--drivers/pci/hotplug/acpiphp.h8
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c29
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c36
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c47
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c41
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c96
-rw-r--r--drivers/pci/hotplug/fakephp.c14
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c16
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c19
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c15
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c1
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c16
-rw-r--r--drivers/pci/pci-sysfs.c4
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c29
-rw-r--r--drivers/pci/pcie/portdrv_pci.c2
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c15
-rw-r--r--drivers/pnp/resource.c4
-rw-r--r--drivers/ps3/Makefile4
-rw-r--r--drivers/ps3/ps3-sys-manager.c (renamed from drivers/ps3/sys-manager.c)0
-rw-r--r--drivers/ps3/ps3-vuart.c (renamed from drivers/ps3/vuart.c)0
-rw-r--r--drivers/rtc/interface.c4
-rw-r--r--drivers/rtc/rtc-dev.c12
-rw-r--r--drivers/scsi/zorro7xx.c3
-rw-r--r--drivers/serial/ip22zilog.c247
-rw-r--r--drivers/serial/pxa.c4
-rw-r--r--drivers/spi/atmel_spi.c2
-rw-r--r--drivers/spi/spi_s3c24xx_gpio.c21
-rw-r--r--drivers/usb/README6
-rw-r--r--drivers/usb/core/driver.c11
-rw-r--r--drivers/usb/core/hcd.c3
-rw-r--r--drivers/usb/core/hub.c2
-rw-r--r--drivers/usb/core/message.c36
-rw-r--r--drivers/usb/core/sysfs.c6
-rw-r--r--drivers/usb/core/usb.c25
-rw-r--r--drivers/usb/gadget/omap_udc.c6
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c16
-rw-r--r--drivers/usb/host/Kconfig2
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/image/microtek.c2
-rw-r--r--drivers/usb/misc/adutux.c262
-rw-r--r--drivers/usb/misc/usbled.c4
-rw-r--r--drivers/usb/serial/generic.c5
-rw-r--r--drivers/usb/serial/keyspan.c32
-rw-r--r--drivers/usb/serial/mos7840.c2
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h3
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/storage/scsiglue.c4
-rw-r--r--drivers/usb/storage/unusual_devs.h17
-rw-r--r--drivers/video/Kconfig11
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/atmel_lcdfb.c4
-rw-r--r--drivers/video/efifb.c232
-rw-r--r--drivers/video/fb_ddc.c8
-rw-r--r--drivers/video/imacfb.c4
-rw-r--r--drivers/video/ps3fb.c11
-rw-r--r--fs/Kconfig9
-rw-r--r--fs/compat_ioctl.c6
-rw-r--r--fs/exec.c6
-rw-r--r--fs/ext2/ext2.h7
-rw-r--r--fs/fuse/dir.c81
-rw-r--r--fs/fuse/file.c47
-rw-r--r--fs/fuse/fuse_i.h5
-rw-r--r--fs/fuse/inode.c4
-rw-r--r--fs/ocfs2/aops.c2
-rw-r--r--fs/ocfs2/cluster/masklog.h2
-rw-r--r--fs/ocfs2/dcache.c20
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c4
-rw-r--r--fs/ocfs2/file.c19
-rw-r--r--fs/ocfs2/inode.c6
-rw-r--r--fs/ocfs2/localalloc.c5
-rw-r--r--fs/ocfs2/super.c6
-rw-r--r--fs/proc/base.c51
-rw-r--r--fs/proc/generic.c37
-rw-r--r--fs/proc/internal.h2
-rw-r--r--fs/proc/root.c2
-rw-r--r--fs/sysfs/file.c6
-rw-r--r--include/asm-arm/arch-at91/board.h3
-rw-r--r--include/asm-arm/arch-ixp23xx/irqs.h2
-rw-r--r--include/asm-arm/arch-omap/board-innovator.h2
-rw-r--r--include/asm-arm/arch-pxa/irqs.h20
-rw-r--r--include/asm-arm/arch-pxa/mfp-pxa300.h2
-rw-r--r--include/asm-arm/arch-pxa/mfp-pxa320.h2
-rw-r--r--include/asm-arm/arch-pxa/mfp.h18
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h5
-rw-r--r--include/asm-arm/arch-s3c2410/spi-gpio.h2
-rw-r--r--include/asm-m32r/thread_info.h11
-rw-r--r--include/asm-m32r/unistd.h66
-rw-r--r--include/asm-mips/cpu-features.h6
-rw-r--r--include/asm-mips/system.h2
-rw-r--r--include/linux/ext2_fs.h7
-rw-r--r--include/linux/fuse.h5
-rw-r--r--include/linux/kd.h2
-rw-r--r--include/linux/pnp.h4
-rw-r--r--include/linux/rtc.h5
-rw-r--r--include/linux/sched.h4
-rw-r--r--include/linux/screen_info.h2
-rw-r--r--include/linux/serial_core.h2
-rw-r--r--include/linux/usb.h1
-rw-r--r--include/linux/usbdevice_fs.h3
-rw-r--r--ipc/mqueue.c6
-rw-r--r--kernel/exit.c11
-rw-r--r--kernel/kallsyms.c7
-rw-r--r--kernel/sched.c5
-rw-r--r--kernel/sched_debug.c8
-rw-r--r--kernel/sched_stats.h3
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/utsname_sysctl.c4
-rw-r--r--lib/hexdump.c3
-rw-r--r--lib/kobject.c4
-rw-r--r--mm/page_alloc.c24
-rw-r--r--mm/shmem.c5
-rw-r--r--mm/slab.c4
-rw-r--r--mm/sparse-vmemmap.c12
-rwxr-xr-xscripts/checkpatch.pl395
-rw-r--r--security/commoncap.c9
178 files changed, 2281 insertions, 1197 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 299615d821a..c3014df066c 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -262,6 +262,8 @@ mtrr.txt
- how to use PPro Memory Type Range Registers to increase performance.
mutex-design.txt
- info on the generic mutex subsystem.
+namespaces/
+ - directory with various information about namespaces
nbd.txt
- info on a TCP implementation of a network block device.
netlabel/
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 054a7ecf64c..4953bc25872 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -11,7 +11,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
procfs-guide.xml writing_usb_driver.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
- genericirq.xml s390-drivers.xml
+ genericirq.xml s390-drivers.xml uio-howto.xml
###
# The build process is as follows (targets):
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index c119484258b..fdd7f4f887b 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -30,6 +30,12 @@
<revhistory>
<revision>
+ <revnumber>0.4</revnumber>
+ <date>2007-11-26</date>
+ <authorinitials>hjk</authorinitials>
+ <revremark>Removed section about uio_dummy.</revremark>
+ </revision>
+ <revision>
<revnumber>0.3</revnumber>
<date>2007-04-29</date>
<authorinitials>hjk</authorinitials>
@@ -94,6 +100,26 @@ interested in translating it, please email me
user space. This simplifies development and reduces the risk of
serious bugs within a kernel module.
</para>
+ <para>
+ Please note that UIO is not an universal driver interface. Devices
+ that are already handled well by other kernel subsystems (like
+ networking or serial or USB) are no candidates for an UIO driver.
+ Hardware that is ideally suited for an UIO driver fulfills all of
+ the following:
+ </para>
+<itemizedlist>
+<listitem>
+ <para>The device has memory that can be mapped. The device can be
+ controlled completely by writing to this memory.</para>
+</listitem>
+<listitem>
+ <para>The device usually generates interrupts.</para>
+</listitem>
+<listitem>
+ <para>The device does not fit into one of the standard kernel
+ subsystems.</para>
+</listitem>
+</itemizedlist>
</sect1>
<sect1 id="thanks">
@@ -174,8 +200,9 @@ interested in translating it, please email me
For cards that don't generate interrupts but need to be
polled, there is the possibility to set up a timer that
triggers the interrupt handler at configurable time intervals.
- See <filename>drivers/uio/uio_dummy.c</filename> for an
- example of this technique.
+ This interrupt simulation is done by calling
+ <function>uio_event_notify()</function>
+ from the timer's event handler.
</para>
<para>
@@ -263,63 +290,11 @@ offset = N * getpagesize();
</sect1>
</chapter>
-<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
-<?dbhtml filename="using-uio_dummy.html"?>
-<title>Using uio_dummy</title>
- <para>
- Well, there is no real use for uio_dummy. Its only purpose is
- to test most parts of the UIO system (everything except
- hardware interrupts), and to serve as an example for the
- kernel module that you will have to write yourself.
- </para>
-
-<sect1 id="what_uio_dummy_does">
-<title>What uio_dummy does</title>
- <para>
- The kernel module <filename>uio_dummy.ko</filename> creates a
- device that uses a timer to generate periodic interrupts. The
- interrupt handler does nothing but increment a counter. The
- driver adds two custom attributes, <varname>count</varname>
- and <varname>freq</varname>, that appear under
- <filename>/sys/devices/platform/uio_dummy/</filename>.
- </para>
-
- <para>
- The attribute <varname>count</varname> can be read and
- written. The associated file
- <filename>/sys/devices/platform/uio_dummy/count</filename>
- appears as a normal text file and contains the total number of
- timer interrupts. If you look at it (e.g. using
- <function>cat</function>), you'll notice it is slowly counting
- up.
- </para>
-
- <para>
- The attribute <varname>freq</varname> can be read and written.
- The content of
- <filename>/sys/devices/platform/uio_dummy/freq</filename>
- represents the number of system timer ticks between two timer
- interrupts. The default value of <varname>freq</varname> is
- the value of the kernel variable <varname>HZ</varname>, which
- gives you an interval of one second. Lower values will
- increase the frequency. Try the following:
- </para>
-<programlisting format="linespecific">
-cd /sys/devices/platform/uio_dummy/
-echo 100 > freq
-</programlisting>
- <para>
- Use <function>cat count</function> to see how the interrupt
- frequency changes.
- </para>
-</sect1>
-</chapter>
-
<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
<?dbhtml filename="custom_kernel_module.html"?>
<title>Writing your own kernel module</title>
<para>
- Please have a look at <filename>uio_dummy.c</filename> as an
+ Please have a look at <filename>uio_cif.c</filename> as an
example. The following paragraphs explain the different
sections of this file.
</para>
@@ -354,9 +329,8 @@ See the description below for details.
interrupt, it's your modules task to determine the irq number during
initialization. If you don't have a hardware generated interrupt but
want to trigger the interrupt handler in some other way, set
-<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The
-uio_dummy module does this as it triggers the event mechanism in a timer
-routine. If you had no interrupt at all, you could set
+<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>.
+If you had no interrupt at all, you could set
<varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
rarely makes sense.
</para></listitem>
diff --git a/Documentation/namespaces/compatibility-list.txt b/Documentation/namespaces/compatibility-list.txt
new file mode 100644
index 00000000000..defc5589bfc
--- /dev/null
+++ b/Documentation/namespaces/compatibility-list.txt
@@ -0,0 +1,39 @@
+ Namespaces compatibility list
+
+This document contains the information about the problems user
+may have when creating tasks living in different namespaces.
+
+Here's the summary. This matrix shows the known problems, that
+occur when tasks share some namespace (the columns) while living
+in different other namespaces (the rows):
+
+ UTS IPC VFS PID User Net
+UTS X
+IPC X 1
+VFS X
+PID 1 1 X
+User 2 2 X
+Net X
+
+1. Both the IPC and the PID namespaces provide IDs to address
+ object inside the kernel. E.g. semaphore with IPCID or
+ process group with pid.
+
+ In both cases, tasks shouldn't try exposing this ID to some
+ other task living in a different namespace via a shared filesystem
+ or IPC shmem/message. The fact is that this ID is only valid
+ within the namespace it was obtained in and may refer to some
+ other object in another namespace.
+
+2. Intentionally, two equal user IDs in different user namespaces
+ should not be equal from the VFS point of view. In other
+ words, user 10 in one user namespace shouldn't have the same
+ access permissions to files, belonging to user 10 in another
+ namespace.
+
+ The same is true for the IPC namespaces being shared - two users
+ from different user namespaces should not access the same IPC objects
+ even having equal UIDs.
+
+ But currently this is not so.
+
diff --git a/Documentation/tty.txt b/Documentation/tty.txt
index 048a8762cfb..8e65c4498c5 100644
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -132,6 +132,14 @@ set_termios() Notify the tty driver that the device's termios
tty->termios. Previous settings should be passed in
the "old" argument.
+ The API is defined such that the driver should return
+ the actual modes selected. This means that the
+ driver function is responsible for modifying any
+ bits in the request it cannot fulfill to indicate
+ the actual modes being used. A device with no
+ hardware capability for change (eg a USB dongle or
+ virtual port) can provide NULL for this method.
+
throttle() Notify the tty driver that input buffers for the
line discipline are close to full, and it should
somehow signal that no more characters should be
diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt
index 97842deec47..b2fc4d4a991 100644
--- a/Documentation/usb/power-management.txt
+++ b/Documentation/usb/power-management.txt
@@ -278,6 +278,14 @@ optional. The methods' jobs are quite simple:
(although the interfaces will be in the same altsettings as
before the suspend).
+If the device is disconnected or powered down while it is suspended,
+the disconnect method will be called instead of the resume or
+reset_resume method. This is also quite likely to happen when
+waking up from hibernation, as many systems do not maintain suspend
+current to the USB host controllers during hibernation. (It's
+possible to work around the hibernation-forces-disconnect problem by
+using the USB Persist facility.)
+
The reset_resume method is used by the USB Persist facility (see
Documentation/usb/persist.txt) and it can also be used under certain
circumstances when CONFIG_USB_PERSIST is not enabled. Currently, if a
diff --git a/Documentation/x86_64/uefi.txt b/Documentation/x86_64/uefi.txt
new file mode 100644
index 00000000000..91a98edfb58
--- /dev/null
+++ b/Documentation/x86_64/uefi.txt
@@ -0,0 +1,29 @@
+General note on [U]EFI x86_64 support
+-------------------------------------
+
+The nomenclature EFI and UEFI are used interchangeably in this document.
+
+Although the tools below are _not_ needed for building the kernel,
+the needed bootloader support and associated tools for x86_64 platforms
+with EFI firmware and specifications are listed below.
+
+1. UEFI specification: http://www.uefi.org
+
+2. Booting Linux kernel on UEFI x86_64 platform requires bootloader
+ support. Elilo with x86_64 support can be used.
+
+3. x86_64 platform with EFI/UEFI firmware.
+
+Mechanics:
+---------
+- Build the kernel with the following configuration.
+ CONFIG_FB_EFI=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+- Create a VFAT partition on the disk
+- Copy the following to the VFAT partition:
+ elilo bootloader with x86_64 support, elilo configuration file,
+ kernel image built in first step and corresponding
+ initrd. Instructions on building elilo and its dependencies
+ can be found in the elilo sourceforge project.
+- Boot to EFI shell and invoke elilo choosing the kernel image built
+ in first step.
diff --git a/MAINTAINERS b/MAINTAINERS
index f5bd9bab7ed..7c8392e1797 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -323,8 +323,7 @@ S: Maintained
ALCATEL SPEEDTOUCH USB DRIVER
P: Duncan Sands
M: duncan.sands@free.fr
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org/SpeedTouch/
S: Maintained
@@ -440,7 +439,7 @@ S: Maintained
ARM/ATMEL AT91RM9200 ARM ARCHITECTURE
P: Andrew Victor
-M: andrew@sanpeople.com
+M: linux@maxim.org.za
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://maxim.org.za/at91_26.html
S: Maintained
@@ -1043,7 +1042,7 @@ S: Maintained
CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
P: Lennert Buytenhek
M: kernel@wantstofly.org
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER
@@ -1552,7 +1551,7 @@ S: Maintained
FREESCALE HIGHSPEED USB DEVICE DRIVER
P: Li Yang
M: leoli@freescale.com
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: linuxppc-dev@ozlabs.org
S: Maintained
@@ -2111,6 +2110,14 @@ L: irda-users@lists.sourceforge.net (subscribers-only)
W: http://irda.sourceforge.net/
S: Maintained
+ISCSI
+P: Mike Christie
+M: michaelc@cs.wisc.edu
+L: open-iscsi@googlegroups.com
+W: www.open-iscsi.org
+T: git kernel.org:/pub/scm/linux/kernel/mnc/linux-2.6-iscsi.git
+S: Maintained
+
ISAPNP
P: Jaroslav Kysela
M: perex@perex.cz
@@ -3810,22 +3817,20 @@ S: Maintained
USB ACM DRIVER
P: Oliver Neukum
M: oliver@neukum.name
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB BLOCK DRIVER (UB ub)
P: Pete Zaitcev
M: zaitcev@redhat.com
L: linux-kernel@vger.kernel.org
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Supported
USB CDC ETHERNET DRIVER
P: Greg Kroah-Hartman
M: greg@kroah.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
W: http://www.kroah.com/linux-usb/
@@ -3839,13 +3844,13 @@ S: Maintained
USB EHCI DRIVER
P: David Brownell
M: dbrownell@users.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Odd Fixes
USB ET61X[12]51 DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com
W: http://www.linux-projects.org
S: Maintained
@@ -3853,41 +3858,33 @@ S: Maintained
USB GADGET/PERIPHERAL SUBSYSTEM
P: David Brownell
M: dbrownell@users.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org/gadget
S: Maintained
USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
P: Jiri Kosina
M: jkosina@suse.cz
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git
S: Maintained
-USB HUB DRIVER
-P: Johannes Erdfelt
-M: johannes@erdfelt.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
-S: Maintained
-
USB ISP116X DRIVER
P: Olav Kongas
M: ok@artecdesign.ee
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB KAWASAKI LSI DRIVER
P: Oliver Neukum
M: oliver@neukum.name
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB MASS STORAGE DRIVER
P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net
-L: linux-usb-users@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: usb-storage@lists.one-eyed-alien.net
S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
@@ -3895,28 +3892,26 @@ W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
USB OHCI DRIVER
P: David Brownell
M: dbrownell@users.sourceforge.net
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Odd Fixes
USB OPTION-CARD DRIVER
P: Matthias Urlichs
M: smurf@smurf.noris.de
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB OV511 DRIVER
P: Mark McClelland
M: mmcclell@bigfoot.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://alpha.dyndns.org/ov511/
S: Maintained
USB PEGASUS DRIVER
P: Petko Manolov
M: petkan@users.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: netdev@vger.kernel.org
W: http://pegasus2.sourceforge.net/
S: Maintained
@@ -3924,14 +3919,13 @@ S: Maintained
USB PRINTER DRIVER (usblp)
P: Pete Zaitcev
M: zaitcev@redhat.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Supported
USB RTL8150 DRIVER
P: Petko Manolov
M: petkan@users.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: netdev@vger.kernel.org
W: http://pegasus2.sourceforge.net/
S: Maintained
@@ -3939,8 +3933,7 @@ S: Maintained
USB SE401 DRIVER
P: Jeroen Vreeken
M: pe1rxq@amsat.org
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://www.chello.nl/~j.vreeken/se401/
S: Maintained
@@ -3954,72 +3947,59 @@ USB SERIAL DIGI ACCELEPORT DRIVER
P: Peter Berger and Al Borchers
M: pberger@brimson.com
M: alborchers@steinerpoint.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB SERIAL DRIVER
P: Greg Kroah-Hartman
M: gregkh@suse.de
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Supported
USB SERIAL BELKIN F5U103 DRIVER
P: William Greathouse
M: wgreathouse@smva.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB SERIAL CYPRESS M8 DRIVER
P: Lonnie Mendez
M: dignome@gmail.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
W: http://geocities.com/i0xox0i
W: http://firstlight.net/cvs
-USB SERIAL CYBERJACK PINPAD/E-COM DRIVER
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
-S: Maintained
-
USB AUERSWALD DRIVER
P: Wolfgang Muees
M: wolfgang@iksw-muees.de
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
P: Gary Brubaker
M: xavyer@ix.netcom.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB SERIAL KEYSPAN DRIVER
P: Greg Kroah-Hartman
M: greg@kroah.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://www.kroah.com/linux/
S: Maintained
USB SERIAL WHITEHEAT DRIVER
P: Support Department
M: support@connecttech.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://www.connecttech.com
S: Supported
USB SN9C1xx DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com
W: http://www.linux-projects.org
S: Maintained
@@ -4027,8 +4007,7 @@ S: Maintained
USB SUBSYSTEM
P: Greg Kroah-Hartman
M: gregkh@suse.de
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
@@ -4036,8 +4015,7 @@ S: Supported
USB UHCI DRIVER
P: Alan Stern
M: stern@rowland.harvard.edu
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
S: Maintained
USB "USBNET" DRIVER FRAMEWORK
@@ -4050,7 +4028,7 @@ S: Maintained
USB W996[87]CF DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com
W: http://www.linux-projects.org
S: Maintained
@@ -4058,7 +4036,7 @@ S: Maintained
USB ZC0301 DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com
W: http://www.linux-projects.org
S: Maintained
@@ -4066,15 +4044,14 @@ S: Maintained
USB ZD1201 DRIVER
P: Jeroen Vreeken
M: pe1rxq@amsat.org
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
W: http://linux-lc100020.sourceforge.net
S: Maintained
USB ZR364XX DRIVER
P: Antoine Jacquet
M: royale@zerezo.com
-L: linux-usb-devel@lists.sourceforge.net
+L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com
W: http://royale.zerezo.com/zr364xx/
S: Maintained
diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c
index 95c8508c29b..117cab30bd3 100644
--- a/arch/arm/common/uengine.c
+++ b/arch/arm/common/uengine.c
@@ -374,8 +374,8 @@ static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
u8 *ucode;
int i;
- gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL);
- gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL);
+ 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);
@@ -388,8 +388,6 @@ static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
per_ctx_regs = 32;
- memset(gpr_a, 0, sizeof(gpr_a));
- memset(gpr_b, 0, sizeof(gpr_b));
for (i = 0; i < 256; i++) {
struct ixp2000_reg_value *r = c->initial_reg_values + i;
u32 *bank;
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index d645897652c..29dec080a60 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -339,16 +339,6 @@ __pabt_svc:
str r1, [sp] @ save the "real" r0 copied
@ from the exception stack
-#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
-#ifndef CONFIG_MMU
-#warning "NPTL on non MMU needs fixing"
-#else
- @ make sure our user space atomic helper is aborted
- cmp r2, #TASK_SIZE
- bichs r3, r3, #PSR_Z_BIT
-#endif
-#endif
-
@
@ We are now ready to fill in the remaining blanks on the stack:
@
@@ -372,9 +362,25 @@ __pabt_svc:
zero_fp
.endm
+ .macro kuser_cmpxchg_check
+#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
+ @ Make sure our user space atomic helper is restarted
+ @ if it was interrupted in a critical region. Here we
+ @ perform a quick test inline since it should be false
+ @ 99.9999% of the time. The rest is done out of line.
+ cmp r2, #TASK_SIZE
+ blhs kuser_cmpxchg_fixup
+#endif
+#endif
+ .endm
+
.align 5
__dabt_usr:
usr_entry
+ kuser_cmpxchg_check
@
@ Call the processor-specific abort handler:
@@ -404,6 +410,7 @@ __dabt_usr:
.align 5
__irq_usr:
usr_entry
+ kuser_cmpxchg_check
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_off
@@ -446,9 +453,9 @@ __und_usr:
@
@ r0 - instruction
@
-1: ldrt r0, [r4]
adr r9, ret_from_exception
adr lr, __und_usr_unknown
+1: ldrt r0, [r4]
@
@ fallthrough to call_fpe
@
@@ -669,7 +676,7 @@ __kuser_helper_start:
*
* Clobbered:
*
- * the Z flag might be lost
+ * none
*
* Definition and user space usage example:
*
@@ -730,9 +737,6 @@ __kuser_memory_barrier: @ 0xffff0fa0
*
* - This routine already includes memory barriers as needed.
*
- * - A failure might be transient, i.e. it is possible, although unlikely,
- * that "failure" be returned even if *ptr == oldval.
- *
* For example, a user space atomic_add implementation could look like this:
*
* #define atomic_add(ptr, val) \
@@ -769,46 +773,62 @@ __kuser_cmpxchg: @ 0xffff0fc0
#elif __LINUX_ARM_ARCH__ < 6
+#ifdef CONFIG_MMU
+
/*
- * Theory of operation:
- *
- * We set the Z flag before loading oldval. If ever an exception
- * occurs we can not be sure the loaded value will still be the same
- * when the exception returns, therefore the user exception handler
- * will clear the Z flag whenever the interrupted user code was
- * actually from the kernel address space (see the usr_entry macro).
- *
- * The post-increment on the str is used to prevent a race with an
- * exception happening just after the str instruction which would
- * clear the Z flag although the exchange was done.
+ * The only thing that can break atomicity in this cmpxchg
+ * implementation is either an IRQ or a data abort exception
+ * causing another process/thread to be scheduled in the middle
+ * of the critical sequence. To prevent this, code is added to
+ * the IRQ and data abort exception handlers to set the pc back
+ * to the beginning of the critical section if it is found to be
+ * within that critical section (see kuser_cmpxchg_fixup).
*/
-#ifdef CONFIG_MMU
- teq ip, ip @ set Z flag
- ldr ip, [r2] @ load current val
- add r3, r2, #1 @ prepare store ptr
- teqeq ip, r0 @ compare with oldval if still allowed
- streq r1, [r3, #-1]! @ store newval if still allowed
- subs r0, r2, r3 @ if r2 == r3 the str occured
+1: ldr r3, [r2] @ load current val
+ subs r3, r3, r0 @ compare with oldval
+2: streq r1, [r2] @ store newval if eq
+ rsbs r0, r3, #0 @ set return val and C flag
+ usr_ret lr
+
+ .text
+kuser_cmpxchg_fixup:
+ @ Called from kuser_cmpxchg_check macro.
+ @ r2 = address of interrupted insn (must be preserved).
+ @ sp = saved regs. r7 and r8 are clobbered.
+ @ 1b = first critical insn, 2b = last critical insn.
+ @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
+ mov r7, #0xffff0fff
+ sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
+ subs r8, r2, r7
+ rsbcss r8, r8, #(2b - 1b)
+ strcs r7, [sp, #S_PC]
+ mov pc, lr
+ .previous
+
#else
#warning "NPTL on non MMU needs fixing"
mov r0, #-1
adds r0, r0, #0
-#endif
usr_ret lr
+#endif
#else
#ifdef CONFIG_SMP
mcr p15, 0, r0, c7, c10, 5 @ dmb
#endif
- ldrex r3, [r2]
+1: ldrex r3, [r2]
subs r3, r3, r0
strexeq r3, r1, [r2]
+ teqeq r3, #1
+ beq 1b
rsbs r0, r3, #0
+ /* beware -- each __kuser slot must be 8 instructions max */
#ifdef CONFIG_SMP
- mcr p15, 0, r0, c7, c10, 5 @ dmb
-#endif
+ b __kuser_memory_barrier
+#else
usr_ret lr
+#endif
#endif
@@ -829,7 +849,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
*
* Clobbered:
*
- * the Z flag might be lost
+ * none
*
* Definition and user space usage example:
*
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 4764bd9ccee..c34db4e868f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -327,7 +327,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
if ((instr & hook->instr_mask) == hook->instr_val &&
(regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
if (hook->fn(regs, instr) == 0) {
- spin_unlock_irq(&undef_lock);
+ spin_unlock_irqrestore(&undef_lock, flags);
return;
}
}
@@ -509,7 +509,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
* existence. Don't ever use this from user code.
*/
case 0xfff0:
- {
+ for (;;) {
extern void do_DataAbort(unsigned long addr, unsigned int fsr,
struct pt_regs *regs);
unsigned long val;
@@ -545,7 +545,6 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
up_read(&mm->mmap_sem);
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
- return -1;
}
#endif
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 0417c165d50..9296833f91c 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -14,6 +14,7 @@
#include <asm/mach/map.h>
#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
@@ -435,7 +436,40 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA25,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA26,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91rm9200_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA25, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA25, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA26, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA26, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91rm9200_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
static struct resource twi_resources[] = {
[0] = {
@@ -457,7 +491,7 @@ static struct platform_device at91rm9200_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */
@@ -466,10 +500,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PA26, 1);
+ i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91rm9200_twi_device);
}
#else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index ffd3154c1e5..3091bf47d8c 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -13,6 +13,7 @@
#include <asm/mach/map.h>
#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
@@ -352,7 +353,41 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA23,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA24,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9260_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9260_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
static struct resource twi_resources[] = {
[0] = {
@@ -374,7 +409,7 @@ static struct platform_device at91sam9260_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */
@@ -383,10 +418,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PA24, 1);
+ i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9260_twi_device);
}
#else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 3576595b494..64979a9023c 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -14,7 +14,9 @@
#include <asm/mach/map.h>
#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+#include <linux/fb.h>
#include <video/atmel_lcdc.h>
#include <asm/arch/board.h>
@@ -275,7 +277,40 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA7,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA8,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9261_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA7, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA7, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA8, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA8, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9261_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
static struct resource twi_resources[] = {
[0] = {
@@ -297,7 +332,7 @@ static struct platform_device at91sam9261_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */
@@ -306,10 +341,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PA8, 1);
+ i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9261_twi_device);
}
#else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index f924bd5017d..ac329a98e95 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -13,7 +13,9 @@
#include <asm/mach/map.h>
#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+#include <linux/fb.h>
#include <video/atmel_lcdc.h>
#include <asm/arch/board.h>
@@ -421,7 +423,40 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PB4,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PB5,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9263_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9263_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
static struct resource twi_resources[] = {
[0] = {
@@ -443,7 +478,7 @@ static struct platform_device at91sam9263_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */
@@ -452,10 +487,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PB5, 1);
+ i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9263_twi_device);
}
#else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index cd7532bcd4e..2bd60a3dc62 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -10,8 +10,9 @@
#include <asm/mach/map.h>
#include <linux/platform_device.h>
-#include <linux/fb.h>
+#include <linux/i2c-gpio.h>
+#include <linux/fb.h>
#include <video/atmel_lcdc.h>
#include <asm/arch/board.h>
@@ -169,7 +170,40 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA23,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA24,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9rl_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9rl_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
static struct resource twi_resources[] = {
[0] = {
@@ -191,7 +225,7 @@ static struct platform_device at91sam9rl_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */
@@ -200,10 +234,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PA24, 1);
+ i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9rl_twi_device);
}
#else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index 76ec856cd4f..0f0878294a6 100644
--- a/arch/arm/mach-at91/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -128,7 +128,7 @@ static void __init carmeva_board_init(void)
/* USB Device */
at91_add_device_udc(&carmeva_udc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* SPI */
at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices));
/* Compact Flash */
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index dde089922e3..d0aa20c9383 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -23,7 +23,6 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/mtd/physmap.h>
@@ -85,12 +84,12 @@ static struct at91_udc_data __initdata csb337_udc_data = {
};
static struct i2c_board_info __initdata csb337_i2c_devices[] = {
- { I2C_BOARD_INFO("rtc-ds1307", 0x68),
- .type = "ds1307",
+ {
+ I2C_BOARD_INFO("rtc-ds1307", 0x68),
+ .type = "ds1307",
},
};
-
static struct at91_cf_data __initdata csb337_cf_data = {
/*
* connector P4 on the CSB 337 mates to
@@ -168,9 +167,7 @@ static void __init csb337_board_init(void)
/* USB Device */
at91_add_device_udc(&csb337_udc_data);
/* I2C */
- at91_add_device_i2c();
- i2c_register_board_info(0, csb337_i2c_devices,
- ARRAY_SIZE(csb337_i2c_devices));
+ at91_add_device_i2c(csb337_i2c_devices, ARRAY_SIZE(csb337_i2c_devices));
/* Compact Flash */
at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */
at91_add_device_cf(&csb337_cf_data);
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index 77f04b935b3..c5c721d27f4 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -129,7 +129,7 @@ static void __init csb637_board_init(void)
/* USB Device */
at91_add_device_udc(&csb637_udc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* SPI */
at91_add_device_spi(NULL, 0);
/* NOR flash */
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index af497896a96..40c9e433170 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -124,6 +124,19 @@ static struct spi_board_info dk_spi_devices[] = {
#endif
};
+static struct i2c_board_info __initdata dk_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ics1523", 0x26),
+ },
+ {
+ I2C_BOARD_INFO("x9429", 0x28),
+ },
+ {
+ I2C_BOARD_INFO("at24c", 0x50),
+ .type = "24c1024",
+ }
+};
+
static struct mtd_partition __initdata dk_nand_partition[] = {
{
.name = "NAND Partition 1",
@@ -185,7 +198,7 @@ static void __init dk_board_init(void)
/* Compact Flash */
at91_add_device_cf(&dk_cf_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
/* SPI */
at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index 20458b5548f..b7b79bb9d6c 100644
--- a/arch/arm/mach-at91/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -91,6 +91,14 @@ static struct at91_mmc_data __initdata eb9200_mmc_data = {
.wire4 = 1,
};
+static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24c", 0x50),
+ .type = "24c512",
+ },
+};
+
+
static void __init eb9200_board_init(void)
{
/* Serial */
@@ -102,7 +110,7 @@ static void __init eb9200_board_init(void)
/* USB Device */
at91_add_device_udc(&eb9200_udc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(eb9200_i2c_devices, ARRAY_SIZE(eb9200_i2c_devices));
/* Compact Flash */
at91_add_device_cf(&eb9200_cf_data);
/* SPI */
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 322fdd75a1e..d05b1b2be9f 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -145,7 +145,7 @@ static void __init ek_board_init(void)
at91_add_device_udc(&ek_udc_data);
at91_set_multi_drive(ek_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
/* SPI */
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
index c77d84ce9ca..cf1b7b2f76f 100644
--- a/arch/arm/mach-at91/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -92,7 +92,7 @@ static void __init kafa_board_init(void)
/* USB Device */
at91_add_device_udc(&kafa_udc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* SPI */
at91_add_device_spi(NULL, 0);
}
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index 7d9b1a278fd..4b39b9cda75 100644
--- a/arch/arm/mach-at91/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -124,7 +124,7 @@ static void __init kb9202_board_init(void)
/* MMC */
at91_add_device_mmc(0, &kb9202_mmc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* SPI */
at91_add_device_spi(NULL, 0);
/* NAND */
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
index 49cfe7ab4a8..6acb55c09ae 100644
--- a/arch/arm/mach-at91/board-picotux200.c
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -139,7 +139,7 @@ static void __init picotux200_board_init(void)
// at91_add_device_udc(&picotux200_udc_data);
// at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* SPI */
// at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 65fa532bb4a..b343a6c2812 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -189,7 +189,7 @@ static void __init ek_board_init(void)
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
}
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 42e172cb0f4..550ae59a3ac 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -382,14 +382,14 @@ static struct platform_device ek_button_device = {
static void __init ek_add_device_buttons(void)
{
- at91_set_gpio_input(AT91_PIN_PB27, 0); /* btn0 */
- at91_set_deglitch(AT91_PIN_PB27, 1);
- at91_set_gpio_input(AT91_PIN_PB26, 0); /* btn1 */
- at91_set_deglitch(AT91_PIN_PB26, 1);
- at91_set_gpio_input(AT91_PIN_PB25, 0); /* btn2 */
- at91_set_deglitch(AT91_PIN_PB25, 1);
- at91_set_gpio_input(AT91_PIN_PB24, 0); /* btn3 */
- at91_set_deglitch(AT91_PIN_PB24, 1);
+ at91_set_gpio_input(AT91_PIN_PA27, 0); /* btn0 */
+ at91_set_deglitch(AT91_PIN_PA27, 1);
+ at91_set_gpio_input(AT91_PIN_PA26, 0); /* btn1 */
+ at91_set_deglitch(AT91_PIN_PA26, 1);
+ at91_set_gpio_input(AT91_PIN_PA25, 0); /* btn2 */
+ at91_set_deglitch(AT91_PIN_PA25, 1);
+ at91_set_gpio_input(AT91_PIN_PA24, 0); /* btn3 */
+ at91_set_deglitch(AT91_PIN_PA24, 1);
platform_device_register(&ek_button_device);
}
@@ -406,7 +406,7 @@ static void __init ek_board_init(void)
/* USB Device */
at91_add_device_udc(&ek_udc_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* NAND */
at91_add_device_nand(&ek_nand_data);
/* DM9000 ethernet */
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 2a1cc73390b..ab9dcc07545 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -291,7 +291,7 @@ static void __init ek_board_init(void)
/* NAND */
at91_add_device_nand(&ek_nand_data);
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* LCD Controller */
at91_add_device_lcdc(&ek_lcdc_data);
/* AC97 */
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index 9b61320f295..bc0546d7245 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -181,7 +181,7 @@ static void __init ek_board_init(void)
/* Serial */
at91_add_device_serial();
/* I2C */
- at91_add_device_i2c();
+ at91_add_device_i2c(NULL, 0);
/* NAND */
at91_add_device_nand(&ek_nand_data);
/* SPI */
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 848efb2a4eb..57c3b647ce8 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -351,7 +351,7 @@ static void init_programmable_clock(struct clk *clk)
pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
clk->parent = parent;
- clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
+ clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2));
}
#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -587,8 +587,11 @@ int __init at91_clock_init(unsigned long main_clock)
mckr = at91_sys_read(AT91_PMC_MCKR);
mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
freq = mck.parent->rate_hz;
- freq /= (1 << ((mckr >> 2) & 3)); /* prescale */
- mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */
+ freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */
+ if (cpu_is_at91rm9200())
+ mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
+ else
+ mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
/* Register the PMC's standard clocks */
for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c
index 0791b56caec..a7465db8489 100644
--- a/arch/arm/mach-imx/irq.c
+++ b/arch/arm/mach-imx/irq.c
@@ -43,12 +43,46 @@
*
*/
-#define INTENNUM_OFF 0x8
-#define INTDISNUM_OFF 0xC
+#define INTCNTL_OFF 0x00
+#define NIMASK_OFF 0x04
+#define INTENNUM_OFF 0x08
+#define INTDISNUM_OFF 0x0C
+#define INTENABLEH_OFF 0x10
+#define INTENABLEL_OFF 0x14
+#define INTTYPEH_OFF 0x18
+#define INTTYPEL_OFF 0x1C
+#define NIPRIORITY_OFF(x) (0x20+4*(7-(x)))
+#define NIVECSR_OFF 0x40
+#define FIVECSR_OFF 0x44
+#define INTSRCH_OFF 0x48
+#define INTSRCL_OFF 0x4C
+#define INTFRCH_OFF 0x50
+#define INTFRCL_OFF 0x54
+#define NIPNDH_OFF 0x58
+#define NIPNDL_OFF 0x5C
+#define FIPNDH_OFF 0x60
+#define FIPNDL_OFF 0x64
#define VA_AITC_BASE IO_ADDRESS(IMX_AITC_BASE)
-#define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF)
+#define IMX_AITC_INTCNTL (VA_AITC_BASE + INTCNTL_OFF)
+#define IMX_AITC_NIMASK (VA_AITC_BASE + NIMASK_OFF)
#define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF)
+#define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF)
+#define IMX_AITC_INTENABLEH (VA_AITC_BASE + INTENABLEH_OFF)
+#define IMX_AITC_INTENABLEL (VA_AITC_BASE + INTENABLEL_OFF)
+#define IMX_AITC_INTTYPEH (VA_AITC_BASE + INTTYPEH_OFF)
+#define IMX_AITC_INTTYPEL (VA_AITC_BASE + INTTYPEL_OFF)
+#define IMX_AITC_NIPRIORITY(x) (VA_AITC_BASE + NIPRIORITY_OFF(x))
+#define IMX_AITC_NIVECSR (VA_AITC_BASE + NIVECSR_OFF)
+#define IMX_AITC_FIVECSR (VA_AITC_BASE + FIVECSR_OFF)
+#define IMX_AITC_INTSRCH (VA_AITC_BASE + INTSRCH_OFF)
+#define IMX_AITC_INTSRCL (VA_AITC_BASE + INTSRCL_OFF)
+#define IMX_AITC_INTFRCH (VA_AITC_BASE + INTFRCH_OFF)
+#define IMX_AITC_INTFRCL (VA_AITC_BASE + INTFRCL_OFF)
+#define IMX_AITC_NIPNDH (VA_AITC_BASE + NIPNDH_OFF)
+#define IMX_AITC_NIPNDL (VA_AITC_BASE + NIPNDL_OFF)
+#define IMX_AITC_FIPNDH (VA_AITC_BASE + FIPNDH_OFF)
+#define IMX_AITC_FIPNDL (VA_AITC_BASE + FIPNDL_OFF)
#if 0
#define DEBUG_IRQ(fmt...) printk(fmt)
@@ -222,7 +256,12 @@ imx_init_irq(void)
DEBUG_IRQ("Initializing imx interrupts\n");
- /* Mask all interrupts initially */
+ /* Disable all interrupts initially. */
+ /* Do not rely on the bootloader. */
+ __raw_writel(0, IMX_AITC_INTENABLEH);
+ __raw_writel(0, IMX_AITC_INTENABLEL);
+
+ /* Mask all GPIO interrupts as well */
IMR(0) = 0;
IMR(1) = 0;
IMR(2) = 0;
@@ -245,6 +284,6 @@ imx_init_irq(void)
set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler);
set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler);
- /* Disable all interrupts initially. */
- /* In IMX this is done in the bootloader. */
+ /* Release masking of interrupts according to priority */
+ __raw_writel(-1, IMX_AITC_NIMASK);
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index d0f2b597db1..8e126e6b74c 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -146,7 +146,7 @@ static struct clk pxa27x_clks[] = {
INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev),
INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev),
- INIT_CKEN("USBCLK", USB, 48000000, 0, &pxa27x_device_ohci.dev),
+ INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev),
INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
index 1010f77d977..74128eb8f8d 100644
--- a/arch/arm/mach-pxa/pxa320.c
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -23,8 +23,11 @@
static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
MFP_ADDR_X(GPIO0, GPIO4, 0x0124),
- MFP_ADDR_X(GPIO5, GPIO26, 0x028C),
- MFP_ADDR_X(GPIO27, GPIO62, 0x0400),
+ MFP_ADDR_X(GPIO5, GPIO9, 0x028C),
+ MFP_ADDR(GPIO10, 0x0458),
+ MFP_ADDR_X(GPIO11, GPIO26, 0x02A0),
+ MFP_ADDR_X(GPIO27, GPIO48, 0x0400),
+ MFP_ADDR_X(GPIO49, GPIO62, 0x045C),
MFP_ADDR_X(GPIO63, GPIO73, 0x04B4),
MFP_ADDR_X(GPIO74, GPIO98, 0x04F0),
MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 71766ac0328..422afee8816 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -309,6 +309,7 @@ void ssp_exit(struct ssp_dev *dev)
if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
printk(KERN_WARNING "SSP: tried to close invalid port\n");
+ mutex_unlock(&mutex);
return;
}
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
index dac4a5f68c2..bd0bdf908d9 100644
--- a/arch/frv/kernel/break.S
+++ b/arch/frv/kernel/break.S
@@ -63,7 +63,7 @@ __break_trace_through_exceptions:
# entry point for Break Exceptions/Interrupts
#
###############################################################################
- .text
+ .section .text.break
.balign 4
.globl __entry_break
__entry_break:
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 1e74f3c5cee..f926c709477 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -38,7 +38,7 @@
#define nr_syscalls ((syscall_table_size)/4)
- .text
+ .section .text.entry
.balign 4
.macro LEDS val
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index 3b71e0c8639..a17a81d58bf 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -76,6 +76,12 @@ SECTIONS
*(.data.init_task)
}
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(L1_CACHE_BYTES);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
.trap : {
/* trap table management - read entry-table.S before modifying */
. = ALIGN(8192);
@@ -86,28 +92,25 @@ SECTIONS
*(.trap.break)
}
- . = ALIGN(4096);
- .data.page_aligned : { *(.data.idt) }
-
- . = ALIGN(L1_CACHE_BYTES);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
/* Text and read-only data */
. = ALIGN(4);
_text = .;
_stext = .;
.text : {
- *(
- .text.start .text.*
+ *(.text.start)
+ *(.text.entry)
+ *(.text.break)
+ *(.text.tlbmiss)
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
#ifdef CONFIG_DEBUG_INFO
+ *(
.init.text
.exit.text
.exitcall.exit
-#endif
)
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
+#endif
*(.fixup)
*(.gnu.warning)
*(.exitcall.exit)
diff --git a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
index 04da6746837..07643482cad 100644
--- a/arch/frv/mm/tlb-miss.S
+++ b/arch/frv/mm/tlb-miss.S
@@ -16,7 +16,7 @@
#include <asm/highmem.h>
#include <asm/spr-regs.h>
- .section .text
+ .section .text.tlbmiss
.balign 4
.globl __entry_insn_mmu_miss
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index a753d79c4e8..18124542a6e 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -36,7 +36,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
unsigned long r2, unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, struct pt_regs *regs)
{
- sigset_t saveset, newset;
+ sigset_t newset;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
@@ -44,21 +44,18 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
if (copy_from_user(&newset, unewset, sizeof(newset)))
return -EFAULT;
- sigdelsetmask(&newset, ~_BLOCKABLE);
+ sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
+ current->saved_sigmask = current->blocked;
current->blocked = newset;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- regs->r0 = -EINTR;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(regs, &saveset))
- return regs->r0;
- }
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
}
asmlinkage int
diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S
index 751ac2a3d12..95aa7987484 100644
--- a/arch/m32r/kernel/syscall_table.S
+++ b/arch/m32r/kernel/syscall_table.S
@@ -284,3 +284,43 @@ ENTRY(sys_call_table)
.long sys_mq_getsetattr
.long sys_ni_syscall /* reserved for kexec */
.long sys_waitid
+ .long sys_ni_syscall /* 285 */ /* available */
+ .long sys_add_key
+ .long sys_request_key
+ .long sys_keyctl
+ .long sys_ioprio_set
+ .long sys_ioprio_get /* 290 */
+ .long sys_inotify_init
+ .long sys_inotify_add_watch
+ .long sys_inotify_rm_watch
+ .long sys_migrate_pages
+ .long sys_openat /* 295 */
+ .long sys_mkdirat
+ .long sys_mknodat
+ .long sys_fchownat
+ .long sys_futimesat
+ .long sys_fstatat64 /* 300 */
+ .long sys_unlinkat
+ .long sys_renameat
+ .long sys_linkat
+ .long sys_symlinkat
+ .long sys_readlinkat /* 305 */
+ .long sys_fchmodat
+ .long sys_faccessat
+ .long sys_pselect6
+ .long sys_ppoll
+ .long sys_unshare /* 310 */
+ .long sys_set_robust_list
+ .long sys_get_robust_list
+ .long sys_splice
+ .long sys_sync_file_range
+ .long sys_tee /* 315 */
+ .long sys_vmsplice
+ .long sys_move_pages
+ .long sys_getcpu
+ .long sys_epoll_pwait
+ .long sys_utimensat /* 320 */
+ .long sys_signalfd
+ .long sys_timerfd
+ .long sys_eventfd
+ .long sys_fallocate
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
index 74c5c62365a..0e2b5cd81f6 100644
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -5,6 +5,10 @@
*
* Copyright (C) 2007 by Ralf Baechle
*/
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/time.h>
static cycle_t c0_hpt_read(void)
{
@@ -18,7 +22,7 @@ static struct clocksource clocksource_mips = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void __init init_mips_clocksource(void)
+void __init init_mips_clocksource(void)
{
/* Calclate a somewhat reasonable rating value */
clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 174f09e42f6..5f389ee26fc 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -31,25 +31,6 @@
unsigned long sgi_gfxaddr;
EXPORT_SYMBOL_GPL(sgi_gfxaddr);
-/*
- * Stop-A is originally a Sun thing that isn't standard on IP22 so to avoid
- * accidents it's disabled by default on IP22.
- *
- * FIXME: provide a mechanism to change the value of stop_a_enabled.
- */
-int stop_a_enabled;
-
-void ip22_do_break(void)
-{
- if (!stop_a_enabled)
- return;
-
- printk("\n");
- ArcEnterInteractiveMode();
-}
-
-EXPORT_SYMBOL(ip22_do_break);
-
extern void ip22_be_init(void) __init;
void __init plat_mem_setup(void)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 18f397ca05e..232c298c933 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -187,6 +187,11 @@ config FORCE_MAX_ZONEORDER
default "9" if PPC_64K_PAGES
default "13"
+config HUGETLB_PAGE_SIZE_VARIABLE
+ bool
+ depends on HUGETLB_PAGE
+ default y
+
config MATH_EMULATION
bool "Math emulation"
depends on 4xx || 8xx || E200 || PPC_MPC832x || E500
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 31999bc1c8a..ba6813a4aa3 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -168,7 +168,7 @@ ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p $(objtree)/include/asm-um
$(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch
else
- $(Q)cd $(TOPDIR)/include/asm-um && ln -fsn ../asm-$(SUBARCH) arch
+ $(Q)cd $(TOPDIR)/include/asm-um && ln -fsn ../asm-$(HEADER_ARCH) arch
endif
$(objtree)/$(ARCH_DIR)/include:
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 7e6cdde62ea..b1a77b11f08 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1128,6 +1128,7 @@ static void do_ubd_request(struct request_queue *q)
"errno = %d\n", -n);
else if(list_empty(&dev->restart))
list_add(&dev->restart, &restart);
+ kfree(io_req);
return;
}
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index e34e1effe0f..ef02d941c2a 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -59,7 +59,7 @@ long long disable_timer(void)
{
struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
- if(setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
+ if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
printk(UM_KERN_ERR "disable_timer - setitimer failed, "
"errno = %d\n", errno);
@@ -74,13 +74,61 @@ long long os_nsecs(void)
return timeval_to_ns(&tv);
}
+#ifdef UML_CONFIG_NO_HZ
+static int after_sleep_interval(struct timespec *ts)
+{
+}
+#else
+static inline long long timespec_to_us(const struct timespec *ts)
+{
+ return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
+ ts->tv_nsec / UM_NSEC_PER_USEC;
+}
+
+static int after_sleep_interval(struct timespec *ts)
+{
+ int usec = UM_USEC_PER_SEC / UM_HZ;
+ long long start_usecs = timespec_to_us(ts);
+ struct timeval tv;
+ struct itimerval interval;
+
+ /*
+ * It seems that rounding can increase the value returned from
+ * setitimer to larger than the one passed in. Over time,
+ * this will cause the remaining time to be greater than the
+ * tick interval. If this happens, then just reduce the first
+ * tick to the interval value.
+ */
+ if (start_usecs > usec)
+ start_usecs = usec;
+ tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC,
+ .tv_usec = start_usecs % UM_USEC_PER_SEC });
+ interval = ((struct itimerval) { { 0, usec }, tv });
+
+ if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
+ return -errno;
+
+ return 0;
+}
+#endif
+
extern void alarm_handler(int sig, struct sigcontext *sc);
void idle_sleep(unsigned long long nsecs)
{
- struct timespec ts = { .tv_sec = nsecs / UM_NSEC_PER_SEC,
- .tv_nsec = nsecs % UM_NSEC_PER_SEC };
+ struct timespec ts;
+
+ /*
+ * nsecs can come in as zero, in which case, this starts a
+ * busy loop. To prevent this, reset nsecs to the tick
+ * interval if it is zero.
+ */
+ if (nsecs == 0)
+ nsecs = UM_NSEC_PER_SEC / UM_HZ;
+ ts = ((struct timespec) { .tv_sec = nsecs / UM_NSEC_PER_SEC,
+ .tv_nsec = nsecs % UM_NSEC_PER_SEC });
if (nanosleep(&ts, &ts) == 0)
alarm_handler(SIGVTALRM, NULL);
+ after_sleep_interval(&ts);
}
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 6ef5a060fa1..4cc5b0411db 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -236,39 +236,30 @@ start_of_setup:
movw %ax, %es
cld
-# Apparently some ancient versions of LILO invoked the kernel
-# with %ss != %ds, which happened to work by accident for the
-# old code. If the CAN_USE_HEAP flag is set in loadflags, or
-# %ss != %ds, then adjust the stack pointer.
+# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
+# which happened to work by accident for the old code. Recalculate the stack
+# pointer if %ss is invalid. Otherwise leave it alone, LOADLIN sets up the
+# stack behind its own code, so we can't blindly put it directly past the heap.
- # Smallest possible stack we can tolerate
- movw $(_end+STACK_SIZE), %cx
-
- movw heap_end_ptr, %dx
- addw $512, %dx
- jnc 1f
- xorw %dx, %dx # Wraparound - whole segment available
-1: testb $CAN_USE_HEAP, loadflags
- jnz 2f
-
- # No CAN_USE_HEAP
movw %ss, %dx
cmpw %ax, %dx # %ds == %ss?
movw %sp, %dx
- # If so, assume %sp is reasonably set, otherwise use
- # the smallest possible stack.
- jne 4f # -> Smallest possible stack...
+ je 2f # -> assume %sp is reasonably set
+
+ # Invalid %ss, make up a new stack
+ movw $_end, %dx
+ testb $CAN_USE_HEAP, loadflags
+ jz 1f
+ movw heap_end_ptr, %dx
+1: addw $STACK_SIZE, %dx
+ jnc 2f
+ xorw %dx, %dx # Prevent wraparound
- # Make sure the stack is at least minimum size. Take a value
- # of zero to mean "full segment."
-2:
+2: # Now %dx should point to the end of our stack space
andw $~3, %dx # dword align (might as well...)
jnz 3f
movw $0xfffc, %dx # Make sure we're not zero
-3: cmpw %cx, %dx
- jnb 5f
-4: movw %cx, %dx # Minimum value we can possibly use
-5: movw %ax, %ss
+3: movw %ax, %ss
movzwl %dx, %esp # Clear upper half of %esp
sti # Now we should have a working stack
diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt_32.c
index 6a80d67c212..f5000799f8e 100644
--- a/arch/x86/kernel/paravirt_32.c
+++ b/arch/x86/kernel/paravirt_32.c
@@ -465,8 +465,8 @@ struct pv_mmu_ops pv_mmu_ops = {
};
EXPORT_SYMBOL_GPL(pv_time_ops);
-EXPORT_SYMBOL_GPL(pv_cpu_ops);
-EXPORT_SYMBOL_GPL(pv_mmu_ops);
+EXPORT_SYMBOL (pv_cpu_ops);
+EXPORT_SYMBOL (pv_mmu_ops);
EXPORT_SYMBOL_GPL(pv_apic_ops);
EXPORT_SYMBOL_GPL(pv_info);
EXPORT_SYMBOL (pv_irq_ops);
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig
index c4dffbeea5e..19626ace0f5 100644
--- a/arch/x86/lguest/Kconfig
+++ b/arch/x86/lguest/Kconfig
@@ -2,6 +2,7 @@ config LGUEST_GUEST
bool "Lguest guest support"
select PARAVIRT
depends on !X86_PAE
+ depends on !(X86_VISWS || X86_VOYAGER)
select VIRTIO
select VIRTIO_RING
select VIRTIO_CONSOLE
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a7308b2cd05..0f9c8c89065 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -345,7 +345,7 @@ static void __init find_early_table_space(unsigned long end)
/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
This runs before bootmem is initialized and gets pages directly from the
physical memory. To access them they are temporarily mapped. */
-void __meminit init_memory_mapping(unsigned long start, unsigned long end)
+void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
{
unsigned long next;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index b2e32f9d007..0ac6c5dc49b 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -244,6 +244,8 @@ pte_t xen_make_pte(unsigned long long pte)
if (pte & 1)
pte = phys_to_machine(XPADDR(pte)).maddr;
+ pte &= ~_PAGE_PCD;
+
return (pte_t){ pte, pte >> 32 };
}
@@ -291,6 +293,8 @@ pte_t xen_make_pte(unsigned long pte)
if (pte & _PAGE_PRESENT)
pte = phys_to_machine(XPADDR(pte)).maddr;
+ pte &= ~_PAGE_PCD;
+
return (pte_t){ pte };
}
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 015689d295c..e48ee4f8749 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -494,7 +494,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id)
if (apic_id == -1)
return apic_id;
- for (i = 0; i < NR_CPUS; ++i) {
+ for_each_possible_cpu(i) {
if (cpu_physical_id(i) == apic_id)
return i;
}
@@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
return 0;
}
- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
+ BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
/*
* Buggy BIOS check
@@ -774,7 +774,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
pr = acpi_driver_data(device);
- if (pr->id >= NR_CPUS) {
+ if (pr->id >= nr_cpu_ids) {
kfree(pr);
return 0;
}
@@ -845,7 +845,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
if (!pr)
return -ENODEV;
- if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
+ if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) {
kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
}
return 0;
@@ -883,13 +883,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
break;
}
- if (pr->id >= 0 && (pr->id < NR_CPUS)) {
+ if (pr->id >= 0 && (pr->id < nr_cpu_ids)) {
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
break;
}
result = acpi_processor_start(device);
- if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
+ if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) {
kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
} else {
printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
@@ -912,7 +912,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
return;
}
- if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
+ if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id)))
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
break;
default:
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 3f4d6aa1399..2683eac30c6 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -770,9 +770,10 @@ int device_add(struct device *dev)
error = device_add_attrs(dev);
if (error)
goto AttrsError;
- error = device_pm_add(dev);
+ error = dpm_sysfs_add(dev);
if (error)
goto PMError;
+ device_pm_add(dev);
error = bus_add_device(dev);
if (error)
goto BusError;
@@ -797,6 +798,7 @@ int device_add(struct device *dev)
return error;
BusError:
device_pm_remove(dev);
+ dpm_sysfs_remove(dev);
PMError:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->bus_notifier,
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index a803733c839..44504e6618f 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,5 +1,6 @@
obj-y := shutdown.o
-obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o
+obj-$(CONFIG_PM) += sysfs.o
+obj-$(CONFIG_PM_SLEEP) += main.o
obj-$(CONFIG_PM_TRACE) += trace.o
ifeq ($(CONFIG_DEBUG_DRIVER),y)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 0ab4ab21f56..691ffb64cc3 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -38,20 +38,14 @@ static DEFINE_MUTEX(dpm_list_mtx);
int (*platform_enable_wakeup)(struct device *dev, int is_on);
-int device_pm_add(struct device *dev)
+void device_pm_add(struct device *dev)
{
- int error;
-
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
mutex_lock(&dpm_list_mtx);
list_add_tail(&dev->power.entry, &dpm_active);
- error = dpm_sysfs_add(dev);
- if (error)
- list_del(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
- return error;
}
void device_pm_remove(struct device *dev)
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 5c4efd493fa..379da4e958e 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -13,14 +13,29 @@ extern void device_shutdown(void);
extern struct list_head dpm_active; /* The active device list */
-static inline struct device * to_device(struct list_head * entry)
+static inline struct device *to_device(struct list_head *entry)
{
return container_of(entry, struct device, power.entry);
}
-extern int device_pm_add(struct device *);
+extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
+#else /* CONFIG_PM_SLEEP */
+
+
+static inline void device_pm_add(struct device *dev)
+{
+}
+
+static inline void device_pm_remove(struct device *dev)
+{
+}
+
+#endif
+
+#ifdef CONFIG_PM
+
/*
* sysfs.c
*/
@@ -28,16 +43,15 @@ extern void device_pm_remove(struct device *);
extern int dpm_sysfs_add(struct device *);
extern void dpm_sysfs_remove(struct device *);
-#else /* CONFIG_PM_SLEEP */
-
+#else /* CONFIG_PM */
-static inline int device_pm_add(struct device * dev)
+static inline int dpm_sysfs_add(struct device *dev)
{
return 0;
}
-static inline void device_pm_remove(struct device * dev)
-{
+static inline void dpm_sysfs_remove(struct device *dev)
+{
}
#endif
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index bf18d757b87..a509b8d7978 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -457,7 +457,7 @@ config LEGACY_PTYS
config LEGACY_PTY_COUNT
int "Maximum number of legacy PTY in use"
depends on LEGACY_PTYS
- range 1 256
+ range 0 256
default "256"
---help---
The maximum number of legacy PTYs that can be used at any one time.
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index fd771a4d6d1..81503d94fec 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -450,6 +450,11 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
goto out_err;
}
+ if (request_locality(chip, 0) != 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
/* Default timeouts */
@@ -487,11 +492,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
dev_dbg(dev, "\tData Avail Int Support\n");
- if (request_locality(chip, 0) != 0) {
- rc = -ENODEV;
- goto out_err;
- }
-
/* INTERRUPT Setup */
init_waitqueue_head(&chip->vendor.read_queue);
init_waitqueue_head(&chip->vendor.int_queue);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 6a7d25fc247..c46b7c219ee 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -3,11 +3,13 @@
#
menuconfig DMADEVICES
- bool "DMA Offload Engine support"
+ bool "DMA Engine support"
depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
help
- Intel(R) offload engines enable offloading memory copies in the
- network stack and RAID operations in the MD driver.
+ DMA engines can do asynchronous data transfers without
+ involving the host CPU. Currently, this framework can be
+ used to offload memory copies in the network stack and
+ RAID operations in the MD driver.
if DMADEVICES
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
index 57670dc5034..909d6709ec1 100644
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -118,8 +118,7 @@ hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg)
return(0);
case CARD_INIT:
delay = (75*HZ)/100 +1;
- cs->hw.hfcD.timer.expires = jiffies + delay;
- add_timer(&cs->hw.hfcD.timer);
+ mod_timer(&cs->hw.hfcD.timer, jiffies + delay);
spin_lock_irqsave(&cs->lock, flags);
reset_hfcs(cs);
init2bds0(cs);
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 8135e4c3bf4..afd82966f9a 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -156,7 +156,7 @@ static void sm501_dump_clk(struct sm501_devdata *sm)
dev_dbg(sm->dev, "PM0[%c]: "
"P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), "
-x "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n",
+ "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n",
(pmc & 3 ) == 0 ? '*' : '-',
fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31, px_div)),
fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15, misc_div)),
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index d552de68311..eeea84c309e 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -386,7 +386,7 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port)
sdio_out(port, UART_IER, port->ier);
}
-static void sdio_uart_receive_chars(struct sdio_uart_port *port, int *status)
+static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *status)
{
struct tty_struct *tty = port->tty;
unsigned int ch, flag;
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index f6cc0c5b565..1ef417cca2d 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -66,7 +66,7 @@ struct slot {
char name[SLOT_NAME_SIZE];
};
-/**
+/*
* struct acpiphp_bridge - PCI bridge information
*
* for each bridge device in ACPI namespace
@@ -97,7 +97,7 @@ struct acpiphp_bridge {
};
-/**
+/*
* struct acpiphp_slot - PCI slot information
*
* PCI slot information for each *physical* PCI slot
@@ -118,7 +118,7 @@ struct acpiphp_slot {
};
-/**
+/*
* struct acpiphp_func - PCI function information
*
* PCI function information for each object in ACPI namespace
@@ -137,7 +137,7 @@ struct acpiphp_func {
u32 flags; /* see below */
};
-/**
+/*
* struct acpiphp_attention_info - device specific attention registration
*
* ACPI has no generic method of setting/getting attention status
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index a0ca63adad5..c8c263875c2 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -91,10 +91,10 @@ static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
* acpiphp_register_attention - set attention LED callback
* @info: must be completely filled with LED callbacks
*
- * Description: this is used to register a hardware specific ACPI
+ * Description: This is used to register a hardware specific ACPI
* driver that manipulates the attention LED. All the fields in
* info must be set.
- **/
+ */
int acpiphp_register_attention(struct acpiphp_attention_info *info)
{
int retval = -EINVAL;
@@ -112,10 +112,10 @@ int acpiphp_register_attention(struct acpiphp_attention_info *info)
* acpiphp_unregister_attention - unset attention LED callback
* @info: must match the pointer used to register
*
- * Description: this is used to un-register a hardware specific acpi
+ * Description: This is used to un-register a hardware specific acpi
* driver that manipulates the attention LED. The pointer to the
* info struct must be the same as the one used to set it.
- **/
+ */
int acpiphp_unregister_attention(struct acpiphp_attention_info *info)
{
int retval = -EINVAL;
@@ -133,7 +133,6 @@ int acpiphp_unregister_attention(struct acpiphp_attention_info *info)
* @hotplug_slot: slot to enable
*
* Actual tasks are done in acpiphp_enable_slot()
- *
*/
static int enable_slot(struct hotplug_slot *hotplug_slot)
{
@@ -151,7 +150,6 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
* @hotplug_slot: slot to disable
*
* Actual tasks are done in acpiphp_disable_slot()
- *
*/
static int disable_slot(struct hotplug_slot *hotplug_slot)
{
@@ -168,15 +166,15 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
}
- /**
- * set_attention_status - set attention LED
+/**
+ * set_attention_status - set attention LED
* @hotplug_slot: slot to set attention LED on
* @status: value to set attention LED to (0 or 1)
*
* attention status LED, so we use a callback that
* was registered with us. This allows hardware specific
* ACPI implementations to blink the light for us.
- **/
+ */
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{
int retval = -ENODEV;
@@ -199,7 +197,6 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
*
* Some platforms may not implement _STA method properly.
* In that case, the value returned may not be reliable.
- *
*/
static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
@@ -213,7 +210,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
}
- /**
+/**
* get_attention_status - get attention LED status
* @hotplug_slot: slot to get status from
* @value: returns with value of attention LED
@@ -221,8 +218,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
* ACPI doesn't have known method to determine the state
* of the attention status LED, so we use a callback that
* was registered with us. This allows hardware specific
- * ACPI implementations to determine its state
- **/
+ * ACPI implementations to determine its state.
+ */
static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
int retval = -EINVAL;
@@ -244,8 +241,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
* @value: pointer to store status
*
* ACPI doesn't provide any formal means to access latch status.
- * Instead, we fake latch status from _STA
- *
+ * Instead, we fake latch status from _STA.
*/
static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
@@ -265,8 +261,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
* @value: pointer to store status
*
* ACPI doesn't provide any formal means to access adapter status.
- * Instead, we fake adapter status from _STA
- *
+ * Instead, we fake adapter status from _STA.
*/
static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 1e125b56c9a..ff1b1c71291 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -82,7 +82,6 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
* 2. has _PS0 method
* 3. has _PS3 method
* 4. ..
- *
*/
static int is_ejectable(acpi_handle handle)
{
@@ -986,10 +985,8 @@ static int power_off_slot(struct acpiphp_slot *slot)
/**
- * acpiphp_max_busnr - return the highest reserved bus number under
- * the given bus.
+ * acpiphp_max_busnr - return the highest reserved bus number under the given bus.
* @bus: bus to start search with
- *
*/
static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
{
@@ -1018,7 +1015,6 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
/**
* acpiphp_bus_add - add a new bus to acpi subsystem
* @func: acpiphp_func of the bridge
- *
*/
static int acpiphp_bus_add(struct acpiphp_func *func)
{
@@ -1063,7 +1059,6 @@ acpiphp_bus_add_out:
/**
* acpiphp_bus_trim - trim a bus from acpi subsystem
* @handle: handle to acpi namespace
- *
*/
static int acpiphp_bus_trim(acpi_handle handle)
{
@@ -1089,7 +1084,6 @@ static int acpiphp_bus_trim(acpi_handle handle)
*
* This function should be called per *physical slot*,
* not per each slot object in ACPI namespace.
- *
*/
static int enable_device(struct acpiphp_slot *slot)
{
@@ -1185,6 +1179,7 @@ static void disable_bridges(struct pci_bus *bus)
/**
* disable_device - disable a slot
+ * @slot: ACPI PHP slot
*/
static int disable_device(struct acpiphp_slot *slot)
{
@@ -1240,14 +1235,15 @@ static int disable_device(struct acpiphp_slot *slot)
/**
* get_slot_status - get ACPI slot status
+ * @slot: ACPI PHP slot
*
- * if a slot has _STA for each function and if any one of them
- * returned non-zero status, return it
+ * If a slot has _STA for each function and if any one of them
+ * returned non-zero status, return it.
*
- * if a slot doesn't have _STA and if any one of its functions'
- * configuration space is configured, return 0x0f as a _STA
+ * If a slot doesn't have _STA and if any one of its functions'
+ * configuration space is configured, return 0x0f as a _STA.
*
- * otherwise return 0
+ * Otherwise return 0.
*/
static unsigned int get_slot_status(struct acpiphp_slot *slot)
{
@@ -1281,6 +1277,7 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)
/**
* acpiphp_eject_slot - physically eject the slot
+ * @slot: ACPI PHP slot
*/
int acpiphp_eject_slot(struct acpiphp_slot *slot)
{
@@ -1314,6 +1311,7 @@ int acpiphp_eject_slot(struct acpiphp_slot *slot)
/**
* acpiphp_check_bridge - re-enumerate devices
+ * @bridge: where to begin re-enumeration
*
* Iterate over all slots under this bridge and make sure that if a
* card is present they are enabled, and if not they are disabled.
@@ -1538,13 +1536,11 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
/**
* handle_hotplug_event_bridge - handle ACPI event on bridges
- *
* @handle: Notify()'ed acpi_handle
* @type: Notify code
* @context: pointer to acpiphp_bridge structure
*
- * handles ACPI event notification on {host,p2p} bridges
- *
+ * Handles ACPI event notification on {host,p2p} bridges.
*/
static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context)
{
@@ -1634,13 +1630,11 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
/**
* handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
- *
* @handle: Notify()'ed acpi_handle
* @type: Notify code
* @context: pointer to acpiphp_func structure
*
- * handles ACPI event notification on slots
- *
+ * Handles ACPI event notification on slots.
*/
static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
{
@@ -1705,7 +1699,6 @@ static struct acpi_pci_driver acpi_pci_hp_driver = {
/**
* acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
- *
*/
int __init acpiphp_glue_init(void)
{
@@ -1726,7 +1719,7 @@ int __init acpiphp_glue_init(void)
/**
* acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
*
- * This function frees all data allocated in acpiphp_glue_init()
+ * This function frees all data allocated in acpiphp_glue_init().
*/
void acpiphp_glue_exit(void)
{
@@ -1760,7 +1753,6 @@ int __init acpiphp_get_num_slots(void)
* acpiphp_for_each_slot - call function for each slot
* @fn: callback function
* @data: context to be passed to callback function
- *
*/
static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
{
@@ -1786,6 +1778,7 @@ static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
/**
* acpiphp_enable_slot - power on slot
+ * @slot: ACPI PHP slot
*/
int acpiphp_enable_slot(struct acpiphp_slot *slot)
{
@@ -1815,6 +1808,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
/**
* acpiphp_disable_slot - power off slot
+ * @slot: ACPI PHP slot
*/
int acpiphp_disable_slot(struct acpiphp_slot *slot)
{
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 56829f82be4..47d26b65e99 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -134,11 +134,11 @@ static struct acpiphp_attention_info ibm_attention_info =
* ibm_slot_from_id - workaround for bad ibm hardware
* @id: the slot number that linux refers to the slot by
*
- * Description: this method returns the aCPI slot descriptor
+ * Description: This method returns the aCPI slot descriptor
* corresponding to the Linux slot number. This descriptor
* has info about the aPCI slot id and attention status.
* This descriptor must be freed using kfree when done.
- **/
+ */
static union apci_descriptor *ibm_slot_from_id(int id)
{
int ind = 0, size;
@@ -173,9 +173,9 @@ ibm_slot_done:
* @slot: the hotplug_slot to work with
* @status: what to set the LED to (0 or 1)
*
- * Description: this method is registered with the acpiphp module as a
- * callback to do the device specific task of setting the LED status
- **/
+ * Description: This method is registered with the acpiphp module as a
+ * callback to do the device specific task of setting the LED status.
+ */
static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
{
union acpi_object args[2];
@@ -213,13 +213,13 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
* @slot: the hotplug_slot to work with
* @status: returns what the LED is set to (0 or 1)
*
- * Description: this method is registered with the acpiphp module as a
- * callback to do the device specific task of getting the LED status
+ * Description: This method is registered with the acpiphp module as a
+ * callback to do the device specific task of getting the LED status.
*
* Because there is no direct method of getting the LED status directly
* from an ACPI call, we read the aPCI table and parse out our
* slot descriptor to read the status from that.
- **/
+ */
static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
{
union apci_descriptor *ibm_slot;
@@ -245,8 +245,8 @@ static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
* @event: the event info (device specific)
* @context: passed context (our notification struct)
*
- * Description: this method is registered as a callback with the ACPI
- * subsystem it is called when this device has an event to notify the OS of
+ * Description: This method is registered as a callback with the ACPI
+ * subsystem it is called when this device has an event to notify the OS of.
*
* The events actually come from the device as two events that get
* synthesized into one event with data by this function. The event
@@ -256,7 +256,7 @@ static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
* From section 5.6.2.2 of the ACPI 2.0 spec, I understand that the OSPM will
* only re-enable the interrupt that causes this event AFTER this method
* has returned, thereby enforcing serial access for the notification struct.
- **/
+ */
static void ibm_handle_events(acpi_handle handle, u32 event, void *context)
{
u8 detail = event & 0x0f;
@@ -279,16 +279,16 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context)
* ibm_get_table_from_acpi - reads the APLS buffer from ACPI
* @bufp: address to pointer to allocate for the table
*
- * Description: this method reads the APLS buffer in from ACPI and
+ * Description: This method reads the APLS buffer in from ACPI and
* stores the "stripped" table into a single buffer
- * it allocates and passes the address back in bufp
+ * it allocates and passes the address back in bufp.
*
* If NULL is passed in as buffer, this method only calculates
* the size of the table and returns that without filling
- * in the buffer
+ * in the buffer.
*
- * returns < 0 on error or the size of the table on success
- **/
+ * Returns < 0 on error or the size of the table on success.
+ */
static int ibm_get_table_from_acpi(char **bufp)
{
union acpi_object *package;
@@ -349,17 +349,18 @@ read_table_done:
/**
* ibm_read_apci_table - callback for the sysfs apci_table file
* @kobj: the kobject this binary attribute is a part of
+ * @bin_attr: struct bin_attribute for this file
* @buffer: the kernel space buffer to fill
* @pos: the offset into the file
* @size: the number of bytes requested
*
- * Description: gets registered with sysfs as the reader callback
- * to be executed when /sys/bus/pci/slots/apci_table gets read
+ * Description: Gets registered with sysfs as the reader callback
+ * to be executed when /sys/bus/pci/slots/apci_table gets read.
*
* Since we don't get notified on open and close for this file,
* things get really tricky here...
- * our solution is to only allow reading the table in all at once
- **/
+ * our solution is to only allow reading the table in all at once.
+ */
static ssize_t ibm_read_apci_table(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t size)
@@ -385,10 +386,10 @@ static ssize_t ibm_read_apci_table(struct kobject *kobj,
* @context: a pointer to our handle to fill when we find the device
* @rv: a return value to fill if desired
*
- * Description: used as a callback when calling acpi_walk_namespace
+ * Description: Used as a callback when calling acpi_walk_namespace
* to find our device. When this method returns non-zero
- * acpi_walk_namespace quits its search and returns our value
- **/
+ * acpi_walk_namespace quits its search and returns our value.
+ */
static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
u32 lvl, void *context, void **rv)
{
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index a96b739b2d3..74178875b94 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -117,12 +117,10 @@ static inline int is_slot66mhz(struct slot *slot)
/**
* detect_SMBIOS_pointer - find the System Management BIOS Table in mem region.
- *
* @begin: begin pointer for region to be scanned.
* @end: end pointer for region to be scanned.
*
- * Returns pointer to the head of the SMBIOS tables (or NULL)
- *
+ * Returns pointer to the head of the SMBIOS tables (or %NULL).
*/
static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
{
@@ -157,9 +155,9 @@ static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *e
/**
* init_SERR - Initializes the per slot SERR generation.
+ * @ctrl: controller to use
*
* For unexpected switch opens
- *
*/
static int init_SERR(struct controller * ctrl)
{
@@ -224,14 +222,15 @@ static int pci_print_IRQ_route (void)
/**
* get_subsequent_smbios_entry: get the next entry from bios table.
- *
- * Gets the first entry if previous == NULL
- * Otherwise, returns the next entry
- * Uses global SMBIOS Table pointer
- *
+ * @smbios_start: where to start in the SMBIOS table
+ * @smbios_table: location of the SMBIOS table
* @curr: %NULL or pointer to previously returned structure
*
- * returns a pointer to an SMBIOS structure or NULL if none found
+ * Gets the first entry if previous == NULL;
+ * otherwise, returns the next entry.
+ * Uses global SMBIOS Table pointer.
+ *
+ * Returns a pointer to an SMBIOS structure or NULL if none found.
*/
static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
void __iomem *smbios_table,
@@ -272,17 +271,18 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
/**
- * get_SMBIOS_entry
- *
- * @type:SMBIOS structure type to be returned
+ * get_SMBIOS_entry - return the requested SMBIOS entry or %NULL
+ * @smbios_start: where to start in the SMBIOS table
+ * @smbios_table: location of the SMBIOS table
+ * @type: SMBIOS structure type to be returned
* @previous: %NULL or pointer to previously returned structure
*
- * Gets the first entry of the specified type if previous == NULL
+ * Gets the first entry of the specified type if previous == %NULL;
* Otherwise, returns the next entry of the given type.
- * Uses global SMBIOS Table pointer
- * Uses get_subsequent_smbios_entry
+ * Uses global SMBIOS Table pointer.
+ * Uses get_subsequent_smbios_entry.
*
- * returns a pointer to an SMBIOS structure or %NULL if none found
+ * Returns a pointer to an SMBIOS structure or %NULL if none found.
*/
static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
void __iomem *smbios_table,
@@ -581,7 +581,9 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
/**
* cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
- *
+ * @ctrl: struct controller to use
+ * @func: PCI device/function info
+ * @status: LED control flag: 1 = LED on, 0 = LED off
*/
static int
cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
@@ -621,7 +623,8 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
/**
* set_attention_status - Turns the Amber LED for a slot on or off
- *
+ * @hotplug_slot: slot to change LED on
+ * @status: LED control flag
*/
static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
{
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index 856d57b4d60..4018420c6f9 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -123,7 +123,7 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl)
}
/**
- * cpqhp_find_slot: find the struct slot of given device
+ * cpqhp_find_slot - find the struct slot of given device
* @ctrl: scan lots of this controller
* @device: the device id to find
*/
@@ -305,9 +305,8 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl)
/**
- * sort_by_size: sort nodes on the list by their length, smallest first.
+ * sort_by_size - sort nodes on the list by their length, smallest first.
* @head: list to sort
- *
*/
static int sort_by_size(struct pci_resource **head)
{
@@ -354,9 +353,8 @@ static int sort_by_size(struct pci_resource **head)
/**
- * sort_by_max_size: sort nodes on the list by their length, largest first.
+ * sort_by_max_size - sort nodes on the list by their length, largest first.
* @head: list to sort
- *
*/
static int sort_by_max_size(struct pci_resource **head)
{
@@ -403,8 +401,10 @@ static int sort_by_max_size(struct pci_resource **head)
/**
- * do_pre_bridge_resource_split: find node of resources that are unused
- *
+ * do_pre_bridge_resource_split - find node of resources that are unused
+ * @head: new list head
+ * @orig_head: original list head
+ * @alignment: max node size (?)
*/
static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **head,
struct pci_resource **orig_head, u32 alignment)
@@ -477,8 +477,9 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h
/**
- * do_bridge_resource_split: find one node of resources that aren't in use
- *
+ * do_bridge_resource_split - find one node of resources that aren't in use
+ * @head: list head
+ * @alignment: max node size (?)
*/
static struct pci_resource *do_bridge_resource_split(struct pci_resource **head, u32 alignment)
{
@@ -525,14 +526,13 @@ error:
/**
- * get_io_resource: find first node of given size not in ISA aliasing window.
+ * get_io_resource - find first node of given size not in ISA aliasing window.
* @head: list to search
* @size: size of node to find, must be a power of two.
*
- * Description: this function sorts the resource list by size and then returns
+ * Description: This function sorts the resource list by size and then returns
* returns the first node of "size" length that is not in the ISA aliasing
* window. If it finds a node larger than "size" it will split it up.
- *
*/
static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
{
@@ -620,7 +620,7 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
/**
- * get_max_resource: get largest node which has at least the given size.
+ * get_max_resource - get largest node which has at least the given size.
* @head: the list to search the node in
* @size: the minimum size of the node to find
*
@@ -712,7 +712,7 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz
/**
- * get_resource: find resource of given size and split up larger ones.
+ * get_resource - find resource of given size and split up larger ones.
* @head: the list to search for resources
* @size: the size limit to use
*
@@ -804,14 +804,14 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
/**
- * cpqhp_resource_sort_and_combine: sort nodes by base addresses and clean up.
+ * cpqhp_resource_sort_and_combine - sort nodes by base addresses and clean up
* @head: the list to sort and clean up
*
* Description: Sorts all of the nodes in the list in ascending order by
* their base addresses. Also does garbage collection by
* combining adjacent nodes.
*
- * returns 0 if success
+ * Returns %0 if success.
*/
int cpqhp_resource_sort_and_combine(struct pci_resource **head)
{
@@ -951,9 +951,9 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data)
/**
* cpqhp_slot_create - Creates a node and adds it to the proper bus.
- * @busnumber - bus where new node is to be located
+ * @busnumber: bus where new node is to be located
*
- * Returns pointer to the new node or NULL if unsuccessful
+ * Returns pointer to the new node or %NULL if unsuccessful.
*/
struct pci_func *cpqhp_slot_create(u8 busnumber)
{
@@ -986,7 +986,7 @@ struct pci_func *cpqhp_slot_create(u8 busnumber)
* slot_remove - Removes a node from the linked list of slots.
* @old_slot: slot to remove
*
- * Returns 0 if successful, !0 otherwise.
+ * Returns %0 if successful, !0 otherwise.
*/
static int slot_remove(struct pci_func * old_slot)
{
@@ -1026,7 +1026,7 @@ static int slot_remove(struct pci_func * old_slot)
* bridge_slot_remove - Removes a node from the linked list of slots.
* @bridge: bridge to remove
*
- * Returns 0 if successful, !0 otherwise.
+ * Returns %0 if successful, !0 otherwise.
*/
static int bridge_slot_remove(struct pci_func *bridge)
{
@@ -1071,7 +1071,7 @@ out:
* cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed
* @bus: bus to find
* @device: device to find
- * @index: is 0 for first function found, 1 for the second...
+ * @index: is %0 for first function found, %1 for the second...
*
* Returns pointer to the node if successful, %NULL otherwise.
*/
@@ -1115,16 +1115,13 @@ static int is_bridge(struct pci_func * func)
/**
- * set_controller_speed - set the frequency and/or mode of a specific
- * controller segment.
- *
+ * set_controller_speed - set the frequency and/or mode of a specific controller segment.
* @ctrl: controller to change frequency/mode for.
* @adapter_speed: the speed of the adapter we want to match.
* @hp_slot: the slot number where the adapter is installed.
*
- * Returns 0 if we successfully change frequency and/or mode to match the
+ * Returns %0 if we successfully change frequency and/or mode to match the
* adapter speed.
- *
*/
static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
{
@@ -1253,13 +1250,14 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
/**
* board_replaced - Called after a board has been replaced in the system.
+ * @func: PCI device/function information
+ * @ctrl: hotplug controller
*
- * This is only used if we don't have resources for hot add
- * Turns power on for the board
- * Checks to see if board is the same
- * If board is same, reconfigures it
+ * This is only used if we don't have resources for hot add.
+ * Turns power on for the board.
+ * Checks to see if board is the same.
+ * If board is same, reconfigures it.
* If board isn't same, turns it back off.
- *
*/
static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
{
@@ -1403,10 +1401,11 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
/**
* board_added - Called after a board has been added to the system.
+ * @func: PCI device/function info
+ * @ctrl: hotplug controller
*
- * Turns power on for the board
- * Configures board
- *
+ * Turns power on for the board.
+ * Configures board.
*/
static u32 board_added(struct pci_func *func, struct controller *ctrl)
{
@@ -1607,8 +1606,10 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/**
- * remove_board - Turns off slot and LED's
- *
+ * remove_board - Turns off slot and LEDs
+ * @func: PCI device/function info
+ * @replace_flag: whether replacing or adding a new device
+ * @ctrl: target controller
*/
static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
{
@@ -1902,11 +1903,11 @@ static void interrupt_event_handler(struct controller *ctrl)
/**
- * cpqhp_pushbutton_thread
+ * cpqhp_pushbutton_thread - handle pushbutton events
+ * @slot: target slot (struct)
*
- * Scheduled procedure to handle blocking stuff for the pushbuttons
+ * Scheduled procedure to handle blocking stuff for the pushbuttons.
* Handles all pending events and exits.
- *
*/
void cpqhp_pushbutton_thread(unsigned long slot)
{
@@ -2137,9 +2138,10 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
}
/**
- * switch_leds: switch the leds, go from one site to the other.
+ * switch_leds - switch the leds, go from one site to the other.
* @ctrl: controller to use
* @num_of_slots: number of slots to use
+ * @work_LED: LED control value
* @direction: 1 to start from the left side, 0 to start right.
*/
static void switch_leds(struct controller *ctrl, const int num_of_slots,
@@ -2165,11 +2167,11 @@ static void switch_leds(struct controller *ctrl, const int num_of_slots,
}
/**
- * hardware_test - runs hardware tests
+ * cpqhp_hardware_test - runs hardware tests
+ * @ctrl: target controller
+ * @test_num: the number written to the "test" file in sysfs.
*
* For hot plug ctrl folks to play with.
- * test_num is the number written to the "test" file in sysfs
- *
*/
int cpqhp_hardware_test(struct controller *ctrl, int test_num)
{
@@ -2249,14 +2251,12 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)
/**
* configure_new_device - Configures the PCI header information of one board.
- *
* @ctrl: pointer to controller structure
* @func: pointer to function structure
* @behind_bridge: 1 if this is a recursive call, 0 if not
* @resources: pointer to set of resource lists
*
- * Returns 0 if success
- *
+ * Returns 0 if success.
*/
static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
u8 behind_bridge, struct resource_lists * resources)
@@ -2346,15 +2346,13 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func
/**
* configure_new_function - Configures the PCI header information of one device
- *
* @ctrl: pointer to controller structure
* @func: pointer to function structure
* @behind_bridge: 1 if this is a recursive call, 0 if not
* @resources: pointer to set of resource lists
*
* Calls itself recursively for bridged devices.
- * Returns 0 if success
- *
+ * Returns 0 if success.
*/
static int configure_new_function(struct controller *ctrl, struct pci_func *func,
u8 behind_bridge,
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 027f6865d7e..d7a293e3faf 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -165,11 +165,11 @@ static void remove_slot(struct dummy_slot *dslot)
}
/**
- * Rescan slot.
- * Tries hard not to re-enable already existing devices
- * also handles scanning of subfunctions
+ * pci_rescan_slot - Rescan slot
+ * @temp: Device template. Should be set: bus and devfn.
*
- * @param temp Device template. Should be set: bus and devfn.
+ * Tries hard not to re-enable already existing devices;
+ * also handles scanning of subfunctions.
*/
static void pci_rescan_slot(struct pci_dev *temp)
{
@@ -229,10 +229,10 @@ static void pci_rescan_slot(struct pci_dev *temp)
/**
- * Rescan PCI bus.
- * call pci_rescan_slot for each possible function of the bus
+ * pci_rescan_bus - Rescan PCI bus
+ * @bus: the PCI bus to rescan
*
- * @param bus
+ * Call pci_rescan_slot for each possible function of the bus.
*/
static void pci_rescan_bus(const struct pci_bus *bus)
{
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index c8cb49c5a75..f1e0966cee9 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -208,10 +208,10 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
/**
* board_added - Called after a board has been added to the system.
+ * @p_slot: &slot where board is added
*
- * Turns power on for the board
- * Configures board
- *
+ * Turns power on for the board.
+ * Configures board.
*/
static int board_added(struct slot *p_slot)
{
@@ -276,8 +276,8 @@ err_exit:
}
/**
- * remove_board - Turns off slot and LED's
- *
+ * remove_board - Turns off slot and LEDs
+ * @p_slot: slot where board is being removed
*/
static int remove_board(struct slot *p_slot)
{
@@ -319,11 +319,11 @@ struct power_work_info {
};
/**
- * pciehp_pushbutton_thread
+ * pciehp_power_thread - handle pushbutton events
+ * @work: &struct work_struct describing work to be done
*
- * Scheduled procedure to handle blocking stuff for the pushbuttons
+ * Scheduled procedure to handle blocking stuff for the pushbuttons.
* Handles all pending events and exits.
- *
*/
static void pciehp_power_thread(struct work_struct *work)
{
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index deb6b5e35fe..b169b0e2647 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -100,6 +100,7 @@ static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
/**
* find_php_slot - return hotplug slot structure for device node
+ * @dn: target &device_node
*
* This routine will return the hotplug slot structure
* for a given device node. Note that built-in PCI slots
@@ -293,9 +294,8 @@ static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
* dlpar_add_slot - DLPAR add an I/O Slot
* @drc_name: drc-name of newly added slot
*
- * Make the hotplug module and the kernel aware
- * of a newly added I/O Slot.
- * Return Codes -
+ * Make the hotplug module and the kernel aware of a newly added I/O Slot.
+ * Return Codes:
* 0 Success
* -ENODEV Not a valid drc_name
* -EINVAL Slot already added
@@ -339,9 +339,9 @@ exit:
/**
* dlpar_remove_vio_slot - DLPAR remove a virtual I/O Slot
* @drc_name: drc-name of newly added slot
+ * @dn: &device_node
*
- * Remove the kernel and hotplug representations
- * of an I/O Slot.
+ * Remove the kernel and hotplug representations of an I/O Slot.
* Return Codes:
* 0 Success
* -EINVAL Vio dev doesn't exist
@@ -359,11 +359,11 @@ static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
}
/**
- * dlpar_remove_slot - DLPAR remove a PCI I/O Slot
+ * dlpar_remove_pci_slot - DLPAR remove a PCI I/O Slot
* @drc_name: drc-name of newly added slot
+ * @dn: &device_node
*
- * Remove the kernel and hotplug representations
- * of a PCI I/O Slot.
+ * Remove the kernel and hotplug representations of a PCI I/O Slot.
* Return Codes:
* 0 Success
* -ENODEV Not a valid drc_name
@@ -405,8 +405,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
* dlpar_remove_slot - DLPAR remove an I/O Slot
* @drc_name: drc-name of newly added slot
*
- * Remove the kernel and hotplug representations
- * of an I/O Slot.
+ * Remove the kernel and hotplug representations of an I/O Slot.
* Return Codes:
* 0 Success
* -ENODEV Not a valid drc_name
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 458c08ef265..58f1a992770 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -54,10 +54,12 @@ module_param(debug, bool, 0644);
/**
* set_attention_status - set attention LED
+ * @hotplug_slot: target &hotplug_slot
+ * @value: LED control value
+ *
* echo 0 > attention -- set LED OFF
* echo 1 > attention -- set LED ON
* echo 2 > attention -- set LED ID(identify, light is blinking)
- *
*/
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
{
@@ -99,6 +101,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
/**
* get_attention_status - get attention LED status
+ * @hotplug_slot: slot to get status
+ * @value: pointer to store status
*/
static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
{
@@ -254,6 +258,11 @@ static int is_php_type(char *drc_type)
/**
* is_php_dn() - return 1 if this is a hotpluggable pci slot, else 0
+ * @dn: target &device_node
+ * @indexes: passed to get_children_props()
+ * @names: passed to get_children_props()
+ * @types: returned from get_children_props()
+ * @power_domains:
*
* This routine will return true only if the device node is
* a hotpluggable slot. This routine will return false
@@ -279,7 +288,7 @@ static int is_php_dn(struct device_node *dn, const int **indexes,
/**
* rpaphp_add_slot -- declare a hotplug slot to the hotplug subsystem.
- * @dn device node of slot
+ * @dn: device node of slot
*
* This subroutine will register a hotplugable slot with the
* PCI hotplug infrastructure. This routine is typicaly called
@@ -291,7 +300,7 @@ static int is_php_dn(struct device_node *dn, const int **indexes,
* routine will just return without doing anything, since embedded
* slots cannot be hotplugged.
*
- * To remove a slot, it suffices to call rpaphp_deregister_slot()
+ * To remove a slot, it suffices to call rpaphp_deregister_slot().
*/
int rpaphp_add_slot(struct device_node *dn)
{
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 54ca8650d51..0de84533cd8 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -79,6 +79,7 @@ static void set_slot_name(struct slot *slot)
/**
* rpaphp_enable_slot - record slot state, config pci device
+ * @slot: target &slot
*
* Initialize values in the slot, and the hotplug_slot info
* structures to indicate if there is a pci card plugged into
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index d2fc35598cd..eb5cac6f08a 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -231,10 +231,10 @@ static int fix_bus_speed(struct controller *ctrl, struct slot *pslot,
/**
* board_added - Called after a board has been added to the system.
+ * @p_slot: target &slot
*
- * Turns power on for the board
- * Configures board
- *
+ * Turns power on for the board.
+ * Configures board.
*/
static int board_added(struct slot *p_slot)
{
@@ -350,8 +350,8 @@ err_exit:
/**
- * remove_board - Turns off slot and LED's
- *
+ * remove_board - Turns off slot and LEDs
+ * @p_slot: target &slot
*/
static int remove_board(struct slot *p_slot)
{
@@ -397,11 +397,11 @@ struct pushbutton_work_info {
};
/**
- * shpchp_pushbutton_thread
+ * shpchp_pushbutton_thread - handle pushbutton events
+ * @work: &struct work_struct to be handled
*
- * Scheduled procedure to handle blocking stuff for the pushbuttons
+ * Scheduled procedure to handle blocking stuff for the pushbuttons.
* Handles all pending events and exits.
- *
*/
static void shpchp_pushbutton_thread(struct work_struct *work)
{
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 1b7b2812bf2..7d1877341aa 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -702,8 +702,10 @@ static int __init pci_sysfs_init(void)
sysfs_initialized = 1;
for_each_pci_dev(pdev) {
retval = pci_create_sysfs_dev_files(pdev);
- if (retval)
+ if (retval) {
+ pci_dev_put(pdev);
return retval;
+ }
}
return 0;
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 92a8469b21b..3c0d8d138f5 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -168,11 +168,11 @@ static int find_device_iter(struct device *device, void *data)
/**
* find_source_device - search through device hierarchy for source device
- * @p_dev: pointer to Root Port pci_dev data structure
+ * @parent: pointer to Root Port pci_dev data structure
* @id: device ID of agent who sends an error message to this Root Port
*
* Invoked when error is detected at the Root Port.
- **/
+ */
static struct device* find_source_device(struct pci_dev *parent, u16 id)
{
struct pci_dev *dev = parent;
@@ -286,14 +286,15 @@ static void report_resume(struct pci_dev *dev, void *data)
/**
* broadcast_error_message - handle message broadcast to downstream drivers
- * @device: pointer to from where in a hierarchy message is broadcasted down
- * @api: callback to be broadcasted
+ * @dev: pointer to from where in a hierarchy message is broadcasted down
* @state: error state
+ * @error_mesg: message to print
+ * @cb: callback to be broadcasted
*
* Invoked during error recovery process. Once being invoked, the content
* of error severity will be broadcasted to all downstream drivers in a
* hierarchy in question.
- **/
+ */
static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
enum pci_channel_state state,
char *error_mesg,
@@ -428,7 +429,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev,
* Invoked when an error is nonfatal/fatal. Once being invoked, broadcast
* error detected message to all downstream drivers within a hierarchy in
* question and return the returned code.
- **/
+ */
static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
struct pci_dev *dev,
int severity)
@@ -488,7 +489,7 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
* @info: comprehensive error information
*
* Invoked when an error being detected by Root Port.
- **/
+ */
static void handle_error_source(struct pcie_device * aerdev,
struct pci_dev *dev,
struct aer_err_info info)
@@ -521,7 +522,7 @@ static void handle_error_source(struct pcie_device * aerdev,
* @rpc: pointer to a Root Port data structure
*
* Invoked when PCIE bus loads AER service driver.
- **/
+ */
void aer_enable_rootport(struct aer_rpc *rpc)
{
struct pci_dev *pdev = rpc->rpd->port;
@@ -569,7 +570,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
* @rpc: pointer to a Root Port data structure
*
* Invoked when PCIE bus unloads AER service driver.
- **/
+ */
static void disable_root_aer(struct aer_rpc *rpc)
{
struct pci_dev *pdev = rpc->rpd->port;
@@ -590,7 +591,7 @@ static void disable_root_aer(struct aer_rpc *rpc)
* @rpc: pointer to the root port which holds an error
*
* Invoked by DPC handler to consume an error.
- **/
+ */
static struct aer_err_source* get_e_source(struct aer_rpc *rpc)
{
struct aer_err_source *e_source;
@@ -655,7 +656,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
* aer_isr_one_error - consume an error detected by root port
* @p_device: pointer to error root port service device
* @e_src: pointer to an error source
- **/
+ */
static void aer_isr_one_error(struct pcie_device *p_device,
struct aer_err_source *e_src)
{
@@ -706,7 +707,7 @@ static void aer_isr_one_error(struct pcie_device *p_device,
* @work: definition of this work item
*
* Invoked, as DPC, when root port records new detected error
- **/
+ */
void aer_isr(struct work_struct *work)
{
struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
@@ -729,7 +730,7 @@ void aer_isr(struct work_struct *work)
* @rpc: pointer to a root port device being deleted
*
* Invoked when AER service unloaded on a specific Root Port
- **/
+ */
void aer_delete_rootport(struct aer_rpc *rpc)
{
/* Disable root port AER itself */
@@ -743,7 +744,7 @@ void aer_delete_rootport(struct aer_rpc *rpc)
* @dev: pointer to AER pcie device
*
* Invoked when AER service driver is loaded.
- **/
+ */
int aer_init(struct pcie_device *dev)
{
if (aer_osc_setup(dev) && !forceload)
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index df383645e36..26057f98f72 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -217,7 +217,7 @@ static int slot_reset_iter(struct device *device, void *data)
static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
{
- pci_ers_result_t status;
+ pci_ers_result_t status = PCI_ERS_RESULT_NONE;
int retval;
/* If fatal, restore cfg space for possible link reset at upstream */
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 11adab13f2b..3c5eb374adf 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -83,9 +83,11 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
i < PNP_MAX_IRQ)
i++;
- if (i >= PNP_MAX_IRQ)
+ if (i >= PNP_MAX_IRQ) {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ "
+ "resources: %d \n", PNP_MAX_IRQ);
return;
-
+ }
/*
* in IO-APIC mode, use overrided attribute. Two reasons:
* 1. BIOS bug in DSDT
@@ -181,6 +183,9 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
}
res->dma_resource[i].start = dma;
res->dma_resource[i].end = dma;
+ } else {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of DMA "
+ "resources: %d \n", PNP_MAX_DMA);
}
}
@@ -202,6 +207,9 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
}
res->port_resource[i].start = io;
res->port_resource[i].end = io + len - 1;
+ } else {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of IO "
+ "resources: %d \n", PNP_MAX_PORT);
}
}
@@ -225,6 +233,9 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
res->mem_resource[i].start = mem;
res->mem_resource[i].end = mem + len - 1;
+ } else {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of mem "
+ "resources: %d\n", PNP_MAX_MEM);
}
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 41d73a5e931..e50ebcffb96 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -367,8 +367,10 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
{
struct pci_dev *pci = NULL;
for_each_pci_dev(pci) {
- if (pci->irq == *irq)
+ if (pci->irq == *irq) {
+ pci_dev_put(pci);
return 0;
+ }
}
}
#endif
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index 746031de219..1f5a2d33bf5 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1,6 +1,6 @@
-obj-$(CONFIG_PS3_VUART) += vuart.o
+obj-$(CONFIG_PS3_VUART) += ps3-vuart.o
obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o
ps3av_mod-objs += ps3av.o ps3av_cmd.o
obj-$(CONFIG_PPC_PS3) += sys-manager-core.o
-obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o
+obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o
obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o
diff --git a/drivers/ps3/sys-manager.c b/drivers/ps3/ps3-sys-manager.c
index 8461b08ab9f..8461b08ab9f 100644
--- a/drivers/ps3/sys-manager.c
+++ b/drivers/ps3/ps3-sys-manager.c
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/ps3-vuart.c
index 9dea585ef80..9dea585ef80 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/ps3-vuart.c
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index de0da545c7a..a4f56e95cf9 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -293,7 +293,7 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
return -EINVAL;
/* Cannot register while the char dev is in use */
- if (!(mutex_trylock(&rtc->char_lock)))
+ if (test_and_set_bit(RTC_DEV_BUSY, &rtc->flags))
return -EBUSY;
spin_lock_irq(&rtc->irq_task_lock);
@@ -303,7 +303,7 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
}
spin_unlock_irq(&rtc->irq_task_lock);
- mutex_unlock(&rtc->char_lock);
+ clear_bit(RTC_DEV_BUSY, &rtc->flags);
return retval;
}
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 814583bd2fe..ae1bf177d62 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -26,10 +26,7 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
struct rtc_device, char_dev);
const struct rtc_class_ops *ops = rtc->ops;
- /* We keep the lock as long as the device is in use
- * and return immediately if busy
- */
- if (!(mutex_trylock(&rtc->char_lock)))
+ if (test_and_set_bit(RTC_DEV_BUSY, &rtc->flags))
return -EBUSY;
file->private_data = rtc;
@@ -43,8 +40,8 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
return 0;
}
- /* something has gone wrong, release the lock */
- mutex_unlock(&rtc->char_lock);
+ /* something has gone wrong */
+ clear_bit(RTC_DEV_BUSY, &rtc->flags);
return err;
}
@@ -405,7 +402,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
if (rtc->ops->release)
rtc->ops->release(rtc->dev.parent);
- mutex_unlock(&rtc->char_lock);
+ clear_bit(RTC_DEV_BUSY, &rtc->flags);
return 0;
}
@@ -440,7 +437,6 @@ void rtc_dev_prepare(struct rtc_device *rtc)
rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
- mutex_init(&rtc->char_lock);
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
INIT_WORK(&rtc->uie_task, rtc_uie_task);
setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c
index ac67394c737..64d40a2d4d4 100644
--- a/drivers/scsi/zorro7xx.c
+++ b/drivers/scsi/zorro7xx.c
@@ -13,7 +13,10 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/zorro.h>
+
+#include <asm/amigahw.h>
#include <asm/amigaints.h>
+
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_spi.h>
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index f3257f708ef..9c95bc0398a 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -45,8 +45,6 @@
#include "ip22zilog.h"
-void ip22_do_break(void);
-
/*
* On IP22 we need to delay after register accesses but we do not need to
* flush writes.
@@ -81,12 +79,9 @@ struct uart_ip22zilog_port {
#define IP22ZILOG_FLAG_REGS_HELD 0x00000040
#define IP22ZILOG_FLAG_TX_STOPPED 0x00000080
#define IP22ZILOG_FLAG_TX_ACTIVE 0x00000100
+#define IP22ZILOG_FLAG_RESET_DONE 0x00000200
- unsigned int cflag;
-
- /* L1-A keyboard break state. */
- int kbd_id;
- int l1_down;
+ unsigned int tty_break;
unsigned char parity_mask;
unsigned char prev_status;
@@ -250,13 +245,26 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up,
}
}
-static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
- struct zilog_channel *channel)
+#define Rx_BRK 0x0100 /* BREAK event software flag. */
+#define Rx_SYS 0x0200 /* SysRq event software flag. */
+
+static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
+ struct zilog_channel *channel)
{
- struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */
+ struct tty_struct *tty;
+ unsigned char ch, flag;
+ unsigned int r1;
+
+ tty = NULL;
+ if (up->port.info != NULL &&
+ up->port.info->tty != NULL)
+ tty = up->port.info->tty;
- while (1) {
- unsigned char ch, r1, flag;
+ for (;;) {
+ ch = readb(&channel->control);
+ ZSDELAY();
+ if (!(ch & Rx_CH_AV))
+ break;
r1 = read_zsreg(channel, R1);
if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
@@ -265,43 +273,26 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
ZS_WSYNC(channel);
}
- ch = readb(&channel->control);
- ZSDELAY();
-
- /* This funny hack depends upon BRK_ABRT not interfering
- * with the other bits we care about in R1.
- */
- if (ch & BRK_ABRT)
- r1 |= BRK_ABRT;
-
ch = readb(&channel->data);
ZSDELAY();
ch &= up->parity_mask;
- if (ZS_IS_CONS(up) && (r1 & BRK_ABRT)) {
- /* Wait for BREAK to deassert to avoid potentially
- * confusing the PROM.
- */
- while (1) {
- ch = readb(&channel->control);
- ZSDELAY();
- if (!(ch & BRK_ABRT))
- break;
- }
- ip22_do_break();
- return;
- }
+ /* Handle the null char got when BREAK is removed. */
+ if (!ch)
+ r1 |= up->tty_break;
/* A real serial line, record the character and status. */
flag = TTY_NORMAL;
up->port.icount.rx++;
- if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
- if (r1 & BRK_ABRT) {
- r1 &= ~(PAR_ERR | CRC_ERR);
+ if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | Rx_SYS | Rx_BRK)) {
+ up->tty_break = 0;
+
+ if (r1 & (Rx_SYS | Rx_BRK)) {
up->port.icount.brk++;
- if (uart_handle_break(&up->port))
- goto next_char;
+ if (r1 & Rx_SYS)
+ continue;
+ r1 &= ~(PAR_ERR | CRC_ERR);
}
else if (r1 & PAR_ERR)
up->port.icount.parity++;
@@ -310,30 +301,21 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
if (r1 & Rx_OVR)
up->port.icount.overrun++;
r1 &= up->port.read_status_mask;
- if (r1 & BRK_ABRT)
+ if (r1 & Rx_BRK)
flag = TTY_BREAK;
else if (r1 & PAR_ERR)
flag = TTY_PARITY;
else if (r1 & CRC_ERR)
flag = TTY_FRAME;
}
- if (uart_handle_sysrq_char(&up->port, ch))
- goto next_char;
- if (up->port.ignore_status_mask == 0xff ||
- (r1 & up->port.ignore_status_mask) == 0)
- tty_insert_flip_char(tty, ch, flag);
+ if (uart_handle_sysrq_char(&up->port, ch))
+ continue;
- if (r1 & Rx_OVR)
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
- next_char:
- ch = readb(&channel->control);
- ZSDELAY();
- if (!(ch & Rx_CH_AV))
- break;
+ if (tty)
+ uart_insert_char(&up->port, r1, Rx_OVR, ch, flag);
}
-
- tty_flip_buffer_push(tty);
+ return tty;
}
static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
@@ -348,6 +330,15 @@ static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
ZSDELAY();
ZS_WSYNC(channel);
+ if (up->curregs[R15] & BRKIE) {
+ if ((status & BRK_ABRT) && !(up->prev_status & BRK_ABRT)) {
+ if (uart_handle_break(&up->port))
+ up->tty_break = Rx_SYS;
+ else
+ up->tty_break = Rx_BRK;
+ }
+ }
+
if (ZS_WANTS_MODEM_STATUS(up)) {
if (status & SYNC)
up->port.icount.dsr++;
@@ -356,10 +347,10 @@ static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
* But it does not tell us which bit has changed, we have to keep
* track of this ourselves.
*/
- if ((status & DCD) ^ up->prev_status)
+ if ((status ^ up->prev_status) ^ DCD)
uart_handle_dcd_change(&up->port,
(status & DCD));
- if ((status & CTS) ^ up->prev_status)
+ if ((status ^ up->prev_status) ^ CTS)
uart_handle_cts_change(&up->port,
(status & CTS));
@@ -447,19 +438,21 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
while (up) {
struct zilog_channel *channel
= ZILOG_CHANNEL_FROM_PORT(&up->port);
+ struct tty_struct *tty;
unsigned char r3;
spin_lock(&up->port.lock);
r3 = read_zsreg(channel, R3);
/* Channel A */
+ tty = NULL;
if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
writeb(RES_H_IUS, &channel->control);
ZSDELAY();
ZS_WSYNC(channel);
if (r3 & CHARxIP)
- ip22zilog_receive_chars(up, channel);
+ tty = ip22zilog_receive_chars(up, channel);
if (r3 & CHAEXT)
ip22zilog_status_handle(up, channel);
if (r3 & CHATxIP)
@@ -467,18 +460,22 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
}
spin_unlock(&up->port.lock);
+ if (tty)
+ tty_flip_buffer_push(tty);
+
/* Channel B */
up = up->next;
channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
spin_lock(&up->port.lock);
+ tty = NULL;
if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
writeb(RES_H_IUS, &channel->control);
ZSDELAY();
ZS_WSYNC(channel);
if (r3 & CHBRxIP)
- ip22zilog_receive_chars(up, channel);
+ tty = ip22zilog_receive_chars(up, channel);
if (r3 & CHBEXT)
ip22zilog_status_handle(up, channel);
if (r3 & CHBTxIP)
@@ -486,6 +483,9 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
}
spin_unlock(&up->port.lock);
+ if (tty)
+ tty_flip_buffer_push(tty);
+
up = up->next;
}
@@ -681,11 +681,46 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
spin_unlock_irqrestore(&port->lock, flags);
}
+static void __ip22zilog_reset(struct uart_ip22zilog_port *up)
+{
+ struct zilog_channel *channel;
+ int i;
+
+ if (up->flags & IP22ZILOG_FLAG_RESET_DONE)
+ return;
+
+ /* Let pending transmits finish. */
+ channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+ for (i = 0; i < 1000; i++) {
+ unsigned char stat = read_zsreg(channel, R1);
+ if (stat & ALL_SNT)
+ break;
+ udelay(100);
+ }
+
+ if (!ZS_IS_CHANNEL_A(up)) {
+ up++;
+ channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+ }
+ write_zsreg(channel, R9, FHWRES);
+ ZSDELAY_LONG();
+ (void) read_zsreg(channel, R0);
+
+ up->flags |= IP22ZILOG_FLAG_RESET_DONE;
+ up->next->flags |= IP22ZILOG_FLAG_RESET_DONE;
+}
+
static void __ip22zilog_startup(struct uart_ip22zilog_port *up)
{
struct zilog_channel *channel;
channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+
+ __ip22zilog_reset(up);
+
+ __load_zsregs(channel, up->curregs);
+ /* set master interrupt enable */
+ write_zsreg(channel, R9, up->curregs[R9]);
up->prev_status = readb(&channel->control);
/* Enable receiver and transmitter. */
@@ -859,8 +894,6 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,
else
up->flags &= ~IP22ZILOG_FLAG_MODEM_STATUS;
- up->cflag = termios->c_cflag;
-
ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
uart_update_timeout(port, termios->c_cflag, baud);
@@ -992,74 +1025,29 @@ ip22zilog_console_write(struct console *con, const char *s, unsigned int count)
spin_unlock_irqrestore(&up->port.lock, flags);
}
-void
-ip22serial_console_termios(struct console *con, char *options)
-{
- int baud = 9600, bits = 8, cflag;
- int parity = 'n';
- int flow = 'n';
-
- if (options)
- uart_parse_options(options, &baud, &parity, &bits, &flow);
-
- cflag = CREAD | HUPCL | CLOCAL;
-
- switch (baud) {
- case 150: cflag |= B150; break;
- case 300: cflag |= B300; break;
- case 600: cflag |= B600; break;
- case 1200: cflag |= B1200; break;
- case 2400: cflag |= B2400; break;
- case 4800: cflag |= B4800; break;
- case 9600: cflag |= B9600; break;
- case 19200: cflag |= B19200; break;
- case 38400: cflag |= B38400; break;
- default: baud = 9600; cflag |= B9600; break;
- }
-
- con->cflag = cflag | CS8; /* 8N1 */
-
- uart_update_timeout(&ip22zilog_port_table[con->index].port, cflag, baud);
-}
-
static int __init ip22zilog_console_setup(struct console *con, char *options)
{
struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
unsigned long flags;
- int baud, brg;
-
- printk("Console: ttyS%d (IP22-Zilog)\n", con->index);
+ int baud = 9600, bits = 8;
+ int parity = 'n';
+ int flow = 'n';
- /* Get firmware console settings. */
- ip22serial_console_termios(con, options);
+ up->flags |= IP22ZILOG_FLAG_IS_CONS;
- /* Firmware console speed is limited to 150-->38400 baud so
- * this hackish cflag thing is OK.
- */
- switch (con->cflag & CBAUD) {
- case B150: baud = 150; break;
- case B300: baud = 300; break;
- case B600: baud = 600; break;
- case B1200: baud = 1200; break;
- case B2400: baud = 2400; break;
- case B4800: baud = 4800; break;
- default: case B9600: baud = 9600; break;
- case B19200: baud = 19200; break;
- case B38400: baud = 38400; break;
- };
-
- brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+ printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index);
spin_lock_irqsave(&up->port.lock, flags);
- up->curregs[R15] = BRKIE;
- ip22zilog_convert_to_zs(up, con->cflag, 0, brg);
+ up->curregs[R15] |= BRKIE;
__ip22zilog_startup(up);
spin_unlock_irqrestore(&up->port.lock, flags);
- return 0;
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+ return uart_set_options(&up->port, con, baud, parity, bits, flow);
}
static struct uart_driver ip22zilog_reg;
@@ -1140,25 +1128,10 @@ static void __init ip22zilog_prepare(void)
up[(chip * 2) + 1].port.line = (chip * 2) + 1;
up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
}
-}
-
-static void __init ip22zilog_init_hw(void)
-{
- int i;
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
- struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
- unsigned long flags;
- int baud, brg;
- spin_lock_irqsave(&up->port.lock, flags);
-
- if (ZS_IS_CHANNEL_A(up)) {
- write_zsreg(channel, R9, FHWRES);
- ZSDELAY_LONG();
- (void) read_zsreg(channel, R0);
- }
+ for (channel = 0; channel < NUM_CHANNELS; channel++) {
+ struct uart_ip22zilog_port *up = &ip22zilog_port_table[channel];
+ int brg;
/* Normal serial TTY. */
up->parity_mask = 0xff;
@@ -1169,16 +1142,10 @@ static void __init ip22zilog_init_hw(void)
up->curregs[R9] = NV | MIE;
up->curregs[R10] = NRZ;
up->curregs[R11] = TCBR | RCBR;
- baud = 9600;
- brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+ brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR);
up->curregs[R12] = (brg & 0xff);
up->curregs[R13] = (brg >> 8) & 0xff;
up->curregs[R14] = BRENAB;
- __load_zsregs(channel, up->curregs);
- /* set master interrupt enable */
- write_zsreg(channel, R9, up->curregs[R9]);
-
- spin_unlock_irqrestore(&up->port.lock, flags);
}
}
@@ -1195,8 +1162,6 @@ static int __init ip22zilog_ports_init(void)
panic("IP22-Zilog: Unable to register zs interrupt handler.\n");
}
- ip22zilog_init_hw();
-
ret = uart_register_driver(&ip22zilog_reg);
if (ret == 0) {
int i;
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index af3a011b2b2..352fcb8926a 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -585,11 +585,11 @@ serial_pxa_type(struct uart_port *port)
return up->name;
}
-#ifdef CONFIG_SERIAL_PXA_CONSOLE
-
static struct uart_pxa_port *serial_pxa_ports[4];
static struct uart_driver serial_pxa_reg;
+#ifdef CONFIG_SERIAL_PXA_CONSOLE
+
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
/*
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 0d342dcdd30..ff6a14bf128 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -497,7 +497,7 @@ static int atmel_spi_setup(struct spi_device *spi)
/* chipselect must have been muxed as GPIO (e.g. in board setup) */
npcs_pin = (unsigned int)spi->controller_data;
if (!spi->controller_state) {
- ret = gpio_request(npcs_pin, "spi_npcs");
+ ret = gpio_request(npcs_pin, spi->dev.bus_id);
if (ret)
return ret;
spi->controller_state = (void *)npcs_pin;
diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c
index 0fa25e2e80f..109d82c1abc 100644
--- a/drivers/spi/spi_s3c24xx_gpio.c
+++ b/drivers/spi/spi_s3c24xx_gpio.c
@@ -96,6 +96,7 @@ static void s3c2410_spigpio_chipselect(struct spi_device *dev, int value)
static int s3c2410_spigpio_probe(struct platform_device *dev)
{
+ struct s3c2410_spigpio_info *info;
struct spi_master *master;
struct s3c2410_spigpio *sp;
int ret;
@@ -113,10 +114,11 @@ static int s3c2410_spigpio_probe(struct platform_device *dev)
platform_set_drvdata(dev, sp);
/* copy in the plkatform data */
- sp->info = dev->dev.platform_data;
+ info = sp->info = dev->dev.platform_data;
/* setup spi bitbang adaptor */
sp->bitbang.master = spi_master_get(master);
+ sp->bitbang.master->bus_num = info->bus_num;
sp->bitbang.chipselect = s3c2410_spigpio_chipselect;
sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0;
@@ -124,13 +126,18 @@ static int s3c2410_spigpio_probe(struct platform_device *dev)
sp->bitbang.txrx_word[SPI_MODE_2] = s3c2410_spigpio_txrx_mode2;
sp->bitbang.txrx_word[SPI_MODE_3] = s3c2410_spigpio_txrx_mode3;
- /* set state of spi pins */
- s3c2410_gpio_setpin(sp->info->pin_clk, 0);
- s3c2410_gpio_setpin(sp->info->pin_mosi, 0);
+ /* set state of spi pins, always assume that the clock is
+ * available, but do check the MOSI and MISO. */
+ s3c2410_gpio_setpin(info->pin_clk, 0);
+ s3c2410_gpio_cfgpin(info->pin_clk, S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_cfgpin(sp->info->pin_clk, S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_cfgpin(sp->info->pin_mosi, S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_cfgpin(sp->info->pin_miso, S3C2410_GPIO_INPUT);
+ if (info->pin_mosi < S3C2410_GPH10) {
+ s3c2410_gpio_setpin(info->pin_mosi, 0);
+ s3c2410_gpio_cfgpin(info->pin_mosi, S3C2410_GPIO_OUTPUT);
+ }
+
+ if (info->pin_miso != S3C2410_GPA0 && info->pin_miso < S3C2410_GPH10)
+ s3c2410_gpio_cfgpin(info->pin_miso, S3C2410_GPIO_INPUT);
ret = spi_bitbang_start(&sp->bitbang);
if (ret)
diff --git a/drivers/usb/README b/drivers/usb/README
index 3c843412855..284f46b3e1c 100644
--- a/drivers/usb/README
+++ b/drivers/usb/README
@@ -39,12 +39,12 @@ first subdirectory in the list below that it fits into.
image/ - This is for still image drivers, like scanners or
digital cameras.
-input/ - This is for any driver that uses the input subsystem,
+../input/ - This is for any driver that uses the input subsystem,
like keyboard, mice, touchscreens, tablets, etc.
-media/ - This is for multimedia drivers, like video cameras,
+../media/ - This is for multimedia drivers, like video cameras,
radios, and any other drivers that talk to the v4l
subsystem.
-net/ - This is for network drivers.
+../net/ - This is for network drivers.
serial/ - This is for USB to serial drivers.
storage/ - This is for USB mass-storage drivers.
class/ - This is for all USB device drivers that do not fit
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 8586817698a..c51f8e9312e 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -585,9 +585,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct usb_device *usb_dev;
- if (!dev)
- return -ENODEV;
-
/* driver is often null here; dev_dbg() would oops */
pr_debug ("usb %s: uevent\n", dev->bus_id);
@@ -631,14 +628,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM;
- if (add_uevent_var(env, "BUSNUM=%03d",
- usb_dev->bus->busnum))
- return -ENOMEM;
-
- if (add_uevent_var(env, "DEVNUM=%03d",
- usb_dev->devnum))
- return -ENOMEM;
-
return 0;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index fea8256a18d..d5ed3fa9e30 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1311,8 +1311,8 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
hcd = bus_to_hcd(udev->bus);
/* No more submits can occur */
-rescan:
spin_lock_irq(&hcd_urb_list_lock);
+rescan:
list_for_each_entry (urb, &ep->urb_list, urb_list) {
int is_in;
@@ -1345,6 +1345,7 @@ rescan:
usb_put_urb (urb);
/* list contents may have changed */
+ spin_lock(&hcd_urb_list_lock);
goto rescan;
}
spin_unlock_irq(&hcd_urb_list_lock);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 036c3dea855..13b326a1337 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -335,7 +335,7 @@ static void kick_khubd(struct usb_hub *hub)
to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
spin_lock_irqsave(&hub_event_lock, flags);
- if (!hub->disconnected & list_empty(&hub->event_list)) {
+ if (!hub->disconnected && list_empty(&hub->event_list)) {
list_add_tail(&hub->event_list, &hub_event_list);
wake_up(&khubd_wait);
}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 316a746e008..fcd40ecbeec 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1172,7 +1172,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
struct usb_host_interface *alt;
int ret;
int manual = 0;
- int changed;
if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
@@ -1212,8 +1211,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
*/
/* prevent submissions using previous endpoint settings */
- changed = (iface->cur_altsetting != alt);
- if (changed && device_is_registered(&iface->dev))
+ if (iface->cur_altsetting != alt && device_is_registered(&iface->dev))
usb_remove_sysfs_intf_files(iface);
usb_disable_interface(dev, iface);
@@ -1250,7 +1248,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* (Likewise, EP0 never "halts" on well designed devices.)
*/
usb_enable_interface(dev, iface);
- if (changed && device_is_registered(&iface->dev))
+ if (device_is_registered(&iface->dev))
usb_create_sysfs_intf_files(iface);
return 0;
@@ -1348,34 +1346,10 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
struct usb_interface *intf;
struct usb_host_interface *alt;
- if (!dev)
- return -ENODEV;
-
- /* driver is often null here; dev_dbg() would oops */
- pr_debug ("usb %s: uevent\n", dev->bus_id);
-
intf = to_usb_interface(dev);
usb_dev = interface_to_usbdev(intf);
alt = intf->cur_altsetting;
-#ifdef CONFIG_USB_DEVICEFS
- if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
- usb_dev->bus->busnum, usb_dev->devnum))
- return -ENOMEM;
-#endif
-
- if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
- le16_to_cpu(usb_dev->descriptor.idVendor),
- le16_to_cpu(usb_dev->descriptor.idProduct),
- le16_to_cpu(usb_dev->descriptor.bcdDevice)))
- return -ENOMEM;
-
- if (add_uevent_var(env, "TYPE=%d/%d/%d",
- usb_dev->descriptor.bDeviceClass,
- usb_dev->descriptor.bDeviceSubClass,
- usb_dev->descriptor.bDeviceProtocol))
- return -ENOMEM;
-
if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
@@ -1641,12 +1615,6 @@ free_interfaces:
intf->dev.bus_id, ret);
continue;
}
-
- /* The driver's probe method can call usb_set_interface(),
- * which would mean the interface's sysfs files are already
- * created. Just in case, we'll remove them first.
- */
- usb_remove_sysfs_intf_files(intf);
usb_create_sysfs_intf_files(intf);
}
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index b04afd06e50..32bd130b1ee 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -735,6 +735,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
struct usb_host_interface *alt = intf->cur_altsetting;
int retval;
+ if (intf->sysfs_files_created)
+ return 0;
retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
if (retval)
return retval;
@@ -746,6 +748,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
if (intf->intf_assoc)
retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
usb_create_intf_ep_files(intf, udev);
+ intf->sysfs_files_created = 1;
return 0;
}
@@ -753,8 +756,11 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf)
{
struct device *dev = &intf->dev;
+ if (!intf->sysfs_files_created)
+ return;
usb_remove_intf_ep_files(intf);
device_remove_file(dev, &dev_attr_interface);
sysfs_remove_group(&dev->kobj, &intf_attr_grp);
sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
+ intf->sysfs_files_created = 0;
}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index c4a6f1095b8..8f142370103 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -192,9 +192,34 @@ static void usb_release_dev(struct device *dev)
kfree(udev);
}
+#ifdef CONFIG_HOTPLUG
+static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct usb_device *usb_dev;
+
+ usb_dev = to_usb_device(dev);
+
+ if (add_uevent_var(env, "BUSNUM=%03d", usb_dev->bus->busnum))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "DEVNUM=%03d", usb_dev->devnum))
+ return -ENOMEM;
+
+ return 0;
+}
+
+#else
+
+static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_HOTPLUG */
+
struct device_type usb_device_type = {
.name = "usb_device",
.release = usb_release_dev,
+ .uevent = usb_dev_uevent,
};
#ifdef CONFIG_PM
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 87c4f50dfb6..d377154658b 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -1241,14 +1241,14 @@ static void pullup_enable(struct omap_udc *udc)
udc->gadget.dev.parent->power.power_state = PMSG_ON;
udc->gadget.dev.power.power_state = PMSG_ON;
UDC_SYSCON1_REG |= UDC_PULLUP_EN;
- if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx())
+ if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
OTG_CTRL_REG |= OTG_BSESSVLD;
UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
}
static void pullup_disable(struct omap_udc *udc)
{
- if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx())
+ if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
OTG_CTRL_REG &= ~OTG_BSESSVLD;
UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
UDC_SYSCON1_REG &= ~UDC_PULLUP_EN;
@@ -1386,7 +1386,7 @@ static void update_otg(struct omap_udc *udc)
{
u16 devstat;
- if (!gadget_is_otg(udc->gadget))
+ if (!gadget_is_otg(&udc->gadget))
return;
if (OTG_CTRL_REG & OTG_ID)
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index e3e90f8a75e..4ce050c3d13 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -52,10 +52,10 @@
#include <asm/arch/irqs.h>
#include <asm/arch/hardware.h>
-#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-udc.h>
-#include <asm/arch/udc.h>
+
+#include <asm/plat-s3c24xx/regs-udc.h>
+#include <asm/plat-s3c24xx/udc.h>
#include <asm/mach-types.h>
@@ -1511,7 +1511,11 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev)
unsigned int value;
dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+ /* some cpus cannot read from an line configured to IRQ! */
+ s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_INPUT);
value = s3c2410_gpio_getpin(udc_info->vbus_pin);
+ s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_SFN2);
if (udc_info->vbus_pin_inverted)
value = !value;
@@ -1872,9 +1876,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
if (udc_info && udc_info->vbus_pin > 0) {
irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
retval = request_irq(irq, s3c2410_udc_vbus_irq,
- IRQF_DISABLED | IRQF_TRIGGER_RISING
- | IRQF_TRIGGER_FALLING,
- gadget_name, udc);
+ IRQF_DISABLED | IRQF_TRIGGER_RISING
+ | IRQF_TRIGGER_FALLING | IRQF_SHARED,
+ gadget_name, udc);
if (retval != 0) {
dev_err(dev, "can't get vbus irq %i, err %d\n",
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 177e78ed241..49a91c5ee51 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
config USB_OHCI_HCD_SSB
bool "OHCI support for Broadcom SSB OHCI core"
- depends on USB_OHCI_HCD && (SSB = y || SSB = CONFIG_USB_OHCI_HCD) && EXPERIMENTAL
+ depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL
default n
---help---
Support for the Sonics Silicon Backplane (SSB) attached
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c1514442883..5f2d74ed5ad 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -575,12 +575,15 @@ static int ehci_run (struct usb_hcd *hcd)
* from the companions to the EHCI controller. If any of the
* companions are in the middle of a port reset at the time, it
* could cause trouble. Write-locking ehci_cf_port_reset_rwsem
- * guarantees that no resets are in progress.
+ * guarantees that no resets are in progress. After we set CF,
+ * a short delay lets the hardware catch up; new resets shouldn't
+ * be started before the port switching actions could complete.
*/
down_write(&ehci_cf_port_reset_rwsem);
hcd->state = HC_STATE_RUNNING;
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+ msleep(5);
up_write(&ehci_cf_port_reset_rwsem);
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 91e999c9f68..bc207e3c21f 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -819,7 +819,7 @@ static int mts_usb_probe(struct usb_interface *intf,
goto out_kfree2;
new_desc->host->hostdata[0] = (unsigned long)new_desc;
- if (scsi_add_host(new_desc->host, NULL)) {
+ if (scsi_add_host(new_desc->host, &dev->dev)) {
err_retval = -EIO;
goto out_host_put;
}
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index c567aa7a41e..5a2c44e4c1f 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -79,12 +79,22 @@ MODULE_DEVICE_TABLE(usb, device_table);
#define COMMAND_TIMEOUT (2*HZ) /* 60 second timeout for a command */
+/*
+ * The locking scheme is a vanilla 3-lock:
+ * adu_device.buflock: A spinlock, covers what IRQs touch.
+ * adutux_mutex: A Static lock to cover open_count. It would also cover
+ * any globals, but we don't have them in 2.6.
+ * adu_device.mtx: A mutex to hold across sleepers like copy_from_user.
+ * It covers all of adu_device, except the open_count
+ * and what .buflock covers.
+ */
+
/* Structure to hold all of our device specific stuff */
struct adu_device {
- struct mutex mtx; /* locks this structure */
+ struct mutex mtx;
struct usb_device* udev; /* save off the usb device pointer */
struct usb_interface* interface;
- unsigned char minor; /* the starting minor number for this device */
+ unsigned int minor; /* the starting minor number for this device */
char serial_number[8];
int open_count; /* number of times this port has been opened */
@@ -107,8 +117,11 @@ struct adu_device {
char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint;
struct urb* interrupt_out_urb;
+ int out_urb_finished;
};
+static DEFINE_MUTEX(adutux_mutex);
+
static struct usb_driver adu_driver;
static void adu_debug_data(int level, const char *function, int size,
@@ -132,27 +145,31 @@ static void adu_debug_data(int level, const char *function, int size,
*/
static void adu_abort_transfers(struct adu_device *dev)
{
- dbg(2," %s : enter", __FUNCTION__);
+ unsigned long flags;
- if (dev == NULL) {
- dbg(1," %s : dev is null", __FUNCTION__);
- goto exit;
- }
+ dbg(2," %s : enter", __FUNCTION__);
if (dev->udev == NULL) {
dbg(1," %s : udev is null", __FUNCTION__);
goto exit;
}
- dbg(2," %s : udev state %d", __FUNCTION__, dev->udev->state);
- if (dev->udev->state == USB_STATE_NOTATTACHED) {
- dbg(1," %s : udev is not attached", __FUNCTION__);
- goto exit;
- }
-
/* shutdown transfer */
- usb_unlink_urb(dev->interrupt_in_urb);
- usb_unlink_urb(dev->interrupt_out_urb);
+
+ /* XXX Anchor these instead */
+ spin_lock_irqsave(&dev->buflock, flags);
+ if (!dev->read_urb_finished) {
+ spin_unlock_irqrestore(&dev->buflock, flags);
+ usb_kill_urb(dev->interrupt_in_urb);
+ } else
+ spin_unlock_irqrestore(&dev->buflock, flags);
+
+ spin_lock_irqsave(&dev->buflock, flags);
+ if (!dev->out_urb_finished) {
+ spin_unlock_irqrestore(&dev->buflock, flags);
+ usb_kill_urb(dev->interrupt_out_urb);
+ } else
+ spin_unlock_irqrestore(&dev->buflock, flags);
exit:
dbg(2," %s : leave", __FUNCTION__);
@@ -162,8 +179,6 @@ static void adu_delete(struct adu_device *dev)
{
dbg(2, "%s enter", __FUNCTION__);
- adu_abort_transfers(dev);
-
/* free data structures */
usb_free_urb(dev->interrupt_in_urb);
usb_free_urb(dev->interrupt_out_urb);
@@ -239,7 +254,10 @@ static void adu_interrupt_out_callback(struct urb *urb)
goto exit;
}
- wake_up_interruptible(&dev->write_wait);
+ spin_lock(&dev->buflock);
+ dev->out_urb_finished = 1;
+ wake_up(&dev->write_wait);
+ spin_unlock(&dev->buflock);
exit:
adu_debug_data(5, __FUNCTION__, urb->actual_length,
@@ -252,12 +270,17 @@ static int adu_open(struct inode *inode, struct file *file)
struct adu_device *dev = NULL;
struct usb_interface *interface;
int subminor;
- int retval = 0;
+ int retval;
dbg(2,"%s : enter", __FUNCTION__);
subminor = iminor(inode);
+ if ((retval = mutex_lock_interruptible(&adutux_mutex))) {
+ dbg(2, "%s : mutex lock failed", __FUNCTION__);
+ goto exit_no_lock;
+ }
+
interface = usb_find_interface(&adu_driver, subminor);
if (!interface) {
err("%s - error, can't find device for minor %d",
@@ -267,54 +290,54 @@ static int adu_open(struct inode *inode, struct file *file)
}
dev = usb_get_intfdata(interface);
- if (!dev) {
+ if (!dev || !dev->udev) {
retval = -ENODEV;
goto exit_no_device;
}
- /* lock this device */
- if ((retval = mutex_lock_interruptible(&dev->mtx))) {
- dbg(2, "%s : mutex lock failed", __FUNCTION__);
+ /* check that nobody else is using the device */
+ if (dev->open_count) {
+ retval = -EBUSY;
goto exit_no_device;
}
- /* increment our usage count for the device */
++dev->open_count;
dbg(2,"%s : open count %d", __FUNCTION__, dev->open_count);
/* save device in the file's private structure */
file->private_data = dev;
- if (dev->open_count == 1) {
- /* initialize in direction */
- dev->read_buffer_length = 0;
+ /* initialize in direction */
+ dev->read_buffer_length = 0;
- /* fixup first read by having urb waiting for it */
- usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
- usb_rcvintpipe(dev->udev,
- dev->interrupt_in_endpoint->bEndpointAddress),
- dev->interrupt_in_buffer,
- le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
- adu_interrupt_in_callback, dev,
- dev->interrupt_in_endpoint->bInterval);
- /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
- dev->read_urb_finished = 0;
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
- if (retval)
- --dev->open_count;
- }
- mutex_unlock(&dev->mtx);
+ /* fixup first read by having urb waiting for it */
+ usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
+ usb_rcvintpipe(dev->udev,
+ dev->interrupt_in_endpoint->bEndpointAddress),
+ dev->interrupt_in_buffer,
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
+ adu_interrupt_in_callback, dev,
+ dev->interrupt_in_endpoint->bInterval);
+ dev->read_urb_finished = 0;
+ if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL))
+ dev->read_urb_finished = 1;
+ /* we ignore failure */
+ /* end of fixup for first read */
+
+ /* initialize out direction */
+ dev->out_urb_finished = 1;
+
+ retval = 0;
exit_no_device:
+ mutex_unlock(&adutux_mutex);
+exit_no_lock:
dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval);
-
return retval;
}
-static int adu_release_internal(struct adu_device *dev)
+static void adu_release_internal(struct adu_device *dev)
{
- int retval = 0;
-
dbg(2," %s : enter", __FUNCTION__);
/* decrement our usage count for the device */
@@ -326,12 +349,11 @@ static int adu_release_internal(struct adu_device *dev)
}
dbg(2," %s : leave", __FUNCTION__);
- return retval;
}
static int adu_release(struct inode *inode, struct file *file)
{
- struct adu_device *dev = NULL;
+ struct adu_device *dev;
int retval = 0;
dbg(2," %s : enter", __FUNCTION__);
@@ -343,15 +365,13 @@ static int adu_release(struct inode *inode, struct file *file)
}
dev = file->private_data;
-
if (dev == NULL) {
dbg(1," %s : object is NULL", __FUNCTION__);
retval = -ENODEV;
goto exit;
}
- /* lock our device */
- mutex_lock(&dev->mtx); /* not interruptible */
+ mutex_lock(&adutux_mutex); /* not interruptible */
if (dev->open_count <= 0) {
dbg(1," %s : device not opened", __FUNCTION__);
@@ -359,19 +379,15 @@ static int adu_release(struct inode *inode, struct file *file)
goto exit;
}
+ adu_release_internal(dev);
if (dev->udev == NULL) {
/* the device was unplugged before the file was released */
- mutex_unlock(&dev->mtx);
- adu_delete(dev);
- dev = NULL;
- } else {
- /* do the work */
- retval = adu_release_internal(dev);
+ if (!dev->open_count) /* ... and we're the last user */
+ adu_delete(dev);
}
exit:
- if (dev)
- mutex_unlock(&dev->mtx);
+ mutex_unlock(&adutux_mutex);
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
return retval;
}
@@ -393,12 +409,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
dev = file->private_data;
dbg(2," %s : dev=%p", __FUNCTION__, dev);
- /* lock this object */
+
if (mutex_lock_interruptible(&dev->mtx))
return -ERESTARTSYS;
/* verify that the device wasn't unplugged */
- if (dev->udev == NULL || dev->minor == 0) {
+ if (dev->udev == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d", retval);
goto exit;
@@ -452,7 +468,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
should_submit = 1;
} else {
/* even the primary was empty - we may need to do IO */
- if (dev->interrupt_in_urb->status == -EINPROGRESS) {
+ if (!dev->read_urb_finished) {
/* somebody is doing IO */
spin_unlock_irqrestore(&dev->buflock, flags);
dbg(2," %s : submitted already", __FUNCTION__);
@@ -460,6 +476,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
/* we must initiate input */
dbg(2," %s : initiate input", __FUNCTION__);
dev->read_urb_finished = 0;
+ spin_unlock_irqrestore(&dev->buflock, flags);
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
usb_rcvintpipe(dev->udev,
@@ -469,15 +486,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
adu_interrupt_in_callback,
dev,
dev->interrupt_in_endpoint->bInterval);
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
- if (!retval) {
- spin_unlock_irqrestore(&dev->buflock, flags);
- dbg(2," %s : submitted OK", __FUNCTION__);
- } else {
+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ if (retval) {
+ dev->read_urb_finished = 1;
if (retval == -ENOMEM) {
retval = bytes_read ? bytes_read : -ENOMEM;
}
- spin_unlock_irqrestore(&dev->buflock, flags);
dbg(2," %s : submit failed", __FUNCTION__);
goto exit;
}
@@ -486,10 +500,14 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
/* we wait for I/O to complete */
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&dev->read_wait, &wait);
- if (!dev->read_urb_finished)
+ spin_lock_irqsave(&dev->buflock, flags);
+ if (!dev->read_urb_finished) {
+ spin_unlock_irqrestore(&dev->buflock, flags);
timeout = schedule_timeout(COMMAND_TIMEOUT);
- else
+ } else {
+ spin_unlock_irqrestore(&dev->buflock, flags);
set_current_state(TASK_RUNNING);
+ }
remove_wait_queue(&dev->read_wait, &wait);
if (timeout <= 0) {
@@ -509,19 +527,23 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
retval = bytes_read;
/* if the primary buffer is empty then use it */
- if (should_submit && !dev->interrupt_in_urb->status==-EINPROGRESS) {
+ spin_lock_irqsave(&dev->buflock, flags);
+ if (should_submit && dev->read_urb_finished) {
+ dev->read_urb_finished = 0;
+ spin_unlock_irqrestore(&dev->buflock, flags);
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
usb_rcvintpipe(dev->udev,
dev->interrupt_in_endpoint->bEndpointAddress),
- dev->interrupt_in_buffer,
- le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
- adu_interrupt_in_callback,
- dev,
- dev->interrupt_in_endpoint->bInterval);
- /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
- dev->read_urb_finished = 0;
- usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ dev->interrupt_in_buffer,
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
+ adu_interrupt_in_callback,
+ dev,
+ dev->interrupt_in_endpoint->bInterval);
+ if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL) != 0)
+ dev->read_urb_finished = 1;
/* we ignore failure */
+ } else {
+ spin_unlock_irqrestore(&dev->buflock, flags);
}
exit:
@@ -535,24 +557,24 @@ exit:
static ssize_t adu_write(struct file *file, const __user char *buffer,
size_t count, loff_t *ppos)
{
+ DECLARE_WAITQUEUE(waita, current);
struct adu_device *dev;
size_t bytes_written = 0;
size_t bytes_to_write;
size_t buffer_size;
+ unsigned long flags;
int retval;
- int timeout = 0;
dbg(2," %s : enter, count = %Zd", __FUNCTION__, count);
dev = file->private_data;
- /* lock this object */
retval = mutex_lock_interruptible(&dev->mtx);
if (retval)
goto exit_nolock;
/* verify that the device wasn't unplugged */
- if (dev->udev == NULL || dev->minor == 0) {
+ if (dev->udev == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d", retval);
goto exit;
@@ -564,42 +586,37 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
goto exit;
}
-
while (count > 0) {
- if (dev->interrupt_out_urb->status == -EINPROGRESS) {
- timeout = COMMAND_TIMEOUT;
+ add_wait_queue(&dev->write_wait, &waita);
+ set_current_state(TASK_INTERRUPTIBLE);
+ spin_lock_irqsave(&dev->buflock, flags);
+ if (!dev->out_urb_finished) {
+ spin_unlock_irqrestore(&dev->buflock, flags);
- while (timeout > 0) {
- if (signal_pending(current)) {
+ mutex_unlock(&dev->mtx);
+ if (signal_pending(current)) {
dbg(1," %s : interrupted", __FUNCTION__);
+ set_current_state(TASK_RUNNING);
retval = -EINTR;
- goto exit;
+ goto exit_onqueue;
}
- mutex_unlock(&dev->mtx);
- timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout);
+ if (schedule_timeout(COMMAND_TIMEOUT) == 0) {
+ dbg(1, "%s - command timed out.", __FUNCTION__);
+ retval = -ETIMEDOUT;
+ goto exit_onqueue;
+ }
+ remove_wait_queue(&dev->write_wait, &waita);
retval = mutex_lock_interruptible(&dev->mtx);
if (retval) {
retval = bytes_written ? bytes_written : retval;
goto exit_nolock;
}
- if (timeout > 0) {
- break;
- }
- dbg(1," %s : interrupted timeout: %d", __FUNCTION__, timeout);
- }
-
-
- dbg(1," %s : final timeout: %d", __FUNCTION__, timeout);
-
- if (timeout == 0) {
- dbg(1, "%s - command timed out.", __FUNCTION__);
- retval = -ETIMEDOUT;
- goto exit;
- }
-
- dbg(4," %s : in progress, count = %Zd", __FUNCTION__, count);
+ dbg(4," %s : in progress, count = %Zd", __FUNCTION__, count);
} else {
+ spin_unlock_irqrestore(&dev->buflock, flags);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&dev->write_wait, &waita);
dbg(4," %s : sending, count = %Zd", __FUNCTION__, count);
/* write the data into interrupt_out_buffer from userspace */
@@ -622,11 +639,12 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
bytes_to_write,
adu_interrupt_out_callback,
dev,
- dev->interrupt_in_endpoint->bInterval);
- /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
+ dev->interrupt_out_endpoint->bInterval);
dev->interrupt_out_urb->actual_length = bytes_to_write;
+ dev->out_urb_finished = 0;
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
if (retval < 0) {
+ dev->out_urb_finished = 1;
err("Couldn't submit interrupt_out_urb %d", retval);
goto exit;
}
@@ -637,16 +655,17 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
bytes_written += bytes_to_write;
}
}
-
- retval = bytes_written;
+ mutex_unlock(&dev->mtx);
+ return bytes_written;
exit:
- /* unlock the device */
mutex_unlock(&dev->mtx);
exit_nolock:
-
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
+ return retval;
+exit_onqueue:
+ remove_wait_queue(&dev->write_wait, &waita);
return retval;
}
@@ -831,25 +850,22 @@ static void adu_disconnect(struct usb_interface *interface)
dbg(2," %s : enter", __FUNCTION__);
dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
+ mutex_lock(&dev->mtx); /* not interruptible */
+ dev->udev = NULL; /* poison */
minor = dev->minor;
-
- /* give back our minor */
usb_deregister_dev(interface, &adu_class);
- dev->minor = 0;
+ mutex_unlock(&dev->mtx);
- mutex_lock(&dev->mtx); /* not interruptible */
+ mutex_lock(&adutux_mutex);
+ usb_set_intfdata(interface, NULL);
/* if the device is not opened, then we clean up right now */
dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
- if (!dev->open_count) {
- mutex_unlock(&dev->mtx);
+ if (!dev->open_count)
adu_delete(dev);
- } else {
- dev->udev = NULL;
- mutex_unlock(&dev->mtx);
- }
+
+ mutex_unlock(&adutux_mutex);
dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
(minor - ADU_MINOR_BASE));
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index 49c5c5c4c43..06cb71942dc 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -144,12 +144,14 @@ static void led_disconnect(struct usb_interface *interface)
struct usb_led *dev;
dev = usb_get_intfdata (interface);
- usb_set_intfdata (interface, NULL);
device_remove_file(&interface->dev, &dev_attr_blue);
device_remove_file(&interface->dev, &dev_attr_red);
device_remove_file(&interface->dev, &dev_attr_green);
+ /* first remove the files, then set the pointer to NULL */
+ usb_set_intfdata (interface, NULL);
+
usb_put_dev(dev->udev);
kfree(dev);
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 9eb4a65ee4d..d41531139c5 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -327,6 +327,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
unsigned char *data = urb->transfer_buffer;
int status = urb->status;
+ unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -339,11 +340,11 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
/* Throttle the device if requested by tty */
- spin_lock(&port->lock);
+ spin_lock_irqsave(&port->lock, flags);
if (!(port->throttled = port->throttle_req))
/* Handle data and continue reading from device */
flush_and_resubmit_read_urb(port);
- spin_unlock(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
}
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 1f7ab15df36..feba9679ace 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1215,12 +1215,14 @@ static int keyspan_chars_in_buffer (struct usb_serial_port *port)
static int keyspan_open (struct usb_serial_port *port, struct file *filp)
{
- struct keyspan_port_private *p_priv;
- struct keyspan_serial_private *s_priv;
- struct usb_serial *serial = port->serial;
+ struct keyspan_port_private *p_priv;
+ struct keyspan_serial_private *s_priv;
+ struct usb_serial *serial = port->serial;
const struct keyspan_device_details *d_details;
int i, err;
+ int baud_rate, device_port;
struct urb *urb;
+ unsigned int cflag;
s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
@@ -1263,6 +1265,30 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
}
+ /* get the terminal config for the setup message now so we don't
+ * need to send 2 of them */
+
+ cflag = port->tty->termios->c_cflag;
+ device_port = port->number - port->serial->minor;
+
+ /* Baud rate calculation takes baud rate as an integer
+ so other rates can be generated if desired. */
+ baud_rate = tty_get_baud_rate(port->tty);
+ /* If no match or invalid, leave as default */
+ if (baud_rate >= 0
+ && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
+ NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
+ p_priv->baud = baud_rate;
+ }
+
+ /* set CTS/RTS handshake etc. */
+ p_priv->cflag = cflag;
+ p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
+
+ keyspan_send_setup(port, 1);
+ //mdelay(100);
+ //keyspan_set_termios(port, NULL);
+
return (0);
}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index a5ced7e08cb..c29c9127113 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -2711,7 +2711,7 @@ static int mos7840_startup(struct usb_serial *serial)
status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
if (status < 0) {
dbg("Writing ZLP_REG5 failed status-0x%x\n", status);
- return -1;
+ goto error;
} else
dbg("ZLP_REG5 Writing success status%d\n", status);
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 2cd3f1d4b68..cf8add91de0 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -86,6 +86,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
+ { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index ed603e3decd..d31f5d29998 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -104,3 +104,6 @@
#define WS002IN_VENDOR_ID 0x11f6
#define WS002IN_PRODUCT_ID 0x2001
+/* Corega CG-USBRS232R Serial Adapter */
+#define COREGA_VENDOR_ID 0x07aa
+#define COREGA_PRODUCT_ID 0x002a
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 833f6e1e372..605ebccdcd5 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -136,6 +136,8 @@ static struct usb_device_id id_table_3port [] = {
{ USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
+ { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
+ { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 1ba19eaa197..836a34ae6ec 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -177,6 +177,10 @@ static int slave_configure(struct scsi_device *sdev)
* is an occasional series of retries that will all fail. */
sdev->retry_hwerror = 1;
+ /* USB disks should allow restart. Some drives spin down
+ * automatically, requiring a START-STOP UNIT command. */
+ sdev->allow_restart = 1;
+
} else {
/* Non-disk-type devices don't need to blacklist any pages
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 22ab2380367..2c27721bd25 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -342,11 +342,11 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100,
US_FL_FIX_CAPACITY),
/* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */
-UNUSUAL_DEV( 0x04b0, 0x040f, 0x0200, 0x0200,
- "NIKON",
- "NIKON DSC D200",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_CAPACITY),
+UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200,
+ "NIKON",
+ "NIKON DSC D200",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
/* Reported by Emil Larsson <emil@swip.net> */
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
@@ -731,6 +731,13 @@ UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
#endif
+/* Reported by RTE <raszilki@yandex.ru> */
+UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141,
+ "JetFlash",
+ "TS1GJF2A/120",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_MAX_SECTORS_64 ),
+
/* Fabrizio Fellini <fello@libero.it> */
UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Fujifilm",
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7d86e9eae91..5b3dbcfcda4 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -641,6 +641,17 @@ config FB_VESA
You will get a boot time penguin logo at no additional cost. Please
read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
+config FB_EFI
+ bool "EFI-based Framebuffer Support"
+ depends on (FB = y) && X86
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the EFI frame buffer device driver. If the firmware on
+ your platform is UEFI2.0, select Y to add support for
+ Graphics Output Protocol for early console messages to appear.
+
config FB_IMAC
bool "Intel-based Macintosh Framebuffer Support"
depends on (FB = y) && X86 && EFI
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 59d6c45a910..83e02b3429b 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_FB_OMAP) += omap/
obj-$(CONFIG_FB_UVESA) += uvesafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o
obj-$(CONFIG_FB_IMAC) += imacfb.o
+obj-$(CONFIG_FB_EFI) += efifb.o
obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 235b618b411..11a3a222dfc 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -268,6 +268,10 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
/* Turn off the LCD controller and the DMA controller */
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
+ /* Wait for the LCDC core to become idle */
+ while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
+ msleep(10);
+
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
if (info->var.bits_per_pixel == 1)
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
new file mode 100644
index 00000000000..bd779ae44b1
--- /dev/null
+++ b/drivers/video/efifb.c
@@ -0,0 +1,232 @@
+/*
+ * Framebuffer driver for EFI/UEFI based system
+ *
+ * (c) 2006 Edgar Hucek <gimli@dark-green.com>
+ * Original efi driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+#include <linux/screen_info.h>
+
+#include <video/vga.h>
+
+static struct fb_var_screeninfo efifb_defined __initdata = {
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .right_margin = 32,
+ .upper_margin = 16,
+ .lower_margin = 4,
+ .vsync_len = 4,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo efifb_fix __initdata = {
+ .id = "EFI VGA",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .accel = FB_ACCEL_NONE,
+ .visual = FB_VISUAL_TRUECOLOR,
+};
+
+static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ /*
+ * Set a single color register. The values supplied are
+ * already rounded down to the hardware's capabilities
+ * (according to the entries in the `var' structure). Return
+ * != 0 for invalid regno.
+ */
+
+ if (regno >= info->cmap.len)
+ return 1;
+
+ if (regno < 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset);
+ }
+ return 0;
+}
+
+static struct fb_ops efifb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = efifb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static int __init efifb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ int err;
+ unsigned int size_vmode;
+ unsigned int size_remap;
+ unsigned int size_total;
+
+ efifb_fix.smem_start = screen_info.lfb_base;
+ efifb_defined.bits_per_pixel = screen_info.lfb_depth;
+ efifb_defined.xres = screen_info.lfb_width;
+ efifb_defined.yres = screen_info.lfb_height;
+ efifb_fix.line_length = screen_info.lfb_linelength;
+
+ /* size_vmode -- that is the amount of memory needed for the
+ * used video mode, i.e. the minimum amount of
+ * memory we need. */
+ size_vmode = efifb_defined.yres * efifb_fix.line_length;
+
+ /* size_total -- all video memory we have. Used for
+ * entries, ressource allocation and bounds
+ * checking. */
+ size_total = screen_info.lfb_size;
+ if (size_total < size_vmode)
+ size_total = size_vmode;
+
+ /* size_remap -- the amount of video memory we are going to
+ * use for efifb. With modern cards it is no
+ * option to simply use size_total as that
+ * wastes plenty of kernel address space. */
+ size_remap = size_vmode * 2;
+ if (size_remap < size_vmode)
+ size_remap = size_vmode;
+ if (size_remap > size_total)
+ size_remap = size_total;
+ efifb_fix.smem_len = size_remap;
+
+ if (!request_mem_region(efifb_fix.smem_start, size_total, "efifb"))
+ /* We cannot make this fatal. Sometimes this comes from magic
+ spaces our resource handlers simply don't know about */
+ printk(KERN_WARNING
+ "efifb: cannot reserve video memory at 0x%lx\n",
+ efifb_fix.smem_start);
+
+ info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
+ if (!info) {
+ err = -ENOMEM;
+ goto err_release_mem;
+ }
+ info->pseudo_palette = info->par;
+ info->par = NULL;
+
+ info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
+ if (!info->screen_base) {
+ printk(KERN_ERR "efifb: abort, cannot ioremap video memory "
+ "0x%x @ 0x%lx\n",
+ efifb_fix.smem_len, efifb_fix.smem_start);
+ err = -EIO;
+ goto err_unmap;
+ }
+
+ printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, "
+ "using %dk, total %dk\n",
+ efifb_fix.smem_start, info->screen_base,
+ size_remap/1024, size_total/1024);
+ printk(KERN_INFO "efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
+ efifb_defined.xres, efifb_defined.yres,
+ efifb_defined.bits_per_pixel, efifb_fix.line_length,
+ screen_info.pages);
+
+ efifb_defined.xres_virtual = efifb_defined.xres;
+ efifb_defined.yres_virtual = efifb_fix.smem_len /
+ efifb_fix.line_length;
+ printk(KERN_INFO "efifb: scrolling: redraw\n");
+ efifb_defined.yres_virtual = efifb_defined.yres;
+
+ /* some dummy values for timing to make fbset happy */
+ efifb_defined.pixclock = 10000000 / efifb_defined.xres *
+ 1000 / efifb_defined.yres;
+ efifb_defined.left_margin = (efifb_defined.xres / 8) & 0xf8;
+ efifb_defined.hsync_len = (efifb_defined.xres / 8) & 0xf8;
+
+ efifb_defined.red.offset = screen_info.red_pos;
+ efifb_defined.red.length = screen_info.red_size;
+ efifb_defined.green.offset = screen_info.green_pos;
+ efifb_defined.green.length = screen_info.green_size;
+ efifb_defined.blue.offset = screen_info.blue_pos;
+ efifb_defined.blue.length = screen_info.blue_size;
+ efifb_defined.transp.offset = screen_info.rsvd_pos;
+ efifb_defined.transp.length = screen_info.rsvd_size;
+
+ printk(KERN_INFO "efifb: %s: "
+ "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+ "Truecolor",
+ screen_info.rsvd_size,
+ screen_info.red_size,
+ screen_info.green_size,
+ screen_info.blue_size,
+ screen_info.rsvd_pos,
+ screen_info.red_pos,
+ screen_info.green_pos,
+ screen_info.blue_pos);
+
+ efifb_fix.ypanstep = 0;
+ efifb_fix.ywrapstep = 0;
+
+ info->fbops = &efifb_ops;
+ info->var = efifb_defined;
+ info->fix = efifb_fix;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ err = -ENOMEM;
+ goto err_unmap;
+ }
+ if (register_framebuffer(info) < 0) {
+ err = -EINVAL;
+ goto err_fb_dealoc;
+ }
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ info->node, info->fix.id);
+ return 0;
+
+err_fb_dealoc:
+ fb_dealloc_cmap(&info->cmap);
+err_unmap:
+ iounmap(info->screen_base);
+ framebuffer_release(info);
+err_release_mem:
+ release_mem_region(efifb_fix.smem_start, size_total);
+ return err;
+}
+
+static struct platform_driver efifb_driver = {
+ .probe = efifb_probe,
+ .driver = {
+ .name = "efifb",
+ },
+};
+
+static struct platform_device efifb_device = {
+ .name = "efifb",
+};
+
+static int __init efifb_init(void)
+{
+ int ret;
+
+ if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
+ return -ENODEV;
+
+ ret = platform_driver_register(&efifb_driver);
+
+ if (!ret) {
+ ret = platform_device_register(&efifb_device);
+ if (ret)
+ platform_driver_unregister(&efifb_driver);
+ }
+ return ret;
+}
+module_init(efifb_init);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
index f836137a0ed..a0df63289b5 100644
--- a/drivers/video/fb_ddc.c
+++ b/drivers/video/fb_ddc.c
@@ -56,13 +56,12 @@ unsigned char *fb_ddc_read(struct i2c_adapter *adapter)
int i, j;
algo_data->setscl(algo_data->data, 1);
- algo_data->setscl(algo_data->data, 0);
for (i = 0; i < 3; i++) {
/* For some old monitors we need the
* following process to initialize/stop DDC
*/
- algo_data->setsda(algo_data->data, 0);
+ algo_data->setsda(algo_data->data, 1);
msleep(13);
algo_data->setscl(algo_data->data, 1);
@@ -97,14 +96,15 @@ unsigned char *fb_ddc_read(struct i2c_adapter *adapter)
algo_data->setsda(algo_data->data, 1);
msleep(15);
algo_data->setscl(algo_data->data, 0);
+ algo_data->setsda(algo_data->data, 0);
if (edid)
break;
}
/* Release the DDC lines when done or the Apple Cinema HD display
* will switch off
*/
- algo_data->setsda(algo_data->data, 0);
- algo_data->setscl(algo_data->data, 0);
+ algo_data->setsda(algo_data->data, 1);
+ algo_data->setscl(algo_data->data, 1);
return edid;
}
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c
index 6455fd2a39f..9366ef2bb5f 100644
--- a/drivers/video/imacfb.c
+++ b/drivers/video/imacfb.c
@@ -234,10 +234,6 @@ static int __init imacfb_probe(struct platform_device *dev)
size_remap = size_total;
imacfb_fix.smem_len = size_remap;
-#ifndef __i386__
- screen_info.imacpm_seg = 0;
-#endif
-
if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
printk(KERN_WARNING
"imacfb: cannot reserve video memory at 0x%lx\n",
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 75836aa8319..9c56c492a69 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -51,7 +51,6 @@
#define L1GPU_DISPLAY_SYNC_HSYNC 1
#define L1GPU_DISPLAY_SYNC_VSYNC 2
-#define DDR_SIZE (0) /* used no ddr */
#define GPU_CMD_BUF_SIZE (64 * 1024)
#define GPU_IOIF (0x0d000000UL)
#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
@@ -1060,6 +1059,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
u64 xdr_lpar;
int status, res_index;
struct task_struct *task;
+ unsigned long max_ps3fb_size;
status = ps3_open_hv_device(dev);
if (status) {
@@ -1085,8 +1085,15 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
ps3fb_set_sync(&dev->core);
+ max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
+ if (ps3fb_videomemory.size > max_ps3fb_size) {
+ dev_info(&dev->core, "Limiting ps3fb mem size to %lu bytes\n",
+ max_ps3fb_size);
+ ps3fb_videomemory.size = max_ps3fb_size;
+ }
+
/* get gpu context handle */
- status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
+ status = lv1_gpu_memory_allocate(ps3fb_videomemory.size, 0, 0, 0, 0,
&ps3fb.memory_handle, &ddr_lpar);
if (status) {
dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
diff --git a/fs/Kconfig b/fs/Kconfig
index 429a0022850..635f3e286ad 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -459,6 +459,15 @@ config OCFS2_DEBUG_MASKLOG
This option will enlarge your kernel, but it allows debugging of
ocfs2 filesystem issues.
+config OCFS2_DEBUG_FS
+ bool "OCFS2 expensive checks"
+ depends on OCFS2_FS
+ default n
+ help
+ This option will enable expensive consistency checks. Enable
+ this option for debugging only as it is likely to decrease
+ performance of the filesystem.
+
config MINIX_FS
tristate "Minix fs support"
help
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index bd26e4cbb99..e8b7c3a98a5 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1954,6 +1954,12 @@ ULONG_IOCTL(TIOCSCTTY)
COMPATIBLE_IOCTL(TIOCGPTN)
COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCSERGETLSR)
+#ifdef TCGETS2
+COMPATIBLE_IOCTL(TCGETS2)
+COMPATIBLE_IOCTL(TCSETS2)
+COMPATIBLE_IOCTL(TCSETSW2)
+COMPATIBLE_IOCTL(TCSETSF2)
+#endif
/* Little f */
COMPATIBLE_IOCTL(FIOCLEX)
COMPATIBLE_IOCTL(FIONCLEX)
diff --git a/fs/exec.c b/fs/exec.c
index 4ccaaa4b13b..282240afe99 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1780,6 +1780,12 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
but keep the previous behaviour for now. */
if (!ispipe && !S_ISREG(inode->i_mode))
goto close_fail;
+ /*
+ * Dont allow local users get cute and trick others to coredump
+ * into their pre-created files:
+ */
+ if (inode->i_uid != current->fsuid)
+ goto close_fail;
if (!file->f_op)
goto close_fail;
if (!file->f_op->write)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 7730388c493..c87ae29c19c 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -178,3 +178,10 @@ extern const struct inode_operations ext2_special_inode_operations;
/* symlink.c */
extern const struct inode_operations ext2_fast_symlink_inode_operations;
extern const struct inode_operations ext2_symlink_inode_operations;
+
+static inline ext2_fsblk_t
+ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
+{
+ return group_no * (ext2_fsblk_t)EXT2_BLOCKS_PER_GROUP(sb) +
+ le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block);
+}
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 3763757f9fe..80d2f5292cf 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -132,6 +132,21 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
req->out.args[0].value = outarg;
}
+static u64 fuse_get_attr_version(struct fuse_conn *fc)
+{
+ u64 curr_version;
+
+ /*
+ * The spin lock isn't actually needed on 64bit archs, but we
+ * don't yet care too much about such optimizations.
+ */
+ spin_lock(&fc->lock);
+ curr_version = fc->attr_version;
+ spin_unlock(&fc->lock);
+
+ return curr_version;
+}
+
/*
* Check whether the dentry is still valid
*
@@ -171,9 +186,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
return 0;
}
- spin_lock(&fc->lock);
- attr_version = fc->attr_version;
- spin_unlock(&fc->lock);
+ attr_version = fuse_get_attr_version(fc);
parent = dget_parent(entry);
fuse_lookup_init(req, parent->d_inode, entry, &outarg);
@@ -264,9 +277,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
return ERR_PTR(PTR_ERR(forget_req));
}
- spin_lock(&fc->lock);
- attr_version = fc->attr_version;
- spin_unlock(&fc->lock);
+ attr_version = fuse_get_attr_version(fc);
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
@@ -646,6 +657,9 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err) {
+ /* ctime changes */
+ fuse_invalidate_attr(oldent->d_inode);
+
fuse_invalidate_attr(olddir);
if (olddir != newdir)
fuse_invalidate_attr(newdir);
@@ -733,9 +747,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
if (IS_ERR(req))
return PTR_ERR(req);
- spin_lock(&fc->lock);
- attr_version = fc->attr_version;
- spin_unlock(&fc->lock);
+ attr_version = fuse_get_attr_version(fc);
memset(&inarg, 0, sizeof(inarg));
memset(&outarg, 0, sizeof(outarg));
@@ -775,6 +787,31 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
return err;
}
+int fuse_update_attributes(struct inode *inode, struct kstat *stat,
+ struct file *file, bool *refreshed)
+{
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ int err;
+ bool r;
+
+ if (fi->i_time < get_jiffies_64()) {
+ r = true;
+ err = fuse_do_getattr(inode, stat, file);
+ } else {
+ r = false;
+ err = 0;
+ if (stat) {
+ generic_fillattr(inode, stat);
+ stat->mode = fi->orig_i_mode;
+ }
+ }
+
+ if (refreshed != NULL)
+ *refreshed = r;
+
+ return err;
+}
+
/*
* Calling into a user-controlled filesystem gives the filesystem
* daemon ptrace-like capabilities over the requester process. This
@@ -862,14 +899,9 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
*/
if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
- struct fuse_inode *fi = get_fuse_inode(inode);
- if (fi->i_time < get_jiffies_64()) {
- err = fuse_do_getattr(inode, NULL, NULL);
- if (err)
- return err;
-
- refreshed = true;
- }
+ err = fuse_update_attributes(inode, NULL, NULL, &refreshed);
+ if (err)
+ return err;
}
if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
@@ -935,7 +967,6 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
struct page *page;
struct inode *inode = file->f_path.dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_file *ff = file->private_data;
struct fuse_req *req;
if (is_bad_inode(inode))
@@ -952,7 +983,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
}
req->num_pages = 1;
req->pages[0] = page;
- fuse_read_fill(req, ff, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
+ fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
request_send(fc, req);
nbytes = req->out.args[0].size;
err = req->out.h.error;
@@ -1173,22 +1204,12 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
struct kstat *stat)
{
struct inode *inode = entry->d_inode;
- struct fuse_inode *fi = get_fuse_inode(inode);
struct fuse_conn *fc = get_fuse_conn(inode);
- int err;
if (!fuse_allow_task(fc, current))
return -EACCES;
- if (fi->i_time < get_jiffies_64())
- err = fuse_do_getattr(inode, stat, NULL);
- else {
- err = 0;
- generic_fillattr(inode, stat);
- stat->mode = fi->orig_i_mode;
- }
-
- return err;
+ return fuse_update_attributes(inode, stat, NULL, NULL);
}
static int fuse_setxattr(struct dentry *entry, const char *name,
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 535b3739900..bb05d227cf3 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -289,14 +289,16 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
return fuse_fsync_common(file, de, datasync, 0);
}
-void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff,
+void fuse_read_fill(struct fuse_req *req, struct file *file,
struct inode *inode, loff_t pos, size_t count, int opcode)
{
struct fuse_read_in *inarg = &req->misc.read_in;
+ struct fuse_file *ff = file->private_data;
inarg->fh = ff->fh;
inarg->offset = pos;
inarg->size = count;
+ inarg->flags = file->f_flags;
req->in.h.opcode = opcode;
req->in.h.nodeid = get_node_id(inode);
req->in.numargs = 1;
@@ -313,9 +315,8 @@ static size_t fuse_send_read(struct fuse_req *req, struct file *file,
fl_owner_t owner)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_file *ff = file->private_data;
- fuse_read_fill(req, ff, inode, pos, count, FUSE_READ);
+ fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
if (owner != NULL) {
struct fuse_read_in *inarg = &req->misc.read_in;
@@ -376,15 +377,16 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
fuse_put_request(fc, req);
}
-static void fuse_send_readpages(struct fuse_req *req, struct fuse_file *ff,
+static void fuse_send_readpages(struct fuse_req *req, struct file *file,
struct inode *inode)
{
struct fuse_conn *fc = get_fuse_conn(inode);
loff_t pos = page_offset(req->pages[0]);
size_t count = req->num_pages << PAGE_CACHE_SHIFT;
req->out.page_zeroing = 1;
- fuse_read_fill(req, ff, inode, pos, count, FUSE_READ);
+ fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
if (fc->async_read) {
+ struct fuse_file *ff = file->private_data;
req->ff = fuse_file_get(ff);
req->end = fuse_readpages_end;
request_send_background(fc, req);
@@ -396,7 +398,7 @@ static void fuse_send_readpages(struct fuse_req *req, struct fuse_file *ff,
struct fuse_fill_data {
struct fuse_req *req;
- struct fuse_file *ff;
+ struct file *file;
struct inode *inode;
};
@@ -411,7 +413,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
(req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
(req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
req->pages[req->num_pages - 1]->index + 1 != page->index)) {
- fuse_send_readpages(req, data->ff, inode);
+ fuse_send_readpages(req, data->file, inode);
data->req = req = fuse_get_req(fc);
if (IS_ERR(req)) {
unlock_page(page);
@@ -435,7 +437,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
if (is_bad_inode(inode))
goto out;
- data.ff = file->private_data;
+ data.file = file;
data.inode = inode;
data.req = fuse_get_req(fc);
err = PTR_ERR(data.req);
@@ -445,7 +447,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
if (!err) {
if (data.req->num_pages)
- fuse_send_readpages(data.req, data.ff, inode);
+ fuse_send_readpages(data.req, file, inode);
else
fuse_put_request(fc, data.req);
}
@@ -453,11 +455,31 @@ out:
return err;
}
-static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
+static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ struct inode *inode = iocb->ki_filp->f_mapping->host;
+
+ if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) {
+ int err;
+ /*
+ * If trying to read past EOF, make sure the i_size
+ * attribute is up-to-date.
+ */
+ err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
+ if (err)
+ return err;
+ }
+
+ return generic_file_aio_read(iocb, iov, nr_segs, pos);
+}
+
+static void fuse_write_fill(struct fuse_req *req, struct file *file,
struct inode *inode, loff_t pos, size_t count,
int writepage)
{
struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
struct fuse_write_in *inarg = &req->misc.write.in;
struct fuse_write_out *outarg = &req->misc.write.out;
@@ -466,6 +488,7 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
inarg->offset = pos;
inarg->size = count;
inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0;
+ inarg->flags = file->f_flags;
req->in.h.opcode = FUSE_WRITE;
req->in.h.nodeid = get_node_id(inode);
req->in.argpages = 1;
@@ -486,7 +509,7 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
fl_owner_t owner)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- fuse_write_fill(req, file->private_data, inode, pos, count, 0);
+ fuse_write_fill(req, file, inode, pos, count, 0);
if (owner != NULL) {
struct fuse_write_in *inarg = &req->misc.write.in;
inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
@@ -887,7 +910,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
static const struct file_operations fuse_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
- .aio_read = generic_file_aio_read,
+ .aio_read = fuse_file_aio_read,
.write = do_sync_write,
.aio_write = generic_file_aio_write,
.mmap = fuse_file_mmap,
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 6c5461de1a5..3ab8a3048e8 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -447,7 +447,7 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
/**
* Initialize READ or READDIR request
*/
-void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff,
+void fuse_read_fill(struct fuse_req *req, struct file *file,
struct inode *inode, loff_t pos, size_t count, int opcode);
/**
@@ -593,3 +593,6 @@ int fuse_valid_type(int m);
int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
+
+int fuse_update_attributes(struct inode *inode, struct kstat *stat,
+ struct file *file, bool *refreshed);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 9a68d697084..84f9f7dfdf5 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -56,6 +56,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
fi->i_time = 0;
fi->nodeid = 0;
fi->nlookup = 0;
+ fi->attr_version = 0;
INIT_LIST_HEAD(&fi->write_files);
fi->forget_req = fuse_request_alloc();
if (!fi->forget_req) {
@@ -562,8 +563,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
arg->major = FUSE_KERNEL_VERSION;
arg->minor = FUSE_KERNEL_MINOR_VERSION;
arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
- arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS |
- FUSE_ATOMIC_O_TRUNC;
+ arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC;
req->in.h.opcode = FUSE_INIT;
req->in.numargs = 1;
req->in.args[0].size = sizeof(*arg);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 556e34ccb00..56f7790cad4 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1514,7 +1514,7 @@ int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size)
{
struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
- if (new_size < le16_to_cpu(di->id2.i_data.id_count))
+ if (new_size <= le16_to_cpu(di->id2.i_data.id_count))
return 1;
return 0;
}
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index cd046060114..597e064bb94 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -212,7 +212,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
#define mlog_errno(st) do { \
int _st = (st); \
if (_st != -ERESTARTSYS && _st != -EINTR && \
- _st != AOP_TRUNCATED_PAGE) \
+ _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC) \
mlog(ML_ERROR, "status = %lld\n", (long long)_st); \
} while (0)
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 1957a5ed219..9923278ea6d 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -344,12 +344,24 @@ static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
{
struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
- mlog_bug_on_msg(!dl && !(dentry->d_flags & DCACHE_DISCONNECTED),
- "dentry: %.*s\n", dentry->d_name.len,
- dentry->d_name.name);
+ if (!dl) {
+ /*
+ * No dentry lock is ok if we're disconnected or
+ * unhashed.
+ */
+ if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
+ !d_unhashed(dentry)) {
+ unsigned long long ino = 0ULL;
+ if (inode)
+ ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
+ mlog(ML_ERROR, "Dentry is missing cluster lock. "
+ "inode: %llu, d_flags: 0x%x, d_name: %.*s\n",
+ ino, dentry->d_flags, dentry->d_name.len,
+ dentry->d_name.name);
+ }
- if (!dl)
goto out;
+ }
mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n",
dentry->d_name.len, dentry->d_name.name,
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 62e4a7daa28..a54d33d95ad 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -908,7 +908,7 @@ lookup:
* but they might own this lockres. wait on them. */
bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
if (bit < O2NM_MAX_NODES) {
- mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to"
+ mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
"recover before lock mastery can begin\n",
dlm->name, namelen, (char *)lockid, bit);
wait_on_recovery = 1;
@@ -962,7 +962,7 @@ redo_request:
spin_lock(&dlm->spinlock);
bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
if (bit < O2NM_MAX_NODES) {
- mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to"
+ mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
"recover before lock mastery can begin\n",
dlm->name, namelen, (char *)lockid, bit);
wait_on_recovery = 1;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index bbac7cd33e0..b75b2e1f0e4 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -399,7 +399,7 @@ static int ocfs2_truncate_file(struct inode *inode,
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
status = ocfs2_truncate_inline(inode, di_bh, new_i_size,
- i_size_read(inode), 0);
+ i_size_read(inode), 1);
if (status)
mlog_errno(status);
@@ -1521,6 +1521,7 @@ static int ocfs2_remove_inode_range(struct inode *inode,
u32 trunc_start, trunc_len, cpos, phys_cpos, alloc_size;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct ocfs2_cached_dealloc_ctxt dealloc;
+ struct address_space *mapping = inode->i_mapping;
ocfs2_init_dealloc_ctxt(&dealloc);
@@ -1529,10 +1530,20 @@ static int ocfs2_remove_inode_range(struct inode *inode,
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
ret = ocfs2_truncate_inline(inode, di_bh, byte_start,
- byte_start + byte_len, 1);
- if (ret)
+ byte_start + byte_len, 0);
+ if (ret) {
mlog_errno(ret);
- return ret;
+ goto out;
+ }
+ /*
+ * There's no need to get fancy with the page cache
+ * truncate of an inline-data inode. We're talking
+ * about less than a page here, which will be cached
+ * in the dinode buffer anyway.
+ */
+ unmap_mapping_range(mapping, 0, 0, 0);
+ truncate_inode_pages(mapping, 0);
+ goto out;
}
trunc_start = ocfs2_clusters_for_bytes(osb->sb, byte_start);
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 1d5e0cb0fda..ebb2bbe30f3 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -455,8 +455,8 @@ static int ocfs2_read_locked_inode(struct inode *inode,
status = -EINVAL;
fe = (struct ocfs2_dinode *) bh->b_data;
if (!OCFS2_IS_VALID_DINODE(fe)) {
- mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n",
- (unsigned long long)le64_to_cpu(fe->i_blkno), 7,
+ mlog(0, "Invalid dinode #%llu: signature = %.*s\n",
+ (unsigned long long)args->fi_blkno, 7,
fe->i_signature);
goto bail;
}
@@ -863,7 +863,7 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
status = ocfs2_try_open_lock(inode, 1);
if (status == -EAGAIN) {
status = 0;
- mlog(0, "Skipping delete of %llu because it is in use on"
+ mlog(0, "Skipping delete of %llu because it is in use on "
"other nodes\n", (unsigned long long)oi->ip_blkno);
goto bail;
}
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index d272847d5a0..58ea88b5af3 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -484,6 +484,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
+#ifdef OCFS2_DEBUG_FS
if (le32_to_cpu(alloc->id1.bitmap1.i_used) !=
ocfs2_local_alloc_count_bits(alloc)) {
ocfs2_error(osb->sb, "local alloc inode %llu says it has "
@@ -494,6 +495,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
status = -EIO;
goto bail;
}
+#endif
free_bits = le32_to_cpu(alloc->id1.bitmap1.i_total) -
le32_to_cpu(alloc->id1.bitmap1.i_used);
@@ -712,9 +714,8 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
void *bitmap;
struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
- mlog_entry("total = %u, COUNT = %u, used = %u\n",
+ mlog_entry("total = %u, used = %u\n",
le32_to_cpu(alloc->id1.bitmap1.i_total),
- ocfs2_local_alloc_count_bits(alloc),
le32_to_cpu(alloc->id1.bitmap1.i_used));
if (!alloc->id1.bitmap1.i_total) {
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index be562ac3e89..5ee77542066 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -438,14 +438,14 @@ unlock_osb:
}
if (!ret) {
- if (!ocfs2_is_hard_readonly(osb))
- ocfs2_set_journal_params(osb);
-
/* Only save off the new mount options in case of a successful
* remount. */
osb->s_mount_opt = parsed_options.mount_opt;
osb->s_atime_quantum = parsed_options.atime_quantum;
osb->preferred_slot = parsed_options.slot;
+
+ if (!ocfs2_is_hard_readonly(osb))
+ ocfs2_set_journal_params(osb);
}
out:
return ret;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a17c2685907..02a63ac0417 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2411,19 +2411,23 @@ out:
* Find the first task with tgid >= tgid
*
*/
-static struct task_struct *next_tgid(unsigned int tgid,
- struct pid_namespace *ns)
-{
+struct tgid_iter {
+ unsigned int tgid;
struct task_struct *task;
+};
+static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
+{
struct pid *pid;
+ if (iter.task)
+ put_task_struct(iter.task);
rcu_read_lock();
retry:
- task = NULL;
- pid = find_ge_pid(tgid, ns);
+ iter.task = NULL;
+ pid = find_ge_pid(iter.tgid, ns);
if (pid) {
- tgid = pid_nr_ns(pid, ns) + 1;
- task = pid_task(pid, PIDTYPE_PID);
+ iter.tgid = pid_nr_ns(pid, ns);
+ iter.task = pid_task(pid, PIDTYPE_PID);
/* What we to know is if the pid we have find is the
* pid of a thread_group_leader. Testing for task
* being a thread_group_leader is the obvious thing
@@ -2436,23 +2440,25 @@ retry:
* found doesn't happen to be a thread group leader.
* As we don't care in the case of readdir.
*/
- if (!task || !has_group_leader_pid(task))
+ if (!iter.task || !has_group_leader_pid(iter.task)) {
+ iter.tgid += 1;
goto retry;
- get_task_struct(task);
+ }
+ get_task_struct(iter.task);
}
rcu_read_unlock();
- return task;
+ return iter;
}
#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, int tgid)
+ struct tgid_iter iter)
{
char name[PROC_NUMBUF];
- int len = snprintf(name, sizeof(name), "%d", tgid);
+ int len = snprintf(name, sizeof(name), "%d", iter.tgid);
return proc_fill_cache(filp, dirent, filldir, name, len,
- proc_pid_instantiate, task, NULL);
+ proc_pid_instantiate, iter.task, NULL);
}
/* for the /proc/ directory itself, after non-process stuff has been done */
@@ -2460,8 +2466,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
- struct task_struct *task;
- int tgid;
+ struct tgid_iter iter;
struct pid_namespace *ns;
if (!reaper)
@@ -2474,14 +2479,14 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
}
ns = filp->f_dentry->d_sb->s_fs_info;
- tgid = filp->f_pos - TGID_OFFSET;
- for (task = next_tgid(tgid, ns);
- task;
- put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
- tgid = task_pid_nr_ns(task, ns);
- filp->f_pos = tgid + TGID_OFFSET;
- if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
- put_task_struct(task);
+ iter.task = NULL;
+ iter.tgid = filp->f_pos - TGID_OFFSET;
+ for (iter = next_tgid(ns, iter);
+ iter.task;
+ iter.tgid += 1, iter = next_tgid(ns, iter)) {
+ filp->f_pos = iter.tgid + TGID_OFFSET;
+ if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
+ put_task_struct(iter.task);
goto out;
}
}
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index a9806bc21ec..39f3d651903 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -555,41 +555,6 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
return 0;
}
-/*
- * Kill an inode that got unregistered..
- */
-static void proc_kill_inodes(struct proc_dir_entry *de)
-{
- struct list_head *p;
- struct super_block *sb;
-
- /*
- * Actually it's a partial revoke().
- */
- spin_lock(&sb_lock);
- list_for_each_entry(sb, &proc_fs_type.fs_supers, s_instances) {
- file_list_lock();
- list_for_each(p, &sb->s_files) {
- struct file *filp = list_entry(p, struct file,
- f_u.fu_list);
- struct dentry *dentry = filp->f_path.dentry;
- struct inode *inode;
- const struct file_operations *fops;
-
- if (dentry->d_op != &proc_dentry_operations)
- continue;
- inode = dentry->d_inode;
- if (PDE(inode) != de)
- continue;
- fops = filp->f_op;
- filp->f_op = NULL;
- fops_put(fops);
- }
- file_list_unlock();
- }
- spin_unlock(&sb_lock);
-}
-
static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
const char *name,
mode_t mode,
@@ -764,8 +729,6 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
continue_removing:
if (S_ISDIR(de->mode))
parent->nlink--;
- if (!S_ISREG(de->mode))
- proc_kill_inodes(de);
de->nlink = 0;
WARN_ON(de->subdir);
if (!atomic_read(&de->count))
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 1b2b6c6bb47..1820eb2ef76 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -78,5 +78,3 @@ static inline int proc_fd(struct inode *inode)
{
return PROC_I(inode)->fd;
}
-
-extern struct file_system_type proc_fs_type;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 1f86bb860e0..ec9cb3b6c93 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -98,7 +98,7 @@ static void proc_kill_sb(struct super_block *sb)
put_pid_ns(ns);
}
-struct file_system_type proc_fs_type = {
+static struct file_system_type proc_fs_type = {
.name = "proc",
.get_sb = proc_get_sb,
.kill_sb = proc_kill_sb,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 27d1785b764..4045bdcc4b3 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -119,7 +119,11 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
sysfs_put_active_two(attr_sd);
- BUG_ON(count > (ssize_t)PAGE_SIZE);
+ /*
+ * The code works fine with PAGE_SIZE return but it's likely to
+ * indicate truncated result or overflow in normal use cases.
+ */
+ BUG_ON(count >= (ssize_t)PAGE_SIZE);
if (count >= 0) {
buffer->needs_read_fill = 0;
buffer->count = count;
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index c0d7075982c..79054965baa 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -33,6 +33,7 @@
#include <linux/mtd/partitions.h>
#include <linux/device.h>
+#include <linux/i2c.h>
#include <linux/spi/spi.h>
/* USB Device */
@@ -94,7 +95,7 @@ struct at91_nand_data {
extern void __init at91_add_device_nand(struct at91_nand_data *data);
/* I2C*/
-extern void __init at91_add_device_i2c(void);
+extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
/* SPI */
extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
diff --git a/include/asm-arm/arch-ixp23xx/irqs.h b/include/asm-arm/arch-ixp23xx/irqs.h
index e6963958572..27c58089895 100644
--- a/include/asm-arm/arch-ixp23xx/irqs.h
+++ b/include/asm-arm/arch-ixp23xx/irqs.h
@@ -153,7 +153,7 @@
*/
#define NR_IXP23XX_MACH_IRQS 32
-#define NR_IRQS NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS
+#define NR_IRQS (NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS)
#define IXP23XX_MACH_IRQ(irq) (NR_IXP23XX_IRQ + (irq))
diff --git a/include/asm-arm/arch-omap/board-innovator.h b/include/asm-arm/arch-omap/board-innovator.h
index b3cf33441f6..56d2c98e143 100644
--- a/include/asm-arm/arch-omap/board-innovator.h
+++ b/include/asm-arm/arch-omap/board-innovator.h
@@ -37,7 +37,7 @@
#define OMAP1510P1_EMIFF_PRI_VALUE 0x00
#define NR_FPGA_IRQS 24
-#define NR_IRQS IH_BOARD_BASE + NR_FPGA_IRQS
+#define NR_IRQS (IH_BOARD_BASE + NR_FPGA_IRQS)
#ifndef __ASSEMBLY__
void fpga_write(unsigned char val, int reg);
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index 6238dbf7a23..b76ee6d1f5b 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -13,7 +13,7 @@
#define PXA_IRQ(x) (x)
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
#define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI) */
@@ -52,11 +52,27 @@
#define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */
#define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */
#define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */
#endif
+#ifdef CONFIG_PXA3xx
+#define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request */
+#define IRQ_CIR PXA_IRQ(34) /* Consumer IR */
+#define IRQ_TSI PXA_IRQ(36) /* Touch Screen Interface (PXA320) */
+#define IRQ_USIM2 PXA_IRQ(38) /* USIM2 Controller */
+#define IRQ_GRPHICS PXA_IRQ(39) /* Graphics Controller */
+#define IRQ_MMC2 PXA_IRQ(41) /* MMC2 Controller */
+#define IRQ_1WIRE PXA_IRQ(44) /* 1-Wire Controller */
+#define IRQ_NAND PXA_IRQ(45) /* NAND Controller */
+#define IRQ_USB2 PXA_IRQ(46) /* USB 2.0 Device Controller */
+#define IRQ_WAKEUP0 PXA_IRQ(49) /* EXT_WAKEUP0 */
+#define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */
+#define IRQ_DMEMC PXA_IRQ(51) /* Dynamic Memory Controller */
+#define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */
+#endif
+
#define PXA_GPIO_IRQ_BASE (64)
#define PXA_GPIO_IRQ_NUM (128)
diff --git a/include/asm-arm/arch-pxa/mfp-pxa300.h b/include/asm-arm/arch-pxa/mfp-pxa300.h
index 822a27cd786..a2099664988 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa300.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa300.h
@@ -179,7 +179,7 @@
#define GPIO62_LCD_CS_N MFP_CFG_DRV(GPIO62, AF2, DS01X)
#define GPIO72_LCD_FCLK MFP_CFG_DRV(GPIO72, AF1, DS01X)
#define GPIO73_LCD_LCLK MFP_CFG_DRV(GPIO73, AF1, DS01X)
-#define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS01X)
+#define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS02X)
#define GPIO75_LCD_BIAS MFP_CFG_DRV(GPIO75, AF1, DS01X)
#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF2, DS01X)
diff --git a/include/asm-arm/arch-pxa/mfp-pxa320.h b/include/asm-arm/arch-pxa/mfp-pxa320.h
index 488a5bbc49e..52deedcaf3b 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa320.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa320.h
@@ -18,7 +18,7 @@
#include <asm/arch/mfp.h>
/* GPIO */
-#define GPIO46_GPIO MFP_CFG(GPIO6, AF0)
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
diff --git a/include/asm-arm/arch-pxa/mfp.h b/include/asm-arm/arch-pxa/mfp.h
index ac4157af5a8..03c508d94f0 100644
--- a/include/asm-arm/arch-pxa/mfp.h
+++ b/include/asm-arm/arch-pxa/mfp.h
@@ -346,23 +346,31 @@ typedef uint32_t mfp_cfg_t;
#define MFP_CFG_PIN(mfp_cfg) (((mfp_cfg) >> 16) & 0xffff)
#define MFP_CFG_VAL(mfp_cfg) ((mfp_cfg) & 0xffff)
-#define MFPR_DEFAULT (0x0000)
+/*
+ * MFP register defaults to
+ * drive strength fast 3mA (010'b)
+ * edge detection logic disabled
+ * alternate function 0
+ */
+#define MFPR_DEFAULT (0x0840)
#define MFP_CFG(pin, af) \
((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af))
#define MFP_CFG_DRV(pin, af, drv) \
- ((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
+ ((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_DRV_MASK) |\
((MFP_##drv) << 10) | (MFP_##af))
#define MFP_CFG_LPM(pin, af, lpm) \
- ((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af) |\
+ ((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_LPM_MASK) |\
(((MFP_LPM_##lpm) & 0x3) << 7) |\
(((MFP_LPM_##lpm) & 0x4) << 12) |\
- (((MFP_LPM_##lpm) & 0x8) << 10))
+ (((MFP_LPM_##lpm) & 0x8) << 10) |\
+ (MFP_##af))
#define MFP_CFG_X(pin, af, drv, lpm) \
- ((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
+ ((MFP_PIN_##pin << 16) |\
+ (MFPR_DEFAULT & ~(MFPR_DRV_MASK | MFPR_LPM_MASK)) |\
((MFP_##drv) << 10) | (MFP_##af) |\
(((MFP_LPM_##lpm) & 0x3) << 7) |\
(((MFP_LPM_##lpm) & 0x4) << 12) |\
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index bb68b598c43..6b33df6f199 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -110,7 +110,10 @@
#define DALGN __REG(0x400000a0) /* DMA Alignment Register */
#define DINT __REG(0x400000f0) /* DMA Interrupt Register */
-#define DRCMR(n) __REG2(0x40000100, (n)<<2)
+#define DRCMR(n) (*(((n) < 64) ? \
+ &__REG2(0x40000100, ((n) & 0x3f) << 2) : \
+ &__REG2(0x40001100, ((n) & 0x3f) << 2)))
+
#define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */
#define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */
#define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */
diff --git a/include/asm-arm/arch-s3c2410/spi-gpio.h b/include/asm-arm/arch-s3c2410/spi-gpio.h
index c1e4db7c971..ba1dca88d48 100644
--- a/include/asm-arm/arch-s3c2410/spi-gpio.h
+++ b/include/asm-arm/arch-s3c2410/spi-gpio.h
@@ -21,6 +21,8 @@ struct s3c2410_spigpio_info {
unsigned long pin_mosi;
unsigned long pin_miso;
+ int bus_num;
+
unsigned long board_size;
struct spi_board_info *board_info;
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index c039820dba7..1effcd0f5e6 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -149,16 +149,21 @@ static inline unsigned int get_thread_fault_code(void)
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
#define TIF_IRET 4 /* return with iret */
-#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
- /* 31..28 fault code */
-#define TIF_MEMDIE 17
+#define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */
+#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
+#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE 18 /* OOM killer killed process */
+#define TIF_FREEZE 19 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_IRET (1<<TIF_IRET)
+#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index cbbd53762ea..f467eac9ba7 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -290,10 +290,50 @@
#define __NR_mq_getsetattr (__NR_mq_open+5)
#define __NR_kexec_load 283
#define __NR_waitid 284
+/* 285 is unused */
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+#define __NR_migrate_pages 294
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+#define __NR_set_robust_list 311
+#define __NR_get_robust_list 312
+#define __NR_splice 313
+#define __NR_sync_file_range 314
+#define __NR_tee 315
+#define __NR_vmsplice 316
+#define __NR_move_pages 317
+#define __NR_getcpu 318
+#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd 322
+#define __NR_eventfd 323
+#define __NR_fallocate 324
#ifdef __KERNEL__
-#define NR_syscalls 285
+#define NR_syscalls 325
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_STAT64
@@ -311,6 +351,30 @@
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __IGNORE_lchown
+#define __IGNORE_setuid
+#define __IGNORE_getuid
+#define __IGNORE_setgid
+#define __IGNORE_getgid
+#define __IGNORE_geteuid
+#define __IGNORE_getegid
+#define __IGNORE_fcntl
+#define __IGNORE_setreuid
+#define __IGNORE_setregid
+#define __IGNORE_getrlimit
+#define __IGNORE_getgroups
+#define __IGNORE_setgroups
+#define __IGNORE_select
+#define __IGNORE_mmap
+#define __IGNORE_fchown
+#define __IGNORE_setfsuid
+#define __IGNORE_setfsgid
+#define __IGNORE_setresuid
+#define __IGNORE_getresuid
+#define __IGNORE_setresgid
+#define __IGNORE_getresgid
+#define __IGNORE_chown
+
/*
* "Conditional" syscalls
*
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index f6bd308f047..5ea701fc342 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -207,13 +207,13 @@
#endif
#ifndef cpu_dcache_line_size
-#define cpu_dcache_line_size() current_cpu_data.dcache.linesz
+#define cpu_dcache_line_size() cpu_data[0].dcache.linesz
#endif
#ifndef cpu_icache_line_size
-#define cpu_icache_line_size() current_cpu_data.icache.linesz
+#define cpu_icache_line_size() cpu_data[0].icache.linesz
#endif
#ifndef cpu_scache_line_size
-#define cpu_scache_line_size() current_cpu_data.scache.linesz
+#define cpu_scache_line_size() cpu_data[0].scache.linesz
#endif
#endif /* __ASM_CPU_FEATURES_H */
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 1030562d6ea..a944eda4faf 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -209,8 +209,6 @@ extern void *set_except_vector(int n, void *addr);
extern unsigned long ebase;
extern void per_cpu_trap_init(void);
-extern int stop_a_enabled;
-
/*
* See include/asm-ia64/system.h; prevents deadlock on SMP
* systems.
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 0f6c86c634f..84cec2aa9f1 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -563,11 +563,4 @@ enum {
~EXT2_DIR_ROUND)
#define EXT2_MAX_REC_LEN ((1<<16)-1)
-static inline ext2_fsblk_t
-ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
-{
- return group_no * (ext2_fsblk_t)EXT2_BLOCKS_PER_GROUP(sb) +
- le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block);
-}
-
#endif /* _LINUX_EXT2_FS_H */
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index d0c437028c8..5c86f1196c3 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -16,6 +16,7 @@
* - add lk_flags in fuse_lk_in
* - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
* - add blksize field to fuse_attr
+ * - add file flags field to fuse_read_in and fuse_write_in
*/
#include <asm/types.h>
@@ -280,6 +281,8 @@ struct fuse_read_in {
__u32 size;
__u32 read_flags;
__u64 lock_owner;
+ __u32 flags;
+ __u32 padding;
};
#define FUSE_COMPAT_WRITE_IN_SIZE 24
@@ -290,6 +293,8 @@ struct fuse_write_in {
__u32 size;
__u32 write_flags;
__u64 lock_owner;
+ __u32 flags;
+ __u32 padding;
};
struct fuse_write_out {
diff --git a/include/linux/kd.h b/include/linux/kd.h
index c91fc0c9c49..15f2853ea58 100644
--- a/include/linux/kd.h
+++ b/include/linux/kd.h
@@ -126,7 +126,7 @@ struct kbdiacrs {
#define KDSKBDIACR 0x4B4B /* write kernel accent table */
struct kbdiacruc {
- __u32 diacr, base, result;
+ unsigned int diacr, base, result;
};
struct kbdiacrsuc {
unsigned int kb_cnt; /* number of entries in following array */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 664d68cb1fb..0a0426c2867 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -13,8 +13,8 @@
#include <linux/errno.h>
#include <linux/mod_devicetable.h>
-#define PNP_MAX_PORT 8
-#define PNP_MAX_MEM 4
+#define PNP_MAX_PORT 24
+#define PNP_MAX_MEM 12
#define PNP_MAX_IRQ 2
#define PNP_MAX_DMA 2
#define PNP_NAME_LEN 50
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 6d5e4a46781..f2d0d152772 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -133,6 +133,9 @@ struct rtc_class_ops {
#define RTC_DEVICE_NAME_SIZE 20
struct rtc_task;
+/* flags */
+#define RTC_DEV_BUSY 0
+
struct rtc_device
{
struct device dev;
@@ -145,7 +148,7 @@ struct rtc_device
struct mutex ops_lock;
struct cdev char_dev;
- struct mutex char_lock;
+ unsigned long flags;
unsigned long irq_data;
spinlock_t irq_lock;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index ee800e7a70d..ac3d496fbd2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -282,6 +282,10 @@ static inline void touch_all_softlockup_watchdogs(void)
/* Attach to any functions which should be ignored in wchan output. */
#define __sched __attribute__((__section__(".sched.text")))
+
+/* Linker adds these: start and end of __sched functions */
+extern char __sched_text_start[], __sched_text_end[];
+
/* Is this address in the __sched functions? */
extern int in_sched_functions(unsigned long addr);
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index 827b85bbf38..1ee2c05142f 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -63,6 +63,8 @@ struct screen_info {
#define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */
+#define VIDEO_TYPE_EFI 0x70 /* EFI graphic mode */
+
#ifdef __KERNEL__
extern struct screen_info screen_info;
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 6a5203fb9cf..9963f81fea9 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -437,7 +437,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
#ifdef SUPPORT_SYSRQ
if (port->sysrq) {
if (ch && time_before(jiffies, port->sysrq)) {
- handle_sysrq(ch, port->info->tty);
+ handle_sysrq(ch, port->info ? port->info->tty : NULL);
port->sysrq = 0;
return 1;
}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index c5c8f169d3c..416ee7617d9 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -157,6 +157,7 @@ struct usb_interface {
* bound to */
enum usb_interface_condition condition; /* state of binding */
unsigned is_active:1; /* the interface is not suspended */
+ unsigned sysfs_files_created:1; /* the sysfs attributes exist */
unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
struct device dev; /* interface specific device info */
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 342dd5a7e8b..8ca5a7fbc9e 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -102,7 +102,8 @@ struct usbdevfs_urb {
int start_frame;
int number_of_packets;
int error_count;
- unsigned int signr; /* signal to be sent on error, -1 if none should be sent */
+ unsigned int signr; /* signal to be sent on completion,
+ or 0 if none should be sent. */
void *usercontext;
struct usbdevfs_iso_packet_desc iso_frame_desc[0];
};
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 1e04cd464af..6ca7b97114f 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -1138,8 +1138,10 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
if (u_mqstat) {
ret = audit_mq_getsetattr(mqdes, &mqstat);
- if (ret != 0)
- goto out;
+ if (ret != 0) {
+ spin_unlock(&info->lock);
+ goto out_fput;
+ }
if (mqstat.mq_flags & O_NONBLOCK)
filp->f_flags |= O_NONBLOCK;
else
diff --git a/kernel/exit.c b/kernel/exit.c
index cd0f1d4137a..549c0558ba6 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1357,7 +1357,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
int __user *stat_addr, struct rusage __user *ru)
{
int retval, exit_code;
- struct pid_namespace *ns;
+ pid_t pid;
if (!p->exit_code)
return 0;
@@ -1376,12 +1376,11 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
* keep holding onto the tasklist_lock while we call getrusage and
* possibly take page faults for user memory.
*/
- ns = current->nsproxy->pid_ns;
+ pid = task_pid_nr_ns(p, current->nsproxy->pid_ns);
get_task_struct(p);
read_unlock(&tasklist_lock);
if (unlikely(noreap)) {
- pid_t pid = task_pid_nr_ns(p, ns);
uid_t uid = p->uid;
int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
@@ -1389,7 +1388,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
if (unlikely(!exit_code) || unlikely(p->exit_state))
goto bail_ref;
return wait_noreap_copyout(p, pid, uid,
- why, (exit_code << 8) | 0x7f,
+ why, exit_code,
infop, ru);
}
@@ -1451,11 +1450,11 @@ bail_ref:
if (!retval && infop)
retval = put_user(exit_code, &infop->si_status);
if (!retval && infop)
- retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
+ retval = put_user(pid, &infop->si_pid);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
if (!retval)
- retval = task_pid_nr_ns(p, ns);
+ retval = pid;
put_task_struct(p);
BUG_ON(!retval);
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 474219a4192..2fc25810509 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -32,9 +32,14 @@
/* These will be re-linked against their real values during the second link stage */
extern const unsigned long kallsyms_addresses[] __attribute__((weak));
-extern const unsigned long kallsyms_num_syms __attribute__((weak));
extern const u8 kallsyms_names[] __attribute__((weak));
+/* tell the compiler that the count isn't in the small data section if the arch
+ * has one (eg: FRV)
+ */
+extern const unsigned long kallsyms_num_syms
+__attribute__((weak, section(".rodata")));
+
extern const u8 kallsyms_token_table[] __attribute__((weak));
extern const u16 kallsyms_token_index[] __attribute__((weak));
diff --git a/kernel/sched.c b/kernel/sched.c
index 38933cafea8..98dcdf272db 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5466,7 +5466,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
return table;
}
-static ctl_table * sd_alloc_ctl_cpu_table(int cpu)
+static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
{
struct ctl_table *entry, *table;
struct sched_domain *sd;
@@ -6708,9 +6708,6 @@ void __init sched_init_smp(void)
int in_sched_functions(unsigned long addr)
{
- /* Linker adds these: start and end of __sched functions */
- extern char __sched_text_start[], __sched_text_end[];
-
return in_lock_functions(addr) ||
(addr >= (unsigned long)__sched_text_start
&& addr < (unsigned long)__sched_text_end);
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 5d0d623a546..d30467b47dd 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -327,10 +327,12 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
avg_atom = -1LL;
avg_per_cpu = p->se.sum_exec_runtime;
- if (p->se.nr_migrations)
- avg_per_cpu = div64_64(avg_per_cpu, p->se.nr_migrations);
- else
+ if (p->se.nr_migrations) {
+ avg_per_cpu = div64_64(avg_per_cpu,
+ p->se.nr_migrations);
+ } else {
avg_per_cpu = -1LL;
+ }
__PN(avg_atom);
__PN(avg_per_cpu);
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
index 630178e53bb..5b32433e7ee 100644
--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -52,7 +52,8 @@ static int show_schedstat(struct seq_file *seq, void *v)
sd->lb_nobusyq[itype],
sd->lb_nobusyg[itype]);
}
- seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n",
+ seq_printf(seq,
+ " %u %u %u %u %u %u %u %u %u %u %u %u\n",
sd->alb_count, sd->alb_failed, sd->alb_pushed,
sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed,
sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed,
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 27a2338deb4..cb89fa8db11 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -133,6 +133,8 @@ void tick_nohz_update_jiffies(void)
if (!ts->tick_stopped)
return;
+ touch_softlockup_watchdog();
+
cpu_clear(cpu, nohz_cpu_mask);
now = ktime_get();
diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c
index c76c06466bf..fe3a56c2256 100644
--- a/kernel/utsname_sysctl.c
+++ b/kernel/utsname_sysctl.c
@@ -18,6 +18,10 @@
static void *get_uts(ctl_table *table, int write)
{
char *which = table->data;
+ struct uts_namespace *uts_ns;
+
+ uts_ns = current->nsproxy->uts_ns;
+ which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
if (!write)
down_read(&uts_sem);
diff --git a/lib/hexdump.c b/lib/hexdump.c
index bd5edaeaa80..343546550dc 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -106,7 +106,8 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
linebuf[lx++] = ' ';
for (j = 0; (j < rowsize) && (j < len) && (lx + 2) < linebuflen; j++)
- linebuf[lx++] = isprint(ptr[j]) ? ptr[j] : '.';
+ linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j]
+ : '.';
nil:
linebuf[lx++] = '\0';
}
diff --git a/lib/kobject.c b/lib/kobject.c
index a7e3bf4d3c7..b52e9f4ef37 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -313,8 +313,8 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
struct kobject *temp_kobj;
temp_kobj = kset_find_obj(kobj->kset, new_name);
if (temp_kobj) {
- printk(KERN_WARNING "kobject '%s' can not be renamed "
- "to '%s' as '%s' is already in existance.\n",
+ printk(KERN_WARNING "kobject '%s' cannot be renamed "
+ "to '%s' as '%s' is already in existence.\n",
kobject_name(kobj), new_name, new_name);
kobject_put(temp_kobj);
return -EINVAL;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 12376ae3f73..b5a58d476c1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -305,7 +305,6 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
{
int i;
- VM_BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM);
/*
* clear_highpage() will use KM_USER0, so it's a bug to use __GFP_ZERO
* and __GFP_HIGHMEM from hard or soft interrupt context.
@@ -3266,6 +3265,16 @@ static void inline setup_usemap(struct pglist_data *pgdat,
#endif /* CONFIG_SPARSEMEM */
#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
+
+/* Return a sensible default order for the pageblock size. */
+static inline int pageblock_default_order(void)
+{
+ if (HPAGE_SHIFT > PAGE_SHIFT)
+ return HUGETLB_PAGE_ORDER;
+
+ return MAX_ORDER-1;
+}
+
/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
static inline void __init set_pageblock_order(unsigned int order)
{
@@ -3281,7 +3290,16 @@ static inline void __init set_pageblock_order(unsigned int order)
}
#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
-/* Defined this way to avoid accidently referencing HUGETLB_PAGE_ORDER */
+/*
+ * When CONFIG_HUGETLB_PAGE_SIZE_VARIABLE is not set, set_pageblock_order()
+ * and pageblock_default_order() are unused as pageblock_order is set
+ * at compile-time. See include/linux/pageblock-flags.h for the values of
+ * pageblock_order based on the kernel config
+ */
+static inline int pageblock_default_order(unsigned int order)
+{
+ return MAX_ORDER-1;
+}
#define set_pageblock_order(x) do {} while (0)
#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
@@ -3366,7 +3384,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
if (!size)
continue;
- set_pageblock_order(HUGETLB_PAGE_ORDER);
+ set_pageblock_order(pageblock_default_order());
setup_usemap(pgdat, zone, size);
ret = init_currently_empty_zone(zone, zone_start_pfn,
size, MEMMAP_EARLY);
diff --git a/mm/shmem.c b/mm/shmem.c
index 253d205914b..51b3d6ccdda 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1072,7 +1072,7 @@ shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
pvma.vm_pgoff = idx;
pvma.vm_end = PAGE_SIZE;
- page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0);
+ page = alloc_page_vma(gfp, &pvma, 0);
mpol_free(pvma.vm_policy);
return page;
}
@@ -1093,7 +1093,7 @@ shmem_swapin(struct shmem_inode_info *info,swp_entry_t entry,unsigned long idx)
static inline struct page *
shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx)
{
- return alloc_page(gfp | __GFP_ZERO);
+ return alloc_page(gfp);
}
#endif
@@ -1306,6 +1306,7 @@ repeat:
info->alloced++;
spin_unlock(&info->lock);
+ clear_highpage(filepage);
flush_dcache_page(filepage);
SetPageUptodate(filepage);
}
diff --git a/mm/slab.c b/mm/slab.c
index c31cd3682a0..202465a193c 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2881,6 +2881,8 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
unsigned int objnr;
struct slab *slabp;
+ BUG_ON(virt_to_cache(objp) != cachep);
+
objp -= obj_offset(cachep);
kfree_debugcheck(objp);
page = virt_to_head_page(objp);
@@ -3759,8 +3761,6 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
{
unsigned long flags;
- BUG_ON(virt_to_cache(objp) != cachep);
-
local_irq_save(flags);
debug_check_no_locks_freed(objp, obj_size(cachep));
__cache_free(cachep, objp);
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 22620f6a976..cd75b21dd4c 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -34,6 +34,16 @@
* or to back the page tables that are used to create the mapping.
* Uses the main allocators if they are available, else bootmem.
*/
+
+static void * __init_refok __earlyonly_bootmem_alloc(int node,
+ unsigned long size,
+ unsigned long align,
+ unsigned long goal)
+{
+ return __alloc_bootmem_node(NODE_DATA(node), size, align, goal);
+}
+
+
void * __meminit vmemmap_alloc_block(unsigned long size, int node)
{
/* If the main allocator is up use that, fallback to bootmem. */
@@ -44,7 +54,7 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
return page_address(page);
return NULL;
} else
- return __alloc_bootmem_node(NODE_DATA(node), size, size,
+ return __earlyonly_bootmem_alloc(node, size, size,
__pa(MAX_DMA_ADDRESS));
}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index cbb42580a81..579f50fa838 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.11';
+my $V = '0.12';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -19,8 +19,11 @@ my $chk_signoff = 1;
my $chk_patch = 1;
my $tst_type = 0;
my $emacs = 0;
+my $terse = 0;
my $file = 0;
my $check = 0;
+my $summary = 1;
+my $mailback = 0;
my $root;
GetOptions(
'q|quiet+' => \$quiet,
@@ -29,10 +32,13 @@ GetOptions(
'patch!' => \$chk_patch,
'test-type!' => \$tst_type,
'emacs!' => \$emacs,
+ 'terse!' => \$terse,
'file!' => \$file,
'subjective!' => \$check,
'strict!' => \$check,
'root=s' => \$root,
+ 'summary!' => \$summary,
+ 'mailback!' => \$mailback,
) or exit;
my $exit = 0;
@@ -42,6 +48,7 @@ if ($#ARGV < 0) {
print "version: $V\n";
print "options: -q => quiet\n";
print " --no-tree => run without a kernel tree\n";
+ print " --terse => one line per report\n";
print " --emacs => emacs compile window format\n";
print " --file => check a source file\n";
print " --strict => enable more subjective tests\n";
@@ -49,6 +56,11 @@ if ($#ARGV < 0) {
exit(1);
}
+if ($terse) {
+ $emacs = 1;
+ $quiet++;
+}
+
if ($tree) {
if (defined $root) {
if (!top_of_kernel_tree($root)) {
@@ -90,41 +102,6 @@ our $Attribute = qr{
__(?:mem|cpu|dev|)(?:initdata|init)
}x;
our $Inline = qr{inline|__always_inline|noinline};
-our $NonptrType = qr{
- \b
- (?:const\s+)?
- (?:unsigned\s+)?
- (?:
- void|
- char|
- short|
- int|
- long|
- unsigned|
- float|
- double|
- bool|
- long\s+int|
- long\s+long|
- long\s+long\s+int|
- (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
- struct\s+$Ident|
- union\s+$Ident|
- enum\s+$Ident|
- ${Ident}_t|
- ${Ident}_handler|
- ${Ident}_handler_fn
- )
- (?:\s+$Sparse)*
- \b
- }x;
-
-our $Type = qr{
- \b$NonptrType\b
- (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
- (?:\s+$Sparse|\s+$Attribute)*
- }x;
-our $Declare = qr{(?:$Storage\s+)?$Type};
our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
our $Lval = qr{$Ident(?:$Member)*};
@@ -136,7 +113,50 @@ our $Operators = qr{
&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
}x;
-our $Bare = '';
+our $NonptrType;
+our $Type;
+our $Declare;
+
+our @typeList = (
+ qr{void},
+ qr{char},
+ qr{short},
+ qr{int},
+ qr{long},
+ qr{unsigned},
+ qr{float},
+ qr{double},
+ qr{bool},
+ qr{long\s+int},
+ qr{long\s+long},
+ qr{long\s+long\s+int},
+ qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
+ qr{struct\s+$Ident},
+ qr{union\s+$Ident},
+ qr{enum\s+$Ident},
+ qr{${Ident}_t},
+ qr{${Ident}_handler},
+ qr{${Ident}_handler_fn},
+);
+
+sub build_types {
+ my $all = "(?: \n" . join("|\n ", @typeList) . "\n)";
+ $NonptrType = qr{
+ \b
+ (?:const\s+)?
+ (?:unsigned\s+)?
+ $all
+ (?:\s+$Sparse|\s+const)*
+ \b
+ }x;
+ $Type = qr{
+ \b$NonptrType\b
+ (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+ (?:\s+$Sparse|\s+$Attribute)*
+ }x;
+ $Declare = qr{(?:$Storage\s+)?$Type};
+}
+build_types();
$chk_signoff = 0 if ($file);
@@ -278,6 +298,81 @@ sub sanitise_line {
return $res;
}
+sub ctx_statement_block {
+ my ($linenr, $remain, $off) = @_;
+ my $line = $linenr - 1;
+ my $blk = '';
+ my $soff = $off;
+ my $coff = $off - 1;
+
+ my $type = '';
+ my $level = 0;
+ my $c;
+ my $len = 0;
+ while (1) {
+ #warn "CSB: blk<$blk>\n";
+ # If we are about to drop off the end, pull in more
+ # context.
+ if ($off >= $len) {
+ for (; $remain > 0; $line++) {
+ next if ($rawlines[$line] =~ /^-/);
+ $remain--;
+ $blk .= sanitise_line($rawlines[$line]) . "\n";
+ $len = length($blk);
+ $line++;
+ last;
+ }
+ # Bail if there is no further context.
+ #warn "CSB: blk<$blk> off<$off> len<$len>\n";
+ if ($off == $len) {
+ last;
+ }
+ }
+ $c = substr($blk, $off, 1);
+
+ #warn "CSB: c<$c> type<$type> level<$level>\n";
+ # Statement ends at the ';' or a close '}' at the
+ # outermost level.
+ if ($level == 0 && $c eq ';') {
+ last;
+ }
+
+ if (($type eq '' || $type eq '(') && $c eq '(') {
+ $level++;
+ $type = '(';
+ }
+ if ($type eq '(' && $c eq ')') {
+ $level--;
+ $type = ($level != 0)? '(' : '';
+
+ if ($level == 0 && $coff < $soff) {
+ $coff = $off;
+ }
+ }
+ if (($type eq '' || $type eq '{') && $c eq '{') {
+ $level++;
+ $type = '{';
+ }
+ if ($type eq '{' && $c eq '}') {
+ $level--;
+ $type = ($level != 0)? '{' : '';
+
+ if ($level == 0) {
+ last;
+ }
+ }
+ $off++;
+ }
+
+ my $statement = substr($blk, $soff, $off - $soff + 1);
+ my $condition = substr($blk, $soff, $coff - $soff + 1);
+
+ #warn "STATEMENT<$statement>\n";
+ #warn "CONDITION<$condition>\n";
+
+ return ($statement, $condition);
+}
+
sub ctx_block_get {
my ($linenr, $remain, $outer, $open, $close, $off) = @_;
my $line;
@@ -421,9 +516,6 @@ sub annotate_values {
my $paren = 0;
my @paren_type;
- # Include any user defined types we may have found as we went.
- my $type_match = "(?:$Type$Bare)";
-
while (length($cur)) {
print " <$type> " if ($debug);
if ($cur =~ /^(\s+)/o) {
@@ -433,7 +525,7 @@ sub annotate_values {
$type = 'N';
}
- } elsif ($cur =~ /^($type_match)/) {
+ } elsif ($cur =~ /^($Type)/) {
print "DECLARE($1)\n" if ($debug);
$type = 'T';
@@ -457,7 +549,7 @@ sub annotate_values {
}
$type = 'N';
- } elsif ($cur =~ /^(if|while|typeof)\b/o) {
+ } elsif ($cur =~ /^(if|while|typeof|for)\b/o) {
print "COND($1)\n" if ($debug);
$paren_type[$paren] = 'N';
$type = 'N';
@@ -515,11 +607,30 @@ sub annotate_values {
return $res;
}
+sub possible {
+ my ($possible) = @_;
+
+ #print "CHECK<$possible>\n";
+ if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
+ $possible ne 'goto' && $possible ne 'return' &&
+ $possible ne 'struct' && $possible ne 'enum' &&
+ $possible ne 'case' && $possible ne 'else' &&
+ $possible ne 'typedef') {
+ #print "POSSIBLE<$possible>\n";
+ push(@typeList, $possible);
+ build_types();
+ }
+}
+
my $prefix = '';
my @report = ();
sub report {
- push(@report, $prefix . $_[0]);
+ my $line = $prefix . $_[0];
+
+ $line = (split('\n', $line))[0] . "\n" if ($terse);
+
+ push(@report, $line);
}
sub report_dump {
@report;
@@ -574,9 +685,6 @@ sub process {
my $prev_values = 'N';
- # Possible bare types.
- my @bare = ();
-
# Pre-scan the patch looking for any __setup documentation.
my @setup_docs = ();
my $setup_docs = 0;
@@ -631,21 +739,35 @@ sub process {
$realline++;
$realcnt-- if ($realcnt != 0);
- # track any sort of multi-line comment. Obviously if
- # the added text or context do not include the whole
- # comment we will not see it. Such is life.
- #
+ # Guestimate if this is a continuing comment. Run
+ # the context looking for a comment "edge". If this
+ # edge is a close comment then we must be in a comment
+ # at context start.
+ if ($linenr == $first_line) {
+ my $edge;
+ for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) {
+ ($edge) = ($lines[$ln - 1] =~ m@(/\*|\*/)@);
+ last if (defined $edge);
+ }
+ if (defined $edge && $edge eq '*/') {
+ $in_comment = 1;
+ }
+ }
+
# Guestimate if this is a continuing comment. If this
# is the start of a diff block and this line starts
# ' *' then it is very likely a comment.
if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
$in_comment = 1;
}
- if ($line =~ m@/\*@) {
- $in_comment = 1;
- }
- if ($line =~ m@\*/@) {
- $in_comment = 0;
+
+ # Find the last comment edge on _this_ line.
+ while (($line =~ m@(/\*|\*/)@g)) {
+ if ($1 eq '/*') {
+ $in_comment = 1;
+ } else {
+ $in_comment = 0;
+ }
}
# Measure the line length and indent.
@@ -687,7 +809,7 @@ sub process {
}
# Check for wrappage within a valid hunk of the file
- if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) {
+ if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
ERROR("patch seems to be corrupt (line wrapped?)\n" .
$herecurr) if (!$emitted_corrupt++);
}
@@ -727,6 +849,11 @@ sub process {
WARN("line over 80 characters\n" . $herecurr);
}
+# check for adding lines without a newline.
+ if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
+ WARN("adding a line without newline at end of file\n" . $herecurr);
+ }
+
# check we are in a valid source file *.[hc] if not then ignore this hunk
next if ($realfile !~ /\.[hc]$/);
@@ -752,30 +879,41 @@ sub process {
# Check for potential 'bare' types
if ($realcnt &&
- $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ &&
$line !~ /$Ident:\s*$/ &&
- $line !~ /^.\s*$Ident\s*\(/ &&
- # definitions in global scope can only start with types
- ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ ||
- # declarations always start with types
- $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) ||
- # any (foo ... *) is a pointer cast, and foo is a type
- $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) {
- my $possible = $1;
- if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
- $possible ne 'goto' && $possible ne 'return' &&
- $possible ne 'struct' && $possible ne 'enum' &&
- $possible ne 'case' && $possible ne 'else' &&
- $possible ne 'typedef') {
- #print "POSSIBLE<$possible>\n";
- push(@bare, $possible);
- my $bare = join("|", @bare);
- $Bare = '|' . qr{
- \b(?:$bare)\b
- (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
- (?:\s+$Sparse)*
- }x;
+ ($line =~ /^.\s*$Ident\s*\(\*+\s*$Ident\)\s*\(/ ||
+ $line !~ /^.\s*$Ident\s*\(/)) {
+ # definitions in global scope can only start with types
+ if ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
+ possible($1);
+
+ # declarations always start with types
+ } elsif ($prev_values eq 'N' && $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) {
+ possible($1);
+
+ # any (foo ... *) is a pointer cast, and foo is a type
+ } elsif ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) {
+ possible($1);
+ }
+
+ # Check for any sort of function declaration.
+ # int foo(something bar, other baz);
+ # void (*store_gdt)(x86_descr_ptr *);
+ if ($prev_values eq 'N' && $line =~ /^(.(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
+ my ($name_len) = length($1);
+ my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len);
+ my $ctx = join("\n", @ctx);
+
+ $ctx =~ s/\n.//;
+ substr($ctx, 0, $name_len + 1) = '';
+ $ctx =~ s/\)[^\)]*$//;
+ for my $arg (split(/\s*,\s*/, $ctx)) {
+ if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) {
+
+ possible($1);
+ }
+ }
}
+
}
#
@@ -935,6 +1073,10 @@ sub process {
# $clean = 0;
# }
+ if ($line =~ /\bLINUX_VERSION_CODE\b/) {
+ WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged" . $herecurr);
+ }
+
# printk should use KERN_* levels. Note that follow on printk's on the
# same line do not need a level, so we use the current block context
# to try and find and validate the current printk. In summary the current
@@ -965,6 +1107,12 @@ sub process {
ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr);
}
+# open braces for enum, union and struct go on the same line.
+ if ($line =~ /^.\s*{/ &&
+ $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
+ ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
+ }
+
# check for spaces between functions and their parentheses.
while ($line =~ /($Ident)\s+\(/g) {
if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ &&
@@ -1172,9 +1320,27 @@ sub process {
}
# Check for illegal assignment in if conditional.
- if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) {
- #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/);
- ERROR("do not use assignment in if condition\n" . $herecurr);
+ if ($line =~ /\bif\s*\(/) {
+ my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
+
+ if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
+ ERROR("do not use assignment in if condition ($c)\n" . $herecurr);
+ }
+
+ # Find out what is on the end of the line after the
+ # conditional.
+ substr($s, 0, length($c)) = '';
+ $s =~ s/\n.*//g;
+
+ if (length($c) && $s !~ /^\s*({|;|\/\*.*\*\/)?\s*\\*\s*$/) {
+ ERROR("trailing statements should be on next line\n" . $herecurr);
+ }
+ }
+
+# if and else should not have general statements after it
+ if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ &&
+ $1 !~ /^\s*(?:\sif|{|\\|$)/) {
+ ERROR("trailing statements should be on next line\n" . $herecurr);
}
# Check for }<nl>else {, these must be at the same
@@ -1205,12 +1371,6 @@ sub process {
}
}
-# if and else should not have general statements after it
- if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ &&
- $1 !~ /^\s*(?:\sif|{|\\|$)/) {
- ERROR("trailing statements should be on next line\n" . $herecurr);
- }
-
# multi-statement macros should be enclosed in a do while loop, grab the
# first statement and ensure its the whole macro if its not enclosed
# in a known goot container
@@ -1233,6 +1393,10 @@ sub process {
$off = length($1);
$ln--;
$cnt++;
+ while ($lines[$ln - 1] =~ /^-/) {
+ $ln--;
+ $cnt++;
+ }
}
my @ctx = ctx_statement($ln, $cnt, $off);
my $ctx_ln = $ln + $#ctx + 1;
@@ -1268,25 +1432,23 @@ sub process {
if ($lines[$nr - 1] =~ /{\s*$/) {
my ($lvl, @block) = ctx_block_level($nr, $cnt);
- my $stmt = join(' ', @block);
- $stmt =~ s/(^[^{]*){//;
+ my $stmt = join("\n", @block);
+ # Drop the diff line leader.
+ $stmt =~ s/\n./\n/g;
+ # Drop the code outside the block.
+ $stmt =~ s/(^[^{]*){\s*//;
my $before = $1;
- $stmt =~ s/}([^}]*$)//;
+ $stmt =~ s/\s*}([^}]*$)//;
my $after = $1;
#print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n";
#print "stmt<$stmt>\n\n";
- # Count the ;'s if there is fewer than two
- # then there can only be one statement,
- # if there is a brace inside we cannot
- # trivially detect if its one statement.
- # Also nested if's often require braces to
- # disambiguate the else binding so shhh there.
- my @semi = ($stmt =~ /;/g);
- push(@semi, "/**/") if ($stmt =~ m@/\*@);
- ##print "semi<" . scalar(@semi) . ">\n";
- if ($lvl == 0 && scalar(@semi) < 2 &&
+ # Count the newlines, if there is only one
+ # then the block should not have {}'s.
+ my @lines = ($stmt =~ /\n/g);
+ #print "lines<" . scalar(@lines) . ">\n";
+ if ($lvl == 0 && scalar(@lines) == 0 &&
$stmt !~ /{/ && $stmt !~ /\bif\b/ &&
$before !~ /}/ && $after !~ /{/) {
my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n";
@@ -1372,6 +1534,11 @@ sub process {
ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
}
+# Check for __inline__ and __inline, prefer inline
+ if ($line =~ /\b(__inline__|__inline)\b/) {
+ WARN("plain inline is preferred over $1\n" . $herecurr);
+ }
+
# check for new externs in .c files.
if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) {
WARN("externs should be avoided in .c files\n" . $herecurr);
@@ -1392,21 +1559,33 @@ sub process {
}
}
- if ($chk_patch && !$is_patch) {
+ # In mailback mode only produce a report in the negative, for
+ # things that appear to be patches.
+ if ($mailback && ($clean == 1 || !$is_patch)) {
+ exit(0);
+ }
+
+ # This is not a patch, and we are are in 'no-patch' mode so
+ # just keep quiet.
+ if (!$chk_patch && !$is_patch) {
+ exit(0);
+ }
+
+ if (!$is_patch) {
ERROR("Does not appear to be a unified-diff format patch\n");
}
if ($is_patch && $chk_signoff && $signoff == 0) {
ERROR("Missing Signed-off-by: line(s)\n");
}
- if ($clean == 0 && ($chk_patch || $is_patch)) {
- print report_dump();
- if ($quiet < 2) {
- print "total: $cnt_error errors, $cnt_warn warnings, " .
- (($check)? "$cnt_chk checks, " : "") .
- "$cnt_lines lines checked\n";
- }
+ print report_dump();
+ if ($summary) {
+ print "total: $cnt_error errors, $cnt_warn warnings, " .
+ (($check)? "$cnt_chk checks, " : "") .
+ "$cnt_lines lines checked\n";
+ print "\n" if ($quiet == 0);
}
+
if ($clean == 1 && $quiet == 0) {
print "Your patch has no obvious style problems and is ready for submission.\n"
}
diff --git a/security/commoncap.c b/security/commoncap.c
index 302e8d0839a..5bc1895f3f9 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -526,6 +526,15 @@ int cap_task_kill(struct task_struct *p, struct siginfo *info,
if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
return 0;
+ /*
+ * Running a setuid root program raises your capabilities.
+ * Killing your own setuid root processes was previously
+ * allowed.
+ * We must preserve legacy signal behavior in this case.
+ */
+ if (p->euid == 0 && p->uid == current->uid)
+ return 0;
+
/* sigcont is permitted within same session */
if (sig == SIGCONT && (task_session_nr(current) == task_session_nr(p)))
return 0;