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>.
</para>
</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 id="Efficiency">
......
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 3
EXTRAVERSION =-rc2
EXTRAVERSION =-rc3
NAME=Feisty Dunnart
# *DOCUMENTATION*
......
......@@ -50,7 +50,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
if (nr_env < 2)
return -ENOMEM;
snprintf(buf, bufsz, "AMBA_ID=%08lx", pcdev->periphid);
snprintf(buf, bufsz, "AMBA_ID=%08x", pcdev->periphid);
*envp++ = buf;
*envp++ = NULL;
return 0;
......
......@@ -116,7 +116,7 @@ static inline void do_set_rtc(void)
return;
if (next_rtc_update &&
time_before(xtime.tv_sec, next_rtc_update))
time_before((unsigned long)xtime.tv_sec, next_rtc_update))
return;
if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
......
......@@ -159,9 +159,14 @@ static struct resource sa11x0mcp_resources[] = {
},
};
static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
static struct platform_device sa11x0mcp_device = {
.name = "sa11x0-mcp",
.id = 0,
.dev = {
.dma_mask = &sa11x0mcp_dma_mask,
},
.num_resources = ARRAY_SIZE(sa11x0mcp_resources),
.resource = sa11x0mcp_resources,
};
......
......@@ -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
default y
help
Say Y if you want to have kernel support for ARM Thumb instructions,
fault handlers, and system calls.
Say Y if you want to include kernel support for running user space
Thumb binaries.
The Thumb instruction set is a compressed form of the standard ARM
instruction set resulting in smaller binaries at the expense of
......
......@@ -589,7 +589,7 @@ acpi_boot_init (void)
smp_boot_data.cpu_count = available_cpus;
smp_build_cpu_map();
# ifdef CONFIG_NUMA
# ifdef CONFIG_ACPI_NUMA
if (srat_num_cpus == 0) {
int cpu, i = 1;
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)
desc->handler->ack(irq);
action_ret = handle_IRQ_event(irq, regs, desc->action);
desc->handler->end(irq);
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
} else {
spin_lock(&desc->lock);
desc->handler->ack(irq);
......
......@@ -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.
*
* Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT)
* called_from_init (1 for boot processing)
*/
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;
u64 size;
......@@ -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);
if (irq_safe || called_from_init)
if (irq_safe)
printk(KERN_INFO "CPU %d: SAL log contains %s error record\n",
smp_processor_id(),
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)
local_irq_enable();
/* 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;
}
......@@ -469,32 +468,6 @@ init_handler_platform (pal_min_state_area_t *ms,
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
/*
* ia64_mca_register_cpev
......@@ -831,7 +804,7 @@ ia64_mca_ucmc_handler(void)
int recover = psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc);
/* 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
......@@ -875,7 +848,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
local_irq_enable();
/* 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);
if (!cmc_polling_enabled) {
......
......@@ -18,10 +18,6 @@
* 10/13/00 Goutham Rao <goutham.rao@intel.com> Updated smp_call_function and
* smp_call_function_single to resend IPI on timeouts
*/
#define __KERNEL_SYSCALLS__
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......
......@@ -10,10 +10,6 @@
* smp_boot_cpus()/smp_commence() is replaced by
* smp_prepare_cpus()/__cpu_up()/smp_cpus_done().
*/
#define __KERNEL_SYSCALLS__
#include <linux/config.h>
#include <linux/module.h>
......@@ -306,7 +302,6 @@ smp_callin (void)
#ifdef CONFIG_IA64_MCA
ia64_mca_cmc_vector_setup(); /* Setup vector on AP & enable */
ia64_mca_check_errors(); /* For post-failure MCA error logging */
#endif
#ifdef CONFIG_PERFMON
......
......@@ -5,9 +5,14 @@
CPPFLAGS=""
CC=$1
OBJDUMP=$2
READELF=$3
dir=$(dirname $0)
tmp=${TMPDIR:-/tmp}
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
res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ')
rm -f $out
......@@ -20,6 +25,16 @@ warning: your linker cannot handle cross-segment segment-relative relocations.
EOF
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
then
CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
......
......@@ -71,6 +71,8 @@ u64 sn_partition_serial_number;
short physical_node_map[MAX_PHYSNODE_ID];
EXPORT_SYMBOL(physical_node_map);
int numionodes;
/*
* This is the address of the RRegs in the HSpace of the global
......
......@@ -6,7 +6,7 @@
* Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
*
*/
#include <linux/module.h>
#include <asm/pgalloc.h>
/**
......
......@@ -772,7 +772,7 @@ sn_sal_read_proc(char *page, char **start, off_t off, int count,
int len = 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,
sn_total_tx_count, sn_total_rx_count);
*eof = 1;
......
......@@ -72,13 +72,6 @@
/* How many iterations between battery polls */
#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;
/* VIA registers - spaced 0x200 bytes apart */
......@@ -1218,12 +1211,6 @@ pmu_start(void)
wait_for_ack();
/* set the shift register to shift out and send a byte */
send_byte(req->data[0]);
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("R");
else
whacky_debug = 0;
#endif /* CONFIG_XMON */
}
void __openfirmware
......@@ -1476,29 +1463,17 @@ pmu_sr_intr(struct pt_regs *regs)
case sending:
req = current_req;
if (data_len < 0) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("s");
#endif /* CONFIG_XMON */
data_len = req->nbytes - 1;
send_byte(data_len);
break;
}
if (data_index <= data_len) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("S");
#endif /* CONFIG_XMON */
send_byte(req->data[data_index++]);
break;
}
req->sent = 1;
data_len = pmu_data_len[req->data[0]][1];
if (data_len == 0) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("D");
#endif /* CONFIG_XMON */
pmu_state = idle;
current_req = req->next;
if (req->reply_expected)
......@@ -1506,10 +1481,6 @@ pmu_sr_intr(struct pt_regs *regs)
else
return req;
} else {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(req))
xmon_printf("-");
#endif /* CONFIG_XMON */
pmu_state = reading;
data_index = 0;
reply_ptr = req->reply + req->reply_len;
......@@ -1532,18 +1503,10 @@ pmu_sr_intr(struct pt_regs *regs)
case reading:
case reading_intr:
if (data_len == -1) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(current_req))
xmon_printf("r");
#endif /* CONFIG_XMON */
data_len = bite;
if (bite > 32)
printk(KERN_ERR "PMU: bad reply len %d\n", bite);
} else if (data_index < 32) {
#ifdef CONFIG_XMON
if (LIVE_DEBUG(current_req))
xmon_printf("R");
#endif /* CONFIG_XMON */
reply_ptr[data_index++] = bite;
}
if (data_index < data_len) {
......@@ -1551,12 +1514,6 @@ pmu_sr_intr(struct pt_regs *regs)
break;
}
#ifdef CONFIG_XMON
if (LIVE_DEBUG(current_req)) {
whacky_debug = 1;
xmon_printf("D");
}
#endif /* CONFIG_XMON */
if (pmu_state == reading_intr) {
pmu_state = idle;
int_data_state[int_data_last] = int_data_ready;
......@@ -1603,10 +1560,6 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
intr = in_8(&via[IFR]) & (SR_INT | CB1_INT);
if (intr == 0)
break;
#ifdef CONFIG_XMON
if (whacky_debug)
xmon_printf("|%02x|", intr);
#endif /* CONFIG_XMON */
handled = 1;
if (++nloop > 1000) {
printk(KERN_DEBUG "PMU: stuck in intr loop, "
......@@ -1629,10 +1582,6 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
recheck:
if (pmu_state == idle) {
if (adb_int_pending) {
#ifdef CONFIG_XMON
if (whacky_debug)
xmon_printf("!A!");
#endif /* CONFIG_XMON */
if (int_data_state[0] == int_data_empty)
int_data_last = 0;
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)
struct fb_fillrect modded;
int vxres, vyres;
if (rinfo->asleep)
if (info->state != FBINFO_STATE_RUNNING)
return;
if (radeon_accel_disabled()) {
cfb_fillrect(info, region);
......@@ -81,7 +81,7 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
modded.width = area->width;
modded.height = area->height;
if (rinfo->asleep)
if (info->state != FBINFO_STATE_RUNNING)
return;
if (radeon_accel_disabled()) {
cfb_copyarea(info, area);
......@@ -108,7 +108,7 @@ void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct radeonfb_info *rinfo = info->par;
if (rinfo->asleep)
if (info->state != FBINFO_STATE_RUNNING)
return;
radeon_engine_idle();
......@@ -119,7 +119,7 @@ int radeonfb_sync(struct fb_info *info)
{
struct radeonfb_info *rinfo = info->par;
if (rinfo->asleep)
if (info->state != FBINFO_STATE_RUNNING)
return 0;
radeon_engine_idle();
......
......@@ -566,8 +566,9 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
break;
}
do_div(vclk, 1000);
xtal = (xtal * denom) / num;
vclk *= denom;
do_div(vclk, 1000 * num);
xtal = vclk;
if ((xtal > 26900) && (xtal < 27100))
xtal = 2700;
......
......@@ -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;
unsigned long *dst = NULL, *src = NULL;
if (p->state != FBINFO_STATE_RUNNING)
return;
/* We want rotation but lack hardware to do it for us. */
if (!p->fbops->fb_rotate && p->var.rotate) {
}
......
......@@ -367,6 +367,9 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
unsigned long *dst;
int dst_idx, left;
if (p->state != FBINFO_STATE_RUNNING)
return;
/* We want rotation but lack hardware to do it for us. */
if (!p->fbops->fb_rotate && p->var.rotate) {
}
......
......@@ -275,6 +275,9 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
int x2, y2, vxres, vyres;
u8 *dst1;
if (p->state != FBINFO_STATE_RUNNING)
return;
vxres = p->var.xres_virtual;
vyres = p->var.yres_virtual;
/*
......
......@@ -195,11 +195,13 @@ static void fb_flashcursor(void *private)
{
struct fb_info *info = (struct fb_info *) private;
/* Test to see if the cursor is erased but still on */
if (!info || (info->cursor.rop == ROP_COPY))
if (!info || info->state != FBINFO_STATE_RUNNING ||
info->cursor.rop == ROP_COPY)
return;
acquire_console_sem();
info->cursor.enable ^= 1;
info->fbops->fb_cursor(info, &info->cursor);
release_console_sem();
}
#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)
struct fb_info *info = (struct fb_info *) dev_addr;
schedule_work(&info->queue);
cursor_timer.expires = jiffies + HZ / 5;
add_timer(&cursor_timer);
mod_timer(&cursor_timer, jiffies + HZ/5);
}
int __init fb_console_setup(char *this_opt)
......@@ -353,8 +354,6 @@ static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
info->fbops->fb_imageblit(info, image);
image->dx += cnt * vc->vc_font.width;
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,
info->fbops->fb_imageblit(info, image);
image->dx += cnt * vc->vc_font.width;
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,
move_buf_aligned(info, dst, src, pitch, width, image.height);
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,
......@@ -676,7 +671,7 @@ static const char *fbcon_startup(void)
if (!info->queue.func) {
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;
add_timer(&cursor_timer);
}
......@@ -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)
return;
if (info->state != FBINFO_STATE_RUNNING)
return;
if (!height || !width)
return;
......@@ -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)
return;
if (info->state != FBINFO_STATE_RUNNING)
return;
if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
return;
......@@ -983,6 +982,8 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
if (!info->fbops->fb_blank && console_blanked)
return;
if (info->state != FBINFO_STATE_RUNNING)
return;
if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
return;
......@@ -2265,6 +2266,39 @@ static int fbcon_set_origin(struct vc_data *vc)
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
*/
......@@ -2291,16 +2325,35 @@ const struct consw fb_con = {
.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)
{
if (!num_registered_fb)
return -ENODEV;
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;
}
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);
}
......
......@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/linux_logo.h>
#include <linux/proc_fs.h>
#include <linux/console.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
......@@ -222,6 +223,9 @@ static struct {
#ifdef CONFIG_FB_RADEON
{ "radeonfb", radeonfb_init, radeonfb_setup },
#endif
#ifdef CONFIG_FB_RADEON_OLD
{ "radeonfb_old", radeonfb_init, radeonfb_setup },
#endif
#ifdef CONFIG_FB_CONTROL
{ "controlfb", control_init, control_setup },
#endif
......@@ -395,6 +399,7 @@ extern const char *global_mode_option;
static initcall_t pref_init_funcs[FB_MAX];
static int num_pref_init_funcs __initdata = 0;
static struct notifier_block *fb_notifier_list;
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
......@@ -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 align = info->pixmap.buf_align - 1;
u32 offset, count = 1000;
struct fb_pixmap *buf = &info->pixmap;
u32 align = buf->buf_align - 1, offset;
spin_lock(&info->pixmap.lock);
offset = info->pixmap.offset + align;
/* If IO mapped, we need to sync before access, no sharing of
* 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;
if (offset + size > info->pixmap.size) {
while (atomic_read(&info->pixmap.count) && count--);
if (info->fbops->fb_sync &&
info->pixmap.flags & FB_PIXMAP_SYNC)
if (offset + size > buf->size) {
/* We do not fit. In order to be able to re-use the buffer,
* we must ensure no asynchronous DMA'ing or whatever operation
* is in progress, we sync for that.
*/
if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
info->fbops->fb_sync(info);
offset = 0;
}
info->pixmap.offset = offset + size;
atomic_inc(&info->pixmap.count);
smp_mb__after_atomic_inc();
spin_unlock(&info->pixmap.lock);
buf->offset = offset + size;
return offset;
}
......@@ -685,8 +699,8 @@ int fb_show_logo(struct fb_info *info)
struct fb_image image;
int x;
/* Return if the frame buffer is not mapped */
if (fb_logo.logo == NULL)
/* Return if the frame buffer is not mapped or suspended */
if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
return 0;
image.depth = fb_logo.depth;
......@@ -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)) {
image.dx = x;
info->fbops->fb_imageblit(info, &image);
//atomic_dec(&info->pixmap.count);
//smp_mb__after_atomic_dec();
}
if (palette != NULL)
......@@ -780,6 +792,9 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
if (!info || ! info->screen_base)
return -ENODEV;
if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;
if (info->fbops->fb_read)
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)
if (!info || !info->screen_base)
return -ENODEV;
if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;
if (info->fbops->fb_write)
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)
fb_pan_display(info, &info->var);
fb_set_cmap(&info->cmap, 1, info);
notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info);
}
}
return 0;
......@@ -979,7 +999,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct fb_con2fbmap con2fb;
#endif
struct fb_cmap cmap;
int i;
int i, rc;
if (!fb)
return -ENODEV;
......@@ -990,7 +1010,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT;
acquire_console_sem();
i = fb_set_var(info, &var);
release_console_sem();
if (i) return i;
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
......@@ -1009,13 +1031,19 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPAN_DISPLAY:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
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;
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
return 0;
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
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
......@@ -1045,7 +1073,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return 0;
#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
case FBIOBLANK:
return fb_blank(info, arg);
acquire_console_sem();
i = fb_blank(info, arg);
release_console_sem();
return i;
default:
if (fb->fb_ioctl == NULL)
return -EINVAL;
......@@ -1242,7 +1273,6 @@ register_framebuffer(struct fb_info *fb_info)
fb_info->pixmap.outbuf = sys_outbuf;
if (fb_info->pixmap.inbuf == NULL)
fb_info->pixmap.inbuf = sys_inbuf;
spin_lock_init(&fb_info->pixmap.lock);
registered_fb[i] = fb_info;
......@@ -1279,8 +1309,42 @@ unregister_framebuffer(struct fb_info *fb_info)
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)
{
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);
EXPORT_SYMBOL(move_buf_unaligned);
EXPORT_SYMBOL(move_buf_aligned);
EXPORT_SYMBOL(fb_set_suspend);
EXPORT_SYMBOL(fb_register_client);
EXPORT_SYMBOL(fb_unregister_client);
MODULE_LICENSE("GPL");
......@@ -1615,8 +1615,9 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
}
#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;
unsigned char *pedid = NULL;
......
......@@ -48,6 +48,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
info->cursor.image.depth = cursor->image.depth;
}
if (info->state != FBINFO_STATE_RUNNING)
return 0;
s_pitch = (info->cursor.image.width + 7) >> 3;
dsize = s_pitch * info->cursor.image.height;
d_pitch = (s_pitch + scan_align) & ~scan_align;
......@@ -74,8 +77,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
info->cursor.image.data = dst;
info->fbops->fb_imageblit(info, &info->cursor.image);
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
return 0;
}
......
......@@ -114,7 +114,6 @@ extern void ia64_mca_ucmc_handler(void);
extern void ia64_monarch_init_handler(void);
extern void ia64_slave_init_handler(void);
extern void ia64_mca_cmc_vector_setup(void);
extern int ia64_mca_check_errors(void);
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_MCA_H */
......@@ -339,6 +339,24 @@ struct fb_info;
struct device;
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
*
......@@ -363,8 +381,6 @@ struct fb_pixmap {
/* access methods */
void (*outbuf)(u8 *dst, u8 *addr, unsigned int size);
u8 (*inbuf) (u8 *addr);
spinlock_t lock; /* spinlock */
atomic_t count;
};
/*
......@@ -449,6 +465,9 @@ struct fb_info {
struct vc_data *display_fg; /* Console visible on this display */
int currcon; /* Current VC. */
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 */
void *par;
};
......
......@@ -216,28 +216,37 @@
/* Rage128 GL */
#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245
#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246
#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x534b
#define PCI_DEVICE_ID_ATI_RAGE128_RH 0x534c
#define PCI_DEVICE_ID_ATI_RAGE128_RI 0x534d
#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x5247
/* Rage128 VR */
#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b
#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c
#define PCI_DEVICE_ID_ATI_RAGE128_RM 0x5345
#define PCI_DEVICE_ID_ATI_RAGE128_RN 0x5346
#define PCI_DEVICE_ID_ATI_RAGE128_RO 0x5347
#define PCI_DEVICE_ID_ATI_RAGE128_SE 0x5345
#define PCI_DEVICE_ID_ATI_RAGE128_SF 0x5346
#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 */
#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45
#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46
/* Rage128 Pro Ultra */
#define PCI_DEVICE_ID_ATI_RAGE128_U1 0x5446
#define PCI_DEVICE_ID_ATI_RAGE128_U2 0x544C
#define PCI_DEVICE_ID_ATI_RAGE128_U3 0x5452
/* Rage128 M4 */
#define PCI_DEVICE_ID_ATI_RAGE128_MF 0x4d46
#define PCI_DEVICE_ID_ATI_RAGE128_ML 0x4d4c
/* Rage128 Pro GL */
#define PCI_DEVICE_ID_ATI_Rage128_PA 0x5041
#define PCI_DEVICE_ID_ATI_Rage128_PB 0x5042
#define PCI_DEVICE_ID_ATI_Rage128_PC 0x5043
#define PCI_DEVICE_ID_ATI_Rage128_PD 0x5044
#define PCI_DEVICE_ID_ATI_Rage128_PE 0x5045
#define PCI_DEVICE_ID_ATI_RAGE128_PA 0x5041
#define PCI_DEVICE_ID_ATI_RAGE128_PB 0x5042
#define PCI_DEVICE_ID_ATI_RAGE128_PC 0x5043
#define PCI_DEVICE_ID_ATI_RAGE128_PD 0x5044
#define PCI_DEVICE_ID_ATI_RAGE128_PE 0x5045
#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046
/* Rage128 Pro VR */
#define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047
......
......@@ -415,5 +415,8 @@
#define PWR_MGT_SLOWDOWN_MCLK 0x00002000
#define PMI_PMSCR_REG 0x60
/* used by ATI bug fix for hardware ROM */
#define RAGE128_MPP_TB_CONFIG 0x01c0
#endif /* REG_RAGE128_H */
......@@ -97,10 +97,16 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
rfcomm_dlc_unlock(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);
/* 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);
}
......@@ -111,6 +117,13 @@ static inline void rfcomm_dev_hold(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))
rfcomm_dev_destruct(dev);
}
......@@ -134,10 +147,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
struct rfcomm_dev *dev;
read_lock(&rfcomm_dev_lock);
dev = __rfcomm_dev_get(id);
if (dev)
rfcomm_dev_hold(dev);
read_unlock(&rfcomm_dev_lock);
if (dev) rfcomm_dev_hold(dev);
return dev;
}
......@@ -214,8 +230,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
rfcomm_dlc_unlock(dlc);
/* 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);
out:
write_unlock_bh(&rfcomm_dev_lock);
......@@ -486,7 +503,8 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
rfcomm_dev_del(dev);
/* 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_dev_put(dev);
rfcomm_dlc_lock(dlc);
......@@ -541,6 +559,10 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
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);
if (!dev)
return -ENODEV;
......@@ -561,10 +583,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
if (err < 0) {
rfcomm_dev_put(dev);
if (err < 0)
return err;
}
/* Wait for DLC to connect */
add_wait_queue(&dev->wait, &wait);
......@@ -589,9 +609,6 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->wait, &wait);
if (err < 0)
rfcomm_dev_put(dev);
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