diff options
342 files changed, 4981 insertions, 2179 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b47fba58d20..79f0ed9f60d 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -169,3 +169,12 @@ What: pci_module_init(driver) When: January 2007 Why: Is replaced by pci_register_driver(pci_driver). Who: Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de> + +--------------------------- + +What: I2C interface of the it87 driver +When: January 2007 +Why: The ISA interface is faster and should be always available. The I2C + probing is also known to cause trouble in at least one case (see + bug #5889.) +Who: Jean Delvare <khali@linux-fr.org> diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f new file mode 100644 index 00000000000..28c5b7d1eb9 --- /dev/null +++ b/Documentation/hwmon/f71805f @@ -0,0 +1,105 @@ +Kernel driver f71805f +===================== + +Supported chips: + * Fintek F71805F/FG + Prefix: 'f71805f' + Addresses scanned: none, address read from Super I/O config space + Datasheet: Provided by Fintek on request + +Author: Jean Delvare <khali@linux-fr.org> + +Thanks to Denis Kieft from Barracuda Networks for the donation of a +test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and +for providing initial documentation. + +Thanks to Kris Chen from Fintek for answering technical questions and +providing additional documentation. + +Thanks to Chris Lin from Jetway for providing wiring schematics and +anwsering technical questions. + + +Description +----------- + +The Fintek F71805F/FG Super I/O chip includes complete hardware monitoring +capabilities. It can monitor up to 9 voltages (counting its own power +source), 3 fans and 3 temperature sensors. + +This chip also has fan controlling features, using either DC or PWM, in +three different modes (one manual, two automatic). The driver doesn't +support these features yet. + +The driver assumes that no more than one chip is present, which seems +reasonable. + + +Voltage Monitoring +------------------ + +Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported +range is thus from 0 to 2.040 V. Voltage values outside of this range +need external resistors. An exception is in0, which is used to monitor +the chip's own power source (+3.3V), and is divided internally by a +factor 2. + +The two LSB of the voltage limit registers are not used (always 0), so +you can only set the limits in steps of 32 mV (before scaling). + +The wirings and resistor values suggested by Fintek are as follow: + + pin expected + name use R1 R2 divider raw val. + +in0 VCC VCC3.3V int. int. 2.00 1.65 V +in1 VIN1 VTT1.2V 10K - 1.00 1.20 V +in2 VIN2 VRAM 100K 100K 2.00 ~1.25 V (1) +in3 VIN3 VCHIPSET 47K 100K 1.47 2.24 V (2) +in4 VIN4 VCC5V 200K 47K 5.25 0.95 V +in5 VIN5 +12V 200K 20K 11.00 1.05 V +in6 VIN6 VCC1.5V 10K - 1.00 1.50 V +in7 VIN7 VCORE 10K - 1.00 ~1.40 V (1) +in8 VIN8 VSB5V 200K 47K 1.00 0.95 V + +(1) Depends on your hardware setup. +(2) Obviously not correct, swapping R1 and R2 would make more sense. + +These values can be used as hints at best, as motherboard manufacturers +are free to use a completely different setup. As a matter of fact, the +Jetway K8M8MS uses a significantly different setup. You will have to +find out documentation about your own motherboard, and edit sensors.conf +accordingly. + +Each voltage measured has associated low and high limits, each of which +triggers an alarm when crossed. + + +Fan Monitoring +-------------- + +Fan rotation speeds are reported as 12-bit values from a gated clock +signal. Speeds down to 366 RPM can be measured. There is no theoretical +high limit, but values over 6000 RPM seem to cause problem. The effective +resolution is much lower than you would expect, the step between different +register values being 10 rather than 1. + +The chip assumes 2 pulse-per-revolution fans. + +An alarm is triggered if the rotation speed drops below a programmable +limit or is too low to be measured. + + +Temperature Monitoring +---------------------- + +Temperatures are reported in degrees Celsius. Each temperature measured +has a high limit, those crossing triggers an alarm. There is an associated +hysteresis value, below which the temperature has to drop before the +alarm is cleared. + +All temperature channels are external, there is no embedded temperature +sensor. Each channel can be used for connecting either a thermal diode +or a thermistor. The driver reports the currently selected mode, but +doesn't allow changing it. In theory, the BIOS should have configured +everything properly. diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 7f42e441c64..9555be1ed99 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -9,7 +9,7 @@ Supported chips: http://www.ite.com.tw/ * IT8712F Prefix: 'it8712' - Addresses scanned: I2C 0x28 - 0x2f + Addresses scanned: I2C 0x2d from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website http://www.ite.com.tw/ diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index 764cdc5480e..a0d0ab24288 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface @@ -179,11 +179,12 @@ temp[1-*]_auto_point[1-*]_temp_hyst **************** temp[1-3]_type Sensor type selection. - Integers 1, 2, 3 or thermistor Beta value (3435) + Integers 1 to 4 or thermistor Beta value (typically 3435) Read/Write. 1: PII/Celeron Diode 2: 3904 transistor 3: thermal diode + 4: thermistor (default/unknown Beta) Not all types are supported by all chips temp[1-4]_max Temperature max value. @@ -261,6 +262,21 @@ alarms Alarm bitmask. of individual bits. Bits are defined in kernel/include/sensors.h. +alarms_in Alarm bitmask relative to in (voltage) channels + Read only + A '1' bit means an alarm, LSB corresponds to in0 and so on + Prefered to 'alarms' for newer chips + +alarms_fan Alarm bitmask relative to fan channels + Read only + A '1' bit means an alarm, LSB corresponds to fan1 and so on + Prefered to 'alarms' for newer chips + +alarms_temp Alarm bitmask relative to temp (temperature) channels + Read only + A '1' bit means an alarm, LSB corresponds to temp1 and so on + Prefered to 'alarms' for newer chips + beep_enable Beep/interrupt enable 0 to disable. 1 to enable. diff --git a/Documentation/i2c/busses/i2c-sis69x b/Documentation/i2c/busses/i2c-sis96x index b88953dfd58..00a009b977e 100644 --- a/Documentation/i2c/busses/i2c-sis69x +++ b/Documentation/i2c/busses/i2c-sis96x @@ -7,7 +7,7 @@ Supported adapters: Any combination of these host bridges: 645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746 and these south bridges: - 961, 962, 963(L) + 961, 962, 963(L) Author: Mark M. Hoffman <mhoffman@lightlink.com> @@ -29,7 +29,7 @@ The command "lspci" as root should produce something like these lines: or perhaps this... -00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 +00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961 00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016 diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 1284498e847..54e5f9b1536 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -880,6 +880,10 @@ address which can extend beyond that limit. - device_type : Should be "soc" - ranges : Should be defined as specified in 1) to describe the translation of SOC addresses for memory mapped SOC registers. + - bus-frequency: Contains the bus frequency for the SOC node. + Typically, the value of this field is filled in by the boot + loader. + Recommended properties: @@ -919,6 +923,7 @@ SOC. device_type = "soc"; ranges = <00000000 e0000000 00100000> reg = <e0000000 00003000>; + bus-frequency = <0>; } @@ -1170,6 +1175,8 @@ platforms are moved over to use the flattened-device-tree model. mdio@24520 { reg = <24520 20>; + device_type = "mdio"; + compatible = "gianfar"; ethernet-phy@0 { ...... @@ -1317,6 +1324,7 @@ not necessary as they are usually the same as the root node. device_type = "soc"; ranges = <00000000 e0000000 00100000> reg = <e0000000 00003000>; + bus-frequency = <0>; mdio@24520 { reg = <24520 20>; diff --git a/Documentation/spi/butterfly b/Documentation/spi/butterfly index a2e8c8d90e3..9927af7a629 100644 --- a/Documentation/spi/butterfly +++ b/Documentation/spi/butterfly @@ -12,13 +12,20 @@ You can make this adapter from an old printer cable and solder things directly to the Butterfly. Or (if you have the parts and skills) you can come up with something fancier, providing ciruit protection to the Butterfly and the printer port, or with a better power supply than two -signal pins from the printer port. +signal pins from the printer port. Or for that matter, you can use +similar cables to talk to many AVR boards, even a breadboard. + +This is more powerful than "ISP programming" cables since it lets kernel +SPI protocol drivers interact with the AVR, and could even let the AVR +issue interrupts to them. Later, your protocol driver should work +easily with a "real SPI controller", instead of this bitbanger. The first cable connections will hook Linux up to one SPI bus, with the AVR and a DataFlash chip; and to the AVR reset line. This is all you need to reflash the firmware, and the pins are the standard Atmel "ISP" -connector pins (used also on non-Butterfly AVR boards). +connector pins (used also on non-Butterfly AVR boards). On the parport +side this is like "sp12" programming cables. Signal Butterfly Parport (DB-25) ------ --------- --------------- @@ -40,10 +47,14 @@ by clearing PORTB.[0-3]); (b) configure the mtd_dataflash driver; and SELECT = J400.PB0/nSS = pin 17/C3,nSELECT GND = J400.GND = pin 24/GND -The "USI" controller, using J405, can be used for a second SPI bus. That -would let you talk to the AVR over SPI, running firmware that makes it act -as an SPI slave, while letting either Linux or the AVR use the DataFlash. -There are plenty of spare parport pins to wire this one up, such as: +Or you could flash firmware making the AVR into an SPI slave (keeping the +DataFlash in reset) and tweak the spi_butterfly driver to make it bind to +the driver for your custom SPI-based protocol. + +The "USI" controller, using J405, can also be used for a second SPI bus. +That would let you talk to the AVR using custom SPI-with-USI firmware, +while letting either Linux or the AVR use the DataFlash. There are plenty +of spare parport pins to wire this one up, such as: Signal Butterfly Parport (DB-25) ------ --------- --------------- diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt new file mode 100644 index 00000000000..90a5e9e5bef --- /dev/null +++ b/Documentation/unshare.txt @@ -0,0 +1,295 @@ + +unshare system call: +-------------------- +This document describes the new system call, unshare. The document +provides an overview of the feature, why it is needed, how it can +be used, its interface specification, design, implementation and +how it can be tested. + +Change Log: +----------- +version 0.1 Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006 + +Contents: +--------- + 1) Overview + 2) Benefits + 3) Cost + 4) Requirements + 5) Functional Specification + 6) High Level Design + 7) Low Level Design + 8) Test Specification + 9) Future Work + +1) Overview +----------- +Most legacy operating system kernels support an abstraction of threads +as multiple execution contexts within a process. These kernels provide +special resources and mechanisms to maintain these "threads". The Linux +kernel, in a clever and simple manner, does not make distinction +between processes and "threads". The kernel allows processes to share +resources and thus they can achieve legacy "threads" behavior without +requiring additional data structures and mechanisms in the kernel. The +power of implementing threads in this manner comes not only from +its simplicity but also from allowing application programmers to work +outside the confinement of all-or-nothing shared resources of legacy +threads. On Linux, at the time of thread creation using the clone system +call, applications can selectively choose which resources to share +between threads. + +unshare system call adds a primitive to the Linux thread model that +allows threads to selectively 'unshare' any resources that were being +shared at the time of their creation. unshare was conceptualized by +Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part +of the discussion on POSIX threads on Linux. unshare augments the +usefulness of Linux threads for applications that would like to control +shared resources without creating a new process. unshare is a natural +addition to the set of available primitives on Linux that implement +the concept of process/thread as a virtual machine. + +2) Benefits +----------- +unshare would be useful to large application frameworks such as PAM +where creating a new process to control sharing/unsharing of process +resources is not possible. Since namespaces are shared by default +when creating a new process using fork or clone, unshare can benefit +even non-threaded applications if they have a need to disassociate +from default shared namespace. The following lists two use-cases +where unshare can be used. + +2.1 Per-security context namespaces +----------------------------------- +unshare can be used to implement polyinstantiated directories using +the kernel's per-process namespace mechanism. Polyinstantiated directories, +such as per-user and/or per-security context instance of /tmp, /var/tmp or +per-security context instance of a user's home directory, isolate user +processes when working with these directories. Using unshare, a PAM +module can easily setup a private namespace for a user at login. +Polyinstantiated directories are required for Common Criteria certification +with Labeled System Protection Profile, however, with the availability +of shared-tree feature in the Linux kernel, even regular Linux systems +can benefit from setting up private namespaces at login and +polyinstantiating /tmp, /var/tmp and other directories deemed +appropriate by system administrators. + +2.2 unsharing of virtual memory and/or open files +------------------------------------------------- +Consider a client/server application where the server is processing +client requests by creating processes that share resources such as +virtual memory and open files. Without unshare, the server has to +decide what needs to be shared at the time of creating the process +which services the request. unshare allows the server an ability to +disassociate parts of the context during the servicing of the +request. For large and complex middleware application frameworks, this +ability to unshare after the process was created can be very +useful. + +3) Cost +------- +In order to not duplicate code and to handle the fact that unshare +works on an active task (as opposed to clone/fork working on a newly +allocated inactive task) unshare had to make minor reorganizational +changes to copy_* functions utilized by clone/fork system call. +There is a cost associated with altering existing, well tested and +stable code to implement a new feature that may not get exercised +extensively in the beginning. However, with proper design and code +review of the changes and creation of an unshare test for the LTP +the benefits of this new feature can exceed its cost. + +4) Requirements +--------------- +unshare reverses sharing that was done using clone(2) system call, +so unshare should have a similar interface as clone(2). That is, +since flags in clone(int flags, void *stack) specifies what should +be shared, similar flags in unshare(int flags) should specify +what should be unshared. Unfortunately, this may appear to invert +the meaning of the flags from the way they are used in clone(2). +However, there was no easy solution that was less confusing and that +allowed incremental context unsharing in future without an ABI change. + +unshare interface should accommodate possible future addition of +new context flags without requiring a rebuild of old applications. +If and when new context flags are added, unshare design should allow +incremental unsharing of those resources on an as needed basis. + +5) Functional Specification +--------------------------- +NAME + unshare - disassociate parts of the process execution context + +SYNOPSIS + #include <sched.h> + + int unshare(int flags); + +DESCRIPTION + unshare allows a process to disassociate parts of its execution + context that are currently being shared with other processes. Part + of execution context, such as the namespace, is shared by default + when a new process is created using fork(2), while other parts, + such as the virtual memory, open file descriptors, etc, may be + shared by explicit request to share them when creating a process + using clone(2). + + The main use of unshare is to allow a process to control its + shared execution context without creating a new process. + + The flags argument specifies one or bitwise-or'ed of several of + the following constants. + + CLONE_FS + If CLONE_FS is set, file system information of the caller + is disassociated from the shared file system information. + + CLONE_FILES + If CLONE_FILES is set, the file descriptor table of the + caller is disassociated from the shared file descriptor + table. + + CLONE_NEWNS + If CLONE_NEWNS is set, the namespace of the caller is + disassociated from the shared namespace. + + CLONE_VM + If CLONE_VM is set, the virtual memory of the caller is + disassociated from the shared virtual memory. + +RETURN VALUE + On success, zero returned. On failure, -1 is returned and errno is + +ERRORS + EPERM CLONE_NEWNS was specified by a non-root process (process + without CAP_SYS_ADMIN). + + ENOMEM Cannot allocate sufficient memory to copy parts of caller's + context that need to be unshared. + + EINVAL Invalid flag was specified as an argument. + +CONFORMING TO + The unshare() call is Linux-specific and should not be used + in programs intended to be portable. + +SEE ALSO + clone(2), fork(2) + +6) High Level Design +-------------------- +Depending on the flags argument, the unshare system call allocates +appropriate process context structures, populates it with values from +the current shared version, associates newly duplicated structures +with the current task structure and releases corresponding shared +versions. Helper functions of clone (copy_*) could not be used +directly by unshare because of the following two reasons. + 1) clone operates on a newly allocated not-yet-active task + structure, where as unshare operates on the current active + task. Therefore unshare has to take appropriate task_lock() + before associating newly duplicated context structures + 2) unshare has to allocate and duplicate all context structures + that are being unshared, before associating them with the + current task and releasing older shared structures. Failure + do so will create race conditions and/or oops when trying + to backout due to an error. Consider the case of unsharing + both virtual memory and namespace. After successfully unsharing + vm, if the system call encounters an error while allocating + new namespace structure, the error return code will have to + reverse the unsharing of vm. As part of the reversal the + system call will have to go back to older, shared, vm + structure, which may not exist anymore. + +Therefore code from copy_* functions that allocated and duplicated +current context structure was moved into new dup_* functions. Now, +copy_* functions call dup_* functions to allocate and duplicate +appropriate context structures and then associate them with the +task structure that is being constructed. unshare system call on +the other hand performs the following: + 1) Check flags to force missing, but implied, flags + 2) For each context structure, call the corresponding unshare + helper function to allocate and duplicate a new context + structure, if the appropriate bit is set in the flags argument. + 3) If there is no error in allocation and duplication and there + are new context structures then lock the current task structure, + associate new context structures with the current task structure, + and release the lock on the current task structure. + 4) Appropriately release older, shared, context structures. + +7) Low Level Design +------------------- +Implementation of unshare can be grouped in the following 4 different +items: + a) Reorganization of existing copy_* functions + b) unshare system call service function + c) unshare helper functions for each different process context + d) Registration of system call number for different architectures + + 7.1) Reorganization of copy_* functions + Each copy function such as copy_mm, copy_namespace, copy_files, + etc, had roughly two components. The first component allocated + and duplicated the appropriate structure and the second component + linked it to the task structure passed in as an argument to the copy + function. The first component was split into its own function. + These dup_* functions allocated and duplicated the appropriate + context structure. The reorganized copy_* functions invoked + their corresponding dup_* functions and then linked the newly + duplicated structures to the task structure with which the + copy function was called. + + 7.2) unshare system call service function + * Check flags + Force implied flags. If CLONE_THREAD is set force CLONE_VM. + If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is + set and signals are also being shared, force CLONE_THREAD. If + CLONE_NEWNS is set, force CLONE_FS. + * For each context flag, invoke the corresponding unshare_* + helper routine with flags passed into the system call and a + reference to pointer pointing the new unshared structure + * If any new structures are created by unshare_* helper + functions, take the task_lock() on the current task, + modify appropriate context pointers, and release the + task lock. + * For all newly unshared structures, release the corresponding + older, shared, structures. + + 7.3) unshare_* helper functions + For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND, + and CLONE_THREAD, return -EINVAL since they are not implemented yet. + For others, check the flag value to see if the unsharing is + required for that structure. If it is, invoke the corresponding + dup_* function to allocate and duplicate the structure and return + a pointer to it. + + 7.4) Appropriately modify architecture specific code to register the + the new system call. + +8) Test Specification +--------------------- +The test for unshare should test the following: + 1) Valid flags: Test to check that clone flags for signal and + signal handlers, for which unsharing is not implemented + yet, return -EINVAL. + 2) Missing/implied flags: Test to make sure that if unsharing + namespace without specifying unsharing of filesystem, correctly + unshares both namespace and filesystem information. + 3) For each of the four (namespace, filesystem, files and vm) + supported unsharing, verify that the system call correctly + unshares the appropriate structure. Verify that unsharing + them individually as well as in combination with each + other works as expected. + 4) Concurrent execution: Use shared memory segments and futex on + an address in the shm segment to synchronize execution of + about 10 threads. Have a couple of threads execute execve, + a couple _exit and the rest unshare with different combination + of flags. Verify that unsharing is performed as expected and + that there are no oops or hangs. + +9) Future Work +-------------- +The current implementation of unshare does not allow unsharing of +signals and signal handlers. Signals are complex to begin with and +to unshare signals and/or signal handlers of a currently running +process is even more complex. If in the future there is a specific +need to allow unsharing of signals and/or signal handlers, it can +be incrementally added to unshare without affecting legacy +applications using unshare. + diff --git a/MAINTAINERS b/MAINTAINERS index a05aefdea60..b22db521cec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -931,6 +931,12 @@ M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com L: ext3-users@redhat.com S: Maintained +F71805F HARDWARE MONITORING DRIVER +P: Jean Delvare +M: khali@linux-fr.org +L: lm-sensors@lm-sensors.org +S: Maintained + FARSYNC SYNCHRONOUS DRIVER P: Kevin Curtis M: kevin.curtis@farsite.co.uk diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 4b873527ce1..02c2db08114 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -73,9 +73,6 @@ cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); -/* cpus reported in the hwrpb */ -static unsigned long hwrpb_cpu_present_mask __initdata = 0; - int smp_num_probed; /* Internal processor count */ int smp_num_cpus = 1; /* Number that came online. */ @@ -442,7 +439,7 @@ setup_smp(void) if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; /* Assume here that "whami" == index */ - hwrpb_cpu_present_mask |= (1UL << i); + cpu_set(i, cpu_possible_map); cpu->pal_revision = boot_cpu_palrev; } @@ -453,12 +450,12 @@ setup_smp(void) } } else { smp_num_probed = 1; - hwrpb_cpu_present_mask = (1UL << boot_cpuid); + cpu_set(boot_cpuid, cpu_possible_map); } cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", - smp_num_probed, hwrpb_cpu_present_mask); + smp_num_probed, cpu_possible_map.bits[0]); } /* @@ -467,8 +464,6 @@ setup_smp(void) void __init smp_prepare_cpus(unsigned int max_cpus) { - int cpu_count, i; - /* Take care of some initial bookkeeping. */ memset(ipi_data, 0, sizeof(ipi_data)); @@ -486,19 +481,7 @@ smp_prepare_cpus(unsigned int max_cpus) printk(KERN_INFO "SMP starting up secondaries.\n"); - cpu_count = 1; - for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) { - if (i == boot_cpuid) - continue; - - if (((hwrpb_cpu_present_mask >> i) & 1) == 0) - continue; - - cpu_set(i, cpu_possible_map); - cpu_count++; - } - - smp_num_cpus = cpu_count; + smp_num_cpus = smp_num_probed; } void __devinit diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5959e36c3b4..15dc1a0dffb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -10,9 +10,9 @@ config ARM default y help The ARM series is a line of low-power-consumption RISC chip designs - licensed by ARM ltd and targeted at embedded applications and + licensed by ARM Ltd and targeted at embedded applications and handhelds such as the Compaq IPAQ. ARM-based PCs are no longer - manufactured, but legacy ARM-based PC hardware remains popular in + manufactured, but legacy ARM-based PC hardware remains popular in Europe. There is an ARM Linux project with a web page at <http://www.arm.linux.org.uk/>. @@ -69,6 +69,9 @@ config GENERIC_ISA_DMA config FIQ bool +config ARCH_MTD_XIP + bool + source "init/Kconfig" menu "System Type" @@ -81,45 +84,62 @@ config ARCH_CLPS7500 bool "Cirrus-CL-PS7500FE" select TIMER_ACORN select ISA + help + Support for the Cirrus Logic PS7500FE system-on-a-chip. config ARCH_CLPS711X bool "CLPS711x/EP721x-based" + help + Support for Cirrus Logic 711x/721x based boards. config ARCH_CO285 bool "Co-EBSA285" select FOOTBRIDGE select FOOTBRIDGE_ADDIN + help + Support for Intel's EBSA285 companion chip. config ARCH_EBSA110 bool "EBSA-110" select ISA help This is an evaluation board for the StrongARM processor available - from Digital. It has limited hardware on-board, including an onboard + from Digital. It has limited hardware on-board, including an Ethernet interface, two PCMCIA sockets, two serial ports and a parallel port. config ARCH_FOOTBRIDGE bool "FootBridge" select FOOTBRIDGE + help + Support for systems based on the DC21285 companion chip + ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. config ARCH_INTEGRATOR bool "Integrator" select ARM_AMBA select ICST525 + help + Support for ARM's Integrator platform. config ARCH_IOP3XX bool "IOP3xx-based" select PCI + help + Support for Intel's IOP3XX (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" select DMABOUNCE select PCI + help + Support for Intel's IXP4XX (XScale) family of processors. config ARCH_IXP2000 bool "IXP2400/2800-based" select PCI + help + Support for Intel's IXP2400/2800 (XScale) family of processors. config ARCH_L7200 bool "LinkUp-L7200" @@ -136,6 +156,9 @@ config ARCH_L7200 config ARCH_PXA bool "PXA2xx-based" + select ARCH_MTD_XIP + help + Support for Intel's PXA2XX processor line. config ARCH_RPC bool "RiscPC" @@ -152,19 +175,25 @@ config ARCH_SA1100 bool "SA1100-based" select ISA select ARCH_DISCONTIGMEM_ENABLE + select ARCH_MTD_XIP + help + Support for StrongARM 11x0 based boards. config ARCH_S3C2410 bool "Samsung S3C2410" help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or - the Samsung SMDK2410 development board (and derviatives). + the Samsung SMDK2410 development board (and derivatives). config ARCH_SHARK bool "Shark" select ISA select ISA_DMA select PCI + help + Support for the StrongARM based Digital DNARD machine, also known + as "Shark" (<http://www.shark-linux.de/shark.html>). config ARCH_LH7A40X bool "Sharp LH7A40X" @@ -176,6 +205,8 @@ config ARCH_LH7A40X config ARCH_OMAP bool "TI OMAP" + help + Support for TI's OMAP platform (OMAP1 and OMAP2). config ARCH_VERSATILE bool "Versatile" @@ -194,6 +225,8 @@ config ARCH_REALVIEW config ARCH_IMX bool "IMX" + help + Support for Motorola's i.MX family of processors (MX1, MXL). config ARCH_H720X bool "Hynix-HMS720x-based" @@ -210,8 +243,8 @@ config ARCH_AAEC2000 config ARCH_AT91RM9200 bool "AT91RM9200" help - Say Y here if you intend to run this kernel on an AT91RM9200-based - board. + Say Y here if you intend to run this kernel on an Atmel + AT91RM9200-based board. endchoice @@ -417,8 +450,8 @@ config AEABI To use this you need GCC version 4.0.0 or later. config OABI_COMPAT - bool "Allow old ABI binaries to run with this kernel" - depends on AEABI + bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" + depends on AEABI && EXPERIMENTAL default y help This option preserves the old syscall interface along with the diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig index 9592e3925c7..5fdaf3ce9d5 100644 --- a/arch/arm/configs/enp2611_defconfig +++ b/arch/arm/configs/enp2611_defconfig @@ -171,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0" # CONFIG_XIP_KERNEL is not set # diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig index d9d6bb86a6f..c67fc449a11 100644 --- a/arch/arm/configs/ixdp2400_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig @@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0" # CONFIG_XIP_KERNEL is not set # diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig index 2dc9d499c7d..60d66e82c51 100644 --- a/arch/arm/configs/ixdp2401_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig @@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0" # CONFIG_XIP_KERNEL is not set # diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig index ea8f4b478fa..f54f3dcc5b3 100644 --- a/arch/arm/configs/ixdp2801_defconfig +++ b/arch/arm/configs/ixdp2801_defconfig @@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware ixdp2x01_clock=50000000" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0" # CONFIG_XIP_KERNEL is not set # diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 1964ccd8a71..6695b07cf1b 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,11 +1,10 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-rc1 -# Sun Nov 13 17:41:24 2005 +# Linux kernel version: 2.6.16-rc2 +# Mon Feb 6 11:17:23 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_CALIBRATE_DELAY=y @@ -28,27 +27,31 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y +CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set +CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -102,6 +105,7 @@ CONFIG_ARCH_S3C2410=y # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set # # S3C24XX Implementations @@ -160,7 +164,6 @@ CONFIG_CPU_TLB_V4WBI=y # Bus support # CONFIG_ISA=y -CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -172,6 +175,7 @@ CONFIG_ISA_DMA_API=y # # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set +# CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -214,6 +218,8 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set CONFIG_APM=y # @@ -259,6 +265,11 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -276,7 +287,6 @@ CONFIG_TCP_CONG_BIC=y # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -300,6 +310,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -412,8 +427,6 @@ CONFIG_PARPORT_1284=y # # Block devices # -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -502,7 +515,6 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_SMC91X is not set CONFIG_DM9000=y @@ -607,11 +619,11 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_ROCKETPORT is not set # CONFIG_CYCLADES is not set # CONFIG_DIGIEPCA is not set -# CONFIG_ESPSERIAL is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -625,6 +637,7 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y @@ -687,6 +700,7 @@ CONFIG_S3C2410_RTC=y # # TPM devices # +# CONFIG_TCG_TPM is not set # CONFIG_TELCLOCK is not set # @@ -731,6 +745,12 @@ CONFIG_SENSORS_EEPROM=m # CONFIG_I2C_DEBUG_CHIP is not set # +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# # Hardware Monitoring support # CONFIG_HWMON=y @@ -863,6 +883,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y CONFIG_INOTIFY=y @@ -897,6 +918,7 @@ CONFIG_SYSFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -965,6 +987,7 @@ CONFIG_SOLARIS_X86_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -1020,12 +1043,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1034,6 +1058,7 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index d058e7c1256..8c3035d5ffc 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -291,21 +291,21 @@ CALL(sys_mq_getsetattr) /* 280 */ CALL(sys_waitid) CALL(sys_socket) - CALL(sys_bind) - CALL(sys_connect) + CALL(ABI(sys_bind, sys_oabi_bind)) + CALL(ABI(sys_connect, sys_oabi_connect)) CALL(sys_listen) /* 285 */ CALL(sys_accept) CALL(sys_getsockname) CALL(sys_getpeername) CALL(sys_socketpair) CALL(sys_send) -/* 290 */ CALL(sys_sendto) +/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto)) CALL(sys_recv) CALL(sys_recvfrom) CALL(sys_shutdown) CALL(sys_setsockopt) /* 295 */ CALL(sys_getsockopt) - CALL(sys_sendmsg) + CALL(ABI(sys_sendmsg, sys_oabi_sendmsg)) CALL(sys_recvmsg) CALL(ABI(sys_semop, sys_oabi_semop)) CALL(sys_semget) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d401d908c46..964cd717506 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -333,10 +333,14 @@ __pabt_svc: @ 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: @@ -705,7 +709,12 @@ __kuser_memory_barrier: @ 0xffff0fa0 * The C flag is also set if *ptr was changed to allow for assembly * optimization in the calling code. * - * Note: this routine already includes memory barriers as needed. + * Notes: + * + * - 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: * @@ -756,12 +765,18 @@ __kuser_cmpxchg: @ 0xffff0fc0 * exception happening just after the str instruction which would * clear the Z flag although the exchange was done. */ +#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 +#else +#warning "NPTL on non MMU needs fixing" + mov r0, #-1 + adds r0, r0, #0 +#endif mov pc, lr #else diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index eafa8e5284a..9d4b76409c6 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -59,6 +59,16 @@ * struct sembuf loses its padding with EABI. Since arrays of them are * used they have to be copyed to remove the padding. Compatibility wrappers * provided below. + * + * sys_bind: + * sys_connect: + * sys_sendmsg: + * sys_sendto: + * + * struct sockaddr_un loses its padding with EABI. Since the size of the + * structure is used as a validation test in unix_mkname(), we need to + * change the length argument to 110 whenever it is 112. Compatibility + * wrappers provided below. */ #include <linux/syscalls.h> @@ -67,6 +77,7 @@ #include <linux/fcntl.h> #include <linux/eventpoll.h> #include <linux/sem.h> +#include <linux/socket.h> #include <asm/ipc.h> #include <asm/uaccess.h> @@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, return sys_ipc(call, first, second, third, ptr, fifth); } } + +asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen) +{ + sa_family_t sa_family; + if (addrlen == 112 && + get_user(sa_family, &addr->sa_family) == 0 && + sa_family == AF_UNIX) + addrlen = 110; + return sys_bind(fd, addr, addrlen); +} + +asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen) +{ + sa_family_t sa_family; + if (addrlen == 112 && + get_user(sa_family, &addr->sa_family) == 0 && + sa_family == AF_UNIX) + addrlen = 110; + return sys_connect(fd, addr, addrlen); +} + +asmlinkage long sys_oabi_sendto(int fd, void __user *buff, + size_t len, unsigned flags, + struct sockaddr __user *addr, + int addrlen) +{ + sa_family_t sa_family; + if (addrlen == 112 && + get_user(sa_family, &addr->sa_family) == 0 && + sa_family == AF_UNIX) + addrlen = 110; + return sys_sendto(fd, buff, len, flags, addr, addrlen); +} + +asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) +{ + struct sockaddr __user *addr; + int msg_namelen; + sa_family_t sa_family; + if (msg && + get_user(msg_namelen, &msg->msg_namelen) == 0 && + msg_namelen == 112 && + get_user(addr, &msg->msg_name) == 0 && + get_user(sa_family, &addr->sa_family) == 0 && + sa_family == AF_UNIX) + { + /* + * HACK ALERT: there is a limit to how much backward bending + * we should do for what is actually a transitional + * compatibility layer. This already has known flaws with + * a few ioctls that we don't intend to fix. Therefore + * consider this blatent hack as another one... and take care + * to run for cover. In most cases it will "just work fine". + * If it doesn't, well, tough. + */ + put_user(110, &msg->msg_namelen); + } + return sys_sendmsg(fd, msg, flags); +} + diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 0793dcf54f2..0e2b641268a 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -24,6 +24,8 @@ config ARCH_CEIVA config ARCH_CLEP7312 bool "CLEP7312" + help + Boards based on the Cirrus Logic 7212/7312 chips. config ARCH_EDB7211 bool "EDB7211" diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index dc31e3fd6c5..8ab1b040288 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -27,7 +27,6 @@ #include <asm/mach/arch.h> #include <linux/interrupt.h> #include "generic.h" -#include <asm/serial.h> static struct resource cs89x0_resources[] = { [0] = { diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 9e5a13bb39d..52fac89e95b 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -106,6 +106,7 @@ static void __init enp2611_pci_preinit(void) { ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); ixp2000_pci_preinit(); + pcibios_setup("firmware"); } static inline int enp2611_pci_valid_device(struct pci_bus *bus, diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 7c782403042..09101271298 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -68,6 +68,7 @@ void __init ixdp2400_pci_preinit(void) { ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); ixp2000_pci_preinit(); + pcibios_setup("firmware"); } int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 10f06606d46..150519fb38e 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -212,6 +212,7 @@ void __init ixdp2x01_pci_preinit(void) { ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000); ixp2000_pci_preinit(); + pcibios_setup("firmware"); } #define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) @@ -299,7 +300,9 @@ struct hw_pci ixdp2x01_pci __initdata = { int __init ixdp2x01_pci_init(void) { - pci_common_init(&ixdp2x01_pci); + if (machine_is_ixdp2401() || machine_is_ixdp2801()) + pci_common_init(&ixdp2x01_pci); + return 0; } diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index bdc20b51b07..a177e78b2b8 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -30,6 +30,7 @@ static void __init omap_generic_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); } @@ -104,7 +105,7 @@ static void __init omap_generic_init(void) static void __init omap_generic_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 9533c36a92d..89f0cc74a51 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -128,6 +128,7 @@ static void __init h2_init_smc91x(void) static void __init h2_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); h2_init_smc91x(); @@ -194,7 +195,7 @@ static void __init h2_init(void) static void __init h2_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } MACHINE_START(OMAP_H2, "TI-H2") diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index d665efc1c34..d9f38626599 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -203,6 +203,7 @@ static void __init h3_init_smc91x(void) void h3_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); h3_init_smc91x(); @@ -210,7 +211,7 @@ void h3_init_irq(void) static void __init h3_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 652f37c7f90..a04e4332915 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -181,6 +181,7 @@ static void __init innovator_init_smc91x(void) void innovator_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); #ifdef CONFIG_ARCH_OMAP15XX @@ -285,7 +286,7 @@ static void __init innovator_init(void) static void __init innovator_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap1510()) { diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index 58f783930d4..60d5f8a3339 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c @@ -65,6 +65,7 @@ static struct omap_board_config_kernel netstar_config[] = { static void __init netstar_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); } @@ -108,7 +109,7 @@ static void __init netstar_init(void) static void __init netstar_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } #define MACHINE_PANICED 1 diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index e5d126e8f27..543fa136106 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -169,6 +169,7 @@ static void __init osk_init_cf(void) static void __init osk_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); osk_init_smc91x(); @@ -269,7 +270,7 @@ static void __init osk_init(void) static void __init osk_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } MACHINE_START(OMAP_OSK, "TI-OSK") diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 67fada20762..e488f723677 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -34,6 +34,7 @@ static void __init omap_generic_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); } @@ -72,7 +73,7 @@ static void __init omap_generic_init(void) static void __init omap_generic_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 88708a0c52a..3913a3cc0ce 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -144,6 +144,7 @@ static void __init perseus2_init_smc91x(void) void omap_perseus2_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); perseus2_init_smc91x(); @@ -160,7 +161,7 @@ static struct map_desc omap_perseus2_io_desc[] __initdata = { static void __init omap_perseus2_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); iotable_init(omap_perseus2_io_desc, ARRAY_SIZE(omap_perseus2_io_desc)); diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 959b4b847c8..bfd5fdd1a87 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -162,6 +162,7 @@ static struct omap_board_config_kernel voiceblue_config[] = { static void __init voiceblue_init_irq(void) { + omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); } @@ -206,7 +207,7 @@ static void __init voiceblue_init(void) static void __init voiceblue_map_io(void) { - omap_map_common_io(); + omap1_map_common_io(); } #define MACHINE_PANICED 1 diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index a7a19f75b9e..82d556be79c 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <asm/tlb.h> #include <asm/mach/map.h> #include <asm/io.h> #include <asm/arch/mux.h> @@ -83,15 +84,24 @@ static struct map_desc omap16xx_io_desc[] __initdata = { }; #endif -static int initialized = 0; - -static void __init _omap_map_io(void) +/* + * Maps common IO regions for omap1. This should only get called from + * board specific init. + */ +void __init omap1_map_common_io(void) { - initialized = 1; - - /* We have to initialize the IO space mapping before we can run - * cpu_is_omapxxx() macros. */ iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); + + /* Normally devicemaps_init() would flush caches and tlb after + * mdesc->map_io(), but we must also do it here because of the CPU + * revision check below. + */ + local_flush_tlb_all(); + flush_cache_all(); + + /* We want to check CPU revision early for cpu_is_omapxxxx() macros. + * IO space mapping must be initialized before we can do that. + */ omap_check_revision(); #ifdef CONFIG_ARCH_OMAP730 @@ -111,7 +121,14 @@ static void __init _omap_map_io(void) #endif omap_sram_init(); +} +/* + * Common low-level hardware init for omap1. This should only get called from + * board specific init. + */ +void __init omap1_init_common_hw() +{ /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort * on a Posted Write in the TIPB Bridge". */ @@ -121,16 +138,7 @@ static void __init _omap_map_io(void) /* Must init clocks early to assure that timer interrupt works */ omap1_clk_init(); -} -/* - * This should only get called from board specific init - */ -void __init omap_map_common_io(void) -{ - if (!initialized) { - _omap_map_io(); - omap1_mux_init(); - } + omap1_mux_init(); } diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index b937123e5c6..eaecbf422d8 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -33,6 +33,7 @@ static void __init omap_generic_init_irq(void) { + omap2_init_common_hw(); omap_init_irq(); } @@ -64,7 +65,7 @@ static void __init omap_generic_init(void) static void __init omap_generic_map_io(void) { - omap_map_common_io(); + omap2_map_common_io(); } MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index c3c35d40378..a300d634d8a 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -136,6 +136,7 @@ static inline void __init h4_init_smc91x(void) static void __init omap_h4_init_irq(void) { + omap2_init_common_hw(); omap_init_irq(); omap_gpio_init(); h4_init_smc91x(); @@ -181,7 +182,7 @@ static void __init omap_h4_init(void) static void __init omap_h4_map_io(void) { - omap_map_common_io(); + omap2_map_common_io(); } MACHINE_START(OMAP_H4, "OMAP2420 H4 board") diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 4a222f59f2c..4303d988c4b 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -182,7 +182,7 @@ static const struct icst307_params realview_oscvco_params = { static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco) { void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; - void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET; + void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; u32 val; val = readl(sys_osc) & ~0x7ffff; diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index af2f3d52b61..08489efdaf0 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c @@ -40,7 +40,6 @@ #include <linux/mutex.h> #include <asm/hardware.h> -#include <asm/atomic.h> #include <asm/irq.h> #include <asm/io.h> @@ -59,22 +58,18 @@ static DEFINE_MUTEX(clocks_mutex); void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) { unsigned long clkcon; - unsigned long flags; - - local_irq_save(flags); clkcon = __raw_readl(S3C2410_CLKCON); - clkcon &= ~clocks; if (enable) clkcon |= clocks; + else + clkcon &= ~clocks; /* ensure none of the special function bits set */ clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); __raw_writel(clkcon, S3C2410_CLKCON); - - local_irq_restore(flags); } /* enable and disable calls for use with the clk struct */ @@ -138,16 +133,32 @@ void clk_put(struct clk *clk) int clk_enable(struct clk *clk) { - if (IS_ERR(clk)) + if (IS_ERR(clk) || clk == NULL) return -EINVAL; - return (clk->enable)(clk, 1); + clk_enable(clk->parent); + + mutex_lock(&clocks_mutex); + + if ((clk->usage++) == 0) + (clk->enable)(clk, 1); + + mutex_unlock(&clocks_mutex); + return 0; } void clk_disable(struct clk *clk) { - if (!IS_ERR(clk)) + if (IS_ERR(clk) || clk == NULL) + return; + + mutex_lock(&clocks_mutex); + + if ((--clk->usage) == 0) (clk->enable)(clk, 0); + + mutex_unlock(&clocks_mutex); + clk_disable(clk->parent); } @@ -361,6 +372,14 @@ int s3c24xx_register_clock(struct clk *clk) if (clk->enable == NULL) clk->enable = clk_null_enable; + /* if this is a standard clock, set the usage state */ + + if (clk->ctrlbit) { + unsigned long clkcon = __raw_readl(S3C2410_CLKCON); + + clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0; + } + /* add to the list of available clocks */ mutex_lock(&clocks_mutex); @@ -402,6 +421,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, * the LCD clock if it is not needed. */ + mutex_lock(&clocks_mutex); + s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0); s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0); s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0); @@ -409,6 +430,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0); s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0); + mutex_unlock(&clocks_mutex); + /* assume uart clocks are correctly setup */ /* register our clocks */ diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h index 177d5c8decf..eb5c95d1e7f 100644 --- a/arch/arm/mach-s3c2410/clock.h +++ b/arch/arm/mach-s3c2410/clock.h @@ -16,6 +16,7 @@ struct clk { struct clk *parent; const char *name; int id; + int usage; unsigned long rate; unsigned long ctrlbit; int (*enable)(struct clk *, int enable); diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index b8d994a24d1..0a47d38789a 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -275,6 +275,11 @@ static struct resource s3c_adc_resource[] = { }, [1] = { .start = IRQ_TC, + .end = IRQ_TC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_ADC, .end = IRQ_ADC, .flags = IORESOURCE_IRQ, } diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 792f6637583..ee82763b02b 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <asm/mach/map.h> +#include <asm/tlb.h> #include <asm/io.h> #include <asm/cacheflush.h> @@ -96,6 +97,14 @@ void __init omap_map_sram(void) omap_sram_io_desc[0].length); /* + * Normally devicemaps_init() would flush caches and tlb after + * mdesc->map_io(), but since we're called from map_io(), we + * must do it here. + */ + local_flush_tlb_all(); + flush_cache_all(); + + /* * Looks like we need to preserve some bootloader code at the * beginning of SRAM for jumping to flash for reboot to work... */ diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index f214f74f264..961c0d58ded 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c @@ -202,18 +202,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int i; unsigned long tmp; + ret = 0; for (i = 0; i <= PT_MAX; i++) { tmp = get_reg(child, i); if (put_user(tmp, datap)) { ret = -EFAULT; - goto out_tsk; + break; } data += sizeof(long); } - ret = 0; break; } @@ -222,10 +222,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int i; unsigned long tmp; + ret = 0; for (i = 0; i <= PT_MAX; i++) { if (get_user(tmp, datap)) { ret = -EFAULT; - goto out_tsk; + break; } if (i == PT_DCCR) { @@ -237,7 +238,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) data += sizeof(long); } - ret = 0; break; } diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index d11206e467a..1ba57efff60 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -24,7 +24,6 @@ /* * Setup options */ -struct drive_info_struct { char dummy[32]; } drive_info; struct screen_info screen_info; extern int root_mountflags; diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 1b665928336..5a8b3fb6d27 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S @@ -309,3 +309,4 @@ ENTRY(sys_call_table) .long sys_faccessat .long sys_pselect6 .long sys_ppoll + .long sys_unshare /* 310 */ diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c index d58003f1ad0..c9104bfff66 100644 --- a/arch/ia64/dig/setup.c +++ b/arch/ia64/dig/setup.c @@ -25,16 +25,6 @@ #include <asm/machvec.h> #include <asm/system.h> -/* - * This is here so we can use the CMOS detection in ide-probe.c to - * determine what drives are present. In theory, we don't need this - * as the auto-detection could be done via ide-probe.c:do_probe() but - * in practice that would be much slower, which is painful when - * running in the simulator. Note that passing zeroes in DRIVE_INFO - * is sufficient (the IDE driver will autodetect the drive geometry). - */ -char drive_info[4*16]; - void __init dig_setup (char **cmdline_p) { diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index c485a3b32ba..9990320b6f9 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -410,24 +410,16 @@ efi_init (void) efi_config_table_t *config_tables; efi_char16_t *c16; u64 efi_desc_size; - char *cp, *end, vendor[100] = "unknown"; + char *cp, vendor[100] = "unknown"; extern char saved_command_line[]; int i; /* it's too early to be able to use the standard kernel command line support... */ for (cp = saved_command_line; *cp; ) { if (memcmp(cp, "mem=", 4) == 0) { - cp += 4; - mem_limit = memparse(cp, &end); - if (end != cp) - break; - cp = end; + mem_limit = memparse(cp + 4, &cp); } else if (memcmp(cp, "max_addr=", 9) == 0) { - cp += 9; - max_addr = GRANULEROUNDDOWN(memparse(cp, &end)); - if (end != cp) - break; - cp = end; + max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp)); } else { while (*cp != ' ' && *cp) ++cp; @@ -458,7 +450,7 @@ efi_init (void) /* Show what we know for posterity */ c16 = __va(efi.systab->fw_vendor); if (c16) { - for (i = 0;i < (int) sizeof(vendor) && *c16; ++i) + for (i = 0;i < (int) sizeof(vendor) - 1 && *c16; ++i) vendor[i] = *c16++; vendor[i] = '\0'; } diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index fbc7ea35dd5..f1778a84ea6 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -352,6 +352,7 @@ start_ap: mov ar.rsc=0 // place RSE in enforced lazy mode ;; loadrs // clear the dirty partition + mov IA64_KR(PER_CPU_DATA)=r0 // clear physical per-CPU base ;; mov ar.bspstore=r2 // establish the new RSE stack ;; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index c0766575a3a..35f7835294a 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS]; EXPORT_SYMBOL(__per_cpu_offset); #endif +extern void ia64_setup_printk_clock(void); + DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); @@ -445,6 +447,8 @@ setup_arch (char **cmdline_p) /* process SAL system table: */ ia64_sal_init(efi.sal_systab); + ia64_setup_printk_clock(); + #ifdef CONFIG_SMP cpu_physical_id(0) = hard_smp_processor_id(); diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 028a2b95936..a094ec49ccf 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -278,3 +278,30 @@ udelay (unsigned long usecs) } } EXPORT_SYMBOL(udelay); + +static unsigned long long ia64_itc_printk_clock(void) +{ + if (ia64_get_kr(IA64_KR_PER_CPU_DATA)) + return sched_clock(); + return 0; +} + +static unsigned long long ia64_default_printk_clock(void) +{ + return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) * + (1000000000/HZ); +} + +unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock; + +unsigned long long printk_clock(void) +{ + return ia64_printk_clock(); +} + +void __init +ia64_setup_printk_clock(void) +{ + if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) + ia64_printk_clock = ia64_itc_printk_clock; +} diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c index 9ab684d1bb5..3db62f24596 100644 --- a/arch/ia64/sn/kernel/mca.c +++ b/arch/ia64/sn/kernel/mca.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. */ #include <linux/types.h> @@ -137,7 +137,8 @@ int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdat static int __init sn_salinfo_init(void) { - salinfo_platform_oemdata = &sn_salinfo_platform_oemdata; + if (ia64_platform_is("sn2")) + salinfo_platform_oemdata = &sn_salinfo_platform_oemdata; return 0; } diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index ee36bff93c3..48645ac120f 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -67,6 +67,7 @@ extern unsigned long last_time_offset; extern void (*ia64_mark_idle) (int); extern void snidle(int); extern unsigned char acpi_kbd_controller_present; +extern unsigned long long (*ia64_printk_clock)(void); unsigned long sn_rtc_cycles_per_second; EXPORT_SYMBOL(sn_rtc_cycles_per_second); @@ -125,20 +126,6 @@ struct screen_info sn_screen_info = { }; /* - * This is here so we can use the CMOS detection in ide-probe.c to - * determine what drives are present. In theory, we don't need this - * as the auto-detection could be done via ide-probe.c:do_probe() but - * in practice that would be much slower, which is painful when - * running in the simulator. Note that passing zeroes in DRIVE_INFO - * is sufficient (the IDE driver will autodetect the drive geometry). - */ -#ifdef CONFIG_IA64_GENERIC -extern char drive_info[4 * 16]; -#else -char drive_info[4 * 16]; -#endif - -/* * This routine can only be used during init, since * smp_boot_data is an init data structure. * We have to use smp_boot_data.cpu_phys_id to find @@ -372,6 +359,16 @@ sn_scan_pcdp(void) } } +static unsigned long sn2_rtc_initial; + +static unsigned long long ia64_sn2_printk_clock(void) +{ + unsigned long rtc_now = rtc_time(); + + return (rtc_now - sn2_rtc_initial) * + (1000000000 / sn_rtc_cycles_per_second); +} + /** * sn_setup - SN platform setup routine * @cmdline_p: kernel command line @@ -386,6 +383,7 @@ void __init sn_setup(char **cmdline_p) u32 version = sn_sal_rev(); extern void sn_cpu_init(void); + sn2_rtc_initial = rtc_time(); ia64_sn_plat_set_error_handling_features(); // obsolete ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); @@ -437,19 +435,6 @@ void __init sn_setup(char **cmdline_p) */ build_cnode_tables(); - /* - * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard - * support here so we don't have to listen to failed keyboard probe - * messages. - */ - if (version <= 0x0209 && acpi_kbd_controller_present) { - printk(KERN_INFO "Disabling legacy keyboard support as prom " - "is too old and doesn't provide FADT\n"); - acpi_kbd_controller_present = 0; - } - - printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); - status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift); @@ -463,6 +448,21 @@ void __init sn_setup(char **cmdline_p) platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; + ia64_printk_clock = ia64_sn2_printk_clock; + + /* + * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard + * support here so we don't have to listen to failed keyboard probe + * messages. + */ + if (version <= 0x0209 && acpi_kbd_controller_present) { + printk(KERN_INFO "Disabling legacy keyboard support as prom " + "is too old and doesn't provide FADT\n"); + acpi_kbd_controller_present = 0; + } + + printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); + /* * we set the default root device to /dev/hda * to make simulation easy diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 19b54fbcd7e..70db21f3df2 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved. * * SGI Altix topology and hardware performance monitoring API. * Mark Goodwin <markgw@sgi.com>. @@ -973,6 +973,9 @@ static int __devinit sn_hwperf_misc_register_init(void) { int e; + if (!ia64_platform_is("sn2")) + return 0; + sn_hwperf_init(); /* diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index dbc8a392105..be8b711367e 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c @@ -18,11 +18,6 @@ #include <asm/irq.h> #include <asm/tlbflush.h> -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) -extern struct drive_info_struct drive_info; -EXPORT_SYMBOL(drive_info); -#endif - /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); EXPORT_SYMBOL(dump_fpu); diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index c2e4dccf011..d742037a7cc 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -37,12 +37,6 @@ extern void init_mmu(void); #endif -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) \ - || defined(CONFIG_BLK_DEV_IDE_MODULE) \ - || defined(CONFIG_BLK_DEV_HD_MODULE) -struct drive_info_struct { char dummy[32]; } drive_info; -#endif - extern char _end[]; /* diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 99bf4382479..63c117dae0c 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -39,6 +39,14 @@ asmlinkage void ret_from_fork(void); +/* + * The following aren't currently used. + */ +void (*pm_idle)(void); +EXPORT_SYMBOL(pm_idle); + +void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); /* * The idle loop on an m68knommu.. diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index 050685b87a3..b9713a72305 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -140,7 +140,7 @@ void __init plat_setup(void) uart.type = PORT_UNKNOWN; uart.uartclk = 18432000; uart.irq = COBALT_SERIAL_IRQ; - uart.flags = STD_COM_FLAGS; + uart.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; uart.iobase = 0xc800000; uart.iotype = UPIO_PORT; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index fa98f10d013..5232fc75293 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -4,6 +4,7 @@ * for more details. * * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others. + * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2004 Thiemo Seufer */ @@ -58,8 +59,8 @@ ATTRIB_NORET void cpu_idle(void) } } -extern int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); +extern void do_signal(struct pt_regs *regs); +extern void do_signal32(struct pt_regs *regs); /* * Native o32 and N64 ABI without DSP ASE diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index a42e0e8caa7..d7c4a38ed5a 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -617,6 +617,23 @@ einval: li v0, -EINVAL sys sys_inotify_init 0 sys sys_inotify_add_watch 3 /* 4285 */ sys sys_inotify_rm_watch 2 + sys sys_migrate_pages 4 + sys sys_openat 4 + sys sys_mkdirat 3 + sys sys_mknodat 4 /* 4290 */ + sys sys_fchownat 5 + sys sys_futimesat 3 + sys sys_newfstatat 4 + sys sys_unlinkat 3 + sys sys_renameat 4 /* 4295 */ + sys sys_linkat 4 + sys sys_symlinkat 3 + sys sys_readlinkat 4 + sys sys_fchmodat 3 + sys sys_faccessat 3 /* 4300 */ + sys sys_pselect6 6 + sys sys_ppoll 5 + sys sys_unshare 1 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 47bfbd41670..98bf25df56f 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -443,3 +443,20 @@ sys_call_table: PTR sys_inotify_init PTR sys_inotify_add_watch PTR sys_inotify_rm_watch /* 5245 */ + PTR sys_migrate_pages + PTR sys_openat + PTR sys_mkdirat + PTR sys_mknodat + PTR sys_fchownat /* 5250 */ + PTR sys_futimesat + PTR sys_newfstatat + PTR sys_unlinkat + PTR sys_renameat + PTR sys_linkat /* 5255 */ + PTR sys_symlinkat + PTR sys_readlinkat + PTR sys_fchmodat + PTR sys_faccessat + PTR sys_pselect6 /* 5260 */ + PTR sys_ppoll + PTR sys_unshare diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index b465ced1758..bc4980cefc8 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -369,3 +369,20 @@ EXPORT(sysn32_call_table) PTR sys_inotify_init PTR sys_inotify_add_watch PTR sys_inotify_rm_watch + PTR sys_migrate_pages /* 6250 */ + PTR sys_openat + PTR sys_mkdirat + PTR sys_mknodat + PTR sys_fchownat + PTR sys_futimesat /* 6255 */ + PTR sys_newfstatat + PTR sys_unlinkat + PTR sys_renameat + PTR sys_linkat + PTR sys_symlinkat /* 6260 */ + PTR sys_readlinkat + PTR sys_fchmodat + PTR sys_faccessat + PTR sys_pselect6 + PTR sys_ppoll /* 6265 */ + PTR sys_unshare diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 3d338ca7eee..5b0414018c9 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -491,4 +491,21 @@ sys_call_table: PTR sys_inotify_init PTR sys_inotify_add_watch /* 4285 */ PTR sys_inotify_rm_watch + PTR sys_migrate_pages + PTR compat_sys_openat + PTR sys_mkdirat + PTR sys_mknodat /* 4290 */ + PTR sys_fchownat + PTR compat_sys_futimesat + PTR compat_sys_newfstatat + PTR sys_unlinkat + PTR sys_renameat /* 4295 */ + PTR sys_linkat + PTR sys_symlinkat + PTR sys_readlinkat + PTR sys_fchmodat + PTR sys_faccessat /* 4300 */ + PTR sys_pselect6 + PTR sys_ppoll + PTR sys_unshare .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index aaec4785e9a..c974cc9b30e 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -39,8 +39,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -int do_signal(sigset_t *oldset, struct pt_regs *regs); - /* * Atomically swap in the new signal mask, and wait for a signal. */ @@ -50,7 +48,7 @@ save_static_function(sys_sigsuspend); __attribute_used__ noinline static int _sys_sigsuspend(nabi_no_regargs struct pt_regs regs) { - sigset_t saveset, newset; + sigset_t newset; sigset_t __user *uset; uset = (sigset_t __user *) regs.regs[4]; @@ -59,19 +57,15 @@ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs) sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; + current->saved_sigmask = current->blocked; current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - regs.regs[2] = EINTR; - regs.regs[7] = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, ®s)) - return -EINTR; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } #endif @@ -79,7 +73,7 @@ save_static_function(sys_rt_sigsuspend); __attribute_used__ noinline static int _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) { - sigset_t saveset, newset; + sigset_t newset; sigset_t __user *unewset; size_t sigsetsize; @@ -94,19 +88,15 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; + current->saved_sigmask = current->blocked; current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - regs.regs[2] = EINTR; - regs.regs[7] = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, ®s)) - return -EINTR; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } #ifdef CONFIG_TRAD_SIGNALS @@ -315,11 +305,11 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, current->comm, current->pid, frame, regs->cp0_epc, frame->regs[31]); #endif - return 1; + return 0; give_sigsegv: force_sigsegv(signr, current); - return 0; + return -EFAULT; } #endif @@ -375,11 +365,11 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, current->comm, current->pid, frame, regs->cp0_epc, regs->regs[31]); #endif - return 1; + return 0; give_sigsegv: force_sigsegv(signr, current); - return 0; + return -EFAULT; } static inline int handle_signal(unsigned long sig, siginfo_t *info, @@ -393,7 +383,7 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, regs->regs[2] = EINTR; break; case ERESTARTSYS: - if(!(ka->sa.sa_flags & SA_RESTART)) { + if (!(ka->sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; } @@ -420,9 +410,10 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, return ret; } -int do_signal(sigset_t *oldset, struct pt_regs *regs) +void do_signal(struct pt_regs *regs) { struct k_sigaction ka; + sigset_t *oldset; siginfo_t info; int signr; @@ -432,17 +423,31 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return 1; + return; if (try_to_freeze()) goto no_signal; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else oldset = ¤t->blocked; + signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) - return handle_signal(signr, &info, &ka, oldset, regs); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { + /* + * A signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TIF_RESTORE_SIGMASK flag. + */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + } + } no_signal: /* @@ -463,18 +468,25 @@ no_signal: regs->cp0_epc -= 4; } } - return 0; + + /* + * If there's no signal to deliver, we just put the saved sigmask + * back + */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } } /* * notification of userspace execution resumption - * - triggered by current->work.notify_resume + * - triggered by the TIF_WORK_MASK flags */ -asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, +asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) { /* deal with pending signal delivery */ - if (thread_info_flags & _TIF_SIGPENDING) { - current->thread.abi->do_signal(oldset, regs); - } + if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + current->thread.abi->do_signal(regs); } diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 136260c8f75..da3271e1fda 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -694,11 +694,11 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, current->comm, current->pid, frame, regs->cp0_epc, frame->sf_code); #endif - return 1; + return 0; give_sigsegv: force_sigsegv(signr, current); - return 0; + return -EFAULT; } int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, @@ -765,11 +765,11 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, current->comm, current->pid, frame, regs->cp0_epc, frame->rs_code); #endif - return 1; + return 0; give_sigsegv: force_sigsegv(signr, current); - return 0; + return -EFAULT; } static inline int handle_signal(unsigned long sig, siginfo_t *info, diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 9156863c1a5..384fc4a639a 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -186,9 +186,9 @@ int setup_rt_frame_n32(struct k_sigaction * ka, current->comm, current->pid, frame, regs->cp0_epc, regs->regs[31]); #endif - return 1; + return 0; give_sigsegv: force_sigsegv(signr, current); - return 0; + return -EFAULT; } diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 332358430ff..1da2eeb3ef9 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -212,12 +212,12 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) int error; char * filename; - filename = getname((char *) (long)regs.regs[4]); + filename = getname((char __user *) (long)regs.regs[4]); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, (char **) (long)regs.regs[5], - (char **) (long)regs.regs[6], ®s); + error = do_execve(filename, (char __user *__user *) (long)regs.regs[5], + (char __user *__user *) (long)regs.regs[6], ®s); putname(filename); out: @@ -227,7 +227,7 @@ out: /* * Compacrapability ... */ -asmlinkage int sys_uname(struct old_utsname * name) +asmlinkage int sys_uname(struct old_utsname __user * name) { if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) return 0; @@ -237,7 +237,7 @@ asmlinkage int sys_uname(struct old_utsname * name) /* * Compacrapability ... */ -asmlinkage int sys_olduname(struct oldold_utsname * name) +asmlinkage int sys_olduname(struct oldold_utsname __user * name) { int error; @@ -274,7 +274,7 @@ void sys_set_thread_area(unsigned long addr) asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) { int tmp, len; - char *name; + char __user *name; switch(cmd) { case SETNAME: { @@ -283,7 +283,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - name = (char *) arg1; + name = (char __user *) arg1; len = strncpy_from_user(nodename, name, __NEW_UTS_LEN); if (len < 0) @@ -324,7 +324,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) * This is really horribly ugly. */ asmlinkage int sys_ipc (uint call, int first, int second, - unsigned long third, void *ptr, long fifth) + unsigned long third, void __user *ptr, long fifth) { int version, ret; @@ -333,24 +333,25 @@ asmlinkage int sys_ipc (uint call, int first, int second, switch (call) { case SEMOP: - return sys_semtimedop (first, (struct sembuf *)ptr, second, - NULL); + return sys_semtimedop (first, (struct sembuf __user *)ptr, + second, NULL); case SEMTIMEDOP: - return sys_semtimedop (first, (struct sembuf *)ptr, second, - (const struct timespec __user *)fifth); + return sys_semtimedop (first, (struct sembuf __user *)ptr, + second, + (const struct timespec __user *)fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { union semun fourth; if (!ptr) return -EINVAL; - if (get_user(fourth.__pad, (void **) ptr)) + if (get_user(fourth.__pad, (void *__user *) ptr)) return -EFAULT; return sys_semctl (first, second, third, fourth); } case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, + return sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third); case MSGRCV: switch (version) { @@ -360,7 +361,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, return -EINVAL; if (copy_from_user(&tmp, - (struct ipc_kludge *) ptr, + (struct ipc_kludge __user *) ptr, sizeof (tmp))) return -EFAULT; return sys_msgrcv (first, tmp.msgp, second, @@ -368,35 +369,38 @@ asmlinkage int sys_ipc (uint call, int first, int second, } default: return sys_msgrcv (first, - (struct msgbuf *) ptr, + (struct msgbuf __user *) ptr, second, fifth, third); } case MSGGET: return sys_msgget ((key_t) first, second); case MSGCTL: - return sys_msgctl (first, second, (struct msqid_ds *) ptr); + return sys_msgctl (first, second, + (struct msqid_ds __user *) ptr); case SHMAT: switch (version) { default: { ulong raddr; - ret = do_shmat (first, (char *) ptr, second, &raddr); + ret = do_shmat (first, (char __user *) ptr, second, + &raddr); if (ret) return ret; - return put_user (raddr, (ulong *) third); + return put_user (raddr, (ulong __user *) third); } case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; - return do_shmat (first, (char *) ptr, second, (ulong *) third); + return do_shmat (first, (char __user *) ptr, second, + (ulong *) third); } case SHMDT: - return sys_shmdt ((char *)ptr); + return sys_shmdt ((char __user *)ptr); case SHMGET: return sys_shmget (first, second, third); case SHMCTL: return sys_shmctl (first, second, - (struct shmid_ds *) ptr); + (struct shmid_ds __user *) ptr); default: return -ENOSYS; } diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c index dcd819d57da..83eb08b7a07 100644 --- a/arch/mips/lasat/setup.c +++ b/arch/mips/lasat/setup.c @@ -134,8 +134,8 @@ void __init serial_init(void) memset(&s, 0, sizeof(s)); - s.flags = STD_COM_FLAGS; - s.iotype = SERIAL_IO_MEM; + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = UPIO_MEM; if (mips_machtype == MACH_LASAT_100) { s.uartclk = LASAT_BASE_BAUD_100 * 16; diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c index 625843b30be..873cf3141a3 100644 --- a/arch/mips/mips-boards/atlas/atlas_setup.c +++ b/arch/mips/mips-boards/atlas/atlas_setup.c @@ -82,8 +82,8 @@ static void __init serial_init(void) #endif s.irq = ATLASINT_UART; s.uartclk = ATLAS_BASE_BAUD * 16; - s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - s.iotype = SERIAL_IO_PORT; + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; + s.iotype = UPIO_PORT; s.regshift = 3; if (early_serial_setup(&s) != 0) { diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c index f966bc161df..4266ce44517 100644 --- a/arch/mips/mips-boards/sead/sead_setup.c +++ b/arch/mips/mips-boards/sead/sead_setup.c @@ -71,8 +71,8 @@ static void __init serial_init(void) #endif s.irq = MIPSCPU_INT_BASE + MIPSCPU_INT_UART0; s.uartclk = SEAD_BASE_BAUD * 16; - s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - s.iotype = 0; + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; + s.iotype = UPIO_PORT; s.regshift = 3; if (early_serial_setup(&s) != 0) { diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c index 485d5a58d9c..a2fd62997ca 100644 --- a/arch/mips/mips-boards/sim/sim_setup.c +++ b/arch/mips/mips-boards/sim/sim_setup.c @@ -88,8 +88,8 @@ static void __init serial_init(void) but poll for now */ s.irq = 0; s.uartclk = BASE_BAUD * 16; - s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST; - s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST; + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = UPIO_PORT; s.regshift = 0; s.timeout = 4; diff --git a/arch/mips/momentum/jaguar_atx/ja-console.c b/arch/mips/momentum/jaguar_atx/ja-console.c index da6e1ed34db..2292d0ec47f 100644 --- a/arch/mips/momentum/jaguar_atx/ja-console.c +++ b/arch/mips/momentum/jaguar_atx/ja-console.c @@ -93,7 +93,7 @@ static void inline ja_console_probe(void) up.uartclk = JAGUAR_ATX_UART_CLK; up.regshift = 2; up.iotype = UPIO_MEM; - up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; up.line = 0; if (early_serial_setup(&up)) diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c index 8aa9bd65b45..a592260fd67 100644 --- a/arch/mips/philips/pnx8550/common/platform.c +++ b/arch/mips/philips/pnx8550/common/platform.c @@ -66,28 +66,28 @@ struct ip3106_port ip3106_ports[] = { [0] = { .port = { .type = PORT_IP3106, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .membase = (void __iomem *)PNX8550_UART_PORT0, .mapbase = PNX8550_UART_PORT0, .irq = PNX8550_UART_INT(0), .uartclk = 3692300, .fifosize = 16, .ops = &ip3106_pops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, }, [1] = { .port = { .type = PORT_IP3106, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .membase = (void __iomem *)PNX8550_UART_PORT1, .mapbase = PNX8550_UART_PORT1, .irq = PNX8550_UART_INT(1), .uartclk = 3692300, .fifosize = 16, .ops = &ip3106_pops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, }, diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index 059755b5ed5..8bce711575d 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c @@ -185,7 +185,7 @@ static void __init py_uart_setup(void) up.uartclk = TITAN_UART_CLK; up.regshift = 0; up.iotype = UPIO_MEM; - up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; up.line = 0; if (early_serial_setup(&up)) diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index d10a269aeae..2c38770b1e1 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c @@ -66,11 +66,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) #include <linux/tty.h> #include <linux/serial.h> #include <linux/serial_core.h> -extern int early_serial_setup(struct uart_port *port); - -#define STD_COM_FLAGS (ASYNC_SKIP_TEST) -#define BASE_BAUD (1843200 / 16) - #endif /* CONFIG_SERIAL_8250 */ /* An arbitrary time; this can be decreased if reliability looks good */ @@ -110,8 +105,8 @@ void __init plat_setup(void) o2_serial[0].type = PORT_16550A; o2_serial[0].line = 0; o2_serial[0].irq = MACEISA_SERIAL1_IRQ; - o2_serial[0].flags = STD_COM_FLAGS; - o2_serial[0].uartclk = BASE_BAUD * 16; + o2_serial[0].flags = UPF_SKIP_TEST; + o2_serial[0].uartclk = 1843200; o2_serial[0].iotype = UPIO_MEM; o2_serial[0].membase = (char *)&mace->isa.serial1; o2_serial[0].fifosize = 14; @@ -121,8 +116,8 @@ void __init plat_setup(void) o2_serial[1].type = PORT_16550A; o2_serial[1].line = 1; o2_serial[1].irq = MACEISA_SERIAL2_IRQ; - o2_serial[1].flags = STD_COM_FLAGS; - o2_serial[1].uartclk = BASE_BAUD * 16; + o2_serial[1].flags = UPF_SKIP_TEST; + o2_serial[1].uartclk = 1843200; o2_serial[1].iotype = UPIO_MEM; o2_serial[1].membase = (char *)&mace->isa.serial2; o2_serial[1].fifosize = 14; diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c index 29b4d61898f..05273ccced0 100644 --- a/arch/parisc/hpux/sys_hpux.c +++ b/arch/parisc/hpux/sys_hpux.c @@ -468,19 +468,23 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2) if ( opcode == 1 ) { /* GETFSIND */ len = strlen_user((char *)arg1); printk(KERN_DEBUG "len of arg1 = %d\n", len); - - fsname = (char *) kmalloc(len+1, GFP_KERNEL); + if (len == 0) + return 0; + fsname = (char *) kmalloc(len, GFP_KERNEL); if ( !fsname ) { printk(KERN_DEBUG "failed to kmalloc fsname\n"); return 0; } - if ( copy_from_user(fsname, (char *)arg1, len+1) ) { + if ( copy_from_user(fsname, (char *)arg1, len) ) { printk(KERN_DEBUG "failed to copy_from_user fsname\n"); kfree(fsname); return 0; } + /* String could be altered by userspace after strlen_user() */ + fsname[len] = '\0'; + printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname); if ( !strcmp(fsname, "hfs") ) { fstype = 0; diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index e4362dfa37f..340730fb8c9 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -66,7 +66,7 @@ _GLOBAL(load_up_fpu) #else ld r4,PACACURRENT(r13) addi r5,r4,THREAD /* Get THREAD */ - ld r4,THREAD_FPEXC_MODE(r5) + lwz r4,THREAD_FPEXC_MODE(r5) ori r12,r12,MSR_FP or r12,r12,r4 std r12,_MSR(r1) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 30826846634..41565962939 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -749,11 +749,12 @@ iSeries_secondary_smp_loop: .globl decrementer_iSeries_masked decrementer_iSeries_masked: + /* We may not have a valid TOC pointer in here. */ li r11,1 ld r12,PACALPPACAPTR(r13) stb r11,LPPACADECRINT(r12) - LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy) - lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12) + LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy) + lwz r12,0(r12) mtspr SPRN_DEC,r12 /* fall through */ diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 4d9b4388918..946f3219fd2 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -334,9 +334,6 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, spin_unlock_irqrestore(&(tbl->it_lock), flags); - /* Make sure updates are seen by hardware */ - mb(); - DBG("mapped %d elements:\n", outcount); /* For the sake of iommu_unmap_sg, we clear out the length in the @@ -347,6 +344,10 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, outs->dma_address = DMA_ERROR_CODE; outs->dma_length = 0; } + + /* Make sure updates are seen by hardware */ + mb(); + return outcount; failure: @@ -358,6 +359,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) >> PAGE_SHIFT; __iommu_free(tbl, vaddr, npages); + s->dma_address = DMA_ERROR_CODE; + s->dma_length = 0; } } spin_unlock_irqrestore(&(tbl->it_lock), flags); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d50c8df0183..294832a7e0a 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -491,7 +491,12 @@ void __init finish_device_tree(void) size = 16; finish_node(allnodes, &size, 1); size -= 16; - end = start = (unsigned long) __va(lmb_alloc(size, 128)); + + if (0 == size) + end = start = 0; + else + end = start = (unsigned long)__va(lmb_alloc(size, 128)); + finish_node(allnodes, &end, 0); BUG_ON(end != start + size); @@ -1398,8 +1403,8 @@ struct device_node *of_find_node_by_name(struct device_node *from, read_lock(&devtree_lock); np = from ? from->allnext : allnodes; - for (; np != 0; np = np->allnext) - if (np->name != 0 && strcasecmp(np->name, name) == 0 + for (; np != NULL; np = np->allnext) + if (np->name != NULL && strcasecmp(np->name, name) == 0 && of_node_get(np)) break; if (from) @@ -1917,3 +1922,30 @@ int prom_update_property(struct device_node *np, return 0; } + +#ifdef CONFIG_KEXEC +/* We may have allocated the flat device tree inside the crash kernel region + * in prom_init. If so we need to move it out into regular memory. */ +void kdump_move_device_tree(void) +{ + unsigned long start, end; + struct boot_param_header *new; + + start = __pa((unsigned long)initial_boot_params); + end = start + initial_boot_params->totalsize; + + if (end < crashk_res.start || start > crashk_res.end) + return; + + new = (struct boot_param_header*) + __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE)); + + memcpy(new, initial_boot_params, initial_boot_params->totalsize); + + initial_boot_params = new; + + DBG("Flat device tree blob moved to %p\n", initial_boot_params); + + /* XXX should we unreserve the old DT? */ +} +#endif /* CONFIG_KEXEC */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 7881ec96ef1..ec7153f4d47 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2098,6 +2098,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_stdout(); + /* Bail if this is a kdump kernel. */ + if (PHYSICAL_START > 0) + prom_panic("Error: You can't boot a kdump kernel from OF!\n"); + /* * Check for an initrd */ diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index a8099c80615..3934c227549 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -465,8 +465,10 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, if (parent == NULL) return NULL; bus = of_match_bus(parent); - if (strcmp(bus->name, "pci")) + if (strcmp(bus->name, "pci")) { + of_node_put(parent); return NULL; + } bus->count_cells(dev, &na, &ns); of_node_put(parent); if (!OF_CHECK_COUNTS(na, ns)) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 7fe4a5c944c..b5b2add7ad1 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -22,6 +22,7 @@ #include <asm/prom.h> #include <asm/rtas.h> +#include <asm/hvcall.h> #include <asm/semaphore.h> #include <asm/machdep.h> #include <asm/page.h> @@ -565,6 +566,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; #ifdef CONFIG_PPC_PSERIES static void rtas_percpu_suspend_me(void *info) { + int i; long rc; long flags; struct rtas_suspend_me_data *data = @@ -587,18 +589,16 @@ static void rtas_percpu_suspend_me(void *info) if (rc == H_Continue) { data->waiting = 0; - rtas_call(ibm_suspend_me_token, 0, 1, - data->args->args); + data->args->args[data->args->nargs] = + rtas_call(ibm_suspend_me_token, 0, 1, NULL); + for_each_cpu(i) + plpar_hcall_norets(H_PROD,i); } else { data->waiting = -EBUSY; printk(KERN_ERR "Error on H_Join hypervisor call\n"); } out: - /* before we restore interrupts, make sure we don't - * generate a spurious soft lockup errors - */ - touch_softlockup_watchdog(); local_irq_restore(flags); return; } diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 50500093c97..aaf384c3f04 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -672,8 +672,7 @@ static void rtas_flash_firmware(int reboot_type) static void remove_flash_pde(struct proc_dir_entry *dp) { if (dp) { - if (dp->data != NULL) - kfree(dp->data); + kfree(dp->data); dp->owner = NULL; remove_proc_entry(dp->name, dp->parent); } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index e29b275e09e..a717dff695e 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -398,6 +398,9 @@ void __init setup_system(void) { DBG(" -> setup_system()\n"); +#ifdef CONFIG_KEXEC + kdump_move_device_tree(); +#endif /* * Unflatten the device-tree passed by prom_init or kexec */ diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index c6d0595da6b..bd837b5dbf0 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -142,11 +142,7 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka, return 0; } -static inline compat_uptr_t to_user_ptr(void *kp) -{ - return (compat_uptr_t)(u64)kp; -} - +#define to_user_ptr(p) ptr_to_compat(p) #define from_user_ptr(p) compat_ptr(p) static inline int save_general_regs(struct pt_regs *regs, @@ -213,8 +209,8 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka, return 0; } -#define to_user_ptr(p) (p) -#define from_user_ptr(p) (p) +#define to_user_ptr(p) ((unsigned long)(p)) +#define from_user_ptr(p) ((void __user *)(p)) static inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) @@ -526,7 +522,7 @@ long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act, ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); + ret = put_user(to_user_ptr(old_ka.sa.sa_handler), &oact->sa_handler); ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); } @@ -675,8 +671,8 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, int r6, int r7, int r8, struct pt_regs *regs) { - stack_32_t __user * newstack = (stack_32_t __user *)(long) __new; - stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old; + stack_32_t __user * newstack = compat_ptr(__new); + stack_32_t __user * oldstack = compat_ptr(__old); stack_t uss, uoss; int ret; mm_segment_t old_fs; @@ -708,7 +704,7 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, set_fs(old_fs); /* Copy the stack information to the user output buffer */ if (!ret && oldstack && - (put_user((long)uoss.ss_sp, &oldstack->ss_sp) || + (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) || __put_user(uoss.ss_flags, &oldstack->ss_flags) || __put_user(uoss.ss_size, &oldstack->ss_size))) return -EFAULT; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index b3193116e68..497a5d3df35 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -60,8 +60,8 @@ struct rt_sigframe { struct ucontext uc; unsigned long _unused[2]; unsigned int tramp[TRAMP_SIZE]; - struct siginfo *pinfo; - void *puc; + struct siginfo __user *pinfo; + void __user *puc; struct siginfo info; /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ char abigap[288]; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index c8458c531b2..13595a64f01 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -540,6 +540,9 @@ int __devinit start_secondary(void *unused) if (smp_ops->take_timebase) smp_ops->take_timebase(); + if (system_state > SYSTEM_BOOTING) + per_cpu(last_jiffy, cpu) = get_tb(); + spin_lock(&call_lock); cpu_set(cpu, cpu_online_map); spin_unlock(&call_lock); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index c4a294d657b..1886045a2fd 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -612,10 +612,10 @@ void __init generic_calibrate_decr(void) ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */ node_found = 0; - if (cpu != 0) { + if (cpu) { fp = (unsigned int *)get_property(cpu, "timebase-frequency", NULL); - if (fp != 0) { + if (fp) { node_found = 1; ppc_tb_freq = *fp; } @@ -626,10 +626,10 @@ void __init generic_calibrate_decr(void) ppc_proc_freq = DEFAULT_PROC_FREQ; node_found = 0; - if (cpu != 0) { + if (cpu) { fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL); - if (fp != 0) { + if (fp) { node_found = 1; ppc_proc_freq = *fp; } diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 2da65a9c93f..5d29dcca523 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -144,7 +144,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) } #ifdef CONFIG_PPC_MAPLE -void udbg_maple_real_putc(unsigned char c) +void udbg_maple_real_putc(char c) { if (udbg_comport) { while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c index 9584608fd76..bbe3eac918e 100644 --- a/arch/powerpc/mm/lmb.c +++ b/arch/powerpc/mm/lmb.c @@ -197,6 +197,8 @@ long __init lmb_reserve(unsigned long base, unsigned long size) { struct lmb_region *_rgn = &(lmb.reserved); + BUG_ON(0 == size); + return lmb_add_region(_rgn, base, size); } @@ -227,6 +229,8 @@ unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align, long i, j; unsigned long base = 0; + BUG_ON(0 == size); + #ifdef CONFIG_PPC32 /* On 32-bit, make sure we allocate lowmem */ if (max_addr == LMB_ALLOC_ANYWHERE) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 15aac0d78df..550517c2dd4 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -435,17 +435,12 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg) { clear_page(page); - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; /* * We shouldnt have to do this, but some versions of glibc * require it (ld.so assumes zero filled pages are icache clean) * - Anton */ - - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &pg->flags)) - clear_bit(PG_arch_1, &pg->flags); + flush_dcache_page(pg); } EXPORT_SYMBOL(clear_user_page); @@ -469,12 +464,7 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, return; #endif - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &pg->flags)) - clear_bit(PG_arch_1, &pg->flags); + flush_dcache_page(pg); } void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 16031b565be..3b998a393e3 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -2,7 +2,7 @@ obj-y += interrupt.o iommu.o setup.o spider-pic.o obj-y += pervasive.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SPU_FS) += spufs/ spu-base.o +obj-$(CONFIG_SPU_FS) += spu-base.o spufs/ spu-base-y += spu_base.o spu_priv1.o diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 3a2057fa314..814f54742e0 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h @@ -5,7 +5,6 @@ extern void chrp_nvram_init(void); extern void chrp_get_rtc_time(struct rtc_time *); extern int chrp_set_rtc_time(struct rtc_time *); -extern void chrp_calibrate_decr(void); extern long chrp_time_init(void); extern void chrp_find_bridges(void); diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 00c52f27ef4..8ef279ad36a 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -204,9 +204,11 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d struct device_node *root = find_path_device("/"); struct device_node *rtas; + of_node_get(root); rtas = of_find_node_by_name (root, "rtas"); if (rtas) { hose->ops = &rtas_pci_ops; + of_node_put(rtas); } else { printk ("RTAS supporting Pegasos OF not found, please upgrade" " your firmware\n"); diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 2dc87aa5962..e1fadbf4915 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -506,7 +506,7 @@ void __init chrp_init(void) ppc_md.halt = rtas_halt; ppc_md.time_init = chrp_time_init; - ppc_md.calibrate_decr = chrp_calibrate_decr; + ppc_md.calibrate_decr = generic_calibrate_decr; /* this may get overridden with rtas routines later... */ ppc_md.set_rtc_time = chrp_set_rtc_time; diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index 36a0f97bb7b..78df2e7ca88 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c @@ -167,24 +167,3 @@ void chrp_get_rtc_time(struct rtc_time *tm) tm->tm_mon = mon; tm->tm_year = year; } - - -void __init chrp_calibrate_decr(void) -{ - struct device_node *cpu; - unsigned int freq, *fp; - - /* - * The cpu node should have a timebase-frequency property - * to tell us the rate at which the decrementer counts. - */ - freq = 16666000; /* hardcoded default */ - cpu = find_type_devices("cpu"); - if (cpu != 0) { - fp = (unsigned int *) - get_property(cpu, "timebase-frequency", NULL); - if (fp != 0) - freq = *fp; - } - ppc_tb_freq = freq; -} diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 535c802b369..87eb6bb7f0e 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -1052,8 +1052,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter) } EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus); -extern int pmac_i2c_match_adapter(struct device_node *dev, - struct i2c_adapter *adapter) +int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter) { struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev); diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index f671ed25390..de3f30e6b33 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -136,14 +136,14 @@ static void __init fixup_bus_range(struct device_node *bridge) |(((unsigned int)(off)) & 0xFCUL) \ |1UL) -static unsigned long macrisc_cfg_access(struct pci_controller* hose, +static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { unsigned int caddr; if (bus == hose->first_busno) { if (dev_fn < (11 << 3)) - return 0; + return NULL; caddr = MACRISC_CFA0(dev_fn, offset); } else caddr = MACRISC_CFA1(bus, dev_fn, offset); @@ -154,14 +154,14 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose, } while (in_le32(hose->cfg_addr) != caddr); offset &= has_uninorth ? 0x07 : 0x03; - return ((unsigned long)hose->cfg_data) + offset; + return hose->cfg_data + offset; } static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; - unsigned long addr; + volatile void __iomem *addr; hose = pci_bus_to_host(bus); if (hose == NULL) @@ -177,13 +177,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - *val = in_8((u8 *)addr); + *val = in_8(addr); break; case 2: - *val = in_le16((u16 *)addr); + *val = in_le16(addr); break; default: - *val = in_le32((u32 *)addr); + *val = in_le32(addr); break; } return PCIBIOS_SUCCESSFUL; @@ -193,7 +193,7 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose; - unsigned long addr; + volatile void __iomem *addr; hose = pci_bus_to_host(bus); if (hose == NULL) @@ -209,16 +209,16 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - out_8((u8 *)addr, val); - (void) in_8((u8 *)addr); + out_8(addr, val); + (void) in_8(addr); break; case 2: - out_le16((u16 *)addr, val); - (void) in_le16((u16 *)addr); + out_le16(addr, val); + (void) in_le16(addr); break; default: - out_le32((u32 *)addr, val); - (void) in_le32((u32 *)addr); + out_le32(addr, val); + (void) in_le32(addr); break; } return PCIBIOS_SUCCESSFUL; @@ -348,25 +348,23 @@ static int u3_ht_skip_device(struct pci_controller *hose, + (((unsigned int)bus) << 16) \ + 0x01000000UL) -static unsigned long u3_ht_cfg_access(struct pci_controller* hose, +static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset) { if (bus == hose->first_busno) { /* For now, we don't self probe U3 HT bridge */ if (PCI_SLOT(devfn) == 0) - return 0; - return ((unsigned long)hose->cfg_data) + - U3_HT_CFA0(devfn, offset); + return NULL; + return hose->cfg_data + U3_HT_CFA0(devfn, offset); } else - return ((unsigned long)hose->cfg_data) + - U3_HT_CFA1(bus, devfn, offset); + return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); } static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; - unsigned long addr; + volatile void __iomem *addr; hose = pci_bus_to_host(bus); if (hose == NULL) @@ -400,13 +398,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - *val = in_8((u8 *)addr); + *val = in_8(addr); break; case 2: - *val = in_le16((u16 *)addr); + *val = in_le16(addr); break; default: - *val = in_le32((u32 *)addr); + *val = in_le32(addr); break; } return PCIBIOS_SUCCESSFUL; @@ -416,7 +414,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose; - unsigned long addr; + volatile void __iomem *addr; hose = pci_bus_to_host(bus); if (hose == NULL) @@ -442,16 +440,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - out_8((u8 *)addr, val); - (void) in_8((u8 *)addr); + out_8(addr, val); + (void) in_8(addr); break; case 2: - out_le16((u16 *)addr, val); - (void) in_le16((u16 *)addr); + out_le16(addr, val); + (void) in_le16(addr); break; default: - out_le32((u32 *)addr, val); - (void) in_le32((u32 *)addr); + out_le32((u32 __iomem *)addr, val); + (void) in_le32(addr); break; } return PCIBIOS_SUCCESSFUL; @@ -476,7 +474,7 @@ static struct pci_ops u3_ht_pci_ops = |(((unsigned int)(off)) & 0xfcU) \ |1UL) -static unsigned long u4_pcie_cfg_access(struct pci_controller* hose, +static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, int offset) { unsigned int caddr; @@ -492,14 +490,14 @@ static unsigned long u4_pcie_cfg_access(struct pci_controller* hose, } while (in_le32(hose->cfg_addr) != caddr); offset &= 0x03; - return ((unsigned long)hose->cfg_data) + offset; + return hose->cfg_data + offset; } static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; - unsigned long addr; + volatile void __iomem *addr; hose = pci_bus_to_host(bus); if (hose == NULL) @@ -515,13 +513,13 @@ static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - *val = in_8((u8 *)addr); + *val = in_8(addr); break; case 2: - *val = in_le16((u16 *)addr); + *val = in_le16(addr); break; default: - *val = in_le32((u32 *)addr); + *val = in_le32(addr); break; } return PCIBIOS_SUCCESSFUL; @@ -531,7 +529,7 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose; - unsigned long addr; + volatile void __iomem *addr; hose = pci_bus_to_host(bus); if (hose == NULL) @@ -547,16 +545,16 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - out_8((u8 *)addr, val); - (void) in_8((u8 *)addr); + out_8(addr, val); + (void) in_8(addr); break; case 2: - out_le16((u16 *)addr, val); - (void) in_le16((u16 *)addr); + out_le16(addr, val); + (void) in_le16(addr); break; default: - out_le32((u32 *)addr, val); - (void) in_le32((u32 *)addr); + out_le32(addr, val); + (void) in_le32(addr); break; } return PCIBIOS_SUCCESSFUL; @@ -773,8 +771,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) * the reg address cell, we shall fix that by killing struct * reg_property and using some accessor functions instead */ - hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, - 0x02000000); + hose->cfg_data = ioremap(0xf2000000, 0x02000000); /* * /ht node doesn't expose a "ranges" property, so we "remove" diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 89c4c363616..1955462f408 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -82,8 +82,6 @@ #undef SHOW_GATWICK_IRQS -unsigned char drive_info; - int ppc_override_l2cr = 0; int ppc_override_l2cr_value; int has_l2cache = 0; diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 6373372932b..e3cbba49fd6 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -333,7 +333,7 @@ void handle_eeh_events (struct eeh_event *event) rc = eeh_reset_device(frozen_pdn, NULL); if (rc) goto hard_fail; - pci_walk_bus(frozen_bus, eeh_report_reset, 0); + pci_walk_bus(frozen_bus, eeh_report_reset, NULL); } /* If all devices reported they can proceed, the re-enable PIO */ @@ -342,11 +342,11 @@ void handle_eeh_events (struct eeh_event *event) rc = eeh_reset_device(frozen_pdn, NULL); if (rc) goto hard_fail; - pci_walk_bus(frozen_bus, eeh_report_reset, 0); + pci_walk_bus(frozen_bus, eeh_report_reset, NULL); } /* Tell all device drivers that they can resume operations */ - pci_walk_bus(frozen_bus, eeh_report_resume, 0); + pci_walk_bus(frozen_bus, eeh_report_resume, NULL); return; @@ -367,7 +367,7 @@ hard_fail: eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); /* Notify all devices that they're about to go down. */ - pci_walk_bus(frozen_bus, eeh_report_failure, 0); + pci_walk_bus(frozen_bus, eeh_report_failure, NULL); /* Shut down the device drivers for good. */ pcibios_remove_pci_devices(frozen_bus); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index da6cebaf72c..9edeca83f43 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -585,7 +585,7 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) { /* Don't risk a hypervisor call if we're crashing */ - if (!crash_shutdown) { + if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { unsigned long vpa = __pa(get_lppaca()); if (unregister_vpa(hard_smp_processor_id(), vpa)) { diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 977de9db875..6298264efe3 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -59,7 +59,7 @@ static unsigned long dart_tablesize; static u32 *dart_vbase; /* Mapped base address for the dart */ -static unsigned int *__iomem dart; +static unsigned int __iomem *dart; /* Dummy val that entries are set to when unused */ static unsigned int dart_emptyval; diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index 3e6ca7f5843..c1e89ad0684 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -810,13 +810,16 @@ initial_mmu: mtspr SPRN_MD_TWC, r9 li r11, MI_BOOTINIT /* Create RPN for address 0 */ addis r11, r11, 0x0080 /* Add 8M */ - mtspr SPRN_MD_RPN, r8 + mtspr SPRN_MD_RPN, r11 + + addi r10, r10, 0x0100 + mtspr SPRN_MD_CTR, r10 addis r8, r8, 0x0080 /* Add 8M */ mtspr SPRN_MD_EPN, r8 mtspr SPRN_MD_TWC, r9 addis r11, r11, 0x0080 /* Add 8M */ - mtspr SPRN_MD_RPN, r8 + mtspr SPRN_MD_RPN, r11 #endif /* Since the cache is enabled according to the information we diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 3a6e4bcb3c5..15bd9b448a4 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -186,11 +186,15 @@ EXPORT_SYMBOL(flush_tlb_kernel_range); EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(_tlbie); #ifdef CONFIG_ALTIVEC +#ifndef CONFIG_SMP EXPORT_SYMBOL(last_task_used_altivec); +#endif EXPORT_SYMBOL(giveup_altivec); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SPE +#ifndef CONFIG_SMP EXPORT_SYMBOL(last_task_used_spe); +#endif EXPORT_SYMBOL(giveup_spe); #endif /* CONFIG_SPE */ #ifdef CONFIG_SMP diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c index 159b228eca1..0ec53f04933 100644 --- a/arch/ppc/platforms/4xx/bamboo.c +++ b/arch/ppc/platforms/4xx/bamboo.c @@ -332,8 +332,8 @@ bamboo_early_serial_map(void) port.irq = 0; port.uartclk = clocks.uart0; port.regshift = 0; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = 0; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c index 8110f55668c..ce48a4f08cb 100644 --- a/arch/ppc/platforms/4xx/bubinga.c +++ b/arch/ppc/platforms/4xx/bubinga.c @@ -97,8 +97,8 @@ bubinga_early_serial_map(void) port.irq = ACTING_UART0_INT; port.uartclk = uart_clock; port.regshift = 0; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = 0; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c index 64ebae19cdb..9a828b62341 100644 --- a/arch/ppc/platforms/4xx/ebony.c +++ b/arch/ppc/platforms/4xx/ebony.c @@ -225,8 +225,8 @@ ebony_early_serial_map(void) port.irq = 0; port.uartclk = clocks.uart0; port.regshift = 0; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = 0; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c index d810b736d9b..21d29132aeb 100644 --- a/arch/ppc/platforms/4xx/luan.c +++ b/arch/ppc/platforms/4xx/luan.c @@ -279,8 +279,8 @@ luan_early_serial_map(void) port.irq = UART0_INT; port.uartclk = clocks.uart0; port.regshift = 0; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = 0; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c index 73b2c98158f..4f355b6acab 100644 --- a/arch/ppc/platforms/4xx/ocotea.c +++ b/arch/ppc/platforms/4xx/ocotea.c @@ -248,8 +248,8 @@ ocotea_early_serial_map(void) port.irq = UART0_INT; port.uartclk = clocks.uart0; port.regshift = 0; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = 0; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/4xx/xilinx_ml300.c b/arch/ppc/platforms/4xx/xilinx_ml300.c index 0b1b77d986b..e90d97f64f7 100644 --- a/arch/ppc/platforms/4xx/xilinx_ml300.c +++ b/arch/ppc/platforms/4xx/xilinx_ml300.c @@ -95,8 +95,8 @@ ml300_early_serial_map(void) port.irq = old_ports[i].irq; port.uartclk = old_ports[i].baud_base * 16; port.regshift = old_ports[i].iomem_reg_shift; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = i; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c index e60f4bd437e..b065b8babcd 100644 --- a/arch/ppc/platforms/4xx/yucca.c +++ b/arch/ppc/platforms/4xx/yucca.c @@ -305,8 +305,8 @@ yucca_early_serial_map(void) port.irq = UART0_INT; port.uartclk = clocks.uart0; port.regshift = 0; - port.iotype = SERIAL_IO_MEM; - port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.iotype = UPIO_MEM; + port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; port.line = 0; if (early_serial_setup(&port) != 0) { diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index 012e1e652c0..1a659bbc186 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c @@ -301,14 +301,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, struct uart_port p; memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4500); p.uartclk = binfo->bi_busfreq; gen550_init(0, &p); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4600); p.uartclk = binfo->bi_busfreq; diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 2eceb1e6f4e..408d64f18e1 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -162,14 +162,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; p.uartclk = binfo->bi_busfreq; gen550_init(0, &p); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; p.uartclk = binfo->bi_busfreq; diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index b332ebae6bd..1801ab392e2 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -534,14 +534,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; p.uartclk = binfo->bi_busfreq; gen550_init(0, &p); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; p.uartclk = binfo->bi_busfreq; diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index e777ba824aa..8a72221f816 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c @@ -64,7 +64,7 @@ sbc8560_early_serial_map(void) uart_req.irq = MPC85xx_IRQ_EXT9; uart_req.flags = STD_COM_FLAGS; uart_req.uartclk = BASE_BAUD * 16; - uart_req.iotype = SERIAL_IO_MEM; + uart_req.iotype = UPIO_MEM; uart_req.mapbase = UARTA_ADDR; uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE); uart_req.type = PORT_16650; diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c index b436f4d0a3f..a5e38ba6273 100644 --- a/arch/ppc/platforms/85xx/tqm85xx.c +++ b/arch/ppc/platforms/85xx/tqm85xx.c @@ -346,14 +346,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; p.uartclk = binfo->bi_busfreq; gen550_init(0, &p); memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; + p.iotype = UPIO_MEM; p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; p.uartclk = binfo->bi_busfreq; diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c index 48a4a510d59..aefcc0e7be5 100644 --- a/arch/ppc/platforms/chestnut.c +++ b/arch/ppc/platforms/chestnut.c @@ -116,7 +116,7 @@ chestnut_early_serial_map(void) port.uartclk = BASE_BAUD * 16; port.irq = UART0_INT; port.flags = STD_COM_FLAGS | UPF_IOREMAP; - port.iotype = SERIAL_IO_MEM; + port.iotype = UPIO_MEM; port.mapbase = CHESTNUT_UART0_IO_BASE; port.regshift = 0; diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c index 32358b3fb23..ffde8f6f630 100644 --- a/arch/ppc/platforms/ev64260.c +++ b/arch/ppc/platforms/ev64260.c @@ -330,7 +330,7 @@ ev64260_early_serial_map(void) port.irq = EV64260_UART_0_IRQ; port.uartclk = BASE_BAUD * 16; port.regshift = 2; - port.iotype = SERIAL_IO_MEM; + port.iotype = UPIO_MEM; port.flags = STD_COM_FLAGS; #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index 708b8739ecd..872c0a3ba3c 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c @@ -100,7 +100,7 @@ static void __init ppc7d_early_serial_map(void) serial_req.uartclk = UART_CLK; serial_req.irq = 4; serial_req.flags = STD_COM_FLAGS; - serial_req.iotype = SERIAL_IO_MEM; + serial_req.iotype = UPIO_MEM; serial_req.membase = (u_char *) PPC7D_SERIAL_0; gen550_init(0, &serial_req); diff --git a/arch/ppc/platforms/spruce.c b/arch/ppc/platforms/spruce.c index 5ad70d357cb..69e1de7971f 100644 --- a/arch/ppc/platforms/spruce.c +++ b/arch/ppc/platforms/spruce.c @@ -176,8 +176,8 @@ spruce_early_serial_map(void) memset(&serial_req, 0, sizeof(serial_req)); serial_req.uartclk = uart_clk; serial_req.irq = UART0_INT; - serial_req.flags = ASYNC_BOOT_AUTOCONF; - serial_req.iotype = SERIAL_IO_MEM; + serial_req.flags = UPF_BOOT_AUTOCONF; + serial_req.iotype = UPIO_MEM; serial_req.membase = (u_char *)UART0_IO_BASE; serial_req.regshift = 0; diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c index ab34b1d6072..2fe28ded2c6 100644 --- a/arch/ppc/syslib/ocp.c +++ b/arch/ppc/syslib/ocp.c @@ -189,8 +189,8 @@ ocp_device_resume(struct device *dev) struct bus_type ocp_bus_type = { .name = "ocp", .match = ocp_device_match, - .probe = ocp_driver_probe, - .remove = ocp_driver_remove, + .probe = ocp_device_probe, + .remove = ocp_device_remove, .suspend = ocp_device_suspend, .resume = ocp_device_resume, }; diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index 1b5fe9e398d..7bada82527a 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c @@ -108,7 +108,7 @@ mpc83xx_early_serial_map(void) #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) memset(&serial_req, 0, sizeof (serial_req)); - serial_req.iotype = SERIAL_IO_MEM; + serial_req.iotype = UPIO_MEM; serial_req.mapbase = pdata[0].mapbase; serial_req.membase = pdata[0].membase; serial_req.regshift = 0; diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 1a47ff4b831..e4dda43fdaa 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c @@ -90,7 +90,7 @@ mpc85xx_early_serial_map(void) #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) memset(&serial_req, 0, sizeof (serial_req)); - serial_req.iotype = SERIAL_IO_MEM; + serial_req.iotype = UPIO_MEM; serial_req.mapbase = pdata[0].mapbase; serial_req.membase = pdata[0].membase; serial_req.regshift = 0; diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index bf9a7a361b3..cc20f0e3a7d 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -100,12 +100,12 @@ #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) -asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group) +asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group) { return sys_chown(filename, low2highuid(user), low2highgid(group)); } -asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group) +asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group) { return sys_lchown(filename, low2highuid(user), low2highgid(group)); } @@ -141,7 +141,7 @@ asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid) low2highuid(suid)); } -asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid) +asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid) { int retval; @@ -158,7 +158,7 @@ asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid) low2highgid(sgid)); } -asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid) +asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid) { int retval; @@ -179,7 +179,7 @@ asmlinkage long sys32_setfsgid16(u16 gid) return sys_setfsgid((gid_t)gid); } -static int groups16_to_user(u16 *grouplist, struct group_info *group_info) +static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info) { int i; u16 group; @@ -193,7 +193,7 @@ static int groups16_to_user(u16 *grouplist, struct group_info *group_info) return 0; } -static int groups16_from_user(struct group_info *group_info, u16 *grouplist) +static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist) { int i; u16 group; @@ -207,7 +207,7 @@ static int groups16_from_user(struct group_info *group_info, u16 *grouplist) return 0; } -asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist) +asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist) { int i; @@ -231,7 +231,7 @@ out: return i; } -asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist) +asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) { struct group_info *group_info; int retval; @@ -278,14 +278,14 @@ asmlinkage long sys32_getegid16(void) /* 32-bit timeval and related flotsam. */ -static inline long get_tv32(struct timeval *o, struct compat_timeval *i) +static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i) { return (!access_ok(VERIFY_READ, o, sizeof(*o)) || (__get_user(o->tv_sec, &i->tv_sec) || __get_user(o->tv_usec, &i->tv_usec))); } -static inline long put_tv32(struct compat_timeval *o, struct timeval *i) +static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) { return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || (__put_user(i->tv_sec, &o->tv_sec) || @@ -341,7 +341,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) return -ENOSYS; } -asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low) +asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) { if ((int)high < 0) return -EINVAL; @@ -357,7 +357,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned return sys_ftruncate(fd, (high << 32) | low); } -int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf) +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) { int err; @@ -591,7 +591,7 @@ sys32_delete_module(const char __user *name_user, unsigned int flags) extern struct timezone sys_tz; -asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) +asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { if (tv) { struct timeval ktv; @@ -606,7 +606,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *t return 0; } -static inline long get_ts32(struct timespec *o, struct compat_timeval *i) +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) { long usec; @@ -620,7 +620,7 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i) return 0; } -asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) +asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { struct timespec kts; struct timezone ktz; @@ -645,7 +645,7 @@ asmlinkage long sys32_pause(void) return -ERESTARTNOHAND; } -asmlinkage long sys32_pread64(unsigned int fd, char *ubuf, +asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, u32 poshi, u32 poslo) { if ((compat_ssize_t) count < 0) @@ -653,7 +653,7 @@ asmlinkage long sys32_pread64(unsigned int fd, char *ubuf, return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); } -asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf, +asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf, size_t count, u32 poshi, u32 poslo) { if ((compat_ssize_t) count < 0) @@ -666,7 +666,7 @@ asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 coun return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); } -asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count) +asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count) { mm_segment_t old_fs = get_fs(); int ret; @@ -686,7 +686,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size } asmlinkage long sys32_sendfile64(int out_fd, int in_fd, - compat_loff_t *offset, s32 count) + compat_loff_t __user *offset, s32 count) { mm_segment_t old_fs = get_fs(); int ret; @@ -722,7 +722,7 @@ struct timex32 { extern int do_adjtimex(struct timex *); -asmlinkage long sys32_adjtimex(struct timex32 *utp) +asmlinkage long sys32_adjtimex(struct timex32 __user *utp) { struct timex txc; int ret; @@ -789,12 +789,13 @@ struct __sysctl_args32 { u32 __unused[4]; }; -asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) +asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) { struct __sysctl_args32 tmp; int error; - size_t oldlen, *oldlenp = NULL; - unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; + size_t oldlen; + size_t __user *oldlenp = NULL; + unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; @@ -806,20 +807,20 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) basically copy the whole sysctl.c here, and glibc's __sysctl uses rw memory for the structure anyway. */ - if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || - put_user(oldlen, (size_t *)addr)) + if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) || + put_user(oldlen, (size_t __user *)addr)) return -EFAULT; - oldlenp = (size_t *)addr; + oldlenp = (size_t __user *)addr; } lock_kernel(); - error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), - oldlenp, (void *)A(tmp.newval), tmp.newlen); + error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval), + oldlenp, compat_ptr(tmp.newval), tmp.newlen); unlock_kernel(); if (oldlenp) { if (!error) { - if (get_user(oldlen, (size_t *)addr) || - put_user(oldlen, (u32 *)A(tmp.oldlenp))) + if (get_user(oldlen, (size_t __user *)addr) || + put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp))) error = -EFAULT; } copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); @@ -853,7 +854,7 @@ struct stat64_emu31 { unsigned long st_ino; }; -static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat) +static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat) { struct stat64_emu31 tmp; @@ -877,7 +878,7 @@ static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat) return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf) +asmlinkage long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf) { struct kstat stat; int ret = vfs_stat(filename, &stat); @@ -886,7 +887,7 @@ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf) return ret; } -asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf) +asmlinkage long sys32_lstat64(char __user * filename, struct stat64_emu31 __user * statbuf) { struct kstat stat; int ret = vfs_lstat(filename, &stat); @@ -895,7 +896,7 @@ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf) return ret; } -asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf) +asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf) { struct kstat stat; int ret = vfs_fstat(fd, &stat); @@ -952,7 +953,7 @@ out: asmlinkage unsigned long -old32_mmap(struct mmap_arg_struct_emu31 *arg) +old32_mmap(struct mmap_arg_struct_emu31 __user *arg) { struct mmap_arg_struct_emu31 a; int error = -EFAULT; @@ -970,7 +971,7 @@ out: } asmlinkage long -sys32_mmap2(struct mmap_arg_struct_emu31 *arg) +sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) { struct mmap_arg_struct_emu31 a; int error = -EFAULT; @@ -982,7 +983,7 @@ out: return error; } -asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count) +asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count) { if ((compat_ssize_t) count < 0) return -EINVAL; @@ -990,7 +991,7 @@ asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count) return sys_read(fd, buf, count); } -asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count) +asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count) { if ((compat_ssize_t) count < 0) return -EINVAL; @@ -1002,12 +1003,12 @@ asmlinkage long sys32_clone(struct pt_regs regs) { unsigned long clone_flags; unsigned long newsp; - int *parent_tidptr, *child_tidptr; + int __user *parent_tidptr, *child_tidptr; clone_flags = regs.gprs[3] & 0xffffffffUL; newsp = regs.orig_gpr2 & 0x7fffffffUL; - parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL); - child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL); + parent_tidptr = compat_ptr(regs.gprs[4]); + child_tidptr = compat_ptr(regs.gprs[5]); if (!newsp) newsp = regs.gprs[15]; return do_fork(clone_flags, newsp, ®s, 0, diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index 6a63553493c..e351780bb66 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -122,8 +122,8 @@ out: #ifndef CONFIG_64BIT struct sel_arg_struct { unsigned long n; - fd_set *inp, *outp, *exp; - struct timeval *tvp; + fd_set __user *inp, *outp, *exp; + struct timeval __user *tvp; }; asmlinkage long old_select(struct sel_arg_struct __user *arg) diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 5d21e9e6e7b..a46793beedd 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -486,7 +486,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) info.si_signo = signal; info.si_errno = 0; info.si_code = ILL_ILLOPC; - info.si_addr = (void *) location; + info.si_addr = (void __user *) location; do_trap(interruption_code, signal, "illegal operation", regs, &info); } diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index 2d5cb138575..b075ab499d0 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -42,8 +42,8 @@ static volatile long cmm_timed_pages_target = 0; static long cmm_timeout_pages = 0; static long cmm_timeout_seconds = 0; -static struct cmm_page_array *cmm_page_list = 0; -static struct cmm_page_array *cmm_timed_page_list = 0; +static struct cmm_page_array *cmm_page_list = NULL; +static struct cmm_page_array *cmm_timed_page_list = NULL; static unsigned long cmm_thread_active = 0; static struct work_struct cmm_thread_starter; @@ -259,7 +259,7 @@ static struct ctl_table cmm_table[]; static int cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) + void __user *buffer, size_t *lenp, loff_t *ppos) { char buf[16], *p; long pages; @@ -300,7 +300,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, static int cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) + void __user *buffer, size_t *lenp, loff_t *ppos) { char buf[64], *p; long pages, seconds; @@ -419,7 +419,7 @@ cmm_init (void) #ifdef CONFIG_CMM_IUCV smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); #endif - INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, 0); + INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL); init_waitqueue_head(&cmm_thread_wait); init_timer(&cmm_timer); return 0; diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c index c46f9154cfd..123abbbc91e 100644 --- a/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/arch/sh/boards/renesas/rts7751r2d/io.c @@ -216,24 +216,26 @@ void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) { volatile __u8 *bp; volatile __u16 *p; + unsigned char *s = addr; if (CHECK_AX88796L_PORT(port)) { p = (volatile unsigned short *)port88796l(port, 0); - while (count--) *((unsigned char *) addr)++ = *p & 0xff; + while (count--) *s++ = *p & 0xff; } else if (PXSEG(port)) - while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; + while (count--) *s++ = *(volatile unsigned char *)port; else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { bp = (__u8 *)PCI_IOMAP(port); - while (count--) *((volatile unsigned char *) addr)++ = *bp; + while (count--) *s++ = *bp; } else { p = (volatile unsigned short *)port2adr(port); - while (count--) *((unsigned char *) addr)++ = *p & 0xff; + while (count--) *s++ = *p & 0xff; } } void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) { volatile __u16 *p; + __u16 *s = addr; if (CHECK_AX88796L_PORT(port)) p = (volatile unsigned short *)port88796l(port, 1); @@ -243,7 +245,7 @@ void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) p = (volatile unsigned short *)PCI_IOMAP(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) *((__u16 *) addr)++ = *p; + while (count--) *s++ = *p; } void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) @@ -252,8 +254,9 @@ void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) maybebadio(insl, port); else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + __u32 *s = addr; - while (count--) *((__u32 *) addr)++ = *p; + while (count--) *s++ = *p; } else maybebadio(insl, port); } @@ -262,24 +265,26 @@ void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) { volatile __u8 *bp; volatile __u16 *p; + const __u8 *s = addr; if (CHECK_AX88796L_PORT(port)) { p = (volatile unsigned short *)port88796l(port, 0); - while (count--) *p = *((unsigned char *) addr)++; + while (count--) *p = *s++; } else if (PXSEG(port)) - while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; + while (count--) *(volatile unsigned char *)port = *s++; else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { bp = (__u8 *)PCI_IOMAP(port); - while (count--) *bp = *((volatile unsigned char *) addr)++; + while (count--) *bp = *s++; } else { p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *((unsigned char *) addr)++; + while (count--) *p = *s++; } } void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) { volatile __u16 *p; + const __u16 *s = addr; if (CHECK_AX88796L_PORT(port)) p = (volatile unsigned short *)port88796l(port, 1); @@ -289,7 +294,7 @@ void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) p = (volatile unsigned short *)PCI_IOMAP(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *((__u16 *) addr)++; + while (count--) *p = *s++; } void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) @@ -298,8 +303,9 @@ void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) maybebadio(outsl, port); else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + const __u32 *s = addr; - while (count--) *p = *((__u32 *) addr)++; + while (count--) *p = *s++; } else maybebadio(outsl, port); } diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c index 472b450e61b..de29c45f23a 100644 --- a/arch/sh64/kernel/sh_ksyms.c +++ b/arch/sh64/kernel/sh_ksyms.c @@ -31,14 +31,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); -#if 0 -/* Not yet - there's no declaration of drive_info anywhere. */ -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) -extern struct drive_info_struct drive_info; -EXPORT_SYMBOL(drive_info); -#endif -#endif - /* platform dependent support */ EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(iounmap); diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 267ec8f6fb5..887f6a160c5 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -38,7 +38,7 @@ #define curptr g6 -#define NR_SYSCALLS 299 /* Each OS is different... */ +#define NR_SYSCALLS 300 /* Each OS is different... */ /* These are just handy. */ #define _SV save %sp, -STACKFRAME_SZ, %sp diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index fbb05a452e5..118cac84a0f 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -54,7 +54,7 @@ void (*pm_idle)(void); * This is done via auxio, but could be used as a fallback * handler when auxio is not present-- unused for now... */ -void (*pm_power_off)(void); +void (*pm_power_off)(void) = machine_power_off; /* * sysctl - toggle power-off restriction for serial console diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 6877ae4cd1d..c0314705d73 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -78,7 +78,7 @@ sys_call_table: /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat -/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll +/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -190,5 +190,6 @@ sunos_sys_table: /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys #endif diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index bc56a7d8830..069d49777b2 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16-rc2 -# Sat Feb 4 02:31:38 2006 +# Tue Feb 7 17:47:18 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -30,7 +30,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -766,6 +766,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 12911e7463f..a73553ae7e5 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -25,7 +25,7 @@ #define curptr g6 -#define NR_SYSCALLS 299 /* Each OS is different... */ +#define NR_SYSCALLS 300 /* Each OS is different... */ .text .align 32 diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 2881faf3663..5928b3c33e2 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -79,7 +79,7 @@ sys_call_table32: /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat - .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll + .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare #endif /* CONFIG_COMPAT */ @@ -148,7 +148,7 @@ sys_call_table: /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat - .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll + .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -261,4 +261,5 @@ sunos_sys_table: /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys #endif diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S index d25667eeae1..7043ca18caf 100644 --- a/arch/sparc64/solaris/systbl.S +++ b/arch/sparc64/solaris/systbl.S @@ -283,32 +283,3 @@ solaris_sys_table: .word solaris_unimplemented /* 253 */ .word solaris_unimplemented /* 254 */ .word solaris_unimplemented /* 255 */ - .word solaris_unimplemented /* 256 */ - .word solaris_unimplemented /* 257 */ - .word solaris_unimplemented /* 258 */ - .word solaris_unimplemented /* 259 */ - .word solaris_unimplemented /* 260 */ - .word solaris_unimplemented /* 261 */ - .word solaris_unimplemented /* 262 */ - .word solaris_unimplemented /* 263 */ - .word solaris_unimplemented /* 264 */ - .word solaris_unimplemented /* 265 */ - .word solaris_unimplemented /* 266 */ - .word solaris_unimplemented /* 267 */ - .word solaris_unimplemented /* 268 */ - .word solaris_unimplemented /* 269 */ - .word solaris_unimplemented /* 270 */ - .word solaris_unimplemented /* 271 */ - .word solaris_unimplemented /* 272 */ - .word solaris_unimplemented /* 273 */ - .word solaris_unimplemented /* 274 */ - .word solaris_unimplemented /* 275 */ - .word solaris_unimplemented /* 276 */ - .word solaris_unimplemented /* 277 */ - .word solaris_unimplemented /* 278 */ - .word solaris_unimplemented /* 279 */ - .word solaris_unimplemented /* 280 */ - .word solaris_unimplemented /* 281 */ - .word solaris_unimplemented /* 282 */ - .word solaris_unimplemented /* 283 */ - diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 5d50d4a44ab..2f880cb167a 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -9,6 +9,7 @@ #include <termios.h> #include <string.h> #include <signal.h> +#include <sched.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/socket.h> @@ -73,7 +74,6 @@ static void winch_handler(int sig) struct winch_data { int pty_fd; int pipe_fd; - int close_me; }; static int winch_thread(void *arg) @@ -84,7 +84,6 @@ static int winch_thread(void *arg) int count, err; char c = 1; - os_close_file(data->close_me); pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; count = os_write_file(pipe_fd, &c, sizeof(c)); @@ -153,15 +152,16 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) } data = ((struct winch_data) { .pty_fd = fd, - .pipe_fd = fds[1], - .close_me = fds[0] } ); - err = run_helper_thread(winch_thread, &data, 0, &stack, 0); + .pipe_fd = fds[1] } ); + /* CLONE_FILES so this thread doesn't hold open files which are open + * now, but later closed. This is a problem with /dev/net/tun. + */ + err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ printk("fork of winch_thread failed - errno = %d\n", errno); goto out_close; } - os_close_file(fds[1]); *fd_out = fds[0]; n = os_read_file(fds[0], &c, sizeof(c)); if(n != sizeof(c)){ @@ -169,13 +169,12 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) printk("read failed, err = %d\n", -n); printk("fd %d will not support SIGWINCH\n", fd); err = -EINVAL; - goto out_close1; + goto out_close; } return err ; out_close: os_close_file(fds[1]); - out_close1: os_close_file(fds[0]); out: return err; diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 8ebb2241ad4..8c7279bb353 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -131,9 +131,8 @@ static int uml_net_open(struct net_device *dev) SA_INTERRUPT | SA_SHIRQ, dev->name, dev); if(err != 0){ printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); - if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); - lp->fd = -1; err = -ENETUNREACH; + goto out_close; } lp->tl.data = (unsigned long) &lp->user; @@ -145,9 +144,19 @@ static int uml_net_open(struct net_device *dev) */ while((err = uml_net_rx(dev)) > 0) ; - out: spin_unlock(&lp->lock); - return(err); + + spin_lock(&opened_lock); + list_add(&lp->list, &opened); + spin_unlock(&opened_lock); + + return 0; +out_close: + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); + lp->fd = -1; +out: + spin_unlock(&lp->lock); + return err; } static int uml_net_close(struct net_device *dev) @@ -161,9 +170,13 @@ static int uml_net_close(struct net_device *dev) if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); lp->fd = -1; - list_del(&lp->list); spin_unlock(&lp->lock); + + spin_lock(&opened_lock); + list_del(&lp->list); + spin_unlock(&opened_lock); + return 0; } @@ -410,11 +423,7 @@ static int eth_configure(int n, void *init, char *mac, if (device->have_mac) set_ether_mac(dev, device->mac); - spin_lock(&opened_lock); - list_add(&lp->list, &opened); - spin_unlock(&opened_lock); - - return(0); + return 0; } static struct uml_net *find_device(int n) diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h index 4892e5fcef0..83b688ca198 100644 --- a/arch/um/include/registers.h +++ b/arch/um/include/registers.h @@ -14,7 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); extern void save_registers(int pid, union uml_pt_regs *regs); extern void restore_registers(int pid, union uml_pt_regs *regs); extern void init_registers(int pid); -extern void get_safe_registers(unsigned long * regs); +extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs); extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer); #endif diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c deleted file mode 100644 index eea1c9c4bb0..00000000000 --- a/arch/um/kernel/skas/process.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <setjmp.h> -#include <sched.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include <sys/user.h> -#include <sys/time.h> -#include <asm/unistd.h> -#include <asm/types.h> -#include "user.h" -#include "ptrace_user.h" -#include "sysdep/ptrace.h" -#include "user_util.h" -#include "kern_util.h" -#include "skas.h" -#include "stub-data.h" -#include "mm_id.h" -#include "sysdep/sigcontext.h" -#include "sysdep/stub.h" -#include "os.h" -#include "proc_mm.h" -#include "skas_ptrace.h" -#include "chan_user.h" -#include "registers.h" -#include "mem.h" -#include "uml-config.h" -#include "process.h" - -int is_skas_winch(int pid, int fd, void *data) -{ - if(pid != os_getpgrp()) - return(0); - - register_winch_irq(-1, fd, -1, data); - return(1); -} - -void wait_stub_done(int pid, int sig, char * fname) -{ - int n, status, err; - - do { - if ( sig != -1 ) { - err = ptrace(PTRACE_CONT, pid, 0, sig); - if(err) - panic("%s : continue failed, errno = %d\n", - fname, errno); - } - sig = 0; - - CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - } while((n >= 0) && WIFSTOPPED(status) && - ((WSTOPSIG(status) == SIGVTALRM) || - /* running UML inside a detached screen can cause - * SIGWINCHes - */ - (WSTOPSIG(status) == SIGWINCH))); - - if((n < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - unsigned long regs[HOST_FRAME_SIZE]; - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) - printk("Failed to get registers from stub, " - "errno = %d\n", errno); - else { - int i; - - printk("Stub registers -\n"); - for(i = 0; i < HOST_FRAME_SIZE; i++) - printk("\t%d - %lx\n", i, regs[i]); - } - panic("%s : failed to wait for SIGUSR1/SIGTRAP, " - "pid = %d, n = %d, errno = %d, status = 0x%x\n", - fname, pid, n, errno, status); - } -} - -void get_skas_faultinfo(int pid, struct faultinfo * fi) -{ - int err; - - if(ptrace_faultinfo){ - err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); - if(err) - panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " - "errno = %d\n", errno); - - /* Special handling for i386, which has different structs */ - if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) - memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, - sizeof(struct faultinfo) - - sizeof(struct ptrace_faultinfo)); - } - else { - wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); - - /* faultinfo is prepared by the stub-segv-handler at start of - * the stub stack page. We just have to copy it. - */ - memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); - } -} - -static void handle_segv(int pid, union uml_pt_regs * regs) -{ - get_skas_faultinfo(pid, ®s->skas.faultinfo); - segv(regs->skas.faultinfo, 0, 1, NULL); -} - -/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ -static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) -{ - int err, status; - - /* Mark this as a syscall */ - UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); - - if (!local_using_sysemu) - { - err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); - if(err < 0) - panic("handle_trap - nullifying syscall failed errno = %d\n", - errno); - - err = ptrace(PTRACE_SYSCALL, pid, 0, 0); - if(err < 0) - panic("handle_trap - continuing to end of syscall failed, " - "errno = %d\n", errno); - - CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); - if((err < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGTRAP + 0x80)) - panic("handle_trap - failed to wait at end of syscall, " - "errno = %d, status = %d\n", errno, status); - } - - handle_syscall(regs); -} - -extern int __syscall_stub_start; -int stub_code_fd = -1; -__u64 stub_code_offset; - -static int userspace_tramp(void *stack) -{ - void *addr; - - ptrace(PTRACE_TRACEME, 0, 0, 0); - - init_new_thread_signals(1); - enable_timer(); - - if(!proc_mm){ - /* This has a pte, but it can't be mapped in with the usual - * tlb_flush mechanism because this is part of that mechanism - */ - addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), - PROT_EXEC, MAP_FIXED | MAP_PRIVATE, - stub_code_fd, stub_code_offset); - if(addr == MAP_FAILED){ - printk("mapping stub code failed, errno = %d\n", - errno); - exit(1); - } - - if(stack != NULL){ - int fd; - __u64 offset; - - fd = phys_mapping(to_phys(stack), &offset); - addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), - PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, fd, offset); - if(addr == MAP_FAILED){ - printk("mapping stub stack failed, " - "errno = %d\n", errno); - exit(1); - } - } - } - if(!ptrace_faultinfo){ - unsigned long v = UML_CONFIG_STUB_CODE + - (unsigned long) stub_segv_handler - - (unsigned long) &__syscall_stub_start; - - set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); - set_handler(SIGSEGV, (void *) v, SA_ONSTACK, - SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, - SIGUSR1, -1); - } - - os_stop_process(os_getpid()); - return(0); -} - -/* Each element set once, and only accessed by a single processor anyway */ -#undef NR_CPUS -#define NR_CPUS 1 -int userspace_pid[NR_CPUS]; - -int start_userspace(unsigned long stub_stack) -{ - void *stack; - unsigned long sp; - int pid, status, n, flags; - - if ( stub_code_fd == -1 ) - stub_code_fd = phys_mapping(to_phys(&__syscall_stub_start), - &stub_code_offset); - - stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) - panic("start_userspace : mmap failed, errno = %d", errno); - sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); - - flags = CLONE_FILES | SIGCHLD; - if(proc_mm) flags |= CLONE_VM; - pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); - if(pid < 0) - panic("start_userspace : clone failed, errno = %d", errno); - - do { - CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) - panic("start_userspace : wait failed, errno = %d", - errno); - } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); - - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) - panic("start_userspace : expected SIGSTOP, got status = %d", - status); - - if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0) - panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n", - errno); - - if(munmap(stack, PAGE_SIZE) < 0) - panic("start_userspace : munmap failed, errno = %d\n", errno); - - return(pid); -} - -void userspace(union uml_pt_regs *regs) -{ - int err, status, op, pid = userspace_pid[0]; - int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ - - while(1){ - restore_registers(pid, regs); - - /* Now we set local_using_sysemu to be used for one loop */ - local_using_sysemu = get_using_sysemu(); - - op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL)); - - err = ptrace(op, pid, 0, 0); - if(err) - panic("userspace - could not resume userspace process, " - "pid=%d, ptrace operation = %d, errno = %d\n", - op, errno); - - CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); - if(err < 0) - panic("userspace - waitpid failed, errno = %d\n", - errno); - - regs->skas.is_user = 1; - save_registers(pid, regs); - UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ - - if(WIFSTOPPED(status)){ - switch(WSTOPSIG(status)){ - case SIGSEGV: - if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) - user_signal(SIGSEGV, regs, pid); - else handle_segv(pid, regs); - break; - case SIGTRAP + 0x80: - handle_trap(pid, regs, local_using_sysemu); - break; - case SIGTRAP: - relay_signal(SIGTRAP, regs); - break; - case SIGIO: - case SIGVTALRM: - case SIGILL: - case SIGBUS: - case SIGFPE: - case SIGWINCH: - user_signal(WSTOPSIG(status), regs, pid); - break; - default: - printk("userspace - child stopped with signal " - "%d\n", WSTOPSIG(status)); - } - pid = userspace_pid[0]; - interrupt_end(); - - /* Avoid -ERESTARTSYS handling in host */ - PT_SYSCALL_NR(regs->skas.regs) = -1; - } - } -} -#define INIT_JMP_NEW_THREAD 0 -#define INIT_JMP_REMOVE_SIGSTACK 1 -#define INIT_JMP_CALLBACK 2 -#define INIT_JMP_HALT 3 -#define INIT_JMP_REBOOT 4 - - -int copy_context_skas0(unsigned long new_stack, int pid) -{ - int err; - unsigned long regs[MAX_REG_NR]; - unsigned long current_stack = current_stub_stack(); - struct stub_data *data = (struct stub_data *) current_stack; - struct stub_data *child_data = (struct stub_data *) new_stack; - __u64 new_offset; - int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); - - /* prepare offset and fd of child's stack as argument for parent's - * and child's mmap2 calls - */ - *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), - .fd = new_fd, - .timer = ((struct itimerval) - { { 0, 1000000 / hz() }, - { 0, 1000000 / hz() }})}); - get_safe_registers(regs); - - /* Set parent's instruction pointer to start of clone-stub */ - regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - (unsigned long) stub_clone_handler - - (unsigned long) &__syscall_stub_start; - regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - - sizeof(void *); - err = ptrace_setregs(pid, regs); - if(err < 0) - panic("copy_context_skas0 : PTRACE_SETREGS failed, " - "pid = %d, errno = %d\n", pid, errno); - - /* set a well known return code for detection of child write failure */ - child_data->err = 12345678; - - /* Wait, until parent has finished its work: read child's pid from - * parent's stack, and check, if bad result. - */ - wait_stub_done(pid, 0, "copy_context_skas0"); - - pid = data->err; - if(pid < 0) - panic("copy_context_skas0 - stub-parent reports error %d\n", - pid); - - /* Wait, until child has finished too: read child's result from - * child's stack and check it. - */ - wait_stub_done(pid, -1, "copy_context_skas0"); - if (child_data->err != UML_CONFIG_STUB_DATA) - panic("copy_context_skas0 - stub-child reports error %d\n", - child_data->err); - - if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, - (void *)PTRACE_O_TRACESYSGOOD) < 0) - panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, " - "errno = %d\n", errno); - - return pid; -} - -/* - * This is used only, if stub pages are needed, while proc_mm is - * availabl. Opening /proc/mm creates a new mm_context, which lacks - * the stub-pages. Thus, we map them using /proc/mm-fd - */ -void map_stub_pages(int fd, unsigned long code, - unsigned long data, unsigned long stack) -{ - struct proc_mm_op mmop; - int n; - - mmop = ((struct proc_mm_op) { .op = MM_MMAP, - .u = - { .mmap = - { .addr = code, - .len = PAGE_SIZE, - .prot = PROT_EXEC, - .flags = MAP_FIXED | MAP_PRIVATE, - .fd = stub_code_fd, - .offset = stub_code_offset - } } }); - n = os_write_file(fd, &mmop, sizeof(mmop)); - if(n != sizeof(mmop)) - panic("map_stub_pages : /proc/mm map for code failed, " - "err = %d\n", -n); - - if ( stack ) { - __u64 map_offset; - int map_fd = phys_mapping(to_phys((void *)stack), &map_offset); - mmop = ((struct proc_mm_op) - { .op = MM_MMAP, - .u = - { .mmap = - { .addr = data, - .len = PAGE_SIZE, - .prot = PROT_READ | PROT_WRITE, - .flags = MAP_FIXED | MAP_SHARED, - .fd = map_fd, - .offset = map_offset - } } }); - n = os_write_file(fd, &mmop, sizeof(mmop)); - if(n != sizeof(mmop)) - panic("map_stub_pages : /proc/mm map for data failed, " - "err = %d\n", -n); - } -} - -void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, - void (*handler)(int)) -{ - unsigned long flags; - sigjmp_buf switch_buf, fork_buf; - - *switch_buf_ptr = &switch_buf; - *fork_buf_ptr = &fork_buf; - - /* Somewhat subtle - siglongjmp restores the signal mask before doing - * the longjmp. This means that when jumping from one stack to another - * when the target stack has interrupts enabled, an interrupt may occur - * on the source stack. This is bad when starting up a process because - * it's not supposed to get timer ticks until it has been scheduled. - * So, we disable interrupts around the sigsetjmp to ensure that - * they can't happen until we get back here where they are safe. - */ - flags = get_signals(); - block_signals(); - if(sigsetjmp(fork_buf, 1) == 0) - new_thread_proc(stack, handler); - - remove_sigstack(); - - set_signals(flags); -} - -void thread_wait(void *sw, void *fb) -{ - sigjmp_buf buf, **switch_buf = sw, *fork_buf; - - *switch_buf = &buf; - fork_buf = fb; - if(sigsetjmp(buf, 1) == 0) - siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); -} - -void switch_threads(void *me, void *next) -{ - sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; - - *me_ptr = &my_buf; - if(sigsetjmp(my_buf, 1) == 0) - siglongjmp(*next_buf, 1); -} - -static sigjmp_buf initial_jmpbuf; - -/* XXX Make these percpu */ -static void (*cb_proc)(void *arg); -static void *cb_arg; -static sigjmp_buf *cb_back; - -int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) -{ - sigjmp_buf **switch_buf = switch_buf_ptr; - int n; - - set_handler(SIGWINCH, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, - SIGVTALRM, -1); - - *fork_buf_ptr = &initial_jmpbuf; - n = sigsetjmp(initial_jmpbuf, 1); - switch(n){ - case INIT_JMP_NEW_THREAD: - new_thread_proc((void *) stack, new_thread_handler); - break; - case INIT_JMP_REMOVE_SIGSTACK: - remove_sigstack(); - break; - case INIT_JMP_CALLBACK: - (*cb_proc)(cb_arg); - siglongjmp(*cb_back, 1); - break; - case INIT_JMP_HALT: - kmalloc_ok = 0; - return(0); - case INIT_JMP_REBOOT: - kmalloc_ok = 0; - return(1); - default: - panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); - } - siglongjmp(**switch_buf, 1); -} - -void initial_thread_cb_skas(void (*proc)(void *), void *arg) -{ - sigjmp_buf here; - - cb_proc = proc; - cb_arg = arg; - cb_back = &here; - - block_signals(); - if(sigsetjmp(here, 1) == 0) - siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK); - unblock_signals(); - - cb_proc = NULL; - cb_arg = NULL; - cb_back = NULL; -} - -void halt_skas(void) -{ - block_signals(); - siglongjmp(initial_jmpbuf, INIT_JMP_HALT); -} - -void reboot_skas(void) -{ - block_signals(); - siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); -} - -void switch_mm_skas(struct mm_id *mm_idp) -{ - int err; - -#warning need cpu pid in switch_mm_skas - if(proc_mm){ - err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, - mm_idp->u.mm_fd); - if(err) - panic("switch_mm_skas - PTRACE_SWITCH_MM failed, " - "errno = %d\n", errno); - } - else userspace_pid[0] = mm_idp->u.pid; -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index e2d3ca445ef..27cdf916442 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -193,6 +193,24 @@ __uml_setup("root=", uml_root_setup, " root=/dev/ubd5\n\n" ); +#ifndef CONFIG_MODE_TT + +static int __init no_skas_debug_setup(char *line, int *add) +{ + printf("'debug' is not necessary to gdb UML in skas mode - run \n"); + printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n"); + printf("doesn't work as expected\n"); + + return 0; +} + +__uml_setup("debug", no_skas_debug_setup, +"debug\n" +" this flag is not needed to run gdb on UML in skas mode\n\n" +); + +#endif + #ifdef CONFIG_SMP static int __init uml_ncpus_setup(char *line, int *add) { diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 52945338b64..87c3aa0252d 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -122,6 +122,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, return(-EINVAL); } *fd_out = ((int *) CMSG_DATA(cmsg))[0]; + os_set_exec_close(*fd_out, 1); return(0); } @@ -137,7 +138,8 @@ static int tuntap_open(void *data) return(err); if(pri->fixed_config){ - pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0); + pri->fd = os_open_file("/dev/net/tun", + of_cloexec(of_rdwr(OPENFLAGS())), 0); if(pri->fd < 0){ printk("Failed to open /dev/net/tun, err = %d\n", -pri->fd); diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 9890e9090f5..fbb080c2fc2 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -60,7 +60,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) multi_count++; - get_safe_registers(regs); + get_safe_registers(regs, NULL); regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 120a21c5883..bbf34cb91ce 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -310,16 +310,12 @@ void userspace(union uml_pt_regs *regs) } } } -#define INIT_JMP_NEW_THREAD 0 -#define INIT_JMP_REMOVE_SIGSTACK 1 -#define INIT_JMP_CALLBACK 2 -#define INIT_JMP_HALT 3 -#define INIT_JMP_REBOOT 4 int copy_context_skas0(unsigned long new_stack, int pid) { int err; - unsigned long regs[MAX_REG_NR]; + unsigned long regs[HOST_FRAME_SIZE]; + unsigned long fp_regs[HOST_FP_SIZE]; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; struct stub_data *child_data = (struct stub_data *) new_stack; @@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) .timer = ((struct itimerval) { { 0, 1000000 / hz() }, { 0, 1000000 / hz() }})}); - get_safe_registers(regs); + get_safe_registers(regs, fp_regs); /* Set parent's instruction pointer to start of clone-stub */ regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + @@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid) panic("copy_context_skas0 : PTRACE_SETREGS failed, " "pid = %d, errno = %d\n", pid, errno); + err = ptrace_setfpregs(pid, fp_regs); + if(err < 0) + panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " + "pid = %d, errno = %d\n", pid, errno); + /* set a well known return code for detection of child write failure */ child_data->err = 12345678; @@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, set_signals(flags); } +#define INIT_JMP_NEW_THREAD 0 +#define INIT_JMP_REMOVE_SIGSTACK 1 +#define INIT_JMP_CALLBACK 2 +#define INIT_JMP_HALT 3 +#define INIT_JMP_REBOOT 4 + void thread_wait(void *sw, void *fb) { sigjmp_buf buf, **switch_buf = sw, *fork_buf; diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 6c5b17ed59e..829d6b0d8b0 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -49,6 +49,7 @@ static int ptrace_child(void *arg) int pid = os_getpid(), ppid = getppid(); int sc_result; + change_sig(SIGWINCH, 0); if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ perror("ptrace"); os_kill_process(pid, 0); diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index aee4812333c..7a6f6b99cef 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -122,9 +122,12 @@ void init_registers(int pid) err); } -void get_safe_registers(unsigned long *regs) +void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); + if(fp_regs != NULL) + memcpy(fp_regs, exec_fp_regs, + HOST_FP_SIZE * sizeof(unsigned long)); } void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 4b638dfb52b..001941fa1a1 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -70,9 +70,12 @@ void init_registers(int pid) err); } -void get_safe_registers(unsigned long *regs) +void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); + if(fp_regs != NULL) + memcpy(fp_regs, exec_fp_regs, + HOST_FP_SIZE * sizeof(unsigned long)); } void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c index 12e404c6fa4..b5f9c33e311 100644 --- a/arch/um/sys-x86_64/ptrace_user.c +++ b/arch/um/sys-x86_64/ptrace_user.c @@ -24,6 +24,13 @@ int ptrace_setregs(long pid, unsigned long *regs) return(0); } +int ptrace_setfpregs(long pid, unsigned long *regs) +{ + if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0) + return -errno; + return 0; +} + void ptrace_pokeuser(unsigned long addr, unsigned long data) { panic("ptrace_pokeuser"); diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 5a585bfbb8c..7bd54a921cf 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -57,7 +57,7 @@ void foo(void) #endif DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); - DEFINE(HOST_FP_SIZE, 0); + DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); DEFINE(HOST_XFP_SIZE, 0); DEFINE_LONGS(HOST_RBX, RBX); DEFINE_LONGS(HOST_RCX, RCX); diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 067c0f47bd0..ada4535d016 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -685,6 +685,9 @@ ia32_sys_call_table: .quad sys_readlinkat /* 305 */ .quad sys_fchmodat .quad sys_faccessat + .quad sys_ni_syscall /* pselect6 for now */ + .quad sys_ni_syscall /* ppoll for now */ + .quad sys_unshare /* 310 */ ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 .quad ni_syscall diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 363db5a003d..9435ab7d6fb 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -94,7 +94,6 @@ unsigned long saved_video_mode; /* * Setup options */ -struct drive_info_struct { char dummy[32]; } drive_info; struct screen_info screen_info; struct sys_desc_table_struct { unsigned short length; @@ -572,7 +571,6 @@ void __init setup_arch(char **cmdline_p) unsigned long kernel_end; ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); - drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; edid_info = EDID_INFO; saved_video_mode = SAVED_VIDEO_MODE; diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index a28756ef7ce..67e4e28f4df 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -59,6 +59,7 @@ #include <asm/nmi.h> #include <asm/irq.h> #include <asm/hw_irq.h> +#include <asm/numa.h> /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -890,6 +891,7 @@ do_rest: if (boot_error) { cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ + clear_node_cpumask(cpu); /* was set by numa_add_cpu */ cpu_clear(cpu, cpu_present_map); cpu_clear(cpu, cpu_possible_map); x86_cpu_to_apicid[cpu] = BAD_APICID; @@ -1187,6 +1189,7 @@ void remove_cpu_from_maps(void) cpu_clear(cpu, cpu_callout_map); cpu_clear(cpu, cpu_callin_map); clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ + clear_node_cpumask(cpu); } int __cpu_disable(void) diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index c0844bffbf8..dba7237be5c 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -748,7 +748,7 @@ static __init int late_hpet_init(void) * Timer0 and Timer1 is used by platform. */ hd.hd_phys_address = vxtime.hpet_address; - hd.hd_address = (void *)fix_to_virt(FIX_HPET_BASE); + hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); hd.hd_nirqs = ntimer; hd.hd_flags = HPET_DATA_PLATFORM; hpet_reserve_timer(&hd, 0); diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index b614d54d2ae..3496abc8d37 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c @@ -39,11 +39,6 @@ extern void __write_lock_failed(rwlock_t *rw); extern void __read_lock_failed(rwlock_t *rw); #endif -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) -extern struct drive_info_struct drive_info; -EXPORT_SYMBOL(drive_info); -#endif - /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); //EXPORT_SYMBOL(dump_fpu); diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b4a3fe4ec24..18f371fe37f 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -49,7 +49,7 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) return pci_mmcfg_virt[0].virt; /* Fall back to type 0 */ - return 0; + return NULL; } static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) diff --git a/block/elevator.c b/block/elevator.c index 2fc269f6972..24b702d649a 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -293,7 +293,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) rq->flags &= ~REQ_STARTED; - __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0); + elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); } static void elv_drain_elevator(request_queue_t *q) @@ -310,41 +310,11 @@ static void elv_drain_elevator(request_queue_t *q) } } -void __elv_add_request(request_queue_t *q, struct request *rq, int where, - int plug) +void elv_insert(request_queue_t *q, struct request *rq, int where) { struct list_head *pos; unsigned ordseq; - if (q->ordcolor) - rq->flags |= REQ_ORDERED_COLOR; - - if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { - /* - * toggle ordered color - */ - if (blk_barrier_rq(rq)) - q->ordcolor ^= 1; - - /* - * barriers implicitly indicate back insertion - */ - if (where == ELEVATOR_INSERT_SORT) - where = ELEVATOR_INSERT_BACK; - - /* - * this request is scheduling boundary, update end_sector - */ - if (blk_fs_request(rq)) { - q->end_sector = rq_end_sector(rq); - q->boundary_rq = rq; - } - } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) - where = ELEVATOR_INSERT_BACK; - - if (plug) - blk_plug_device(q); - rq->q = q; switch (where) { @@ -425,6 +395,42 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, } } +void __elv_add_request(request_queue_t *q, struct request *rq, int where, + int plug) +{ + if (q->ordcolor) + rq->flags |= REQ_ORDERED_COLOR; + + if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { + /* + * toggle ordered color + */ + if (blk_barrier_rq(rq)) + q->ordcolor ^= 1; + + /* + * barriers implicitly indicate back insertion + */ + if (where == ELEVATOR_INSERT_SORT) + where = ELEVATOR_INSERT_BACK; + + /* + * this request is scheduling boundary, update + * end_sector + */ + if (blk_fs_request(rq)) { + q->end_sector = rq_end_sector(rq); + q->boundary_rq = rq; + } + } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) + where = ELEVATOR_INSERT_BACK; + + if (plug) + blk_plug_device(q); + + elv_insert(q, rq, where); +} + void elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index ee5ed98db4c..03d9c82b0fe 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -454,7 +454,7 @@ static void queue_flush(request_queue_t *q, unsigned which) rq->end_io = end_io; q->prepare_flush_fn(q, rq); - __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); + elv_insert(q, rq, ELEVATOR_INSERT_FRONT); } static inline struct request *start_ordered(request_queue_t *q, @@ -490,7 +490,7 @@ static inline struct request *start_ordered(request_queue_t *q, else q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH; - __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); + elv_insert(q, rq, ELEVATOR_INSERT_FRONT); if (q->ordered & QUEUE_ORDERED_PREFLUSH) { queue_flush(q, QUEUE_ORDERED_PREFLUSH); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index cc72210687e..24f7af9d0ab 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -310,6 +310,8 @@ static int sg_io(struct file *file, request_queue_t *q, if (!rq->timeout) rq->timeout = BLK_DEFAULT_TIMEOUT; + rq->retries = 0; + start_time = jiffies; /* ignore return value. All information is passed back to caller @@ -427,6 +429,7 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q, rq->data = buffer; rq->data_len = bytes; rq->flags |= REQ_BLOCK_PC; + rq->retries = 0; blk_execute_rq(q, bd_disk, rq, 0); err = rq->errors & 0xff; /* only 8 bit SCSI status */ diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 47ac90e615f..2953e2cc56f 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c @@ -17,7 +17,6 @@ #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/highmem.h> -#include <asm/bug.h> #include <asm/scatterlist.h> #include "internal.h" #include "scatterwalk.h" diff --git a/drivers/base/base.h b/drivers/base/base.h index e3b548d46cf..5735b38582d 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *); extern void driver_detach(struct device_driver * drv); extern int driver_probe_device(struct device_driver *, struct device *); +extern void sysdev_shutdown(void); +extern int sysdev_suspend(pm_message_t state); +extern int sysdev_resume(void); + static inline struct class_device *to_class_dev(struct kobject *obj) { return container_of(obj, struct class_device, kobj); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 29f6af554e7..c3141565d59 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = { decl_subsys(bus, &ktype_bus, NULL); +#ifdef CONFIG_HOTPLUG + /* Manually detach a device from its associated driver. */ static int driver_helper(struct device *dev, void *data) { @@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv, } static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); +#endif static struct device * next_device(struct klist_iter * i) { diff --git a/drivers/base/memory.c b/drivers/base/memory.c index d1a05224627..105a0d61eb1 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -303,7 +303,7 @@ static int block_size_init(void) */ #ifdef CONFIG_ARCH_MEMORY_PROBE static ssize_t -memory_probe_store(struct class *class, const char __user *buf, size_t count) +memory_probe_store(struct class *class, const char *buf, size_t count) { u64 phys_addr; int ret; diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 0a7aa07b9a2..317edbf0fec 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c @@ -9,10 +9,9 @@ */ #include <linux/device.h> +#include "../base.h" #include "power.h" -extern int sysdev_resume(void); - /** * resume_device - Restore state for one device. diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index c2475f3134e..8826a5b6673 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <asm/semaphore.h> +#include "../base.h" #include "power.h" #define to_dev(node) container_of(node, struct device, kobj.entry) @@ -28,7 +29,6 @@ extern struct subsystem devices_subsys; * they only get one called once when interrupts are disabled. */ -extern int sysdev_shutdown(void); /** * device_shutdown - call ->shutdown() on each device to shutdown. diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 50501764d05..8660779fb28 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c @@ -9,10 +9,9 @@ */ #include <linux/device.h> +#include "../base.h" #include "power.h" -extern int sysdev_suspend(pm_message_t state); - /* * The entries in the dpm_active list are in a depth first order, simply * because children are guaranteed to be discovered after parents, and diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index f3a0c562bcb..40d7242a07c 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -27,22 +27,30 @@ static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) { - return sprintf(buf, "%u\n", dev->power.power_state.event); + if (dev->power.power_state.event) + return sprintf(buf, "2\n"); + else + return sprintf(buf, "0\n"); } static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) { pm_message_t state; - char * rest; - int error = 0; + int error = -EINVAL; - state.event = simple_strtoul(buf, &rest, 10); - if (*rest) - return -EINVAL; - if (state.event) + state.event = PM_EVENT_SUSPEND; + /* Older apps expected to write "3" here - confused with PCI D3 */ + if ((n == 1) && !strcmp(buf, "3")) error = dpm_runtime_suspend(dev, state); - else + + if ((n == 1) && !strcmp(buf, "2")) + error = dpm_runtime_suspend(dev, state); + + if ((n == 1) && !strcmp(buf, "0")) { dpm_runtime_resume(dev); + error = 0; + } + return error ? error : n; } diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 66ed8f2fece..6fc23ab127b 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -21,8 +21,11 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/pm.h> +#include <linux/device.h> #include <asm/semaphore.h> +#include "base.h" + extern struct subsystem devices_subsys; #define to_sysdev(k) container_of(k, struct sys_device, kobj) diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 193446e6a08..e2761725955 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -42,8 +42,6 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> -#include <asm/bug.h> - #include <asm/vio.h> #include <asm/scatterlist.h> #include <asm/iseries/hv_types.h> diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4c67727d75b..05ba410682a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -222,7 +222,7 @@ config SYNCLINKMP config SYNCLINK_GT tristate "SyncLink GT/AC support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && PCI help Support for SyncLink GT and SyncLink AC families of synchronous and asynchronous serial adapters diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 71b8b32b075..107df9fdba4 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -980,7 +980,7 @@ extern int drm_put_head(drm_head_t * head); extern unsigned int drm_debug; extern unsigned int drm_cards_limit; extern drm_head_t **drm_heads; -extern struct drm_sysfs_class *drm_class; +extern struct class *drm_class; extern struct proc_dir_entry *drm_proc_root; /* Proc support (drm_proc.h) */ @@ -1011,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); /* sysfs support (drm_sysfs.c) */ -struct drm_sysfs_class; -extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, - char *name); -extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); -extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, +extern struct class *drm_sysfs_create(struct module *owner, char *name); +extern void drm_sysfs_destroy(struct class *cs); +extern struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head); extern void drm_sysfs_device_remove(struct class_device *class_dev); diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 7a9263ff300..68073e14fde 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c @@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); drm_head_t **drm_heads; -struct drm_sysfs_class *drm_class; +struct class *drm_class; struct proc_dir_entry *drm_proc_root; static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 68e43ddc16a..0b9f98a7eb1 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c @@ -1,3 +1,4 @@ + /* * drm_sysfs.c - Modifications to drm_sysfs_class.c to support * extra sysfs attribute from DRM. Normal drm_sysfs_class @@ -19,36 +20,6 @@ #include "drm_core.h" #include "drmP.h" -struct drm_sysfs_class { - struct class_device_attribute attr; - struct class class; -}; -#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) - -struct simple_dev { - dev_t dev; - struct class_device class_dev; -}; -#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) - -static void release_simple_dev(struct class_device *class_dev) -{ - struct simple_dev *s_dev = to_simple_dev(class_dev); - kfree(s_dev); -} - -static ssize_t show_dev(struct class_device *class_dev, char *buf) -{ - struct simple_dev *s_dev = to_simple_dev(class_dev); - return print_dev_t(buf, s_dev->dev); -} - -static void drm_sysfs_class_release(struct class *class) -{ - struct drm_sysfs_class *cs = to_drm_sysfs_class(class); - kfree(cs); -} - /* Display the version of drm_core. This doesn't work right in current design */ static ssize_t version_show(struct class *dev, char *buf) { @@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); * Note, the pointer created here is to be destroyed when finished by making a * call to drm_sysfs_destroy(). */ -struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) +struct class *drm_sysfs_create(struct module *owner, char *name) { - struct drm_sysfs_class *cs; - int retval; - - cs = kmalloc(sizeof(*cs), GFP_KERNEL); - if (!cs) { - retval = -ENOMEM; - goto error; - } - memset(cs, 0x00, sizeof(*cs)); - - cs->class.name = name; - cs->class.class_release = drm_sysfs_class_release; - cs->class.release = release_simple_dev; - - cs->attr.attr.name = "dev"; - cs->attr.attr.mode = S_IRUGO; - cs->attr.attr.owner = owner; - cs->attr.show = show_dev; - cs->attr.store = NULL; - - retval = class_register(&cs->class); - if (retval) - goto error; - class_create_file(&cs->class, &class_attr_version); - - return cs; - - error: - kfree(cs); - return ERR_PTR(retval); + struct class *class; + + class = class_create(owner, name); + if (!class) + return class; + + class_create_file(class, &class_attr_version); + return class; } /** @@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) * Note, the pointer to be destroyed must have been created with a call to * drm_sysfs_create(). */ -void drm_sysfs_destroy(struct drm_sysfs_class *cs) +void drm_sysfs_destroy(struct class *class) { - if ((cs == NULL) || (IS_ERR(cs))) + if ((class == NULL) || (IS_ERR(class))) return; - class_unregister(&cs->class); + class_remove_file(class, &class_attr_version); + class_destroy(class); } static ssize_t show_dri(struct class_device *class_device, char *buf) @@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = { /** * drm_sysfs_device_add - adds a class device to sysfs for a character driver - * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. + * @cs: pointer to the struct class that this device should be registered to. * @dev: the dev_t for the device to be added. * @device: a pointer to a struct device that is assiociated with this class device. * @fmt: string for the class device's name @@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = { * class. A "dev" file will be created, showing the dev_t for the device. The * pointer to the struct class_device will be returned from the call. Any further * sysfs files that might be required can be created using this pointer. - * Note: the struct drm_sysfs_class passed to this function must have previously been + * Note: the struct class passed to this function must have previously been * created with a call to drm_sysfs_create(). */ -struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, - drm_head_t *head) +struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) { - struct simple_dev *s_dev = NULL; - int i, retval; - - if ((cs == NULL) || (IS_ERR(cs))) { - retval = -ENODEV; - goto error; - } - - s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL); - if (!s_dev) { - retval = -ENOMEM; - goto error; - } - memset(s_dev, 0x00, sizeof(*s_dev)); - - s_dev->dev = MKDEV(DRM_MAJOR, head->minor); - s_dev->class_dev.dev = &(head->dev->pdev)->dev; - s_dev->class_dev.class = &cs->class; + struct class_device *class_dev; + int i; - snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); - retval = class_device_register(&s_dev->class_dev); - if (retval) - goto error; + class_dev = class_device_create(cs, NULL, + MKDEV(DRM_MAJOR, head->minor), + &(head->dev->pdev)->dev, + "card%d", head->minor); + if (!class_dev) + return NULL; - class_device_create_file(&s_dev->class_dev, &cs->attr); - class_set_devdata(&s_dev->class_dev, head); + class_set_devdata(class_dev, head); for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); - return &s_dev->class_dev; - -error: - kfree(s_dev); - return ERR_PTR(retval); + class_device_create_file(class_dev, &class_device_attrs[i]); + return class_dev; } /** @@ -192,10 +122,9 @@ error: */ void drm_sysfs_device_remove(struct class_device *class_dev) { - struct simple_dev *s_dev = to_simple_dev(class_dev); int i; for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); - class_device_unregister(&s_dev->class_dev); + class_device_remove_file(class_dev, &class_device_attrs[i]); + class_device_unregister(class_dev); } diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 80a5b840e22..fee68cc895f 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c @@ -103,6 +103,7 @@ #include <linux/serial.h> #include <linux/generic_serial.h> +#include <linux/tty_flip.h> #include "ser_a2232.h" #include "ser_a2232fw.h" diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index 7a4dfb95d08..837b1ec3ffe 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c @@ -92,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file) return 0; } -static ssize_t epx_c3_write(struct file *file, const char *data, +static ssize_t epx_c3_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { /* Refresh the timer. */ @@ -105,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int options, retval = -EINVAL; + int __user *argp = (void __user *)arg; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, @@ -114,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, - &ident, sizeof(ident))) + if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0,(int *)arg); + return put_user(0, argp); case WDIOC_KEEPALIVE: epx_c3_pet(); return 0; case WDIOC_GETTIMEOUT: - return put_user(WATCHDOG_TIMEOUT,(int *)arg); - case WDIOC_SETOPTIONS: { - if (get_user(options, (int *)arg)) + return put_user(WATCHDOG_TIMEOUT, argp); + case WDIOC_SETOPTIONS: + if (get_user(options, argp)) return -EFAULT; if (options & WDIOS_DISABLECARD) { @@ -141,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, } return retval; - } default: return -ENOIOCTLCMD; } diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 009c08fe5d6..1991f94af75 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -159,7 +159,7 @@ enum i82875p_chips { struct i82875p_pvt { struct pci_dev *ovrfl_pdev; - void *ovrfl_window; + void __iomem *ovrfl_window; }; diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c5829591436..7230d4e0819 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -113,6 +113,16 @@ config SENSORS_DS1621 This driver can also be built as a module. If so, the module will be called ds1621. +config SENSORS_F71805F + tristate "Fintek F71805F/FG" + depends on HWMON && EXPERIMENTAL + help + If you say yes here you get support for hardware monitoring + features of the Fintek F71805F/FG chips. + + This driver can also be built as a module. If so, the module + will be called f71805f. + config SENSORS_FSCHER tristate "FSC Hermes" depends on HWMON && I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 06d4a1d1410..fbdb8d911a7 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o +obj-$(CONFIG_SENSORS_F71805F) += f71805f.o obj-$(CONFIG_SENSORS_FSCHER) += fscher.o obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c new file mode 100644 index 00000000000..e029e0a94ec --- /dev/null +++ b/drivers/hwmon/f71805f.c @@ -0,0 +1,908 @@ +/* + * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated + * hardware monitoring features + * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> + * + * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates + * complete hardware monitoring features: voltage, fan and temperature + * sensors, and manual and automatic fan speed control. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/platform_device.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <asm/io.h> + +static struct platform_device *pdev; + +#define DRVNAME "f71805f" + +/* + * Super-I/O constants and functions + */ + +#define F71805F_LD_HWM 0x04 + +#define SIO_REG_LDSEL 0x07 /* Logical device select */ +#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ +#define SIO_REG_DEVREV 0x22 /* Device revision */ +#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ +#define SIO_REG_ENABLE 0x30 /* Logical device enable */ +#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ + +#define SIO_FINTEK_ID 0x1934 +#define SIO_F71805F_ID 0x0406 + +static inline int +superio_inb(int base, int reg) +{ + outb(reg, base); + return inb(base + 1); +} + +static int +superio_inw(int base, int reg) +{ + int val; + outb(reg++, base); + val = inb(base + 1) << 8; + outb(reg, base); + val |= inb(base + 1); + return val; +} + +static inline void +superio_select(int base, int ld) +{ + outb(SIO_REG_LDSEL, base); + outb(ld, base + 1); +} + +static inline void +superio_enter(int base) +{ + outb(0x87, base); + outb(0x87, base); +} + +static inline void +superio_exit(int base) +{ + outb(0xaa, base); +} + +/* + * ISA constants + */ + +#define REGION_LENGTH 2 +#define ADDR_REG_OFFSET 0 +#define DATA_REG_OFFSET 1 + +static struct resource f71805f_resource __initdata = { + .flags = IORESOURCE_IO, +}; + +/* + * Registers + */ + +/* in nr from 0 to 8 (8-bit values) */ +#define F71805F_REG_IN(nr) (0x10 + (nr)) +#define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr)) +#define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr)) +/* fan nr from 0 to 2 (12-bit values, two registers) */ +#define F71805F_REG_FAN(nr) (0x20 + 2 * (nr)) +#define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr)) +#define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr)) +/* temp nr from 0 to 2 (8-bit values) */ +#define F71805F_REG_TEMP(nr) (0x1B + (nr)) +#define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) +#define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) +#define F71805F_REG_TEMP_MODE 0x01 + +#define F71805F_REG_START 0x00 +/* status nr from 0 to 2 */ +#define F71805F_REG_STATUS(nr) (0x36 + (nr)) + +/* + * Data structures and manipulation thereof + */ + +struct f71805f_data { + unsigned short addr; + const char *name; + struct semaphore lock; + struct class_device *class_dev; + + struct semaphore update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long last_limits; /* In jiffies */ + + /* Register values */ + u8 in[9]; + u8 in_high[9]; + u8 in_low[9]; + u16 fan[3]; + u16 fan_low[3]; + u8 fan_enabled; /* Read once at init time */ + u8 temp[3]; + u8 temp_high[3]; + u8 temp_hyst[3]; + u8 temp_mode; + u8 alarms[3]; +}; + +static inline long in_from_reg(u8 reg) +{ + return (reg * 8); +} + +/* The 2 least significant bits are not used */ +static inline u8 in_to_reg(long val) +{ + if (val <= 0) + return 0; + if (val >= 2016) + return 0xfc; + return (((val + 16) / 32) << 2); +} + +/* in0 is downscaled by a factor 2 internally */ +static inline long in0_from_reg(u8 reg) +{ + return (reg * 16); +} + +static inline u8 in0_to_reg(long val) +{ + if (val <= 0) + return 0; + if (val >= 4032) + return 0xfc; + return (((val + 32) / 64) << 2); +} + +/* The 4 most significant bits are not used */ +static inline long fan_from_reg(u16 reg) +{ + reg &= 0xfff; + if (!reg || reg == 0xfff) + return 0; + return (1500000 / reg); +} + +static inline u16 fan_to_reg(long rpm) +{ + /* If the low limit is set below what the chip can measure, + store the largest possible 12-bit value in the registers, + so that no alarm will ever trigger. */ + if (rpm < 367) + return 0xfff; + return (1500000 / rpm); +} + +static inline long temp_from_reg(u8 reg) +{ + return (reg * 1000); +} + +static inline u8 temp_to_reg(long val) +{ + if (val < 0) + val = 0; + else if (val > 1000 * 0xff) + val = 0xff; + return ((val + 500) / 1000); +} + +/* + * Device I/O access + */ + +static u8 f71805f_read8(struct f71805f_data *data, u8 reg) +{ + u8 val; + + down(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + val = inb(data->addr + DATA_REG_OFFSET); + up(&data->lock); + + return val; +} + +static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) +{ + down(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + outb(val, data->addr + DATA_REG_OFFSET); + up(&data->lock); +} + +/* It is important to read the MSB first, because doing so latches the + value of the LSB, so we are sure both bytes belong to the same value. */ +static u16 f71805f_read16(struct f71805f_data *data, u8 reg) +{ + u16 val; + + down(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + val = inb(data->addr + DATA_REG_OFFSET) << 8; + outb(++reg, data->addr + ADDR_REG_OFFSET); + val |= inb(data->addr + DATA_REG_OFFSET); + up(&data->lock); + + return val; +} + +static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) +{ + down(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + outb(val >> 8, data->addr + DATA_REG_OFFSET); + outb(++reg, data->addr + ADDR_REG_OFFSET); + outb(val & 0xff, data->addr + DATA_REG_OFFSET); + up(&data->lock); +} + +static struct f71805f_data *f71805f_update_device(struct device *dev) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + int nr; + + down(&data->update_lock); + + /* Limit registers cache is refreshed after 60 seconds */ + if (time_after(jiffies, data->last_updated + 60 * HZ) + || !data->valid) { + for (nr = 0; nr < 9; nr++) { + data->in_high[nr] = f71805f_read8(data, + F71805F_REG_IN_HIGH(nr)); + data->in_low[nr] = f71805f_read8(data, + F71805F_REG_IN_LOW(nr)); + } + for (nr = 0; nr < 3; nr++) { + if (data->fan_enabled & (1 << nr)) + data->fan_low[nr] = f71805f_read16(data, + F71805F_REG_FAN_LOW(nr)); + } + for (nr = 0; nr < 3; nr++) { + data->temp_high[nr] = f71805f_read8(data, + F71805F_REG_TEMP_HIGH(nr)); + data->temp_hyst[nr] = f71805f_read8(data, + F71805F_REG_TEMP_HYST(nr)); + } + data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); + + data->last_limits = jiffies; + } + + /* Measurement registers cache is refreshed after 1 second */ + if (time_after(jiffies, data->last_updated + HZ) + || !data->valid) { + for (nr = 0; nr < 9; nr++) { + data->in[nr] = f71805f_read8(data, + F71805F_REG_IN(nr)); + } + for (nr = 0; nr < 3; nr++) { + if (data->fan_enabled & (1 << nr)) + data->fan[nr] = f71805f_read16(data, + F71805F_REG_FAN(nr)); + } + for (nr = 0; nr < 3; nr++) { + data->temp[nr] = f71805f_read8(data, + F71805F_REG_TEMP(nr)); + } + for (nr = 0; nr < 3; nr++) { + data->alarms[nr] = f71805f_read8(data, + F71805F_REG_STATUS(nr)); + } + + data->last_updated = jiffies; + data->valid = 1; + } + + up(&data->update_lock); + + return data; +} + +/* + * Sysfs interface + */ + +static ssize_t show_in0(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + + return sprintf(buf, "%ld\n", in0_from_reg(data->in[0])); +} + +static ssize_t show_in0_max(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + + return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0])); +} + +static ssize_t show_in0_min(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + + return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0])); +} + +static ssize_t set_in0_max(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->in_high[0] = in0_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]); + up(&data->update_lock); + + return count; +} + +static ssize_t set_in0_min(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->in_low[0] = in0_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]); + up(&data->update_lock); + + return count; +} + +static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); +static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); +static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); + +static ssize_t show_in(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", in_from_reg(data->in[nr])); +} + +static ssize_t show_in_max(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr])); +} + +static ssize_t show_in_min(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr])); +} + +static ssize_t set_in_max(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->in_high[nr] = in_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); + up(&data->update_lock); + + return count; +} + +static ssize_t set_in_min(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->in_low[nr] = in_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); + up(&data->update_lock); + + return count; +} + +#define sysfs_in(offset) \ +static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ + show_in, NULL, offset); \ +static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ + show_in_max, set_in_max, offset); \ +static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ + show_in_min, set_in_min, offset) + +sysfs_in(1); +sysfs_in(2); +sysfs_in(3); +sysfs_in(4); +sysfs_in(5); +sysfs_in(6); +sysfs_in(7); +sysfs_in(8); + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr])); +} + +static ssize_t show_fan_min(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); +} + +static ssize_t set_fan_min(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->fan_low[nr] = fan_to_reg(val); + f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); + up(&data->update_lock); + + return count; +} + +#define sysfs_fan(offset) \ +static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ + show_fan, NULL, offset - 1); \ +static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + show_fan_min, set_fan_min, offset - 1) + +sysfs_fan(1); +sysfs_fan(2); +sysfs_fan(3); + +static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr])); +} + +static ssize_t show_temp_max(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr])); +} + +static ssize_t show_temp_hyst(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr])); +} + +static ssize_t show_temp_type(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + + /* 3 is diode, 4 is thermistor */ + return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4); +} + +static ssize_t set_temp_max(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->temp_high[nr] = temp_to_reg(val); + f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]); + up(&data->update_lock); + + return count; +} + +static ssize_t set_temp_hyst(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->temp_hyst[nr] = temp_to_reg(val); + f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]); + up(&data->update_lock); + + return count; +} + +#define sysfs_temp(offset) \ +static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ + show_temp, NULL, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ + show_temp_max, set_temp_max, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ + show_temp_hyst, set_temp_hyst, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO, \ + show_temp_type, NULL, offset - 1) + +sysfs_temp(1); +sysfs_temp(2); +sysfs_temp(3); + +static ssize_t show_alarms_in(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + + return sprintf(buf, "%d\n", data->alarms[0] | + ((data->alarms[1] & 0x01) << 8)); +} + +static ssize_t show_alarms_fan(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + + return sprintf(buf, "%d\n", data->alarms[2] & 0x07); +} + +static ssize_t show_alarms_temp(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + + return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07); +} + +static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL); +static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL); +static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL); + +static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", data->name); +} + +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +/* + * Device registration and initialization + */ + +static void __devinit f71805f_init_device(struct f71805f_data *data) +{ + u8 reg; + int i; + + reg = f71805f_read8(data, F71805F_REG_START); + if ((reg & 0x41) != 0x01) { + printk(KERN_DEBUG DRVNAME ": Starting monitoring " + "operations\n"); + f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); + } + + /* Fan monitoring can be disabled. If it is, we won't be polling + the register values, and won't create the related sysfs files. */ + for (i = 0; i < 3; i++) { + reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i)); + if (!(reg & 0x80)) + data->fan_enabled |= (1 << i); + } +} + +static int __devinit f71805f_probe(struct platform_device *pdev) +{ + struct f71805f_data *data; + struct resource *res; + int err; + + if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { + err = -ENOMEM; + printk(KERN_ERR DRVNAME ": Out of memory\n"); + goto exit; + } + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + data->addr = res->start; + init_MUTEX(&data->lock); + data->name = "f71805f"; + init_MUTEX(&data->update_lock); + + platform_set_drvdata(pdev, data); + + data->class_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + dev_err(&pdev->dev, "Class registration failed (%d)\n", err); + goto exit_free; + } + + /* Initialize the F71805F chip */ + f71805f_init_device(data); + + /* Register sysfs interface files */ + device_create_file(&pdev->dev, &dev_attr_in0_input); + device_create_file(&pdev->dev, &dev_attr_in0_max); + device_create_file(&pdev->dev, &dev_attr_in0_min); + device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr); + if (data->fan_enabled & (1 << 0)) { + device_create_file(&pdev->dev, + &sensor_dev_attr_fan1_input.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_fan1_min.dev_attr); + } + if (data->fan_enabled & (1 << 1)) { + device_create_file(&pdev->dev, + &sensor_dev_attr_fan2_input.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_fan2_min.dev_attr); + } + if (data->fan_enabled & (1 << 2)) { + device_create_file(&pdev->dev, + &sensor_dev_attr_fan3_input.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_fan3_min.dev_attr); + } + device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_temp2_input.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_temp3_input.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_max_hyst.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_temp2_max_hyst.dev_attr); + device_create_file(&pdev->dev, + &sensor_dev_attr_temp3_max_hyst.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr); + device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr); + device_create_file(&pdev->dev, &dev_attr_alarms_in); + device_create_file(&pdev->dev, &dev_attr_alarms_fan); + device_create_file(&pdev->dev, &dev_attr_alarms_temp); + device_create_file(&pdev->dev, &dev_attr_name); + + return 0; + +exit_free: + kfree(data); +exit: + return err; +} + +static int __devexit f71805f_remove(struct platform_device *pdev) +{ + struct f71805f_data *data = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + hwmon_device_unregister(data->class_dev); + kfree(data); + + return 0; +} + +static struct platform_driver f71805f_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRVNAME, + }, + .probe = f71805f_probe, + .remove = __devexit_p(f71805f_remove), +}; + +static int __init f71805f_device_add(unsigned short address) +{ + int err; + + pdev = platform_device_alloc(DRVNAME, address); + if (!pdev) { + err = -ENOMEM; + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); + goto exit; + } + + f71805f_resource.start = address; + f71805f_resource.end = address + REGION_LENGTH - 1; + f71805f_resource.name = pdev->name; + err = platform_device_add_resources(pdev, &f71805f_resource, 1); + if (err) { + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); + goto exit_device_put; + } + + err = platform_device_add(pdev); + if (err) { + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); + goto exit_device_put; + } + + return 0; + +exit_device_put: + platform_device_put(pdev); +exit: + return err; +} + +static int __init f71805f_find(int sioaddr, unsigned short *address) +{ + int err = -ENODEV; + u16 devid; + + superio_enter(sioaddr); + + devid = superio_inw(sioaddr, SIO_REG_MANID); + if (devid != SIO_FINTEK_ID) + goto exit; + + devid = superio_inw(sioaddr, SIO_REG_DEVID); + if (devid != SIO_F71805F_ID) { + printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " + "skipping\n"); + goto exit; + } + + superio_select(sioaddr, F71805F_LD_HWM); + if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { + printk(KERN_WARNING DRVNAME ": Device not activated, " + "skipping\n"); + goto exit; + } + + *address = superio_inw(sioaddr, SIO_REG_ADDR); + if (*address == 0) { + printk(KERN_WARNING DRVNAME ": Base address not set, " + "skipping\n"); + goto exit; + } + + err = 0; + printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", + *address, superio_inb(sioaddr, SIO_REG_DEVREV)); + +exit: + superio_exit(sioaddr); + return err; +} + +static int __init f71805f_init(void) +{ + int err; + unsigned short address; + + if (f71805f_find(0x2e, &address) + && f71805f_find(0x4e, &address)) + return -ENODEV; + + err = platform_driver_register(&f71805f_driver); + if (err) + goto exit; + + /* Sets global pdev as a side effect */ + err = f71805f_device_add(address); + if (err) + goto exit_driver; + + return 0; + +exit_driver: + platform_driver_unregister(&f71805f_driver); +exit: + return err; +} + +static void __exit f71805f_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&f71805f_driver); +} + +MODULE_AUTHOR("Jean Delvare <khali@linux-fr>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("F71805F hardware monitoring driver"); + +module_init(f71805f_init); +module_exit(f71805f_exit); diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 0da7c9c508c..e87d52c5994 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -45,8 +45,7 @@ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; static unsigned short isa_address; /* Insmod parameters */ @@ -830,6 +829,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) if ((err = i2c_attach_client(new_client))) goto ERROR2; + if (!is_isa) + dev_info(&new_client->dev, "The I2C interface to IT87xxF " + "hardware monitoring chips is deprecated. Please " + "report if you still rely on it.\n"); + /* Check PWM configuration */ enable_pwm_interface = it87_check_pwm(new_client); diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index a2f420d01fb..df9e02aaa70 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -87,15 +87,15 @@ static struct i2c_driver lm77_driver = { /* In the temperature registers, the low 3 bits are not part of the temperature values; they are the status bits. */ -static inline u16 LM77_TEMP_TO_REG(int temp) +static inline s16 LM77_TEMP_TO_REG(int temp) { int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); - return (u16)((ntemp / 500) * 8); + return (ntemp / 500) * 8; } -static inline int LM77_TEMP_FROM_REG(u16 reg) +static inline int LM77_TEMP_FROM_REG(s16 reg) { - return ((int)reg / 8) * 500; + return (reg / 8) * 500; } /* sysfs stuff */ diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index b176bf0c4c7..a2f6bb67623 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -303,10 +303,6 @@ struct w83792d_data { static int w83792d_attach_adapter(struct i2c_adapter *adapter); static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); static int w83792d_detach_client(struct i2c_client *client); - -static int w83792d_read_value(struct i2c_client *client, u8 register); -static int w83792d_write_value(struct i2c_client *client, u8 register, - u8 value); static struct w83792d_data *w83792d_update_device(struct device *dev); #ifdef DEBUG @@ -329,6 +325,20 @@ static inline long in_count_from_reg(int nr, struct w83792d_data *data) return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); } +/* The SMBus locks itself. The Winbond W83792D chip has a bank register, + but the driver only accesses registers in bank 0, so we don't have + to switch banks and lock access between switches. */ +static inline int w83792d_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static inline int +w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + /* following are the sysfs callback functions */ static ssize_t show_in(struct device *dev, struct device_attribute *attr, char *buf) @@ -1386,19 +1396,6 @@ w83792d_detach_client(struct i2c_client *client) return 0; } -/* The SMBus locks itself. The Winbond W83792D chip has a bank register, - but the driver only accesses registers in bank 0, so we don't have - to switch banks and lock access between switches. */ -static int w83792d_read_value(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - static void w83792d_init_client(struct i2c_client *client) { diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 938848ae162..3df3f09995c 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c @@ -202,7 +202,7 @@ EXPORT_SYMBOL(i2c_sibyte_del_bus); #ifdef MODULE MODULE_AUTHOR("Kip Walker, Broadcom Corp."); MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); -MODULE_PARM(bit_scan, "i"); +module_param(bit_scan, int, 0); MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 08d5b8fed2d..ff92735c7c8 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -124,6 +124,7 @@ config I2C_I801 ICH6 ICH7 ESB2 + ICH8 This driver can also be built as a module. If so, the module will be called i2c-i801. diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1c752ddc10e..8e0f3158215 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -32,6 +32,7 @@ ICH6 266A ICH7 27DA ESB2 269B + ICH8 283E This driver supports several versions of Intel's I/O Controller Hubs (ICH). For SMBus support, they are similar to the PIIX4 and are part of Intel's '810' and other chipsets. @@ -527,6 +528,7 @@ static struct pci_device_id i801_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, { 0, } }; diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index 3e5eba9fcac..c63025a4c86 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c @@ -121,14 +121,11 @@ static struct i2c_adapter parport_adapter = { static int __init i2c_parport_init(void) { - int type_count; - - type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); - if (type < 0 || type >= type_count) { + if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); type = 0; } - + if (base == 0) { printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); base = DEFAULT_BASE; @@ -152,7 +149,7 @@ static int __init i2c_parport_init(void) release_region(base, 3); return -ENODEV; } - + return 0; } diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 2854d858fc9..7e2e8cd1c14 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -241,14 +241,11 @@ static struct parport_driver i2c_parport_driver = { static int __init i2c_parport_init(void) { - int type_count; - - type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); - if (type < 0 || type >= type_count) { + if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); type = 0; } - + return parport_register_driver(&i2c_parport_driver); } diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 86e2234faf8..7579f4b256a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -861,7 +861,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *r decode_ISR(isr); } - if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32)) + if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog)) i2c->isrlog[i2c->irqlogidx++] = isr; show_state(i2c); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0ce58b50604..1a2c9ab5d9e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -946,6 +946,20 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val } } +s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, + u8 length, u8 *values) +{ + union i2c_smbus_data data; + + if (length > I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; + data.block[0] = length; + memcpy(data.block + 1, values, length); + return i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_WRITE, command, + I2C_SMBUS_I2C_BLOCK_DATA, &data); +} + /* Simulate a SMBus command using the i2c protocol No checking of parameters is done! */ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, @@ -1150,6 +1164,7 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data); EXPORT_SYMBOL(i2c_smbus_write_word_data); EXPORT_SYMBOL(i2c_smbus_write_block_data); EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); +EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C-Bus main module"); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 6c60a9d2afd..09086b8b648 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -190,7 +190,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, if (lba48) { task_ioreg_t tasklets[10]; - pr_debug("%s: LBA=0x%012llx\n", drive->name, block); + pr_debug("%s: LBA=0x%012llx\n", drive->name, + (unsigned long long)block); tasklets[0] = 0; tasklets[1] = 0; @@ -317,7 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", drive->name, rq_data_dir(rq) == READ ? "read" : "writ", - block, rq->nr_sectors, (unsigned long)rq->buffer); + (unsigned long long)block, rq->nr_sectors, + (unsigned long)rq->buffer); if (hwif->rw_disk) hwif->rw_disk(drive, rq); diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index e95c4293a49..f6a05965a4e 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -1319,15 +1319,6 @@ static struct class ucm_class = { .release = ib_ucm_release_class_dev }; -static ssize_t show_dev(struct class_device *class_dev, char *buf) -{ - struct ib_ucm_device *dev; - - dev = container_of(class_dev, struct ib_ucm_device, class_dev); - return print_dev_t(buf, dev->dev.dev); -} -static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); - static ssize_t show_ibdev(struct class_device *class_dev, char *buf) { struct ib_ucm_device *dev; @@ -1364,15 +1355,13 @@ static void ib_ucm_add_one(struct ib_device *device) ucm_dev->class_dev.class = &ucm_class; ucm_dev->class_dev.dev = device->dma_device; + ucm_dev->class_dev.devt = ucm_dev->dev.dev; snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", ucm_dev->devnum); if (class_device_register(&ucm_dev->class_dev)) goto err_cdev; if (class_device_create_file(&ucm_dev->class_dev, - &class_device_attr_dev)) - goto err_class; - if (class_device_create_file(&ucm_dev->class_dev, &class_device_attr_ibdev)) goto err_class; diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 0ef560144be..6dfc94122dd 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -351,7 +351,7 @@ config HISAX_ENTERNOW_PCI config HISAX_AMD7930 bool "Am7930 (EXPERIMENTAL)" - depends on EXPERIMENTAL && SPARC + depends on EXPERIMENTAL && SPARC && BROKEN help This enables HiSax support for the AMD7930 chips on some SPARCs. This code is not finished yet. diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 7d4a0ac28c0..12ad462737b 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -187,6 +187,14 @@ config WINDFARM_PM91 This driver provides thermal control for the PowerMac9,1 which is the recent (SMU based) single CPU desktop G5 +config WINDFARM_PM112 + tristate "Support for thermal management on PowerMac11,2" + depends on WINDFARM && I2C && PMAC_SMU + select I2C_POWERMAC + help + This driver provides thermal control for the PowerMac11,2 + which are the recent dual and quad G5 machines using the + 970MP dual-core processor. config ANSLCD tristate "Support for ANS LCD display" diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index f4657aa81fb..6081acdea40 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -35,3 +35,8 @@ obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \ windfarm_smu_sensors.o \ windfarm_lm75_sensor.o windfarm_pid.o \ windfarm_cpufreq_clamp.o windfarm_pm91.o +obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ + windfarm_smu_controls.o \ + windfarm_smu_sensors.o \ + windfarm_max6690_sensor.o \ + windfarm_lm75_sensor.o windfarm_pid.o diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index 3f0cb0312ea..7a2482cc26a 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h @@ -14,6 +14,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/notifier.h> +#include <linux/device.h> /* Display a 16.16 fixed point value */ #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) @@ -39,6 +40,7 @@ struct wf_control { char *name; int type; struct kref ref; + struct device_attribute attr; }; #define WF_CONTROL_TYPE_GENERIC 0 @@ -87,6 +89,7 @@ struct wf_sensor { struct wf_sensor_ops *ops; char *name; struct kref ref; + struct device_attribute attr; }; /* Same lifetime rules as controls */ diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 6c2a471ea6c..bb8d5efe19b 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -33,6 +33,7 @@ #include <linux/reboot.h> #include <linux/device.h> #include <linux/platform_device.h> +#include <linux/mutex.h> #include "windfarm.h" @@ -48,13 +49,17 @@ static LIST_HEAD(wf_controls); static LIST_HEAD(wf_sensors); -static DECLARE_MUTEX(wf_lock); +static DEFINE_MUTEX(wf_lock); static struct notifier_block *wf_client_list; static int wf_client_count; static unsigned int wf_overtemp; static unsigned int wf_overtemp_counter; struct task_struct *wf_thread; +static struct platform_device wf_platform_device = { + .name = "windfarm", +}; + /* * Utilities & tick thread */ @@ -156,26 +161,67 @@ static void wf_control_release(struct kref *kref) kfree(ct); } +static ssize_t wf_show_control(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct wf_control *ctrl = container_of(attr, struct wf_control, attr); + s32 val = 0; + int err; + + err = ctrl->ops->get_value(ctrl, &val); + if (err < 0) + return err; + return sprintf(buf, "%d\n", val); +} + +/* This is really only for debugging... */ +static ssize_t wf_store_control(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct wf_control *ctrl = container_of(attr, struct wf_control, attr); + int val; + int err; + char *endp; + + val = simple_strtoul(buf, &endp, 0); + while (endp < buf + count && (*endp == ' ' || *endp == '\n')) + ++endp; + if (endp - buf < count) + return -EINVAL; + err = ctrl->ops->set_value(ctrl, val); + if (err < 0) + return err; + return count; +} + int wf_register_control(struct wf_control *new_ct) { struct wf_control *ct; - down(&wf_lock); + mutex_lock(&wf_lock); list_for_each_entry(ct, &wf_controls, link) { if (!strcmp(ct->name, new_ct->name)) { printk(KERN_WARNING "windfarm: trying to register" " duplicate control %s\n", ct->name); - up(&wf_lock); + mutex_unlock(&wf_lock); return -EEXIST; } } kref_init(&new_ct->ref); list_add(&new_ct->link, &wf_controls); + new_ct->attr.attr.name = new_ct->name; + new_ct->attr.attr.owner = THIS_MODULE; + new_ct->attr.attr.mode = 0644; + new_ct->attr.show = wf_show_control; + new_ct->attr.store = wf_store_control; + device_create_file(&wf_platform_device.dev, &new_ct->attr); + DBG("wf: Registered control %s\n", new_ct->name); wf_notify(WF_EVENT_NEW_CONTROL, new_ct); - up(&wf_lock); + mutex_unlock(&wf_lock); return 0; } @@ -183,9 +229,9 @@ EXPORT_SYMBOL_GPL(wf_register_control); void wf_unregister_control(struct wf_control *ct) { - down(&wf_lock); + mutex_lock(&wf_lock); list_del(&ct->link); - up(&wf_lock); + mutex_unlock(&wf_lock); DBG("wf: Unregistered control %s\n", ct->name); @@ -197,16 +243,16 @@ struct wf_control * wf_find_control(const char *name) { struct wf_control *ct; - down(&wf_lock); + mutex_lock(&wf_lock); list_for_each_entry(ct, &wf_controls, link) { if (!strcmp(ct->name, name)) { if (wf_get_control(ct)) ct = NULL; - up(&wf_lock); + mutex_unlock(&wf_lock); return ct; } } - up(&wf_lock); + mutex_unlock(&wf_lock); return NULL; } EXPORT_SYMBOL_GPL(wf_find_control); @@ -246,26 +292,46 @@ static void wf_sensor_release(struct kref *kref) kfree(sr); } +static ssize_t wf_show_sensor(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr); + s32 val = 0; + int err; + + err = sens->ops->get_value(sens, &val); + if (err < 0) + return err; + return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val)); +} + int wf_register_sensor(struct wf_sensor *new_sr) { struct wf_sensor *sr; - down(&wf_lock); + mutex_lock(&wf_lock); list_for_each_entry(sr, &wf_sensors, link) { if (!strcmp(sr->name, new_sr->name)) { printk(KERN_WARNING "windfarm: trying to register" " duplicate sensor %s\n", sr->name); - up(&wf_lock); + mutex_unlock(&wf_lock); return -EEXIST; } } kref_init(&new_sr->ref); list_add(&new_sr->link, &wf_sensors); + new_sr->attr.attr.name = new_sr->name; + new_sr->attr.attr.owner = THIS_MODULE; + new_sr->attr.attr.mode = 0444; + new_sr->attr.show = wf_show_sensor; + new_sr->attr.store = NULL; + device_create_file(&wf_platform_device.dev, &new_sr->attr); + DBG("wf: Registered sensor %s\n", new_sr->name); wf_notify(WF_EVENT_NEW_SENSOR, new_sr); - up(&wf_lock); + mutex_unlock(&wf_lock); return 0; } @@ -273,9 +339,9 @@ EXPORT_SYMBOL_GPL(wf_register_sensor); void wf_unregister_sensor(struct wf_sensor *sr) { - down(&wf_lock); + mutex_lock(&wf_lock); list_del(&sr->link); - up(&wf_lock); + mutex_unlock(&wf_lock); DBG("wf: Unregistered sensor %s\n", sr->name); @@ -287,16 +353,16 @@ struct wf_sensor * wf_find_sensor(const char *name) { struct wf_sensor *sr; - down(&wf_lock); + mutex_lock(&wf_lock); list_for_each_entry(sr, &wf_sensors, link) { if (!strcmp(sr->name, name)) { if (wf_get_sensor(sr)) sr = NULL; - up(&wf_lock); + mutex_unlock(&wf_lock); return sr; } } - up(&wf_lock); + mutex_unlock(&wf_lock); return NULL; } EXPORT_SYMBOL_GPL(wf_find_sensor); @@ -329,7 +395,7 @@ int wf_register_client(struct notifier_block *nb) struct wf_control *ct; struct wf_sensor *sr; - down(&wf_lock); + mutex_lock(&wf_lock); rc = notifier_chain_register(&wf_client_list, nb); if (rc != 0) goto bail; @@ -341,19 +407,19 @@ int wf_register_client(struct notifier_block *nb) if (wf_client_count == 1) wf_start_thread(); bail: - up(&wf_lock); + mutex_unlock(&wf_lock); return rc; } EXPORT_SYMBOL_GPL(wf_register_client); int wf_unregister_client(struct notifier_block *nb) { - down(&wf_lock); + mutex_lock(&wf_lock); notifier_chain_unregister(&wf_client_list, nb); wf_client_count++; if (wf_client_count == 0) wf_stop_thread(); - up(&wf_lock); + mutex_unlock(&wf_lock); return 0; } @@ -361,23 +427,23 @@ EXPORT_SYMBOL_GPL(wf_unregister_client); void wf_set_overtemp(void) { - down(&wf_lock); + mutex_lock(&wf_lock); wf_overtemp++; if (wf_overtemp == 1) { printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); wf_overtemp_counter = 0; wf_notify(WF_EVENT_OVERTEMP, NULL); } - up(&wf_lock); + mutex_unlock(&wf_lock); } EXPORT_SYMBOL_GPL(wf_set_overtemp); void wf_clear_overtemp(void) { - down(&wf_lock); + mutex_lock(&wf_lock); WARN_ON(wf_overtemp == 0); if (wf_overtemp == 0) { - up(&wf_lock); + mutex_unlock(&wf_lock); return; } wf_overtemp--; @@ -385,7 +451,7 @@ void wf_clear_overtemp(void) printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); wf_notify(WF_EVENT_NORMALTEMP, NULL); } - up(&wf_lock); + mutex_unlock(&wf_lock); } EXPORT_SYMBOL_GPL(wf_clear_overtemp); @@ -395,10 +461,6 @@ int wf_is_overtemp(void) } EXPORT_SYMBOL_GPL(wf_is_overtemp); -static struct platform_device wf_platform_device = { - .name = "windfarm", -}; - static int __init windfarm_core_init(void) { DBG("wf: core loaded\n"); diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c new file mode 100644 index 00000000000..5b9ad6ca7cb --- /dev/null +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -0,0 +1,169 @@ +/* + * Windfarm PowerMac thermal control. MAX6690 sensor. + * + * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> + * + * Use and redistribute under the terms of the GNU GPL v2. + */ +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/i2c-dev.h> +#include <asm/prom.h> +#include <asm/pmac_low_i2c.h> + +#include "windfarm.h" + +#define VERSION "0.1" + +/* This currently only exports the external temperature sensor, + since that's all the control loops need. */ + +/* Some MAX6690 register numbers */ +#define MAX6690_INTERNAL_TEMP 0 +#define MAX6690_EXTERNAL_TEMP 1 + +struct wf_6690_sensor { + struct i2c_client i2c; + struct wf_sensor sens; +}; + +#define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) +#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) + +static int wf_max6690_attach(struct i2c_adapter *adapter); +static int wf_max6690_detach(struct i2c_client *client); + +static struct i2c_driver wf_max6690_driver = { + .driver = { + .name = "wf_max6690", + }, + .attach_adapter = wf_max6690_attach, + .detach_client = wf_max6690_detach, +}; + +static int wf_max6690_get(struct wf_sensor *sr, s32 *value) +{ + struct wf_6690_sensor *max = wf_to_6690(sr); + s32 data; + + if (max->i2c.adapter == NULL) + return -ENODEV; + + /* chip gets initialized by firmware */ + data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); + if (data < 0) + return data; + *value = data << 16; + return 0; +} + +static void wf_max6690_release(struct wf_sensor *sr) +{ + struct wf_6690_sensor *max = wf_to_6690(sr); + + if (max->i2c.adapter) { + i2c_detach_client(&max->i2c); + max->i2c.adapter = NULL; + } + kfree(max); +} + +static struct wf_sensor_ops wf_max6690_ops = { + .get_value = wf_max6690_get, + .release = wf_max6690_release, + .owner = THIS_MODULE, +}; + +static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) +{ + struct wf_6690_sensor *max; + char *name = "u4-temp"; + + max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); + if (max == NULL) { + printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " + "no memory\n", name); + return; + } + + max->sens.ops = &wf_max6690_ops; + max->sens.name = name; + max->i2c.addr = addr >> 1; + max->i2c.adapter = adapter; + max->i2c.driver = &wf_max6690_driver; + strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); + + if (i2c_attach_client(&max->i2c)) { + printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); + goto fail; + } + + if (wf_register_sensor(&max->sens)) { + i2c_detach_client(&max->i2c); + goto fail; + } + + return; + + fail: + kfree(max); +} + +static int wf_max6690_attach(struct i2c_adapter *adapter) +{ + struct device_node *busnode, *dev = NULL; + struct pmac_i2c_bus *bus; + const char *loc; + u32 *reg; + + bus = pmac_i2c_adapter_to_bus(adapter); + if (bus == NULL) + return -ENODEV; + busnode = pmac_i2c_get_bus_node(bus); + + while ((dev = of_get_next_child(busnode, dev)) != NULL) { + if (!device_is_compatible(dev, "max6690")) + continue; + loc = get_property(dev, "hwsensor-location", NULL); + reg = (u32 *) get_property(dev, "reg", NULL); + if (!loc || !reg) + continue; + printk("found max6690, loc=%s reg=%x\n", loc, *reg); + if (strcmp(loc, "BACKSIDE")) + continue; + wf_max6690_create(adapter, *reg); + } + + return 0; +} + +static int wf_max6690_detach(struct i2c_client *client) +{ + struct wf_6690_sensor *max = i2c_to_6690(client); + + max->i2c.adapter = NULL; + wf_unregister_sensor(&max->sens); + + return 0; +} + +static int __init wf_max6690_sensor_init(void) +{ + return i2c_add_driver(&wf_max6690_driver); +} + +static void __exit wf_max6690_sensor_exit(void) +{ + i2c_del_driver(&wf_max6690_driver); +} + +module_init(wf_max6690_sensor_init); +module_exit(wf_max6690_sensor_exit); + +MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); +MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control"); +MODULE_LICENSE("GPL"); diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c index 2e803b36875..0842432e27a 100644 --- a/drivers/macintosh/windfarm_pid.c +++ b/drivers/macintosh/windfarm_pid.c @@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init); s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) { - s64 error, integ, deriv, prop; - s32 target, sval, adj; + s64 integ, deriv, prop; + s32 error, target, sval, adj; int i, hlen = st->param.history_len; /* Calculate error term */ @@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) integ += st->errors[(st->index + hlen - i) % hlen]; integ *= st->param.interval; integ *= st->param.gr; - sval = st->param.tmax - ((integ >> 20) & 0xffffffff); + sval = st->param.tmax - (s32)(integ >> 20); adj = min(st->param.ttarget, sval); DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); @@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) deriv *= st->param.gd; /* Calculate proportional term */ - prop = (new_temp - adj); + prop = st->last_delta = (new_temp - adj); prop *= st->param.gp; DBG("deriv: %lx, prop: %lx\n", deriv, prop); diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h index a364c2a2499..bbccc22d42b 100644 --- a/drivers/macintosh/windfarm_pid.h +++ b/drivers/macintosh/windfarm_pid.h @@ -72,6 +72,7 @@ struct wf_cpu_pid_state { int index; /* index of current power */ int tindex; /* index of current temp */ s32 target; /* current target value */ + s32 last_delta; /* last Tactual - Ttarget */ s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ s32 temps[2]; /* temp. history buffer */ diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c new file mode 100644 index 00000000000..c2a4e689c78 --- /dev/null +++ b/drivers/macintosh/windfarm_pm112.c @@ -0,0 +1,698 @@ +/* + * Windfarm PowerMac thermal control. + * Control loops for machines with SMU and PPC970MP processors. + * + * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. + * + * Use and redistribute under the terms of the GNU GPL v2. + */ +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/reboot.h> +#include <asm/prom.h> +#include <asm/smu.h> + +#include "windfarm.h" +#include "windfarm_pid.h" + +#define VERSION "0.2" + +#define DEBUG +#undef LOTSA_DEBUG + +#ifdef DEBUG +#define DBG(args...) printk(args) +#else +#define DBG(args...) do { } while(0) +#endif + +#ifdef LOTSA_DEBUG +#define DBG_LOTS(args...) printk(args) +#else +#define DBG_LOTS(args...) do { } while(0) +#endif + +/* define this to force CPU overtemp to 60 degree, useful for testing + * the overtemp code + */ +#undef HACKED_OVERTEMP + +/* We currently only handle 2 chips, 4 cores... */ +#define NR_CHIPS 2 +#define NR_CORES 4 +#define NR_CPU_FANS 3 * NR_CHIPS + +/* Controls and sensors */ +static struct wf_sensor *sens_cpu_temp[NR_CORES]; +static struct wf_sensor *sens_cpu_power[NR_CORES]; +static struct wf_sensor *hd_temp; +static struct wf_sensor *slots_power; +static struct wf_sensor *u4_temp; + +static struct wf_control *cpu_fans[NR_CPU_FANS]; +static char *cpu_fan_names[NR_CPU_FANS] = { + "cpu-rear-fan-0", + "cpu-rear-fan-1", + "cpu-front-fan-0", + "cpu-front-fan-1", + "cpu-pump-0", + "cpu-pump-1", +}; +static struct wf_control *cpufreq_clamp; + +/* Second pump isn't required (and isn't actually present) */ +#define CPU_FANS_REQD (NR_CPU_FANS - 2) +#define FIRST_PUMP 4 +#define LAST_PUMP 5 + +/* We keep a temperature history for average calculation of 180s */ +#define CPU_TEMP_HIST_SIZE 180 + +/* Scale factor for fan speed, *100 */ +static int cpu_fan_scale[NR_CPU_FANS] = { + 100, + 100, + 97, /* inlet fans run at 97% of exhaust fan */ + 97, + 100, /* updated later */ + 100, /* updated later */ +}; + +static struct wf_control *backside_fan; +static struct wf_control *slots_fan; +static struct wf_control *drive_bay_fan; + +/* PID loop state */ +static struct wf_cpu_pid_state cpu_pid[NR_CORES]; +static u32 cpu_thist[CPU_TEMP_HIST_SIZE]; +static int cpu_thist_pt; +static s64 cpu_thist_total; +static s32 cpu_all_tmax = 100 << 16; +static int cpu_last_target; +static struct wf_pid_state backside_pid; +static int backside_tick; +static struct wf_pid_state slots_pid; +static int slots_started; +static struct wf_pid_state drive_bay_pid; +static int drive_bay_tick; + +static int nr_cores; +static int have_all_controls; +static int have_all_sensors; +static int started; + +static int failure_state; +#define FAILURE_SENSOR 1 +#define FAILURE_FAN 2 +#define FAILURE_PERM 4 +#define FAILURE_LOW_OVERTEMP 8 +#define FAILURE_HIGH_OVERTEMP 16 + +/* Overtemp values */ +#define LOW_OVER_AVERAGE 0 +#define LOW_OVER_IMMEDIATE (10 << 16) +#define LOW_OVER_CLEAR ((-10) << 16) +#define HIGH_OVER_IMMEDIATE (14 << 16) +#define HIGH_OVER_AVERAGE (10 << 16) +#define HIGH_OVER_IMMEDIATE (14 << 16) + + +/* Implementation... */ +static int create_cpu_loop(int cpu) +{ + int chip = cpu / 2; + int core = cpu & 1; + struct smu_sdbp_header *hdr; + struct smu_sdbp_cpupiddata *piddata; + struct wf_cpu_pid_param pid; + struct wf_control *main_fan = cpu_fans[0]; + s32 tmax; + int fmin; + + /* Get PID params from the appropriate SAT */ + hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); + if (hdr == NULL) { + printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); + return -EINVAL; + } + piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; + + /* Get FVT params to get Tmax; if not found, assume default */ + hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); + if (hdr) { + struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1]; + tmax = fvt->maxtemp << 16; + } else + tmax = 95 << 16; /* default to 95 degrees C */ + + /* We keep a global tmax for overtemp calculations */ + if (tmax < cpu_all_tmax) + cpu_all_tmax = tmax; + + /* + * Darwin has a minimum fan speed of 1000 rpm for the 4-way and + * 515 for the 2-way. That appears to be overkill, so for now, + * impose a minimum of 750 or 515. + */ + fmin = (nr_cores > 2) ? 750 : 515; + + /* Initialize PID loop */ + pid.interval = 1; /* seconds */ + pid.history_len = piddata->history_len; + pid.gd = piddata->gd; + pid.gp = piddata->gp; + pid.gr = piddata->gr / piddata->history_len; + pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8); + pid.ttarget = tmax - (piddata->target_temp_delta << 16); + pid.tmax = tmax; + pid.min = main_fan->ops->get_min(main_fan); + pid.max = main_fan->ops->get_max(main_fan); + if (pid.min < fmin) + pid.min = fmin; + + wf_cpu_pid_init(&cpu_pid[cpu], &pid); + return 0; +} + +static void cpu_max_all_fans(void) +{ + int i; + + /* We max all CPU fans in case of a sensor error. We also do the + * cpufreq clamping now, even if it's supposedly done later by the + * generic code anyway, we do it earlier here to react faster + */ + if (cpufreq_clamp) + wf_control_set_max(cpufreq_clamp); + for (i = 0; i < NR_CPU_FANS; ++i) + if (cpu_fans[i]) + wf_control_set_max(cpu_fans[i]); +} + +static int cpu_check_overtemp(s32 temp) +{ + int new_state = 0; + s32 t_avg, t_old; + + /* First check for immediate overtemps */ + if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) { + new_state |= FAILURE_LOW_OVERTEMP; + if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) + printk(KERN_ERR "windfarm: Overtemp due to immediate CPU" + " temperature !\n"); + } + if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) { + new_state |= FAILURE_HIGH_OVERTEMP; + if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) + printk(KERN_ERR "windfarm: Critical overtemp due to" + " immediate CPU temperature !\n"); + } + + /* We calculate a history of max temperatures and use that for the + * overtemp management + */ + t_old = cpu_thist[cpu_thist_pt]; + cpu_thist[cpu_thist_pt] = temp; + cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE; + cpu_thist_total -= t_old; + cpu_thist_total += temp; + t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE; + + DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n", + FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp)); + + /* Now check for average overtemps */ + if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) { + new_state |= FAILURE_LOW_OVERTEMP; + if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) + printk(KERN_ERR "windfarm: Overtemp due to average CPU" + " temperature !\n"); + } + if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) { + new_state |= FAILURE_HIGH_OVERTEMP; + if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) + printk(KERN_ERR "windfarm: Critical overtemp due to" + " average CPU temperature !\n"); + } + + /* Now handle overtemp conditions. We don't currently use the windfarm + * overtemp handling core as it's not fully suited to the needs of those + * new machine. This will be fixed later. + */ + if (new_state) { + /* High overtemp -> immediate shutdown */ + if (new_state & FAILURE_HIGH_OVERTEMP) + machine_power_off(); + if ((failure_state & new_state) != new_state) + cpu_max_all_fans(); + failure_state |= new_state; + } else if ((failure_state & FAILURE_LOW_OVERTEMP) && + (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) { + printk(KERN_ERR "windfarm: Overtemp condition cleared !\n"); + failure_state &= ~FAILURE_LOW_OVERTEMP; + } + + return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP); +} + +static void cpu_fans_tick(void) +{ + int err, cpu; + s32 greatest_delta = 0; + s32 temp, power, t_max = 0; + int i, t, target = 0; + struct wf_sensor *sr; + struct wf_control *ct; + struct wf_cpu_pid_state *sp; + + DBG_LOTS(KERN_DEBUG); + for (cpu = 0; cpu < nr_cores; ++cpu) { + /* Get CPU core temperature */ + sr = sens_cpu_temp[cpu]; + err = sr->ops->get_value(sr, &temp); + if (err) { + DBG("\n"); + printk(KERN_WARNING "windfarm: CPU %d temperature " + "sensor error %d\n", cpu, err); + failure_state |= FAILURE_SENSOR; + cpu_max_all_fans(); + return; + } + + /* Keep track of highest temp */ + t_max = max(t_max, temp); + + /* Get CPU power */ + sr = sens_cpu_power[cpu]; + err = sr->ops->get_value(sr, &power); + if (err) { + DBG("\n"); + printk(KERN_WARNING "windfarm: CPU %d power " + "sensor error %d\n", cpu, err); + failure_state |= FAILURE_SENSOR; + cpu_max_all_fans(); + return; + } + + /* Run PID */ + sp = &cpu_pid[cpu]; + t = wf_cpu_pid_run(sp, power, temp); + + if (cpu == 0 || sp->last_delta > greatest_delta) { + greatest_delta = sp->last_delta; + target = t; + } + DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ", + cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp)); + } + DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max)); + + /* Darwin limits decrease to 20 per iteration */ + if (target < (cpu_last_target - 20)) + target = cpu_last_target - 20; + cpu_last_target = target; + for (cpu = 0; cpu < nr_cores; ++cpu) + cpu_pid[cpu].target = target; + + /* Handle possible overtemps */ + if (cpu_check_overtemp(t_max)) + return; + + /* Set fans */ + for (i = 0; i < NR_CPU_FANS; ++i) { + ct = cpu_fans[i]; + if (ct == NULL) + continue; + err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100); + if (err) { + printk(KERN_WARNING "windfarm: fan %s reports " + "error %d\n", ct->name, err); + failure_state |= FAILURE_FAN; + break; + } + } +} + +/* Backside/U4 fan */ +static struct wf_pid_param backside_param = { + .interval = 5, + .history_len = 2, + .gd = 48 << 20, + .gp = 5 << 20, + .gr = 0, + .itarget = 64 << 16, + .additive = 1, +}; + +static void backside_fan_tick(void) +{ + s32 temp; + int speed; + int err; + + if (!backside_fan || !u4_temp) + return; + if (!backside_tick) { + /* first time; initialize things */ + backside_param.min = backside_fan->ops->get_min(backside_fan); + backside_param.max = backside_fan->ops->get_max(backside_fan); + wf_pid_init(&backside_pid, &backside_param); + backside_tick = 1; + } + if (--backside_tick > 0) + return; + backside_tick = backside_pid.param.interval; + + err = u4_temp->ops->get_value(u4_temp, &temp); + if (err) { + printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n", + err); + failure_state |= FAILURE_SENSOR; + wf_control_set_max(backside_fan); + return; + } + speed = wf_pid_run(&backside_pid, temp); + DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n", + FIX32TOPRINT(temp), speed); + + err = backside_fan->ops->set_value(backside_fan, speed); + if (err) { + printk(KERN_WARNING "windfarm: backside fan error %d\n", err); + failure_state |= FAILURE_FAN; + } +} + +/* Drive bay fan */ +static struct wf_pid_param drive_bay_prm = { + .interval = 5, + .history_len = 2, + .gd = 30 << 20, + .gp = 5 << 20, + .gr = 0, + .itarget = 40 << 16, + .additive = 1, +}; + +static void drive_bay_fan_tick(void) +{ + s32 temp; + int speed; + int err; + + if (!drive_bay_fan || !hd_temp) + return; + if (!drive_bay_tick) { + /* first time; initialize things */ + drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan); + drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan); + wf_pid_init(&drive_bay_pid, &drive_bay_prm); + drive_bay_tick = 1; + } + if (--drive_bay_tick > 0) + return; + drive_bay_tick = drive_bay_pid.param.interval; + + err = hd_temp->ops->get_value(hd_temp, &temp); + if (err) { + printk(KERN_WARNING "windfarm: drive bay temp sensor " + "error %d\n", err); + failure_state |= FAILURE_SENSOR; + wf_control_set_max(drive_bay_fan); + return; + } + speed = wf_pid_run(&drive_bay_pid, temp); + DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n", + FIX32TOPRINT(temp), speed); + + err = drive_bay_fan->ops->set_value(drive_bay_fan, speed); + if (err) { + printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err); + failure_state |= FAILURE_FAN; + } +} + +/* PCI slots area fan */ +/* This makes the fan speed proportional to the power consumed */ +static struct wf_pid_param slots_param = { + .interval = 1, + .history_len = 2, + .gd = 0, + .gp = 0, + .gr = 0x1277952, + .itarget = 0, + .min = 1560, + .max = 3510, +}; + +static void slots_fan_tick(void) +{ + s32 power; + int speed; + int err; + + if (!slots_fan || !slots_power) + return; + if (!slots_started) { + /* first time; initialize things */ + wf_pid_init(&slots_pid, &slots_param); + slots_started = 1; + } + + err = slots_power->ops->get_value(slots_power, &power); + if (err) { + printk(KERN_WARNING "windfarm: slots power sensor error %d\n", + err); + failure_state |= FAILURE_SENSOR; + wf_control_set_max(slots_fan); + return; + } + speed = wf_pid_run(&slots_pid, power); + DBG_LOTS("slots PID power=%d.%.3d speed=%d\n", + FIX32TOPRINT(power), speed); + + err = slots_fan->ops->set_value(slots_fan, speed); + if (err) { + printk(KERN_WARNING "windfarm: slots fan error %d\n", err); + failure_state |= FAILURE_FAN; + } +} + +static void set_fail_state(void) +{ + int i; + + if (cpufreq_clamp) + wf_control_set_max(cpufreq_clamp); + for (i = 0; i < NR_CPU_FANS; ++i) + if (cpu_fans[i]) + wf_control_set_max(cpu_fans[i]); + if (backside_fan) + wf_control_set_max(backside_fan); + if (slots_fan) + wf_control_set_max(slots_fan); + if (drive_bay_fan) + wf_control_set_max(drive_bay_fan); +} + +static void pm112_tick(void) +{ + int i, last_failure; + + if (!started) { + started = 1; + for (i = 0; i < nr_cores; ++i) { + if (create_cpu_loop(i) < 0) { + failure_state = FAILURE_PERM; + set_fail_state(); + break; + } + } + DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax)); + +#ifdef HACKED_OVERTEMP + cpu_all_tmax = 60 << 16; +#endif + } + + /* Permanent failure, bail out */ + if (failure_state & FAILURE_PERM) + return; + /* Clear all failure bits except low overtemp which will be eventually + * cleared by the control loop itself + */ + last_failure = failure_state; + failure_state &= FAILURE_LOW_OVERTEMP; + cpu_fans_tick(); + backside_fan_tick(); + slots_fan_tick(); + drive_bay_fan_tick(); + + DBG_LOTS("last_failure: 0x%x, failure_state: %x\n", + last_failure, failure_state); + + /* Check for failures. Any failure causes cpufreq clamping */ + if (failure_state && last_failure == 0 && cpufreq_clamp) + wf_control_set_max(cpufreq_clamp); + if (failure_state == 0 && last_failure && cpufreq_clamp) + wf_control_set_min(cpufreq_clamp); + + /* That's it for now, we might want to deal with other failures + * differently in the future though + */ +} + +static void pm112_new_control(struct wf_control *ct) +{ + int i, max_exhaust; + + if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { + if (wf_get_control(ct) == 0) + cpufreq_clamp = ct; + } + + for (i = 0; i < NR_CPU_FANS; ++i) { + if (!strcmp(ct->name, cpu_fan_names[i])) { + if (cpu_fans[i] == NULL && wf_get_control(ct) == 0) + cpu_fans[i] = ct; + break; + } + } + if (i >= NR_CPU_FANS) { + /* not a CPU fan, try the others */ + if (!strcmp(ct->name, "backside-fan")) { + if (backside_fan == NULL && wf_get_control(ct) == 0) + backside_fan = ct; + } else if (!strcmp(ct->name, "slots-fan")) { + if (slots_fan == NULL && wf_get_control(ct) == 0) + slots_fan = ct; + } else if (!strcmp(ct->name, "drive-bay-fan")) { + if (drive_bay_fan == NULL && wf_get_control(ct) == 0) + drive_bay_fan = ct; + } + return; + } + + for (i = 0; i < CPU_FANS_REQD; ++i) + if (cpu_fans[i] == NULL) + return; + + /* work out pump scaling factors */ + max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]); + for (i = FIRST_PUMP; i <= LAST_PUMP; ++i) + if ((ct = cpu_fans[i]) != NULL) + cpu_fan_scale[i] = + ct->ops->get_max(ct) * 100 / max_exhaust; + + have_all_controls = 1; +} + +static void pm112_new_sensor(struct wf_sensor *sr) +{ + unsigned int i; + + if (have_all_sensors) + return; + if (!strncmp(sr->name, "cpu-temp-", 9)) { + i = sr->name[9] - '0'; + if (sr->name[10] == 0 && i < NR_CORES && + sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0) + sens_cpu_temp[i] = sr; + + } else if (!strncmp(sr->name, "cpu-power-", 10)) { + i = sr->name[10] - '0'; + if (sr->name[11] == 0 && i < NR_CORES && + sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0) + sens_cpu_power[i] = sr; + } else if (!strcmp(sr->name, "hd-temp")) { + if (hd_temp == NULL && wf_get_sensor(sr) == 0) + hd_temp = sr; + } else if (!strcmp(sr->name, "slots-power")) { + if (slots_power == NULL && wf_get_sensor(sr) == 0) + slots_power = sr; + } else if (!strcmp(sr->name, "u4-temp")) { + if (u4_temp == NULL && wf_get_sensor(sr) == 0) + u4_temp = sr; + } else + return; + + /* check if we have all the sensors we need */ + for (i = 0; i < nr_cores; ++i) + if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL) + return; + + have_all_sensors = 1; +} + +static int pm112_wf_notify(struct notifier_block *self, + unsigned long event, void *data) +{ + switch (event) { + case WF_EVENT_NEW_SENSOR: + pm112_new_sensor(data); + break; + case WF_EVENT_NEW_CONTROL: + pm112_new_control(data); + break; + case WF_EVENT_TICK: + if (have_all_controls && have_all_sensors) + pm112_tick(); + } + return 0; +} + +static struct notifier_block pm112_events = { + .notifier_call = pm112_wf_notify, +}; + +static int wf_pm112_probe(struct device *dev) +{ + wf_register_client(&pm112_events); + return 0; +} + +static int wf_pm112_remove(struct device *dev) +{ + wf_unregister_client(&pm112_events); + /* should release all sensors and controls */ + return 0; +} + +static struct device_driver wf_pm112_driver = { + .name = "windfarm", + .bus = &platform_bus_type, + .probe = wf_pm112_probe, + .remove = wf_pm112_remove, +}; + +static int __init wf_pm112_init(void) +{ + struct device_node *cpu; + + if (!machine_is_compatible("PowerMac11,2")) + return -ENODEV; + + /* Count the number of CPU cores */ + nr_cores = 0; + for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; ) + ++nr_cores; + + printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); + driver_register(&wf_pm112_driver); + return 0; +} + +static void __exit wf_pm112_exit(void) +{ + driver_unregister(&wf_pm112_driver); +} + +module_init(wf_pm112_init); +module_exit(wf_pm112_exit); + +MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); +MODULE_DESCRIPTION("Thermal control for PowerMac11,2"); +MODULE_LICENSE("GPL"); diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index eb69a601e76..f1df6efcbe6 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -538,45 +538,6 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) } } - -/* - * ****** Attributes ****** - * - */ - -#define BUILD_SHOW_FUNC_FIX(name, data) \ -static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - ssize_t r; \ - s32 val = 0; \ - data->ops->get_value(data, &val); \ - r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ - return r; \ -} \ -static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); - - -#define BUILD_SHOW_FUNC_INT(name, data) \ -static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - s32 val = 0; \ - data->ops->get_value(data, &val); \ - return sprintf(buf, "%d", val); \ -} \ -static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); - -BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); -BUILD_SHOW_FUNC_INT(sys_fan, fan_system); -BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); - -BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); -BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); -BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); - /* * ****** Setup / Init / Misc ... ****** * @@ -654,17 +615,13 @@ static void wf_smu_new_control(struct wf_control *ct) return; if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { - if (wf_get_control(ct) == 0) { + if (wf_get_control(ct) == 0) fan_cpu_main = ct; - device_create_file(wf_smu_dev, &dev_attr_cpu_fan); - } } if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { - if (wf_get_control(ct) == 0) { + if (wf_get_control(ct) == 0) fan_system = ct; - device_create_file(wf_smu_dev, &dev_attr_sys_fan); - } } if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { @@ -683,10 +640,8 @@ static void wf_smu_new_control(struct wf_control *ct) } if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { - if (wf_get_control(ct) == 0) { + if (wf_get_control(ct) == 0) fan_hd = ct; - device_create_file(wf_smu_dev, &dev_attr_hd_fan); - } } if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) @@ -699,24 +654,18 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) return; if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_cpu_power = sr; - device_create_file(wf_smu_dev, &dev_attr_cpu_power); - } } if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_cpu_temp = sr; - device_create_file(wf_smu_dev, &dev_attr_cpu_temp); - } } if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_hd_temp = sr; - device_create_file(wf_smu_dev, &dev_attr_hd_temp); - } } if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) @@ -794,32 +743,20 @@ static int wf_smu_remove(struct device *ddev) * with that except by adding locks all over... I'll do that * eventually but heh, who ever rmmod this module anyway ? */ - if (sensor_cpu_power) { - device_remove_file(wf_smu_dev, &dev_attr_cpu_power); + if (sensor_cpu_power) wf_put_sensor(sensor_cpu_power); - } - if (sensor_cpu_temp) { - device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); + if (sensor_cpu_temp) wf_put_sensor(sensor_cpu_temp); - } - if (sensor_hd_temp) { - device_remove_file(wf_smu_dev, &dev_attr_hd_temp); + if (sensor_hd_temp) wf_put_sensor(sensor_hd_temp); - } /* Release all controls */ - if (fan_cpu_main) { - device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); + if (fan_cpu_main) wf_put_control(fan_cpu_main); - } - if (fan_hd) { - device_remove_file(wf_smu_dev, &dev_attr_hd_fan); + if (fan_hd) wf_put_control(fan_hd); - } - if (fan_system) { - device_remove_file(wf_smu_dev, &dev_attr_sys_fan); + if (fan_system) wf_put_control(fan_system); - } if (cpufreq_clamp) wf_put_control(cpufreq_clamp); diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 43243cf7410..0d6372e96d3 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -458,45 +458,6 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st) /* - * ****** Attributes ****** - * - */ - -#define BUILD_SHOW_FUNC_FIX(name, data) \ -static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - ssize_t r; \ - s32 val = 0; \ - data->ops->get_value(data, &val); \ - r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ - return r; \ -} \ -static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); - - -#define BUILD_SHOW_FUNC_INT(name, data) \ -static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - s32 val = 0; \ - data->ops->get_value(data, &val); \ - return sprintf(buf, "%d", val); \ -} \ -static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); - -BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); -BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); -BUILD_SHOW_FUNC_INT(slots_fan, fan_slots); - -BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); -BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); -BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); -BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power); - -/* * ****** Setup / Init / Misc ... ****** * */ @@ -581,10 +542,8 @@ static void wf_smu_new_control(struct wf_control *ct) return; if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { - if (wf_get_control(ct) == 0) { + if (wf_get_control(ct) == 0) fan_cpu_main = ct; - device_create_file(wf_smu_dev, &dev_attr_cpu_fan); - } } if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { @@ -603,17 +562,13 @@ static void wf_smu_new_control(struct wf_control *ct) } if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { - if (wf_get_control(ct) == 0) { + if (wf_get_control(ct) == 0) fan_hd = ct; - device_create_file(wf_smu_dev, &dev_attr_hd_fan); - } } if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { - if (wf_get_control(ct) == 0) { + if (wf_get_control(ct) == 0) fan_slots = ct; - device_create_file(wf_smu_dev, &dev_attr_slots_fan); - } } if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && @@ -627,31 +582,23 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) return; if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_cpu_power = sr; - device_create_file(wf_smu_dev, &dev_attr_cpu_power); - } } if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_cpu_temp = sr; - device_create_file(wf_smu_dev, &dev_attr_cpu_temp); - } } if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_hd_temp = sr; - device_create_file(wf_smu_dev, &dev_attr_hd_temp); - } } if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { - if (wf_get_sensor(sr) == 0) { + if (wf_get_sensor(sr) == 0) sensor_slots_power = sr; - device_create_file(wf_smu_dev, &dev_attr_slots_power); - } } if (sensor_cpu_power && sensor_cpu_temp && @@ -720,40 +667,26 @@ static int wf_smu_remove(struct device *ddev) * with that except by adding locks all over... I'll do that * eventually but heh, who ever rmmod this module anyway ? */ - if (sensor_cpu_power) { - device_remove_file(wf_smu_dev, &dev_attr_cpu_power); + if (sensor_cpu_power) wf_put_sensor(sensor_cpu_power); - } - if (sensor_cpu_temp) { - device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); + if (sensor_cpu_temp) wf_put_sensor(sensor_cpu_temp); - } - if (sensor_hd_temp) { - device_remove_file(wf_smu_dev, &dev_attr_hd_temp); + if (sensor_hd_temp) wf_put_sensor(sensor_hd_temp); - } - if (sensor_slots_power) { - device_remove_file(wf_smu_dev, &dev_attr_slots_power); + if (sensor_slots_power) wf_put_sensor(sensor_slots_power); - } /* Release all controls */ - if (fan_cpu_main) { - device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); + if (fan_cpu_main) wf_put_control(fan_cpu_main); - } if (fan_cpu_second) wf_put_control(fan_cpu_second); if (fan_cpu_third) wf_put_control(fan_cpu_third); - if (fan_hd) { - device_remove_file(wf_smu_dev, &dev_attr_hd_fan); + if (fan_hd) wf_put_control(fan_hd); - } - if (fan_slots) { - device_remove_file(wf_smu_dev, &dev_attr_slots_fan); + if (fan_slots) wf_put_control(fan_slots); - } if (cpufreq_clamp) wf_put_control(cpufreq_clamp); diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 4d811600bda..a9e88edc0c7 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c @@ -24,7 +24,7 @@ #include "windfarm.h" -#define VERSION "0.3" +#define VERSION "0.4" #undef DEBUG @@ -34,6 +34,8 @@ #define DBG(args...) do { } while(0) #endif +static int smu_supports_new_fans_ops = 1; + /* * SMU fans control object */ @@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value) /* Fill SMU command structure */ cmd.cmd = SMU_CMD_FAN_COMMAND; - cmd.data_len = 14; + + /* The SMU has an "old" and a "new" way of setting the fan speed + * Unfortunately, I found no reliable way to know which one works + * on a given machine model. After some investigations it appears + * that MacOS X just tries the new one, and if it fails fallbacks + * to the old ones ... Ugh. + */ + retry: + if (smu_supports_new_fans_ops) { + buffer[0] = 0x30; + buffer[1] = id; + *((u16 *)(&buffer[2])) = value; + cmd.data_len = 4; + } else { + if (id > 7) + return -EINVAL; + /* Fill argument buffer */ + memset(buffer, 0, 16); + buffer[0] = pwm ? 0x10 : 0x00; + buffer[1] = 0x01 << id; + *((u16 *)&buffer[2 + id * 2]) = value; + cmd.data_len = 14; + } + cmd.reply_len = 16; cmd.data_buf = cmd.reply_buf = buffer; cmd.status = 0; cmd.done = smu_done_complete; cmd.misc = ∁ - /* Fill argument buffer */ - memset(buffer, 0, 16); - buffer[0] = pwm ? 0x10 : 0x00; - buffer[1] = 0x01 << id; - *((u16 *)&buffer[2 + id * 2]) = value; - rc = smu_queue_cmd(&cmd); if (rc) return rc; wait_for_completion(&comp); + + /* Handle fallback (see coment above) */ + if (cmd.status != 0 && smu_supports_new_fans_ops) { + printk(KERN_WARNING "windfarm: SMU failed new fan command " + "falling back to old method\n"); + smu_supports_new_fans_ops = 0; + goto retry; + } + return cmd.status; } @@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, /* Names used on desktop models */ if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || - !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan")) + !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") || + !strcmp(l, "CPU A EXHAUST")) fct->ctrl.name = "cpu-rear-fan-0"; - else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1")) + else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") || + !strcmp(l, "CPU B EXHAUST")) fct->ctrl.name = "cpu-rear-fan-1"; else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || - !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan")) + !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") || + !strcmp(l, "CPU A INTAKE")) fct->ctrl.name = "cpu-front-fan-0"; - else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1")) + else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") || + !strcmp(l, "CPU B INTAKE")) fct->ctrl.name = "cpu-front-fan-1"; - else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan")) + else if (!strcmp(l, "CPU A PUMP")) + fct->ctrl.name = "cpu-pump-0"; + else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || + !strcmp(l, "EXPANSION SLOTS INTAKE")) fct->ctrl.name = "slots-fan"; - else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay")) + else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") || + !strcmp(l, "DRIVE BAY A INTAKE")) fct->ctrl.name = "drive-bay-fan"; + else if (!strcmp(l, "BACKSIDE")) + fct->ctrl.name = "backside-fan"; /* Names used on iMac models */ if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) @@ -223,7 +261,8 @@ static int __init smu_controls_init(void) /* Look for RPM fans */ for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) - if (!strcmp(fans->name, "rpm-fans")) + if (!strcmp(fans->name, "rpm-fans") || + device_is_compatible(fans, "smu-rpm-fans")) break; for (fan = NULL; fans && (fan = of_get_next_child(fans, fan)) != NULL;) { diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c new file mode 100644 index 00000000000..3a32c59494f --- /dev/null +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -0,0 +1,418 @@ +/* + * Windfarm PowerMac thermal control. SMU "satellite" controller sensors. + * + * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> + * + * Released under the terms of the GNU GPL v2. + */ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/wait.h> +#include <linux/i2c.h> +#include <linux/i2c-dev.h> +#include <asm/semaphore.h> +#include <asm/prom.h> +#include <asm/smu.h> +#include <asm/pmac_low_i2c.h> + +#include "windfarm.h" + +#define VERSION "0.2" + +#define DEBUG + +#ifdef DEBUG +#define DBG(args...) printk(args) +#else +#define DBG(args...) do { } while(0) +#endif + +/* If the cache is older than 800ms we'll refetch it */ +#define MAX_AGE msecs_to_jiffies(800) + +struct wf_sat { + int nr; + atomic_t refcnt; + struct semaphore mutex; + unsigned long last_read; /* jiffies when cache last updated */ + u8 cache[16]; + struct i2c_client i2c; + struct device_node *node; +}; + +static struct wf_sat *sats[2]; + +struct wf_sat_sensor { + int index; + int index2; /* used for power sensors */ + int shift; + struct wf_sat *sat; + struct wf_sensor sens; +}; + +#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) +#define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) + +static int wf_sat_attach(struct i2c_adapter *adapter); +static int wf_sat_detach(struct i2c_client *client); + +static struct i2c_driver wf_sat_driver = { + .driver = { + .name = "wf_smu_sat", + }, + .attach_adapter = wf_sat_attach, + .detach_client = wf_sat_detach, +}; + +/* + * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested + * length down to the low-level driver, so we use this, which + * works well enough with the SMU i2c driver code... + */ +static int sat_read_block(struct i2c_client *client, u8 command, + u8 *values, int len) +{ + union i2c_smbus_data data; + int err; + + data.block[0] = len; + err = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA, + &data); + if (!err) + memcpy(values, data.block, len); + return err; +} + +struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, + unsigned int *size) +{ + struct wf_sat *sat; + int err; + unsigned int i, len; + u8 *buf; + u8 data[4]; + + /* TODO: Add the resulting partition to the device-tree */ + + if (sat_id > 1 || (sat = sats[sat_id]) == NULL) + return NULL; + + err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); + if (err) { + printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); + return NULL; + } + + len = i2c_smbus_read_word_data(&sat->i2c, 9); + if (len < 0) { + printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); + return NULL; + } + if (len == 0) { + printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id); + return NULL; + } + + len = le16_to_cpu(len); + len = (len + 3) & ~3; + buf = kmalloc(len, GFP_KERNEL); + if (buf == NULL) + return NULL; + + for (i = 0; i < len; i += 4) { + err = sat_read_block(&sat->i2c, 0xa, data, 4); + if (err) { + printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", + err); + goto fail; + } + buf[i] = data[1]; + buf[i+1] = data[0]; + buf[i+2] = data[3]; + buf[i+3] = data[2]; + } +#ifdef DEBUG + DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id); + for (i = 0; i < len; ++i) + DBG(" %x", buf[i]); + DBG("\n"); +#endif + + if (size) + *size = len; + return (struct smu_sdbp_header *) buf; + + fail: + kfree(buf); + return NULL; +} + +/* refresh the cache */ +static int wf_sat_read_cache(struct wf_sat *sat) +{ + int err; + + err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16); + if (err) + return err; + sat->last_read = jiffies; +#ifdef LOTSA_DEBUG + { + int i; + DBG(KERN_DEBUG "wf_sat_get: data is"); + for (i = 0; i < 16; ++i) + DBG(" %.2x", sat->cache[i]); + DBG("\n"); + } +#endif + return 0; +} + +static int wf_sat_get(struct wf_sensor *sr, s32 *value) +{ + struct wf_sat_sensor *sens = wf_to_sat(sr); + struct wf_sat *sat = sens->sat; + int i, err; + s32 val; + + if (sat->i2c.adapter == NULL) + return -ENODEV; + + down(&sat->mutex); + if (time_after(jiffies, (sat->last_read + MAX_AGE))) { + err = wf_sat_read_cache(sat); + if (err) + goto fail; + } + + i = sens->index * 2; + val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift; + if (sens->index2 >= 0) { + i = sens->index2 * 2; + /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */ + val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4; + } + + *value = val; + err = 0; + + fail: + up(&sat->mutex); + return err; +} + +static void wf_sat_release(struct wf_sensor *sr) +{ + struct wf_sat_sensor *sens = wf_to_sat(sr); + struct wf_sat *sat = sens->sat; + + if (atomic_dec_and_test(&sat->refcnt)) { + if (sat->i2c.adapter) { + i2c_detach_client(&sat->i2c); + sat->i2c.adapter = NULL; + } + if (sat->nr >= 0) + sats[sat->nr] = NULL; + kfree(sat); + } + kfree(sens); +} + +static struct wf_sensor_ops wf_sat_ops = { + .get_value = wf_sat_get, + .release = wf_sat_release, + .owner = THIS_MODULE, +}; + +static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) +{ + struct wf_sat *sat; + struct wf_sat_sensor *sens; + u32 *reg; + char *loc, *type; + u8 addr, chip, core; + struct device_node *child; + int shift, cpu, index; + char *name; + int vsens[2], isens[2]; + + reg = (u32 *) get_property(dev, "reg", NULL); + if (reg == NULL) + return; + addr = *reg; + DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); + + sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); + if (sat == NULL) + return; + sat->nr = -1; + sat->node = of_node_get(dev); + atomic_set(&sat->refcnt, 0); + init_MUTEX(&sat->mutex); + sat->i2c.addr = (addr >> 1) & 0x7f; + sat->i2c.adapter = adapter; + sat->i2c.driver = &wf_sat_driver; + strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); + + if (i2c_attach_client(&sat->i2c)) { + printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); + goto fail; + } + + vsens[0] = vsens[1] = -1; + isens[0] = isens[1] = -1; + child = NULL; + while ((child = of_get_next_child(dev, child)) != NULL) { + reg = (u32 *) get_property(child, "reg", NULL); + type = get_property(child, "device_type", NULL); + loc = get_property(child, "location", NULL); + if (reg == NULL || loc == NULL) + continue; + + /* the cooked sensors are between 0x30 and 0x37 */ + if (*reg < 0x30 || *reg > 0x37) + continue; + index = *reg - 0x30; + + /* expect location to be CPU [AB][01] ... */ + if (strncmp(loc, "CPU ", 4) != 0) + continue; + chip = loc[4] - 'A'; + core = loc[5] - '0'; + if (chip > 1 || core > 1) { + printk(KERN_ERR "wf_sat_create: don't understand " + "location %s for %s\n", loc, child->full_name); + continue; + } + cpu = 2 * chip + core; + if (sat->nr < 0) + sat->nr = chip; + else if (sat->nr != chip) { + printk(KERN_ERR "wf_sat_create: can't cope with " + "multiple CPU chips on one SAT (%s)\n", loc); + continue; + } + + if (strcmp(type, "voltage-sensor") == 0) { + name = "cpu-voltage"; + shift = 4; + vsens[core] = index; + } else if (strcmp(type, "current-sensor") == 0) { + name = "cpu-current"; + shift = 8; + isens[core] = index; + } else if (strcmp(type, "temp-sensor") == 0) { + name = "cpu-temp"; + shift = 10; + } else + continue; /* hmmm shouldn't happen */ + + /* the +16 is enough for "cpu-voltage-n" */ + sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); + if (sens == NULL) { + printk(KERN_ERR "wf_sat_create: couldn't create " + "%s sensor %d (no memory)\n", name, cpu); + continue; + } + sens->index = index; + sens->index2 = -1; + sens->shift = shift; + sens->sat = sat; + atomic_inc(&sat->refcnt); + sens->sens.ops = &wf_sat_ops; + sens->sens.name = (char *) (sens + 1); + snprintf(sens->sens.name, 16, "%s-%d", name, cpu); + + if (wf_register_sensor(&sens->sens)) { + atomic_dec(&sat->refcnt); + kfree(sens); + } + } + + /* make the power sensors */ + for (core = 0; core < 2; ++core) { + if (vsens[core] < 0 || isens[core] < 0) + continue; + cpu = 2 * sat->nr + core; + sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); + if (sens == NULL) { + printk(KERN_ERR "wf_sat_create: couldn't create power " + "sensor %d (no memory)\n", cpu); + continue; + } + sens->index = vsens[core]; + sens->index2 = isens[core]; + sens->shift = 0; + sens->sat = sat; + atomic_inc(&sat->refcnt); + sens->sens.ops = &wf_sat_ops; + sens->sens.name = (char *) (sens + 1); + snprintf(sens->sens.name, 16, "cpu-power-%d", cpu); + + if (wf_register_sensor(&sens->sens)) { + atomic_dec(&sat->refcnt); + kfree(sens); + } + } + + if (sat->nr >= 0) + sats[sat->nr] = sat; + + return; + + fail: + kfree(sat); +} + +static int wf_sat_attach(struct i2c_adapter *adapter) +{ + struct device_node *busnode, *dev = NULL; + struct pmac_i2c_bus *bus; + + bus = pmac_i2c_adapter_to_bus(adapter); + if (bus == NULL) + return -ENODEV; + busnode = pmac_i2c_get_bus_node(bus); + + while ((dev = of_get_next_child(busnode, dev)) != NULL) + if (device_is_compatible(dev, "smu-sat")) + wf_sat_create(adapter, dev); + return 0; +} + +static int wf_sat_detach(struct i2c_client *client) +{ + struct wf_sat *sat = i2c_to_sat(client); + + /* XXX TODO */ + + sat->i2c.adapter = NULL; + return 0; +} + +static int __init sat_sensors_init(void) +{ + int err; + + err = i2c_add_driver(&wf_sat_driver); + if (err < 0) + return err; + return 0; +} + +static void __exit sat_sensors_exit(void) +{ + i2c_del_driver(&wf_sat_driver); +} + +module_init(sat_sensors_init); +/*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ + +MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); +MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control"); +MODULE_LICENSE("GPL"); diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 1a00d9c75a2..bed25dcf8a1 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c @@ -220,14 +220,29 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node) !strcmp(l, "CPU T-Diode")) { ads->sens.ops = &smu_cputemp_ops; ads->sens.name = "cpu-temp"; + if (cpudiode == NULL) { + DBG("wf: cpudiode partition (%02x) not found\n", + SMU_SDB_CPUDIODE_ID); + goto fail; + } } else if (!strcmp(c, "current-sensor") && !strcmp(l, "CPU Current")) { ads->sens.ops = &smu_cpuamp_ops; ads->sens.name = "cpu-current"; + if (cpuvcp == NULL) { + DBG("wf: cpuvcp partition (%02x) not found\n", + SMU_SDB_CPUVCP_ID); + goto fail; + } } else if (!strcmp(c, "voltage-sensor") && !strcmp(l, "CPU Voltage")) { ads->sens.ops = &smu_cpuvolt_ops; ads->sens.name = "cpu-voltage"; + if (cpuvcp == NULL) { + DBG("wf: cpuvcp partition (%02x) not found\n", + SMU_SDB_CPUVCP_ID); + goto fail; + } } else if (!strcmp(c, "power-sensor") && !strcmp(l, "Slots Power")) { ads->sens.ops = &smu_slotspow_ops; @@ -365,29 +380,22 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) return NULL; } -static int smu_fetch_param_partitions(void) +static void smu_fetch_param_partitions(void) { struct smu_sdbp_header *hdr; /* Get CPU voltage/current/power calibration data */ hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); - if (hdr == NULL) { - DBG("wf: cpuvcp partition (%02x) not found\n", - SMU_SDB_CPUVCP_ID); - return -ENODEV; + if (hdr != NULL) { + cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; + /* Keep version around */ + cpuvcp_version = hdr->version; } - cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; - /* Keep version around */ - cpuvcp_version = hdr->version; /* Get CPU diode calibration data */ hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); - if (hdr == NULL) { - DBG("wf: cpudiode partition (%02x) not found\n", - SMU_SDB_CPUDIODE_ID); - return -ENODEV; - } - cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; + if (hdr != NULL) + cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; /* Get slots power calibration data if any */ hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); @@ -398,23 +406,18 @@ static int smu_fetch_param_partitions(void) hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); if (hdr != NULL) debugswitches = (u8 *)&hdr[1]; - - return 0; } static int __init smu_sensors_init(void) { struct device_node *smu, *sensors, *s; struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; - int rc; if (!smu_present()) return -ENODEV; /* Get parameters partitions */ - rc = smu_fetch_param_partitions(); - if (rc) - return rc; + smu_fetch_param_partitions(); smu = of_find_node_by_type(NULL, "smu"); if (smu == NULL) diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 130ea7f21f5..12ebaf8bddc 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { .cold_ids = { &dtt200u_usb_table[0], NULL }, .warm_ids = { &dtt200u_usb_table[1], NULL }, }, - { 0 }, + { NULL }, } }; @@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { .cold_ids = { &dtt200u_usb_table[2], NULL }, .warm_ids = { &dtt200u_usb_table[3], NULL }, }, - { 0 }, + { NULL }, } }; diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 028204956bb..3835235b68d 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { .cold_ids = { &vp7045_usb_table[2], NULL }, .warm_ids = { &vp7045_usb_table[3], NULL }, }, - { 0 }, + { NULL }, } }; diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 297c32ab51e..840fe017712 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c @@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user if (kp->clipcount > 2048) return -EINVAL; if (kp->clipcount) { - struct v4l2_clip32 *uclips = compat_ptr(up->clips); - struct v4l2_clip *kclips; + struct v4l2_clip32 __user *uclips; + struct v4l2_clip __user *kclips; int n = kp->clipcount; + compat_caddr_t p; + if (get_user(p, &up->clips)) + return -EFAULT; + uclips = compat_ptr(p); kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); kp->clips = kclips; while (--n >= 0) { - if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) || - copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c))) + if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) + return -EFAULT; + if (put_user(n ? kclips + 1 : NULL, &kclips->next)) return -EFAULT; - kclips->next = n ? kclips + 1 : 0; uclips += 1; kclips += 1; } } else - kp->clips = 0; + kp->clips = NULL; return 0; } static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) || - copy_to_user(&up->w, &kp->w, sizeof(up->w)) || + if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || put_user(kp->field, &up->field) || put_user(kp->chromakey, &up->chromakey) || put_user(kp->clipcount, &up->clipcount)) @@ -199,33 +202,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) || - copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) + return -EFAULT; return 0; } static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) || - copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) + return -EFAULT; return 0; } static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) || - copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) + return -EFAULT; return 0; } static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) || - copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) + return -EFAULT; return 0; } @@ -279,18 +278,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) || - copy_from_user(kp, up, sizeof(struct v4l2_standard))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_standard))) + return -EFAULT; return 0; } static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) || - copy_to_user(up, kp, sizeof(struct v4l2_standard))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_standard))) + return -EFAULT; return 0; } @@ -328,18 +325,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) || - copy_from_user(kp, up, sizeof(struct v4l2_tuner))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_tuner))) + return -EFAULT; return 0; } static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) || - copy_to_user(up, kp, sizeof(struct v4l2_tuner))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_tuner))) + return -EFAULT; return 0; } @@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user break; case V4L2_MEMORY_USERPTR: { - unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); + compat_long_t tmp; - if(get_user(kp->length, &up->length) || - get_user(kp->m.userptr, &tmp)) - return -EFAULT; + if (get_user(kp->length, &up->length) || + get_user(tmp, &up->m.userptr)) + return -EFAULT; + + kp->m.userptr = (unsigned long)compat_ptr(tmp); } break; case V4L2_MEMORY_OVERLAY: @@ -468,33 +465,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) || - copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) + return -EFAULT; return 0; } static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) || - copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) + return -EFAULT; return 0; } static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) || - copy_from_user(kp, up, sizeof(struct v4l2_input))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_input))) + return -EFAULT; return 0; } static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) || - copy_to_user(up, kp, sizeof(struct v4l2_input))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_input))) + return -EFAULT; return 0; } diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c483a863b11..5d397b7a549 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -65,7 +65,7 @@ config MMC_AU1X depends on SOC_AU1X00 && MMC help This selects the AMD Alchemy(R) Multimedia card interface. - iIf you have a Alchemy platform with a MMC slot, say Y or M here. + If you have a Alchemy platform with a MMC slot, say Y or M here. If unsure, say N. diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index effa0d7a73a..205bb708333 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -301,7 +301,7 @@ config MTD_JEDEC config MTD_XIP bool "XIP aware MTD support" - depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM + depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP default y if XIP_KERNEL help This allows MTD support to work with flash memory which is also diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 18b027e73f2..86633c5f1a4 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -29,7 +29,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/skbuff.h> -#include <linux/irq.h> +#include <asm/irq.h> /* Used for the temporal inet entries and routing */ #include <linux/socket.h> #include <linux/bitops.h> diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 13b745b3966..da0c878dcba 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -614,7 +614,7 @@ static void rebuild_rx_bufs(struct net_device *dev) static int init_i596_mem(struct net_device *dev) { struct i596_private *lp = dev->priv; -#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) +#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) || defined(ENABLE_APRICOT) short ioaddr = dev->base_addr; #endif unsigned long flags; diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h index c68ba9c2ef4..aca47f3a7b9 100644 --- a/drivers/net/appletalk/cops.h +++ b/drivers/net/appletalk/cops.h @@ -51,7 +51,7 @@ struct ltfirmware { unsigned int length; - unsigned char * data; + const unsigned char * data; }; #define DAYNA 1 diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 38c3f033f73..8c8d6c453c4 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -97,25 +97,44 @@ static int __init arcrimi_probe(struct net_device *dev) "must specify the shmem and irq!\n"); return -ENODEV; } + if (dev->dev_addr[0] == 0) { + BUGMSG(D_NORMAL, "You need to specify your card's station " + "ID!\n"); + return -ENODEV; + } /* - * Grab the memory region at mem_start for BUFFER_SIZE bytes. + * Grab the memory region at mem_start for MIRROR_SIZE bytes. * Later in arcrimi_found() the real size will be determined * and this reserve will be released and the correct size * will be taken. */ - if (!request_mem_region(dev->mem_start, BUFFER_SIZE, "arcnet (90xx)")) { + if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { BUGMSG(D_NORMAL, "Card memory already allocated\n"); return -ENODEV; } - if (dev->dev_addr[0] == 0) { - release_mem_region(dev->mem_start, BUFFER_SIZE); - BUGMSG(D_NORMAL, "You need to specify your card's station " - "ID!\n"); - return -ENODEV; - } return arcrimi_found(dev); } +static int check_mirror(unsigned long addr, size_t size) +{ + void __iomem *p; + int res = -1; + + if (!request_mem_region(addr, size, "arcnet (90xx)")) + return -1; + + p = ioremap(addr, size); + if (p) { + if (readb(p) == TESTvalue) + res = 1; + else + res = 0; + iounmap(p); + } + + release_mem_region(addr, size); + return res; +} /* * Set up the struct net_device associated with this card. Called after @@ -125,19 +144,28 @@ static int __init arcrimi_found(struct net_device *dev) { struct arcnet_local *lp; unsigned long first_mirror, last_mirror, shmem; + void __iomem *p; int mirror_size; int err; + p = ioremap(dev->mem_start, MIRROR_SIZE); + if (!p) { + release_mem_region(dev->mem_start, MIRROR_SIZE); + BUGMSG(D_NORMAL, "Can't ioremap\n"); + return -ENODEV; + } + /* reserve the irq */ if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) { - release_mem_region(dev->mem_start, BUFFER_SIZE); + iounmap(p); + release_mem_region(dev->mem_start, MIRROR_SIZE); BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); return -ENODEV; } shmem = dev->mem_start; - isa_writeb(TESTvalue, shmem); - isa_writeb(dev->dev_addr[0], shmem + 1); /* actually the node ID */ + writeb(TESTvalue, p); + writeb(dev->dev_addr[0], p + 1); /* actually the node ID */ /* find the real shared memory start/end points, including mirrors */ @@ -146,17 +174,18 @@ static int __init arcrimi_found(struct net_device *dev) * 2k (or there are no mirrors at all) but on some, it's 4k. */ mirror_size = MIRROR_SIZE; - if (isa_readb(shmem) == TESTvalue - && isa_readb(shmem - mirror_size) != TESTvalue - && isa_readb(shmem - 2 * mirror_size) == TESTvalue) - mirror_size *= 2; + if (readb(p) == TESTvalue + && check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 + && check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) + mirror_size = 2 * MIRROR_SIZE; - first_mirror = last_mirror = shmem; - while (isa_readb(first_mirror) == TESTvalue) + first_mirror = shmem - mirror_size; + while (check_mirror(first_mirror, mirror_size) == 1) first_mirror -= mirror_size; first_mirror += mirror_size; - while (isa_readb(last_mirror) == TESTvalue) + last_mirror = shmem + mirror_size; + while (check_mirror(last_mirror, mirror_size) == 1) last_mirror += mirror_size; last_mirror -= mirror_size; @@ -181,7 +210,8 @@ static int __init arcrimi_found(struct net_device *dev) * with the correct size. There is a VERY slim chance this could * fail. */ - release_mem_region(shmem, BUFFER_SIZE); + iounmap(p); + release_mem_region(shmem, MIRROR_SIZE); if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) { diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 6c2c9b9ac6d..43150b2bd13 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -53,7 +53,7 @@ /* Internal function declarations */ -static int com90xx_found(int ioaddr, int airq, u_long shmem); +static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *); static void com90xx_command(struct net_device *dev, int command); static int com90xx_status(struct net_device *dev); static void com90xx_setmask(struct net_device *dev, int mask); @@ -116,14 +116,26 @@ static void __init com90xx_probe(void) unsigned long airqmask; int ports[(0x3f0 - 0x200) / 16 + 1] = {0}; - u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] = - {0}; + unsigned long *shmems; + void __iomem **iomem; int numports, numshmems, *port; u_long *p; + int index; if (!io && !irq && !shmem && !*device && com90xx_skip_probe) return; + shmems = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(unsigned long), + GFP_KERNEL); + if (!shmems) + return; + iomem = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(void __iomem *), + GFP_KERNEL); + if (!iomem) { + kfree(shmems); + return; + } + BUGLVL(D_NORMAL) printk(VERSION); /* set up the arrays where we'll store the possible probe addresses */ @@ -179,6 +191,8 @@ static void __init com90xx_probe(void) if (!numports) { BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n"); + kfree(shmems); + kfree(iomem); return; } /* Stage 2: we have now reset any possible ARCnet cards, so we can't @@ -202,8 +216,8 @@ static void __init com90xx_probe(void) * 0xD1 byte in the right place, or are read-only. */ numprint = -1; - for (p = &shmems[0]; p < shmems + numshmems; p++) { - u_long ptr = *p; + for (index = 0, p = &shmems[0]; index < numshmems; p++, index++) { + void __iomem *base; numprint++; numprint %= 8; @@ -213,38 +227,49 @@ static void __init com90xx_probe(void) } BUGMSG2(D_INIT, "%lXh ", *p); - if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) { + if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) { BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n"); BUGMSG2(D_INIT_REASONS, "Stage 3: "); BUGLVL(D_INIT_REASONS) numprint = 0; - *p-- = shmems[--numshmems]; - continue; + goto out; + } + base = ioremap(*p, MIRROR_SIZE); + if (!base) { + BUGMSG2(D_INIT_REASONS, "(ioremap)\n"); + BUGMSG2(D_INIT_REASONS, "Stage 3: "); + BUGLVL(D_INIT_REASONS) numprint = 0; + goto out1; } - if (isa_readb(ptr) != TESTvalue) { + if (readb(base) != TESTvalue) { BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n", - isa_readb(ptr), TESTvalue); + readb(base), TESTvalue); BUGMSG2(D_INIT_REASONS, "S3: "); BUGLVL(D_INIT_REASONS) numprint = 0; - release_mem_region(*p, BUFFER_SIZE); - *p-- = shmems[--numshmems]; - continue; + goto out2; } /* By writing 0x42 to the TESTvalue location, we also make * sure no "mirror" shmem areas show up - if they occur * in another pass through this loop, they will be discarded * because *cptr != TESTvalue. */ - isa_writeb(0x42, ptr); - if (isa_readb(ptr) != 0x42) { + writeb(0x42, base); + if (readb(base) != 0x42) { BUGMSG2(D_INIT_REASONS, "(read only)\n"); BUGMSG2(D_INIT_REASONS, "S3: "); - release_mem_region(*p, BUFFER_SIZE); - *p-- = shmems[--numshmems]; - continue; + goto out2; } BUGMSG2(D_INIT_REASONS, "\n"); BUGMSG2(D_INIT_REASONS, "S3: "); BUGLVL(D_INIT_REASONS) numprint = 0; + iomem[index] = base; + continue; + out2: + iounmap(base); + out1: + release_mem_region(*p, MIRROR_SIZE); + out: + *p-- = shmems[--numshmems]; + index--; } BUGMSG2(D_INIT, "\n"); @@ -252,6 +277,8 @@ static void __init com90xx_probe(void) BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n"); for (port = &ports[0]; port < ports + numports; port++) release_region(*port, ARCNET_TOTAL_SIZE); + kfree(shmems); + kfree(iomem); return; } /* Stage 4: something of a dummy, to report the shmems that are @@ -351,30 +378,32 @@ static void __init com90xx_probe(void) mdelay(RESETtime); } else { /* just one shmem and port, assume they match */ - isa_writeb(TESTvalue, shmems[0]); + writeb(TESTvalue, iomem[0]); } #else inb(_RESET); mdelay(RESETtime); #endif - for (p = &shmems[0]; p < shmems + numshmems; p++) { - u_long ptr = *p; + for (index = 0; index < numshmems; index++) { + u_long ptr = shmems[index]; + void __iomem *base = iomem[index]; - if (isa_readb(ptr) == TESTvalue) { /* found one */ + if (readb(base) == TESTvalue) { /* found one */ BUGMSG2(D_INIT, "%lXh)\n", *p); openparen = 0; /* register the card */ - if (com90xx_found(*port, airq, *p) == 0) + if (com90xx_found(*port, airq, ptr, base) == 0) found = 1; numprint = -1; /* remove shmem from the list */ - *p = shmems[--numshmems]; + shmems[index] = shmems[--numshmems]; + iomem[index] = iomem[numshmems]; break; /* go to the next I/O port */ } else { - BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr)); + BUGMSG2(D_INIT_REASONS, "%Xh-", readb(base)); } } @@ -391,17 +420,40 @@ static void __init com90xx_probe(void) BUGLVL(D_INIT_REASONS) printk("\n"); /* Now put back TESTvalue on all leftover shmems. */ - for (p = &shmems[0]; p < shmems + numshmems; p++) { - isa_writeb(TESTvalue, *p); - release_mem_region(*p, BUFFER_SIZE); + for (index = 0; index < numshmems; index++) { + writeb(TESTvalue, iomem[index]); + iounmap(iomem[index]); + release_mem_region(shmems[index], MIRROR_SIZE); } + kfree(shmems); + kfree(iomem); } +static int check_mirror(unsigned long addr, size_t size) +{ + void __iomem *p; + int res = -1; + + if (!request_mem_region(addr, size, "arcnet (90xx)")) + return -1; + + p = ioremap(addr, size); + if (p) { + if (readb(p) == TESTvalue) + res = 1; + else + res = 0; + iounmap(p); + } + + release_mem_region(addr, size); + return res; +} /* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -static int __init com90xx_found(int ioaddr, int airq, u_long shmem) +static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *p) { struct net_device *dev = NULL; struct arcnet_local *lp; @@ -412,7 +464,8 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem) dev = alloc_arcdev(device); if (!dev) { BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n"); - release_mem_region(shmem, BUFFER_SIZE); + iounmap(p); + release_mem_region(shmem, MIRROR_SIZE); return -ENOMEM; } lp = dev->priv; @@ -423,24 +476,27 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem) * 2k (or there are no mirrors at all) but on some, it's 4k. */ mirror_size = MIRROR_SIZE; - if (isa_readb(shmem) == TESTvalue - && isa_readb(shmem - mirror_size) != TESTvalue - && isa_readb(shmem - 2 * mirror_size) == TESTvalue) - mirror_size *= 2; + if (readb(p) == TESTvalue && + check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 && + check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) + mirror_size = 2 * MIRROR_SIZE; - first_mirror = last_mirror = shmem; - while (isa_readb(first_mirror) == TESTvalue) + first_mirror = shmem - mirror_size; + while (check_mirror(first_mirror, mirror_size) == 1) first_mirror -= mirror_size; first_mirror += mirror_size; - while (isa_readb(last_mirror) == TESTvalue) + last_mirror = shmem + mirror_size; + while (check_mirror(last_mirror, mirror_size) == 1) last_mirror += mirror_size; last_mirror -= mirror_size; dev->mem_start = first_mirror; dev->mem_end = last_mirror + MIRROR_SIZE - 1; - release_mem_region(shmem, BUFFER_SIZE); + iounmap(p); + release_mem_region(shmem, MIRROR_SIZE); + if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) goto err_free_dev; diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 3b1bef1ee21..77411a00d1e 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c @@ -86,7 +86,6 @@ #include <linux/bitops.h> #include <linux/jiffies.h> -#include <asm/bug.h> #include <asm/system.h> #include <asm/uaccess.h> diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index a37b82ebca3..247c8ca8603 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -1719,17 +1719,10 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) hp100_outw(i, FRAGMENT_LEN); /* and first/only fragment length */ if (lp->mode == 2) { /* memory mapped */ - if (lp->mem_ptr_virt) { /* high pci memory was remapped */ - /* Note: The J2585B needs alignment to 32bits here! */ - memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); - if (!ok_flag) - memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); - } else { - /* Note: The J2585B needs alignment to 32bits here! */ - isa_memcpy_toio(lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3); - if (!ok_flag) - isa_memset_io(lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len); - } + /* Note: The J2585B needs alignment to 32bits here! */ + memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); + if (!ok_flag) + memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); } else { /* programmed i/o */ outsl(ioaddr + HP100_REG_DATA32, skb->data, (skb->len + 3) >> 2); @@ -1799,10 +1792,7 @@ static void hp100_rx(struct net_device *dev) /* First we get the header, which contains information about the */ /* actual length of the received packet. */ if (lp->mode == 2) { /* memory mapped mode */ - if (lp->mem_ptr_virt) /* if memory was remapped */ - header = readl(lp->mem_ptr_virt); - else - header = isa_readl(lp->mem_ptr_phys); + header = readl(lp->mem_ptr_virt); } else /* programmed i/o */ header = hp100_inl(DATA32); @@ -1834,13 +1824,9 @@ static void hp100_rx(struct net_device *dev) ptr = skb->data; /* Now transfer the data from the card into that area */ - if (lp->mode == 2) { - if (lp->mem_ptr_virt) - memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); - /* Note alignment to 32bit transfers */ - else - isa_memcpy_fromio(ptr, lp->mem_ptr_phys, pkt_len); - } else /* io mapped */ + if (lp->mode == 2) + memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); + else /* io mapped */ insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2); skb->protocol = eth_type_trans(skb, dev); diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 591c5864ffb..7e49522b8b3 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -204,7 +204,7 @@ static inline int emac_phy_gpcs(int phy_mode) static inline void emac_tx_enable(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; unsigned long flags; u32 r; @@ -220,7 +220,7 @@ static inline void emac_tx_enable(struct ocp_enet_private *dev) static void emac_tx_disable(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; unsigned long flags; u32 r; @@ -244,7 +244,7 @@ static void emac_tx_disable(struct ocp_enet_private *dev) static void emac_rx_enable(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; unsigned long flags; u32 r; @@ -275,7 +275,7 @@ static void emac_rx_enable(struct ocp_enet_private *dev) static void emac_rx_disable(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; unsigned long flags; u32 r; @@ -299,7 +299,7 @@ static void emac_rx_disable(struct ocp_enet_private *dev) static inline void emac_rx_disable_async(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; unsigned long flags; u32 r; @@ -315,7 +315,7 @@ static inline void emac_rx_disable_async(struct ocp_enet_private *dev) static int emac_reset(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; unsigned long flags; int n = 20; @@ -348,7 +348,7 @@ static int emac_reset(struct ocp_enet_private *dev) static void emac_hash_mc(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; u16 gaht[4] = { 0 }; struct dev_mc_list *dmi; @@ -393,7 +393,7 @@ static inline int emac_opb_mhz(void) /* BHs disabled */ static int emac_configure(struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; struct net_device *ndev = dev->ndev; int gige; u32 r; @@ -555,7 +555,7 @@ static void emac_full_tx_reset(struct net_device *ndev) static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; u32 r; int n; @@ -604,7 +604,7 @@ static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg, u16 val) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; int n; DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg, @@ -666,7 +666,7 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val) static void emac_set_multicast_list(struct net_device *ndev) { struct ocp_enet_private *dev = ndev->priv; - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; u32 rmr = emac_iff2rmr(ndev); DBG("%d: multicast %08x" NL, dev->def->index, rmr); @@ -825,7 +825,7 @@ static void emac_clean_rx_ring(struct ocp_enet_private *dev) } static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot, - int flags) + gfp_t flags) { struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags); if (unlikely(!skb)) @@ -1047,7 +1047,7 @@ static inline u16 emac_tx_csum(struct ocp_enet_private *dev, static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; struct net_device *ndev = dev->ndev; /* Send the packet out */ @@ -1519,7 +1519,7 @@ static void emac_rxde(void *param) static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs) { struct ocp_enet_private *dev = dev_instance; - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; struct ibm_emac_error_stats *st = &dev->estats; u32 isr = in_be32(&p->isr); @@ -1619,17 +1619,17 @@ static void emac_remove(struct ocp_device *ocpdev) DBG("%d: remove" NL, dev->def->index); - ocp_set_drvdata(ocpdev, 0); + ocp_set_drvdata(ocpdev, NULL); unregister_netdev(dev->ndev); tah_fini(dev->tah_dev); rgmii_fini(dev->rgmii_dev, dev->rgmii_input); zmii_fini(dev->zmii_dev, dev->zmii_input); - emac_dbg_register(dev->def->index, 0); + emac_dbg_register(dev->def->index, NULL); mal_unregister_commac(dev->mal, &dev->commac); - iounmap((void *)dev->emacp); + iounmap(dev->emacp); kfree(dev->ndev); } @@ -2048,9 +2048,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) goto out4; /* Map EMAC regs */ - dev->emacp = - (struct emac_regs *)ioremap(dev->def->paddr, - sizeof(struct emac_regs)); + dev->emacp = ioremap(dev->def->paddr, sizeof(struct emac_regs)); if (!dev->emacp) { printk(KERN_ERR "emac%d: could not ioremap device registers!\n", dev->def->index); @@ -2210,7 +2208,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) return 0; out6: - iounmap((void *)dev->emacp); + iounmap(dev->emacp); out5: tah_fini(dev->tah_dev); out4: diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index 911abbaf471..f61273b2e94 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h @@ -155,7 +155,7 @@ struct ibm_emac_error_stats { struct ocp_enet_private { struct net_device *ndev; /* 0 */ - struct emac_regs *emacp; + struct emac_regs __iomem *emacp; struct mal_descriptor *tx_desc; int tx_cnt; diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c index 75d3b863904..c7e1ecfa08f 100644 --- a/drivers/net/ibm_emac/ibm_emac_debug.c +++ b/drivers/net/ibm_emac/ibm_emac_debug.c @@ -58,7 +58,7 @@ static void emac_desc_dump(int idx, struct ocp_enet_private *p) static void emac_mac_dump(int idx, struct ocp_enet_private *dev) { - struct emac_regs *p = dev->emacp; + struct emac_regs __iomem *p = dev->emacp; printk("** EMAC%d registers **\n" "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h index a1ffb8a44ff..7f03d536c9a 100644 --- a/drivers/net/ibm_emac/ibm_emac_rgmii.h +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h @@ -31,7 +31,7 @@ struct rgmii_regs { /* RGMII device */ struct ibm_ocp_rgmii { - struct rgmii_regs *base; + struct rgmii_regs __iomem *base; int users; /* number of EMACs using this RGMII bridge */ }; diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c index 35c1185079e..e129e0aaa04 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.c +++ b/drivers/net/ibm_emac/ibm_emac_zmii.c @@ -80,7 +80,7 @@ static inline u32 zmii_mode_mask(int mode, int input) static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) { struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); - struct zmii_regs *p; + struct zmii_regs __iomem *p; ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode); @@ -94,8 +94,7 @@ static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) } dev->mode = PHY_MODE_NA; - p = (struct zmii_regs *)ioremap(ocpdev->def->paddr, - sizeof(struct zmii_regs)); + p = ioremap(ocpdev->def->paddr, sizeof(struct zmii_regs)); if (!p) { printk(KERN_ERR "zmii%d: could not ioremap device registers!\n", @@ -231,7 +230,7 @@ void __exit __zmii_fini(struct ocp_device *ocpdev, int input) if (!--dev->users) { /* Free everything if this is the last user */ ocp_set_drvdata(ocpdev, NULL); - iounmap((void *)dev->base); + iounmap(dev->base); kfree(dev); } } diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h index 0bb26062c0a..92c85441075 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.h +++ b/drivers/net/ibm_emac/ibm_emac_zmii.h @@ -32,7 +32,7 @@ struct zmii_regs { /* ZMII device */ struct ibm_ocp_zmii { - struct zmii_regs *base; + struct zmii_regs __iomem *base; int mode; /* subset of PHY_MODE_XXXX */ int users; /* number of EMACs using this ZMII bridge */ u32 fer_save; /* FER value left by firmware */ diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 02d5c682273..f6f3dafe83e 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -622,7 +622,7 @@ static int __init mac_sonic_init_module(void) return 0; out_unregister: - driver_unregister(&mac_sonic_driver); + platform_driver_unregister(&mac_sonic_driver); return -ENOMEM; } diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index df572018595..6b4fff80ae5 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -32,6 +32,8 @@ */ #include <linux/init.h> #include <linux/dma-mapping.h> +#include <linux/in.h> +#include <linux/ip.h> #include <linux/tcp.h> #include <linux/udp.h> #include <linux/etherdevice.h> diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index c5c738a51ee..56344103ac2 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -32,6 +32,9 @@ #include <asm/uaccess.h> #include <asm/io.h> +#ifdef CONFIG_NET_POLL_CONTROLLER +#include <asm/irq.h> +#endif #ifdef DEBUG #define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 7db1d1d0bb3..cf5c805452a 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -29,6 +29,7 @@ #include <linux/ioport.h> #include <net/arp.h> +#include <asm/irq.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/byteorder.h> diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 8dea07b4799..eba8e5cfacc 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -29,7 +29,7 @@ #include <linux/netdevice.h> #include <linux/hdlc.h> #include <linux/pci.h> -#include <asm/delay.h> +#include <linux/delay.h> #include <asm/io.h> #include "hd64572.h" diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 5380ddfcd7d..050e854e777 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <net/arp.h> +#include <asm/irq.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/byteorder.h> diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 9c1e10602f2..9d3b51c3ef5 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -27,8 +27,8 @@ #include <linux/hdlc.h> #include <linux/pci.h> #include <linux/dma-mapping.h> +#include <linux/delay.h> #include <asm/io.h> -#include <asm/delay.h> #include "wanxl.h" diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index c5cd61c7f92..e5bb9f5ae42 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, if (essid->length) { dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ /* if it is to big, trunk it */ - dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length); + dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length); } else { dwrq->flags = 0; dwrq->length = 0; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 38d6d00fb0f..014cc8d54a9 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -38,10 +38,10 @@ #include <linux/slab.h> #include <linux/completion.h> #include <linux/blkdev.h> +#include <linux/delay.h> #include <scsi/scsi_host.h> #include <scsi/scsi_device.h> #include <asm/semaphore.h> -#include <asm/delay.h> #include "aacraid.h" diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 311a4122bd7..93edaa8696c 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -537,9 +537,9 @@ static int mac53c94_remove(struct macio_dev *mdev) free_irq(fp->intr, fp); if (fp->regs) - iounmap((void *) fp->regs); + iounmap(fp->regs); if (fp->dma) - iounmap((void *) fp->dma); + iounmap(fp->dma); kfree(fp->dma_cmd_space); scsi_host_put(host); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 59a1c9d9d3b..723f7acbeb1 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -463,7 +463,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) } static void* -mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) +mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) { struct mempool_zone *zone = pool_data; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7d0700091f3..2a547538d44 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1679,7 +1679,7 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) { int sg_bufflen = tablesize * sizeof(struct scatterlist); - unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN; + gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN; /* * TODO: test without low_dma, we should not need it since diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 7aef7518b0d..8c5c276c557 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -362,7 +362,7 @@ static struct uart_ops serial21285_ops = { static struct uart_port serial21285_port = { .mapbase = 0x42000160, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = NO_IRQ, .fifosize = 16, .ops = &serial21285_ops, diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 8cbf0fc5a22..7f0f35a05dc 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -332,7 +332,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg * Make sure that we do not overflow the buffer */ if (tty_request_buffer_room(tty, 1) == 0) { - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); return; } @@ -353,7 +353,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg } while((rx = uart->urx.w) & URX_DATA_READY); #endif - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); clear_and_exit: return; diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 60f5a5dc17f..9843ae3d420 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c @@ -509,7 +509,7 @@ static _INLINE_ void receive_chars(ser_info_t *info) info->rx_cur = (QUICC_BD *)bdp; - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); } static _INLINE_ void receive_break(ser_info_t *info) @@ -521,7 +521,7 @@ static _INLINE_ void receive_break(ser_info_t *info) * the break. If not, we exit now, losing the break. FIXME */ tty_insert_flip_char(tty, 0, TTY_BREAK); - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); } static _INLINE_ void transmit_chars(ser_info_t *info) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 179c1f065e6..b1fc97d5f64 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2229,6 +2229,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) * and restore the IER */ wait_for_xmitr(up, BOTH_EMPTY); + up->ier |= UART_IER_THRI; serial_out(up, UART_IER, ier | UART_IER_THRI); } diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c index 06ae8fbcc94..8d8d7a70d03 100644 --- a/drivers/serial/8250_au1x00.c +++ b/drivers/serial/8250_au1x00.c @@ -56,7 +56,6 @@ static struct plat_serial8250_port au1x00_data[] = { #elif defined(CONFIG_SOC_AU1550) PORT(UART0_ADDR, AU1550_UART0_INT), PORT(UART1_ADDR, AU1550_UART1_INT), - PORT(UART2_ADDR, AU1550_UART2_INT), PORT(UART3_ADDR, AU1550_UART3_INT), #elif defined(CONFIG_SOC_AU1200) PORT(UART0_ADDR, AU1200_UART0_INT), diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index bb9ec28ccc2..94886c000d2 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1882,6 +1882,10 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, pbn_b0_4_1843200 }, + { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, + PCI_VENDOR_ID_AFAVLAB, + PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, + pbn_b0_4_1152000 }, { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 429de2723a1..321a3b3a572 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -561,7 +561,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { .port = { .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), .mapbase = INTEGRATOR_UART0_BASE, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = IRQ_UARTINT0, .uartclk = 14745600, .fifosize = 16, @@ -576,7 +576,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { .port = { .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), .mapbase = INTEGRATOR_UART1_BASE, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = IRQ_UARTINT1, .uartclk = 14745600, .fifosize = 16, diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index ceb5d7f37bb..344022fe53e 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c @@ -892,7 +892,7 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res int ret = 0; switch (up->port.iotype) { - case SERIAL_IO_MEM: + case UPIO_MEM: if (up->port.mapbase) { *res = request_mem_region(up->port.mapbase, size, "serial"); if (!*res) @@ -900,8 +900,8 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res } break; - case SERIAL_IO_HUB6: - case SERIAL_IO_PORT: + case UPIO_HUB6: + case UPIO_PORT: *res = request_region(up->port.iobase, size, "serial"); if (!*res) ret = -EBUSY; @@ -919,7 +919,7 @@ static void serial8250_release_port(struct uart_port *port) size <<= up->port.regshift; switch (up->port.iotype) { - case SERIAL_IO_MEM: + case UPIO_MEM: if (up->port.mapbase) { /* * Unmap the area. @@ -935,8 +935,8 @@ static void serial8250_release_port(struct uart_port *port) } break; - case SERIAL_IO_HUB6: - case SERIAL_IO_PORT: + case UPIO_HUB6: + case UPIO_PORT: start = up->port.iobase; if (size) diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 16af5626c24..b7bf4c698a4 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -252,12 +252,9 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) /* If we have not enough room in tty flip buffer, then we try * later, which will be the next rx-interrupt or a timeout */ - if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { - tty->flip.work.func((void *)tty); - if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { - printk(KERN_WARNING "TTY_DONT_FLIP set\n"); - return; - } + if(tty_buffer_request_room(tty, i) < i) { + printk(KERN_WARNING "No room in flip buffer\n"); + return; } /* get pointer */ @@ -276,9 +273,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) continue; error_return: - *tty->flip.char_buf_ptr++ = ch; - *tty->flip.flag_buf_ptr++ = flg; - tty->flip.count++; + tty_insert_flip_char(tty, ch, flg); } /* End while (i--) */ @@ -908,7 +903,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .port = { .irq = SMC1_IRQ, .ops = &cpm_uart_pops, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .lock = SPIN_LOCK_UNLOCKED, }, .flags = FLAG_SMC, @@ -922,7 +917,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .port = { .irq = SMC2_IRQ, .ops = &cpm_uart_pops, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .lock = SPIN_LOCK_UNLOCKED, }, .flags = FLAG_SMC, @@ -939,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .port = { .irq = SCC1_IRQ, .ops = &cpm_uart_pops, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, @@ -953,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .port = { .irq = SCC2_IRQ, .ops = &cpm_uart_pops, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, @@ -967,7 +962,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .port = { .irq = SCC3_IRQ, .ops = &cpm_uart_pops, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, @@ -981,7 +976,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .port = { .irq = SCC4_IRQ, .ops = &cpm_uart_pops, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index a64ba26a94e..ba5541de673 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c @@ -262,6 +262,7 @@ static inline void dz_receive_chars(struct dz_port *dport) } tty_insert_flip_char(tty, ch, flag); ignore_char: + ; } while (status & DZ_DVAL); if (tty) @@ -650,7 +651,7 @@ static void __init dz_init_ports(void) for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { spin_lock_init(&dport->port.lock); dport->port.membase = (char *) base; - dport->port.iotype = SERIAL_IO_PORT; + dport->port.iotype = UPIO_PORT; dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; dport->port.line = i; dport->port.fifosize = 1; diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 858048efe1e..4d53fb5ca87 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -668,7 +668,7 @@ static struct imx_port imx_ports[] = { .rtsirq = UART1_MINT_RTS, .port = { .type = PORT_IMX, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .membase = (void *)IMX_UART1_BASE, .mapbase = IMX_UART1_BASE, /* FIXME */ .irq = UART1_MINT_RX, @@ -684,7 +684,7 @@ static struct imx_port imx_ports[] = { .rtsirq = UART2_MINT_RTS, .port = { .type = PORT_IMX, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .membase = (void *)IMX_UART2_BASE, .mapbase = IMX_UART2_BASE, /* FIXME */ .irq = UART2_MINT_RX, diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 66f117d1506..419dd3cd786 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c @@ -215,7 +215,7 @@ static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs) /* Lower and upper byte of baud rate generator divisor. */ write_zsreg(channel, R12, regs[R12]); write_zsreg(channel, R13, regs[R13]); - + /* Now rewrite R14, with BRENAB (if set). */ write_zsreg(channel, R14, regs[R14]); @@ -571,7 +571,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl) else clear_bits |= DTR; - /* NOTE: Not subject to 'transmitter active' rule. */ + /* NOTE: Not subject to 'transmitter active' rule. */ up->curregs[R5] |= set_bits; up->curregs[R5] &= ~clear_bits; write_zsreg(channel, R5, up->curregs[R5]); @@ -654,7 +654,7 @@ static void ip22zilog_enable_ms(struct uart_port *port) if (new_reg != up->curregs[R15]) { up->curregs[R15] = new_reg; - /* NOTE: Not subject to 'transmitter active' rule. */ + /* NOTE: Not subject to 'transmitter active' rule. */ write_zsreg(channel, R15, up->curregs[R15]); } } @@ -680,7 +680,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) if (new_reg != up->curregs[R5]) { up->curregs[R5] = new_reg; - /* NOTE: Not subject to 'transmitter active' rule. */ + /* NOTE: Not subject to 'transmitter active' rule. */ write_zsreg(channel, R5, up->curregs[R5]); } diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index b48066a64a7..242a0410439 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c @@ -80,7 +80,7 @@ #include <asm/serial.h> /* Standard COM flags */ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) /* * SERIAL_PORT_DFNS tells us about built-in ports that have no diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h index 07d0dd80aa3..7c3ec24f7e5 100644 --- a/drivers/serial/m32r_sio.h +++ b/drivers/serial/m32r_sio.h @@ -37,7 +37,7 @@ struct old_serial_port { unsigned int irq; unsigned int flags; unsigned char io_type; - unsigned char *iomem_base; + unsigned char __iomem *iomem_base; unsigned short iomem_reg_shift; }; diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 0ef648fa4b2..8cbbb954df2 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c @@ -57,20 +57,16 @@ struct timer_list mcfrs_timer_struct; * keep going. Perhaps one day the cflag settings for the * console can be used instead. */ -#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ - defined(CONFIG_senTec) || defined(CONFIG_SNEHA) -#define CONSOLE_BAUD_RATE 19200 -#define DEFAULT_CBAUD B19200 -#endif - #if defined(CONFIG_HW_FEITH) #define CONSOLE_BAUD_RATE 38400 #define DEFAULT_CBAUD B38400 -#endif - -#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) +#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) #define CONSOLE_BAUD_RATE 115200 #define DEFAULT_CBAUD B115200 +#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ + defined(CONFIG_senTec) || defined(CONFIG_SNEHA) +#define CONSOLE_BAUD_RATE 19200 +#define DEFAULT_CBAUD B19200 #endif #ifndef CONSOLE_BAUD_RATE @@ -350,7 +346,7 @@ static inline void receive_chars(struct mcf_serial *info) } tty_insert_flip_char(tty, ch, flag); } - tty_flip_buffer_push(tty); + tty_schedule_flip(tty); return; } diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 4e49168c317..868eaf4a1a6 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -462,7 +462,7 @@ static int __init mux_probe(struct parisc_device *dev) port->mapbase = dev->hpa.start + MUX_OFFSET + (i * MUX_LINE_OFFSET); port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); - port->iotype = SERIAL_IO_MEM; + port->iotype = UPIO_MEM; port->type = PORT_MUX; port->irq = NO_IRQ; port->uartclk = 0; diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4e03a87f3fb..9b7ed58cb53 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1492,7 +1492,7 @@ no_dma: /* * Init remaining bits of "port" structure */ - uap->port.iotype = SERIAL_IO_MEM; + uap->port.iotype = UPIO_MEM; uap->port.irq = np->intrs[0].line; uap->port.uartclk = ZS_CLOCK; uap->port.fifosize = 1; diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 0a2dd6c5b95..7410e093a6b 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -161,7 +161,11 @@ s3c24xx_serial_dbg(const char *fmt, ...) /* we can support 3 uarts, but not always use them */ +#ifdef CONFIG_CPU_S3C2400 +#define NR_PORTS (2) +#else #define NR_PORTS (3) +#endif /* port irq numbers */ diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index ff7b60b4de3..2c00b862585 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -628,7 +628,7 @@ static void __init sa1100_init_ports(void) sa1100_ports[i].port.ops = &sa1100_pops; sa1100_ports[i].port.fifosize = 8; sa1100_ports[i].port.line = i; - sa1100_ports[i].port.iotype = SERIAL_IO_MEM; + sa1100_ports[i].port.iotype = UPIO_MEM; init_timer(&sa1100_ports[i].timer); sa1100_ports[i].timer.function = sa1100_timeout; sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d0490f67f59..04186eaae22 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c @@ -501,7 +501,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { .port = { .membase = (void*) io_p2v (UART1_PHYS), .mapbase = UART1_PHYS, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = IRQ_UART1INTR, .uartclk = 14745600/2, .fifosize = 16, @@ -514,7 +514,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { .port = { .membase = (void*) io_p2v (UART2_PHYS), .mapbase = UART2_PHYS, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = IRQ_UART2INTR, .uartclk = 14745600/2, .fifosize = 16, @@ -527,7 +527,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { .port = { .membase = (void*) io_p2v (UART3_PHYS), .mapbase = UART3_PHYS, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = IRQ_UART3INTR, .uartclk = 14745600/2, .fifosize = 16, diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 80737c131ce..44f6bf79bbe 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1468,10 +1468,10 @@ static struct sci_port sci_ports[] = { .port = { .membase = (void *)0xff923000, .mapbase = 0xff923000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 61, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1482,10 +1482,10 @@ static struct sci_port sci_ports[] = { .port = { .membase = (void *)0xff924000, .mapbase = 0xff924000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 62, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, @@ -1496,10 +1496,10 @@ static struct sci_port sci_ports[] = { .port = { .membase = (void *)0xff925000, .mapbase = 0xff925000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 63, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 2, }, .type = PORT_SCIF, @@ -1511,10 +1511,10 @@ static struct sci_port sci_ports[] = { .port = { .membase = (void *)0xffe00000, .mapbase = 0xffe00000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 43, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1525,10 +1525,10 @@ static struct sci_port sci_ports[] = { .port = { .membase = (void *)0xffe10000, .mapbase = 0xffe10000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 79, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 8bcaebcc0ad..85664228a0b 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -1036,7 +1036,7 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg up->port.irq = edev->irqs[0]; up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; up->port.mapbase = (unsigned long)up->regs; - up->port.iotype = SERIAL_IO_MEM; + up->port.iotype = UPIO_MEM; writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index bc67442c6b4..30870456694 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -109,11 +109,11 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) offset <<= up->port.regshift; switch (up->port.iotype) { - case SERIAL_IO_HUB6: + case UPIO_HUB6: outb(up->port.hub6 - 1 + offset, up->port.iobase); return inb(up->port.iobase + 1); - case SERIAL_IO_MEM: + case UPIO_MEM: return readb(up->port.membase + offset); default: @@ -139,12 +139,12 @@ serial_out(struct uart_sunsu_port *up, int offset, int value) offset <<= up->port.regshift; switch (up->port.iotype) { - case SERIAL_IO_HUB6: + case UPIO_HUB6: outb(up->port.hub6 - 1 + offset, up->port.iobase); outb(value, up->port.iobase + 1); break; - case SERIAL_IO_MEM: + case UPIO_MEM: writeb(value, up->port.membase + offset); break; @@ -1052,7 +1052,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) return; up->type_probed = PORT_UNKNOWN; - up->port.iotype = SERIAL_IO_MEM; + up->port.iotype = UPIO_MEM; /* * First we look for Ebus-bases su's diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 3c72484adea..5cc4d4c2935 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1487,7 +1487,7 @@ static void __init sunzilog_prepare(void) up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; /* Channel A */ - up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM; + up[(chip * 2) + 0].port.iotype = UPIO_MEM; up[(chip * 2) + 0].port.irq = zilog_irq; up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; up[(chip * 2) + 0].port.fifosize = 1; @@ -1498,7 +1498,7 @@ static void __init sunzilog_prepare(void) up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; /* Channel B */ - up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM; + up[(chip * 2) + 1].port.iotype = UPIO_MEM; up[(chip * 2) + 1].port.irq = zilog_irq; up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; up[(chip * 2) + 1].port.fifosize = 1; diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c index 9378895a8d5..df705fda424 100644 --- a/drivers/serial/v850e_uart.c +++ b/drivers/serial/v850e_uart.c @@ -496,7 +496,7 @@ static int __init v850e_uart_init (void) port->ops = &v850e_uart_ops; port->line = chan; - port->iotype = SERIAL_IO_MEM; + port->iotype = UPIO_MEM; port->flags = UPF_BOOT_AUTOCONF; /* We actually use multiple IRQs, but the serial diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index c70ae81b5d9..12357e1fa55 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c @@ -38,10 +38,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample) static int nic_wait(struct ioc3_driver_data *idd) { - volatile unsigned mcr; + unsigned mcr; do { - mcr = (volatile unsigned)idd->vma->mcr; + mcr = readl(&idd->vma->mcr); } while (!(mcr & 2)); return mcr & 1; @@ -53,7 +53,7 @@ static int nic_reset(struct ioc3_driver_data *idd) unsigned long flags; local_irq_save(flags); - idd->vma->mcr = mcr_pack(500, 65); + writel(mcr_pack(500, 65), &idd->vma->mcr); presence = nic_wait(idd); local_irq_restore(flags); @@ -68,7 +68,7 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) unsigned long flags; local_irq_save(flags); - idd->vma->mcr = mcr_pack(6, 13); + writel(mcr_pack(6, 13), &idd->vma->mcr); result = nic_wait(idd); local_irq_restore(flags); @@ -80,9 +80,9 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) { if (bit) - idd->vma->mcr = mcr_pack(6, 110); + writel(mcr_pack(6, 110), &idd->vma->mcr); else - idd->vma->mcr = mcr_pack(80, 30); + writel(mcr_pack(80, 30), &idd->vma->mcr); nic_wait(idd); } @@ -337,7 +337,7 @@ static void probe_nic(struct ioc3_driver_data *idd) int save = 0, loops = 3; unsigned long first, addr; - idd->vma->gpcr_s = GPCR_MLAN_EN; + writel(GPCR_MLAN_EN, &idd->vma->gpcr_s); while(loops>0) { idd->nic_part[0] = 0; @@ -408,7 +408,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) read_lock_irqsave(&ioc3_submodules_lock, flags); - if(idd->dual_irq && idd->vma->eisr) { + if(idd->dual_irq && readb(&idd->vma->eisr)) { /* send Ethernet IRQ to the driver */ if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && ioc3_ethernet->intr) { @@ -682,7 +682,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) idd->id = ioc3_counter++; up_write(&ioc3_devices_rwsem); - idd->gpdr_shadow = idd->vma->gpdr; + idd->gpdr_shadow = readl(&idd->vma->gpdr); /* Read IOC3 NIC contents */ probe_nic(idd); diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b77dbd63e59..7a75faeb052 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -75,16 +75,6 @@ config SPI_BUTTERFLY inexpensive battery powered microcontroller evaluation board. This same cable can be used to flash new firmware. -config SPI_BUTTERFLY - tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" - depends on SPI_MASTER && PARPORT && EXPERIMENTAL - select SPI_BITBANG - help - This uses a custom parallel port cable to connect to an AVR - Butterfly <http://www.atmel.com/products/avr/butterfly>, an - inexpensive battery powered microcontroller evaluation board. - This same cable can be used to flash new firmware. - # # Add new SPI master controllers in alphabetical order above this line # diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 79a3c59615a..ff9e5faa4dc 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c @@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value) struct butterfly *pp = spidev_to_pp(spi); /* set default clock polarity */ - if (value) + if (value != BITBANG_CS_INACTIVE) setsck(spi, spi->mode & SPI_CPOL); /* no chipselect on this USI link config */ if (is_usidev(spi)) return; - /* here, value == "activate or not" */ - - /* most PARPORT_CONTROL_* bits are negated */ + /* here, value == "activate or not"; + * most PARPORT_CONTROL_* bits are negated, so we must + * morph it to value == "bit value to write in control register" + */ if (spi_cs_bit == PARPORT_CONTROL_INIT) value = !value; - /* here, value == "bit value to write in control register" */ - parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); } @@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi, /* override default partitioning with cmdlinepart */ static struct mtd_partition partitions[] = { { - /* JFFS2 wants partitions of 4*N blocks for this device ... */ + /* JFFS2 wants partitions of 4*N blocks for this device, + * so sectors 0 and 1 can't be partitions by themselves. + */ /* sector 0 = 8 pages * 264 bytes/page (1 block) * sector 1 = 248 pages * 264 bytes/page @@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p) if (status < 0) goto clean2; - /* Bus 1 lets us talk to at45db041b (firmware disables AVR) - * or AVR (firmware resets at45, acts as spi slave) + /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR + * (firmware resets at45, acts as spi slave) or neither (we ignore + * both, AVR uses AT45). Here we expect firmware for the first option. */ pp->info[0].max_speed_hz = 15 * 1000 * 1000; strcpy(pp->info[0].modalias, "mtd_dataflash"); @@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p) pp->dataflash->dev.bus_id); #ifdef HAVE_USI - /* even more custom AVR firmware */ + /* Bus 2 is only for talking to the AVR, and it can work no + * matter who masters bus 1; needs appropriate AVR firmware. + */ pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; strcpy(pp->info[1].modalias, "butterfly"); // pp->info[1].platform_data = ... TBD ... ; @@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p) pp = butterfly; butterfly = NULL; -#ifdef HAVE_USI - spi_unregister_device(pp->butterfly); - pp->butterfly = NULL; -#endif - spi_unregister_device(pp->dataflash); - pp->dataflash = NULL; - + /* stop() unregisters child devices too */ + pdev = to_platform_device(pp->bitbang.master->cdev.dev); status = spi_bitbang_stop(&pp->bitbang); /* turn off VCC */ @@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p) parport_release(pp->pd); parport_unregister_device(pp->pd); - pdev = to_platform_device(pp->bitbang.master->cdev.dev); - (void) spi_master_put(pp->bitbang.master); platform_device_unregister(pdev); @@ -420,4 +417,5 @@ static void __exit butterfly_exit(void) } module_exit(butterfly_exit); +MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly"); MODULE_LICENSE("GPL"); diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index a0e5af638e0..4a51e56f85b 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c @@ -17,7 +17,6 @@ #include <linux/types.h> #include <asm/addrspace.h> -#include <asm/bug.h> #include <asm/errno.h> #include <asm/io.h> #include <asm/paccess.h> diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 9d5015e9937..bd39bbd88d4 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -13,7 +13,6 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/fb.h> -#include <asm/bug.h> static ssize_t backlight_show_power(struct class_device *cdev, char *buf) { diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 68c690605aa..9e32485ee7b 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -13,7 +13,6 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/fb.h> -#include <asm/bug.h> static ssize_t lcd_show_power(struct class_device *cdev, char *buf) { diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index f3927b6cda9..f5361cd8ccc 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c @@ -30,7 +30,6 @@ #include <linux/module.h> #include <linux/types.h> -#include <asm/bug.h> #include <asm/io.h> #include <asm/system.h> diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 25148de5fe6..eeeac924b50 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c @@ -27,7 +27,6 @@ #include <linux/module.h> #include <linux/types.h> -#include <asm/bug.h> #include <asm/io.h> #include <asm/system.h> diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 5dd0207ffd4..057e60217fc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -931,8 +931,8 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { int err, i; - sg_req_info_t *r; - struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg; + sg_req_info_t __user *r; + struct compat_sg_req_info __user *o = (void __user *)arg; r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); err = sys_ioctl(fd,cmd,(unsigned long)r); if (err < 0) @@ -2739,8 +2739,8 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon static int lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct compat_timeval *tc = (struct compat_timeval *)arg; - struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval)); + struct compat_timeval __user *tc = (struct compat_timeval __user *)arg; + struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval)); struct timeval ts; if (get_user(ts.tv_sec, &tc->tv_sec) || get_user(ts.tv_usec, &tc->tv_usec) || diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index efc97d9b786..d575452cd9f 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -56,7 +56,7 @@ static u64 debugfs_u8_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); /** - * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. + * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write an unsigned 8 bit value. * * @name: a pointer to a string containing the name of the file to create. * @mode: the permission that the file should have @@ -98,7 +98,7 @@ static u64 debugfs_u16_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); /** - * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. + * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write an unsigned 16 bit value. * * @name: a pointer to a string containing the name of the file to create. * @mode: the permission that the file should have @@ -140,7 +140,7 @@ static u64 debugfs_u32_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); /** - * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. + * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write an unsigned 32 bit value. * * @name: a pointer to a string containing the name of the file to create. * @mode: the permission that the file should have diff --git a/fs/inotify.c b/fs/inotify.c index 878ccca6121..3041503bde0 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -967,7 +967,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) mask_add = 1; /* don't let user-space set invalid bits: we don't want flags set */ - mask &= IN_ALL_EVENTS; + mask &= IN_ALL_EVENTS | IN_ONESHOT; if (unlikely(!mask)) { ret = -EINVAL; goto out; diff --git a/fs/namei.c b/fs/namei.c index faf61c35308..e28de846c59 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1119,9 +1119,11 @@ static int fastcall do_path_lookup(int dfd, const char *name, current->total_link_count = 0; retval = link_path_walk(name, nd); out: - if (unlikely(current->audit_context - && nd && nd->dentry && nd->dentry->d_inode)) + if (likely(retval == 0)) { + if (unlikely(current->audit_context && nd && nd->dentry && + nd->dentry->d_inode)) audit_inode(name, nd->dentry->d_inode, flags); + } return retval; fput_unlock_fail: diff --git a/fs/namespace.c b/fs/namespace.c index ce97becff46..058a44865be 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -494,7 +494,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) p->mnt_namespace = NULL; list_del_init(&p->mnt_child); if (p->mnt_parent != p) - mnt->mnt_mountpoint->d_mounted--; + p->mnt_mountpoint->d_mounted--; change_mnt_propagation(p, MS_PRIVATE); } } @@ -1325,27 +1325,17 @@ dput_out: return retval; } -int copy_namespace(int flags, struct task_struct *tsk) +/* + * Allocate a new namespace structure and populate it with contents + * copied from the namespace of the passed in task structure. + */ +struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) { struct namespace *namespace = tsk->namespace; struct namespace *new_ns; struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; - struct fs_struct *fs = tsk->fs; struct vfsmount *p, *q; - if (!namespace) - return 0; - - get_namespace(namespace); - - if (!(flags & CLONE_NEWNS)) - return 0; - - if (!capable(CAP_SYS_ADMIN)) { - put_namespace(namespace); - return -EPERM; - } - new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); if (!new_ns) goto out; @@ -1396,8 +1386,6 @@ int copy_namespace(int flags, struct task_struct *tsk) } up_write(&namespace_sem); - tsk->namespace = new_ns; - if (rootmnt) mntput(rootmnt); if (pwdmnt) @@ -1405,12 +1393,40 @@ int copy_namespace(int flags, struct task_struct *tsk) if (altrootmnt) mntput(altrootmnt); - put_namespace(namespace); - return 0; +out: + return new_ns; +} + +int copy_namespace(int flags, struct task_struct *tsk) +{ + struct namespace *namespace = tsk->namespace; + struct namespace *new_ns; + int err = 0; + + if (!namespace) + return 0; + + get_namespace(namespace); + + if (!(flags & CLONE_NEWNS)) + return 0; + + if (!capable(CAP_SYS_ADMIN)) { + err = -EPERM; + goto out; + } + + new_ns = dup_namespace(tsk, tsk->fs); + if (!new_ns) { + err = -ENOMEM; + goto out; + } + + tsk->namespace = new_ns; out: put_namespace(namespace); - return -ENOMEM; + return err; } asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index e897e00c2c9..c0a754ecdee 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -465,10 +465,11 @@ static int __init root_nfs_ports(void) "number from server, using default\n"); port = nfsd_port; } - nfs_port = htons(port); + nfs_port = port; dprintk("Root-NFS: Portmapper on server returned %d " "as nfsd port\n", port); } + nfs_port = htons(nfs_port); if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { printk(KERN_ERR "Root-NFS: Unable to get mountd port " diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a00fe868629..6d63f1d9e5f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -195,10 +195,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open /* Openowner is now set, so sequence id will get bumped. Now we need * these checks before we do any creates: */ + status = nfserr_grace; if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) - return nfserr_grace; + goto out; + status = nfserr_no_grace; if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) - return nfserr_no_grace; + goto out; switch (open->op_claim_type) { case NFS4_OPEN_CLAIM_DELEGATE_CUR: diff --git a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c index a3ec238fd9e..e664ac16fad 100644 --- a/fs/reiserfs/hashes.c +++ b/fs/reiserfs/hashes.c @@ -21,7 +21,6 @@ #include <linux/kernel.h> #include <linux/reiserfs_fs.h> #include <asm/types.h> -#include <asm/bug.h> #define DELTA 0x9E3779B9 #define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ diff --git a/fs/select.c b/fs/select.c index c0f02d36c60..bc60a3e14ef 100644 --- a/fs/select.c +++ b/fs/select.c @@ -510,9 +510,9 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, if (sig) { if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t)) - || __get_user(up, (sigset_t * __user *)sig) + || __get_user(up, (sigset_t __user * __user *)sig) || __get_user(sigsetsize, - (size_t * __user)(sig+sizeof(void *)))) + (size_t __user *)(sig+sizeof(void *)))) return -EFAULT; } diff --git a/fs/super.c b/fs/super.c index c177b92419c..30294218fa6 100644 --- a/fs/super.c +++ b/fs/super.c @@ -247,8 +247,9 @@ void generic_shutdown_super(struct super_block *sb) /* Forget any remaining inodes */ if (invalidate_inodes(sb)) { - printk("VFS: Busy inodes after unmount. " - "Self-destruct in 5 seconds. Have a nice day...\n"); + printk("VFS: Busy inodes after unmount of %s. " + "Self-destruct in 5 seconds. Have a nice day...\n", + sb->s_id); } unlock_kernel(); diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 9892268e300..8f2beec526c 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -747,10 +747,11 @@ xfs_convert_page( struct backing_dev_info *bdi; bdi = inode->i_mapping->backing_dev_info; + wbc->nr_to_write--; if (bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; done = 1; - } else if (--wbc->nr_to_write <= 0) { + } else if (wbc->nr_to_write <= 0) { done = 1; } } diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index eda7919b70a..d7f6f2d8ac8 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -673,6 +673,8 @@ linvfs_setattr( if (ia_valid & ATTR_ATIME) { vattr.va_mask |= XFS_AT_ATIME; vattr.va_atime = attr->ia_atime; + if (ia_valid & ATTR_ATIME_SET) + inode->i_atime = attr->ia_atime; } if (ia_valid & ATTR_MTIME) { vattr.va_mask |= XFS_AT_MTIME; diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index cc9c7e8cced..f3b7b1a59c5 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -572,7 +572,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) if something tries to do an invalid cmpxchg(). */ extern void __cmpxchg_called_with_bad_pointer(void); -static inline unsigned long +static __always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { switch (size) { diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h index f5bcc9a1aed..b726acfcab1 100644 --- a/include/asm-arm/arch-omap/io.h +++ b/include/asm-arm/arch-omap/io.h @@ -116,7 +116,11 @@ typedef struct { volatile u32 offset[4096]; } __regbase32; ->offset[((vaddr)&4095)>>2] #define __REG32(paddr) __REGV32(io_p2v(paddr)) -extern void omap_map_common_io(void); +extern void omap1_map_common_io(void); +extern void omap1_init_common_hw(void); + +extern void omap2_map_common_io(void); +extern void omap2_init_common_hw(void); #else diff --git a/include/asm-arm/mutex.h b/include/asm-arm/mutex.h index 6caa59f1f59..cb29d84e690 100644 --- a/include/asm-arm/mutex.h +++ b/include/asm-arm/mutex.h @@ -23,72 +23,71 @@ * simply bail out immediately through the slow path where the lock will be * reattempted until it succeeds. */ -#define __mutex_fastpath_lock(count, fail_fn) \ -do { \ - int __ex_flag, __res; \ - \ - typecheck(atomic_t *, count); \ - typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ - \ - __asm__ ( \ - "ldrex %0, [%2] \n" \ - "sub %0, %0, #1 \n" \ - "strex %1, %0, [%2] \n" \ - \ - : "=&r" (__res), "=&r" (__ex_flag) \ - : "r" (&(count)->counter) \ - : "cc","memory" ); \ - \ - if (unlikely(__res || __ex_flag)) \ - fail_fn(count); \ -} while (0) - -#define __mutex_fastpath_lock_retval(count, fail_fn) \ -({ \ - int __ex_flag, __res; \ - \ - typecheck(atomic_t *, count); \ - typecheck_fn(fastcall int (*)(atomic_t *), fail_fn); \ - \ - __asm__ ( \ - "ldrex %0, [%2] \n" \ - "sub %0, %0, #1 \n" \ - "strex %1, %0, [%2] \n" \ - \ - : "=&r" (__res), "=&r" (__ex_flag) \ - : "r" (&(count)->counter) \ - : "cc","memory" ); \ - \ - __res |= __ex_flag; \ - if (unlikely(__res != 0)) \ - __res = fail_fn(count); \ - __res; \ -}) +static inline void +__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + fail_fn(count); +} + +static inline int +__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + __res = fail_fn(count); + return __res; +} /* * Same trick is used for the unlock fast path. However the original value, * rather than the result, is used to test for success in order to have * better generated assembly. */ -#define __mutex_fastpath_unlock(count, fail_fn) \ -do { \ - int __ex_flag, __res, __orig; \ - \ - typecheck(atomic_t *, count); \ - typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ - \ - __asm__ ( \ - "ldrex %0, [%3] \n" \ - "add %1, %0, #1 \n" \ - "strex %2, %1, [%3] \n" \ - \ - : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) \ - : "r" (&(count)->counter) \ - : "cc","memory" ); \ - \ - if (unlikely(__orig || __ex_flag)) \ - fail_fn(count); \ -} while (0) +static inline void +__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "ldrex %0, [%3] \n\t" + "add %1, %0, #1 \n\t" + "strex %2, %1, [%3] " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __orig |= __ex_flag; + if (unlikely(__orig != 0)) + fail_fn(count); +} /* * If the unlock was done on a contended lock, or if the unlock simply fails @@ -110,12 +109,12 @@ __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) __asm__ ( - "1: ldrex %0, [%3] \n" - "subs %1, %0, #1 \n" - "strexeq %2, %1, [%3] \n" - "movlt %0, #0 \n" - "cmpeq %2, #0 \n" - "bgt 1b \n" + "1: ldrex %0, [%3] \n\t" + "subs %1, %0, #1 \n\t" + "strexeq %2, %1, [%3] \n\t" + "movlt %0, #0 \n\t" + "cmpeq %2, #0 \n\t" + "bgt 1b " : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) : "r" (&count->counter) diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 597496ed2ae..cf6f2cd9c51 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -315,8 +315,9 @@ #define __NR_faccessat 307 #define __NR_pselect6 308 #define __NR_ppoll 309 +#define __NR_unshare 310 -#define NR_syscalls 310 +#define NR_syscalls 311 /* * user-visible error numbers are in the range -1 - -128: see diff --git a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h index e8659e739a6..476180f4cba 100644 --- a/include/asm-m68knommu/hardirq.h +++ b/include/asm-m68knommu/hardirq.h @@ -4,6 +4,7 @@ #include <linux/config.h> #include <linux/cache.h> #include <linux/threads.h> +#include <asm/irq.h> typedef struct { unsigned int __softirq_pending; diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h index 2e7e651c3e3..1ce0518ace2 100644 --- a/include/asm-mips/abi.h +++ b/include/asm-mips/abi.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2005 by Ralf Baechle + * Copyright (C) 2005, 06 by Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 2005 MIPS Technologies, Inc. */ #ifndef _ASM_ABI_H @@ -13,7 +13,7 @@ #include <asm/siginfo.h> struct mips_abi { - int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs); + void (* const do_signal)(struct pt_regs *regs); int (* const setup_frame)(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set); diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index d42685747e7..5a4c8a54b8f 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -18,7 +18,6 @@ #include <linux/types.h> #include <asm/addrspace.h> -#include <asm/bug.h> #include <asm/byteorder.h> #include <asm/cpu.h> #include <asm/cpu-features.h> @@ -57,38 +56,38 @@ * variations of functions: non-prefixed ones that preserve the value * and prefixed ones that preserve byte addresses. The latters are * typically used for moving raw data between a peripheral and memory (cf. - * string I/O functions), hence the "mem_" prefix. + * string I/O functions), hence the "__mem_" prefix. */ #if defined(CONFIG_SWAP_IO_SPACE) # define ioswabb(x) (x) -# define mem_ioswabb(x) (x) +# define __mem_ioswabb(x) (x) # ifdef CONFIG_SGI_IP22 /* * IP22 seems braindead enough to swap 16bits values in hardware, but * not 32bits. Go figure... Can't tell without documentation. */ # define ioswabw(x) (x) -# define mem_ioswabw(x) le16_to_cpu(x) +# define __mem_ioswabw(x) le16_to_cpu(x) # else # define ioswabw(x) le16_to_cpu(x) -# define mem_ioswabw(x) (x) +# define __mem_ioswabw(x) (x) # endif # define ioswabl(x) le32_to_cpu(x) -# define mem_ioswabl(x) (x) +# define __mem_ioswabl(x) (x) # define ioswabq(x) le64_to_cpu(x) -# define mem_ioswabq(x) (x) +# define __mem_ioswabq(x) (x) #else # define ioswabb(x) (x) -# define mem_ioswabb(x) (x) +# define __mem_ioswabb(x) (x) # define ioswabw(x) (x) -# define mem_ioswabw(x) cpu_to_le16(x) +# define __mem_ioswabw(x) cpu_to_le16(x) # define ioswabl(x) (x) -# define mem_ioswabl(x) cpu_to_le32(x) +# define __mem_ioswabl(x) cpu_to_le32(x) # define ioswabq(x) (x) -# define mem_ioswabq(x) cpu_to_le32(x) +# define __mem_ioswabq(x) cpu_to_le32(x) #endif @@ -343,7 +342,7 @@ static inline void pfx##write##bwlq(type val, \ BUG(); \ } \ \ -static inline type pfx##read##bwlq(volatile void __iomem *mem) \ +static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ { \ volatile type *__mem; \ type __val; \ @@ -418,7 +417,7 @@ __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) \ __BUILD_MEMORY_PFX(__raw_, bwlq, type) \ __BUILD_MEMORY_PFX(, bwlq, type) \ -__BUILD_MEMORY_PFX(mem_, bwlq, type) \ +__BUILD_MEMORY_PFX(__mem_, bwlq, type) \ BUILDIO_MEM(b, u8) BUILDIO_MEM(w, u16) @@ -431,7 +430,7 @@ BUILDIO_MEM(q, u64) #define BUILDIO_IOPORT(bwlq, type) \ __BUILD_IOPORT_PFX(, bwlq, type) \ - __BUILD_IOPORT_PFX(mem_, bwlq, type) + __BUILD_IOPORT_PFX(__mem_, bwlq, type) BUILDIO_IOPORT(b, u8) BUILDIO_IOPORT(w, u16) @@ -465,7 +464,7 @@ static inline void writes##bwlq(volatile void __iomem *mem, \ const volatile type *__addr = addr; \ \ while (count--) { \ - mem_write##bwlq(*__addr, mem); \ + __mem_write##bwlq(*__addr, mem); \ __addr++; \ } \ } \ @@ -476,7 +475,7 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ volatile type *__addr = addr; \ \ while (count--) { \ - *__addr = mem_read##bwlq(mem); \ + *__addr = __mem_read##bwlq(mem); \ __addr++; \ } \ } @@ -489,7 +488,7 @@ static inline void outs##bwlq(unsigned long port, const void *addr, \ const volatile type *__addr = addr; \ \ while (count--) { \ - mem_out##bwlq(*__addr, port); \ + __mem_out##bwlq(*__addr, port); \ __addr++; \ } \ } \ @@ -500,7 +499,7 @@ static inline void ins##bwlq(unsigned long port, void *addr, \ volatile type *__addr = addr; \ \ while (count--) { \ - *__addr = mem_in##bwlq(port); \ + *__addr = __mem_in##bwlq(port); \ __addr++; \ } \ } diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index 1612b3fe108..fa193f861e7 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -114,6 +114,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ #define TIF_SECCOMP 5 /* secure computing */ +#define TIF_RESTORE_SIGMASK 9 /* 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 @@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1<<TIF_SECCOMP) +#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) #define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 89ea8b60e94..e7ff9b18778 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -307,17 +307,33 @@ #define __NR_inotify_init (__NR_Linux + 284) #define __NR_inotify_add_watch (__NR_Linux + 285) #define __NR_inotify_rm_watch (__NR_Linux + 286) - +#define __NR_migrate_pages (__NR_Linux + 287) +#define __NR_openat (__NR_Linux + 288) +#define __NR_mkdirat (__NR_Linux + 289) +#define __NR_mknodat (__NR_Linux + 290) +#define __NR_fchownat (__NR_Linux + 291) +#define __NR_futimesat (__NR_Linux + 292) +#define __NR_newfstatat (__NR_Linux + 293) +#define __NR_unlinkat (__NR_Linux + 294) +#define __NR_renameat (__NR_Linux + 295) +#define __NR_linkat (__NR_Linux + 296) +#define __NR_symlinkat (__NR_Linux + 297) +#define __NR_readlinkat (__NR_Linux + 298) +#define __NR_fchmodat (__NR_Linux + 299) +#define __NR_faccessat (__NR_Linux + 300) +#define __NR_pselect6 (__NR_Linux + 301) +#define __NR_ppoll (__NR_Linux + 302) +#define __NR_unshare (__NR_Linux + 303) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 286 +#define __NR_Linux_syscalls 303 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 283 +#define __NR_O32_Linux_syscalls 303 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -571,16 +587,33 @@ #define __NR_inotify_init (__NR_Linux + 243) #define __NR_inotify_add_watch (__NR_Linux + 244) #define __NR_inotify_rm_watch (__NR_Linux + 245) +#define __NR_migrate_pages (__NR_Linux + 246) +#define __NR_openat (__NR_Linux + 247) +#define __NR_mkdirat (__NR_Linux + 248) +#define __NR_mknodat (__NR_Linux + 249) +#define __NR_fchownat (__NR_Linux + 250) +#define __NR_futimesat (__NR_Linux + 251) +#define __NR_newfstatat (__NR_Linux + 252) +#define __NR_unlinkat (__NR_Linux + 253) +#define __NR_renameat (__NR_Linux + 254) +#define __NR_linkat (__NR_Linux + 255) +#define __NR_symlinkat (__NR_Linux + 256) +#define __NR_readlinkat (__NR_Linux + 257) +#define __NR_fchmodat (__NR_Linux + 258) +#define __NR_faccessat (__NR_Linux + 259) +#define __NR_pselect6 (__NR_Linux + 260) +#define __NR_ppoll (__NR_Linux + 261) +#define __NR_unshare (__NR_Linux + 262) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 245 +#define __NR_Linux_syscalls 262 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 242 +#define __NR_64_Linux_syscalls 262 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -838,16 +871,33 @@ #define __NR_inotify_init (__NR_Linux + 247) #define __NR_inotify_add_watch (__NR_Linux + 248) #define __NR_inotify_rm_watch (__NR_Linux + 249) +#define __NR_migrate_pages (__NR_Linux + 250) +#define __NR_openat (__NR_Linux + 251) +#define __NR_mkdirat (__NR_Linux + 252) +#define __NR_mknodat (__NR_Linux + 253) +#define __NR_fchownat (__NR_Linux + 254) +#define __NR_futimesat (__NR_Linux + 255) +#define __NR_newfstatat (__NR_Linux + 256) +#define __NR_unlinkat (__NR_Linux + 257) +#define __NR_renameat (__NR_Linux + 258) +#define __NR_linkat (__NR_Linux + 259) +#define __NR_symlinkat (__NR_Linux + 260) +#define __NR_readlinkat (__NR_Linux + 261) +#define __NR_fchmodat (__NR_Linux + 262) +#define __NR_faccessat (__NR_Linux + 263) +#define __NR_pselect6 (__NR_Linux + 264) +#define __NR_ppoll (__NR_Linux + 265) +#define __NR_unshare (__NR_Linux + 266) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 249 +#define __NR_Linux_syscalls 266 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 246 +#define __NR_N32_Linux_syscalls 266 #ifndef __ASSEMBLY__ diff --git a/include/asm-powerpc/compat.h b/include/asm-powerpc/compat.h index accb80c9a33..aacaabd28ac 100644 --- a/include/asm-powerpc/compat.h +++ b/include/asm-powerpc/compat.h @@ -126,6 +126,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr) return (void __user *)(unsigned long)uptr; } +static inline compat_uptr_t ptr_to_compat(void __user *uptr) +{ + return (u32)(unsigned long)uptr; +} + static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = current->thread.regs; diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 837756ab7dc..2ac63f56959 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -15,7 +15,6 @@ #include <linux/mm.h> #include <asm/scatterlist.h> #include <asm/io.h> -#include <asm/bug.h> #define DMA_ERROR_CODE (~(dma_addr_t)0x0) diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 5b2bd4eefb0..cbd297f44cc 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -222,5 +222,7 @@ extern int of_address_to_resource(struct device_node *dev, int index, extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); +extern void kdump_move_device_tree(void); + #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h index 82ce4760777..2dc93632f21 100644 --- a/include/asm-powerpc/smu.h +++ b/include/asm-powerpc/smu.h @@ -521,6 +521,11 @@ struct smu_sdbp_cpupiddata { extern struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size); +/* Get "sdb" partition data from an SMU satellite */ +extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, + int id, unsigned int *size); + + #endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index 67cdaf3ae9f..c044ec16a87 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -37,7 +37,7 @@ struct thread_info { int preempt_count; /* 0 => preemptable, <0 => BUG */ struct restart_block restart_block; - void *nvgprs_frame; + void __user *nvgprs_frame; /* low level flags - has atomic operations done on it */ unsigned long flags ____cacheline_aligned_in_smp; }; diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h index be104f21c70..0b7c0ca4c3d 100644 --- a/include/asm-s390/uaccess.h +++ b/include/asm-s390/uaccess.h @@ -61,7 +61,7 @@ #define segment_eq(a,b) ((a).ar4 == (b).ar4) -static inline int __access_ok(const void *addr, unsigned long size) +static inline int __access_ok(const void __user *addr, unsigned long size) { return 1; } @@ -208,25 +208,25 @@ extern int __put_user_bad(void) __attribute__((noreturn)); case 1: { \ unsigned char __x; \ __get_user_asm(__x, ptr, __gu_err); \ - (x) = *(__typeof__(*(ptr)) *) &__x; \ + (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ case 2: { \ unsigned short __x; \ __get_user_asm(__x, ptr, __gu_err); \ - (x) = *(__typeof__(*(ptr)) *) &__x; \ + (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ case 4: { \ unsigned int __x; \ __get_user_asm(__x, ptr, __gu_err); \ - (x) = *(__typeof__(*(ptr)) *) &__x; \ + (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ case 8: { \ unsigned long long __x; \ __get_user_asm(__x, ptr, __gu_err); \ - (x) = *(__typeof__(*(ptr)) *) &__x; \ + (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ default: \ diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 2ac64e65e33..0615d601a7c 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -315,11 +315,12 @@ #define __NR_faccessat 296 #define __NR_pselect6 297 #define __NR_ppoll 298 +#define __NR_unshare 299 -/* WARNING: You MAY NOT add syscall numbers larger than 298, since +/* WARNING: You MAY NOT add syscall numbers larger than 299, since * all of the syscall tables in the Sparc kernel are - * sized to have 298 entries (starting at zero). Therefore - * find a free slot in the 0-298 range. + * sized to have 299 entries (starting at zero). Therefore + * find a free slot in the 0-299 range. */ #define _syscall0(type,name) \ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 84ac2bdb090..c58ba8a096c 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -317,11 +317,12 @@ #define __NR_faccessat 296 #define __NR_pselect6 297 #define __NR_ppoll 298 +#define __NR_unshare 299 -/* WARNING: You MAY NOT add syscall numbers larger than 298, since +/* WARNING: You MAY NOT add syscall numbers larger than 299, since * all of the syscall tables in the Sparc kernel are - * sized to have 298 entries (starting at zero). Therefore - * find a free slot in the 0-298 range. + * sized to have 299 entries (starting at zero). Therefore + * find a free slot in the 0-299 range. */ #define _syscall0(type,name) \ diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h index 9afc0c7d366..20468983d45 100644 --- a/include/asm-x86_64/ia32_unistd.h +++ b/include/asm-x86_64/ia32_unistd.h @@ -313,7 +313,10 @@ #define __NR_ia32_readlinkat 305 #define __NR_ia32_fchmodat 306 #define __NR_ia32_faccessat 307 +#define __NR_ia32_pselect6 308 +#define __NR_ia32_ppoll 309 +#define __NR_ia32_unshare 310 -#define IA32_NR_syscalls 308 /* must be > than biggest syscall! */ +#define IA32_NR_syscalls 315 /* must be > than biggest syscall! */ #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h index 34e434ce326..dffe276ca2d 100644 --- a/include/asm-x86_64/numa.h +++ b/include/asm-x86_64/numa.h @@ -22,8 +22,15 @@ extern void numa_set_node(int cpu, int node); extern unsigned char apicid_to_node[256]; #ifdef CONFIG_NUMA extern void __init init_cpu_to_node(void); + +static inline void clear_node_cpumask(int cpu) +{ + clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]); +} + #else #define init_cpu_to_node() do {} while (0) +#define clear_node_cpumask(cpu) do {} while (0) #endif #define NUMA_NO_NODE 0xff diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 436d099b5b6..da0341c5794 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -599,8 +599,14 @@ __SYSCALL(__NR_readlinkat, sys_readlinkat) __SYSCALL(__NR_fchmodat, sys_fchmodat) #define __NR_faccessat 269 __SYSCALL(__NR_faccessat, sys_faccessat) - -#define __NR_syscall_max __NR_faccessat +#define __NR_pselect6 270 +__SYSCALL(__NR_pselect6, sys_ni_syscall) /* for now */ +#define __NR_ppoll 271 +__SYSCALL(__NR_ppoll, sys_ni_syscall) /* for now */ +#define __NR_unshare 272 +__SYSCALL(__NR_unshare, sys_unshare) + +#define __NR_syscall_max __NR_unshare #ifndef __NO_STUBS diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 13e9f4a3ab2..20b446f26ec 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -84,7 +84,6 @@ #include <linux/kernel.h> #include <linux/threads.h> #include <linux/bitmap.h> -#include <asm/bug.h> typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; extern cpumask_t _unused_cpumask_arg_; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index a3f09947940..4361f378997 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -8,7 +8,6 @@ #include <linux/spinlock.h> #include <linux/cache.h> #include <linux/rcupdate.h> -#include <asm/bug.h> struct nameidata; struct vfsmount; diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h index b1999bfeaa5..b81e58b2ebf 100644 --- a/include/linux/dvb/video.h +++ b/include/linux/dvb/video.h @@ -135,7 +135,7 @@ typedef struct video_spu { typedef struct video_spu_palette { /* SPU Palette information */ int length; - uint8_t *palette; + uint8_t __user *palette; } video_spu_palette_t; diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 23fe746a1d5..18cf1f3e118 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -82,6 +82,7 @@ struct elevator_queue extern void elv_dispatch_sort(request_queue_t *, struct request *); extern void elv_add_request(request_queue_t *, struct request *, int, int); extern void __elv_add_request(request_queue_t *, struct request *, int, int); +extern void elv_insert(request_queue_t *, struct request *, int); extern int elv_merge(request_queue_t *, struct request **, struct bio *); extern void elv_merge_requests(request_queue_t *, struct request *, struct request *); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 7863a59bd59..63f1d63cc1d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -100,6 +100,9 @@ extern s32 i2c_smbus_write_block_data(struct i2c_client * client, /* Returns the number of read bytes */ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, u8 command, u8 *values); +extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, + u8 command, u8 length, + u8 *values); /* * A driver is capable of handling one or more physical devices present on diff --git a/include/linux/ioc3.h b/include/linux/ioc3.h index e7906a72a4f..da7c09e4ede 100644 --- a/include/linux/ioc3.h +++ b/include/linux/ioc3.h @@ -27,7 +27,7 @@ struct ioc3_driver_data { int id; /* IOC3 sequence number */ /* PCI mapping */ unsigned long pma; /* physical address */ - struct __iomem ioc3 *vma; /* pointer to registers */ + struct ioc3 __iomem *vma; /* pointer to registers */ struct pci_dev *pdev; /* PCI device */ /* IRQ stuff */ int dual_irq; /* set if separate IRQs are used */ diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 751bb384946..0fe4aa891dd 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -239,7 +239,6 @@ typedef struct journal_superblock_s #include <linux/fs.h> #include <linux/sched.h> -#include <asm/bug.h> #define JBD_ASSERTIONS #ifdef JBD_ASSERTIONS diff --git a/include/linux/mm.h b/include/linux/mm.h index 85854b86746..75e9f072499 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -303,7 +303,7 @@ struct page { */ #define put_page_testzero(p) \ ({ \ - BUG_ON(page_count(p) == 0); \ + BUG_ON(atomic_read(&(p)->_count) == -1);\ atomic_add_negative(-1, &(p)->_count); \ }) diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index fedfbc8a287..7dfd6e1fcde 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -15,7 +15,6 @@ #include <asm/unaligned.h> #include <asm/system.h> #include <asm/io.h> -#include <asm/bug.h> #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 #define map_bankwidth(map) 1 diff --git a/include/linux/namespace.h b/include/linux/namespace.h index 6731977c4c1..3abc8e3b487 100644 --- a/include/linux/namespace.h +++ b/include/linux/namespace.h @@ -15,6 +15,7 @@ struct namespace { extern int copy_namespace(int, struct task_struct *); extern void __put_namespace(struct namespace *namespace); +extern struct namespace *dup_namespace(struct task_struct *, struct fs_struct *); static inline void put_namespace(struct namespace *namespace) { diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 4726ef7ba8e..b959a4525cb 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -84,7 +84,6 @@ #include <linux/threads.h> #include <linux/bitmap.h> #include <linux/numa.h> -#include <asm/bug.h> typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t; extern nodemask_t _unused_nodemask_arg_; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 92a619ba163..7a61ccdcbc4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1832,6 +1832,7 @@ #define PCI_VENDOR_ID_AFAVLAB 0x14db #define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 +#define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 #define PCI_VENDOR_ID_BROADCOM 0x14e4 #define PCI_DEVICE_ID_TIGON3_5752 0x1600 diff --git a/include/linux/smp.h b/include/linux/smp.h index 9dfa3ee769a..44153fdf73f 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -17,7 +17,6 @@ extern void cpu_idle(void); #include <linux/compiler.h> #include <linux/thread_info.h> #include <asm/smp.h> -#include <asm/bug.h> /* * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc. diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 43bcd13eb1e..37c1c76fd54 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -42,13 +42,21 @@ extern void mark_free_pages(struct zone *zone); #ifdef CONFIG_PM /* kernel/power/swsusp.c */ extern int software_suspend(void); + +#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) +extern int pm_prepare_console(void); +extern void pm_restore_console(void); +#else +static inline int pm_prepare_console(void) { return 0; } +static inline void pm_restore_console(void) {} +#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */ #else static inline int software_suspend(void) { printk("Warning: fake suspend called\n"); return -EPERM; } -#endif +#endif /* CONFIG_PM */ #ifdef CONFIG_SUSPEND_SMP extern void disable_nonboot_cpus(void); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index b23be44cbea..5208b12d555 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -549,7 +549,7 @@ struct v4l2_framebuffer struct v4l2_clip { struct v4l2_rect c; - struct v4l2_clip *next; + struct v4l2_clip __user *next; }; struct v4l2_window diff --git a/init/Kconfig b/init/Kconfig index 8b7abae87bf..38416a199de 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -169,7 +169,6 @@ config SYSCTL config AUDIT bool "Auditing support" depends on NET - default y if SECURITY_SELINUX help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for diff --git a/kernel/compat.c b/kernel/compat.c index 1867290c37e..8c9cd88b678 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -23,7 +23,6 @@ #include <linux/security.h> #include <asm/uaccess.h> -#include <asm/bug.h> int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts) { diff --git a/kernel/fork.c b/kernel/fork.c index 7f0ab5ee948..8e88b374cee 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -446,6 +446,55 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) } } +/* + * Allocate a new mm structure and copy contents from the + * mm structure of the passed in task structure. + */ +static struct mm_struct *dup_mm(struct task_struct *tsk) +{ + struct mm_struct *mm, *oldmm = current->mm; + int err; + + if (!oldmm) + return NULL; + + mm = allocate_mm(); + if (!mm) + goto fail_nomem; + + memcpy(mm, oldmm, sizeof(*mm)); + + if (!mm_init(mm)) + goto fail_nomem; + + if (init_new_context(tsk, mm)) + goto fail_nocontext; + + err = dup_mmap(mm, oldmm); + if (err) + goto free_pt; + + mm->hiwater_rss = get_mm_rss(mm); + mm->hiwater_vm = mm->total_vm; + + return mm; + +free_pt: + mmput(mm); + +fail_nomem: + return NULL; + +fail_nocontext: + /* + * If init_new_context() failed, we cannot use mmput() to free the mm + * because it calls destroy_context() + */ + mm_free_pgd(mm); + free_mm(mm); + return NULL; +} + static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) { struct mm_struct * mm, *oldmm; @@ -473,43 +522,17 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) } retval = -ENOMEM; - mm = allocate_mm(); + mm = dup_mm(tsk); if (!mm) goto fail_nomem; - /* Copy the current MM stuff.. */ - memcpy(mm, oldmm, sizeof(*mm)); - if (!mm_init(mm)) - goto fail_nomem; - - if (init_new_context(tsk,mm)) - goto fail_nocontext; - - retval = dup_mmap(mm, oldmm); - if (retval) - goto free_pt; - - mm->hiwater_rss = get_mm_rss(mm); - mm->hiwater_vm = mm->total_vm; - good_mm: tsk->mm = mm; tsk->active_mm = mm; return 0; -free_pt: - mmput(mm); fail_nomem: return retval; - -fail_nocontext: - /* - * If init_new_context() failed, we cannot use mmput() to free the mm - * because it calls destroy_context() - */ - mm_free_pgd(mm); - free_mm(mm); - return retval; } static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old) @@ -597,32 +620,17 @@ out: return newf; } -static int copy_files(unsigned long clone_flags, struct task_struct * tsk) +/* + * Allocate a new files structure and copy contents from the + * passed in files structure. + */ +static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) { - struct files_struct *oldf, *newf; + struct files_struct *newf; struct file **old_fds, **new_fds; - int open_files, size, i, error = 0, expand; + int open_files, size, i, expand; struct fdtable *old_fdt, *new_fdt; - /* - * A background process may not have any files ... - */ - oldf = current->files; - if (!oldf) - goto out; - - if (clone_flags & CLONE_FILES) { - atomic_inc(&oldf->count); - goto out; - } - - /* - * Note: we may be using current for both targets (See exec.c) - * This works because we cache current->files (old) as oldf. Don't - * break this. - */ - tsk->files = NULL; - error = -ENOMEM; newf = alloc_files(); if (!newf) goto out; @@ -651,9 +659,9 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) if (expand) { spin_unlock(&oldf->file_lock); spin_lock(&newf->file_lock); - error = expand_files(newf, open_files-1); + *errorp = expand_files(newf, open_files-1); spin_unlock(&newf->file_lock); - if (error < 0) + if (*errorp < 0) goto out_release; new_fdt = files_fdtable(newf); /* @@ -702,10 +710,8 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); } - tsk->files = newf; - error = 0; out: - return error; + return newf; out_release: free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset); @@ -715,6 +721,40 @@ out_release: goto out; } +static int copy_files(unsigned long clone_flags, struct task_struct * tsk) +{ + struct files_struct *oldf, *newf; + int error = 0; + + /* + * A background process may not have any files ... + */ + oldf = current->files; + if (!oldf) + goto out; + + if (clone_flags & CLONE_FILES) { + atomic_inc(&oldf->count); + goto out; + } + + /* + * Note: we may be using current for both targets (See exec.c) + * This works because we cache current->files (old) as oldf. Don't + * break this. + */ + tsk->files = NULL; + error = -ENOMEM; + newf = dup_fd(oldf, &error); + if (!newf) + goto out; + + tsk->files = newf; + error = 0; +out: + return error; +} + /* * Helper to unshare the files of the current task. * We don't want to expose copy_files internals to @@ -1323,3 +1363,249 @@ void __init proc_caches_init(void) sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); } + + +/* + * Check constraints on flags passed to the unshare system call and + * force unsharing of additional process context as appropriate. + */ +static inline void check_unshare_flags(unsigned long *flags_ptr) +{ + /* + * If unsharing a thread from a thread group, must also + * unshare vm. + */ + if (*flags_ptr & CLONE_THREAD) + *flags_ptr |= CLONE_VM; + + /* + * If unsharing vm, must also unshare signal handlers. + */ + if (*flags_ptr & CLONE_VM) + *flags_ptr |= CLONE_SIGHAND; + + /* + * If unsharing signal handlers and the task was created + * using CLONE_THREAD, then must unshare the thread + */ + if ((*flags_ptr & CLONE_SIGHAND) && + (atomic_read(¤t->signal->count) > 1)) + *flags_ptr |= CLONE_THREAD; + + /* + * If unsharing namespace, must also unshare filesystem information. + */ + if (*flags_ptr & CLONE_NEWNS) + *flags_ptr |= CLONE_FS; +} + +/* + * Unsharing of tasks created with CLONE_THREAD is not supported yet + */ +static int unshare_thread(unsigned long unshare_flags) +{ + if (unshare_flags & CLONE_THREAD) + return -EINVAL; + + return 0; +} + +/* + * Unshare the filesystem structure if it is being shared + */ +static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) +{ + struct fs_struct *fs = current->fs; + + if ((unshare_flags & CLONE_FS) && + (fs && atomic_read(&fs->count) > 1)) { + *new_fsp = __copy_fs_struct(current->fs); + if (!*new_fsp) + return -ENOMEM; + } + + return 0; +} + +/* + * Unshare the namespace structure if it is being shared + */ +static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs) +{ + struct namespace *ns = current->namespace; + + if ((unshare_flags & CLONE_NEWNS) && + (ns && atomic_read(&ns->count) > 1)) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + *new_nsp = dup_namespace(current, new_fs ? new_fs : current->fs); + if (!*new_nsp) + return -ENOMEM; + } + + return 0; +} + +/* + * Unsharing of sighand for tasks created with CLONE_SIGHAND is not + * supported yet + */ +static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp) +{ + struct sighand_struct *sigh = current->sighand; + + if ((unshare_flags & CLONE_SIGHAND) && + (sigh && atomic_read(&sigh->count) > 1)) + return -EINVAL; + else + return 0; +} + +/* + * Unshare vm if it is being shared + */ +static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp) +{ + struct mm_struct *mm = current->mm; + + if ((unshare_flags & CLONE_VM) && + (mm && atomic_read(&mm->mm_users) > 1)) { + *new_mmp = dup_mm(current); + if (!*new_mmp) + return -ENOMEM; + } + + return 0; +} + +/* + * Unshare file descriptor table if it is being shared + */ +static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp) +{ + struct files_struct *fd = current->files; + int error = 0; + + if ((unshare_flags & CLONE_FILES) && + (fd && atomic_read(&fd->count) > 1)) { + *new_fdp = dup_fd(fd, &error); + if (!*new_fdp) + return error; + } + + return 0; +} + +/* + * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not + * supported yet + */ +static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp) +{ + if (unshare_flags & CLONE_SYSVSEM) + return -EINVAL; + + return 0; +} + +/* + * unshare allows a process to 'unshare' part of the process + * context which was originally shared using clone. copy_* + * functions used by do_fork() cannot be used here directly + * because they modify an inactive task_struct that is being + * constructed. Here we are modifying the current, active, + * task_struct. + */ +asmlinkage long sys_unshare(unsigned long unshare_flags) +{ + int err = 0; + struct fs_struct *fs, *new_fs = NULL; + struct namespace *ns, *new_ns = NULL; + struct sighand_struct *sigh, *new_sigh = NULL; + struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; + struct files_struct *fd, *new_fd = NULL; + struct sem_undo_list *new_ulist = NULL; + + check_unshare_flags(&unshare_flags); + + if ((err = unshare_thread(unshare_flags))) + goto bad_unshare_out; + if ((err = unshare_fs(unshare_flags, &new_fs))) + goto bad_unshare_cleanup_thread; + if ((err = unshare_namespace(unshare_flags, &new_ns, new_fs))) + goto bad_unshare_cleanup_fs; + if ((err = unshare_sighand(unshare_flags, &new_sigh))) + goto bad_unshare_cleanup_ns; + if ((err = unshare_vm(unshare_flags, &new_mm))) + goto bad_unshare_cleanup_sigh; + if ((err = unshare_fd(unshare_flags, &new_fd))) + goto bad_unshare_cleanup_vm; + if ((err = unshare_semundo(unshare_flags, &new_ulist))) + goto bad_unshare_cleanup_fd; + + if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) { + + task_lock(current); + + if (new_fs) { + fs = current->fs; + current->fs = new_fs; + new_fs = fs; + } + + if (new_ns) { + ns = current->namespace; + current->namespace = new_ns; + new_ns = ns; + } + + if (new_sigh) { + sigh = current->sighand; + current->sighand = new_sigh; + new_sigh = sigh; + } + + if (new_mm) { + mm = current->mm; + active_mm = current->active_mm; + current->mm = new_mm; + current->active_mm = new_mm; + activate_mm(active_mm, new_mm); + new_mm = mm; + } + + if (new_fd) { + fd = current->files; + current->files = new_fd; + new_fd = fd; + } + + task_unlock(current); + } + +bad_unshare_cleanup_fd: + if (new_fd) + put_files_struct(new_fd); + +bad_unshare_cleanup_vm: + if (new_mm) + mmput(new_mm); + +bad_unshare_cleanup_sigh: + if (new_sigh) + if (atomic_dec_and_test(&new_sigh->count)) + kmem_cache_free(sighand_cachep, new_sigh); + +bad_unshare_cleanup_ns: + if (new_ns) + put_namespace(new_ns); + +bad_unshare_cleanup_fs: + if (new_fs) + put_fs_struct(new_fs); + +bad_unshare_cleanup_thread: +bad_unshare_out: + return err; +} diff --git a/kernel/module.c b/kernel/module.c index e058aedf6b9..5aad477ddc7 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1670,6 +1670,9 @@ static struct module *load_module(void __user *umod, goto free_mod; } + /* Userspace could have altered the string after the strlen_user() */ + args[arglen - 1] = '\0'; + if (find_module(mod->name)) { err = -EEXIST; goto free_mod; diff --git a/kernel/power/console.c b/kernel/power/console.c index 579d239d129..623786d4415 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -9,7 +9,9 @@ #include <linux/console.h> #include "power.h" -#ifdef SUSPEND_CONSOLE +#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) +#define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) + static int orig_fgconsole, orig_kmsg; int pm_prepare_console(void) diff --git a/kernel/power/power.h b/kernel/power/power.h index d8f0d1a76ba..388dba68084 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -1,14 +1,6 @@ #include <linux/suspend.h> #include <linux/utsname.h> -/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but - we probably do not take enough locks for switching consoles, etc, - so bad things might happen. -*/ -#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) -#define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) -#endif - struct swsusp_info { struct new_utsname uts; u32 version_code; @@ -42,14 +34,6 @@ static struct subsys_attribute _name##_attr = { \ extern struct subsystem power_subsys; -#ifdef SUSPEND_CONSOLE -extern int pm_prepare_console(void); -extern void pm_restore_console(void); -#else -static int pm_prepare_console(void) { return 0; } -static void pm_restore_console(void) {} -#endif - /* References to section boundaries */ extern const void __nosave_begin, __nosave_end; diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 59c91c148e8..4e90905f0e8 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -743,7 +743,6 @@ static int submit(int rw, pgoff_t page_off, void *page) if (!bio) return -ENOMEM; bio->bi_sector = page_off * (PAGE_SIZE >> 9); - bio_get(bio); bio->bi_bdev = resume_bdev; bio->bi_end_io = end_io; @@ -753,14 +752,13 @@ static int submit(int rw, pgoff_t page_off, void *page) goto Done; } - if (rw == WRITE) - bio_set_pages_dirty(bio); atomic_set(&io_done, 1); submit_bio(rw | (1 << BIO_RW_SYNC), bio); while (atomic_read(&io_done)) yield(); - + if (rw == READ) + bio_set_pages_dirty(bio); Done: bio_put(bio); return error; diff --git a/kernel/sys.c b/kernel/sys.c index 0929c698aff..f91218a5463 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -428,7 +428,7 @@ void kernel_kexec(void) { #ifdef CONFIG_KEXEC struct kimage *image; - image = xchg(&kexec_image, 0); + image = xchg(&kexec_image, NULL); if (!image) { return; } diff --git a/kernel/timer.c b/kernel/timer.c index 4f1cb0ab525..b9dad399467 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -495,7 +495,7 @@ unsigned long next_timer_interrupt(void) base = &__get_cpu_var(tvec_bases); spin_lock(&base->t_base.lock); expires = base->timer_jiffies + (LONG_MAX >> 1); - list = 0; + list = NULL; /* Look for timer events in tv1. */ j = base->timer_jiffies & TVR_MASK; diff --git a/lib/kobject.c b/lib/kobject.c index 7a0e6809490..efe67fa96a7 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -72,6 +72,8 @@ static int get_kobj_path_length(struct kobject *kobj) * Add 1 to strlen for leading '/' of each level. */ do { + if (kobject_name(parent) == NULL) + return 0; length += strlen(kobject_name(parent)) + 1; parent = parent->parent; } while (parent); @@ -107,6 +109,8 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) int len; len = get_kobj_path_length(kobj); + if (len == 0) + return NULL; path = kmalloc(len, gfp_mask); if (!path) return NULL; @@ -162,6 +166,11 @@ int kobject_add(struct kobject * kobj) return -ENOENT; if (!kobj->k_name) kobj->k_name = kobj->name; + if (!kobj->k_name) { + pr_debug("kobject attempted to be registered with no name!\n"); + WARN_ON(1); + return -EINVAL; + } parent = kobject_get(kobj->parent); pr_debug("kobject %s: registering. parent: %s, set: %s\n", diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index f56e27ae9d5..1b1985c136e 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -22,7 +22,7 @@ #include <linux/kobject.h> #include <net/sock.h> -#define BUFFER_SIZE 1024 /* buffer for the variables */ +#define BUFFER_SIZE 2048 /* buffer for the variables */ #define NUM_ENVP 32 /* number of env pointers */ #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index c8bb8cc899d..d8b6bb419d4 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -72,9 +72,9 @@ static void __spin_lock_debug(spinlock_t *lock) for (;;) { for (i = 0; i < loops_per_jiffy * HZ; i++) { - cpu_relax(); if (__raw_spin_trylock(&lock->raw_lock)) return; + __delay(1); } /* lockup suspected: */ if (print_once) { @@ -144,9 +144,9 @@ static void __read_lock_debug(rwlock_t *lock) for (;;) { for (i = 0; i < loops_per_jiffy * HZ; i++) { - cpu_relax(); if (__raw_read_trylock(&lock->raw_lock)) return; + __delay(1); } /* lockup suspected: */ if (print_once) { @@ -217,9 +217,9 @@ static void __write_lock_debug(rwlock_t *lock) for (;;) { for (i = 0; i < loops_per_jiffy * HZ; i++) { - cpu_relax(); if (__raw_write_trylock(&lock->raw_lock)) return; + __delay(1); } /* lockup suspected: */ if (print_once) { diff --git a/mm/hugetlb.c b/mm/hugetlb.c index ceb3ebb3c39..67f29516662 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -107,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr) set_page_count(page, 1); page[1].mapping = (void *)free_huge_page; for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) - clear_highpage(&page[i]); + clear_user_highpage(&page[i], addr); return page; } @@ -391,12 +391,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, if (!new_page) { page_cache_release(old_page); - - /* Logically this is OOM, not a SIGBUS, but an OOM - * could cause the kernel to go killing other - * processes which won't help the hugepage situation - * at all (?) */ - return VM_FAULT_SIGBUS; + return VM_FAULT_OOM; } spin_unlock(&mm->page_table_lock); @@ -444,15 +439,7 @@ retry: page = alloc_huge_page(vma, address); if (!page) { hugetlb_put_quota(mapping); - /* - * No huge pages available. So this is an OOM - * condition but we do not want to trigger the OOM - * killer, so we return VM_FAULT_SIGBUS. - * - * A program using hugepages may fault with Bus Error - * because no huge pages are available in the cpuset, per - * memory policy or because all are in use! - */ + ret = VM_FAULT_OOM; goto out; } diff --git a/mm/slob.c b/mm/slob.c index 1c240c4b71d..a1f42bdc024 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -336,7 +336,7 @@ EXPORT_SYMBOL(slab_reclaim_pages); #ifdef CONFIG_SMP -void *__alloc_percpu(size_t size, size_t align) +void *__alloc_percpu(size_t size) { int i; struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL); diff --git a/mm/swap.c b/mm/swap.c index bc2442a7b0e..76247424dea 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -34,19 +34,22 @@ /* How many pages do we try to swap or page in/out together? */ int page_cluster; -void put_page(struct page *page) +static void put_compound_page(struct page *page) { - if (unlikely(PageCompound(page))) { - page = (struct page *)page_private(page); - if (put_page_testzero(page)) { - void (*dtor)(struct page *page); + page = (struct page *)page_private(page); + if (put_page_testzero(page)) { + void (*dtor)(struct page *page); - dtor = (void (*)(struct page *))page[1].mapping; - (*dtor)(page); - } - return; + dtor = (void (*)(struct page *))page[1].mapping; + (*dtor)(page); } - if (put_page_testzero(page)) +} + +void put_page(struct page *page) +{ + if (unlikely(PageCompound(page))) + put_compound_page(page); + else if (put_page_testzero(page)) __page_cache_release(page); } EXPORT_SYMBOL(put_page); @@ -244,6 +247,15 @@ void release_pages(struct page **pages, int nr, int cold) struct page *page = pages[i]; struct zone *pagezone; + if (unlikely(PageCompound(page))) { + if (zone) { + spin_unlock_irq(&zone->lru_lock); + zone = NULL; + } + put_compound_page(page); + continue; + } + if (!put_page_testzero(page)) continue; diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c index d2b5933b451..add3cae65e2 100644 --- a/net/dccp/ccids/lib/tfrc_equation.c +++ b/net/dccp/ccids/lib/tfrc_equation.c @@ -15,7 +15,6 @@ #include <linux/config.h> #include <linux/module.h> -#include <asm/bug.h> #include <asm/div64.h> #include "tfrc.h" diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 0b4e95f93da..64ce52bf048 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1578,7 +1578,7 @@ static int sf_setstate(struct ip_mc_list *pmc) new_in = psf->sf_count[MCAST_INCLUDE] != 0; if (new_in) { if (!psf->sf_oldin) { - struct ip_sf_list *prev = 0; + struct ip_sf_list *prev = NULL; for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) { if (dpsf->sf_inaddr == psf->sf_inaddr) diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 42196ba3b0b..45f7ae58f2c 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -8,7 +8,6 @@ * */ -#include <asm/bug.h> #include <linux/compiler.h> #include <linux/config.h> #include <linux/inetdevice.h> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1db50487916..b7d8822c1be 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2165,6 +2165,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, dev->name); break; } + + if (idev) + idev->if_flags |= IF_READY; } else { if (!netif_carrier_ok(dev)) { /* device is still not ready. */ diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 4420948a1bf..807c021d64a 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1978,7 +1978,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc) new_in = psf->sf_count[MCAST_INCLUDE] != 0; if (new_in) { if (!psf->sf_oldin) { - struct ip6_sf_list *prev = 0; + struct ip6_sf_list *prev = NULL; for (dpsf=pmc->mca_tomb; dpsf; dpsf=dpsf->sf_next) { diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 66f1d12ea57..738376cf0c5 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -35,7 +35,6 @@ #include <linux/skbuff.h> #include <asm/uaccess.h> #include <asm/ioctls.h> -#include <asm/bug.h> #include <net/ip.h> #include <net/sock.h> diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 69bd957380e..91cce8b2d7a 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -11,7 +11,6 @@ * */ -#include <asm/bug.h> #include <linux/compiler.h> #include <linux/config.h> #include <linux/netdevice.h> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 077bbf9fb9b..dbf4620768d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -13,7 +13,6 @@ * */ -#include <asm/bug.h> #include <linux/config.h> #include <linux/slab.h> #include <linux/kmod.h> diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index 502f78f13f5..f636f53ca54 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig @@ -1,6 +1,6 @@ config SECURITY_SELINUX bool "NSA SELinux Support" - depends on SECURITY_NETWORK && NET && INET + depends on SECURITY_NETWORK && AUDIT && NET && INET default n help This selects NSA Security-Enhanced Linux (SELinux). diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 53d6c7bbf56..ac5d69bb337 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -43,13 +43,11 @@ static const struct av_perm_to_string #undef S_ }; -#ifdef CONFIG_AUDIT static const char *class_to_string[] = { #define S_(s) s, #include "class_to_string.h" #undef S_ }; -#endif #define TB_(s) static const char * s [] = { #define TE_(s) }; diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h index 3a6d48666db..0741c28e56c 100644 --- a/sound/oss/dmasound/tas_common.h +++ b/sound/oss/dmasound/tas_common.h @@ -178,10 +178,10 @@ tas_write_register( struct tas_data_t *self, if (write_mode & WRITE_SHADOW) memcpy(self->shadow[reg_num],data,reg_width); if (write_mode & WRITE_HW) { - rc=i2c_smbus_write_block_data(self->client, - reg_num, - reg_width, - data); + rc=i2c_smbus_write_i2c_block_data(self->client, + reg_num, + reg_width, + data); if (rc < 0) { printk("tas: I2C block write failed \n"); return rc; @@ -199,10 +199,10 @@ tas_sync_register( struct tas_data_t *self, if (reg_width==0 || self==NULL) return -EINVAL; - rc=i2c_smbus_write_block_data(self->client, - reg_num, - reg_width, - self->shadow[reg_num]); + rc=i2c_smbus_write_i2c_block_data(self->client, + reg_num, + reg_width, + self->shadow[reg_num]); if (rc < 0) { printk("tas: I2C block write failed \n"); return rc; diff --git a/sound/oss/emu10k1/recmgr.c b/sound/oss/emu10k1/recmgr.c index 67c3fd04cfd..2ce56180e7d 100644 --- a/sound/oss/emu10k1/recmgr.c +++ b/sound/oss/emu10k1/recmgr.c @@ -29,7 +29,7 @@ ********************************************************************** */ -#include <asm/delay.h> +#include <linux/delay.h> #include "8010.h" #include "recmgr.h" diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 4988f873a7b..aa57170101f 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -66,7 +66,7 @@ static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, i static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec) { - if (rec) { + if (rec->space) { unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1); dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base); @@ -881,6 +881,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) chip->can_capture = 1; chip->num_freqs = ARRAY_SIZE(awacs_freqs); chip->freq_table = awacs_freqs; + chip->pdev = NULL; chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */ diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 15c63cb2ccb..838fc113c44 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -239,8 +239,8 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix) block[4] = (right_vol >> 8) & 0xff; block[5] = (right_vol >> 0) & 0xff; - if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL, - 6, block) < 0) { + if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6, + block) < 0) { snd_printk("failed to set volume \n"); return -EINVAL; } @@ -345,8 +345,8 @@ static int tumbler_set_drc(struct pmac_tumbler *mix) val[1] = 0; } - if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC, - 2, val) < 0) { + if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC, + 2, val) < 0) { snd_printk("failed to set DRC\n"); return -EINVAL; } @@ -381,8 +381,8 @@ static int snapper_set_drc(struct pmac_tumbler *mix) val[4] = 0x60; val[5] = 0xa0; - if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC, - 6, val) < 0) { + if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC, + 6, val) < 0) { snd_printk("failed to set DRC\n"); return -EINVAL; } @@ -492,8 +492,8 @@ static int tumbler_set_mono_volume(struct pmac_tumbler *mix, vol = info->table[vol]; for (i = 0; i < info->bytes; i++) block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff; - if (i2c_smbus_write_block_data(mix->i2c.client, info->reg, - info->bytes, block) < 0) { + if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg, + info->bytes, block) < 0) { snd_printk("failed to set mono volume %d\n", info->index); return -EINVAL; } @@ -625,7 +625,8 @@ static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int r for (j = 0; j < 3; j++) block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff; } - if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) { + if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg, + 9, block) < 0) { snd_printk("failed to set mono volume %d\n", reg); return -EINVAL; } |