Commit d7203748 authored by Steve French's avatar Steve French

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs
parents d5c7cd85 a60e227b
...@@ -1444,27 +1444,6 @@ as Alan Cox says, <quote>Lock data, not code</quote>. ...@@ -1444,27 +1444,6 @@ as Alan Cox says, <quote>Lock data, not code</quote>.
</para> </para>
</sect1> </sect1>
<sect1 id="sparc">
<title>The Fucked Up Sparc</title>
<para>
Alan Cox says <quote>the irq disable/enable is in the register
window on a sparc</quote>. Andi Kleen says <quote>when you do
restore_flags in a different function you mess up all the
register windows</quote>.
</para>
<para>
So never pass the flags word set by
<function>spin_lock_irqsave()</function> and brethren to another
function (unless it's declared <type>inline</type>). Usually no-one
does this, but now you've been warned. Dave Miller can never do
anything in a straightforward manner (I can say that, because I have
pictures of him and a certain PowerPC maintainer in a compromising
position).
</para>
</sect1>
</chapter> </chapter>
<chapter id="Efficiency"> <chapter id="Efficiency">
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 3 SUBLEVEL = 3
EXTRAVERSION =-rc2 EXTRAVERSION =-rc3
NAME=Feisty Dunnart NAME=Feisty Dunnart
# *DOCUMENTATION* # *DOCUMENTATION*
......
...@@ -50,7 +50,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, ...@@ -50,7 +50,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
if (nr_env < 2) if (nr_env < 2)
return -ENOMEM; return -ENOMEM;
snprintf(buf, bufsz, "AMBA_ID=%08lx", pcdev->periphid); snprintf(buf, bufsz, "AMBA_ID=%08x", pcdev->periphid);
*envp++ = buf; *envp++ = buf;
*envp++ = NULL; *envp++ = NULL;
return 0; return 0;
......
...@@ -116,7 +116,7 @@ static inline void do_set_rtc(void) ...@@ -116,7 +116,7 @@ static inline void do_set_rtc(void)
return; return;
if (next_rtc_update && if (next_rtc_update &&
time_before(xtime.tv_sec, next_rtc_update)) time_before((unsigned long)xtime.tv_sec, next_rtc_update))
return; return;
if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) && if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
......
...@@ -159,9 +159,14 @@ static struct resource sa11x0mcp_resources[] = { ...@@ -159,9 +159,14 @@ static struct resource sa11x0mcp_resources[] = {
}, },
}; };
static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
static struct platform_device sa11x0mcp_device = { static struct platform_device sa11x0mcp_device = {
.name = "sa11x0-mcp", .name = "sa11x0-mcp",
.id = 0, .id = 0,
.dev = {
.dma_mask = &sa11x0mcp_dma_mask,
},
.num_resources = ARRAY_SIZE(sa11x0mcp_resources), .num_resources = ARRAY_SIZE(sa11x0mcp_resources),
.resource = sa11x0mcp_resources, .resource = sa11x0mcp_resources,
}; };
......
...@@ -291,8 +291,8 @@ config ARM_THUMB ...@@ -291,8 +291,8 @@ config ARM_THUMB
depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE
default y default y
help help
Say Y if you want to have kernel support for ARM Thumb instructions, Say Y if you want to include kernel support for running user space
fault handlers, and system calls. Thumb binaries.
The Thumb instruction set is a compressed form of the standard ARM The Thumb instruction set is a compressed form of the standard ARM
instruction set resulting in smaller binaries at the expense of instruction set resulting in smaller binaries at the expense of
......
...@@ -589,7 +589,7 @@ acpi_boot_init (void) ...@@ -589,7 +589,7 @@ acpi_boot_init (void)
smp_boot_data.cpu_count = available_cpus; smp_boot_data.cpu_count = available_cpus;
smp_build_cpu_map(); smp_build_cpu_map();
# ifdef CONFIG_NUMA # ifdef CONFIG_ACPI_NUMA
if (srat_num_cpus == 0) { if (srat_num_cpus == 0) {
int cpu, i = 1; int cpu, i = 1;
for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++) for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++)
......
...@@ -465,8 +465,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -465,8 +465,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
desc->handler->ack(irq); desc->handler->ack(irq);
action_ret = handle_IRQ_event(irq, regs, desc->action); action_ret = handle_IRQ_event(irq, regs, desc->action);
desc->handler->end(irq); desc->handler->end(irq);
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
} else { } else {
spin_lock(&desc->lock); spin_lock(&desc->lock);
desc->handler->ack(irq); desc->handler->ack(irq);
......
...@@ -239,10 +239,9 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe) ...@@ -239,10 +239,9 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
* and wakes up any processes waiting for error records. * and wakes up any processes waiting for error records.
* *
* Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT) * Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT)
* called_from_init (1 for boot processing)
*/ */
static void static void
ia64_mca_log_sal_error_record(int sal_info_type, int called_from_init) ia64_mca_log_sal_error_record(int sal_info_type)
{ {
u8 *buffer; u8 *buffer;
u64 size; u64 size;
...@@ -255,7 +254,7 @@ ia64_mca_log_sal_error_record(int sal_info_type, int called_from_init) ...@@ -255,7 +254,7 @@ ia64_mca_log_sal_error_record(int sal_info_type, int called_from_init)
salinfo_log_wakeup(sal_info_type, buffer, size, irq_safe); salinfo_log_wakeup(sal_info_type, buffer, size, irq_safe);
if (irq_safe || called_from_init) if (irq_safe)
printk(KERN_INFO "CPU %d: SAL log contains %s error record\n", printk(KERN_INFO "CPU %d: SAL log contains %s error record\n",
smp_processor_id(), smp_processor_id(),
sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN"); sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN");
...@@ -280,7 +279,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) ...@@ -280,7 +279,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
local_irq_enable(); local_irq_enable();
/* Get the CMC error record and log it */ /* Get the CMC error record and log it */
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE, 0); ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -469,32 +468,6 @@ init_handler_platform (pal_min_state_area_t *ms, ...@@ -469,32 +468,6 @@ init_handler_platform (pal_min_state_area_t *ms,
while (1); /* hang city if no debugger */ while (1); /* hang city if no debugger */
} }
/*
* ia64_mca_check_errors
*
* External entry to check for error records which may have been posted by SAL
* for a prior failure which resulted in a machine shutdown before an the
* error could be logged. This function must be called after the filesystem
* is initialized.
*
* Inputs : None
*
* Outputs : None
*/
int
ia64_mca_check_errors (void)
{
/*
* If there is an MCA error record pending, get it and log it.
*/
printk(KERN_INFO "CPU %d: checking for saved MCA error records\n", smp_processor_id());
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 1);
return 0;
}
device_initcall(ia64_mca_check_errors);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
/* /*
* ia64_mca_register_cpev * ia64_mca_register_cpev
...@@ -831,7 +804,7 @@ ia64_mca_ucmc_handler(void) ...@@ -831,7 +804,7 @@ ia64_mca_ucmc_handler(void)
int recover = psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc); int recover = psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc);
/* Get the MCA error record and log it */ /* Get the MCA error record and log it */
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 0); ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
/* /*
* Wakeup all the processors which are spinning in the rendezvous * Wakeup all the processors which are spinning in the rendezvous
...@@ -875,7 +848,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs) ...@@ -875,7 +848,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
local_irq_enable(); local_irq_enable();
/* Get the CMC error record and log it */ /* Get the CMC error record and log it */
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC, 0); ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
spin_lock(&cmc_history_lock); spin_lock(&cmc_history_lock);
if (!cmc_polling_enabled) { if (!cmc_polling_enabled) {
......
...@@ -18,10 +18,6 @@ ...@@ -18,10 +18,6 @@
* 10/13/00 Goutham Rao <goutham.rao@intel.com> Updated smp_call_function and * 10/13/00 Goutham Rao <goutham.rao@intel.com> Updated smp_call_function and
* smp_call_function_single to resend IPI on timeouts * smp_call_function_single to resend IPI on timeouts
*/ */
#define __KERNEL_SYSCALLS__
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
......
...@@ -10,10 +10,6 @@ ...@@ -10,10 +10,6 @@
* smp_boot_cpus()/smp_commence() is replaced by * smp_boot_cpus()/smp_commence() is replaced by
* smp_prepare_cpus()/__cpu_up()/smp_cpus_done(). * smp_prepare_cpus()/__cpu_up()/smp_cpus_done().
*/ */
#define __KERNEL_SYSCALLS__
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -306,7 +302,6 @@ smp_callin (void) ...@@ -306,7 +302,6 @@ smp_callin (void)
#ifdef CONFIG_IA64_MCA #ifdef CONFIG_IA64_MCA
ia64_mca_cmc_vector_setup(); /* Setup vector on AP & enable */ ia64_mca_cmc_vector_setup(); /* Setup vector on AP & enable */
ia64_mca_check_errors(); /* For post-failure MCA error logging */
#endif #endif
#ifdef CONFIG_PERFMON #ifdef CONFIG_PERFMON
......
...@@ -5,9 +5,14 @@ ...@@ -5,9 +5,14 @@
CPPFLAGS="" CPPFLAGS=""
CC=$1 CC=$1
OBJDUMP=$2 OBJDUMP=$2
READELF=$3
dir=$(dirname $0) dir=$(dirname $0)
tmp=${TMPDIR:-/tmp} tmp=${TMPDIR:-/tmp}
out=$tmp/out$$ out=$tmp/out$$
# Check whether cross-segment segment-relative relocs work fine. We need
# that for building the gate DSO:
$CC -nostdlib -static -Wl,-T$dir/check-segrel.lds $dir/check-segrel.S -o $out $CC -nostdlib -static -Wl,-T$dir/check-segrel.lds $dir/check-segrel.S -o $out
res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ') res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ')
rm -f $out rm -f $out
...@@ -20,6 +25,16 @@ warning: your linker cannot handle cross-segment segment-relative relocations. ...@@ -20,6 +25,16 @@ warning: your linker cannot handle cross-segment segment-relative relocations.
EOF EOF
fi fi
# Check whether .align inside a function works as expected.
$CC -c $dir/check-text-align.S -o $out
$READELF -u $out | fgrep -q 'prologue(rlen=12)'
res=$?
rm -f $out
if [ $res -eq 0 ]; then
CPPFLAGS="$CPPFLAGS -DHAVE_WORKING_TEXT_ALIGN"
fi
if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep __model__ | grep -q attrib if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep __model__ | grep -q attrib
then then
CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE" CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
......
...@@ -71,6 +71,8 @@ u64 sn_partition_serial_number; ...@@ -71,6 +71,8 @@ u64 sn_partition_serial_number;
short physical_node_map[MAX_PHYSNODE_ID]; short physical_node_map[MAX_PHYSNODE_ID];
EXPORT_SYMBOL(physical_node_map);
int numionodes; int numionodes;
/* /*
* This is the address of the RRegs in the HSpace of the global * This is the address of the RRegs in the HSpace of the global
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
* *
*/ */
#include <linux/module.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
/** /**
......
...@@ -772,7 +772,7 @@ sn_sal_read_proc(char *page, char **start, off_t off, int count, ...@@ -772,7 +772,7 @@ sn_sal_read_proc(char *page, char **start, off_t off, int count,
int len = 0; int len = 0;
off_t begin = 0; off_t begin = 0;
len += sprintf(page, "sn_serial: nasid:%d irq:%d tx:%d rx:%d\n", len += sprintf(page, "sn_serial: nasid:%ld irq:%d tx:%d rx:%d\n",
ia64_sn_get_console_nasid(), sn_sal_irq, ia64_sn_get_console_nasid(), sn_sal_irq,
sn_total_tx_count, sn_total_rx_count); sn_total_tx_count, sn_total_rx_count);
*eof = 1; *eof = 1;
......
...@@ -72,13 +72,6 @@ ...@@ -72,13 +72,6 @@
/* How many iterations between battery polls */ /* How many iterations between battery polls */
#define BATTERY_POLLING_COUNT 2 #define BATTERY_POLLING_COUNT 2
/* Some debugging tools */
#ifdef CONFIG_XMON
//#define LIVE_DEBUG(req) ((req) && (req)->data[0] == 0x7d)
#define LIVE_DEBUG(req) (0)
static int whacky_debug;
#endif /* CONFIG_XMON */
static volatile unsigned char *via; static volatile unsigned char *via;
/* VIA registers - spaced 0x200 bytes apart */ /* VIA registers - spaced 0x200 bytes apart */
...@@ -1218,12 +1211,6 @@ pmu_start(void) ...@@ -1218,12 +1211,6 @@ pmu_start(void)
wait_for_ack(); wait_for_ack();
/* set the shift register to shift out and send a byte */ /* set the shift register to shift out and send a byte */
send_byte(req->data[0]); send_byte(req->data[0]);
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("R");
else
whacky_debug = 0;
#endif /* CONFIG_XMON */
} }
void __openfirmware void __openfirmware
...@@ -1476,29 +1463,17 @@ pmu_sr_intr(struct pt_regs *regs) ...@@ -1476,29 +1463,17 @@ pmu_sr_intr(struct pt_regs *regs)
case sending: case sending:
req = current_req; req = current_req;
if (data_len < 0) { if (data_len < 0) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("s");
#endif /* CONFIG_XMON */
data_len = req->nbytes - 1; data_len = req->nbytes - 1;
send_byte(data_len); send_byte(data_len);
break; break;
} }
if (data_index <= data_len) { if (data_index <= data_len) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("S");
#endif /* CONFIG_XMON */
send_byte(req->data[data_index++]); send_byte(req->data[data_index++]);
break; break;
} }
req->sent = 1; req->sent = 1;
data_len = pmu_data_len[req->data[0]][1]; data_len = pmu_data_len[req->data[0]][1];
if (data_len == 0) { if (data_len == 0) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("D");
#endif /* CONFIG_XMON */
pmu_state = idle; pmu_state = idle;
current_req = req->next; current_req = req->next;
if (req->reply_expected) if (req->reply_expected)
...@@ -1506,10 +1481,6 @@ pmu_sr_intr(struct pt_regs *regs) ...@@ -1506,10 +1481,6 @@ pmu_sr_intr(struct pt_regs *regs)
else else
return req; return req;
} else { } else {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("-");
#endif /* CONFIG_XMON */
pmu_state = reading; pmu_state = reading;
data_index = 0; data_index = 0;
reply_ptr = req->reply + req->reply_len; reply_ptr = req->reply + req->reply_len;
...@@ -1532,18 +1503,10 @@ pmu_sr_intr(struct pt_regs *regs) ...@@ -1532,18 +1503,10 @@ pmu_sr_intr(struct pt_regs *regs)
case reading: case reading:
case reading_intr: case reading_intr:
if (data_len == -1) { if (data_len == -1) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(current_req))
xmon_printf("r");
#endif /* CONFIG_XMON */
data_len = bite; data_len = bite;
if (bite > 32) if (bite > 32)
printk(KERN_ERR "PMU: bad reply len %d\n", bite); printk(KERN_ERR "PMU: bad reply len %d\n", bite);
} else if (data_index < 32) { } else if (data_index < 32) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(current_req))
xmon_printf("R");
#endif /* CONFIG_XMON */
reply_ptr[data_index++] = bite; reply_ptr[data_index++] = bite;
} }
if (data_index < data_len) { if (data_index < data_len) {
...@@ -1551,12 +1514,6 @@ pmu_sr_intr(struct pt_regs *regs) ...@@ -1551,12 +1514,6 @@ pmu_sr_intr(struct pt_regs *regs)
break; break;
} }
#ifdef CONFIG_XMON
if (LIVE_DEBUG(current_req)) {
whacky_debug = 1;
xmon_printf("D");
}
#endif /* CONFIG_XMON */
if (pmu_state == reading_intr) { if (pmu_state == reading_intr) {
pmu_state = idle; pmu_state = idle;
int_data_state[int_data_last] = int_data_ready; int_data_state[int_data_last] = int_data_ready;
...@@ -1603,10 +1560,6 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) ...@@ -1603,10 +1560,6 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
intr = in_8(&via[IFR]) & (SR_INT | CB1_INT); intr = in_8(&via[IFR]) & (SR_INT | CB1_INT);
if (intr == 0) if (intr == 0)
break; break;
#ifdef CONFIG_XMON
if (whacky_debug)
xmon_printf("|%02x|", intr);
#endif /* CONFIG_XMON */
handled = 1; handled = 1;
if (++nloop > 1000) { if (++nloop > 1000) {
printk(KERN_DEBUG "PMU: stuck in intr loop, " printk(KERN_DEBUG "PMU: stuck in intr loop, "
...@@ -1629,10 +1582,6 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) ...@@ -1629,10 +1582,6 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
recheck: recheck:
if (pmu_state == idle) { if (pmu_state == idle) {
if (adb_int_pending) { if (adb_int_pending) {
#ifdef CONFIG_XMON
if (whacky_debug)
xmon_printf("!A!");
#endif /* CONFIG_XMON */
if (int_data_state[0] == int_data_empty) if (int_data_state[0] == int_data_empty)
int_data_last = 0; int_data_last = 0;
else if (int_data_state[1] == int_data_empty) else if (int_data_state[1] == int_data_empty)
......
This diff is collapsed.
...@@ -28,7 +28,7 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) ...@@ -28,7 +28,7 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
struct fb_fillrect modded; struct fb_fillrect modded;
int vxres, vyres; int vxres, vyres;
if (rinfo->asleep) if (info->state != FBINFO_STATE_RUNNING)
return; return;
if (radeon_accel_disabled()) { if (radeon_accel_disabled()) {
cfb_fillrect(info, region); cfb_fillrect(info, region);
...@@ -81,7 +81,7 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) ...@@ -81,7 +81,7 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
modded.width = area->width; modded.width = area->width;
modded.height = area->height; modded.height = area->height;
if (rinfo->asleep) if (info->state != FBINFO_STATE_RUNNING)
return; return;
if (radeon_accel_disabled()) { if (radeon_accel_disabled()) {
cfb_copyarea(info, area); cfb_copyarea(info, area);
...@@ -108,7 +108,7 @@ void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) ...@@ -108,7 +108,7 @@ void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
if (rinfo->asleep) if (info->state != FBINFO_STATE_RUNNING)
return; return;
radeon_engine_idle(); radeon_engine_idle();
...@@ -119,7 +119,7 @@ int radeonfb_sync(struct fb_info *info) ...@@ -119,7 +119,7 @@ int radeonfb_sync(struct fb_info *info)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
if (rinfo->asleep) if (info->state != FBINFO_STATE_RUNNING)
return 0; return 0;
radeon_engine_idle(); radeon_engine_idle();
......
...@@ -566,8 +566,9 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo) ...@@ -566,8 +566,9 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
break; break;
} }
do_div(vclk, 1000); vclk *= denom;
xtal = (xtal * denom) / num; do_div(vclk, 1000 * num);
xtal = vclk;
if ((xtal > 26900) && (xtal < 27100)) if ((xtal > 26900) && (xtal < 27100))
xtal = 2700; xtal = 2700;
......
...@@ -346,6 +346,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) ...@@ -346,6 +346,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
int dst_idx = 0, src_idx = 0, rev_copy = 0; int dst_idx = 0, src_idx = 0, rev_copy = 0;
unsigned long *dst = NULL, *src = NULL; unsigned long *dst = NULL, *src = NULL;
if (p->state != FBINFO_STATE_RUNNING)
return;
/* We want rotation but lack hardware to do it for us. */ /* We want rotation but lack hardware to do it for us. */
if (!p->fbops->fb_rotate && p->var.rotate) { if (!p->fbops->fb_rotate && p->var.rotate) {
} }
......
...@@ -367,6 +367,9 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) ...@@ -367,6 +367,9 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
unsigned long *dst; unsigned long *dst;
int dst_idx, left; int dst_idx, left;
if (p->state != FBINFO_STATE_RUNNING)
return;
/* We want rotation but lack hardware to do it for us. */ /* We want rotation but lack hardware to do it for us. */
if (!p->fbops->fb_rotate && p->var.rotate) { if (!p->fbops->fb_rotate && p->var.rotate) {
} }
......
...@@ -275,6 +275,9 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) ...@@ -275,6 +275,9 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
int x2, y2, vxres, vyres; int x2, y2, vxres, vyres;
u8 *dst1; u8 *dst1;
if (p->state != FBINFO_STATE_RUNNING)
return;
vxres = p->var.xres_virtual; vxres = p->var.xres_virtual;
vyres = p->var.yres_virtual; vyres = p->var.yres_virtual;
/* /*
......
...@@ -195,11 +195,13 @@ static void fb_flashcursor(void *private) ...@@ -195,11 +195,13 @@ static void fb_flashcursor(void *private)
{ {
struct fb_info *info = (struct fb_info *) private; struct fb_info *info = (struct fb_info *) private;
/* Test to see if the cursor is erased but still on */ if (!info || info->state != FBINFO_STATE_RUNNING ||
if (!info || (info->cursor.rop == ROP_COPY)) info->cursor.rop == ROP_COPY)
return; return;
acquire_console_sem();
info->cursor.enable ^= 1; info->cursor.enable ^= 1;
info->fbops->fb_cursor(info, &info->cursor); info->fbops->fb_cursor(info, &info->cursor);
release_console_sem();
} }
#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC) #if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC)
...@@ -226,8 +228,7 @@ static void cursor_timer_handler(unsigned long dev_addr) ...@@ -226,8 +228,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
struct fb_info *info = (struct fb_info *) dev_addr; struct fb_info *info = (struct fb_info *) dev_addr;
schedule_work(&info->queue); schedule_work(&info->queue);
cursor_timer.expires = jiffies + HZ / 5; mod_timer(&cursor_timer, jiffies + HZ/5);
add_timer(&cursor_timer);
} }
int __init fb_console_setup(char *this_opt) int __init fb_console_setup(char *this_opt)
...@@ -353,8 +354,6 @@ static void putcs_unaligned(struct vc_data *vc, struct fb_info *info, ...@@ -353,8 +354,6 @@ static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
info->fbops->fb_imageblit(info, image); info->fbops->fb_imageblit(info, image);
image->dx += cnt * vc->vc_font.width; image->dx += cnt * vc->vc_font.width;
count -= cnt; count -= cnt;
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
} }
} }
...@@ -393,8 +392,6 @@ static void putcs_aligned(struct vc_data *vc, struct fb_info *info, ...@@ -393,8 +392,6 @@ static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
info->fbops->fb_imageblit(info, image); info->fbops->fb_imageblit(info, image);
image->dx += cnt * vc->vc_font.width; image->dx += cnt * vc->vc_font.width;
count -= cnt; count -= cnt;
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
} }
} }
...@@ -465,8 +462,6 @@ static void accel_putc(struct vc_data *vc, struct fb_info *info, ...@@ -465,8 +462,6 @@ static void accel_putc(struct vc_data *vc, struct fb_info *info,
move_buf_aligned(info, dst, src, pitch, width, image.height); move_buf_aligned(info, dst, src, pitch, width, image.height);
info->fbops->fb_imageblit(info, &image); info->fbops->fb_imageblit(info, &image);
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
} }
void accel_putcs(struct vc_data *vc, struct fb_info *info, void accel_putcs(struct vc_data *vc, struct fb_info *info,
...@@ -676,7 +671,7 @@ static const char *fbcon_startup(void) ...@@ -676,7 +671,7 @@ static const char *fbcon_startup(void)
if (!info->queue.func) { if (!info->queue.func) {
INIT_WORK(&info->queue, fb_flashcursor, info); INIT_WORK(&info->queue, fb_flashcursor, info);
cursor_timer.expires = jiffies + HZ / 50; cursor_timer.expires = jiffies + HZ / 5;
cursor_timer.data = (unsigned long ) info; cursor_timer.data = (unsigned long ) info;
add_timer(&cursor_timer); add_timer(&cursor_timer);
} }
...@@ -944,6 +939,8 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, ...@@ -944,6 +939,8 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
if (!info->fbops->fb_blank && console_blanked) if (!info->fbops->fb_blank && console_blanked)
return; return;
if (info->state != FBINFO_STATE_RUNNING)
return;
if (!height || !width) if (!height || !width)
return; return;
...@@ -968,6 +965,8 @@ static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) ...@@ -968,6 +965,8 @@ static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
if (!info->fbops->fb_blank && console_blanked) if (!info->fbops->fb_blank && console_blanked)
return; return;
if (info->state != FBINFO_STATE_RUNNING)
return;
if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
return; return;
...@@ -983,6 +982,8 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, ...@@ -983,6 +982,8 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
if (!info->fbops->fb_blank && console_blanked) if (!info->fbops->fb_blank && console_blanked)
return; return;
if (info->state != FBINFO_STATE_RUNNING)
return;
if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
return; return;
...@@ -2265,6 +2266,39 @@ static int fbcon_set_origin(struct vc_data *vc) ...@@ -2265,6 +2266,39 @@ static int fbcon_set_origin(struct vc_data *vc)
return 0; return 0;
} }
static void fbcon_suspended(struct fb_info *info)
{
/* Clear cursor, restore saved data */
info->cursor.enable = 0;
info->fbops->fb_cursor(info, &info->cursor);
}
static void fbcon_resumed(struct fb_info *info)
{
struct vc_data *vc;
if (info->currcon < 0)
return;
vc = vc_cons[info->currcon].d;
update_screen(vc->vc_num);
}
static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data)
{
struct fb_info *info = (struct fb_info *) data;
switch(action) {
case FB_EVENT_SUSPEND:
fbcon_suspended(info);
break;
case FB_EVENT_RESUME:
fbcon_resumed(info);
break;
}
return 0;
}
/* /*
* The console `switch' structure for the frame buffer based console * The console `switch' structure for the frame buffer based console
*/ */
...@@ -2291,16 +2325,35 @@ const struct consw fb_con = { ...@@ -2291,16 +2325,35 @@ const struct consw fb_con = {
.con_resize = fbcon_resize, .con_resize = fbcon_resize,
}; };
static struct notifier_block fbcon_event_notifer = {
.notifier_call = fbcon_event_notify,
};
static int fbcon_event_notifier_registered;
int __init fb_console_init(void) int __init fb_console_init(void)
{ {
if (!num_registered_fb) if (!num_registered_fb)
return -ENODEV; return -ENODEV;
take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
acquire_console_sem();
if (!fbcon_event_notifier_registered) {
fb_register_client(&fbcon_event_notifer);
fbcon_event_notifier_registered = 1;
}
release_console_sem();
return 0; return 0;
} }
void __exit fb_console_exit(void) void __exit fb_console_exit(void)
{ {
acquire_console_sem();
if (fbcon_event_notifier_registered) {
fb_unregister_client(&fbcon_event_notifer);
fbcon_event_notifier_registered = 0;
}
release_console_sem();
give_up_console(&fb_con); give_up_console(&fb_con);
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/linux_logo.h> #include <linux/linux_logo.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/console.h>
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
#include <linux/kmod.h> #include <linux/kmod.h>
#endif #endif
...@@ -222,6 +223,9 @@ static struct { ...@@ -222,6 +223,9 @@ static struct {
#ifdef CONFIG_FB_RADEON #ifdef CONFIG_FB_RADEON
{ "radeonfb", radeonfb_init, radeonfb_setup }, { "radeonfb", radeonfb_init, radeonfb_setup },
#endif #endif
#ifdef CONFIG_FB_RADEON_OLD
{ "radeonfb_old", radeonfb_init, radeonfb_setup },
#endif
#ifdef CONFIG_FB_CONTROL #ifdef CONFIG_FB_CONTROL
{ "controlfb", control_init, control_setup }, { "controlfb", control_init, control_setup },
#endif #endif
...@@ -395,6 +399,7 @@ extern const char *global_mode_option; ...@@ -395,6 +399,7 @@ extern const char *global_mode_option;
static initcall_t pref_init_funcs[FB_MAX]; static initcall_t pref_init_funcs[FB_MAX];
static int num_pref_init_funcs __initdata = 0; static int num_pref_init_funcs __initdata = 0;
static struct notifier_block *fb_notifier_list;
struct fb_info *registered_fb[FB_MAX]; struct fb_info *registered_fb[FB_MAX];
int num_registered_fb; int num_registered_fb;
...@@ -463,23 +468,32 @@ void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, ...@@ -463,23 +468,32 @@ void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
*/ */
u32 fb_get_buffer_offset(struct fb_info *info, u32 size) u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
{ {
u32 align = info->pixmap.buf_align - 1; struct fb_pixmap *buf = &info->pixmap;
u32 offset, count = 1000; u32 align = buf->buf_align - 1, offset;
spin_lock(&info->pixmap.lock); /* If IO mapped, we need to sync before access, no sharing of
offset = info->pixmap.offset + align; * the pixmap is done
*/
if (buf->flags & FB_PIXMAP_IO) {
if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
info->fbops->fb_sync(info);
return 0;
}
/* See if we fit in the remaining pixmap space */
offset = buf->offset + align;
offset &= ~align; offset &= ~align;
if (offset + size > info->pixmap.size) { if (offset + size > buf->size) {
while (atomic_read(&info->pixmap.count) && count--); /* We do not fit. In order to be able to re-use the buffer,
if (info->fbops->fb_sync && * we must ensure no asynchronous DMA'ing or whatever operation
info->pixmap.flags & FB_PIXMAP_SYNC) * is in progress, we sync for that.
*/
if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
info->fbops->fb_sync(info); info->fbops->fb_sync(info);
offset = 0; offset = 0;
} }
info->pixmap.offset = offset + size; buf->offset = offset + size;
atomic_inc(&info->pixmap.count);
smp_mb__after_atomic_inc();
spin_unlock(&info->pixmap.lock);
return offset; return offset;
} }
...@@ -685,8 +699,8 @@ int fb_show_logo(struct fb_info *info) ...@@ -685,8 +699,8 @@ int fb_show_logo(struct fb_info *info)
struct fb_image image; struct fb_image image;
int x; int x;
/* Return if the frame buffer is not mapped */ /* Return if the frame buffer is not mapped or suspended */
if (fb_logo.logo == NULL) if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
return 0; return 0;
image.depth = fb_logo.depth; image.depth = fb_logo.depth;
...@@ -732,8 +746,6 @@ int fb_show_logo(struct fb_info *info) ...@@ -732,8 +746,6 @@ int fb_show_logo(struct fb_info *info)
x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
image.dx = x; image.dx = x;
info->fbops->fb_imageblit(info, &image); info->fbops->fb_imageblit(info, &image);
//atomic_dec(&info->pixmap.count);
//smp_mb__after_atomic_dec();
} }
if (palette != NULL) if (palette != NULL)
...@@ -780,6 +792,9 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -780,6 +792,9 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
if (!info || ! info->screen_base) if (!info || ! info->screen_base)
return -ENODEV; return -ENODEV;
if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;
if (info->fbops->fb_read) if (info->fbops->fb_read)
return info->fbops->fb_read(file, buf, count, ppos); return info->fbops->fb_read(file, buf, count, ppos);
...@@ -815,6 +830,9 @@ fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ...@@ -815,6 +830,9 @@ fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
if (!info || !info->screen_base) if (!info || !info->screen_base)
return -ENODEV; return -ENODEV;
if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;
if (info->fbops->fb_write) if (info->fbops->fb_write)
return info->fbops->fb_write(file, buf, count, ppos); return info->fbops->fb_write(file, buf, count, ppos);
...@@ -941,6 +959,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) ...@@ -941,6 +959,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
fb_pan_display(info, &info->var); fb_pan_display(info, &info->var);
fb_set_cmap(&info->cmap, 1, info); fb_set_cmap(&info->cmap, 1, info);
notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info);
} }
} }
return 0; return 0;
...@@ -979,7 +999,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -979,7 +999,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct fb_con2fbmap con2fb; struct fb_con2fbmap con2fb;
#endif #endif
struct fb_cmap cmap; struct fb_cmap cmap;
int i; int i, rc;
if (!fb) if (!fb)
return -ENODEV; return -ENODEV;
...@@ -990,7 +1010,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -990,7 +1010,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPUT_VSCREENINFO: case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, (void *) arg, sizeof(var))) if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT; return -EFAULT;
acquire_console_sem();
i = fb_set_var(info, &var); i = fb_set_var(info, &var);
release_console_sem();
if (i) return i; if (i) return i;
if (copy_to_user((void *) arg, &var, sizeof(var))) if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT; return -EFAULT;
...@@ -1009,13 +1031,19 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1009,13 +1031,19 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPAN_DISPLAY: case FBIOPAN_DISPLAY:
if (copy_from_user(&var, (void *) arg, sizeof(var))) if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT; return -EFAULT;
if ((i = fb_pan_display(info, &var))) acquire_console_sem();
i = fb_pan_display(info, &var);
release_console_sem();
if (i)
return i; return i;
if (copy_to_user((void *) arg, &var, sizeof(var))) if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT; return -EFAULT;
return 0; return 0;
case FBIO_CURSOR: case FBIO_CURSOR:
return (fb_cursor(info, (struct fb_cursor *) arg)); acquire_console_sem();
rc = fb_cursor(info, (struct fb_cursor *) arg);
release_console_sem();
return rc;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE #ifdef CONFIG_FRAMEBUFFER_CONSOLE
case FBIOGET_CON2FBMAP: case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb))) if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
...@@ -1045,7 +1073,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1045,7 +1073,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return 0; return 0;
#endif /* CONFIG_FRAMEBUFFER_CONSOLE */ #endif /* CONFIG_FRAMEBUFFER_CONSOLE */
case FBIOBLANK: case FBIOBLANK:
return fb_blank(info, arg); acquire_console_sem();
i = fb_blank(info, arg);
release_console_sem();
return i;
default: default:
if (fb->fb_ioctl == NULL) if (fb->fb_ioctl == NULL)
return -EINVAL; return -EINVAL;
...@@ -1242,7 +1273,6 @@ register_framebuffer(struct fb_info *fb_info) ...@@ -1242,7 +1273,6 @@ register_framebuffer(struct fb_info *fb_info)
fb_info->pixmap.outbuf = sys_outbuf; fb_info->pixmap.outbuf = sys_outbuf;
if (fb_info->pixmap.inbuf == NULL) if (fb_info->pixmap.inbuf == NULL)
fb_info->pixmap.inbuf = sys_inbuf; fb_info->pixmap.inbuf = sys_inbuf;
spin_lock_init(&fb_info->pixmap.lock);
registered_fb[i] = fb_info; registered_fb[i] = fb_info;
...@@ -1279,8 +1309,42 @@ unregister_framebuffer(struct fb_info *fb_info) ...@@ -1279,8 +1309,42 @@ unregister_framebuffer(struct fb_info *fb_info)
return 0; return 0;
} }
/**
* fb_register_client - register a client notifier
* @nb: notifier block to callback on events
*/
int fb_register_client(struct notifier_block *nb)
{
return notifier_chain_register(&fb_notifier_list, nb);
}
/**
* fb_unregister_client - unregister a client notifier
* @nb: notifier block to callback on events
*/
int fb_unregister_client(struct notifier_block *nb)
{
return notifier_chain_unregister(&fb_notifier_list, nb);
}
/**
* fb_set_suspend - low level driver signals suspend
* @info: framebuffer affected
* @state: 0 = resuming, !=0 = suspending
*
* This is meant to be used by low level drivers to
* signal suspend/resume to the core & clients.
* It must be called with the console semaphore held
*/
void fb_set_suspend(struct fb_info *info, int state) void fb_set_suspend(struct fb_info *info, int state)
{ {
if (state) {
notifier_call_chain(&fb_notifier_list, FB_EVENT_SUSPEND, info);
info->state = FBINFO_STATE_SUSPENDED;
} else {
info->state = FBINFO_STATE_RUNNING;
notifier_call_chain(&fb_notifier_list, FB_EVENT_RESUME, info);
}
} }
/** /**
...@@ -1397,5 +1461,7 @@ EXPORT_SYMBOL(fb_get_buffer_offset); ...@@ -1397,5 +1461,7 @@ EXPORT_SYMBOL(fb_get_buffer_offset);
EXPORT_SYMBOL(move_buf_unaligned); EXPORT_SYMBOL(move_buf_unaligned);
EXPORT_SYMBOL(move_buf_aligned); EXPORT_SYMBOL(move_buf_aligned);
EXPORT_SYMBOL(fb_set_suspend); EXPORT_SYMBOL(fb_set_suspend);
EXPORT_SYMBOL(fb_register_client);
EXPORT_SYMBOL(fb_unregister_client);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -1615,8 +1615,9 @@ static int __devinit riva_set_fbinfo(struct fb_info *info) ...@@ -1615,8 +1615,9 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
} }
#ifdef CONFIG_PPC_OF #ifdef CONFIG_PPC_OF
static int riva_get_EDID_OF(struct riva_par *par, struct pci_dev *pd) static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
{ {
struct riva_par *par = (struct riva_par *) info->par;
struct device_node *dp; struct device_node *dp;
unsigned char *pedid = NULL; unsigned char *pedid = NULL;
......
...@@ -48,6 +48,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -48,6 +48,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
info->cursor.image.depth = cursor->image.depth; info->cursor.image.depth = cursor->image.depth;
} }
if (info->state != FBINFO_STATE_RUNNING)
return 0;
s_pitch = (info->cursor.image.width + 7) >> 3; s_pitch = (info->cursor.image.width + 7) >> 3;
dsize = s_pitch * info->cursor.image.height; dsize = s_pitch * info->cursor.image.height;
d_pitch = (s_pitch + scan_align) & ~scan_align; d_pitch = (s_pitch + scan_align) & ~scan_align;
...@@ -74,8 +77,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -74,8 +77,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
info->cursor.image.data = dst; info->cursor.image.data = dst;
info->fbops->fb_imageblit(info, &info->cursor.image); info->fbops->fb_imageblit(info, &info->cursor.image);
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
return 0; return 0;
} }
......
...@@ -114,7 +114,6 @@ extern void ia64_mca_ucmc_handler(void); ...@@ -114,7 +114,6 @@ extern void ia64_mca_ucmc_handler(void);
extern void ia64_monarch_init_handler(void); extern void ia64_monarch_init_handler(void);
extern void ia64_slave_init_handler(void); extern void ia64_slave_init_handler(void);
extern void ia64_mca_cmc_vector_setup(void); extern void ia64_mca_cmc_vector_setup(void);
extern int ia64_mca_check_errors(void);
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_MCA_H */ #endif /* _ASM_IA64_MCA_H */
...@@ -339,6 +339,24 @@ struct fb_info; ...@@ -339,6 +339,24 @@ struct fb_info;
struct device; struct device;
struct file; struct file;
/*
* Register/unregister for framebuffer events
*/
/* The resolution of the passed in fb_info about to change */
#define FB_EVENT_MODE_CHANGE 0x01
/* The display on this fb_info is beeing suspended, no access to the
* framebuffer is allowed any more after that call returns
*/
#define FB_EVENT_SUSPEND 0x02
/* The display on this fb_info was resumed, you can restore the display
* if you own it
*/
#define FB_EVENT_RESUME 0x03
extern int fb_register_client(struct notifier_block *nb);
extern int fb_unregister_client(struct notifier_block *nb);
/* /*
* Pixmap structure definition * Pixmap structure definition
* *
...@@ -363,8 +381,6 @@ struct fb_pixmap { ...@@ -363,8 +381,6 @@ struct fb_pixmap {
/* access methods */ /* access methods */
void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); void (*outbuf)(u8 *dst, u8 *addr, unsigned int size);
u8 (*inbuf) (u8 *addr); u8 (*inbuf) (u8 *addr);
spinlock_t lock; /* spinlock */
atomic_t count;
}; };
/* /*
...@@ -449,6 +465,9 @@ struct fb_info { ...@@ -449,6 +465,9 @@ struct fb_info {
struct vc_data *display_fg; /* Console visible on this display */ struct vc_data *display_fg; /* Console visible on this display */
int currcon; /* Current VC. */ int currcon; /* Current VC. */
void *pseudo_palette; /* Fake palette of 16 colors */ void *pseudo_palette; /* Fake palette of 16 colors */
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend */
/* From here on everything is device dependent */ /* From here on everything is device dependent */
void *par; void *par;
}; };
......
...@@ -216,28 +216,37 @@ ...@@ -216,28 +216,37 @@
/* Rage128 GL */ /* Rage128 GL */
#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245 #define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245
#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246 #define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246
#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x534b #define PCI_DEVICE_ID_ATI_RAGE128_RG 0x5247
#define PCI_DEVICE_ID_ATI_RAGE128_RH 0x534c
#define PCI_DEVICE_ID_ATI_RAGE128_RI 0x534d
/* Rage128 VR */ /* Rage128 VR */
#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b #define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b
#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c #define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c
#define PCI_DEVICE_ID_ATI_RAGE128_RM 0x5345 #define PCI_DEVICE_ID_ATI_RAGE128_SE 0x5345
#define PCI_DEVICE_ID_ATI_RAGE128_RN 0x5346 #define PCI_DEVICE_ID_ATI_RAGE128_SF 0x5346
#define PCI_DEVICE_ID_ATI_RAGE128_RO 0x5347 #define PCI_DEVICE_ID_ATI_RAGE128_SG 0x5347
#define PCI_DEVICE_ID_ATI_RAGE128_SH 0x5348
#define PCI_DEVICE_ID_ATI_RAGE128_SK 0x534b
#define PCI_DEVICE_ID_ATI_RAGE128_SL 0x534c
#define PCI_DEVICE_ID_ATI_RAGE128_SM 0x534d
#define PCI_DEVICE_ID_ATI_RAGE128_SN 0x534e
/* Rage128 Ultra */
#define PCI_DEVICE_ID_ATI_RAGE128_TF 0x5446
#define PCI_DEVICE_ID_ATI_RAGE128_TL 0x544c
#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452
#define PCI_DEVICE_ID_ATI_RAGE128_TS 0x5453
#define PCI_DEVICE_ID_ATI_RAGE128_TT 0x5454
#define PCI_DEVICE_ID_ATI_RAGE128_TU 0x5455
/* Rage128 M3 */ /* Rage128 M3 */
#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45 #define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45
#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46 #define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46
/* Rage128 Pro Ultra */ /* Rage128 M4 */
#define PCI_DEVICE_ID_ATI_RAGE128_U1 0x5446 #define PCI_DEVICE_ID_ATI_RAGE128_MF 0x4d46
#define PCI_DEVICE_ID_ATI_RAGE128_U2 0x544C #define PCI_DEVICE_ID_ATI_RAGE128_ML 0x4d4c
#define PCI_DEVICE_ID_ATI_RAGE128_U3 0x5452
/* Rage128 Pro GL */ /* Rage128 Pro GL */
#define PCI_DEVICE_ID_ATI_Rage128_PA 0x5041 #define PCI_DEVICE_ID_ATI_RAGE128_PA 0x5041
#define PCI_DEVICE_ID_ATI_Rage128_PB 0x5042 #define PCI_DEVICE_ID_ATI_RAGE128_PB 0x5042
#define PCI_DEVICE_ID_ATI_Rage128_PC 0x5043 #define PCI_DEVICE_ID_ATI_RAGE128_PC 0x5043
#define PCI_DEVICE_ID_ATI_Rage128_PD 0x5044 #define PCI_DEVICE_ID_ATI_RAGE128_PD 0x5044
#define PCI_DEVICE_ID_ATI_Rage128_PE 0x5045 #define PCI_DEVICE_ID_ATI_RAGE128_PE 0x5045
#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046 #define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046
/* Rage128 Pro VR */ /* Rage128 Pro VR */
#define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047 #define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047
......
...@@ -416,4 +416,7 @@ ...@@ -416,4 +416,7 @@
#define PMI_PMSCR_REG 0x60 #define PMI_PMSCR_REG 0x60
/* used by ATI bug fix for hardware ROM */
#define RAGE128_MPP_TB_CONFIG 0x01c0
#endif /* REG_RAGE128_H */ #endif /* REG_RAGE128_H */
...@@ -97,10 +97,16 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) ...@@ -97,10 +97,16 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
rfcomm_dlc_unlock(dlc); rfcomm_dlc_unlock(dlc);
rfcomm_dlc_put(dlc); rfcomm_dlc_put(dlc);
/* Refcount should only hit zero when called from rfcomm_dev_del()
which will have taken us off the list. Everything else are
refcounting bugs. */
BUG_ON(!list_empty(&dev->list));
kfree(dev); kfree(dev);
/* It's safe to call module_put() here because socket still /* It's safe to call module_put() here because socket still
holds refference to this module. */ holds reference to this module. */
module_put(THIS_MODULE); module_put(THIS_MODULE);
} }
...@@ -111,6 +117,13 @@ static inline void rfcomm_dev_hold(struct rfcomm_dev *dev) ...@@ -111,6 +117,13 @@ static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
static inline void rfcomm_dev_put(struct rfcomm_dev *dev) static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
{ {
/* The reason this isn't actually a race, as you no
doubt have a little voice screaming at you in your
head, is that the refcount should never actually
reach zero unless the device has already been taken
off the list, in rfcomm_dev_del(). And if that's not
true, we'll hit the BUG() in rfcomm_dev_destruct()
anyway. */
if (atomic_dec_and_test(&dev->refcnt)) if (atomic_dec_and_test(&dev->refcnt))
rfcomm_dev_destruct(dev); rfcomm_dev_destruct(dev);
} }
...@@ -134,10 +147,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id) ...@@ -134,10 +147,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
struct rfcomm_dev *dev; struct rfcomm_dev *dev;
read_lock(&rfcomm_dev_lock); read_lock(&rfcomm_dev_lock);
dev = __rfcomm_dev_get(id); dev = __rfcomm_dev_get(id);
if (dev)
rfcomm_dev_hold(dev);
read_unlock(&rfcomm_dev_lock); read_unlock(&rfcomm_dev_lock);
if (dev) rfcomm_dev_hold(dev);
return dev; return dev;
} }
...@@ -214,8 +230,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) ...@@ -214,8 +230,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
rfcomm_dlc_unlock(dlc); rfcomm_dlc_unlock(dlc);
/* It's safe to call __module_get() here because socket already /* It's safe to call __module_get() here because socket already
holds refference to this module. */ holds reference to this module. */
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
out: out:
write_unlock_bh(&rfcomm_dev_lock); write_unlock_bh(&rfcomm_dev_lock);
...@@ -486,7 +503,8 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) ...@@ -486,7 +503,8 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
rfcomm_dev_del(dev); rfcomm_dev_del(dev);
/* We have to drop DLC lock here, otherwise /* We have to drop DLC lock here, otherwise
* rfcomm_dev_put() will dead lock if it's the last refference */ rfcomm_dev_put() will dead lock if it's
the last reference. */
rfcomm_dlc_unlock(dlc); rfcomm_dlc_unlock(dlc);
rfcomm_dev_put(dev); rfcomm_dev_put(dev);
rfcomm_dlc_lock(dlc); rfcomm_dlc_lock(dlc);
...@@ -541,6 +559,10 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -541,6 +559,10 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
BT_DBG("tty %p id %d", tty, id); BT_DBG("tty %p id %d", tty, id);
/* We don't leak this refcount. For reasons which are not entirely
clear, the TTY layer will call our ->close() method even if the
open fails. We decrease the refcount there, and decreasing it
here too would cause breakage. */
dev = rfcomm_dev_get(id); dev = rfcomm_dev_get(id);
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
...@@ -561,10 +583,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -561,10 +583,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
set_bit(RFCOMM_TTY_ATTACHED, &dev->flags); set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel); err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
if (err < 0) { if (err < 0)
rfcomm_dev_put(dev);
return err; return err;
}
/* Wait for DLC to connect */ /* Wait for DLC to connect */
add_wait_queue(&dev->wait, &wait); add_wait_queue(&dev->wait, &wait);
...@@ -589,9 +609,6 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -589,9 +609,6 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->wait, &wait); remove_wait_queue(&dev->wait, &wait);
if (err < 0)
rfcomm_dev_put(dev);
return err; return err;
} }
......
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