Commit ef0eaa13 authored by Steve French's avatar Steve French

Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git

parents 53b2ec55 df70b17f
...@@ -1042,8 +1042,3 @@ config X86_TRAMPOLINE ...@@ -1042,8 +1042,3 @@ config X86_TRAMPOLINE
bool bool
depends on X86_SMP || (X86_VOYAGER && SMP) depends on X86_SMP || (X86_VOYAGER && SMP)
default y default y
config PC
bool
depends on X86 && !EMBEDDED
default y
...@@ -803,7 +803,6 @@ static int __init detect_init_APIC (void) ...@@ -803,7 +803,6 @@ static int __init detect_init_APIC (void)
void __init init_apic_mappings(void) void __init init_apic_mappings(void)
{ {
unsigned int orig_apicid;
unsigned long apic_phys; unsigned long apic_phys;
/* /*
...@@ -825,11 +824,8 @@ void __init init_apic_mappings(void) ...@@ -825,11 +824,8 @@ void __init init_apic_mappings(void)
* Fetch the APIC ID of the BSP in case we have a * Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken). * default configuration (or the MP table is broken).
*/ */
orig_apicid = boot_cpu_physical_apicid; if (boot_cpu_physical_apicid == -1U)
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
orig_apicid, boot_cpu_physical_apicid);
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
{ {
...@@ -1259,81 +1255,40 @@ fastcall void smp_error_interrupt(struct pt_regs *regs) ...@@ -1259,81 +1255,40 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
} }
/* /*
* This initializes the IO-APIC and APIC hardware. * This initializes the IO-APIC and APIC hardware if this is
* a UP kernel.
*/ */
int __init APIC_init(void) int __init APIC_init_uniprocessor (void)
{ {
if (enable_local_apic < 0) { if (enable_local_apic < 0)
printk(KERN_INFO "APIC disabled\n"); clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
return -1;
}
/* See if we have a SMP configuration or have forced enabled if (!smp_found_config && !cpu_has_apic)
* the local apic.
*/
if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
enable_local_apic = -1;
return -1; return -1;
}
/* /*
* Complain if the BIOS pretends there is an apic. * Complain if the BIOS pretends there is one.
* Then get out because we don't have an a local apic.
*/ */
if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_physical_apicid); boot_cpu_physical_apicid);
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
enable_local_apic = -1;
return -1; return -1;
} }
verify_local_APIC(); verify_local_APIC();
/*
* Should not be necessary because the MP table should list the boot
* CPU too, but we do it for the sake of robustness anyway.
* Makes no sense to do this check in clustered apic mode, so skip it
*/
if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
boot_cpu_physical_apicid);
physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
}
/*
* Switch from PIC to APIC mode.
*/
connect_bsp_APIC(); connect_bsp_APIC();
setup_local_APIC();
#ifdef CONFIG_X86_IO_APIC phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
/*
* Now start the IO-APICs
*/
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
#endif
return 0;
}
void __init APIC_late_time_init(void) setup_local_APIC();
{
/* Improve our loops per jiffy estimate */
loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
cpu_data[0].loops_per_jiffy = loops_per_jiffy;
/* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
* initialized. So redo it here to ensure the boot cpu is setup
* properly.
*/
if (nmi_watchdog == NMI_LOCAL_APIC)
setup_apic_nmi_watchdog();
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
if (smp_found_config && !skip_ioapic_setup && nr_ioapics) if (smp_found_config)
IO_APIC_late_time_init(); if (!skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
#endif #endif
setup_boot_APIC_clock(); setup_boot_APIC_clock();
return 0;
} }
...@@ -435,8 +435,4 @@ void __init init_IRQ(void) ...@@ -435,8 +435,4 @@ void __init init_IRQ(void)
setup_irq(FPU_IRQ, &fpu_irq); setup_irq(FPU_IRQ, &fpu_irq);
irq_ctx_init(smp_processor_id()); irq_ctx_init(smp_processor_id());
#ifdef CONFIG_X86_LOCAL_APIC
APIC_init();
#endif
} }
...@@ -2387,15 +2387,11 @@ void __init setup_IO_APIC(void) ...@@ -2387,15 +2387,11 @@ void __init setup_IO_APIC(void)
sync_Arb_IDs(); sync_Arb_IDs();
setup_IO_APIC_irqs(); setup_IO_APIC_irqs();
init_IO_APIC_traps(); init_IO_APIC_traps();
check_timer();
if (!acpi_ioapic) if (!acpi_ioapic)
print_IO_APIC(); print_IO_APIC();
} }
void __init IO_APIC_late_time_init(void)
{
check_timer();
}
/* /*
* Called after all the initialization is done. If we didnt find any * Called after all the initialization is done. If we didnt find any
* APIC bugs then we can allow the modify fast path * APIC bugs then we can allow the modify fast path
......
...@@ -1078,16 +1078,6 @@ void *xquad_portio; ...@@ -1078,16 +1078,6 @@ void *xquad_portio;
EXPORT_SYMBOL(xquad_portio); EXPORT_SYMBOL(xquad_portio);
#endif #endif
/*
* Fall back to non SMP mode after errors.
*
*/
static __init void disable_smp(void)
{
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
}
static void __init smp_boot_cpus(unsigned int max_cpus) static void __init smp_boot_cpus(unsigned int max_cpus)
{ {
int apicid, cpu, bit, kicked; int apicid, cpu, bit, kicked;
...@@ -1100,6 +1090,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1100,6 +1090,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk("CPU%d: ", 0); printk("CPU%d: ", 0);
print_cpu_info(&cpu_data[0]); print_cpu_info(&cpu_data[0]);
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
boot_cpu_logical_apicid = logical_smp_processor_id(); boot_cpu_logical_apicid = logical_smp_processor_id();
x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
...@@ -1111,27 +1102,68 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1111,27 +1102,68 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpus_clear(cpu_core_map[0]); cpus_clear(cpu_core_map[0]);
cpu_set(0, cpu_core_map[0]); cpu_set(0, cpu_core_map[0]);
map_cpu_to_logical_apicid();
/* /*
* If we couldn't find an SMP configuration at boot time, * If we couldn't find an SMP configuration at boot time,
* get out of here now! * get out of here now!
*/ */
if (!smp_found_config && !acpi_lapic) { if (!smp_found_config && !acpi_lapic) {
printk(KERN_NOTICE "SMP motherboard not detected.\n"); printk(KERN_NOTICE "SMP motherboard not detected.\n");
disable_smp(); smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
if (APIC_init_uniprocessor())
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
map_cpu_to_logical_apicid();
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
return;
}
/*
* Should not be necessary because the MP table should list the boot
* CPU too, but we do it for the sake of robustness anyway.
* Makes no sense to do this check in clustered apic mode, so skip it
*/
if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
boot_cpu_physical_apicid);
physid_set(hard_smp_processor_id(), phys_cpu_present_map);
}
/*
* If we couldn't find a local APIC, then get out of here now!
*/
if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_physical_apicid);
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
return; return;
} }
verify_local_APIC();
/* /*
* If SMP should be disabled, then really disable it! * If SMP should be disabled, then really disable it!
*/ */
if (!max_cpus || (enable_local_apic < 0)) { if (!max_cpus) {
printk(KERN_INFO "SMP mode deactivated.\n"); smp_found_config = 0;
disable_smp(); printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
return; return;
} }
connect_bsp_APIC();
setup_local_APIC();
map_cpu_to_logical_apicid();
setup_portio_remap(); setup_portio_remap();
/* /*
...@@ -1212,6 +1244,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1212,6 +1244,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpu_set(0, cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]); cpu_set(0, cpu_core_map[0]);
smpboot_setup_io_apic();
setup_boot_APIC_clock();
/* /*
* Synchronize the TSC with the AP * Synchronize the TSC with the AP
*/ */
......
...@@ -440,8 +440,8 @@ static int time_init_device(void) ...@@ -440,8 +440,8 @@ static int time_init_device(void)
device_initcall(time_init_device); device_initcall(time_init_device);
extern void (*late_time_init)(void);
#ifdef CONFIG_HPET_TIMER #ifdef CONFIG_HPET_TIMER
extern void (*late_time_init)(void);
/* Duplicate of time_init() below, with hpet_enable part added */ /* Duplicate of time_init() below, with hpet_enable part added */
static void __init hpet_time_init(void) static void __init hpet_time_init(void)
{ {
...@@ -458,11 +458,6 @@ static void __init hpet_time_init(void) ...@@ -458,11 +458,6 @@ static void __init hpet_time_init(void)
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
time_init_hook(); time_init_hook();
#ifdef CONFIG_X86_LOCAL_APIC
if (enable_local_apic >= 0)
APIC_late_time_init();
#endif
} }
#endif #endif
...@@ -487,9 +482,4 @@ void __init time_init(void) ...@@ -487,9 +482,4 @@ void __init time_init(void)
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
time_init_hook(); time_init_hook();
#ifdef CONFIG_X86_LOCAL_APIC
if (enable_local_apic >= 0)
late_time_init = APIC_late_time_init;
#endif
} }
...@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD ...@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
if INPUT_KEYBOARD if INPUT_KEYBOARD
config KEYBOARD_ATKBD config KEYBOARD_ATKBD
tristate "AT keyboard" if !PC tristate "AT keyboard" if !X86_PC
default y default y
select SERIO select SERIO
select SERIO_LIBPS2 select SERIO_LIBPS2
select SERIO_I8042 if PC select SERIO_I8042 if X86_PC
select SERIO_GSCPS2 if GSC select SERIO_GSCPS2 if GSC
help help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
......
...@@ -17,7 +17,7 @@ config MOUSE_PS2 ...@@ -17,7 +17,7 @@ config MOUSE_PS2
default y default y
select SERIO select SERIO
select SERIO_LIBPS2 select SERIO_LIBPS2
select SERIO_I8042 if PC select SERIO_I8042 if X86_PC
select SERIO_GSCPS2 if GSC select SERIO_GSCPS2 if GSC
---help--- ---help---
Say Y here if you have a PS/2 mouse connected to your system. This Say Y here if you have a PS/2 mouse connected to your system. This
......
...@@ -180,12 +180,22 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne ...@@ -180,12 +180,22 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
return; return;
} }
count = min(pc->sg->length - pc->b_count, bcount); count = min(pc->sg->length - pc->b_count, bcount);
buf = kmap_atomic(pc->sg->page, KM_IRQ0); if (PageHighMem(pc->sg->page)) {
drive->hwif->atapi_input_bytes(drive, unsigned long flags;
buf + pc->b_count + pc->sg->offset, count);
kunmap_atomic(buf, KM_IRQ0); local_irq_save(flags);
bcount -= count; buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
pc->b_count += count; pc->sg->offset;
drive->hwif->atapi_input_bytes(drive,
buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(pc->sg->page) + pc->sg->offset;
drive->hwif->atapi_input_bytes(drive,
buf + pc->b_count, count);
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) { if (pc->b_count == pc->sg->length) {
pc->sg++; pc->sg++;
pc->b_count = 0; pc->b_count = 0;
...@@ -205,12 +215,22 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign ...@@ -205,12 +215,22 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
return; return;
} }
count = min(pc->sg->length - pc->b_count, bcount); count = min(pc->sg->length - pc->b_count, bcount);
buf = kmap_atomic(pc->sg->page, KM_IRQ0); if (PageHighMem(pc->sg->page)) {
drive->hwif->atapi_output_bytes(drive, unsigned long flags;
buf + pc->b_count + pc->sg->offset, count);
kunmap_atomic(buf, KM_IRQ0); local_irq_save(flags);
bcount -= count; buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
pc->b_count += count; pc->sg->offset;
drive->hwif->atapi_output_bytes(drive,
buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(pc->sg->page) + pc->sg->offset;
drive->hwif->atapi_output_bytes(drive,
buf + pc->b_count, count);
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) { if (pc->b_count == pc->sg->length) {
pc->sg++; pc->sg++;
pc->b_count = 0; pc->b_count = 0;
......
...@@ -138,11 +138,23 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) ...@@ -138,11 +138,23 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
} }
EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
{
u16 cmd;
return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
}
#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
{ {
unsigned long base = 0; unsigned long base = 0;
int i; int i;
if (!pio_enabled(pdev))
return;
for (i = 0; i < PCI_ROM_RESOURCE; i++) for (i = 0; i < PCI_ROM_RESOURCE; i++)
if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
base = pci_resource_start(pdev, i); base = pci_resource_start(pdev, i);
...@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) ...@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
uhci_check_and_reset_hc(pdev, base); uhci_check_and_reset_hc(pdev, base);
} }
static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
{
return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
}
static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
{ {
void __iomem *base; void __iomem *base;
int wait_time; int wait_time;
u32 control; u32 control;
if (!mmio_resource_enabled(pdev, 0))
return;
base = ioremap_nocache(pci_resource_start(pdev, 0), base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (base == NULL) return; if (base == NULL) return;
...@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) ...@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
u32 hcc_params, val, temp; u32 hcc_params, val, temp;
u8 cap_length; u8 cap_length;
if (!mmio_resource_enabled(pdev, 0))
return;
base = ioremap_nocache(pci_resource_start(pdev, 0), base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (base == NULL) return; if (base == NULL) return;
......
...@@ -247,7 +247,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) ...@@ -247,7 +247,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
wait_queue_head_t *wqh; wait_queue_head_t *wqh;
if (!atomic_read(&inode->i_count)) if (!atomic_read(&inode->i_count))
WARN_ON(!(inode->i_state & I_WILL_FREE)); WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
else else
WARN_ON(inode->i_state & I_WILL_FREE); WARN_ON(inode->i_state & I_WILL_FREE);
......
...@@ -668,10 +668,10 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, ...@@ -668,10 +668,10 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
* to, we need to read it in before the write, * to, we need to read it in before the write,
* i.e. now. * i.e. now.
*/ */
if (!buffer_uptodate(bh) && ((bh_pos < pos && if (!buffer_uptodate(bh) && bh_pos < end &&
bh_end > pos) || bh_end > pos &&
(bh_end > end && (bh_pos < pos ||
bh_end > end))) { bh_end > end)) {
/* /*
* If the buffer is fully or partially * If the buffer is fully or partially
* within the initialized size, do an * within the initialized size, do an
...@@ -784,10 +784,11 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, ...@@ -784,10 +784,11 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
blocksize_bits); blocksize_bits);
cdelta = 0; cdelta = 0;
/* /*
* If the number of remaining clusters in the * If the number of remaining clusters touched
* @pages is smaller or equal to the number of * by the write is smaller or equal to the
* cached clusters, unlock the runlist as the * number of cached clusters, unlock the
* map cache will be used from now on. * runlist as the map cache will be used from
* now on.
*/ */
if (likely(vcn + vcn_len >= cend)) { if (likely(vcn + vcn_len >= cend)) {
if (rl_write_locked) { if (rl_write_locked) {
......
...@@ -118,8 +118,7 @@ extern void release_lapic_nmi(void); ...@@ -118,8 +118,7 @@ extern void release_lapic_nmi(void);
extern void disable_timer_nmi_watchdog(void); extern void disable_timer_nmi_watchdog(void);
extern void enable_timer_nmi_watchdog(void); extern void enable_timer_nmi_watchdog(void);
extern void nmi_watchdog_tick (struct pt_regs * regs); extern void nmi_watchdog_tick (struct pt_regs * regs);
extern int APIC_init(void); extern int APIC_init_uniprocessor (void);
extern void APIC_late_time_init(void);
extern void disable_APIC_timer(void); extern void disable_APIC_timer(void);
extern void enable_APIC_timer(void); extern void enable_APIC_timer(void);
......
...@@ -55,7 +55,6 @@ void init_8259A(int aeoi); ...@@ -55,7 +55,6 @@ void init_8259A(int aeoi);
void FASTCALL(send_IPI_self(int vector)); void FASTCALL(send_IPI_self(int vector));
void init_VISWS_APIC_irqs(void); void init_VISWS_APIC_irqs(void);
void setup_IO_APIC(void); void setup_IO_APIC(void);
void IO_APIC_late_time_init(void);
void disable_IO_APIC(void); void disable_IO_APIC(void);
void print_IO_APIC(void); void print_IO_APIC(void);
int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
......
/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws /* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
* which needs to alter them. */ * which needs to alter them. */
static inline void smpboot_clear_io_apic_irqs(void)
{
io_apic_irqs = 0;
}
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{ {
CMOS_WRITE(0xa, 0xf); CMOS_WRITE(0xa, 0xf);
...@@ -27,3 +32,13 @@ static inline void smpboot_restore_warm_reset_vector(void) ...@@ -27,3 +32,13 @@ static inline void smpboot_restore_warm_reset_vector(void)
*((volatile long *) phys_to_virt(0x467)) = 0; *((volatile long *) phys_to_virt(0x467)) = 0;
} }
static inline void smpboot_setup_io_apic(void)
{
/*
* Here we can be sure that there is an IO-APIC in the system. Let's
* go and set it up:
*/
if (!skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
}
...@@ -11,7 +11,14 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) ...@@ -11,7 +11,14 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
/* for visws do nothing for any of these */ /* for visws do nothing for any of these */
static inline void smpboot_clear_io_apic_irqs(void)
{
}
static inline void smpboot_restore_warm_reset_vector(void) static inline void smpboot_restore_warm_reset_vector(void)
{ {
} }
static inline void smpboot_setup_io_apic(void)
{
}
...@@ -1055,6 +1055,7 @@ typedef struct { ...@@ -1055,6 +1055,7 @@ typedef struct {
unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */ unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */ unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
unsigned char ca0108_chip; /* Audigy 2 Value */ unsigned char ca0108_chip; /* Audigy 2 Value */
unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
unsigned char ca0151_chip; /* P16V */ unsigned char ca0151_chip; /* P16V */
unsigned char spk71; /* Has 7.1 speakers */ unsigned char spk71; /* Has 7.1 speakers */
unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */ unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
......
...@@ -64,6 +64,10 @@ ...@@ -64,6 +64,10 @@
#endif #endif
#endif #endif
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h>
#endif
/* /*
* Versions of gcc older than that listed below may actually compile * Versions of gcc older than that listed below may actually compile
* and link okay, but the end product can have subtle run time bugs. * and link okay, but the end product can have subtle run time bugs.
...@@ -310,7 +314,14 @@ extern void setup_arch(char **); ...@@ -310,7 +314,14 @@ extern void setup_arch(char **);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
#ifdef CONFIG_X86_LOCAL_APIC
static void __init smp_init(void)
{
APIC_init_uniprocessor();
}
#else
#define smp_init() do { } while (0) #define smp_init() do { } while (0)
#endif
static inline void setup_per_cpu_areas(void) { } static inline void setup_per_cpu_areas(void) { }
static inline void smp_prepare_cpus(unsigned int maxcpus) { } static inline void smp_prepare_cpus(unsigned int maxcpus) { }
......
...@@ -579,6 +579,30 @@ static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu) ...@@ -579,6 +579,30 @@ static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu)
return 0; return 0;
} }
static int __devinit snd_emu10k1_cardbus_init(emu10k1_t * emu)
{
unsigned long special_port;
unsigned int value;
/* Special initialisation routine
* before the rest of the IO-Ports become active.
*/
special_port = emu->port + 0x38;
value = inl(special_port);
outl(0x00d00000, special_port);
value = inl(special_port);
outl(0x00d00001, special_port);
value = inl(special_port);
outl(0x00d0005f, special_port);
value = inl(special_port);
outl(0x00d0007f, special_port);
value = inl(special_port);
outl(0x0090007f, special_port);
value = inl(special_port);
return 0;
}
/* /*
* Create the EMU10K1 instance * Create the EMU10K1 instance
*/ */
...@@ -624,6 +648,16 @@ static emu_chip_details_t emu_chip_details[] = { ...@@ -624,6 +648,16 @@ static emu_chip_details_t emu_chip_details[] = {
.ca0108_chip = 1, .ca0108_chip = 1,
.spk71 = 1, .spk71 = 1,
.ac97_chip = 1} , .ac97_chip = 1} ,
/* Audigy 2 ZS Notebook Cardbus card.*/
/* Tested by James@superbug.co.uk 30th October 2005 */
/* Not working yet, but progressing. */
{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
.driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
.id = "Audigy2",
.emu10k2_chip = 1,
.ca0108_chip = 1,
.ca_cardbus_chip = 1,
.spk71 = 1} ,
{.vendor = 0x1102, .device = 0x0008, {.vendor = 0x1102, .device = 0x0008,
.driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
.id = "Audigy2", .id = "Audigy2",
...@@ -1011,6 +1045,11 @@ int __devinit snd_emu10k1_create(snd_card_t * card, ...@@ -1011,6 +1045,11 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
snd_emu10k1_free(emu); snd_emu10k1_free(emu);
return err; return err;
} }
} else if (emu->card_capabilities->ca_cardbus_chip) {
if ((err = snd_emu10k1_cardbus_init(emu)) < 0) {
snd_emu10k1_free(emu);
return err;
}
} else { } else {
/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
does not support this, it shouldn't do any harm */ does not support this, it shouldn't do any harm */
......
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