Commit 1230366a authored by Tony Lindgren's avatar Tony Lindgren

Manual merge to make things compile after updating to 2.6.18-rc4

Some things are probably broken right now with the generic irq
code update.
parent 617dbdff
This diff is collapsed.
......@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mtd/mtd.h>
......
......@@ -52,7 +52,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
static struct irqaction omap2_gp_timer_irq = {
.name = "gp timer",
.flags = SA_INTERRUPT | SA_TIMER,
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = omap2_gp_timer_interrupt,
};
......
......@@ -28,9 +28,9 @@
#include <asm/arch/clock.h>
LIST_HEAD(clocks);
DEFINE_SPINLOCK(clockfw_lock);
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
static struct clk_functions *arch_clock;
......
......@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
......
......@@ -29,52 +29,52 @@
.text
/* Prototype: int __arch_copy_to_user_dsp_2b(void *to, const char *from)
/* Prototype: int __copy_to_user_dsp_2b(void *to, const char *from)
* Purpose : copy 2 bytes to user memory from kernel(DSP) memory
* escaping from unexpected byte swap using __arch_copy_to_user()
* escaping from unexpected byte swap using __copy_to_user()
* in OMAP architecture.
* Params : to - user memory
* : from - kernel(DSP) memory
* Returns : success = 0, failure = 2
*/
ENTRY(__arch_copy_to_user_dsp_2b)
ENTRY(__copy_to_user_dsp_2b)
stmfd sp!, {r4, lr}
ldrb r3, [r1], #1
ldrb r4, [r1], #1
USER( strbt r4, [r0], #1) @ May fault
USER( strbt r3, [r0], #1) @ May fault
mov r0, #0
LOADREGS(fd,sp!,{r4, pc})
ldmfd sp!, {r4, pc}
.section .fixup,"ax"
.align 0
9001: mov r0, #2
LOADREGS(fd,sp!, {r4, pc})
ldmfd sp!, {r4, pc}
.previous
/* Prototype: unsigned long __arch_copy_from_user_dsp_2b(void *to, const void *from);
/* Prototype: unsigned long __copy_from_user_dsp_2b(void *to, const void *from);
* Purpose : copy 2 bytes from user memory to kernel(DSP) memory
* escaping from unexpected byte swap using __arch_copy_to_user()
* escaping from unexpected byte swap using __copy_to_user()
* in OMAP architecture.
* Params : to - kernel (DSP) memory
* : from - user memory
* Returns : success = 0, failure = 2
*/
ENTRY(__arch_copy_from_user_dsp_2b)
ENTRY(__copy_from_user_dsp_2b)
stmfd sp!, {r4, lr}
USER( ldrbt r3, [r1], #1) @ May fault
USER( ldrbt r4, [r1], #1) @ May fault
strb r4, [r0], #1
strb r3, [r0], #1
mov r0, #0
LOADREGS(fd,sp!,{r4, pc})
ldmfd sp!, {r4, pc}
.section .fixup,"ax"
.align 0
9001: mov r3, #0
strh r3, [r0], #2
mov r0, #2
LOADREGS(fd,sp!, {r4, pc})
ldmfd sp!, {r4, pc}
.previous
......@@ -33,9 +33,9 @@
#define HAVE_ASM_COPY_FROM_USER_DSP_2B
#ifdef HAVE_ASM_COPY_FROM_USER_DSP_2B
extern unsigned long __arch_copy_from_user_dsp_2b(void *to,
extern unsigned long __copy_from_user_dsp_2b(void *to,
const void __user *from);
extern unsigned long __arch_copy_to_user_dsp_2b(void __user *to,
extern unsigned long __copy_to_user_dsp_2b(void __user *to,
const void *from);
#endif
......@@ -51,7 +51,7 @@ static __inline__ unsigned long copy_from_user_dsp_2b(void *to,
{
unsigned short tmp;
if (__arch_copy_from_user(&tmp, from, 2))
if (__copy_from_user(&tmp, from, 2))
return 2;
/* expecting compiler to generate "strh" instruction */
*((unsigned short *)to) = tmp;
......@@ -77,7 +77,7 @@ static __inline__ unsigned long copy_from_user_dsp(void *to, const void *from,
/* dest not aligned -- copy 2 bytes */
if (((unsigned long)to & 2) && (n >= 2)) {
#ifdef HAVE_ASM_COPY_FROM_USER_DSP_2B
if (__arch_copy_from_user_dsp_2b(to, from))
if (__copy_from_user_dsp_2b(to, from))
#else
if (copy_from_user_dsp_2b(to, from))
#endif
......@@ -89,14 +89,14 @@ static __inline__ unsigned long copy_from_user_dsp(void *to, const void *from,
/* middle 4*n bytes */
last_n = n & 2;
n4 = n - last_n;
if ((n = __arch_copy_from_user(to, from, n4)) != 0)
if ((n = __copy_from_user(to, from, n4)) != 0)
return n + last_n;
/* last 2 bytes */
if (last_n) {
to += n4;
from += n4;
#ifdef HAVE_ASM_COPY_FROM_USER_DSP_2B
if (__arch_copy_from_user_dsp_2b(to, from))
if (__copy_from_user_dsp_2b(to, from))
#else
if (copy_from_user_dsp_2b(to, from))
#endif
......@@ -108,7 +108,7 @@ static __inline__ unsigned long copy_from_user_dsp(void *to, const void *from,
* DARAM/SARAM with 4-byte alignment or
* external memory
*/
n = __arch_copy_from_user(to, from, n);
n = __copy_from_user(to, from, n);
}
}
else /* security hole - plug it */
......@@ -122,7 +122,7 @@ static __inline__ unsigned long copy_to_user_dsp_2b(void *to, const void *from)
/* expecting compiler to generate "strh" instruction */
unsigned short tmp = *(unsigned short *)from;
return __arch_copy_to_user(to, &tmp, 2);
return __copy_to_user(to, &tmp, 2);
}
#endif
......@@ -144,7 +144,7 @@ static __inline__ unsigned long copy_to_user_dsp(void *to, const void *from,
/* dest not aligned -- copy 2 bytes */
if (((unsigned long)to & 2) && (n >= 2)) {
#ifdef HAVE_ASM_COPY_FROM_USER_DSP_2B
if (__arch_copy_to_user_dsp_2b(to, from))
if (__copy_to_user_dsp_2b(to, from))
#else
if (copy_to_user_dsp_2b(to, from))
#endif
......@@ -156,14 +156,14 @@ static __inline__ unsigned long copy_to_user_dsp(void *to, const void *from,
/* middle 4*n bytes */
last_n = n & 2;
n4 = n - last_n;
if ((n = __arch_copy_to_user(to, from, n4)) != 0)
if ((n = __copy_to_user(to, from, n4)) != 0)
return n + last_n;
/* last 2 bytes */
if (last_n) {
to += n4;
from += n4;
#ifdef HAVE_ASM_COPY_FROM_USER_DSP_2B
if (__arch_copy_to_user_dsp_2b(to, from))
if (__copy_to_user_dsp_2b(to, from))
#else
if (copy_to_user_dsp_2b(to, from))
#endif
......@@ -175,7 +175,7 @@ static __inline__ unsigned long copy_to_user_dsp(void *to, const void *from,
* DARAM/SARAM with 4-byte alignment or
* external memory
*/
n = __arch_copy_to_user(to, from, n);
n = __copy_to_user(to, from, n);
}
}
return n;
......
......@@ -21,7 +21,6 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
......
......@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
......
......@@ -11,7 +11,6 @@
* published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
......@@ -784,7 +783,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
desc->chip->ack(irq);
bank = (struct gpio_bank *) desc->data;
bank = get_irq_data(irq);
if (bank->method == METHOD_MPUIO)
isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
#ifdef CONFIG_ARCH_OMAP15XX
......@@ -851,7 +850,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
/* Don't run the handler if it's already running
* or was disabled lazely.
*/
if (unlikely((d->disable_depth || d->running))) {
if (unlikely((d->depth ||
(d->status & IRQ_INPROGRESS)))) {
irq_mask = 1 <<
(gpio_irq - bank->virtual_irq_start);
/* The unmasking will be done by
......@@ -860,22 +860,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
* it's already running.
*/
_enable_gpio_irqbank(bank, irq_mask, 0);
if (!d->disable_depth) {
if (!d->depth) {
/* Level triggered interrupts
* won't ever be reentered
*/
BUG_ON(level_mask & irq_mask);
d->pending = 1;
d->status |= IRQ_PENDING;
}
continue;
}
d->running = 1;
desc_handle_irq(gpio_irq, d, regs);
d->running = 0;
if (unlikely(d->pending && !d->disable_depth)) {
if (unlikely((d->status & IRQ_PENDING) && !d->depth)) {
irq_mask = 1 <<
(gpio_irq - bank->virtual_irq_start);
d->pending = 0;
d->status &= ~IRQ_PENDING;
_enable_gpio_irqbank(bank, irq_mask, 1);
retrigger |= irq_mask;
}
......@@ -944,7 +944,8 @@ static void mpuio_unmask_irq(unsigned int irq)
_set_gpio_irqenable(bank, gpio, 1);
}
static struct irqchip gpio_irq_chip = {
static struct irq_chip gpio_irq_chip = {
.name = "GPIO",
.ack = gpio_ack_irq,
.mask = gpio_mask_irq,
.unmask = gpio_unmask_irq,
......@@ -952,10 +953,11 @@ static struct irqchip gpio_irq_chip = {
.set_wake = gpio_wake_enable,
};
static struct irqchip mpuio_irq_chip = {
static struct irq_chip mpuio_irq_chip = {
.name = "MPUIO",
.ack = mpuio_ack_irq,
.mask = mpuio_mask_irq,
.unmask = mpuio_unmask_irq
.unmask = mpuio_unmask_irq
};
static int initialized;
......
......@@ -34,7 +34,6 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
......@@ -268,7 +267,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = {
static struct irqaction omap_32k_timer_irq = {
.name = "32KHz timer",
.flags = SA_INTERRUPT | SA_TIMER,
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = omap_32k_timer_interrupt,
};
......
......@@ -72,6 +72,8 @@ source "drivers/edac/Kconfig"
source "drivers/rtc/Kconfig"
source "drivers/dma/Kconfig"
source "drivers/ssi/Kconfig"
endmenu
......@@ -30,6 +30,7 @@
#include <linux/serial_reg.h>
#include <linux/skbuff.h>
#include <linux/firmware.h>
#include <linux/irq.h>
#include <linux/timer.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
......
......@@ -33,6 +33,7 @@
#include <linux/miscdevice.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
......
......@@ -33,6 +33,7 @@
#include <linux/miscdevice.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
......
......@@ -76,14 +76,15 @@ endif
obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_I8K) += i8k.o
obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_HW_RANDOM) += hw_random.o
obj-$(CONFIG_OMAP_RNG) += omap-rng.o
obj-$(CONFIG_HW_RANDOM) += hw_random/
obj-$(CONFIG_FTAPE) += ftape/
obj-$(CONFIG_COBALT_LCD) += lcd.o
obj-$(CONFIG_PPDEV) += ppdev.o
obj-$(CONFIG_NWBUTTON) += nwbutton.o
obj-$(CONFIG_NWFLASH) += nwflash.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
......
......@@ -63,12 +63,18 @@ config LEDS_S3C24XX
This option enables support for LEDs connected to GPIO lines
on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
config LEDS_OMAP_PWM
tristate "LED Support for OMAP PWM-controlled LEDs"
depends on LEDS_CLASS && ARCH_OMAP && OMAP_DM_TIMER
config LEDS_AMS_DELTA
tristate "LED Support for the Amstrad Delta (E3)"
depends LEDS_CLASS && MACH_AMS_DELTA
help
This options enables support for LEDs connected to GPIO lines
controlled by a PWM timer on OMAP CPUs.
This option enables support for the LEDs on Amstrad Delta (E3).
config LEDS_NET48XX
tristate "LED Support for Soekris net48xx series Error LED"
depends on LEDS_CLASS && SCx200_GPIO
help
This option enables support for the Soekris net4801 and net4826 error
LED.
config LEDS_OMAP
tristate "LED Support for OMAP GPIO LEDs"
......@@ -76,6 +82,13 @@ config LEDS_OMAP
help
This option enables support for the LEDs on OMAP processors.
config LEDS_OMAP_PWM
tristate "LED Support for OMAP PWM-controlled LEDs"
depends on LEDS_CLASS && ARCH_OMAP && OMAP_DM_TIMER
help
This options enables support for LEDs connected to GPIO lines
controlled by a PWM timer on OMAP CPUs.
comment "LED Triggers"
config LEDS_TRIGGERS
......@@ -100,5 +113,14 @@ config LEDS_TRIGGER_IDE_DISK
This allows LEDs to be controlled by IDE disk activity.
If unsure, say Y.
config LEDS_TRIGGER_HEARTBEAT
tristate "LED Heartbeat Trigger"
depends LEDS_TRIGGERS
help
This allows LEDs to be controlled by a CPU load average.
The flash frequency is a hyperbolic function of the 1-minute
load average.
If unsure, say Y.
endmenu
......@@ -11,9 +11,12 @@ obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o
obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
obj-$(CONFIG_LEDS_OMAP) += leds-omap.o
obj-$(CONFIG_LEDS_OMAP_PWM) += leds-omap-pwm.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
......@@ -11,7 +11,6 @@
* published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
......
......@@ -23,6 +23,14 @@ config MTD_NAND_VERIFY_WRITE
device thinks the write was successful, a bit could have been
flipped accidentaly due to device wear or something else.
config MTD_NAND_ECC_SMC
bool "NAND ECC Smart Media byte order"
depends on MTD_NAND
default n
help
Software ECC according to the Smart Media Specification.
The original Linux implementation had byte 0 and 1 swapped.
config MTD_NAND_AUTCPU12
tristate "SmartMediaCard on autronix autcpu12 board"
depends on MTD_NAND && ARCH_AUTCPU12
......@@ -49,6 +57,12 @@ config MTD_NAND_SPIA
help
If you had to ask, you don't have one. Say 'N'.
config MTD_NAND_AMS_DELTA
tristate "NAND Flash device on Amstrad E3"
depends on MACH_AMS_DELTA && MTD_NAND
help
Support for NAND flash on Amstrad E3 (Delta).
config MTD_NAND_OMAP
tristate "NAND Flash device on OMAP H3/H2/P2 boards"
depends on ARM && ARCH_OMAP1 && MTD_NAND && (MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_PERSEUS2)
......@@ -64,10 +78,16 @@ config MTD_NAND_OMAP_HW
config MTD_NAND_TOTO
tristate "NAND Flash device on TOTO board"
depends on ARCH_OMAP && MTD_NAND
depends on ARCH_OMAP && MTD_NAND && BROKEN
help
Support for NAND flash on Texas Instruments Toto platform.
config MTD_NAND_TS7250
tristate "NAND Flash device on TS-7250 board"
depends on MACH_TS72XX && MTD_NAND
help
Support for NAND flash on Technologic Systems TS-7250 platform.
config MTD_NAND_IDS
tristate
......@@ -89,7 +109,7 @@ config MTD_NAND_RTC_FROM4
config MTD_NAND_PPCHAMELEONEVB
tristate "NAND Flash device on PPChameleonEVB board"
depends on PPCHAMELEONEVB && MTD_NAND
depends on PPCHAMELEONEVB && MTD_NAND && BROKEN
help
This enables the NAND flash driver on the PPChameleon EVB Board.
......@@ -100,7 +120,7 @@ config MTD_NAND_S3C2410
This enables the NAND flash controller on the S3C2410 and S3C2440
SoCs
No board specfic support is done by this driver, each board
No board specific support is done by this driver, each board
must advertise a platform_device for the driver to attach.
config MTD_NAND_S3C2410_DEBUG
......@@ -122,6 +142,22 @@ config MTD_NAND_S3C2410_HWECC
currently not be able to switch to software, as there is no
implementation for ECC method used by the S3C2410
config MTD_NAND_NDFC
tristate "NDFC NanD Flash Controller"
depends on MTD_NAND && 44x
help
NDFC Nand Flash Controllers are integrated in EP44x SoCs
config MTD_NAND_S3C2410_CLKSTOP
bool "S3C2410 NAND IDLE clock stop"
depends on MTD_NAND_S3C2410
default n
help
Stop the clock to the NAND controller when there is no chip
selected to save power. This will mean there is a small delay
when the is NAND chip selected or released, but will save
approximately 5mA of power when there is nothing happening.
config MTD_NAND_DISKONCHIP
tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
depends on MTD_NAND && EXPERIMENTAL
......@@ -196,11 +232,24 @@ config MTD_NAND_SHARPSL
tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
depends on MTD_NAND && ARCH_PXA
config MTD_NAND_CS553X
tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
depends on MTD_NAND && X86_32 && (X86_PC || X86_GENERICARCH)
help
The CS553x companion chips for the AMD Geode processor
include NAND flash controllers with built-in hardware ECC
capabilities; enabling this option will allow you to use
these. The driver will check the MSRs to verify that the
controller is enabled for NAND, and currently requires that
the controller be in MMIO mode.
If you say "m", the module will be called "cs553x_nand.ko".
config MTD_NAND_NANDSIM
tristate "Support for NAND Flash Simulator"
depends on MTD_NAND && MTD_PARTITIONS
help
The simulator may simulate verious NAND flash chips for the
The simulator may simulate various NAND flash chips for the
MTD nand layer.
endmenu
......@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o
obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
......@@ -17,7 +18,10 @@ obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o
obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o
obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
obj-$(CONFIG_MTD_NAND_OMAP) += omap-nand-flash.o
obj-$(CONFIG_MTD_NAND_OMAP_HW) += omap-hw.o
......
......@@ -14,7 +14,7 @@
* This file is licenced under the GPL.
*/
#include <linux/signal.h> /* SA_INTERRUPT */
#include <linux/signal.h> /* IRQF_DISABLED */
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
......@@ -353,7 +353,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
retval = -ENXIO;
goto err2;
}
retval = usb_add_hcd(hcd, irq, SA_INTERRUPT);
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
if (retval)
goto err2;
......
This diff is collapsed.
......@@ -24,8 +24,8 @@
#include <linux/console.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h> /* For in_interrupt() */
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/security.h>
......@@ -56,7 +56,7 @@ int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
};
EXPORT_SYMBOL(console_printk);
EXPORT_UNUSED_SYMBOL(console_printk); /* June 2006 */
/*
* Low lever drivers may need that to know if they can schedule in
......@@ -71,6 +71,7 @@ EXPORT_SYMBOL(oops_in_progress);
* driver system.
*/
static DECLARE_MUTEX(console_sem);
static DECLARE_MUTEX(secondary_console_sem);
struct console *console_drivers;
/*
* This is used for debugging the mess that is the VT code by
......@@ -80,7 +81,7 @@ struct console *console_drivers;
* path in the console code where we end up in places I want
* locked without the console sempahore held
*/
static int console_locked;
static int console_locked, console_suspended;
/*
* logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
......@@ -330,7 +331,9 @@ static void __call_console_drivers(unsigned long start, unsigned long end)
struct console *con;
for (con = console_drivers; con; con = con->next) {
if ((con->flags & CON_ENABLED) && con->write)
if ((con->flags & CON_ENABLED) && con->write &&
(cpu_online(smp_processor_id()) ||
(con->flags & CON_ANYTIME)))
con->write(con, &LOG_BUF(start), end - start);
}
}
......@@ -470,6 +473,18 @@ __attribute__((weak)) unsigned long long printk_clock(void)
return sched_clock();
}
/* Check if we have any console registered that can be called early in boot. */
static int have_callable_console(void)
{
struct console *con;
for (con = console_drivers; con; con = con->next)
if (con->flags & CON_ANYTIME)
return 1;
return 0;
}
/**
* printk - print a kernel message
* @fmt: format string
......@@ -520,7 +535,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
zap_locks();
/* This stops the holder of console_sem just where we want him */
spin_lock_irqsave(&logbuf_lock, flags);
local_irq_save(flags);
lockdep_off();
spin_lock(&logbuf_lock);
printk_cpu = smp_processor_id();
/* Emit the output into the temporary buffer */
......@@ -587,27 +604,31 @@ asmlinkage int vprintk(const char *fmt, va_list args)
log_level_unknown = 1;
}
if (!cpu_online(smp_processor_id())) {
if (!down_trylock(&console_sem)) {
/*
* Some console drivers may assume that per-cpu resources have
* been allocated. So don't allow them to be called by this
* CPU until it is officially up. We shouldn't be calling into
* random console drivers on a CPU which doesn't exist yet..
* We own the drivers. We can drop the spinlock and
* let release_console_sem() print the text, maybe ...
*/
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
goto out;
}
if (!down_trylock(&console_sem)) {
console_locked = 1;
printk_cpu = UINT_MAX;
spin_unlock(&logbuf_lock);
/*
* We own the drivers. We can drop the spinlock and let
* release_console_sem() print the text
* Console drivers may assume that per-cpu resources have
* been allocated. So unless they're explicitly marked as
* being able to cope (CON_ANYTIME) don't call them until
* this CPU is officially up.
*/
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
console_may_schedule = 0;
release_console_sem();
if (cpu_online(smp_processor_id()) || have_callable_console()) {
console_may_schedule = 0;
release_console_sem();
} else {
/* Release by hand to avoid flushing the buffer. */
console_locked = 0;
up(&console_sem);
}
lockdep_on();
local_irq_restore(flags);
} else {
/*
* Someone else owns the drivers. We drop the spinlock, which
......@@ -615,9 +636,11 @@ asmlinkage int vprintk(const char *fmt, va_list args)
* console drivers with the output which we just produced.
*/
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
spin_unlock(&logbuf_lock);
lockdep_on();
local_irq_restore(flags);
}
out:
preempt_enable();
return printed_len;
}
......@@ -719,6 +742,23 @@ int __init add_preferred_console(char *name, int idx, char *options)
return 0;
}
/**
* suspend_console - suspend the console subsystem
*
* This disables printk() while we go into suspend states
*/
void suspend_console(void)
{
acquire_console_sem();
console_suspended = 1;
}
void resume_console(void)
{
console_suspended = 0;
release_console_sem();
}
/**
* acquire_console_sem - lock the console system for exclusive use.
*
......@@ -730,6 +770,10 @@ int __init add_preferred_console(char *name, int idx, char *options)
void acquire_console_sem(void)
{
BUG_ON(in_interrupt());
if (console_suspended) {
down(&secondary_console_sem);
return;
}
down(&console_sem);
console_locked = 1;
console_may_schedule = 1;
......@@ -750,7 +794,7 @@ int is_console_locked(void)
{
return console_locked;
}
EXPORT_SYMBOL(is_console_locked);
EXPORT_UNUSED_SYMBOL(is_console_locked); /* June 2006 */
/**
* release_console_sem - unlock the console system
......@@ -772,6 +816,13 @@ void release_console_sem(void)
unsigned long _con_start, _log_end;
unsigned long wake_klogd = 0;
if (console_suspended) {
up(&secondary_console_sem);
return;
}
console_may_schedule = 0;
for ( ; ; ) {
spin_lock_irqsave(&logbuf_lock, flags);
wake_klogd |= log_start - log_end;
......@@ -785,11 +836,17 @@ void release_console_sem(void)
local_irq_restore(flags);
}
console_locked = 0;
console_may_schedule = 0;
up(&console_sem);
spin_unlock_irqrestore(&logbuf_lock, flags);
if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))
wake_up_interruptible(&log_wait);
if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) {
/*
* If we printk from within the lock dependency code,
* from within the scheduler code, then do not lock
* up due to self-recursion:
*/
if (!lockdep_internal())
wake_up_interruptible(&log_wait);
}
}
EXPORT_SYMBOL(release_console_sem);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment